使用Azure Pipelines在Kubernetes清单文件中更新Docker映像的正确方法

j8ag8udp  于 2023-10-17  发布在  Kubernetes
关注(0)|答案(2)|浏览(111)

我已经成功地使用Azure Pipelines的Docker任务构建并将Docker镜像推送到Docker Hub。
现在,我想获取Docker镜像并将其部署到AKS中的Kubernetes集群。
我需要使用kubectl apply更新图像。我需要具体使用kubectl apply,而不是replaceeditpatch
如何在实现这一点的同时更新deploy.yml文件中的spec.containers.image

我基本上想把这个变量tag: '$(Build.BuildId)',替换掉deploy.yml中的spec.containers.image,然后运行kubectl apply -f deploy. yml。

下面是我的deploy.yml文件:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myprojectname
  namespace: my-namespace
  labels:
    app: myprojectname
spec:
  replicas: 1
  revisionHistoryLimit: 2
  selector:
    matchLabels:
      web: myprojectname
  template:
    metadata:
      labels:
        app: myprojectname
        web: myprojectname
        type: webapp
    spec:
      containers:
        - name: myprojectname
          image: mydockerhubaccount/myprojectname:25
          resources:
            requests:
              cpu: 20m
              memory: 100Mi
            limits:
              cpu: 500m
              memory: 130Mi
          ports:
            - containerPort: 80

下面是我的azure-pipelines.yml文件:

# Docker
# Build and push an image to Azure Container Registry
# https://learn.microsoft.com/azure/devops/pipelines/languages/docker

trigger:
- master

resources:
- repo: self

variables:
  # Container registry service connection established during pipeline creation
  dockerRegistryServiceConnection: 'Docker Hub'
  imageRepository: 'mydockerhubaccount/myprojectname'
  dockerfilePath: '$(Build.SourcesDirectory)/my-project-name/Dockerfile'
  tag: '$(Build.BuildId)'

  # Agent VM image name
  vmImageName: 'ubuntu-latest'

stages:
- stage: Build
  displayName: Build and push stage
  jobs:
  - job: Build
    displayName: Build
    pool:
      vmImage: $(vmImageName)
    steps:
    - task: Docker@2
      displayName: Build and push an image to container registry
      inputs:
        command: buildAndPush
        repository: $(imageRepository)
        dockerfile: $(dockerfilePath)
        containerRegistry: $(dockerRegistryServiceConnection)
        tags: |
          $(tag)
        buildContext: '$(Build.SourcesDirectory)'
weylhg0b

weylhg0b1#

这可能是一个老问题,但今天仍然有意义。对于“经典”可视化DevOps管道构建器来说,这个过程与YAML步骤构建器基本相同。
一般来说,使用当前版本更新容器镜像标签的方法(不使用“latest”来启用回滚)如下:
1.在发布管道中,记下您的Source Alias。工件是构建过程的结果。如果您的构建过程没有发布工件,请添加默认值:Publish Pipeline Artifact步骤。您可以随意调用源别名,只要它是唯一的,并且空格不重要。
1.在Deploy to Kubernetes的发布管道阶段中,选择正确的清单。
1.然后将Containers字段更新为容器仓库的名称,并添加$(Release.Artifacts.YOUR_SOURCE_ALIAS_HERE.BuildId)作为标记。它应该看起来像这样:YOUR_REPO.azurecr.io/YOUR_CONTAINER_NAME:$(Release.Artifacts.YOUR_SOURCE_ALIAS_HERE.BuildId)
1.当管道部署到K8时,它应该使用构建过程中的最新标记ID。您可以在集群上通过描述您的pod/whatever来确认这一点,例如:kubectl describe pod POD_NAME

YAML部署步骤示例:

steps:
- task: KubernetesManifest@0
  displayName: deploy
  inputs:
    kubernetesServiceConnection: 'YOUR_CONNECTION'
    namespace: 'CLUSTER_NAMEPACE'
    manifests: '$(System.DefaultWorkingDirectory)/YOUR_SOURCE_ALIAS_HERE/Job1/s/whatever-deployment.yml'
    containers: 'YOUR_REPO.azurecr.io/YOUR_CONTAINER_NAME:$(Release.Artifacts.YOUR_SOURCE_ALIAS_HERE.BuildId)'
2skhul33

2skhul332#

为了将Docker镜像名称和版本注入到deployment.yml中,您应该首先为它创建一个占位符。例如,在此部署清单文件示例中:

apiVersion : apps/v1
kind: Deployment
metadata:
  name: <your_k8s_deployment_name>
  namespace: <your_k8s_namespace>
spec:
  replicas: 1
  selector:
    matchLabels:
      app: <your_k8s_namespace>
  template:
    metadata:
      labels:
        app: <your_k8s_namespace>
    spec:
      securityContext:
        runAsNonRoot: true
        runAsUser: 1000
      containers:
        - name: <your_k8s_namespace>
          image: {{DOCKER_IMAGE_NAME}}:{{DOCKER_IMAGE_VERSION}}
          ports:
            - containerPort: 8501

占位符是DOCKER_IMAGE_NAMEDOCKER_IMAGE_VERSION变量。接下来,您需要更新azure-pipelines.yml文件中的这些变量。以下是Azure管道文件的内容片段:

variables:
  dockerRegistryServiceConnection: <your_docker_registry_svc>
  imagePullSecret: <your_imgpull_secret>
  containerRegistryURL: <your_container_registry>.azurecr.io
  imageRepository: <your_image_repository>
  tag: <your_docker_version_tag>
  kubernetesServiceConnection: <your_k8s_svc>
  kubernetesNameSpace: <your_k8s_namespace>
  deploymentPath: <your_manifest_path>
  vmImageName: ubuntu-latest

--- snip ---

- stage: Deploy
  displayName: Deploy stage
  dependsOn: Build
  jobs:
  - job: Deploy
    displayName: Deploy
    pool:
      vmImage: $(vmImageName)
    steps:
    - task: KubernetesManifest@1
      displayName: Create imagePullSecret
      inputs:
        action: createSecret
        kubernetesServiceConnection: $(kubernetesServiceConnection)
        namespace: $(kubernetesNameSpace)
        secretName: $(imagePullSecret)
        dockerRegistryEndpoint: $(dockerRegistryServiceConnection)
    - script: |
        sed -i "s|{{DOCKER_IMAGE_NAME}}|$(containerRegistryURL)/$(imageRepository)|g" $(deploymentPath)
        sed -i "s|{{DOCKER_IMAGE_VERSION}}|$(tag)|g" $(deploymentPath)
      displayName: 'Replace Docker image name and version in deployment manifest file'
    - task: KubernetesManifest@1
      displayName: Deploy to Kubernetes cluster
      inputs:
        action: deploy
        kubernetesServiceConnection: $(kubernetesServiceConnection)
        namespace: $(kubernetesNameSpace)
        imagePullSecrets: $(imagePullSecret) 
        manifests: $(deploymentPath)
        containers: $(containerRegistryURL)/$(imageRepository):$(tag)
        rolloutStatusTimeout: 60

正如您所看到的,这些变量是使用sed Linux命令设置的。* *
注意:我使用多阶段部署,因此使用dependsOn参数。如果你不想要一个多级管道,那么删除stages和dependsOn参数。

相关问题