Docker 开发随笔

Docker 删除所有 none 镜像

1
# docker rmi `docker images | grep  '<none>' | awk '{print $3}'`

Docker 构建镜像时忽略错误信息

根据 Dockerfile 构建镜像,当构建失败时,往往会出现以下错误:

1
2
automake: error: no 'Makefile.am' found for any configure output
Error build: The command [/bin/sh -c aclocal && autoconf && automake -a] returned a non-zero code: 1

在很多企业的应用场景里,上面的错误信息实际上是无害的,可以忽略不处理。但一旦出现此类错误 Docker 就会停止构建,此时如果需要让 Docker 忽略类似的错误信息,可以使用 exit 0

1
RUN make

当 Dockerfile 里包含了上面类似的指令,则可以改写为以下的内容,这将始终返回 0(成功)退出代码,此时 Docker 不会意外终止构建过程

1
RUN make; exit 0

不同网段之间的容器实现互相通信

Docker 命令行的使用

提示

假设存在两个容器,分别是 Redis 容器(172.89.0.2)和 Nginx 容器(172.89.0.5),两者具体的 docker-compose.yml 配置信息如下:

  • Redis 容器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
version: '3.5'

services:
redis:
image: redis:5.0.4-stretch
container_name: redis
restart: always
privileged: false
environment:
TZ: 'Asia/Shanghai'
ports:
- 6379:6379
networks:
redis-network:
ipv4_address: 172.89.0.2
volumes:
- '/usr/local/redis/data:/data'
- '/usr/local/redis/redis.conf:/usr/local/etc/redis/redis.conf'
command: redis-server /usr/local/etc/redis/redis.conf

networks:
redis-network:
name: redis-network
driver: bridge
ipam:
config:
- subnet: 172.89.0.0/24
  • Nginx 容器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
version: '3.5'

services:
nginx:
image: nginx:1.20
container_name: nginx
restart: always
privileged: false
environment:
TZ: 'Asia/Shanghai'
networks:
nginx-network:
ipv4_address: 172.64.0.5
ports:
- 80:80
- 443:443
volumes:
- '/usr/local/nginx/conf/nginx.conf:/usr/local/nginx/conf/nginx.conf'

networks:
nginx-network:
name: nginx-network
driver: bridge
ipam:
config:
- subnet: 172.64.0.0/24

上述的 Redis 和 Nginx 容器分别处于不同的网段中,两者之间的网络无法直接 Ping 得通;若希望在 Redis 内可以 Ping 通 Nginx 容器,那么可以将 Nginx 容器添加到 Redis 容器所在网络里,命令示例如下:

1
2
3
4
5
6
7
8
# 将Nginx容器添加到Redis容器所在网络里
# docker network connect redis-network nginx

# 查看Nginx容器在Redis容器所在网络里的IP
# docker network inspect redis-network

# 在Redis容器内直接Ping通Nginx容器(这里的IP是Nginx容器在新网络里的IP地址)
# ping 172.89.0.3

警告

使用 docker network connect redis-network nginx 命令,将 Nginx 容器添加到 Redis 容器所在网络后,Nginx 在新网络里的 IP 地址是不固定的,例如 Docker 服务重启后 IP 地址会变更,这一点必须注意!


将 Nginx 容器从 Redis 容器所在网络里移除掉,可以使用以下命令:

1
# docker network disconnect redis-network nginx

提示

Docker 默认网络的名称是 bridge,默认情况下创建的所有容器都会在 bridge 网络内。

1
2
3
4
5
# 查看Docker的所有网络
# docker network ls

# 查看某网络下所有容器的信息(包括各个容器的IP)
# docker network inspect redis-network

Docker-Compose 的使用

在 Docker-Compose 中,支持将 Nginx 容器添加到 Redis 容器所在网络里,配置示例如下所示。

提示

值得一提的是,这里通过 docker-compose.yml 配置文件,将 Nginx 容器添加到 Redis 容器所在网络后,Nginx 在新网络里的 IP 地址是固定的。

  • Redis 容器,配置内容和上面的案例一致
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
version: '3.5'

services:
redis:
image: redis:5.0.4-stretch
container_name: redis
restart: always
privileged: false
environment:
TZ: 'Asia/Shanghai'
ports:
- 6379:6379
networks:
redis-network:
ipv4_address: 172.89.0.2
volumes:
- '/usr/local/redis/data:/data'
- '/usr/local/redis/redis.conf:/usr/local/etc/redis/redis.conf'
command: redis-server /usr/local/etc/redis/redis.conf

networks:
redis-network:
name: redis-network
driver: bridge
ipam:
config:
- subnet: 172.89.0.0/24
  • Nginx 容器,配置了多个网络,同时指定了容器在不同网络下的 IP 地址
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
version: '3.5'

services:
nginx:
image: nginx:1.20
container_name: nginx
restart: always
privileged: false
environment:
TZ: 'Asia/Shanghai'
networks:
nginx-network:
ipv4_address: 172.64.0.5
redis-network:
ipv4_address: 172.89.0.3
ports:
- 80:80
- 443:443
volumes:
- '/usr/local/nginx/conf/nginx.conf:/usr/local/nginx/conf/nginx.conf'

networks:
nginx-network:
name: nginx-network
driver: bridge
ipam:
config:
- subnet: 172.64.0.0/24
redis-network:
name: redis-network
driver: bridge
ipam:
config:
- subnet: 172.89.0.0/24
  • 查看 Docker 的网络状况
1
2
3
4
5
# 查看Nginx容器在Redis容器所在网络里的IP
# docker network inspect redis-network

# 在Redis容器内直接Ping通Nginx容器
# ping 172.89.0.3

Docker 升级版本后无法启动

Docker 升级版本后无法正常启动,使用命令 journalctl -u docker 查看系统日志信息,得到的错误信息如下:

1
[graphdriver] prior storage driver devicemapper is deprecated and will be removed in a future release; update the the daemon configuration and explicitly choose this storage driver to continue using it;

创建或编辑 /etc/docker/daemon.json 配置文件,然后在配置文件内添加以下内容:

1
2
3
{
"storage-driver": "devicemapper"
}

再次重启 Docker 服务

1
systemctl restart docker

Docker 查看容器的资源占用情况

使用以下命令,可以查看 Docker 容器的 CPU、内存、网络资源占用情况。

1
2
3
4
5
# 查看所有容器
# docker stats

# 查看特定的容器
# docker stats mysql

Docker 容器添加自定义 Hosts

为了向容器的 /etc/hosts 配置文件中添加一些记录,可以使用以下任意一种方式来实现。

  • Docker 启动容器时,添加 Hosts
1
docker run --add-host=myhostname:10.180.8.1 --name test -it debian
  • Docker-Compose 通过配置参数 extra_hosts 实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
version: "3.5"

services:
pms:
image: idoop/zentao:latest
container_name: pms
privileged: true
ports:
- 8080:80
- 3386:3306
environment:
- ADMINER_USER=root
- ADMINER_PASSWD=123456
- BIND_ADDRESS=false
- SET_CONTAINER_TIMEZONE=true
- CONTAINER_TIMEZONE=Asia/Shanghai
volumes:
- /etc/localtime:/etc/localtime:ro
- /data/pms/:/opt/zbox/
restart: always
extra_hosts:
- "github.com:140.82.112.4"
- "smtp.exmail.qq.com:113.96.208.92"
  • Docker-Compose 的另一种写法,可能需要高版本的 Compose 才支持(例如 1.3 版本)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
version: "3.5"

services:
pms:
image: idoop/zentao:latest
container_name: pms
privileged: true
ports:
- 8080:80
- 3386:3306
environment:
- ADMINER_USER=root
- ADMINER_PASSWD=123456
- BIND_ADDRESS=false
- SET_CONTAINER_TIMEZONE=true
- CONTAINER_TIMEZONE=Asia/Shanghai
volumes:
- /etc/localtime:/etc/localtime:ro
- /data/pms/:/opt/zbox/
restart: always
extra_hosts:
- github.com: 140.82.112.4
- smtp.exmail.qq.com: 113.96.208.92