第一章 Docker安装与优化
1.1 使用阿里源安装
由于GFW的原因,可能会导致安装失败,建议使用国内镜像源。
#卸载旧版本 yum remove docker* -y yum install -y yum-utils device-mapper-persistent-data lvm2 yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo yum makecache fast yum -y install docker-ce # 默认安装最新稳定版本,可通过查询存储库可用版本,进行指定版本进行安装。 # yum list docker-ce --showduplicates | sort -r # yum -y install docker-ce-18.09.1
1.2 离线安装
wget -c https://download.docker.com/linux/static/stable/x86_64/docker-19.03.9.tgz -P /tmp/ tar xf /tmp/docker-19.03.9.tgz -C /tmp/ cp -rf /tmp/docker/* /usr/bin/ cat >/usr/lib/systemd/system/docker.service<1.3 配置优化
cat >>/etc/sysctl.conf<https://docs.docker.com/engine/reference/commandline/dockerd/#daemon
配置说明:
- registry-mirrors
用于指定镜像加速地址- native.cgroupdriver
指定cgroup驱动程序为system, kubernetes中node组件kubelet默认使用system驱动。
https://kubernetes.io/docs/setup/production-environment/container-runtimes/#cgroup-drivers- max-concurrent-downloads
镜像由多层文件组层,指定拉取镜像的最大线程数,加速镜像拉取速度。- storage-driver
Docker推荐使用overlay2作为存储驱动- insecure-registries
无需TLS检查的镜像仓库- data-root
数据存储目录第二章 容器管理
2.1 容器管理指令
2.1.1 docker run 创建并运行容器
# 常用参数 -i, --interactive 交互式 -t, --tty 分配一个伪终端 -e, --env list 设置环境变量 -d, --detach 后台运行容器 -p, --publish list 映射端口到主机指定端口 -P, --publish-all 映射EXPOSE端口到主机随机端口 --restart string 容器退出时重启策略,默认no,可选always|on-failure --name string 指定容器名称 --network network 指定容器连接的网络 --ip string 指定容器的ip地址,只能用于自定义网络 -h, --hostname string 指定容器hostname -v, --volume list 绑定挂载卷 # 资源限制参数 -m, --memory bytes 容器可以使用的最大内存 --memory-reservation bytes 为容器预留内存 --memory-swap bytes swap使用限制最大内存 --oom-kill-disable 禁用OOM Killer -c, --cpu-shares int CPU共享(相对权重) --cpus decimal 使用的CPU数量 --cpuset-cpus string 独占cpu, 设置容器执行在具体的某个或者某几个核上 --device-read-bps list 限制从设备读取的速率 --device-read-iops list 限制从设备读取IO速率 --device-write-bps list 限制设备的写入速率 --device-write-iops list 限制从设备写入的IO速率
示例1:运行一个centos,并查看ip地址,ctrl+D退出容器终端
[root@docker-test-11142 ~]# docker run -it --name centos centos /bin/bash
[root@a54af4106e04 /]# ip a
1: lo:mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
6: eth0@if7:mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever示例二:运行nginx:1.17,设置随docker daemon重启而重启,指定容器名称nginx-test,80端口映射到主机的8080端口
docker run -d --name nginx-test -p 8090:80 --restart=always nginx:1.17
查看后台运行的容器[root@docker-test-11142 ~]# docker ps -l
获取宿主机ip地址
ConTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fc25638a8a83 nginx “/docker-entrypoint.…” 35 seconds ago Up 34 seconds 0.0.0.0:8080->80/tcp nginx-test[root@docker-test-11142 ~]# hostname -I
访问8080端口测试
10.10.11.142 172.17.0.1[root@docker-test-11142 ~]# curl 10.10.11.142:8080
Welcome to nginx! Welcome to nginx!If you see this page, the nginx web server is successfully installed and working. Further configuration is required.
For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.Thank you for using nginx.
退出查看后台运行的容器[root@docker-test-11142 ~]# docker ps -a
ConTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fc25638a8a83 nginx “/docker-entrypoint.…” 10 minutes ago Up 10 minutes 0.0.0.0:8080->80/tcp nginx-test示例4: 内存限制,允许容器最多使用100M内存,并禁用OOM Killer
docker run -d --name centos-noom -m 100m --oom-kill-disable harbor.ioiofast.com/test/centos:mentest ./men 200
查看centos容器资源使用情况, 可以看出内存跑满后,容器并未退出docker stats --all --format “table {{.Container}}t{{.CPUPerc}}t{{.MemUsage}}” centos-noom
ConTAINER CPU % MEM USAGE / LIMIT
centos 0.00% 100MiB / 100MiB示例5: 内存限制,允许容器最多使用100M内存
docker run -d --name centos-oom -m 100m harbor.ioiofast.com/test/centos:mentest ./men 200
容器centos-oom运行起来后,直接就退出状态了[root@docker-test-11142 ~]# docker ps -a -f name=centos-oom
ConTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4f76d939cd3e harbor.ioiofast.com/test/centos:mentest “./men 200” 2 minutes ago Exited (137) 2 minutes ago centos-oom示例6:cpu限制,允许容器最多使用0.5个cpu
docker run -it --cpus=1 --rm --name centos_cpu harbor.ioiofast.com/test/centos:mentest bash
打开另一终端查看容器资源使用状态
cat /dev/urandom >/dev/nulldocker stats --format “table {{.Name}}t{{.CPUPerc}}t{{.MemUsage}}” --no-stream
NAME CPU % MEM USAGE / LIMIT
centos_cpu 100.80% 904KiB / 7.795GiB
centos 0.00% 100MiB / 100MiB2.1.3 docker exec 在运行的容器中执行命令
# 常用参数 -i, --interactive 交互式 -t, --tty 分配一个伪终端
示例:进入nginx-test容器,修改index.html内容
修改主页内容root@fc25638a8a83:/# date >/usr/share/nginx/html/index.html
访问测试
root@fc25638a8a83:/# curl 127.0.0.1
Sun Nov 1 08:00:16 UTC 2020
root@fc25638a8a83:/# exit
exit[root@docker-test-11142 ~]# curl 10.10.11.142:8080
Sun Nov 1 08:00:16 UTC 20202.1.4 docker ps 列出容器
# 常用参数 -a, --all 查看所有容器 -n, --last int 查看最近n个容器 -l, --latest 查看最近运行的一个容器 -q, --quiet 之查看ID -f, --filter filter 根据所提供的条件过滤输出 --format string 使用Go模板的漂亮打印容器
示例1:指定显示模版
可用占位符: https://docs.docker.com/engine/reference/commandline/ps/#formatting[root@docker-test-11142 ~]# docker ps --format “table {{.ID}}t{{.Names}}t{{.Ports}}”
ConTAINER ID NAMES PORTS
2d97dc7cce91 recursing_chaum
fc25638a8a83 nginx-test 0.0.0.0:8080->80/tcp示例2:过滤容器名为nginx-test的容器
支持的过滤器: https://docs.docker.com/engine/reference/commandline/ps/#filtering[root@docker-test-11142 ~]# docker ps -f name=nginx-test
ConTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fc25638a8a83 nginx “/docker-entrypoint.…” 30 minutes ago Up 30 minutes 0.0.0.0:8080->80/tcp nginx-test2.1.4 其他管理指令
docker create / rm / start / stop / restart
create 创建一个待启动的容器
rm 删除容器
-f : 强制删除正常运行的容器
-v : 删除与容器关联的匿名卷start 启动容器
stop 停止容器
restart 重启容器
docker pause / unpause
pause 暂停容器
unpause 恢复暂停的容器
docker cp / logs / stats / inspect /
cp 拷贝文件
示例1:从容器拷贝到宿主
docker cp nginx-test:/etc/nginx/nginx.conf /tmp/nginx.conf
示例2:从宿主拷贝到容器
docker cp /tmp/nginx.conf nginx-test:/etc/nginx/nginx.conflogs 查看容器日志
示例1:实时查看nginx-test的日志
docker logs nginx-test -f
实例2:查看nginx-test最近10条日志
docker logs nginx-test --tail=10stats 查看容器资源使用状态
示例1:格式化查看状态
docker stats --format “table {{.Name}}t{{.CPUPerc}}t{{.MemUsage}}”
使用说明:https://docs.docker.com/engine/reference/commandline/stats/#examplesinspect 查看容器的详细信息
示例1:查看nginx-test分配到的ip
docker inspect nginx-test -f ‘{{.NetworkSettings.Networks.bridge.IPAddress}}’
示例2:查看nginx-test详细的网络信息
docker inspect nginx-test -f ‘{{json .NetworkSettings.Networks}}’第三章 镜像管理
3.1 基本管理命令
images 查看本地镜像 rmi 删除镜像 示例1:删除虚悬镜像 docker rmi $(docker images -qf dangling=true) 示例2:删除本地所有镜像 docker rmi $(docker images -qa) build 构建镜像 示例:从Dockerfile构建 docker build -l test:v1 -f Dockerfile . history 查看镜像构建过程 pull 拉取镜像 示例:拉取私库镜像 docker pull hub.harbor.com/prue:v1 push 上传/推送镜像 示例:docker push hub.harbor.com/prue:v1 save 打包镜像 示例1:打包nginx镜像 docker save -o nginx_latest.tar nginx:latest 示例2:打包并压缩nginx镜像 docker save nginx:latest | gzip > nginx_latest.tar.gz load 导入镜像 示例1: 导入nginx镜像 docker load -i nginx_latest.tar 示例2:导入nginx镜像压缩包 gunzip -c nginx_latest.tar.gz | docker load tag 给镜像打上标签 用法: docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]第四章 数据持久化
4.1 volumes
Docker管理宿主机文件系统的一部分(/var/lib/docker/volumes)。保存数据的最佳方式。
管理卷
docker volume --help
create 创建卷
inspect 查看卷的详细信息
ls 查看所有卷
prune 删除未使用的卷
rm 删除指定的卷创建一个容器使用卷
docker run -d -v nginx-volume:/usr/share/nginx/html/ --name volume-test nginx
注意: 卷不需要提前创建 查看已创建的卷
等同于
docker run -d --mount type=volume,source=nginx-volume,destination=/usr/share/nginx/html/ --name volume-test nginxdocker volume ls
查看卷的详细信息
DRIVER VOLUME NAME
local nginx-volumedocker volume inspect nginx-volume
修改index.html
[
{
“CreatedAt”: “2020-11-01T20:16:58+08:00”,
“Driver”: “local”,
“Labels”: null,
“Mountpoint”: “/var/lib/docker/volumes/nginx-volume/_data”,
“Name”: “nginx-volume”,
“Options”: null,
“Scope”: “local”
}
]
ls -l /var/lib/docker/volumes/nginx-volume/_data
total 8
-rw-r–r-- 1 root root 494 Sep 29 22:12 50x.html
-rw-r–r-- 1 root root 612 Sep 29 22:12 index.htmlecho “nginx volume” >/var/lib/docker/volumes/nginx-volume/_data/index.html
获取容器volume-test的ipdocker inspect volume-test -f ‘{{.NetworkSettings.Networks.bridge.IPAddress}}’
访问测试
172.17.0.2curl 172.17.0.2
创建httpd容器,挂载nginx-volume卷
nginx volumedocker run -d -v nginx-volume:/usr/local/apache2/htdocs/ --name httpd httpd
获取容器httpd ip,访问测试docker inspect httpd -f ‘{{.NetworkSettings.Networks.bridge.IPAddress}}’
172.17.0.3curl 172.17.0.3
查看容器的挂载信息
nginx volumedocker inspect httpd -f ‘{{json .Mounts}}’|jq
[
{
“Type”: “volume”,
“Name”: “nginx-volume”,
“Source”: “/var/lib/docker/volumes/nginx-volume/_data”,
“Destination”: “/usr/local/apache2/htdocs”,
“Driver”: “local”,
“Mode”: “z”,
“RW”: true,
“Propagation”: “”
}
]4.2 bind mounts
将宿主机上的任意位置的文件或者目录挂载到容器中。
docker run -d --name=nginx-test --mount type=bind,src=/app/wwwroot,dst=/usr/share/nginx/html nginx 等同于 docker run -d --name=nginx-test -v /app/wwwroot:/usr/share/nginx/html nginx # 查看容器的挂载信息 docker inspect nginx-test -f '{{json .Mounts}}'|jq [ { "Type": "bind", "Source": "/app/wwwroot", "Destination": "/usr/share/nginx/html", "Mode": "", "RW": true, "Propagation": "rprivate" } ]4.3 tmpfs
挂载存储在主机系统的内存中,而不会写入主机的文件系统。如果不希望将数据持久存储在任何位置,可以使用tmpfs,同时避免写入容器可写层提高性能。
docker run -d --name=nginx-tmpfs --mount type=tmpfs,tmpfs-size=5M,destination=/usr/share/nginx/html nginx # 查看容器的挂载信息 docker inspect nginx-tmpfs -f '{{json .Mounts}}'|jq [ { "Type": "tmpfs", "Source": "", "Destination": "/usr/share/nginx/html", "Mode": "", "RW": true, "Propagation": "" } ]第五章 容器网络
5.1 bridge 桥接模式
默认网络,Docker启动后创建一个docker0网桥,默认创建的容器也是添加到这个网桥中。
也可以自定义网络,相比默认的具备内部DNS发现,可以通过容器名容器之间网络通信。
创建一个自定义网络
docker network create -d bridge --subnet 172.25.0.0/16 custom
查看自定义网络的详细信息docker network inspect custom
[
{
“Name”: “custom”,
“Id”: “7feba58d8708388ed09aad70714ad18e2d03e3560c4903ef3f0b53c04a4fdc37”,
“Created”: “2020-11-01T21:19:33.040434327+08:00”,
“Scope”: “local”,
“Driver”: “bridge”,
“EnableIPv6”: false,
“IPAM”: {
“Driver”: “default”,
“Options”: {},
“Config”: [
{
“Subnet”: “172.25.0.0/16”
}
]
},
“Internal”: false,
“Attachable”: false,
“Ingress”: false,
“ConfigFrom”: {
“Network”: “”
},
“ConfigOnly”: false,
“Containers”: {},
“Options”: {},
“Labels”: {}
}
]使用自定义网络访问其他容器主机名
docker run -d --name nginx --network=custom nginx
docker run -it --rm --network=custom centos bashping nginx
PING nginx (172.25.0.2) 56(84) bytes of data.
64 bytes from nginx.custom (172.25.0.2): icmp_seq=1 ttl=64 time=0.175 ms
^C
— nginx ping statistics —
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.175/0.175/0.175/0.000 mscurl nginx -I
HTTP/1.1 200 OK
Server: nginx/1.19.3
Date: Sun, 01 Nov 2020 13:23:59 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 29 Sep 2020 14:12:31 GMT
Connection: keep-alive
ETag: “5f7340cf-264”
Accept-Ranges: bytes5.2 host 主机模式
容器不会获得一个独立的network namespace,而是与宿主机共用一个。这就意味着容器不会有自己的网卡信息,而是使用宿主机的。容器除了网络,其他都是隔离的。
示例:运行一个nginx容器
docker run -d --name=nginx-host --network=host nginx # 查看主机Ip hostname -I 10.10.11.142 172.17.0.1 # 访问测试 curl 10.10.11.142 -I HTTP/1.1 200 OK Server: nginx/1.19.3 Date: Sun, 01 Nov 2020 13:01:40 GMT Content-Type: text/html Content-Length: 612 Last-Modified: Tue, 29 Sep 2020 14:12:31 GMT Connection: keep-alive ETag: "5f7340cf-264" Accept-Ranges: bytes # 查看容器网络模式 docker inspect nginx-host -f '{{.HostConfig.NetworkMode}}' host5.3 none 无网络模式
获取独立的network namespace,不能访问外部网络以及其他容器,可用于运行批处理作业.
--network=node5.4 container 共享网络模式
与指定的容器使用同一个network namespace,具有同样的网络配置信息,两个容器除了网络,其他都还是隔离的。
# 运行一个nginx容器 docker run -d --name nginx nginx # 查看容器ip docker inspect nginx -f '{{.NetworkSettings.Networks.bridge.IPAddress}}' # 运行centos容器使用nginx容器的网络 docker run -it --rm --network=container:nginx centos [root@fb0c423553b0 /]# ip a 1: lo:mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 102: eth0@if103: mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever 第六章 Dockerfile定制镜像
6.1 Dockerfile指令
FROM** ** 指定基础镜像
Dockerfile的第一条必须是FROM指令,用来指定要制作的镜像继承自哪个镜像
FROM语法格式为:FROMFROM : FROM : RUN 执行命令
该指令用于执行shell命令,当解析Dockerfile时,遇到RUN指令,Docker会将该指令翻译为如下: /bin/sh -c “XXXXXX”,其中xxxxxx为RUN后面的shell命令
#shell格式
RUN
#exec格式
RUN [“executable”, “param1”, “param2”]EXPOSE 声明容器监听的端口
该指令是声明运行时容器提供服务端口,这只是一个声明,在运行时并不会因为这个声明应用就会开启这个端口的服务
EXPOSE 5000
EXPOSE 80,443COPY 复制文件
该指令将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的<目标路径>位置
COPY package.json /usr/src/app/ADD 高级的复制指令
ADD 指令和 COPY 的格式和性质基本一致。但是在 COPY 基础上增加了一些功能。比如<源路径>可以是一个 URL,<源路径>可以是一个压缩文件(可识别的压缩格式(identity、 gzip、 bzip2或 xz))
ADD nginx.conf /home/
ADD nginx.tar.gz /tmp
ADD http://download.nginx.org/nginx.conf /tmpVOLUME 使用卷挂载
将容器内的数据保存在宿主机上,一般位于docker的数据目录下/var/lib/docker/volumes/
VOLUME /myvolUSER 用户
设置运行镜像时要使用的用户名(或 UID)和可选的用户组(或 GID) ,以及 Dockerfile 中跟随它的任何 RUN、 CMD 和 ENTRYPOINT 指令。
USER 0:0
USER root:rootWORKDIR 工作目录
为RUN、CMD、ENTRYPOINT、COPY和ADD设置工作目录
WORKDIR /a
WORKDIR b
WORKDIR cENV 环境变量
为镜像注入环境变量
ENV MY_NAME=“John Doe”
ENV MY_DOG=Rex The Dog
ENV MY_CAT=fluffyCMD
CMD主要是是用来启动该容器下需要执行的哪个程序,CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。
CMD三种方式
CMD [“executable”,“param1”,“param2”] (exec,首选模式)
CMD [“param1”,“param2”] (极少情况下使用,配合ENTRYPOINT使用)
CMD command param1 param2 (shell form)shell 方式 CMD nginx -g daemon off; exec 方式 CMD ["nginx","-g","daemon off;"]ENTRYPOINT
ENTRYPOINT的最佳用处是设置镜像的主命令,允许将镜像当成命令本身来运行(用CMD提供默认选项), ENTRYPOINT 指令指定的程序可被 docker run 命令行参数中的–entrypoint所覆盖。
ENTRYPOINT的两种方式
ENTRYPOINT [“executable”,“param1”,“param2”]
ENTRYPOINT [“param1”,“param2”]ENTRYPOINT ["ping"] CMD ["-h"]6.1.1 CMD和ENTRYPOINT区别
- CMD和ENTRYPOINT指令都可以用来定义运行容器时所使用的默认命令
- Dockerfile至少指定一个CMD或ENTRYPOINT
- CMD可以用作ENTRYPOINT默认参数,或者用作容器的默认命令
- docker run指定时,将会覆盖CMD
- docker run指定–entrypoint时,将会覆盖ENTRYPOINT
- 如果是可执行文件,希望运行时传参,应该使用ENTRYPOINT
6.2 构建一个nginx镜像
6.2.1 编写Dockerfile
创建一个工作目录
mkdir build-nginx
下载nginx-1.18源码包
cd build-nginxwget http://nginx.org/download/nginx-1.18.0.tar.gz
编写dockerfile
FROM centos:7.8.2003
ADD nginx-1.18.0.tar.gz /tmp/
RUN yum install gcc-c++ zlib-devel pcre-develperl perl-devel make flex bison yajl yajl-devel zlib-devel pcre-devel -y &&
cd /tmp/nginx-1.18.0 &&
./configure --with-threads --with-http_v2_module --with-stream &&
make && make install &&
rm -rf /tmp/nginx* && yum clean all
VOLUME /usr/local/nginx/html
WORKDIR /usr/local/nginx/sbin
EXPOSE 80 443
CMD ["./nginx","-g",“daemon off;”]6.2.2 构建镜像
# --no-cache 不使用构建缓存 docker build -t nginx_v -f Dockerfile .6.2.3 镜像测试
使用nginx_v镜像创建一个容器
docker run -d nginx_v
查看运行状态docker ps -l
访问测试
ConTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
aa23189ffbc7 nginx_v:latest “./nginx -g 'daemon …” 2 seconds ago Up 2 seconds 80/tcp, 443/tcp hardcore_wucurl 172.17.0.4
Welcome to nginx! Welcome to nginx!If you see this page, the nginx web server is successfully installed and working. Further configuration is required.
For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.Thank you for using nginx.
查看卷挂载状态docker inspect aa23189f -f ‘{{json .Mounts}}’|jq
刷新首页文件
[
{
“Type”: “volume”,
“Name”: “2a075f4bd80ffdc531fb52ee4a4427b32e89b6afcca88b236c11c032b7e0b003”,
“Source”: “/var/lib/docker/volumes/2a075f4bd80ffdc531fb52ee4a4427b32e89b6afcca88b236c11c032b7e0b003/_data”,
“Destination”: “/usr/local/nginx/html”,
“Driver”: “local”,
“Mode”: “”,
“RW”: true,
“Propagation”: “”
}
]date >/var/lib/docker/volumes/2a075f4bd80ffdc531fb52ee4a4427b32e89b6afcca88b236c11c032b7e0b003/_data/index.html
curl 172.17.0.4
Sun Nov 1 23:24:01 CST 20206.3 Dockerfile 多阶段构建
6.3.1 传统构建一个C程序
vim men.c #include#include #include #define UNIT (1024*1024) int main(int argc, char *argv[]) { long long i = 0; int size = 0; if (argc != 2) { printf(" === argc must 2n"); return 1; } size = strtoull(argv[1], NULL, 10); if (size == 0) { printf(" argv[1]=%s not goodn", argv[1]); return 1; } char *buff = (char *) malloc(size * UNIT); if (buff) printf(" we malloced %d Mbn", size); buff[0] = 1; for (i = 1; i < (size * UNIT); i++) { if (i%1024 == 0) buff[i] = buff[i-1]/8; else buff[i] = i/2; } pause(); } cat >Dockerfile.v1< 6.3.2 使用多阶段构建
cat >Dockerfile.v2<6.4 Dockerfile 最佳实践
https://docs.docker.com/develop/develop-images/dockerfile_best-practices/
- 减少镜像层:一次RUN指令形成新的一层,尽量Shell命令都写在一行,减少镜像层。
- 优化镜像大小:一次RUN形成新的一层,如果没有在同一层删除,无论文件是否最后删除,都会带到下一层,所以要在每一层清理对应的残留数据,减小镜像大小。
- 使用构建缓存:镜像分层是子层依赖父层, 对应到镜像构建缓存机制中, 如果某一层未命中缓存, 那么其剩下的层都不会使用缓存. 因此如果需要最大利用缓存机制, 推荐将变化频度低的指令尽量放上面, 变化频度高的指令放下面。
- 多阶段构建:代码编译、部署在一个Dockerfile完成,只会保留部署阶段产生数据。
- 选择最小的基础镜像
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)