Back
Featured image of post helm镜像拉取失败的解决方案

helm镜像拉取失败的解决方案

背景

最近在国内节点测试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安装,发现可以正常运行了。

参考文档

  1. https://github.com/rofl0r/proxychains-ng
  2. https://github.com/hmgle/graftcp/blob/master/README.zh-CN.md
  3. https://docs.docker.com/config/daemon/systemd/#httphttps-proxy
Built with Hugo
Theme Stack designed by Jimmy