将GitHub Package Registry镜像部署到GKE出现ErrImagePull报错
问题根因
你当前工作流中配置的ghcr.io登录步骤仅对GitHub Actions运行器本身生效,GKE集群的kubelet服务没有获取到ghcr.io私有镜像的拉取凭证,这是Pod触发ErrImagePull报错的核心原因。kubectl apply仅负责将Deployment资源提交给Kubernetes API Server,实际镜像拉取动作由集群节点执行,和运行器本地的Docker登录状态没有关联。
修复方案
1. 准备ghcr.io拉取专用凭证
不要使用工作流内置的GITHUB_TOKEN,该token仅在当前工作流运行周期内有效,过期后集群拉取镜像会再次失败。
- 生成GitHub个人访问令牌(PAT),仅授予
read:packages最小权限即可,如果镜像归属于组织,需要额外确认令牌已获得组织的包访问授权 - 将生成的PAT存入GitHub仓库Secrets,命名为
GHCR_PAT
2. 工作流中新增集群拉取密钥创建步骤
在获取GKE集群凭证之后、执行kubectl apply之前,新增步骤在目标命名空间创建docker-registry类型的密钥,用于存储ghcr.io的认证信息:
- name: Create ghcr.io pull secret for GKE run: | kubectl create secret docker-registry ghcr-pull-secret \ --docker-server=ghcr.io \ --docker-username=替换为你的GitHub用户名 \ --docker-password=${{ secrets.GHCR_PAT }} \ --docker-email=替换为你的GitHub绑定邮箱 \ --dry-run=client -o yaml | kubectl apply -f -
命令末尾的dry-run逻辑可以避免重复运行工作流时触发"密钥已存在"的报错。
3. 配置Pod使用该拉取密钥
两种方案二选一即可:
- 单Deployment生效:在你的Deployment配置清单的Pod spec层级添加
imagePullSecrets字段,关联刚才创建的密钥:
spec: # 其他Deployment配置省略 template: spec: imagePullSecrets: - name: ghcr-pull-secret containers: - name: api image: ghcr.io/你的镜像路径:标签 # 确认镜像路径、标签和GHCR上存储的完全一致,路径大小写错误也会导致拉取失败
- 命名空间全局生效:如果不想给每个Deployment单独配置,可以给命名空间下的默认ServiceAccount绑定拉取密钥,执行以下命令即可,后续该命名空间下所有新建Pod默认都会使用这个密钥拉取镜像:
- name: Set default pull secret for namespace run: | kubectl patch serviceaccount default -p '{"imagePullSecrets": [{"name": "ghcr-pull-secret"}]}'
4. 清理冗余配置&修复已知问题
- 原有工作流里的
Authenticate Into ghcr.io步骤完全冗余,可以直接删除,运行器本地不需要登录ghcr.io - 你当前使用的
google-github-actions/get-gke-credentials@v0版本过旧,建议升级到v1版本避免GKE API兼容问题 - 注意确认Deployment部署的命名空间和创建密钥的命名空间完全一致,跨命名空间的密钥无法被引用
验证方式
部署完成后执行以下命令查看Pod事件,确认镜像拉取状态:
kubectl describe pod -l app=test-api | grep -A 10 Events
如果事件中出现Successfully pulled image相关提示,说明镜像拉取正常,问题修复。
内容的提问来源于stack exchange,提问作者Jplus2
相关产品推荐
相关产品推荐

