Docker DNS
当用户使用自定义网络(docker run --network NETWORK),而不是使用默认的网络(bridge, Linux中对应的网桥为docker0)时,Docker使用内部的DNS服务解析域名。
内部的DNS服务将容器名字解析为该容器的IP,所以容器之间可以通过容器名互相访问
使用内置DNS服务
创建网络
sudo docker network create br0
Docker默认网络,名字为:bridge(Linux中对应网桥docker0)不使用内置DNS,所以我们要自己创建网络
查看创建的docker网络
docker network ls
查看某个网络的详细信息
docker network inspect br0
输出的信息中,可以看到到该网络包含的子网,及接入该网络的容器。
[
{
"Name": "br0",
"Id": "c129fec006b12325fd9378808c9f44138c556ae45c3e70d98b01ece531bdce8c",
"Created": "2020-08-27T10:41:30.991194478+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.20.0.0/16",
"Gateway": "172.20.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"26801f3b43e29ded1d2758058780d4e113e07d814cf8f48e4187581ca33198c4": {
"Name": "sharp_euler",
"EndpointID": "d7062fc0ada243ec7f9925265a7bfa95aede995edb57f7d0d90104e84dffd76f",
"MacAddress": "02:42:ac:14:00:02",
"IPv4Address": "172.20.0.2/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
创建容器时指定自定义的网络
创建、启动 MySQL
docker run -d --name mysql \
--restart always \
--network br0 \
-p 3306:3306 \
-v /opt/docker/volume/mysql/conf:/etc/mysql \
-v /opt/docker/volume/mysql/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD='xxx' \
mysql:8.0
创建、启动 Wordpress ,此时,Wordpress连接MySQL数据库的地址可以使用MySQL的容器名 mysql ,这两个容器内部可以使用容器名 mysql , wordpress 互相访问
docker run -d --name wordpress-01 \
--restart always \
--network br0 \
-p 8080:80 \
-v /opt/docker/volume/wordpress/data/html:/var/www/html \
-e WORDPRESS_DB_HOST='mysql' \
-e WORDPRESS_DB_USER='root' \
-e WORDPRESS_DB_PASSWORD='xxx' \
-e WORDPRESS_DB_NAME='wordpress' \
wordpress
单主机容器网络互通
由上文知道,单主机中的容器只要加入自建的同一个bridge,容器间网络就可以互通。
此时,容器不仅可以通过IP互相访问,还可以通过容器Name、容器ID、容器网络别名互相访问。
示例1: 通过IP、容器ID、容器Name回访
创建、启动容器 docker_web ,并加入自建bridge中 br0
docker run --rm -it --network br0 --name docker_web docker_web
创建启动容器 docker_redis,并加入自建bridge中 br0
docker run --rm -it --network br0 --network-alias redis --name docker_redis redis:alpine
进入容器 docker_web 中,分别使用容器 docker_redis 的IP, Name, ID,网络别名测试网络是否通
# 进入容器docker_web
$ docker exec -it docker_web /bin/sh
# ping 容器docker_web的IP
$ 172.27.0.3
PING 172.27.0.3 (172.27.0.3): 56 data bytes
64 bytes from 172.27.0.3: seq=0 ttl=64 time=0.217 ms
64 bytes from 172.27.0.3: seq=1 ttl=64 time=0.125 ms
# ping 容器docker_web的Name
$ ping docker_web
PING docker_web (172.27.0.2): 56 data bytes
64 bytes from 172.27.0.2: seq=0 ttl=64 time=0.075 ms
64 bytes from 172.27.0.2: seq=1 ttl=64 time=0.082 ms
# ping 容器docker_web的ID
ping c6ccf3c64f0f
PING c6ccf3c64f0f (172.27.0.3): 56 data bytes
64 bytes from 172.27.0.3: seq=0 ttl=64 time=0.151 ms
64 bytes from 172.27.0.3: seq=1 ttl=64 time=0.146 ms
# ping 容器docker_web的网络别名
$ ping redis
PING redis (172.27.0.3): 56 data bytes
64 bytes from 172.27.0.3: seq=0 ttl=64 time=0.160 ms
64 bytes from 172.27.0.3: seq=1 ttl=64 time=0.136 ms
上面可以通过ID和网络别名访问通,是因为他们加入了自定义网桥的别名字段中,可以查看:
$ docker container inspect docker_redis
...
"Networks": {
"br0": {
"IPAMConfig": null,
"Links": null,
"Aliases": [
"redis",
"c6ccf3c64f0f"
],
...
使用外部DNS
当容器创建不使用自定网络时,容器使用外部的DNS服务
默认DNS
默认Docker 直接将宿主机中的/etc/resolv.conf复制到容器中,过滤掉127.0.0.1之类的nameserver
sudo docker run --rm -it nginx /bin/sh
进入容器查看resolv.conf
/ # cat /etc/resolv.conf
nameserver 100.100.2.136
nameserver 100.100.2.138
单个容器指定DNS
sudo docker run --dns 114.114.114.114 --rm -it nginx /bin/sh
进入容器查看resolv.conf
/ # cat /etc/resolv.conf
nameserver 114.114.114.114
所有容器指定DNS
将域名解析写到 /ec/docker/daemon.json
cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://13sxamgp.mirror.aliyuncs.com"],
"dns": ["8.8.8.8", "8.8.4.4"]
}
重启docker读取 daemon.json
sysemctl restart docker
此时创建的容器,未指定DNS和网络的话,容器中DNS就是上面定义的DNS
sudo docker run --rm -it nginx /bin/sh
# 进入容器中
/ # cat /etc/resolv.conf
nameserver 8.8.8.8
nameserver 8.8.4.4