OpenShift v4 Tekton流水线镜像跨仓库复制方案咨询
在OpenShift 4上用Tekton实现镜像跨仓库复制的解决方案
工具选择:优先用Skopeo
- Skopeo是专为跨容器仓库复制镜像设计的工具,支持OCI镜像格式,原生适配各类仓库认证逻辑。Tekton Hub上有官方维护的
skopeo-copy任务可直接复用,无需从零编写镜像处理代码,在流水线容器环境中的成熟度和适配性远高于Crane(Crane更偏向本地CLI场景的镜像操作)。
凭证处理:基于Secret+ServiceAccount的安全方案
1. 内部OpenShift镜像仓库凭证
OpenShift内部镜像仓库的认证可通过权限绑定实现:
- 给专用ServiceAccount添加
system:image-puller集群角色(针对内部镜像所在项目),允许其拉取内部镜像:oc policy add-role-to-user system:image-puller system:serviceaccount:<你的项目>:<专用SA名称> -n <内部镜像所在项目> - 内部仓库的认证信息会自动通过ServiceAccount挂载到Pod的
/var/run/secrets/kubernetes.io/serviceaccount目录,Skopeo可直接读取该目录下的token和ca.crt完成认证。
2. 外部镜像仓库凭证
以Docker Hub为例,创建dockerconfigjson类型的Secret存储外部仓库认证信息:
oc create secret docker-registry external-registry-secret \ --docker-server=docker.io \ --docker-username=<你的用户名> \ --docker-password=<你的密码/令牌> \ --docker-email=<你的邮箱> \ -n <你的流水线项目>
将该Secret绑定到专用ServiceAccount,赋予拉取/推送权限:
oc secrets link <专用SA名称> external-registry-secret --for=pull,push
Skopeo会自动识别挂载到容器的/.docker/config.json文件,完成外部仓库的认证。
专用ServiceAccount:必须使用,拒绝默认pipeline账户
- 默认
pipeline账户权限过宽,不符合最小权限原则,存在安全风险,必须使用专用ServiceAccount。 - 创建专用ServiceAccount:
oc create serviceaccount image-copy-sa -n <你的项目> - 除绑定外部仓库Secret外,需为其配置内部仓库的拉取权限(如前面的
system:image-puller角色绑定)。 - 在
PipelineRun中指定该ServiceAccount:apiVersion: tekton.dev/v1beta1 kind: PipelineRun metadata: generateName: nodejs-image-copy-run- spec: serviceAccountName: image-copy-sa pipelineRef: name: nodejs-build-and-copy-pipeline params: - name: git-url value: "<你的Git仓库地址>" - name: internal-image-url value: "image-registry.openshift-image-registry.svc:5000/<内部项目>/nodejs-app:latest" - name: external-image-url value: "docker.io/<你的用户名>/nodejs-app:latest"
完整示例
1. Skopeo复制Task(可直接复用或自定义)
apiVersion: tekton.dev/v1beta1 kind: Task metadata: name: skopeo-copy spec: params: - name: src-image type: string - name: dest-image type: string steps: - name: copy-image image: quay.io/skopeo/stable:latest command: ["skopeo"] args: - "copy" - "--src-tls-verify=false" # 内部仓库用自签证书时关闭验证,生产环境建议挂载CA证书 - "docker://$(params.src-image)" - "docker://$(params.dest-image)" volumeMounts: - name: docker-config mountPath: /.docker volumes: - name: docker-config secret: secretName: external-registry-secret
2. 整合后的Pipeline
apiVersion: tekton.dev/v1beta1 kind: Pipeline metadata: name: nodejs-build-and-copy-pipeline spec: params: - name: git-url type: string - name: internal-image-url type: string - name: external-image-url type: string tasks: - name: clone-repo taskRef: name: git-clone params: - name: url value: "$(params.git-url)" workspaces: - name: output workspace: shared-workspace - name: build-nodejs-image taskRef: name: s2i-nodejs runAfter: - clone-repo params: - name: IMAGE value: "$(params.internal-image-url)" - name: PATH_CONTEXT value: "." workspaces: - name: source workspace: shared-workspace - name: copy-image-to-external taskRef: name: skopeo-copy runAfter: - build-nodejs-image params: - name: src-image value: "$(params.internal-image-url)" - name: dest-image value: "$(params.external-image-url)" workspaces: - name: shared-workspace
内容的提问来源于stack exchange,提问作者devops036 devops036
相关产品推荐
相关产品推荐

