目录
一、docker容器(Container)简介
1、什么是docker
【docker|自动化运维之docker上——docker简介、docker的安装、docker镜像】2、传统虚拟化与docker的差别?
3、docker容器的优势
4、容器是如何工作的
二、docker的安装
1、配置docker的软件源
2、安装docker-ce
3、启动docker
4、查看docker信息
5、docker中镜像的查询及下载
6、docker中镜像的使用
7、测试
三、docker的镜像
1、镜像的分层结构
2、镜像的构建——三部曲
(1)容器的创建(运行)与删除
(2)容器的更改
容器删除后重新启动,之前创建的文件没了。因此需要保存对容器的更改。
(3)镜像的删除
3、镜像的构建——Dockerfile文件
(1)编写Dockerfile文件
(2)查看镜像
(3)镜像的缓存特性
4、Dockerfile详解
(1)Dockerfile官方文档:
(2)Dockerfile常用指令
(3)Dockerfile实践
5、镜像的优化
1、镜像的优化原则
2、优化实验一:减少镜像的层数,清理镜像构建的中间产物对构建的影响。
3、优化实验二:使用多阶段构建镜像
4、 优化实验三:选择最精简的基础镜像,使用多阶段构建镜像
四、docker命令的常用参数
五、本章总结
一、docker容器(Container)简介
1、什么是docker
文章图片
Docker就好比传统的货运集装箱
文章图片
Docker是管理容器的引擎。 Docker为应用打包、部署平台,而非单纯的虚拟化技术。2、传统虚拟化与docker的差别?
文章图片
文章图片
3、docker容器的优势
对于开发人员:Build once、Run anywhere。4、容器是如何工作的
对于运维人员:Configure once、Run anything。
客户端——>Docker引擎——>仓库
文章图片
二、docker的安装 1、配置docker的软件源
文章图片
curl https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -o docker-ce.repo
文章图片
修改软件docker软件源,只保留上一步中下载的第一个软件源路径,并取消校验。
文章图片
这样配置的docker软件源没有解决依赖性,因此还需要进一步配置centos源20
文章图片
wget https://mirrors.aliyun.com/repo/Centos-7.repo
文章图片
对Centos-7.repo软件源做如下更改(其余部分删除)
文章图片
软件源配置完成后,更新软件源列表,即可看到docker软件仓库和centos7的软件仓库。
2、安装docker-ce
yum install -y docker-ce
文章图片
注意:这里有个小建议。在安装时可以把从外部下载的依赖包保存在自己的软件源中,再次安装时可以从自己的软件源中调取。否则每次都从网络上下载依赖包会比较麻烦。
解决办法:更改yum配置,保存缓存,那么在安装完软件后会将软件包保存在指定目录下。
文章图片
3、启动docker
systemctl enable --now docker#启动并设置docker开机自启动
4、查看docker信息
docker info#查看docker信息
文章图片
5、docker中镜像的查询及下载
docker search yakexi007#查询容器
NAMEDESCRIPTIONSTARSOFFICIALAUTOMATED
yakexi007/game20480
yakexi007/mario0
yakexi007/nginx0
yakexi007/base-debian100
docker pull yakexi007/game2048#拉取容器中的镜像
docker images#查看本地有哪些镜像
文章图片
文章图片
注意:docker的所有数据全部保存在目录中。6、docker中镜像的使用
文章图片
docker run -d --name demo -p 80:80 yakexi007/game2048#运行镜像
-d:打入后台; --name:项目名取为demo(加上名字后方便操作,不加时会随机创建一个名称);
-p:端口映射(宿主机的80端口映射到docker的80端口)
docker ps#查看正在运行的镜像
文章图片
7、测试
在浏览器中访问虚拟机IP,可以访问正在运行中的docker
文章图片
三、docker的镜像 1、镜像的分层结构
文章图片
共享宿主机的kernel;base镜像提供的是最小的Linux发行版;同一docker主机支持运行多种Linux发行版;采用分层结构的最大好处是:共享资源
文章图片
Copy-on-Write 可写容器层;容器层以下所有镜像层都是只读的;docker从上往下依次查找文件;容器层保存镜像变化的部分,并不会对镜像本身进行任何修改;一个镜像最多127层。2、镜像的构建——三部曲
Docker commit构建新镜像三部曲:先拉取一个新镜像busybox
运行容器;修改容器;将容器保存为新的镜像(运行——>修改——>提交)
文章图片
(1)容器的创建(运行)与删除
运行busybox镜像,镜像在运行时会占用终端,并且可以在shell中交互创建文件。
docker run -it --name demo busybox#运行容器
文章图片
重新启动容器,已经在后台运行,通过“attach”进入容器内部后,可以通过
将容器打入后台。
docker start demo#启动容器 docker attach demo#提取正在后台运行的容器
文章图片
关闭容器,将会把后台运行的容器关闭,重新查看进程,确认demo容器已经不在后台运行。
docker stop demo#关闭容器
文章图片
(2)容器的更改
容器删除后重新启动,之前创建的文件没了。因此需要保存对容器的更改。
文章图片
进入busybox容器内部,创建一个file1文件。退出后将更改提交(commit),并重新命名为“demo:v1”那么“demo:v1”就是在“busybox”的基础上新加了一层。通过docker history命令可以查看到两个容器的差别。
文章图片
删除掉现有的容器demo,进入新的容器“demo:v1”后,可以看到之前的更改了。
文章图片
(3)镜像的删除
镜像的删除有两种方法,可以指定镜像名称,也可以指定镜像ID
docker rmi demo:v1#指定镜像名称 docker rmi f4ac6fa47a2a#指定镜像ID
文章图片
此方法的缺点: 效率低、可重复性弱、容易出错;使用者无法对镜像进行审计,存在安全隐患3、镜像的构建——Dockerfile文件
原理:Dockerfile文件中命令的每一层都是逐层提交的。即将构建的操作逻辑以文件的形式表现出来。
文章图片
(1)编写Dockerfile文件
vim Dockerfile#编辑Dockerfile FROM busybox RUN touch file1 Run echo westos > index.html docker build -t demo:v1 .#构建Dockerfile .表示构建的所有数据来自于当前目录
文章图片
(2)查看镜像
通过Dockerfile文件生成镜像后,如果只是要进入查看后退出,可以按照如下命令。
docker run--rm -it demo:v1#退出时删除容器
通过“docker history”可以看到Dockerfile文件中每一步的执行细节。退出容器后删除,再次查看进程已经查不到了。
文章图片
(3)镜像的缓存特性
在上一个Dockerfile的最后再创建一个文件file2,构建时可以看到,前边几步在构建“demo:v1”时已经执行过了,所以构建“demo:v2”时不会再次执行,会使用上一次执行的缓存。
文章图片
4、Dockerfile详解 (1)Dockerfile官方文档:
Docker Documentation | Docker DocumentationHome page for Docker's documentation
文章图片
https://docs.docker.com/
(2)Dockerfile常用指令
COPY指令:
FROM 指定base镜像,如果本地不存在会从远程仓库下载。 MAINTAINER 设置镜像的作者,比如用户邮箱等。 COPY 把文件从build context复制到镜像
支持两种形式:COPY src dest 和 COPY ["src", "dest"]
src必须指定build context中的文件或目录
ADD 用法与COPY类似,不同的是src可以是归档压缩文件,文件会被自动解压到dest,也可以自动下载URL并拷贝到镜像:
ADD html.tar /var/www
ADD http://ip/html.tar /var/www
ENV 设置环境变量,变量可以被后续的指令使用:
ENV HOSTNAME sevrer1.example.com
EXPOSE 如果容器中运行应用服务,可以把服务端口暴露出去:
EXPOSE 80
VOLUME 申明数据卷,通常指定的是应用的数据挂在点:
VOLUME ["/var/www/html"]
WORKDIR 为RUN、CMD、ENTRYPOINT、ADD和COPY指令设置镜像中的当前工作目录,如果目录不存在会自动创建。 RUN 在容器中运行命令并创建新的镜像层,常用于安装软件包:
RUN yum install -y vim
CMD 与 ENTRYPOINT 这两个指令都是用于设置容器启动后执行的命令,但CMD会被docker run后面的命令行覆盖,而ENTRYPOINT不会被忽略,一定会被执行。
docker run后面的参数可以传递给ENTRYPOINT指令当作参数。
Dockerfile中只能指定一个ENTRYPOINT,如果指定了很多,只有最后一个有效。
注意:COPY指令执行时,目标文件只能用相对路径,不能用绝对路径。因此要处理的文件应该和Dockerfile文件放在同一目录下。
vim Dockerfile#编辑Dockerfile文件 FROM busybox COPY index.html /#COPY命令 docker build -t demo:v1 .#构建为demo:v1 docker history demo:v1#查看demo:v1的构建步骤 docker run --rm -it demo:v1#仅查看容器demo:v1的执行结果
文章图片
ADD指令:
此例中,由于所有指令都是基于第一步“FROM busybox”的镜像,如果busybox镜像中不含有该指令,那么将无法执行。对压缩文件来说,busybox中如果没有tar或者gzip命令,将无法处理压缩文件。因此引入“ADD”指令,执行后可以将压缩文件直接解压成目录。
注意:原文件可以来自本机,也可以来自网络
cat Dockerfile FROM busybox COPY index.html / ADD nginx-1.20.2.tar.gz / docker build -t demo:v2 . docker history demo:v2 docker run --rm -it demo:v2#仅执行,不构建
文章图片
ENV指令:
设置环境变量,变量可以被后续的指令使用
文章图片
EXPOSE指令:
一般在docker中封装了一些服务,EXPOSE用于将这些服务的端口设置成对外开放。
文章图片
以超级玛丽游戏为例:
docker search yakexi007#查找镜像 NAMEDESCRIPTIONSTARSOFFICIALAUTOMATED yakexi007/game20480 yakexi007/mario0 yakexi007/nginx0 yakexi007/base-debian100 yakexi007/base-debian110 docker pull yakexi007/mario#拉取镜像 docker history yakexi007/mario:latest#查看此镜像的详细信息 docker run -d --name demo -p 80:8080 yakexi007/mario #后台运行,并将镜像中的8080端口映射为宿主机的80端口
文章图片
后台运行后,在浏览器访问宿主机的80时,实际上访问的是容器内的8080。可以看到正在运行的镜像。
文章图片
VOLUME指令:
申明数据卷,通常指定的是应用的数据挂载点。用于分离容器和数据的,可以是本地,也可以是远程。(相当于数据直接写入宿主机)
由于容器的文件系统是比较慢的,因此通过此方式,将容器中的文件直接挂载到宿主机中,和宿主机中的文件系统保持一致,可以加快文件读写速度。
cat Dockerfile FROM busybox VOLUME /data#创建卷 docker build -t demo:v3 .#构建为demo:v3
文章图片
docker history demo:v3 docker run -it --name demo1 demo:v3#运行容器并命名为demo1
运行容器后,在卷目录“/data”下新建文件file1,可以查看到卷中内容已发生改变。
文章图片
docker inspect demo1#查看demo1的详细信息
表示宿主机中的这个目录实际上挂载的是容器中的“/data”目录下。
文章图片
进入此目录下,可以看到之前在容器内创建的文件。且映射的这两个目录是同步的。在宿主机的此目录下创建file2,重新进土容器后,也可以在该卷中看到file2.
文章图片
VOLUME的删除:删除容器时,创建的卷不会一起删掉,因此需要单独删除
[root@server1 docker]# docker volume ls DRIVERVOLUME NAME localbdf969483abfb346f3f51ae50655cc4949fc521a5696a7ee043e9b59163c439a [root@server1 docker]# docker volume rm bdf969483abfb346f3f51ae50655cc4949fc521a5696a7ee043e9b59163c439a
文章图片
WORKDIR指令:
为RUN、CMD、ENTRYPOINT、ADD和COPY指令设置镜像中的当前工作目录,如果目录不存在会自动创建。(一般用户切换路径)RUN指令:
在容器中运行命令并创建新的镜像层,常用于安装软件包:CMD 与 ENTRYPOINT 指令:
RUN yum install -y vim
cat Dockerfile FROM busybox CMD echo "hello world"#CMD指令 docker build -t demo:v4 .#构建demo:v4 docker run --rm demo:v4#运行后删除(仅查看运行结果) hello world#运行结果
CMD里可以写多个,但只有最后一个生效。
文章图片
书写格式:一般有shell和exec两种书写格式。
Shell和exec格式的区别为:
ENTRYPOINT echo "hello, $name"
Shell格式底层会调用/bin/sh -c来执行命令,可以解析变量,而下面的exec格式不会:ENTRYPOINT ["/bin/echo", "hello, $name"]
需要改写成以下形式:ENTRYPOINT ["/bin/sh", "-c", "echo hello, $name"]
# cat Dockerfile FROM busybox CMD echo "hello world"#shell格式 CMD echo "hello $hostname"#shell格式(解析变量) CMD ["/bin/sh", "-c", "echo hello $hostname"]#exec格式
CMD 与 ENTRYPOINT 区别:已CMD命令结尾时,Dockerfile默认输出为“hello world”。先构建,再运行,在运行时、传入参数“linux”,这个参数将会覆盖原文件中的CMD命令“world”,输出变为“hello linux”。
一般情况下,两个命令可以相互替换。区别在于,CMD可以被覆盖而ENTRYPOINT不能被覆盖。
[root@server1 docker]# cat Dockerfile FROM busybox ENTRYPOINT ["/bin/echo", "hello"] CMD ["world"] [root@server1 docker]# docker build -t demo:v1 .#构建 [root@server1 docker]# docker run --rm demo:v1#运行 hello world [root@server1 docker]# docker run --rm demo:v1 linux#运行时传参 hello linux
文章图片
一般要进入某个容器而不运行时,可以在运行命令的最后加上“bash”,则会替换掉原本的CMD命令。(3)Dockerfile实践
docker run --rm -it demo:v3 docker run --rm -it demo:v3 bash
#Dockerfile文件内容 #vim Dockerfile 1 FROM centos:7 2 ADD nginx-1.20.2.tar.gz /mnt 3 WORKDIR "/mnt/nginx-1.20.2" 4 RUN yum install -y gcc make pcre-devel zlib-devel 5 RUN ./configure --prefix=/usr/local/nginx 6 RUN make 7 RUN make install 8 EXPOSE 80 9 VOLUME /usr/local/nginx/html 10 CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off; "]
docker build -t demo:v1 .#构建 docker run -d --name demo demo:v1#运行[root@server1 docker]# docker ps#查看是否运行 CONTAINER IDIMAGECOMMANDCREATEDSTATUSPORTSNAMES 8b6a5b3e6579demo:v1"/usr/local/nginx/sb…"6 seconds agoUp 6 seconds80/tcpdemo[root@server1 docker]# docker inspect demo | grep IPAddress#查看容器详细信息 "SecondaryIPAddresses": null, "IPAddress": "172.17.0.2", "IPAddress": "172.17.0.2",[root@server1 docker]# curl 172.17.0.2#测试
Welcome to nginx! - 锐客网 body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif;
文章图片
文章图片
因为有卷VOLUME的存在,所以可以直接更改宿主机的发布目录。发布目录可以通过“docker inspect demo”查找到。更改发布文件后,再次访问nginx的IP,可以看到修改成功。
文章图片
5、镜像的优化 1、镜像的优化原则
2、优化实验一:减少镜像的层数,清理镜像构建的中间产物对构建的影响。
选择最精简的基础镜像 减少镜像的层数 清理镜像构建的中间产物 注意优化网络请求 尽量去用构建缓存 使用多阶段构建镜像
在上一步实验的基础上做如下更改:
#编辑Dockerfile文件 # vim Dockerfile 1 FROM centos:7 2 ADD nginx-1.20.2.tar.gz /mnt 3 WORKDIR "/mnt/nginx-1.20.2" 4 RUN yum install -y gcc make pcre-devel zlib-devel && ./configure --prefix=/usr/local/nginx && make && make install && rm -fr /mnt/nginx-1.20.2 5 EXPOSE 80 6 VOLUME /usr/local/nginx/html 7 CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off; "]
优化后的容器为demo:v2,和未优化的demo:v1相比,占用空间有所减少。
文章图片
3、优化实验二:使用多阶段构建镜像
以下为例,第一阶段构建,构建完成后将产生的二进制文件直接复制到“/usr/local/nginx”目录下。
#编辑Dockerfile文件 #vim Dockerfile 1 FROM centos:7 as build 2 ADD nginx-1.20.2.tar.gz /mnt 3 WORKDIR "/mnt/nginx-1.20.2" 4 RUN yum install -y gcc make pcre-devel zlib-devel && ./configure --prefix=/usr/local/nginx && make && make install && rm -fr /mnt/nginx-1.20.2 5 6 7 FROM centos:7 8 COPY --from=build /usr/local/nginx /usr/local/nginx 9 EXPOSE 80 10 VOLUME /usr/local/nginx/html 11 CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off; "]
重新构建的镜像命名为“demo:v3”,占用空间进一步减小。
文章图片
4、 优化实验三:选择最精简的基础镜像,使用多阶段构建镜像
注意:这里用到的nginx为1.18.0版本的,所以在执行前需要先拉取这个版本的nginx
#编辑Dockerfile文件 #vim Dockerfile1 FROM nginx:1.18.0 as base 2 3 # https://en.wikipedia.org/wiki/List_of_tz_database_time_zones 4 ARG TIME_ZONE 5 6 RUN mkdir -p /opt/var/cache/nginx && \ 7cp -a --parents /usr/lib/nginx /opt && \ 8cp -a --parents /usr/share/nginx /opt && \ 9cp -a --parents /var/log/nginx /opt && \ 10cp -aL --parents /var/run /opt && \ 11cp -a --parents /etc/nginx /opt && \ 12cp -a --parents /etc/passwd /opt && \ 13cp -a --parents /etc/group /opt && \ 14cp -a --parents /usr/sbin/nginx /opt && \ 15cp -a --parents /usr/sbin/nginx-debug /opt && \ 16cp -a --parents /lib/x86_64-linux-gnu/ld-* /opt && \ 17cp -a --parents /lib/x86_64-linux-gnu/libpcre.so.* /opt && \ 18cp -a --parents /lib/x86_64-linux-gnu/libz.so.* /opt && \ 19cp -a --parents /lib/x86_64-linux-gnu/libc* /opt && \ 20cp -a --parents /lib/x86_64-linux-gnu/libdl* /opt && \ 21cp -a --parents /lib/x86_64-linux-gnu/libpthread* /opt && \ 22cp -a --parents /lib/x86_64-linux-gnu/libcrypt* /opt && \ 23cp -a --parents /usr/lib/x86_64-linux-gnu/libssl.so.* /opt && \ 24cp -a --parents /usr/lib/x86_64-linux-gnu/libcrypto.so.* /opt && \ 25cp /usr/share/zoneinfo/${TIME_ZONE:-ROC} /opt/etc/localtime 26 27 FROM gcr.io/distroless/base-debian10 28 29 COPY --from=base /opt / 30 31 EXPOSE 80 443 32 33 ENTRYPOINT ["nginx", "-g", "daemon off; "]
修改完Dockerfile文件后,构建为“demo:v4”后测试。可以看到此优化方法构建的镜像"demo:v4"占用空间已经大大减小。
docker build -t demo:v4 .#构建 docker run -d --name demo demo:v4#启动[root@server1 docker]# docker ps#查看容器进程 CONTAINER IDIMAGECOMMANDCREATEDSTATUSPORTSNAMES 715599f41644demo:v4"nginx -g 'daemon of…"2 minutes agoUp 2 minutes80/tcp, 443/tcpdemo
文章图片
测试:可以正常访问nginx
文章图片
四、docker命令的常用参数五、本章总结 1、在安装好docker后,查看docker信息。显示docker的网桥连接有问题,这是因为火墙权限引起的。
docker search busybox(镜像名) 查询镜像 docker pull busybox(镜像名) 拉取镜像 docker images 显示所有镜像
docker ps 显示后台运行的镜像 docker run -d --name demo -p 80:80 yakexi007/game2048(镜像名) 运行镜像 docker rm -f demo 删除镜像 docker historyyakexi007/game2048(镜像名) 查看镜像的构建历史 docker inspect yakexi007/game2048:latest(镜像名) 查看镜像的具体信息 docker container prune 删除已经退出的容器 docker load -i base-debian10.tar (镜像名) 导入本地镜像 docker tag gcr.io/distroless/base-debian10 zzh981030/base-debian10:latest 重新给镜像打标签
文章图片
文章图片
解决办法:手动设置网桥选项
#编辑system配置文件 [root@server2 ~]# vim /etc/sysctl.d/docker.conf#system内容如下 [root@server2 ~]# cat /etc/sysctl.d/docker.conf net.bridge.bridge-nf-call-iptables = 1 net.bridge.bridge-nf-call-ip6tables = 1#重新载入system配置,使之生效 [root@server2 ~]# sysctl --system net.bridge.bridge-nf-call-iptables = 1 net.bridge.bridge-nf-call-ip6tables = 1
文章图片
再次查看,已没有此报错
文章图片
推荐阅读
- nginx|Nginx优化与防盗链
- 软件测试|自动化测试平台设计开发经验
- 软件测试|手把手教你设计接口自动化测试用例(根据接口信息设计测试用例)
- 云原生微服务技术趋势解读
- 韵达基于云原生的业务中台建设 | 实战派
- python|8. 文件系统——文件的删除、移动、复制过程以及链接文件
- 运维|如何限制IP 通过 SSH连接服务器
- 运维|Linux 禁止用户或 IP通过 SSH 登录