部署Bitbucket代码至GKE时遭遇MANIFEST UNKNOWN错误及后续问题
Bitbucket代码部署GKE失败问题排查与修复
初始配置问题(MANIFEST UNKNOWN错误)
初始cloudbuild.yaml直接使用gke-deploy部署,但存在两个核心问题:
- 未先构建并推送Docker镜像到GCR,Kubernetes拉取镜像时找不到对应版本,触发MANIFEST UNKNOWN错误
deployment.yaml中的SHORT_SHA是硬编码字符串,未被替换为实际的提交哈希值
更新后配置的问题
调整后的cloudbuild.yaml新增了镜像构建步骤,但仍有多处错误:
- Docker Push命令错误:标签重复写了
$SHORT_SHA,正确格式应为gcr.io/${_TECH_RADAR_PROJECT_ID}/technology-radar-be/master:$SHORT_SHA,而非:$SHORT_SHA:$SHORT_SHA - Sed替换变量错误:
$master是未定义的环境变量,若固定使用master分支可直接写master,否则应使用Cloud Build内置的$BRANCH_NAME变量;同时替换目标${_TECH_CONTAINER_IMAGE}在deployment.yaml中不存在,原配置里是硬编码的SHORT_SHA字符串 - 缺少Maven构建步骤:云端构建环境未执行
mvn package生成target/docker-demo.jar,Dockerfile直接复制该文件会导致构建失败 - 镜像地址不一致:构建、推送、替换的镜像地址未统一,导致Kubernetes无法拉取正确镜像
核心修复方案
1. 修复Dockerfile(整合Maven构建)
将Maven构建过程嵌入Dockerfile,确保云端构建时能自动生成jar包,无需依赖本地构建产物:
FROM maven:3.8.2-jdk-11 as builder WORKDIR /app # 先复制pom.xml下载依赖,利用Docker缓存加速构建 COPY pom.xml . RUN mvn dependency:go-offline # 复制源码并打包 COPY src ./src RUN mvn package -DskipTests # 使用轻量的JRE镜像运行应用 FROM openjdk:11-jre-slim ARG JAR_FILE=target/docker-demo.jar COPY --from=builder /app/${JAR_FILE} app.jar ENTRYPOINT ["java", "-jar", "/app.jar"]
2. 修正cloudbuild.yaml
substitutions: _CLOUDSDK_COMPUTE_ZONE: us-central1-c _CLOUDSDK_CONTAINER_CLUSTER: kubernetes-cluster-test _TECH_RADAR_PROJECT_ID: java-kubernetes-clusters-test # 补充默认项目ID steps: # 构建Docker镜像 - id: 'build image' name: 'gcr.io/cloud-builders/docker' args: ['build', '-t', 'gcr.io/${_TECH_RADAR_PROJECT_ID}/technology-radar-be:${SHORT_SHA}', '.'] # 推送镜像到GCR - id: 'push image' name: 'gcr.io/cloud-builders/docker' args: ['push', 'gcr.io/${_TECH_RADAR_PROJECT_ID}/technology-radar-be:${SHORT_SHA}'] # 替换deployment.yaml中的镜像地址 - id: 'replace image in deployment' name: 'ubuntu' args: ['bash','-c','sed -i "s|gcr.io/java-kubernetes-clusters-test/bitbucket.org/intivetechradar/technology-radar-be:SHORT_SHA|gcr.io/${_TECH_RADAR_PROJECT_ID}/technology-radar-be:${SHORT_SHA}|" deployment.yaml'] # 部署到GKE - name: 'gcr.io/cloud-builders/kubectl' args: ['apply', '-f', 'deployment.yaml'] env: - 'CLOUDSDK_COMPUTE_ZONE=${_CLOUDSDK_COMPUTE_ZONE}' - 'CLOUDSDK_CONTAINER_CLUSTER=${_CLOUDSDK_CONTAINER_CLUSTER}' - 'CLOUDSDK_CORE_PROJECT=${_TECH_RADAR_PROJECT_ID}' options: logging: CLOUD_LOGGING_ONLY
3. 确认deployment.yaml的镜像占位符
确保deployment.yaml中的镜像地址与sed替换的目标字符串一致:
apiVersion: "apps/v1" kind: "Deployment" metadata: name: "java-kubernetes-clusters-test" namespace: "default" labels: app: "java-kubernetes-clusters-test" spec: replicas: 3 selector: matchLabels: app: "java-kubernetes-clusters-test" template: metadata: labels: app: "java-kubernetes-clusters-test" spec: containers: - name: "technology-radar-be-1" image: "gcr.io/java-kubernetes-clusters-test/bitbucket.org/intivetechradar/technology-radar-be:SHORT_SHA"
额外注意事项
- 确保Cloud Build服务账号拥有GKE集群的编辑权限(
roles/container.developer)和GCR的读写权限(roles/storage.objectAdmin) - 构建触发器中需正确配置
_TECH_RADAR_PROJECT_ID等自定义变量,或在substitutions中设置默认值 - 若使用非master分支,可将镜像标签中的分支名改为
${BRANCH_NAME},实现多分支镜像隔离
内容的提问来源于stack exchange,提问作者Krzysztof Michalski
相关产品推荐
相关产品推荐

