Docker 中默认的容器网络为名为bridge的桥接网络,使用DHCP协议,不能固定容器IP,每次重启,容器的IP是按其启动顺序来分配的,单宿主机多容器时,容器的IP就会发生变化,不利于程序 连接及安全加固配置,本文探讨如何在国产openeuler22.03下让单宿主机多容器的场景下容器内启用固定IP。
1、创建一个自定义的网络
[root@localhost ~]# docker network create --subnet=172.18.0.0/24 snet
6cc2fbec437ba86d0b80bd6a606b1a8d9b46d4f9f3f76826f20efa2adff6bd1a
[root@localhost ~]# docker network list
NETWORK ID NAME DRIVER SCOPE
a3e22572b920 bridge bridge local
57fa83f87a13 host host local
0b547c045c50 none null local
6cc2fbec437b snet bridge local
6cc2fbec437b即为新建的容器网络。命令行中--subnet
参数指定了子网及其掩码为 172.18.0.0/24
,可以根据情况调整。snet
是网络名称,可以自定义。
[root@localhost ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> 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
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:35:f3:4f brd ff:ff:ff:ff:ff:ff
altname enp2s1
inet 192.168.80.132/24 brd 192.168.80.255 scope global dynamic noprefixroute ens33
valid_lft 1357sec preferred_lft 1357sec
inet6 fe80::95f:f5d0:b846:15a/64 scope link noprefixroute
valid_lft forever preferred_lft forever
3: br-58c446696111: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:96:5b:d7:b1 brd ff:ff:ff:ff:ff:ff
inet 172.18.0.1/24 brd 172.18.0.255 scope global br-58c446696111
valid_lft forever preferred_lft forever
inet6 fe80::42:96ff:fe5b:d7b1/64 scope link
valid_lft forever preferred_lft forever
4: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:7c:d2:21:88 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
...
ip addr指令可以看到宿主机上自动启用了地址为172.18.0.1/24的桥接网关。
2、修改docker的配置文件,避免服务器重启后自定义网络丢失
修改docker的配置文件,屏蔽daemon掉电重启时清理docker的db文件功能,避免服务器重启后自定义网络丢失。此段参考:网友hotcoffie写的文章【《全网唯一》解决华为OpenEuler 22.03LTS重启后,docker丢失自定义网络,docker-compose报错: network not found】
和华为官方文档描述:
执行:
[root@localhost ~]# echo "DISABLE_CRASH_FILES_DELETE=true" >>/etc/sysconfig/docker
[root@localhost ~]# cat /etc/sysconfig/docker
# /etc/sysconfig/docker
# Modify these options if you want to change the way the docker daemon runs
OPTIONS='--live-restore'
DOCKER_CERT_PATH=/etc/docker
# If you have a registry secured with https but do not have proper certs
# distributed, you can tell docker to not look for full authorization by
# adding the registry to the INSECURE_REGISTRY line and uncommenting it.
# INSECURE_REGISTRY='--insecure-registry'
# Location used for temporary files, such as those created by
# docker load and build operations. Default is /var/lib/docker/tmp
# Can be overridden by setting the following environment variable.
DISABLE_CRASH_FILES_DELETE=true
请重启服务器,确认自定义网络snet
没有丢失。
3、启动容器时指定固定 IP
可以在 docker run
命令中使用 --ip
参数指定容器的 IP 地址,并关联到自定义网络,例如:
[root@localhost ~]# docker run --name sftpsrv --ip=172.18.0.2 --network=snet --restart=always -p 4434:22 -d atmoz/sftp:debian-stretch sftp:1111:1111
4b5b4a2c06f260b341449209a1913ec9d2dfb1ef2a48efb4182af80ac93d818b
[root@localhost ~]# docker run --name sftpsrv2 --ip=172.18.0.3 --network=snet --restart=always -p 4435:22 -d atmoz/sftp:debian-stretch sftp:1111:1111
94795b86366a7fd234fd7a7ac996a72e50e8d1e319dafa17c521b810a5c7b565
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
94795b86366a atmoz/sftp:debian-stretch "/entrypoint sftp:11…" 4 seconds ago Up 3 seconds 0.0.0.0:4435->22/tcp sftpsrv2
4b5b4a2c06f2 atmoz/sftp:debian-stretch "/entrypoint sftp:11…" 24 seconds ago Up 22 seconds 0.0.0.0:4434->22/tcp sftpsrv
其中,--name
指定容器的名称,--ip
指定容器的 IP 地址,--network
指定容器连接到的网络,-d
指定容器在后台运行,atmoz/sftp:debian-stretch
是本次测试用镜像名称。
注意,指定固定 IP 的容器需连接到相应的自定义网络中。同时,需要确保指定的 IP 地址在子网范围内,而且没有被其他容器或主机使用。
如果在 Docker Compose 中,也可使用 ipv4_address
关键字来指定容器的固定 IP 地址。例如:
version: '3'
services:
sftpsrv:
image: atmoz/sftp:debian-stretch
networks:
snet:
ipv4_address: 172.18.0.2
ports:
- "4434:22"
restart: always
command: sftp:1111:111
networks:
snet:
driver: bridge
ipam:
config:
- subnet: 172.18.0.0/24
测试业务运行情况
[root@localhost ~]# telnet 192.168.80.132 4434
Trying 192.168.80.132...
Connected to 192.168.80.132.
Escape character is '^]'.
SSH-2.0-OpenSSH_7.4p1 Debian-10+deb9u4
Protocol mismatch.
Connection closed by foreign host.
[root@localhost ~]# telnet 192.168.80.132 4435
Trying 192.168.80.132...
Connected to 192.168.80.132.
Escape character is '^]'.
SSH-2.0-OpenSSH_7.4p1 Debian-10+deb9u4
Protocol mismatch.
Connection closed by foreign host.
[root@localhost ~]#
可见业务运行正常。
4、重启容器进行验证,看分配的固定IP是否有变化。
[root@localhost ~]# systemctl restart docker
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
94795b86366a atmoz/sftp:debian-stretch "/entrypoint sftp:11…" About an hour ago Up 40 minutes 0.0.0.0:4435->22/tcp sftpsrv2
4b5b4a2c06f2 atmoz/sftp:debian-stretch "/entrypoint sftp:11…" About an hour ago Up 40 minutes 0.0.0.0:4434->22/tcp sftpsrv
[root@localhost ~]# docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' `docker ps -qa`
172.18.0.3
172.18.0.2
可见容器的IP在重启后不会再发生变化了。