Docker基础
1 docker简介
在项目开发中,为了部署我们的项⽬,需要配置各种各样的依赖环境,容易出错,不易管理,还要搞⼀堆各式各样的配置,⼀个地⽅不对,项⽬就有可能瘫痪。
Docker 属于 Linux 容器的⼀种封装,提供简单易⽤的容器使⽤接⼝。
Docker 将应用程序与该程序的依赖,打包在⼀个⽂件⾥⾯。运⾏这个文件,就会⽣成⼀个虚拟容器。程序在这个虚拟容器⾥运行,就好像在真实的物理机上运行⼀样。有了 Docker,就不⽤担心环境问题。
Doker可以隔离应用级别:⽐如我写了两个应⽤(网站),这两个应⽤部署在同⼀台服务器上,如果⼀个应⽤出现了问
题,导致CPU占100%,那另⼀个应⽤也会受到关联。而dockr在应用隔离的时候将他的资源已经分配好了,应用之间解耦,不会相互影响。
docker应用隔离2 docker安装(linux)
centos7安装docker: yum install docker
centos7启动docker: systemctl start(stop) docker
(开机启动):systemctl enable docker
查看docker版本: docker version
3 docker的重要概念
docker中主要有这么三个东西:Images(镜像)、Containers(容器)、Repository(仓库)。
3.1 Images(镜像)
image其实就是⼀个⽂件系统,它的存储是一层一层往上叠起来的。它与宿主机的内核⼀起为程序提供⼀个虚拟的linux环境。它类似于虚拟机中使⽤到的镜像,由于任何应⽤程序都需要有它⾃⼰的运⾏环境,Image就是⽤来提供所需运⾏环境的⼀个模板。Image本身是只读的,可以通过Dockerfifile定义,也可以到Repository中取拉取。
3.2 Container(容器)
Container是Docker提供的⼀个抽象层,它就像⼀个轻量级的沙盒,其中包含了⼀个极简的Linux系统环境与运⾏在其中的应⽤程序。Container是Image的运⾏实例(类似Java的类和对象)。(Image本身是只读的,Container启动时,Docker会在Image的上层创建⼀个可写层,任何在Container中的修改都不会影响到Image,如果想要在Image保存Container中的修改,Docker采⽤了基于Container⽣成新的Image层的策略),Docker引擎利⽤Container来操作并隔离每个应⽤(也就是说,每个容器中的应⽤都是互相独⽴的)。也就是运⾏Images的地⽅。
3.3 Repository(仓库)
Repository:存放Images的仓库。
官⽅仓库: https://hub.docker.com/ https://hub.docker.com/search?image_fifilter=offiffifficial&type=image
举个例子,小明写了⼀个erp系统,该系统的技术栈⾮常⼴,需要依赖于各种开源库和 中间件。如果按照纯⼿动的部署⽅式,⼩明需要安装各种开源软件,还需要写好每个开源软件的配置⽂件。如果只是部署⼀次,这点时间开销还是可以接受的,但如果⼩明每隔⼏天就需要 换个服务器去部署他的程序,那么这些繁琐的重复⼯作⽆疑是会令⼈发狂的。这时候, Docker的⽤处就派上场了,小明只需要根据应⽤程序的部署步骤编写⼀份Dockerfifile⽂件(将 安装、配置等操作交由Docker⾃动化处理),然后构建并发布他的镜像,这样不管在什么机器上小明都只需要拉取他需要的镜像,然后就可以直接部署运行了。
4 Image
4.1 操作镜像的基本命令
下载镜像 :docker pull hello-world(镜像名是hello-world)。
下载镜像运行镜像:docker run hello-word (运行镜像是在Container中运行的)。
运行镜像查看镜像:docker image ls
查看镜像#REPOSITORY image名称
#TAG 版本号
#IMAGE ID image的id
#CREATED 创建时间
#SIZE image的大小
删除镜像:docker rmi -f 镜像id
#删除镜像 -f 强制删除
删除镜像4.2 创建自定义镜像
创建一个hello-docker目录
在⾥⾯创建⼀个hello.c⽂件
编译hello.c (需要安装依赖gcc 和glibc-static)会⽣成⼀个hello执⾏⽂件
gcc -static hello.c -o hello
应⽤Dockerfifile将可执⾏⽂件hello 打包成⼀个image
现在在hello-docker⽂件夹外⾯新建⼀个Dockerfile并编写
目录结构Dockerfile编写
dockerFile打包镜像:docker build -t maguoq/hello .
maguoq为Docker Hub的账号ID,没有的可以注册⼀下https://hub.docker.com/
hello为image的名字,全名由账号和image名字购成。
.表示Dockerfifile所在的⽬录(根据⾃⼰情况填写eg:/data/)
构建镜像 带有版本的镜像查看并运行镜像
运行镜像 运行带有版本的镜像5 container
想要运⾏⼀个Image,就必须有⼀个container,image就好⽐jave中的类,container就像java中image类所创建出的对象。container通过image创建(复制的过程);然后再image基础上再加⼀层,可读可写成(image是只读的)。最终运⾏的是container。
Container5.1 container操作
#列出本地正在运⾏的container
docker container ls
#列出所有的container 包括运⾏完退出的
docker container ls -a
docker container ls -aq (所有container的ID)
docker container ls -f "status=exited" -q (所有退出的container ID)
#构建运⾏容器
doucker run 名称:版本号(⽆默认最新版);
docker run 会构建container然后执⾏Dockerfifile中的命令
docker run -it [镜像名字] (交互式运⾏,可以进⼊container的读写层,然后操作)
docker run -d [镜像名字] (后台运⾏)
#按照ID删除container
docker container rm CONTAINERID
docker container rm $(docker container ls -aq ) #删所有
docker container rm $(docker container ls -f "status=exited" -q) #删退出的
#杀掉运⾏中的container
docker container kill CONTAINERID
#将⼀个container 改动后变成⼀个新的image
docker container commit [container的名字] [(docker HupID号)/新的名字:版本号]
将一个container构建成一个新的managedocker history [imageID] (查看⼀个image的构建历史)
5.2 通过dockerfile构建出一个新的image
删除原来的 dockerfile,新建一个docker,引用之前的镜像。编写新的dockerfile增加一些操作。
如果引用的镜像没有下载下来的话,在build的时候会去自动下载镜像。然后构建出我们的新的镜像。
引用centos 的镜像的新的镜像构建镜像:docker build -t 镜像名称 . (.指的是dockerfile的位置 当前文件夹)
构建镜像 新的镜像交互运行镜像:docker run -it maguoq/centos-new
我们可以进入镜像的container 的可读可写层。
运行镜像退出container
退出container6 Dockerfile构建镜像实践
6.1 dockerfile 语法
FROM:从那个image基础上构建我们的image,空则为scratch
eg:FROM centos:7.4(版本号)
备注:尽量使⽤官⽅的image作为base,⾮官⽅的image为(id号/名称)
LABEL:注释说明, 指令会添加元数据到镜像。
LABEL <key>=<value> <key>=<value> <key>=<value> ...
编写dockerfile添加LABEL
添加LABEL构建镜像:docker build -t maguoq/centos-new .
查看镜像:docker inspect
VOLUME:数据持久化地址RUN: 执⾏命名,多条命令⽤ && 连接,如果⼀⾏放不下⽤ \ 换⾏
eg: RUN yum update && yum install redis \
&& yum install -y vim
WORKDIR:指定当前⼯作⽬录
eg: WORKDIR /test #没有回⾃动创建
WORKDIR zyz #进⼊ /test/zyz
ADD:将本地⽂件添加到image,ADD 命令会⾃动解压缩⽂件,解压你导⼊的.gz包
eg: ADD hello / #添加到根⽬录
WORKDIR /test
ADD hello zyz/ #添加到/test/zyz下⾯
COPY:通ADD功能差不多,不能⾃动解压⽂件,优先级低于ADD
ENV:定义常量
eg:ENV NAME ZYZ
RUM echo ${NAME}
6.2 RUN、CMD 和 ENTRYPOINT
1. RUN 执行命令并创建新的镜像层,RUN 经常用于安装软件包。(还记得我们在centos中安装了⼀个Redis嘛?在原有的基础上加了⼀层Redis)。
2. CMD 设置容器启动后默认执行的命令及其参数,但 CMD 能够被 docker run 后面跟的命令行参数替换。 基于此,CMD往往被设置为默认执⾏的命令。
3. ENTRYPOINT 配置容器启动时运行的命令,一定都会被执行。
6.3 Dockerfile的 Shell 和 Exec 格式
Shell 格式
<instruction> <command>
例如:
ENV NAME python
RUN apt-get install python3
CMD echo "Hello $NAME "
ENTRYPOINT echo "Hello world"
Exec 格式
<instruction> ["executable", "param1", "param2", ...]
例如:
RUN ["apt-get ", "install", "python3"]
CMD ["/bin/echo", "Hello world"]
ENTRYPOINT ["/bin/echo", "Hello world"]
ENV NAME python
ENTRYPOINT echo "Hello $NAME" #name并没有被替换成python
ENTRYPOINT ["/bin/sh", "-c", "echo Hello, $NAME"] #name被替换成python
6.4 RUM CMD ENTRYPOINT区别
RUN:RUN 指令通常用于安装应用和软件包。
RUN 在当前镜像的顶部执行命令,并通过创建新的镜像层。Dockerfile 中常常包含多个RUN 指令。
RUN 有两种格式:
1.Shell 格式:RUN
2.exec 格式:RUN ["executable", "param1", "param2"]
CMD:指令允许⽤户指定容器的默认执⾏的命令。
此命令会在容器启动且 docker run 没有指定其他命令时运⾏。
如果 docker run 指定了其他命令,CMD 指定的默认命令将被忽略。
如果 Dockerfile 中有多个 CMD 指令,只有最后一个 CMD 有效。
CMD 有三种格式:
1.Exec 格式:CMD ["executable","param1","param2"]
2.CMD ["param1","param2"] 为 ENTRYPOINT 提供额外的参数,此时 ENTRYPOINT必须使用 Exec 格式。
3.Shell 格式:CMD command param1 param2
例子:
CMD echo "Hello world"
docker run -it [image]
输出Hello world
docker run -it [image] /bin/bash
CMD被忽略掉,执⾏bash命令
ENTRYPOINT 指令可让容器以应⽤程序或者服务的形式运⾏。
ENTRYPOINT 看上去与 CMD 很像,它们都可以指定要执⾏的命令及其参数。不同的地⽅在于 ENTRYPOINT 不会被忽略,⼀定会被执⾏,即使运⾏ docker run 时指定了其他命令。
ENTRYPOINT 有两种格式:
1.Exec 格式:ENTRYPOINT ["executable", "param1", "param2"] 这是 ENTRYPOINT的推荐格式。
2.Shell 格式:ENTRYPOINT command param1 param2eg: ENTRYPOINT ["/bin/echo", "Hello"]
CMD ["world"]
docker run -it [image] #输出Hello world
docker run -it [image] /bin/bash #CMD忽略 ENTRYPOINT 执⾏
docker run -it [image] docker #输出 Hello docker
eg:ENTRYPOINT ["java","-jar","hello-1.0-SNAPSHOT.jar"]
CMD []
最佳实践
1. 使用 RUN 指令安装应用和软件包,构建镜像。
2. 如果 Docker 镜像的用途是运行应用程序或服务,比如运行一个 MySQL,应该优先使用 Exec 格式的 ENTRYPOINT 指令。CMD 可为 ENTRYPOINT 提供额外的默认参数,同时可利用 docker run 命令行替换默认参数。
3.如果想为容器设置默认的启动命令,可使用 CMD 指令。用户可在 docker run 命令行中替换此默认命令。
7 镜像发布
将自己的image发布到docker hub,可共他人下载使用,首先要注册docker hup账户。
https://hub.docker.com/
注意:⾃⼰创建的image 名称必须是 【dockerHupId/image名】
1#登录docker
docker login
2#输入用户名和密码
3#docker push [image名称:版本号]
docker push maguoq/hello:latest
#可以使用tag为镜像更名
docker tag 名称 某个ID/名称
8 更换docker的repository
Docker Hup官网速度很慢,下载image速度很慢,这是候我们需要把docker的repository切换到国内的镜像仓库。
登录阿⾥云在产品中⼼搜索【容器镜像服务】开启服务。按照提示操作即可。
配置容器镜像将上面富文本编辑器里面的命令复制下来运行就配置完成了。然后用 docker info 查看镜像地址。
docker info9 阿里云创建私有的镜像仓库
1.登录阿里云控制台界面。搜索容器镜像服务,然后点击创建个人版实例。
创建镜像操作镜像
阿里云操作演示:
#登录阿里云的镜像
登录#推送镜像
$ docker push registry.cn-hangzhou.aliyuncs.com/maguoq/test:[镜像版本号]