简体   繁体   English

如何让k8s Pod(Jenkins生成)使用Service account IAM角色访问AWS资源

[英]How to make k8s Pod (generated by Jenkins) use Service account IAM role to access AWS resources

Follow this link , I can create a pod whose service account's role can access the AWS resources;按照此链接,我可以创建一个 pod,其服务帐户的角色可以访问 AWS 资源; so the pod can access them either.所以 pod 也可以访问它们。

Then, inspired by this EKS-Jenkins-Workshop , I change this workshop a little bit.然后,受此EKS-Jenkins-Workshop 的启发,我对这个研讨会进行了一些更改。 I want to deploy Jenkins Pipeline, this Jenkins Pipeline can create a pod whose account service's role can access aws resources, but the problem is the cdk code in this pod cannot access AWS resources.我想部署Jenkins Pipeline,这个Jenkins Pipeline可以创建一个pod,其账户服务的角色可以访问aws资源,但是问题是这个pod中的cdk代码无法访问AWS资源。 (I write the cdk code to access AWS resources, reference (Your first AWS CDK app)[https://docs.aws.amazon.com/cdk/latest/guide/hello_world.html]) (我写了访问AWS资源的cdk代码,参考(你的第一个AWS CDK应用)[https://docs.aws.amazon.com/cdk/latest/guide/hello_world.html])

This is my Jenkinsfile这是我的 Jenkinsfile

pipeline {
  agent {
    kubernetes {
      yaml """
apiVersion: v1
kind: Pod
metadata:
  name: jenkins-agent
  Namespace: default
spec:
  serviceAccountName: jenkins
  containers:
  - name: node-yuvein
    image: node
    command:
    - cat
    tty: true
"""
    }
  }

  stages {
    stage('Build') {
      steps {
        container('node-yuvein') {
          dir('hello-cdk'){
            sh "pwd"
            sh 'npm --version'
            sh 'node -v'
            sh 'npm install -g typescript'
            sh 'npm install -g aws-cdk'
            sh 'npm install @aws-cdk/aws-s3'
            sh 'npm run build'
            sh 'cdk deploy'
          }
        }
      }
    } 
  }
}

When I run the pipeline, it has this error:当我运行管道时,它有这个错误:

User: arn:aws:sts::450261875116:assumed-role/eksctl-eksworkshop-eksctl3-nodegr-NodeInstanceRole-1TCVDYSM1QKSO/i-0a4df3778517df0c6 is not authorized to perform: cloudformation:DescribeStacks on resource: arn:aws:cloudformation:us-west-2:450261875116:stack/HelloCdkStack/*

I am a beginner of K8s, Jenkins and cdk.我是 K8s、Jenkins 和 cdk 的初学者。 Hope someone can help me.希望可以有人帮帮我。 Thanks a lot.非常感谢。

Further Debugging:进一步调试:

  1. In Jenkins Console, I can get serviceAccountName: "jenkins" , and the name of my service account in EKS is jenkins .在 Jenkins Console 中,我可以得到serviceAccountName: "jenkins" ,我在 EKS 中的服务帐户的名称是jenkins
  2. the pod also get correct ENV: pod 也得到正确的 ENV:
+ echo $AWS_ROLE_ARN
arn:aws:iam::450261875116:role/eksctl-eksworkshop-eksctl3-addon-iamservicea-Role1-YYYFXFS0J4M2

+ echo $AWS_WEB_IDENTITY_TOKEN_FILE
/var/run/secrets/eks.amazonaws.com/serviceaccount/token
  1. The node.js and npm I installed are the lastest version.我安装的 node.js 和 npm 是最新版本。
+ npm --version
6.14.8

+ node -v
v14.13.0
+ aws sts get-caller-identity
{
    "UserId": "AROAWRVNS7GWO5C7QJGRF:botocore-session-1601436882",
    "Account": "450261875116",
    "Arn": "arn:aws:sts::450261875116:assumed-role/eksctl-eksworkshop-eksctl3-addon-iamservicea-Role1-YYYFXFS0J4M2/botocore-session-1601436882"
}

when I run this command, it appears my service account role.当我运行此命令时,它出现了我的服务帐户角色。 But I still get the original error.但我仍然得到原始错误。

Jenkins podTemplate has serviceAccount option: https://github.com/jenkinsci/kubernetes-plugin#pod-and-container-template-configuration Jenkins podTemplateserviceAccount选项: https : //github.com/jenkinsci/kubernetes-plugin#pod-and-container-template-configuration

  • Create an IAM role mapped to an EKS cluster创建映射到 EKS 集群的 IAM 角色
  • Create a ServiceAccount mapped to an IAM role创建映射到 IAM 角色的 ServiceAccount
  • Pass ServiceAccount name to a podTemplate将 ServiceAccount 名称传递给 podTemplate

Further debugging:进一步调试:

  1. Ensure the pod has correct service account name.确保 pod 具有正确的服务帐户名称。
  2. Check if pod got AWS_ROLE_ARN and AWS_WEB_IDENTITY_TOKEN_FILE env vars (they are added automatically).检查 pod 是否有AWS_ROLE_ARNAWS_WEB_IDENTITY_TOKEN_FILE变量(它们是自动添加的)。
  3. Check if AWS SDK you use is above the minimal version: https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-minimum-sdk.html检查您使用的 AWS SDK 是否高于最低版本: https : //docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-minimum-sdk.html
  4. Run aws sts get-caller-identity to see the role, don't waste time on running an actual job.运行aws sts get-caller-identity以查看角色,不要浪费时间运行实际作业。

In the case of working with Jenkins slaves, one needs to customize the container images to use AWS CLI V2 instead of AWS CLI V1.在使用 Jenkins slave 的情况下,需要自定义容器映像以使用 AWS CLI V2 而不是 AWS CLI V1。 I was running into errors related to authorization like the question poses;我遇到了与问题相关的授权错误; my client was using the cluster node roles instead of using the assumed web identity role of my service account attached to my Jenkins-pods for the slave containers.我的客户端使用集群节点角色,而不是使用附加到我的 Jenkins-pod 的服务帐户的假定 Web 身份角色作为从属容器。

Apparently V2 of the AWS CLI includes the web identity token file as part of the default credentials chain whereas V1 does not.显然,AWS CLI 的 V2 包含 Web 身份令牌文件作为默认凭证链的一部分,而 V1 没有。

Here's a sample Dockerfile that pulls the latest AWS CLI version so this pattern works.这是一个示例 Dockerfile,它提取最新的 AWS CLI 版本,以便此模式起作用。

FROM jenkins/inbound-agent

# run updates as root
USER root

# Create docker group
RUN addgroup docker

# Update & Upgrade OS
RUN apt-get update
RUN apt-get -y upgrade

#install python3
RUN apt-get -y install python3


# add AWS Cli version 2 for web_identity_token files
RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
RUN unzip awscliv2.zip
RUN ./aws/install

# Add Maven
RUN apt-get -y install maven --no-install-recommends

# Add docker
RUN curl -sSL https://get.docker.com/ | sh
RUN usermod -aG docker jenkins

# Add docker compose
RUN curl -L "https://github.com/docker/compose/releases/download/1.26.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
RUN chmod +x /usr/local/bin/docker-compose


# Delete cached files we don't need anymore:
RUN apt-get clean
RUN rm -rf /var/lib/apt/lists/*

# close root access
USER jenkins

Further, I had to make sure my serviceaccount was created and attached to both the Jenkins master image and the jenkins slaves.此外,我必须确保我的 serviceaccount 已创建并附加到 Jenkins 主映像和 jenkins slaves。 This can be accomplished via Manage Jenkins -> Manage Nodes and Clouds -> Configure Clouds -> Pod Template Details.这可以通过管理 Jenkins -> 管理节点和云 -> 配置云 -> Pod 模板详细信息来完成。

Be sure to edit Namespace and Serviceaccount fields with the appropriate values.请务必使用适当的值编辑 Namespace 和 Serviceaccount 字段。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM