
本文分享的是基于k8s环境与jenkins实现CI/CD其中的一个配置具体实现
即:不同环境下jenkins与k8s集群连接的问题
为什么会有不同的环境?我总结的原因如下:
a、在实际生产环境中,由于某些历史原因我们或许不能完美的实现所谓的一切皆“云原生”,例如有传统的jenkins和执行专有任务的slave节点
b、存在多集群共一个jenkins服务端的情况,例如k8s中集群A用作基础设施集群(包含日志、存储、devops平台),集群B、C、D用作不同业务线集群
因此,我们可以将不同环境定义为如下两种情况:
同集群:指k8s集群内部的jenkins连接本集群
跨集群:指外部的jenkins连接k8s集群,或者是jenkins连接外部的k8s集群
同集群下,k8s集群内部的jenkins连接所在的k8s集群。这是原生的方式:我们的环境都是全新的,全新的机器、全新安装的集群、全新的jenkins,总之一切都是新的,没有任何历史问题
由于在k8s集群内部部署jenkins时,已经对jenkins做了以下相关的角色授权绑定
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: jenkins
namespace: kube-system
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: jenkins
namespace: kube-system
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["create","delete","get","list","patch","update","watch"]
- apiGroups: [""]
resources: ["pods/exec"]
verbs: ["create","delete","get","list","patch","update","watch"]
- apiGroups: [""]
resources: ["pods/log"]
verbs: ["get","list","watch"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
name: jenkins
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: jenkins
subjects:
- kind: ServiceAccount
name: jenkins
namespace: kube-system
因此只需要在jenkins中配置相应的连接地址就可以了
在jenkins中安装好k8s插件后,打开jenkins——>系统管理——>系统配置——>新增一个kubernetes云
配置名称,即这个云的别名
Kubernetes地址,即在集群内部暴露的k8s service名称
Kubernetes命名空间,这个配置就填写jenkins所属的namespace
Jenkins地址,填写jenkins svc的名称

配置完成后点击测试连接成功
后面配置pod template这里不做介绍,这里配置的pod templete是默认情况下jenkins slave的pod模板,当然也可以在每个流水线中单独指定
配置完成后的动态创建jenkins slave pod测试在本文后面一并给出
一个实际场景:jenkins部署在A集群或部署在传统VM的环境下,想通过jenkins连接B集群,动态创建pod用以执行构建任务
既然是跨集群,那么首先需要考虑的就是网络问题,网络是否可达?需要开通哪些端口的安全组策略?
在这之前,就需要先了解一下jenkins的运行机制及端口有哪些?
http端口:默认8080,如果在jenkins前面做了反向代理并配置了域名,那么可能是常见的80/443端口,我这里通过域名+https的方式访问jenkins
Agent Port:基于JNLP的Jenkins代理通过TCP默认端口50000与Jenkins进行通信
SSH port:jenkins作为ssh服务器,这个一般不会使用,具体使用可参考我之前的文章Jenkins workflowLibs库的使(妙)用
由上面知道了有哪些端口之后,因此需要打通的网络策略包括
jenkins暴露的http port和Agent portjenkins server)连接B集群kube-apiserver暴露的端口除网络策略之外,如果jenkins UI的地址,例如通过ingress设置了白名单限制访问,还需要将B集群的相关源ip设置为白名单
由于这里A集群中的jenkins并没有对B集群的操作权限,因此需要配置授权,即发起对B集群的kube apiserver的请求,和kubectl一样利用config文件用作请求的鉴权,默认在~/.kube/config下,当然我们也可以单独严格指定权限细节,生成一个jenkins专用的config文件,这里就不再延伸了,kubeconfig文件的组成如下
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: xxx
server: https://<master-ip>:6443
name: cluster1
contexts:
- context:
cluster: cluster1
user: admin
name: context-cluster1-admin
current-context: context-cluster1-admin
kind: Config
preferences: {}
users:
- name: admin
user:
client-certificate-data: xxx
client-key-data: xxx
其中包含了3段证书相关的内容,也就是我们常见的证书组成格式:ca.crt、client.crt、client.key
在jenkins中能够识别的证书文件为PKCS#12 certificate,因此需要先将kubeconfig文件中的证书转换生成PKCS#12格式的pfx证书文件
首先,使用yq命令行工具来解析yaml并通过base 64解码生成各个证书文件
服务端证书:
certificate-authority-data——>base 64解码——>ca.crt
yq e ‘.clusters[0].cluster.certificate-authority-data‘ .kube/config | base64 -d > ca.crt
客户端证书
client-certificate-data——>base 64解码——>client.crt
yq e ‘.users[0].user.client-certificate-data‘ .kube/config | base64 -d > client.crt
client-key-data——>base 64解码——>client.key
yq e ‘.users[0].user.client-key-data‘ .kube/config | base64 -d > client.key
然后,通过openssl进行证书格式的转换,生成Client P12认证文件cert.pfx
openssl pkcs12 -export -out cert.pfx -inkey client.key -in client.crt -certfile ca.crt
Enter Export Password: # 输入密码加密
Verifying - Enter Export Password:
通过踩坑证明,这里必须输入密码,不然在后面添加jenkins相关配置后验证会报错
生成文件后,打开jenkins的web界面
添加全局凭据,凭据的类型选择Certificate,选择Upload PKCS#12 certificate
上传刚才生成的cert.pfx证书文件
输入通过openssl生成证书文件时输入的密码

检查上传的证书文件,此时可以查看到,jenkins已经成功加载了证书文件并读取了证书文件的相关信息

在jenkins中新增kubernetes云配置
同样的,打开jenkins——>系统管理——>系统配置——>新增一个kubernetes云
配置名称,即这个云的别名,为外部的k8s集群起一个别名
Kubernetes地址,这里需要填写的是外部集群的kube-apiserver地址,即https://<master ip>:6443
Kubernetes服务证书key,填写上面服务端证书base64解码后的内容
Kubernetes命名空间,填写jenkins所属的namespace
凭据选择上面导入的证书文件作为凭据
Jenkins地址,填写A集群现有jenkins UI域名(访问地址和端口)

配置完成后点击测试连接成功,到这里跨集群的jenkins连接k8s就成功了
这里以跨集群的环境下进行测试验证A集群的jenkins执行构建任务,在B集群中动态创建slave的预期结果
在jenkins系统配置中,除了配置关联外部集群外,这里再配置一下相应的pod template,以便于在B集群中创建默认的slave pod,如图

在自由风格中限制项目的运行节点,标签为上面配置的pod template标签即k8s-test-cluster,执行shell命令进行测试,查看控制台输出

编写测试的pipeline流水线,同样指定标签为上面配置的pod template标签即k8s-test-cluster
pipeline{
agent{
node {
label ‘k8s-test-cluster-jnlp-slave‘
}
}
stages{
stage(‘Deploy to Kubernetes‘){
steps{
script{
sh """
kubectl version
kubectl get cs
"""
}
}
}
}
}
构建后查看控制台输出

到这里,基于不同基础环境下jenkins与k8s连接配置的相关操作就分享完啦
See you ~
原文:https://www.cnblogs.com/ssgeek/p/15101419.html