Pod内Helm拉取报错:x509: certificate signed by unknown authority
我正尝试用client-go编写Helm Operator,想要通过RepoURL和chartName从控制器拉取Chart。本地运行示例代码一切正常,但放到容器里运行就抛出了证书错误。
相关代码如下:
func FetchURL() error { repoURL := "https://kubernetes-charts.storage.googleapis.com" username := "" password := "" var settings environment.EnvSettings flags := pflag.NewFlagSet("helm-env", pflag.ContinueOnError) settings.AddFlags(flags) settings.Init(flags) getters := getter.All(settings) getters := getter.All(settings) // 这里有重复定义,建议删除一行 var err error destDir, err := ioutil.TempDir("", "helm-") if err != nil { return fmt.Errorf("Failed to untar: %s", err) } defer os.RemoveAll(destDir) chartURL, err := repo.FindChartInAuthRepoURL(repoURL, username, password, chartRef, "", "", "", "", getter.All(settings)) if err != nil { return fmt.Errorf("Error finding the Chart URL: %s", err) } fmt.Println(chartURL) return nil }
获取chartURL时抛出的错误:
Fetching Chart Error finding the Chart URL: Looks like "https://kubernetes-charts.storage.googleapis.com" is not a valid chart repository or cannot be reached: Get https://kubernetes-charts.storage.googleapis.com/index.yaml: x509: certificate signed by unknown authority
我知道需要CA证书,但不确定具体是哪一个,而且初始化Helm时也没用到TLS证书。我还把Helm二进制复制到Pod里执行了以下命令:
helm init --client-only helm repo update
结果还是遇到了相同的x509证书错误,有没有人碰到过类似情况?
这个问题我在容器化Helm相关应用时也踩过坑,本质是容器镜像里缺少系统根CA证书,导致没办法验证Google存储服务的SSL证书。给你几个可行的解决办法:
1. 换用或构建包含完整CA证书的镜像
很多轻量镜像(比如alpine、distroless)默认没预装完整的根CA证书包。你可以直接换用ubuntu、debian这类自带完整证书的基础镜像,也可以在构建镜像时手动安装证书:
如果是基于alpine的镜像,在Dockerfile里添加:
RUN apk add --no-cache ca-certificates
如果是基于debian/ubuntu的镜像:
RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates && rm -rf /var/lib/apt/lists/*
2. 代码中临时跳过证书验证(仅测试环境用)
如果只是测试环境临时调试,可以在Helm的settings里禁用证书验证,修改代码如下:
settings.Init(flags) settings.InsecureSkipTLSverify = true // 添加这一行跳过验证
注意:生产环境绝对不要这么做,会带来严重的安全风险。
3. 手动添加目标证书到容器信任列表
如果你的环境有严格的证书管理要求,可以手动下载Google存储服务的根CA证书,然后添加到容器的信任目录:
- 先在本地下载证书:
openssl s_client -showcerts -connect kubernetes-charts.storage.googleapis.com:443 < /dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > google-ca.crt
- 在Dockerfile里把证书复制到容器的信任目录并更新:
COPY google-ca.crt /usr/local/share/ca-certificates/google-ca.crt RUN update-ca-certificates
另外提一句,你代码里有一行重复的getters := getter.All(settings),建议删掉其中一行,避免编译警告。
内容的提问来源于stack exchange,提问作者Prafull Ladha

