• Jenkins连接k8s的多种姿势


    1、概述

    本文分享的是基于k8s环境与jenkins实现CI/CD其中的一个配置具体实现

    即:不同环境下jenkins与k8s集群连接的问题

    为什么会有不同的环境?我总结的原因如下:

    a、在实际生产环境中,由于某些历史原因我们或许不能完美的实现所谓的一切皆“云原生”,例如有传统的jenkins和执行专有任务的slave节点

    b、存在多集群共一个jenkins服务端的情况,例如k8s中集群A用作基础设施集群(包含日志、存储、devops平台),集群BCD用作不同业务线集群

    因此,我们可以将不同环境定义为如下两种情况:

    • 同集群:指k8s集群内部的jenkins连接本集群

    • 跨集群:指外部的jenkins连接k8s集群,或者是jenkins连接外部的k8s集群

    2、同集群

    同集群下,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 template是默认情况下jenkins slavepod模板,当然也可以在每个流水线中单独指定

    配置完成后的动态创建jenkins slave pod测试在本文后面一并给出

    3、跨集群

    一个实际场景:jenkins部署在A集群或部署在传统VM的环境下,想通过jenkins连接B集群,动态创建pod用以执行构建任务

    3.1 端口有什么

    既然是跨集群,那么首先需要考虑的就是网络问题,网络是否可达?需要开通哪些端口的安全组策略?

    在这之前,就需要先了解一下jenkins的运行机制及端口有哪些?

    • http端口:默认8080,如果在jenkins前面做了反向代理并配置了域名,那么可能是常见的80/443端口,我这里通过域名+https的方式访问jenkins

    • Agent Port:基于JNLPJenkins代理通过TCP默认端口50000Jenkins进行通信

    • SSH port:jenkins作为ssh服务器,这个一般不会使用,具体使用可参考我之前的文章Jenkins workflowLibs库的使(妙)用

    3.2 网络策略打通

    由上面知道了有哪些端口之后,因此需要打通的网络策略包括

    • B集群节点连接jenkins暴露的http portAgent port
    • A集群节点(即jenkins server)连接B集群kube-apiserver暴露的端口

    除网络策略之外,如果jenkins UI的地址,例如通过ingress设置了白名单限制访问,还需要将B集群的相关源ip设置为白名单

    3.3 证书的生成和配置

    3.3.1 kubeconfig文件

    由于这里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.crtclient.crtclient.key

    3.3.2 生成证书

    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相关配置后验证会报错

    3.3.3 导入证书

    生成文件后,打开jenkinsweb界面

    添加全局凭据,凭据的类型选择Certificate,选择Upload PKCS#12 certificate

    上传刚才生成的cert.pfx证书文件

    输入通过openssl生成证书文件时输入的密码

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

    3.4 配置连接外部的k8s集群

    jenkins中新增kubernetes云配置

    同样的,打开jenkins——>系统管理——>系统配置——>新增一个kubernetes

    配置名称,即这个云的别名,为外部的k8s集群起一个别名

    Kubernetes地址,这里需要填写的是外部集群的kube-apiserver地址,即https://<master ip>:6443

    Kubernetes服务证书key,填写上面服务端证书base64解码后的内容

    Kubernetes命名空间,填写jenkins所属的namespace

    凭据选择上面导入的证书文件作为凭据

    Jenkins地址,填写A集群现有jenkins UI域名(访问地址和端口)

    配置完成后点击测试连接成功,到这里跨集群的jenkins连接k8s就成功了

    4、测试验证

    4.1 配置pod template

    这里以跨集群的环境下进行测试验证A集群的jenkins执行构建任务,在B集群中动态创建slave的预期结果

    jenkins系统配置中,除了配置关联外部集群外,这里再配置一下相应的pod template,以便于在B集群中创建默认的slave pod,如图

    4.2 自由风格构建测试

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

    4.3 流水线构建测试

    编写测试的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
                      """
                    }
                }
            }
        }
    }
    

    构建后查看控制台输出

    到这里,基于不同基础环境下jenkinsk8s连接配置的相关操作就分享完啦

    See you ~

  • 相关阅读:
    3305: Hero In Maze II (优先队列+bfs)
    2016年5月8日 GDCPC省赛总结
    POJ 2361 Tic Tac Toe
    about 字节
    KMP模式匹配
    scau 8616 汽车拉力比赛
    海盗分金--大于半数才成立
    scau 10692 XYM-入门之道
    函数模板和类模板成员函数的定义通常放在头文件中
    c语言运算符优先级巧记
  • 原文地址:https://www.cnblogs.com/ssgeek/p/15101419.html
Copyright © 2020-2023  润新知