一、安装docker及实验环境
需要全新的企业七虚拟机
获取软件包
[root@server1 ~]# ls
containerd.io-1.2.5-3.1.el7.x86_64.rpm
container-selinux-2.21-1.el7.noarch.rpm
docker-ce-18.09.6-3.el7.x86_64.rpm
docker-ce-cli-18.09.6-3.el7.x86_64.rpm
[root@server1 ~]# yum install -y *.rpm 安装
Loaded plugins: product-id, search-disabled-repos, subscription-manager
[root@server1 ~]# systemctl start docker 启动
[root@server1 ~]# systemctl enable docker 开机启动
二、镜像的导入和容器的使用
[root@server1 ~]# docker images 查看当前系统存在的镜像信息
[root@server1 ~]# docker load -i game2048.tar 向容器内导入镜像文件
-d后台运行 --name :名称(game1) -p:80:80 端口映射,外部主机不能直接通过ip访问docker
[root@server1 ~]# docker run -d --name game1 -p 80:80 game2048
通过本机80端口访问容器内部的80端口上运行的服务
运行容器并打入后台,这个容器是基于game2048这个镜像运行的
[root@server1 ~]# docker ps
查看容器运行状态,看端口是否开启
浏览器访问server1的ip,前提是只要server1的80端口没有被占用,这样就可以通过server1访问容器vm1的80端口
输入server1的ip:172.25.2.1
可以看到2048的游戏就出来了
三、docker命令
docker load -i game2048.tar 导入镜像
docker run -it --name game 创建容器-it:交互式访问容器
docker ps 查看容器状态,当前活跃的
docker ps -a 查看容器状态(包括不活跃的容器),所有的
docker attach vm1 连接容器
docker top vm1 查看容器进程
docker logs vm1 查看容器指令输出 -f 参数可以实时查看
docker inspect vm1 查看容器详情
docker stats vm1 查看容器资源使用率
docker diff vm1 查看容器修改
docker stop vm1 停止容器
docker start vm1 启动容器
docker kill vm1 强制干掉容器
docker restart vm1 重启容器
docker pause/unpause vm1 暂停/恢复容器
docker rm vm1 删除容器
docker rm -f vm1 强制删除容器
docker rmi ubantu 删除镜像
docker images 列出镜像
docker history 命令递归地输出指定镜像的历史镜像。
[root@server1 ~]# docker info 查看docker详细信息
解决上图的warning
向容器中导入ubuntu镜像
[root@server1 ~]# uname -r
3.10.0-957.el7.x86_64
可以看到server1的内核版本型号和Ubuntu镜像运行的内核版本一致
Ubuntu镜像运行是建立在server1的系统之上
删除两个镜像
四、利用docker构建镜像
给server1上传软件包
busybox镜像只有一些基础的命令和文件
-it表示打开交互式docker界面
ctrl + pq ##退出容器但不关闭容器
[root@server1 ~]# docker attach vm3 ##可以直接进入容器
ctrl + D ##退出并关闭容器,下次登陆时需要开启
[root@server1 ~]# docker start vm3 ##打开关闭的容器
[root@server1 ~]# docker attach vm3 ##再进入容器
保存上方更改之后的容器(方法一:不建议使用)
无法查看操作流程,看不到镜像的操作,安全检测无法通过
sh:那一行就是更改的操作
删除第一次导入的旧版本,运行更改之后的的镜像
方法二:dockerfile
删除所有镜像还原实验环境
五、Dockerfile的介绍
Dockerfile是一个包含用于组合映像的命令的文本文档。可以使用在命令行中调用任何命令。 Docker通过读取Dockerfile中的指令自动生成映像。
docker build命令用于从Dockerfile构建映像。可以在docker build命令中使用-f标志指向文件系统中任何位置的Dockerfile。
Dockerfile的基本结构
Dockerfile 一般分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令,’#’ 为 Dockerfile 中的注释。
Dockerfile文件说明
Docker以从上到下的顺序运行Dockerfile的指令。为了指定基本映像,第一条指令必须是FROM。一个声明以#字符开头则被视为注释。可以在Docker文件中使用RUN,CMD,FROM,EXPOSE,ENV等指令。
注意:一定要创建一个新的目录 因为在构建镜像的时候,会默认把dockerfile所在的目录中的所有目录发送给docker引擎,举个例子 如果你把dockerfile放在/目录下 那么这个过程会变得非常的缓慢
[root@server1 ~]# mkdir docker 创建目录
[root@server1 ~]# cd docker/ 进入目录
编写Dockerfile文件名称的第一个字母必须大写 内容为:把构建镜像的操作写入文件,所有人都可以看见
[root@server1 docker]# vim Dockerfile 此镜像建立两个文件file1和file2
FROM busybox FROM:指定基础镜像,必须为第一个命令
RUN echo testfile > file1 RUN:指定运行某命令
RUN echo testfile > file2
[root@server1 docker]# docker build -t test:v2 . test镜像名称:v2标签 . 代表当前目录
Sending build context to Docker daemon 2.048kB 把dockerfile所在的目录中的所有目录发送给docker引擎
Step 1/3 : FROM busybox 执行完此命令
---> 59788edf1f3e 生成一个id
Step 2/3 : RUN echo testfile > file1 运行此命令
---> Running in 0fc195924f41 在临时容器里面运行命令
Removing intermediate container 0fc195924f41 使用此临时容器去运行echo命令创建文件,完成后删除临时容器
---> f8d0917d2b7c 这个容器是完成命令之后的容器
Step 3/3 : RUN echo testfile > file2同上
---> Running in c419b39bc4ca
Removing intermediate container c419b39bc4ca
---> cf709fb5223b
Successfully built cf709fb5223b 最终创建好的容器
Successfully tagged test:v2
缓存特性
再次更改dockerfile 注意:不要随便加空格(要使用缓存 之前内容不能随便更改)
[root@server1 docker]# vim Dockerfile
[root@server1 docker]# cat Dockerfile
FROM busybox
RUN echo testfile > file1
RUN echo testfile > file2
RUN echo testfile > file3 添加一命令
[root@server1 docker]# docker build -t test:v3 . 再次build一个镜像,会出现Using cache ,已经缓存过的不会再缓存了
Sending build context to Docker daemon 2.048kB
Step 1/4 : FROM busybox
---> 59788edf1f3e
Step 2/4 : RUN echo testfile > file1
---> Using cache
---> f8d0917d2b7c
Step 3/4 : RUN echo testfile > file2
---> Using cache
---> cf709fb5223b
Step 4/4 : RUN echo testfile > file3
---> Running in 6f22ee82f269 运行新的指令
Removing intermediate container 6f22ee82f269
---> 2a15134d3148
Successfully built 2a15134d3148
Successfully tagged test:v3
如果我们希望在构建镜像时不使用缓存,可以在docker build命令中加上 --no-cache参数
dockerfile中每一个指令都会创建一个镜像层,上层是依赖于下层的,无论什么时候,只要某一层发生变化,其上面所有层的缓存都会失败
对比来看 v2和v3 有几层是一样的 每一个RUN就会构建一层镜像
而且我们可以看到 每一层的操作,再次说明 共同的镜像层之间的共享的
本质:dockerfile中的每一层其实就是执行了一个docker commit
六、编写dockerfile常用指令
删除之前构建的镜像
七、详细介绍dockerfile的一些常用指令 ,便于我们书写更成熟的dockerfile文件
**1.FROM:**指定base镜像,如果本地不存在会从远程仓库下载(虚拟机要配置上网)
**2.MAINTAINER维护者信息:**设置镜像的作者,比如用户邮箱等 (不是必须的)
**3.RUN:**构建镜像时执行的命令
4.COPY:把文件从build context复制到镜像,但不会自动解压文件,也不能访问网络资源
书写dockerfile
[root@server1 ~]# cd docker/ 进入目录
[root@server1 docker]# vim Dockerfile 编写dockerfile
[root@server1 docker]# cat Dockerfile
FROM busybox
COPY testfile /tmp 指定要复制文档的目的地
[root@server1 docker]# echo hellowestos > testfile 编辑所要复制的文档
[root@server1 docker]# cat testfile
hellowestos
[root@server1 docker]# docker build -t test:v1 . bulid镜像并进行查看
Sending build context to Docker daemon 3.072kB
Step 1/2 : FROM busybox
---> 59788edf1f3e
Step 2/2 : COPY testfile /tmp
---> 712e566b8ab4
Successfully built 712e566b8ab4
Successfully tagged test:v1
[root@server1 docker]# docker history test:v1 查看构建镜像的过程
IMAGE CREATED CREATED BY SIZE COMMENT
712e566b8ab4 14 seconds ago /bin/sh -c #(nop) COPY file:0c321b9eb466f149… 12B
59788edf1f3e 20 months ago /bin/sh -c #(nop) CMD ["sh"] 0B
<missing> 20 months ago /bin/sh -c #(nop) ADD file:63eebd629a5f7558c… 1.15MB
[root@server1 docker]# docker run -it --name vm1 test:v1 运行容器查看是否COPY成功
/ # ls
bin dev etc home proc root sys tmp usr var
/ # cd tmp/
/tmp # ls
testfile
/tmp # cat testfile 成功
hellowestos
/tmp #
5.ADD用法与COPY类似,不同的是src可以是归档压缩文件,文件会被自动解压到dest,也可以下载URL并拷贝到镜像
[root@server1 docker]# docker rmi -f test:v1
Untagged: test:v1
6.VOLUME:申明数据卷,通常指定的是应用的数据挂载点
目的:容器数据持久化的
[root@server1 docker]# vim Dockerfile
[root@server1 docker]# cat Dockerfile
FROM busybox
COPY testfile /tmp
ADD nginx-1.18.0.tar.gz /tmp
VOLUME ["/data"]启动容器的时候会帮我们自动的新建
[root@server1 docker]# docker build -t test:v2 . build镜像
Sending build context to Docker daemon 1.043MB
Step 1/4 : FROM busybox
---> 59788edf1f3e
Step 2/4 : COPY testfile /tmp
---> Using cache
---> 712e566b8ab4
Step 3/4 : ADD nginx-1.18.0.tar.gz /tmp
---> Using cache
---> 92c9ba6afa71
Step 4/4 : VOLUME ["/data"]
---> Running in 8362c1b02d90
Removing intermediate container 8362c1b02d90
---> 67fb999a853e
Successfully built 67fb999a853e
Successfully tagged test:v2
[root@server1 docker]# docker run -it --name vm3 test:v2 运行容器
/ # ls
bin data dev etc home proc root sys tmp usr var
/ # cd data/
/data # ls 按Ctrl+pq
通过docker inspect vm3
这个命令看到
容器中的/data目录与宿主机上的一个新建的本地目录发生了联系
进入到这个目录中去
注意:此目录是docker引擎自动帮我们创建出来的 目录名是随机生成的
由于此宿主机的目录名称过长我们可以指定宿主机的挂载目录
ENV:
设置环境变量,变量可以被后续的指令使用(不是必须的)
ENV HOSTNAME server1.example.com
EXPOSE:
如果容器运行应用服务,可以把服务的端口暴露出去
WOEKDIR:为RUN CMD ENTRYPOINT ADD COPY
指令设置镜像中的当前工作目录(类似于cd ),如果目录不存在会自动创建
RUN:
在容器中运行命令并创建新的镜像层,常用于安装包
每一个RUN指令都会构建一层镜像层 尽可能将 多个命令放在一个RUN指令下RUN yum install -y vim
CMD与ENTRYPOINT
:这两个指令都是用于设置容器启动后执行的命令
但CMD
会被docker run
后面的命令覆盖,而ENTRYPOINT不会被忽略,一定会被执行
docker run
后面的参数可以传递给ENTRYPOINT
指令当作参数 dockerfile中只能指定一个ENTRYPOINT,
如果指定了很多,只有最后一个有效
CMD
与ENTRYPOINT
(容器启动后要运行的!!)
RUN :
在创建容器的时候!!!(在容器中)
八、shell 和 exec两种书写格式
还原实验环境
shell方式
[root@server1 docker]# docker build -t test:v1 . build镜像
Sending build context to Docker daemon 1.043MB
Step 1/3 : FROM busybox
---> 59788edf1f3e
Step 2/3 : ENV name world
---> [Warning] IPv4 forwarding is disabled. Networking will not work.
---> Running in d3f033d8e5b3
Removing intermediate container d3f033d8e5b3
---> 4cb39d753a41
Step 3/3 : ENTRYPOINT echo "hello, $name"
---> [Warning] IPv4 forwarding is disabled. Networking will not work.
---> Running in 7df04f8d1c74
Removing intermediate container 7df04f8d1c74
---> cec05e974b7a
Successfully built cec05e974b7a
Successfully tagged test:v1
[root@server1 docker]# docker run --rm test
test test:v1
[root@server1 docker]# docker run --rm test:v1 --rm表示一次性容器运行完后自动删除
WARNING: IPv4 forwarding is disabled. Networking will not work.
hello, world
发现有一个报错信息
WARNING: IPv4 forwarding is disabled. Networking will not work.
【警告】Ipv4转发被禁用。网络无法工作
解决报错
[root@server1 docker]# echo "net.ipv4.ip_forward=1" >>/usr/lib/sysctl.d/00-system.conf
[root@server1 docker]# systemctl restart network && systemctl restart docker 重启网络和docker服务
[root@server1 docker]# docker rmi -f test:v1
Untagged: test:v1
Deleted: sha256:cec05e974b7aa54f11529816058484f2853f41588a20f3afc7a22b4156e248d2
Deleted: sha256:4cb39d753a4163e290a3711cdd4af78ff7e4d2bb25e6f04f2f79ada5e157a4a7
[root@server1 docker]# docker build -t test:v1 .
Sending build context to Docker daemon 1.043MB
Step 1/3 : FROM busybox
---> 59788edf1f3e
Step 2/3 : ENV name world
---> Running in 7560e53aaf90
Removing intermediate container 7560e53aaf90
---> 0cd9082bf428
Step 3/3 : ENTRYPOINT echo "hello, $name"
---> Running in 8051a1d492ed
Removing intermediate container 8051a1d492ed
---> 1ce59a139d4d
Successfully built 1ce59a139d4d
Successfully tagged test:v1
[root@server1 docker]# docker run --rm test:v1
hello, world
exec的方式
[root@server1 docker]# vim Dockerfile
[root@server1 docker]# cat Dockerfile
FROM busybox
ENV name world
ENTRYPOINT [ "/bin/echo", "hello, $name"]
[root@server1 docker]# docker build -t test:v1 .
Sending build context to Docker daemon 1.043MB
Step 1/3 : FROM busybox
---> 59788edf1f3e
Step 2/3 : ENV name world
---> Using cache
---> 0cd9082bf428
Step 3/3 : ENTRYPOINT [ "/bin/echo", "hello, $name"]
---> Running in a3377acff8cb
Removing intermediate container a3377acff8cb
---> 44beb8a995c8
Successfully built 44beb8a995c8
Successfully tagged test:v1
[root@server1 docker]# docker run --rm test:v1 发现无法解析
hello, $name
原因: shell格式底层会掉用/bin/sh -c 来执行命令,可以解析变量,而exec格式不会
[root@server1 docker]# vim Dockerfile
[root@server1 docker]# cat Dockerfile
FROM busybox
ENV name world
ENTRYPOINT [ "/bin/sh","-c", "echo hello, $name"] 更改参数
[root@server1 docker]# docker build -t test:v2 .
Sending build context to Docker daemon 1.043MB
Step 1/3 : FROM busybox
---> 59788edf1f3e
Step 2/3 : ENV name world
---> Using cache
---> 0cd9082bf428
Step 3/3 : ENTRYPOINT [ "/bin/sh","-c", "echo hello, $name"]
---> Running in 293880da5f1a
Removing intermediate container 293880da5f1a
---> 1ca30cf45343
Successfully built 1ca30cf45343
Successfully tagged test:v2
[root@server1 docker]# docker run --rm test:v2 成功解析
hello, world
exec格式时,ENTRYPOINT可以通过CMD提供的额外参数,CMD的额外参数可以在容器启动时动态替换,在shell格式时ENTRYPOINT会忽略任何CMD或docker run提供的参数
比较CMD和ENTRYPOINT
[root@server1 docker]# vim Dockerfile
[root@server1 docker]# cat Dockerfile
FROM busybox
ENV name world
ENTRYPOINT [ "/bin/echo", "hello"]
CMD ["world"]
[root@server1 docker]# docker build -t test:v
v1 v2
[root@server1 docker]# docker build -t test:v3 .
Sending build context to Docker daemon 1.043MB
Step 1/4 : FROM busybox
---> 59788edf1f3e
Step 2/4 : ENV name world
---> Using cache
---> 0cd9082bf428
Step 3/4 : ENTRYPOINT [ "/bin/echo", "hello"]
---> Running in dfb24dc8efcf
Removing intermediate container dfb24dc8efcf
---> 59ac62c43932
Step 4/4 : CMD ["world"]
---> Running in c555f71b9bc6
Removing intermediate container c555f71b9bc6
---> 785d7db92201
Successfully built 785d7db92201
Successfully tagged test:v3
[root@server1 docker]# docker run --rm test:v3
hello world
[root@server1 docker]# docker run --rm test:v3 westos 覆盖了dockerfile CMD后面的值
hello westos
[root@server1 docker]# cat Dockerfile
FROM busybox
ENV name world
ENTRYPOINT [ "/bin/echo", "hello"]
CMD ["world"]