Docker容器中的DNS解析 [英] DNS resolution in docker containers

查看:294
本文介绍了Docker容器中的DNS解析的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

[环境]

  • CentOS 7
  • Docker 19.03.12,内部版本48a66213fe

我在 docker 容器内的 cerbot (让我们加密客户端)发生故障.看来 acme-v02.api.letsencrypt.org 无法从容器中解决 ,但可以从主机中解决 (最可能的原因).我已经习惯了容器从主机的DNS参数继承的事实,但是在AWS EC2实例的情况下,似乎有些实用程序

DNS手动设置

 <代码> [ec2-user @ ip-172-31-32-243〜] $ cat/etc/resolv.conf#由NetworkManager生成搜索eu-west-2.compute.internal名称服务器172.31.0.2 

基于此以及 AWS控制台中的一些元素,我尝试手动添加这些地址

 <代码> docker run --dns 172.31.0.2 --dns 172.65.32.248 

(我可能找不到正确的DNS)

错误修复

使用主机的网络解决了问题

  docker run --network ="host"; 

但是我只是不太明白为什么.这是-network ="host" 中使用的网络接口的问题.这是可用的一种:

 <代码> [ec2-user @ ip-172-31-32-243〜] $ ip链接显示1:lo:< LOOPBACK,UP,LOWER_UP>mtu 65536 qdisc无队列状态未知模式默认组默认qlen 1000链接/环回00:00:00:00:00:00 brd 00:00:00:00:00:002:eth0:< BROADCAST,MULTICAST,UP,LOWER_UP>mtu 9001 qdisc fq_codel状态UP模式默认组默认qlen 1000链接/以太0a:d2:81:33:16:f2 brd ff:ff:ff:ff:ff:ff:ff3:docker0:< NO-CARRIER,BROADCAST,MULTICAST,UP>mtu 1500 qdisc无队列状态DOWN模式默认组链接/以太02:42:9c:c8:d4:ba brd ff:ff:ff:ff:ff:ff:ff8:br-d15fdfe7243b:<无载波,广播,多播,UP>mtu 1500 qdisc无队列状态DOWN模式默认组链接/以太02:42:e8:56:81:bf brd ff:ff:ff:ff:ff:ff:ff 

是因为-network ="host" 诱导使用 eth0 而不是 docker0 吗?如何从 docker0 解析 acme-v02.api.letsencrypt.org ?

详细错误

 发生意外错误:追溯(最近一次通话):_new_conn中的文件"/usr/lib/python3.8/site-packages/urllib3/connection.py",第156行conn = connection.create_connection(create_connection中的文件"/usr/lib/python3.8/site-packages/urllib3/util/connection.py",第61行用于socket.getaddrinfo(主机,端口,家庭,socket.SOCK_STREAM)中的res:getaddrinfo中的文件"/usr/lib/python3.8/socket.py",第918行用于_socket.getaddrinfo中的res(主机,端口,家庭,类型,原型,标志):socket.gaierror:[Errno -3]再试一次在处理上述异常期间,发生了另一个异常:追溯(最近一次通话):urlopen中的文件"/usr/lib/python3.8/site-packages/urllib3/connectionpool.py",行665httplib_response = self._make_request(_make_request中的文件"/usr/lib/python3.8/site-packages/urllib3/connectionpool.py",第376行self._validate_conn(conn)_validate_conn中的文件"/usr/lib/python3.8/site-packages/urllib3/connectionpool.py",第994行conn.connect()连接中的文件"/usr/lib/python3.8/site-packages/urllib3/connection.py",第334行conn = self._new_conn()_new_conn中的文件"/usr/lib/python3.8/site-packages/urllib3/connection.py",第168行引发NewConnectionError(urllib3.exceptions.NewConnectionError:< urllib3.connection.VerifiedHTTPSConnection对象位于0x7f55dcc4a130> ;:建立新连接失败:[Errno -3]重试在处理上述异常期间,发生了另一个异常:追溯(最近一次通话):发送中的文件"/usr/lib/python3.8/site-packages/requests/adapters.py",第439行resp = conn.urlopen(urlopen中的文件"/usr/lib/python3.8/site-packages/urllib3/connectionpool.py",第719行重试= retries.increment(文件"/usr/lib/python3.8/site-packages/urllib3/util/retry.py",第436行,递增引发MaxRetryError(_pool,url,error或ResponseError(cause))urllib3.exceptions.MaxRetryError:HTTPSConnectionPool(host ='acme-v02.api.letsencrypt.org',port = 443):url:/directory超过了最大重试次数(由NewConnectionError('< urllib3.connection.VerifiedHTTPSConnection对象位于0x7f55dcc4a130> ;:建立新连接失败:[Errno -3]重试'))在处理上述异常期间,发生了另一个异常:requests.exceptions.ConnectionError:HTTPSConnectionPool(host ='acme-v02.api.letsencrypt.org',port = 443):url:/directory超过了最大重试次数(由NewConnectionError('< urllib3.connection.VerifiedHTTPSConnection对象位于0x7f55dcc4a130> ;:建立新连接失败:[Errno -3]重试'))请参阅/var/log/letsencrypt中的日志文件以获取更多详细信息. 

解决方案

看起来docker内部的DNS解析无法正常工作.

对于linux系统,DNS解析是使用/etc/resolv.conf 文件进行的,请检查容器中的该文件,如果它具有无效的DNS,则您的容器将无法解析主机名

Docker使用在主机上的/etc/docker/daemon.json 文件中设置的属性填充容器内/etc/resolv.conf 中的条目./p>

在主机的/etc/docker/daemon.json文件中更新此属性的值:

  {"dns":["8.8.8.8"]} 

注意:此更改需要重新启动docker才能生效,还必须删除并重新创建现有容器.

重新启动Docker:

  sudo systemctl重新启动docker 

删除容器:

  sudo docker stop<容器名称/id>sudo docker rm<容器名称/id> 

您可以添加多个DNS服务器IP地址,每个逗号之间用逗号分隔-检查[ec2-user@ip-172-31-32-243 ~]$ cat /etc/resolv.conf # Generated by NetworkManager search eu-west-2.compute.internal nameserver 172.31.0.2

Based on this and some elements from AWS console, I tried to add these address manually

docker run --dns 172.31.0.2 --dns 172.65.32.248

(I probably did not find the proper DNS)

An inelegant fix

Using the host's network solves the problem

docker run --network="host"

But I just don't quite understand why. Is it a matter of network interface used in --network="host". Here are the one available:

[ec2-user@ip-172-31-32-243 ~]$ ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
    link/ether 0a:d2:81:33:16:f2 brd ff:ff:ff:ff:ff:ff
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default 
    link/ether 02:42:9c:c8:d4:ba brd ff:ff:ff:ff:ff:ff
8: br-d15fdfe7243b: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default 
    link/ether 02:42:e8:56:81:bf brd ff:ff:ff:ff:ff:ff

Would it be because --network="host" induce using eth0 instead of docker0? How can I resolve acme-v02.api.letsencrypt.org from docker0?

Detailed error

An unexpected error occurred:
Traceback (most recent call last):
  File "/usr/lib/python3.8/site-packages/urllib3/connection.py", line 156, in _new_conn
    conn = connection.create_connection(
  File "/usr/lib/python3.8/site-packages/urllib3/util/connection.py", line 61, in create_connection
    for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM):
  File "/usr/lib/python3.8/socket.py", line 918, in getaddrinfo
    for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
socket.gaierror: [Errno -3] Try again

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3.8/site-packages/urllib3/connectionpool.py", line 665, in urlopen
    httplib_response = self._make_request(
  File "/usr/lib/python3.8/site-packages/urllib3/connectionpool.py", line 376, in _make_request
    self._validate_conn(conn)
  File "/usr/lib/python3.8/site-packages/urllib3/connectionpool.py", line 994, in _validate_conn
    conn.connect()
  File "/usr/lib/python3.8/site-packages/urllib3/connection.py", line 334, in connect
    conn = self._new_conn()
  File "/usr/lib/python3.8/site-packages/urllib3/connection.py", line 168, in _new_conn
    raise NewConnectionError(
urllib3.exceptions.NewConnectionError: <urllib3.connection.VerifiedHTTPSConnection object at 0x7f55dcc4a130>: Failed to establish a new connection: [Errno -3] Try again

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3.8/site-packages/requests/adapters.py", line 439, in send
    resp = conn.urlopen(
  File "/usr/lib/python3.8/site-packages/urllib3/connectionpool.py", line 719, in urlopen
    retries = retries.increment(
  File "/usr/lib/python3.8/site-packages/urllib3/util/retry.py", line 436, in increment
    raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='acme-v02.api.letsencrypt.org', port=443): Max retries exceeded with url: /directory (Caused by NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection object at 0x7f55dcc4a130>: Failed to establish a new connection: [Errno -3] Try again'))

During handling of the above exception, another exception occurred:

requests.exceptions.ConnectionError: HTTPSConnectionPool(host='acme-v02.api.letsencrypt.org', port=443): Max retries exceeded with url: /directory (Caused by NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection object at 0x7f55dcc4a130>: Failed to establish a new connection: [Errno -3] Try again'))
Please see the logfiles in /var/log/letsencrypt for more details.

解决方案

Looks like DNS resolution inside docker is not working properly.

For linux systems, DNS resolution happens using /etc/resolv.conf file, check this file inside your container, if it has invalid DNS, then your container won't be able to resolve hostnames.

Docker uses a property set in /etc/docker/daemon.json file(on host) for populating entries in /etc/resolv.conf inside container.

update the value of this property in /etc/docker/daemon.json file in host machine:

{
    "dns": ["8.8.8.8"]
}

Note: This change requires restarting docker to take effect, also existing containers have to be removed and created again.

Restarting Docker:

sudo systemctl restart docker

removing containers:

sudo docker stop <container-name/id>
sudo docker rm <container-name/id>

You can add multiple DNS server ip addresses, separate each one with a comma - check here to get a list of DNS server ip addresses

Cheers!!

这篇关于Docker容器中的DNS解析的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆