jenkins 连接 eks 集群

jenkins master 在 eks 外部

eks 授权认证 讲解

官方参考链接

eks 的授权认证体系还是比较麻烦的;

img

Amazon EKS 使用 IAM 向Kubernetes 集群提供身份验证,但实际的认证和授权,还是依赖K8S自身的RBAC。因此当客户端发起请求时分为两个步骤,认证和授权。

具体认证、授权步骤如下:

  1. 安装16.156版本以上的AWS Cli
  2. 查找本地环境~/.kube目录下的config文件(kubeconfig)
  3. config文件中包含api server的endpoint与CA以及通过何种方式获得token。该实验使用的aws eks get-token
  4. IAM的sts服务根据客户端当前用户或角色返回临时token
  5. 客户端用临时token发出请求到EKS的API server
  6. API通过authenticator server通过webhook方式向IAM获取实体(用户、组、ServiceAccount)确认
  7. IAM返回用户/角色的ARN
  8. 通过authenticator server在事先定义的configmap中做用户认证
  9. 认证通过后根据事先定义的Role和Role Binding做授权

jenkins 连接 eks 具体步骤

如上所知,jenkins 想要连接 eks 需要:

  1. aws iam 访问eks的权限
  2. kubeconfig
  3. eks 中定义 用户/角色绑定 授权

1. 创建 aws iam 用户 并 赋予 其对eks的访问权限(get-token权限)

img

登陆console到IAM创建一个新用户ekssec01,并获取其AKSK,授权其对eks集群的访问权限;

2. 绑定IAM用户到K8s

接下来,我们将定义一个名为 ekssecuser01 用户的 k8s 用户,并映射到其 IAM 用户对应方。运行以下文件以获取现有的配置文件,并保存到一个名为 aws-auth.yaml 的文件中:

kubectl get configmap -n kube-system aws-auth -o yaml | grep -v "creationTimestamp\|resourceVersion\|selfLink\|uid" | sed '/^  annotations:/,+2 d' > aws-auth.yaml

接下来将 rbac 用户映射附加到现有配置映射

⚠️:这里填写时 并不一定追加到该文件的最后,如果 eks 原本有 mapUser 的配置,应该将其追加到该配置的最后,而不是文件最后

# 将如下内容填入 aws-auth.yaml 文件,
data:
  mapUsers: |
    - userarn: arn:aws:iam::${ACCOUNT_ID}:user/ekssec01
      username: ekssecuser01

填写完的 aws-auth.yaml 文件内容应该如下:

    - groups:
      - system:bootstrappers
      - system:nodes
      rolearn: arn:aws:iam::xxxxx:role/eksctl-nodegroup-es-NodeInstanceRole-xxxx
      username: system:node:{{EC2PrivateDNSName}}
  mapUsers: |
    - groups:
      - jenkins-deployment
      userarn: arn:aws:iam::xxx:user/AmazonEKSDeveloper
      username: AmazonEKSDeveloper
    - groups:
      - system:masters
      userarn: arn:aws:iam::xxx:user/xxx
      username: testuser
      # 这是添加完的内容;其中 xxx 填写为 账号的 ACCOUNT_ID
    - userarn: arn:aws:iam::xxxx:user/ekssec01
      username: ekssecuser01
kind: ConfigMap
metadata:
  managedFields:
  - apiVersion: v1
    fieldsType: FieldsV1
    ......

将AKSK通过aws configure配置到ec2客户端。配置前可以通过aws sts get-caller-identity命令查看当前用户,配置后再输入该命令确认用户已经更改。用户更改后执行如下命令

img

上面报错说明该用户还没有认证

接下来,我们通过aws configure切换回有权限的用户A,并应用ConfigMap将此映射应用于系统:

# 这里一定要注意,aws-auth 文件的正确性。为了安全起见,执行之前先对比线上 aws-auth 有没有配置错误;
# kubectl apply -f aws-auth.yaml

# 另外建议直接通过 edit 命令线上修改添加用户 iam 的绑定,执行aws-auth的话,存在风险
kubectl -n kube-system edit configmap aws-auth

3. 测试新用户

行以下命令:aws sts get-caller-identity,确保以 ekssec01用户的身份调用 API:

kubectl get pods -n rbac-test

img

说明该用户已经认证但未授权

4. 创建角色绑定

这里偷个懒,直接使用 eks 集群原有的 role 去绑定 我们新建的用户

cat jenkins-cicd-eks-rbacuser-ClusterRoleBinding.yaml
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: read-pods
subjects:
- kind: User
  name: ekssecuser01
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io

jenkins role 所需要的权限如下:

kubectl get clusterrole jenkins-deployment  -o yaml 
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: jenkins-deployment
rules:
- apiGroups:
  - '*'
  resources:
  - statefulsets
  - services
  - replicationcontrollers
  - replicasets
  - podtemplates
  - podsecuritypolicies
  - pods
  - pods/log
  - pods/exec
  - podpreset
  - poddisruptionbudget
  - persistentvolumes
  - persistentvolumeclaims
  - jobs
  - endpoints
  - deployments
  - deployments/scale
  - daemonsets
  - cronjobs
  - configmaps
  - namespaces
  - events
  - secrets
  verbs:
  - create
  - get
  - watch
  - list
  - patch
  - update
- apiGroups:
  - ""
  resources:
  - nodes
  verbs:
  - get
  - list
  - watch
  - update

5. 验证角色和绑定

现在,用户、角色和 RoleBinding 已定义,换回 ekssec01 用户并进行测试。

aws sts get-caller-identity
# 您应该看到反映您已登录为 ekssec01 用户的输出。

> kubectl get pods 
NAME                                READY   STATUS    RESTARTS   AGE
centos7-test-8d9fc797f-8wcvh        1/1     Running   0          28d
counter                             1/1     Running   0          6d17h
kubectl-645999c9f9-gs6x6            1/1     Running   0          71d
my-nginx-5b56ccd65f-cp4n2           1/1     Running   0          15d
my-nginx-5b56ccd65f-dqjgv           1/1     Running   0          38d
nginx-deployment-66b6c48dd5-6skxq   1/1     Running   0          6d23h
nginx-deployment-66b6c48dd5-bffss   1/1     Running   0          6d23h

6. jenkins master 配置 eks 连接

jenkins 机器上,

切换到 jenkins 用户之后,配置 ekssecuser01 用户 aws aksk

-bash-4.2$ aws configure
AWS Access Key ID [****************6BOP]:
AWS Secret Access Key [****************EdTb]:
Default region name [us-west-2]:
Default output format [None]:
-bash-4.2$ id
uid=995(jenkins) gid=991(jenkins) groups=991(jenkins)

# 更新 kubeconfig 到本地;ekssecuser01 需要有该权限
aws eks update-kubeconfig     --region us-west-2     --name eksclustername
# 更新kubeconfig 到指定文件
aws eks update-kubeconfig     --region us-west-2     --name eksclustername     --kubeconfig jenkins.kubeconfig

Jenkins 添加凭据,导入 jenkins.kubeconfig 文件;

image-20220729112907665

jenkins 配置 eks 集群 信息

image-20220729113039273

image-20220801105202081

这里需要填写 jenkins 的具体端口:http://jenkins-hk.nqspace.com:8080 不然会报错;

点击链接测试,可以看到能获取 eks 的版本信息。表明连接成功;

kubenetes 地址:kubeconfig 中有写;

命名空间:这里我指定了 cicd 工具所在的命名空间;可以根据自己情况,再定;

确定 jenkins agnetd 通信端口

image-20220801104116030

这里指定 jenkins agent 的通讯端口为 50000;然后 jenkins master 上安全组(防火墙)要开放 50000端口;

参考链接

EKS认证与授权实践 | 亚马逊AWS官方博客 (amazon.com)

[EKS 授权管理 – 云云众生 (yylives.cc)](http://yylives.cc/2020/11/24/eks-authz/#:~:text=EKS 授权管理 使用云服务提供的 Kubernetes 集群都要解决一个问题,即将云服务的账号映射到 kubernetes 集群,然后给相应的用户授权。,在 EKS 中,通过 eksctl 创建的集群会自动把创建者加到 system%3Amasters 组中,拥有最高的权限。)