generate kubeconfig for jenkins

2021-03-02 12:00:44
用户分类

k8s集群里有两种用户

  • 普通用户
  • service account用户

前者在集群外访问使用,是可以作用于全局的,跨 namespace,并且需要在全局唯一
后者在集群内pod使用,是K8S的一种资源,是存在于某个namespace之中的,在不同namespace中可以同名,代表了不同的资源。

创建useraccount
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[root@master01 ssl]# cat jenkins_kubeconfig.sh 
export KUBE_APISERVER="https://lb.whistle.com.cn:6443"

kubectl config set-cluster kubernetes \
--certificate-authority=./ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER} \
--kubeconfig=jenkins.kubeconfig

kubectl config set-credentials kubernetes \
--client-certificate=./server.pem \
--client-key=./server-key.pem \
--embed-certs=true \
--kubeconfig=jenkins.kubeconfig

kubectl config set-context default \
--cluster=kubernetes \
--user=kubernetes \
--kubeconfig=jenkins.kubeconfig

kubectl config use-context default --kubeconfig=jenkins.kubeconfig

执行sh kubeconfig.sh 生成名称为jenkins.kubeconfig的kubeconfig文件

基于RBAC(基于角色访问控制)的授权Authorization,创建以下集群角色,并绑定上面创建的user kubernetes

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
[root@master01 ssl]# cat /root/yaml/jenkins/jenkins_rbac.yml                     
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: jenkins_admin
rules:
- apiGroups: [""]
resources: ["pods","services"]
verbs: ["get", "watch", "list", "delete", "create", "update", "patch"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: ["extensions", "apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: ["networking.k8s.io"]
resources: ["ingresses"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: clusterrolebinding-jenkins_admin
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: jenkins_admin
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: kubernetes
1
2
3
[root@master01 jenkins]# kubectl apply -f jenkins_rbac.yml
clusterrole.rbac.authorization.k8s.io/jenkins_admin created
clusterrolebinding.rbac.authorization.k8s.io/clusterrolebinding-jenkins_admin created

在jenkins ->Manage Jenkins->Manage Credentials-> Add Credentials,选择Secret text,在Secret中填写jenkins.kubecofig,注意需要将文件内容base64编码,这个不是必须,注意在pipeline中使用的时候需要解码

1
2
3
 withCredentials([string(credentialsId: 'local-k8s-kube-config', variable: 'kube_config')]) {
sh 'echo "${kube_config}" | base64 -d > /root/.kube/config'
}
了解一下认证机制和证书过期

k8s 的认证和访问控制包括: 认证 签权 准入控制,全部通过后api 请求会被处理
对于kubeconfig 这种 x509证书来说,只要证书不泄露,可以认为是很安全的
kubeconfig 证书不支持吊销,准确的说 k8s 没有实现CRL(证书吊销列表)或 OCSP(在线证书状态协议),并没有一个统一的地方管理这些证书,因此如果您的密钥被盗用,Kubernetes也无法在身份验证层知道

如何解决这种问题:

重新签发证书,涉及到apiserver 等组件的重启
如果用了 rbac,封禁这个角色的权限

如何预防这种问题:

重要:不要使用最高权限的证书,不要使用自带权限的证书如 system:master,这种只适合kubelet 等组件使用,不适合用来签发 kubeconfig
无论是用 user 还是 service account 来生成kubeconfig,都使用 rbac 来授权,这样就算 kubeconfig 丢失,也可以解除 clusterrolebinding来吊销权限。即管理给用户的授权,就变成管理clusterrolebinding了
证书的过期时间设置的短一点,如 1 个月就失效,将影响范围降低
合理规划主账号和子账户,如主账户只允许有一份 admin 证书,其他子用户全部基于 rbac 来操作,甚至主账户也可以用 rbac 来操作,只是权限特别大而已集成外部认证系统

这里顺便介绍一下如何生成最高权限的kubeconfig
admin-csr.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
"CN": "kubernetes-admin",
"hosts": [
"172.18.0.1","100.64.230.122","100.75.187.77"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "system:masters",
"OU": "cloudnative"
}
]
}

admin 证书

1
cd /etc/kubernetes/pki; cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=demo admin-csr.json | cfssljson -bare admin

生成 admin.conf,即最高权限的 kubeconfig

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 配置kubernetes集群参数

kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/pki/ca.pem \
--embed-certs=true \
--server=https://vip:6443 \
--kubeconfig=admin.conf


# 配置客户端认证参数
kubectl config set-credentials kubernetes-admin \
--client-certificate=/etc/kubernetes/pki/admin.pem \
--embed-certs=true \
--client-key=/etc/kubernetes/pki/admin-key.pem \
--kubeconfig=admin.conf


# 设置上下文参数
kubectl config set-context kubernetes-admin@kubernetes \
--cluster=kubernetes \
--user=kubernetes-admin \
--kubeconfig=admin.conf


# 设置默认上下文
kubectl config use-context kubernetes-admin@kubernetes --kubeconfig=admin.conf


# 将 kubeconfig 拷贝到默认路径~/.kube/下,这是 kubectl 命令寻找 kubeconfig 时的默认路径
# 也可以在 kubectl 中手动指定 kubeconfig 文件。如 kubectl --kubeconfig=zhangsan.conf get cs
mkdir -p ~/.kube; cp admin.conf ~/.kube/config`

证书续签

CA 证书的有效期,默认为 10 年

1
2
 cd /etc/kubernetes/pki
ls | grep ca.crt | xargs -I {} openssl x509 -text -in {} | grep "Not After"

查看当前证书有效期

1
kubeadm alpha certs check-expiration

重新签发证书:续签全部证书

1
kubeadm alpha certs renew all

如果不是 kubeadm 创建的集群,需要手动重新生成所有组件的证书

1
2
3
4
5
6
7
8
9
10
11
12
13
14
1.配置kube-controller-manager支持轮换
kube-controller-manager --experimental-cluster-signing-duration=87600h \
--feature-gates=RotateKubeletClientCertificate=true \
...

2.配置kubelet 证书
# Refer https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/#approval

3.配置 kubelet 的启动参数
kubelet --feature-gates=RotateKubeletClientCertificate=true \
--cert-dir=/var/lib/kubelet/pki \
--rotate-certificates \
--rotate-server-certificates \
...


k8s中手动创建kubeconfig供jenkins使用
kubeconfig使用
K8S 集群中的认证、授权与 kubeconfig
手动创建 k8s kubeconfig 文件以实现多环境切换
K8s之配置文件kubeconfig生成
使用serviceaccount制作kubeconfig文件
使用 kubeconfig 或 token 进行用户身份认证