Bitbucket流水线部署Pod至Azure AKS失败:镜像拉取权限拒绝问题求助
问题分析与解决方案
你的问题核心是混淆了Bitbucket流水线内的Docker登录和AKS集群拉取私有镜像的凭证机制:流水线里执行的docker login只作用于Bitbucket的运行环境(比如用来拉取镜像构建、推送),但AKS节点上的kubelet是独立的进程,它拉取私有镜像需要集群层面的镜像拉取凭证(ImagePullSecret),和流水线的登录完全没关系。
下面是具体的排查和解决步骤:
1. 先确认镜像本身的可访问性
先排除镜像本身的问题:
- 本地用你的
$DOCKERHUB_USER和$DOCKERHUB_PASSWORD执行docker pull myrepository/test:1234,确认镜像存在且账号有拉取权限。 - 检查镜像标签是否正确,有没有拼写错误(比如仓库名、标签号)。
2. 在AKS集群创建镜像拉取凭证(ImagePullSecret)
你需要在AKS集群中创建对应Docker Hub的Secret,让kubelet可以用它拉取私有镜像。有两种方式:
方式一:手动创建(适合一次性配置)
在本地安装Azure CLI并登录AKS后,执行:
kubectl create secret docker-registry dockerhub-secret \ --docker-server=docker.io \ --docker-username=$DOCKERHUB_USER \ --docker-password=$DOCKERHUB_PASSWORD \ --docker-email=你的邮箱地址
这里的dockerhub-secret是自定义的Secret名称,后面会用到。
方式二:在Bitbucket流水线中自动创建(适合持续集成场景)
修改你的bitbucket-pipelines.yml,在部署Pod前先登录AKS并创建/更新Secret:
image: atlassian/default-image:2 options: docker: true pipelines: default: - step: name: "Deploy to PROD" deployment: production script: # 第一步:登录Azure并获取AKS凭证 - pipe: microsoft/azure-cli:1.0.0 variables: AZURE_APP_ID: $AZURE_APP_ID AZURE_PASSWORD: $AZURE_PASSWORD AZURE_TENANT_ID: $AZURE_TENANT_ID AZURE_RESOURCE_GROUP: "demo-rg" AZURE_AKS_NAME: "demo-aks" COMMAND: 'aks get-credentials --resource-group $AZURE_RESOURCE_GROUP --name $AZURE_AKS_NAME' # 第二步:创建/更新Docker Hub镜像拉取Secret(避免重复创建报错) - kubectl create secret docker-registry dockerhub-secret \ --docker-server=docker.io \ --docker-username=$DOCKERHUB_USER \ --docker-password=$DOCKERHUB_PASSWORD \ --docker-email=你的邮箱地址 \ --dry-run=client -o yaml | kubectl apply -f - # 第三步:部署Pod - pipe: microsoft/azure-aks-deploy:1.0.0 variables: AZURE_APP_ID: $AZURE_APP_ID AZURE_PASSWORD: $AZURE_PASSWORD AZURE_TENANT_ID: $AZURE_TENANT_ID AZURE_AKS_NAME: "demo-aks" AZURE_RESOURCE_GROUP: "demo-rg" KUBECTL_COMMAND: 'apply' KUBERNETES_SPEC_FILE: 'test.yaml'
3. 修改Pod配置,引用ImagePullSecret
更新你的test.yaml,在Pod的spec中添加imagePullSecrets字段,指定刚才创建的Secret名称:
apiVersion: v1 kind: Pod metadata: name: test labels: app: test spec: imagePullSecrets: - name: dockerhub-secret # 和创建的Secret名称一致 containers: - name: test image: myrepository/test:1234 command: ["/bin/sleep", "3650d"] imagePullPolicy: IfNotPresent restartPolicy: Always
4. 可选优化:给ServiceAccount配置默认ImagePullSecret
如果不想每个Pod都手动添加imagePullSecrets,可以把Secret配置到默认的ServiceAccount上,这样所有使用该ServiceAccount的Pod都会自动使用这个凭证:
kubectl patch serviceaccount default -p '{"imagePullSecrets": [{"name": "dockerhub-secret"}]}'
完成以上步骤后,重新触发Bitbucket流水线,AKS的kubelet就能用正确的凭证拉取你的私有镜像了。
内容的提问来源于stack exchange,提问作者yatta
相关产品推荐
相关产品推荐

