背景
最近在国内节点测试Flagger的时候,使用helm部署经常遇到镜像拉取失败的问题。
Release "ingress-nginx" does not exist. Installing it now.
Error: failed to download "ingress-nginx/ingress-nginx"
配置代理
Proxychains代理失效
最初尝试使用socks5代理Proxychains,实际测试下来没有效果。翻看Proxychains的官方文档说明:
ProxyChains is a UNIX program, that hooks network-related libc functions in dynamically linked programs via a preloaded DLL and redirects the connections through SOCKS4a/5 or HTTP proxies
可以看到,proxychains的魔法是劫持网络相关的libc动态库,因此只适用于链接了相同动态库的程序,而对于脚本或者基于Go这类静态链接编译的语言开发的程序是无效的。
很不幸的是,Helm和Docker都是基于Go开发的。只能另寻出路。
graftcp代理
再次尝试使用另一款支持静态链接编译程序的graftcp,注意提前把apiserver的ip写入黑名单文件$YOUR_BLACKLIST_IP,否则会干扰正常的kubectl和k8s集群的交互。
$ graftcp-local &
$ graftcp -p $YOUR_PORT -b $YOUR_BLACKLIST_IP bash
$^ helm install -i ...
...
Release "ingress-nginx" does not exist. Installing it now.
Error: failed to download "ingress-nginx/ingress-nginx"
查阅helm的缓存目录,发现其实charts配置清单已经从repo下载下来了
$ ls ~/.cache/helm/repository
ingress-nginx-4.0.6.tgz
问题应该出自node上,因为在控制平面节点是通过graftcp开启了一个代理bash,才能正常实现终端代理的,而k8s调度过程中其他node上无法做到这点。
node镜像问题解决
两种解决思路
- node上开启docker代理,一劳永逸
- node上手动通过其他方式下载或者导入其他节点的镜像
docker开启代理
一劳永逸的办法是在所有node上开启docker代理,缺点是只支持http和https七层,而且必须得重启docker,在某些线上环境可能不便于操作。
$ sudo mkdir -p /etc/systemd/system/docker.service.d
$ sudo vim /etc/systemd/system/docker.service.d/http-proxy.conf
[Service]
Environment="HTTP_PROXY=http://proxy.example.com:80"
Environment="HTTPS_PROXY=https://proxy.example.com:443"
$ sudo systemctl daemon-reload
$ sudo systemctl restart docker
国内可以搭配ss(socks5)+privoxy(socks5转http)使用。
镜像下载或导入
除了docker配置代理外,我们可以通过其他手段提前把镜像拉到node上,比如从其他配置了代理的节点上导入。不过,首先我们得确定chart中定义了什么image。
把上述的缓存目录配置解压出来,检查value.yaml的配置
image:
registry: k8s.gcr.io
image: ingress-nginx/controller
tag: "v1.0.4"
...
image:
registry: k8s.gcr.io
image: defaultbackend-amd64
tag: "1.5"
...
image:
registry: k8s.gcr.io
image: ingress-nginx/kube-webhook-certgen
tag: v1.1.1
发现以上三个镜像,镜像下载只需要在备好代理的节点下载好,重点讲下镜像的导入。
首先,在没有网络障碍的节点进行正常的镜像下载后,把镜像打包
docker save -o controller.tar k8s.gcr.io/ingress-nginx/controller:v1.0.4
docker save -o webhook.tar k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.1.1
docker save -o backend.tar k8s.gcr.io/defaultbackend-amd64:1.5
然后同步镜像包到node上,加载即可。
docker load -i controller.tar
docker load -i webhook.tar
docker load -i backend.tar
此后再次执行helm安装,发现可以正常运行了。