前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Jenkins Operator —— Jenkins 在 Kubernetes 上正确的打开方式

Jenkins Operator —— Jenkins 在 Kubernetes 上正确的打开方式

作者头像
CNCF
发布2021-05-07 16:43:49
1.8K0
发布2021-05-07 16:43:49
举报
文章被收录于专栏:CNCF

入门篇:jenkins-operator 的介绍及安装

前言

本月中旬,Jenkins Operator 正式成为 Jenkins 的子项目[1],这将在很大程度上弥合 Jenkins 和 Kubernetes 之间的鸿沟。

Operator 是 Kubernetes 的一种扩展机制,用户可以利用这种扩展机制来让自己的应用以 Kubernetes native(k8s 原生)的方式在 kubernetes 平台上运行起来。关于 Operator 更多详细的内容,可以在 Kubernetes 官方文档[2]上查看。

Jenkins 是一款社区强大、API & 插件丰富、用户众多且开源的持续交付工具。为了让 Jenkins 能在 Kubernetes 上更好的运行,Jenkins 社区提供了 Jenkins Operator。Jenkins Operator 是基于不可变性和声明式的配置即代码来构建的。关于 Operator 的其他信息可以在Jenkins Operator GitHub 和 Jenkins Operator 官网文档[3]进行查看。

以下演示过程中所涉及的代码均在 https://github.com/majinghe/jenkins-operator.git 库中,须将上述库的代码下载到本地,再执行后续操作。

安装

安装的前提条件:

•一个版本为 1.11+ 的 Kubernetes 集群•kubectl 的版本为 1.11+

第一步:Jenkins CRD 创建

执行以下命令来创建 Jenkins CRD

代码语言:javascript
复制
$ kubectl apply -f jenkins_crd.yaml
customresourcedefinition.apiextensions.k8s.io/jenkins.jenkins.io created
customresourcedefinition.apiextensions.k8s.io/jenkinsimages.jenkins.io created
第二步:Jenkins Operator 的安装

此 Operator 是 jenkins-operator 的核心,主要的目的是用来对 jenkins 这种资源的管理,包括创建、删除等,后续会演示。此 Operator 的安装有两种方式:

•用 kubectl 来完成安装•用 helm 来完成安装

关于两种方式的不同使用命令,可以官网进行查看,本文选择用 kubectl 来完成。先创建一个 namespace:

代码语言:javascript
复制
$ kubectl create ns jenkins$ kubectl create ns jenkins

执行 operator 安装命令:

代码语言:javascript
复制
$  kubectl  -n jenkins apply -f jenkins_operator.yaml
serviceaccount/jenkins-operator created
role.rbac.authorization.k8s.io/jenkins-operator created
rolebinding.rbac.authorization.k8s.io/jenkins-operator created
deployment.apps/jenkins-operator created

查看 jenkins namespace 下面的 pod:

代码语言:javascript
复制
$ kubectl -n jenkins get pods -w
NAME                                READY   STATUS    RESTARTS   AGE
jenkins-operator-548d76f664-hp6pm   0/1     Pending   0          0s
jenkins-operator-548d76f664-hp6pm   0/1     ContainerCreating   0          1s
jenkins-operator-548d76f664-hp6pm   1/1     Running             0          34s
第三步:创建 Jenkins 实例

此时如果创建一个 Jenkins 实例,Operator 就会监听到这个事件,从而根据我们对 Jenkins 实例的描述(Jenkins 实例的描述文件 ,以 yaml 格式出现)来创建实例。关于实例的描述文件的格式内容,可以在这儿进行查看。本文使用的文件及内容解释如下:

代码语言:javascript
复制
apiVersion: jenkins.io/v1alpha2
kind: Jenkins
metadata:
  name: jenkins
spec:
/*configurationAsCode 用来描述 jenkins configruation 部分的内容,比如 Github Server、Slack、LDAP 等的配置。上述内容通过 Jenkins Configuration As Code 的形式来组织的。下文会给大家展示用法*/ 
  configurationAsCode:
    configurations:
    - name: jenkins-config
  serviceAccount:
    annotations:
      kubernetes.io/service-account: jenkins
  master:
    basePlugins:
    /*配置与 master 相关的一些配置,比如想要安装的必要插件*/
    - name: kubernetes
      version: "1.29.2"
    plugins:
    /*配置与 master 相关的一些配置,比如想要安装的其他插件*/
    - name: ldap
      version: "2.4"
    - name: github
      version: "1.33.1"
    containers:
    /*master 容器的配置,包括镜像、资源限制、环境变量等*/
    - name: jenkins-master
      image: jenkins/jenkins:lts
      imagePullPolicy: Always
      env:
      - name: JENKINS_HOME
        value: /var/lib/jenkins
      resources:
        limits:
          cpu: 1500m
          memory: 2Gi
        requests:
          cpu: "1"
          memory: 500Mi

上述文件依赖于 jenkins-config 这个对 jenkins configuration 的描述,需要先创建 jenkins-config 这部分内容,此内容是以 configmap 的形式来描述 jenkins configuration 的配置的,诸如LDAP、GitHub Server 等。具体内容可参考如下:

代码语言:javascript
复制
apiVersion: v1
kind: ConfigMap
metadata:
  name: jenkins-config
data:
  jenkins.yaml: |
    security:
      scriptApproval:
      /*Script Approval 配置部分*/
        approvedSignatures:
        - "method groovy.json.JsonSlurper parse java.io.Reader"
    unclassified:
      slackNotifier:
      /*slack 配置部分*/
        teamDomain: slack-test 
        tokenCredentialId: "slack-token"
      gitHubPluginConfig:
      /*GitHub Server 配置部分*/
        configs:
          - name: "GitHub"
            apiUrl: "https://api.github.com/v3/"
            credentialsId: "github-token"
            manageHooks: true
    jenkins:
      clouds:
      /*kubernetes 配置部分*/
      - kubernetes:
          jenkinsTunnel: "jenkins-operator-slave-jenkins.jenkins.svc.cluster.local:50000"
          jenkinsUrl: "http://jenkins-operator-http-jenkins.jenkins.svc.cluster.local:8080"
          name: "kubernetes"
          namespace: "jenkins"
          retentionTimeout: 15
          serverUrl: "https://kubernetes.default.svc.cluster.local:443"
      systemMessage: "<Cloud Native DevSecOps>"
      securityRealm:
        ldap:
        /*LDAP 配置,根据你的 LDAP 配置信息修改即可*/
          configurations:
            - server: "xxxx"
              rootDN: "xxxx"
              userSearchBase: "xxxx"
              userSearch: "xxxx"
              groupSearchBase: "xxxxxx"
              groupMembershipStrategy:
                fromGroupSearch:
                   filter: ""

接下来只需要将上述内容写入 yaml 文件创建 configmap 即可:

代码语言:javascript
复制
$ kubectl -n  jenkins apply -f config.yaml
configmap/jenkins-config created

随后,创建 Jenkins 实例:

代码语言:javascript
复制
$ kubectl -n jenkins apply -f jenkins.yaml
jenkins.jenkins.io/jenkins created

此时,可以在 operator pod 的 log 中看到如下信息:

代码语言:javascript
复制
021-04-04T08:21:44.049Z    INFO    controller-jenkins    base/pod.go:159    Creating a new Jenkins Master Pod jenkins/jenkins-jenkins    {"cr": "jenkins"}

说明,operator 已经捕获到创建 Jenkins 实例这个事件,随后就会去根据实例的描述来创建,可以查看 jenkins namespace 下面的 pod:

代码语言:javascript
复制
$ kubectl -n jenkins get pods -w
NAME                                     READY   STATUS    RESTARTS   AGE
jenkins-jenkins                          2/2     Running   0          13d
jenkins-operator-548d76f664-hp6pm        1/1     Running   0          13d

发现多了一个 jenkins-jenkins 的pod,这就是创建出来的 jenkins master 的pod。

如果想通过 ingress 来对外暴漏 jenkins 的服务,则可以按照下面的 yaml 文件来创建 ingress 资源:

代码语言:javascript
复制
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
 name: jenkins
 annotations:
   kubernetes.io/ingress.class: "nginx"
   nginx.ingress.kubernetes.io/redirect-to-https: "True"
spec:
 tls:
 - hosts:
   - xiaomage.devops.com
   secretName: jenkins-tls
 rules:
 - host: xiaomage.devops.com
   http:
     paths:
     - path: /
       pathType: Prefix
       backend:
         service:
           name: jenkins-operator-http-jenkins
           port:
             number: 8080

接着通过访问 https://xiaomage.devops.com 来访问 jenkins 界面。登陆的用户名和密码可以通过如下命令获取:

代码语言:javascript
复制
$ kubectl -n jenkins get secrets jenkins-operator-credentials-jenkins -o jsonpath='{.data.user}' | base64 -D
$ kubectl -n jenkins get secrets jenkins-operator-credentials-jenkins -o jsonpath='{.data.password}' | base64 -D

此外,也可以通过 port-forward 的方式来使用 jenkins:

代码语言:javascript
复制
$ kubectl -n jenkins port-forward pods/jenkins-jenkins 8080:8080

直接访问 http://localhost:8080 即可访问 jenkins 界面。获取登陆用户名和密码的方法同上。

至此,通过 jenkins-operator 安装 jenkins 的过程已经完美实现,接下来是使用篇。

进阶篇:使用

传统的使用方法就是在界面上点击创建 jenkins job,然后进行配置,最后再使用。但是 jenkins-operator 提供了另外一个 operator— Seed Jobs,顾名思义,就是能够实现 job 的自动发现。其背后的原理其实是借助 Jenkins Job DSLConfiguration As Code:也即将 job 通过 DSL 来进行描述(描述包括 Job 名称,配置,Pipeline 脚本等),然后将这种描述的代码存放到 GitHub 上。Seed Jobs 根据配置来自动捕获 job 添加的动作,从而完成 job 的创建。

Seed Job 的使用前提是 job 定义文件和 job pipeline 文件需要具有如下的文件目录结构:

代码语言:javascript
复制
cicd/
├── jobs
│   └── job-dsl-file
└── pipelines
    └── pipeline-file

Seed Job 可以通过在 jenkins 的配置文件中添加如下内容来启用:

代码语言:javascript
复制
apiVersion: jenkins.io/v1alpha2
kind: Jenkins
metadata:
  name: jenkins
spec:
  master:
  # 可参考第一部分中的相关配置内容 
  seedJobs:
  - id: Demo
    targets: "cicd/jobs/demo_pipeline.groovy" # job dsl 脚本的位置
    credentialType: basicSSHUserPrivateKey
    credentialID: github-ssh-key
    description: "CI/CD Repo"
    repositoryBranch: main
    repositoryUrl: git@github.com:majinghe/jenkins-operator.git  # cicd 仓库地址

cicd/jobs/demo_pipeline.groovy 描述了 demo job 的配置内容,信息如下:

代码语言:javascript
复制
#!/usr/bin/env groovy
pipelineJob('Demo') {
    # job  名称配置
    displayName('Demo')
    # 构建历史配置
    logRotator {
        numToKeep(10)
        daysToKeep(30)
    }
    # 构建参数,多种类型都支持
    parameters {
        choiceParam('ENV', ['SVT1', 'SVT2'])
        stringParam('Release', 'v1.0.0', 'Please input your release number!')
    }
    # pipeline groovy 脚本的具体信息
    definition {
        cpsScm {
            scm {
                git {
                    remote {
                        url('git@github.com:majinghe/jenkins-operator.git')
                        credentials('github-ssh-key')
                    }
                    branches('*/main')
                }
            }
            # pipeline groovy 在库中的位置
            scriptPath('cicd/pipelines/demo.groovy')
        }
    }
}

上述的 job dsl 描述了一个有两个构建参数的 job,cicd/pipelines/demo.groovy 的内容为:

代码语言:javascript
复制
def label = "jnlp-${UUID.randomUUID().toString()}"

podTemplate(
        label: label,
        serviceAccount: "jenkins",
        namespace: "jenkins",
        containers: [
                containerTemplate(
                        name: 'jnlp',
                        image: 'gbyukg/docker-jnlp-slave:1.0',
                        args: '${computer.jnlpmac} ${computer.name}'
                )
        ]
) {
    node(label) {
        container('jnlp'){
            stage("Hello World"){
                println "This is xiaomage, focus on Cloud Native DevSecOps!!!"
            }
        }
    }
}

这个 job 构建会打印This is xiaomage, focus on Cloud Native DevSecOps!!!然后重新创建 jenkins 资源即可:

代码语言:javascript
复制
$ kubectl -n jenkins apply -f jenkins.yaml

随后即可在 jenkins namespace 下面看到 seed job 的 pod:

代码语言:javascript
复制
$ kubectl -n jenkins get pods
NAME                                      READY   STATUS    RESTARTS   AGE
jenkins-jenkins                           1/1     Running   0          5d # jenkins master pod
jenkins-operator-548d76f664-hp6pm         1/1     Running   0          5d # jenkins operator pod
seed-job-agent-jenkins-7ff6d479db-6gqjl   1/1     Running   0          5d # see job pod

重新登陆 jenkins 就能看到两个 job,一个为Seed Job,一个为最终要真正使用的 Job。

此后,只要 job 有修改,只需要修改 GitHub 上关于job的代码即可,然后重新运行 Seed Job 就能把实际使用 Job 的内容进行更新。构建上述的 demo job 可查看构建日志:

可以看到上述构建输出和 pipeline 中定义的是一致的。这些其实也就做到了一切皆代码。一旦 jenkins 有任何问题,也可以通过重建来快速拉起相应的 job。相当于多一层备份机制(这个只能备份 job,job 历史会丢失,如果需要备份 job 历史,可以给 job 历史目录做持久化或者利用 jenkins-operator 的 backup 和 restore 机制,详细内容可以查看这儿[4])

高阶篇:利用 kustomize + sops(gpg) 来部署 jenkins-operator

上面的流程给大家展示了如何一步步来完成 jenkins-operator 的安装和使用,但是通过 kubectl apply 来一个个创建需要的资源是比较繁琐的,而且在多套差异化环境下,这种重复的工作量没有任何意义。所以本文使用了 kustomize 来管理差异化环境下众多的 yaml 文件,目录结构如下:

代码语言:javascript
复制
.
├── base
│   ├── config.yaml
│   ├── jenkins-rbac.yaml
│   ├── jenkins.yaml
│   ├── jenkins_crd.yaml
│   ├── jenkins_operator.yaml
│   ├── kops-secret.yaml
│   ├── kustomization.yaml
│   └── secret
│       └── credentials.secret.yaml
└── overlays
    ├── dev
    │   ├── ingress.yaml
    │   ├── jenkins.yaml
    │   ├── kops-secret.yaml
    │   ├── kustomization.yaml
    │   └── secret
    │       └── secret.tls.yaml
    ├── prod
    │   ├── ingress.yaml
    │   ├── jenkins.yaml
    │   ├── kops-secret.yaml
    │   ├── kustomization.yaml
    │   └── secret
    │       └── secret.tls.yaml
    └── svt
        ├── ingress.yaml
        ├── jenkins.yaml
        ├── kops-secret.yaml
        ├── kustomization.yaml
        └── secret
            └── secret.tls.yaml

关于 kustomize 的使用方法,大家可以看这儿[5]。上述整个代码库在这儿[6]。文中使用了 sops[7] 来加密 yaml 文件中的敏感信息,这样真正能够做到将一切代码化,然后托管到 GitHub 上。

根据不同环境的差异性,修改不同的配置文件后,可以使用以下命令来快速安装使用 Jenkins Operator

代码语言:javascript
复制
$ kustomize build --enable-alpha-plugins . | kubectl -n jenkins apply -f -
serviceaccount/jenkins unchanged
serviceaccount/jenkins-operator unchanged
role.rbac.authorization.k8s.io/jenkins-operator unchanged
rolebinding.rbac.authorization.k8s.io/jenkins-operator unchanged
clusterrolebinding.rbac.authorization.k8s.io/jenkins-role-binding unchanged
configmap/jenkins-config configured
secret/github-ssh-key configured
secret/github-token configured
secret/slack-token configured
secret/your-container-registry configured
deployment.apps/jenkins-operator configured
jenkins.jenkins.io/jenkins configured
ingress.networking.k8s.io/jenkins unchanged

--enable-alpha-plugins 是因为使用了 sops 进行了敏感信息加密。关于 sops 的详细使用,敬请期待后续文章。

参考

[1] https://www.jenkins.io/blog/2021/04/15/jenkins-operator-sub-project/

[2] https://kubernetes.io/docs/concepts/extend-kubernetes/operator/

[3] https://github.com/jenkinsci/kubernetes-operator

[4] https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/configure-backup-and-restore/

[5] https://kustomize.io/

[6] https://github.com/majinghe/jenkins-operator.git

[7] https://github.com/mozilla/sops

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-04-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 CNCF 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 入门篇:jenkins-operator 的介绍及安装
    • 前言
      • 安装
        • 第一步:Jenkins CRD 创建
        • 第二步:Jenkins Operator 的安装
        • 第三步:创建 Jenkins 实例
    • 进阶篇:使用
    • 高阶篇:利用 kustomize + sops(gpg) 来部署 jenkins-operator
      • 参考
      相关产品与服务
      容器服务
      腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档