【问题标题】:How to auto deploy Docker containers from Amazon ECR to Kubernetes using Jenkins如何使用 Jenkins 将 Docker 容器从 Amazon ECR 自动部署到 Kubernetes
【发布时间】:2018-09-14 05:15:39
【问题描述】:

这是我们的环境:

  1. 我有一个在 Amazon 上运行的 Kubernetes 集群。
  2. 在 Amazon 上运行的 Jenkins CI/CD 连接到私有 GitLab 并将我们的服务构建为 Docker 映像。
  3. 存储我们的 Docker 映像的 Amazon ECR。

我的问题:

  1. 当 Jenkins 管道将新建的镜像推送到 ECR 后,如何将镜像从 ECR 自动部署到 Kubernetes(作为 pod)?
  2. 我可以在 Jenkins 管道中执行此操作吗?我已经阅读了很多资料,但我找不到应该怎么做。

还有像 Keel 这样的第 3 方工具,但它不支持 Amazon ECR(ECR 的 Webhook 问题)。

任何帮助将不胜感激。

【问题讨论】:

    标签: jenkins kubernetes devops continuous-deployment aws-ecr


    【解决方案1】:

    我有类似的工作流程,希望这可以帮助您找到方向。我正在为 CI 使用 bitbucket 管道,但我相信 Jenkins 也能正常工作。

    这就是我在 CI 流程中所做的:

    • 构建我的代码并安装依赖项
    • 创建一个具有唯一标签 (commit-id) 的容器 > my-cntnr:12
    • 推送到 ECR
    • Curl Rancher API for my-pod > set(image:my-cntnr:12)
    • Kubernates 更新 pod 并从 ECR 中拉取标签为 12 的容器

    这是供参考的脚本:

          - composer install --no-interaction
          - docker build -t cms .
          - docker tag myrepo:latest 123456789.dkr.ecr.my-region.amazonaws.com/myrepo:$BITBUCKET_BUILD_NUMBER
          - aws ecr get-login --no-include-email --region my-region >> login.sh
          - sh login.sh
          - docker push 123456799.dkr.ecr.my-region.amazonaws.com/myrepo:$BITBUCKET_BUILD_NUMBER
          - sh .docker/workload-update.sh // my curl script calling rancher API
    

    注意:由于我使用的是 Rancher,我可以使用 Rancher API 来更新 pod 和 他们的配置。


    现在,对于 Kubernetes 的 ECR 凭证部分,您必须创建一个密钥(仅限 Kubernetes 实体),该密钥是使用您的 AWS ECR 详细信息创建的。然后你可以在你的 pod.yml 中使用这个秘密作为 image-pull-secret。这将告诉 k8 使用秘密并从 ECR 中提取图像

    我有一个简单的脚本可以快速完成。

    #
    # RUN me where kubectl is available,& make sure to replace account,region etc
    #
    ACCOUNT=123456789
    REGION=my-region
    SECRET_NAME=${REGION}-ecr-registry
    EMAIL=email@email.com ( can be anything)
    
    #
    # Fetch token (which will expire in 12 hours)
    #
    
    TOKEN=`aws ecr --region=$REGION get-authorization-token --output text --query authorizationData[].authorizationToken | base64 -d | cut -d: -f2`
    
    #
    # Create or replace registry secret
    #
    
    kubectl delete secret --ignore-not-found $SECRET_NAME
    kubectl create secret docker-registry $SECRET_NAME \
     --docker-server=https://${ACCOUNT}.dkr.ecr.${REGION}.amazonaws.com \
     --docker-username=AWS \
     --docker-password="${TOKEN}" \
     --docker-email="${EMAIL}"
    

    这就是你如何在你的 pod.yml 中使用它

    apiVersion: v1
    kind: Pod                                            
    metadata:
      name: my-app   
      labels:
        app: my-app                              
    spec:                                                
      containers:
        - image: 123456789.dkr.ecr.my-region.amazonaws.com/my-repo
          name: -cntnr                            
          ports:
            - containerPort: 8080    
      imagePullSecrets:
      - name: my-secret-name ( this will be same as name of secret we created earlier)
    

    我也写了一篇关于这个过程的详细文章。请找here

    【讨论】:

    • 非常简单的解决方案。谢谢
    • 很好的答案和博客。谢谢!
    【解决方案2】:

    是的,这是可能的。您可以将 Amazon ECR 用于您的 Kubernetes 集群,但您需要 create a secret with credentials。您可以为 Jenkins 开发一个管道,它将自动将更新部署到您的 Kubernetes 集群。为此,您需要配置触发器,例如成功完成构建图像的先前管道。您可以使用 kubernetes-plugin 来开发您的管道,或者您可以使用新的图像标签调用 kubectl update。您可以使用默认的部署更新或第 3 方工具更新您的集群,例如 helm

    *更新

    有一个很好的文档:Using AWS EC2 Container Registry. 对于 Jenkins 和 Kubernetes,我建议您使用 kube2iam,它有助于避免授权令牌过期。 为 Kubernetes 节点和 Jenkins 创建自定义角色,也不要忘记为 kube2iam 添加分配角色的权限。

    【讨论】:

    • 感谢您的回复。 Kubernetes 文档针对 AWS 写的不是很好,大部分材料默认是针对 GKE 的。 AWS ECR 的身份验证机制完全不同。在将映像推送到 AWS ECR 之前,您应该运行以下 shell 命令进行身份验证:$(aws ecr get-login --region us-east-2 --no-include-email)
    • 我刚刚用其他信息更新了答案
    【解决方案3】:

    如果您想了解如何使用 GitOps 在 Kubernetes 上的多个环境中实现 CI/CD 自动化,以便在环境之间进行升级,并在 Pull Requests 上预览环境,您可能想查看my recent talk on Jenkins X at DevOxx UK,我在 GKE 上对此进行了现场演示。虽然 Jenkins X 在 AWS, AKS and GKE and other kubernetes clusters too 上工作。

    当您将更改合并到主分支时,Jenkins X 会为您的应用创建一个新的语义版本化分发(pom.xml、jar、docker 映像、helm 图表)。然后,管道会自动生成拉取请求,以通过 GitOps 在所有环境中推广您的应用程序。然后,您可以决定在应用发布管道完成后回滚版本(因为还有一个环境管道)。

    【讨论】:

      【解决方案4】:

      非常有帮助 - 谢谢。一个快速补充:如果您使用命名空间,则需要将 -n <namespace> 添加到每个 kubectl 命令才能使其工作。我在您的 Medium 文章中的 cron 作业脚本中添加了一个 NAMESPACE 环境变量来处理这个问题。

      例子:

      ACCOUNT=123456789876
      REGION=your-region
      NAMESPACE=your-namespace
      SECRET_NAME=${REGION}-ecr-registry
      EMAIL=dummy.email@email.com
      TOKEN=`aws ecr get-login --region ${REGION} --registry-ids ${ACCOUNT} | cut -d' ' -f6`
      echo "ENV variables setup done."
      kubectl delete secret --ignore-not-found $SECRET_NAME -n $NAMESPACE
      kubectl create secret docker-registry $SECRET_NAME -n $NAMESPACE \
      --docker-server=https://${ACCOUNT}.dkr.ecr.${REGION}.amazonaws.com \
      --docker-username=AWS \
      --docker-password="${TOKEN}" \
      --docker-email="${EMAIL}"
      echo "Secret created by name. $SECRET_NAME"
      kubectl patch serviceaccount default -p '{"imagePullSecrets":[{"name":"'$SECRET_NAME'"}]}' -n $NAMESPACE
      echo "All done."
      

      【讨论】:

        猜你喜欢
        • 2021-06-24
        • 1970-01-01
        • 2016-05-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-25
        相关资源
        最近更新 更多