docker ping 域名报错: Name or service not known;ping IP地址报错:connect: Network is unreacha
基础环境
jenkins + jenkins agnet(agnet 在eks中)
jenkins 是脱离 eks 单独安装的,执行任务时调用 api 在eks中创建 jenkins agent 来执行构建任务;
问题描述
最近做 jenkins 项目的构建测试时;
Dockerfile 中 使用 centos 镜像,拉取 redis 构建测试环境
Dockerfile 如下:
FROM centos:7
RUN curl -o redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \
&& tar -xvf redis.tar.gz
jenkins 构建时报错如下:
排查及解决
eks 做了 公网、私网的划分;
启动 此次 docker 容器的机器,恰巧都在私网环境内(私网做了 vpc nat 地址的转发,机器可以连接到公网);
问题详细排查一
进入到 eks 私有子网的主机。查看主机网络环境配置
[root@ip-10-20-149-250 ec2-user]# ip a
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: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq state UP group default qlen 1000
link/ether 02:e9:4a:3b:09:87 brd ff:ff:ff:ff:ff:ff
inet 10.20.149.250/19 brd 10.20.159.255 scope global dynamic eth0
valid_lft 2548sec preferred_lft 2548sec
inet6 fe80::e9:4aff:fe3b:987/64 scope link
valid_lft forever preferred_lft forever
3: eni9968a90ce79@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc noqueue state UP group default
link/ether 6a:fa:13:f5:71:c7 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::68fa:13ff:fef5:71c7/64 scope link
valid_lft forever preferred_lft forever
30: eni78614c52579@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc noqueue state UP group default
link/ether ae:25:89:17:66:ed brd ff:ff:ff:ff:ff:ff link-netnsid 2
inet6 fe80::ac25:89ff:fe17:66ed/64 scope link
valid_lft forever preferred_lft forever
37: enic0ff5a8c056@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc noqueue state UP group default
link/ether d2:43:df:28:0a:34 brd ff:ff:ff:ff:ff:ff link-netnsid 3
inet6 fe80::d043:dfff:fe28:a34/64 scope link
valid_lft forever preferred_lft forever
38: eniff206d3e1a9@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc noqueue state UP group default
link/ether b2:18:ec:36:90:5f brd ff:ff:ff:ff:ff:ff link-netnsid 1
inet6 fe80::b018:ecff:fe36:905f/64 scope link
valid_lft forever preferred_lft forever
84: enidccd1a02d40@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc noqueue state UP group default
link/ether aa:33:6a:95:43:75 brd ff:ff:ff:ff:ff:ff link-netnsid 4
inet6 fe80::a833:6aff:fe95:4375/64 scope link
valid_lft forever preferred_lft forever
85: eni8851af7fcac@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc noqueue state UP group default
link/ether a2:12:01:54:ed:17 brd ff:ff:ff:ff:ff:ff link-netnsid 5
inet6 fe80::a012:1ff:fe54:ed17/64 scope link
valid_lft forever preferred_lft forever
[root@ip-10-20-149-250 ec2-user]#
发现没有 docker0 网络接口,再次查看 /etc/docker/daemon.json 配置文件
[root@ip-10-20-149-250 ec2-user]# cat /etc/docker/daemon.json
{
"bridge": "none",
.....
发现没有 bridge 的网络绑定;这下渐渐明白了;
以前只是对 eks 的网络构建有一点点的连接,通过 aws 自己的 eni 插件实现的;看来就这个机会,可以再深入的了解一下了;
问题详细排查 二
众所周知,公有云 k8s 服务中,网络部分 各大厂商的解决方案是不同的;
aws 中,eks 中的网络解决方案中,使用了 Amazon VPC CNI 网络插件,进行 pod之间 网络的打通;
amazon-vpc-cni-k8s 网络插件,有2个组件构成
1. CNI Plugin,它会在调用时连接主机和 pod 的网络堆栈。
2. ipamd,一个长期运行的节点-本地IP地址管理(IPAM)守护进程,负责:
维护一个可用 IP 地址的热池,以及
为 Pod 分配 IP 地址。
该插件实现的基本要求是:
1. 所有容器都可以在没有 NAT 的情况下与所有其他容器通信
2. 所有节点都可以在没有 NAT 的情况下与所有容器通信(反之亦然)
......
到这里,其实大家已经知道。eks中pod用的是和ec2相同的 vpc IP 地址段;并且每个IP地址都依赖于一个eni,eni可以有多个IP地址;
每个eni都有自己的路由规则用于pod的传出流量;.....
eks 中docker容器并没有像 单机版本 docker 容器一样使用docker0 网络做 桥接;而是使用了真实的 vpc IP地址;
结果
到这里真想就大白了;
普通 docker 中,使用docker0 做网络的桥接;eks 中 pod 的启动是分配了 真实的IP地址的;
这里直接使用 docker build 启动的容器,是没有 docker0 做为桥接,然后又没人给他分配 eni IP地址(eks中,cni 插件来管),所以我docker build 的容器,启动时是没有网络环境的;
解决
-
jenkins 在 eks 中启动 agent 节点,在docker build 环节中,尽量不使用 网络资源;如果真要使用 自己构建完基础镜像,依托于基础镜像再进行 jenkins 构建操作;
-
索性,不使用eks中的jenkins agent 来构建docker镜像;直接在jenkins机器上直接构建;
-
构建时 指定网络
# 这里直接指定 build 时使用 主机网络;完美解决;
docker build --network=host . -t ${IMAGE_REPO}:${GIT_COMMIT}
本文来自博客园, 作者:Star-Hitian, 转载请注明原文链接:https://www.cnblogs.com/Star-Haitian/p/16527054.html