基于Kubectl版本的Docker镜像安装Kustomize失败,求兼容方案
问题
我在构建基于Kubectl客户端版本的Docker镜像时,安装Kustomize遇到了问题。我的Dockerfile内容如下:
FROM alpine:3 AS base FROM base as build WORKDIR /downloads RUN apk add --update bash curl build-base go git jq --no-cache && \ curl -L https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl -o kubectl && \ chmod +x kubectl && \ curl -o install_kustomize.sh "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" && \ chmod +x install_kustomize.sh && \ ./install_kustomize.sh $(./kubectl version --output=json --client=true | jq -r '.kustomizeVersion[1:]') #chmod +x kustomize FROM base as runtime RUN apk add --update coreutils curl jq && rm -rf /var/cache/apk/* COPY --from=build /downloads/kubectl /usr/local/bin/kubectl COPY --from=build /downloads/kustomize /usr/local/bin/kustomize
这个配置之前能用,但现在报错:
5.0.4-0.20230601165947-6ce0bf390ce3 does not exist. Create it first.
原因是kubectl version --output=json --client=true的输出里,Kustomize版本是带后缀的预发布版本:
Client Version: v1.28.2 Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
我找不到这个版本的Kustomize安装包。需要一种更可靠的安装方式,确保Kustomize和Kubectl客户端版本兼容,而且我的流水线需要独立的kustomize命令(不能用kubectl内置的)。
解决方案
方法1:提取主版本号安装官方正式版
Kubectl内置的Kustomize版本号里,前面的核心版本(比如v5.0.4)是官方正式发布的版本,后面的后缀是Kubernetes团队构建时的附加信息,没有对应的公开安装包。我们可以只提取核心版本部分来安装:
修改Dockerfile中调用install_kustomize.sh的行,用sed截取主版本:
# 替换原来的install_kustomize.sh执行行 ./install_kustomize.sh $(./kubectl version --output=json --client=true | jq -r '.kustomizeVersion[1:]' | sed -E 's/-0.*//')
这样会把带后缀的版本号转换成5.0.4,对应官方正式发布的Kustomize版本,能保证和kubectl的兼容性。
方法2:编译与Kubectl完全一致的Kustomize二进制
Kubectl本身依赖的Kustomize模块版本是明确的,我们可以直接用Go编译这个版本的独立kustomize命令,确保版本完全匹配:
修改build阶段的步骤:
FROM base as build WORKDIR /downloads RUN apk add --update bash curl build-base go git jq --no-cache && \ curl -L https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl -o kubectl && \ chmod +x kubectl && \ # 获取kubectl对应的完整Kustomize模块版本 KUSTOMIZE_VERSION=$(./kubectl version --output=json --client=true | jq -r '.kustomizeVersion') && \ # 编译对应版本的kustomize go install sigs.k8s.io/kustomize/kustomize/v5@$KUSTOMIZE_VERSION && \ # 将编译好的二进制复制到当前目录,方便后续拷贝 cp $(go env GOPATH)/bin/kustomize /downloads/kustomize
这种方式得到的kustomize和kubectl内置的版本完全一致,兼容性拉满,而且是独立的可执行命令。
方法3:基于官方Kustomize镜像构建
如果不想自己编译,可以直接用官方发布的Kustomize镜像作为基础,再安装对应版本的kubectl:
# 先拉取对应版本的官方kustomize镜像 FROM sigs.k8s.io/kustomize/kustomize:v5.0.4 as kustomize FROM alpine:3 AS base RUN apk add --update coreutils curl jq && rm -rf /var/cache/apk/* # 安装和kustomize版本兼容的kubectl RUN curl -L https://storage.googleapis.com/kubernetes-release/release/v1.28.2/bin/linux/amd64/kubectl -o /usr/local/bin/kubectl && \ chmod +x /usr/local/bin/kubectl # 从官方镜像拷贝独立的kustomize命令 COPY --from=kustomize /kustomize /usr/local/bin/kustomize
可以通过脚本动态匹配两者的主版本,比如kubectl 1.28对应kustomize 5.0.x,确保版本兼容。
内容的提问来源于stack exchange,提问作者Desolar1um

