[原创]容器中使用 hostname 访问外部机器

容器中使用 hostname 访问外部服务, 不需要配置 /etc/hosts

AWS 上有一个集群服务, VPS 之间使用 ip-xx-xx-xx-xx 是可以直接访问的.

现在有个需求, 要在某几台机器部署 docker, 在容器内访问集群内的服务. 并且使用 hostname 实现.

# 创建 Dockerfile
cat > Dockerfile << EOF
FROM alpine
EOF
# 创建 docker-compose.yml
cat > docker-compose.yml << EOF
version: '3'
services:
  api:
    build: .
    container_name: "api"
    working_dir: /root
    command: tail -f /dev/null
EOF
# 启动容器
docker-compose up -d

# 在容器内尝试连接宿主机, 提示解析不到主机
docker-compose exec api nslookup `hostname`

# nslookup: can't resolve '(null)': Name does not resolve
# nslookup: can't resolve 'ip-172-31-42-98': Name does not resolve

#  在宿主机内解析自己
nslookup ip-172-31-42-98

#Server:		172.31.0.2
#Address:	172.31.0.2#53

#Non-authoritative answer:
#Name:	ip-172-31-42-98.us-west-2.compute.internal
#Address: 172.31.42.98

# 查看宿主机 DNS 设置
cat /etc/resolv.conf 
# nameserver 172.31.0.2
# search us-west-2.compute.internal
# nameserver 8.8.8.8
# nameserver 8.8.8.8

# 查看容器内 DNS 设置
docker-compose exec api cat /etc/resolv.conf
# search us-west-2.compute.internal
# nameserver 127.0.0.11
# options ndots:0

# 尝试将 `nameserver 172.31.0.2` 加入容器内 DNS 设置后再尝试, 依旧解析失败.

# 直接解析完整路径,  是可以解析到内容的
docker-compose exec mmm nslookup ip-172-31-42-98.us-west-2.compute.internal
#nslookup: can't resolve '(null)': Name does not resolve

#Name:      ip-172-31-42-98.us-west-2.compute.internal
#Address 1: 172.31.42.98 ip-172-31-42-98.us-west-2.compute.internal

容器内 DNS 有一行设置是 options ndots:0, 只需要将 ndots 改成 1 就可以解决这个问题.

ndots:n.
sets a threshold for the number of dots which must appear in a name given to res_query(3) (see resolver(3)) before an initial absolute query will be made. The default for n is 1, meaning that if there are any dots in a name, the name will be tried first as an absolute name before any search list elements are appended to it. The value for this option is silently capped to 15.

以解析的域名ip-172-31-42-98为例, 里面最少需要有1个 ., 依次和search配置的列表拼接解析, 直到解析成功. linux 默认是 1. docker 容器默认是 1, 应该是为了安全考虑.

所以只需要修改 DNS ndots:1 即可.

如何让容器启动后默认就是 ndots:1? 只需要配置 /etc/docker/daemon.json 即可.

{
  "dns-opts": ["ndots:1"]
}

# 修改 daemon 后重启 docker
service docker restart

# 重新创建容器
docker-compose down

docker-compose up -d

# 查看配置 ndots 是否有变化
docker-compose exec api cat /etc/resolv.conf
# search us-west-2.compute.internal
# nameserver 127.0.0.11
# options ndots:1

# 解析成功了
docker-compose exec api nslookup ip-172-31-42-98
# Name:      ip-172-31-42-98
# Address 1: 172.31.42.98 ip-172-31-42-98.us-west-2.compute.internal

# 访问其他主机的服务
docker-compose exec mmm curl ip-172-31-41-9:31267/echo/
# OK

参考

man/5/resolv.conf - https://linux.die.net/man/5/resolv.conf

moby/moby - ndots:0 #32093 - https://github.com/moby/moby/issues/32093#issuecomment-313887120

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值