第一章 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
配置说明:
第二章 容器管理
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:
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:
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
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
10.10.11.142 172.17.0.1
[root@docker-test-11142 ~]# curl 10.10.11.142:8080
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
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
[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/null
docker 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 / 100MiB
2.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 2020
2.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-test
2.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.conf
logs 查看容器日志
示例1:实时查看nginx-test的日志
docker logs nginx-test -f
实例2:查看nginx-test最近10条日志
docker logs nginx-test --tail=10
stats 查看容器资源使用状态
示例1:格式化查看状态
docker stats --format “table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}”
使用说明:https://docs.docker.com/engine/reference/commandline/stats/#examples
inspect 查看容器的详细信息
示例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 nginx
docker volume ls
DRIVER VOLUME NAME
local nginx-volume
docker volume inspect nginx-volume
[
{
“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.html
echo “nginx volume” >/var/lib/docker/volumes/nginx-volume/_data/index.html
docker inspect volume-test -f ‘{{.NetworkSettings.Networks.bridge.IPAddress}}’
172.17.0.2
curl 172.17.0.2
nginx volume
docker run -d -v nginx-volume:/usr/local/apache2/htdocs/ --name httpd httpd
docker inspect httpd -f ‘{{.NetworkSettings.Networks.bridge.IPAddress}}’
172.17.0.3
curl 172.17.0.3
nginx volume
docker 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": "rpr\ivate"
}
]
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 bash
ping 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 ms
curl 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: bytes
5.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}}'
host
5.3 none 无网络模式
获取独立的network namespace,不能访问外部网络以及其他容器,可用于运行批处理作业.
--network=node
5.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语法格式为:
FROM
FROM :
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,443
COPY 复制文件
该指令将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的<目标路径>位置
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 /tmp
VOLUME 使用卷挂载
将容器内的数据保存在宿主机上,一般位于docker的数据目录下/var/lib/docker/volumes/
VOLUME /myvol
USER 用户
设置运行镜像时要使用的用户名(或 UID)和可选的用户组(或 GID) ,以及 Dockerfile 中跟随它的任何 RUN、 CMD 和 ENTRYPOINT 指令。
USER 0:0
USER root:root
WORKDIR 工作目录
为RUN、CMD、ENTRYPOINT、COPY和ADD设置工作目录
WORKDIR /a
WORKDIR b
WORKDIR c
ENV 环境变量
为镜像注入环境变量
ENV MY_NAME=“John Doe”
ENV MY_DOG=Rex\ The\ Dog
ENV MY_CAT=fluffy
CMD
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区别
6.2 构建一个nginx镜像
6.2.1 编写Dockerfile
创建一个工作目录
mkdir build-nginx
cd build-nginx
wget 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_wu
curl 172.17.0.4
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 2020
6.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 2\n");
return 1;
}
size = strtoull(argv[1], NULL, 10);
if (size == 0) {
printf(" argv[1]=%s not good\n", argv[1]);
return 1;
}
char *buff = (char *) malloc(size * UNIT);
if (buff)
printf(" we malloced %d Mb\n", 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/