k8s-基于k8s构建Jenkins CI/CD平台

发布流程设计

1638149641401.png

在Kubernetes平台部署Jenkins

1638149759724.png
[root@k8smaster cicd]# kubectl 
apply -f jenkins.yml 

[root@k8smaster cicd]# kubectl get pod -n ops
NAME                      READY   STATUS    RESTARTS   AGE
jenkins-f656474b8-dxhvk   1/1     Running   0          95s

[root@k8smaster cicd]# kubectl logs jenkins-f656474b8-dxhvk -n ops -f 
Please use the following password to proceed to installation:

1cdf4c21f73c4edc83c555121d8596f6

This may also be found at: /var/jenkins_home/secrets/initialAdminPassword

##访问jenkins
http://192.168.153.21:30008/

构建slave镜像

Jenkins Master/Slave架构

1638151273968.png

Jenkins在K8S中动态创建代理

1638151349139.png

相关操作

[root@k8smaster cicd]# cd jenkins-slave/
[root@k8smaster jenkins-slave]# chmod 777 kubectl 
[root@k8smaster jenkins-slave]# ls
Dockerfile  jenkins-slave  kubectl  settings.xml  slave.jar
------------------------------------------------------------------------------------
#构建并推送到镜像仓库

docker build -t 192.168.153.27/library/jenkins-slave-jdk:1.8 .
docker push 192.168.153.27/library/jenkins-slave-jdk:1.8
1638152332667.png

安装插件

修改国内源

#进入nfs共享目录
[root@k8smaster cicd]# cd /ifs/kubernetes/ops-jenkins-pvc-18e51a58-a3fb-41df-91e9-207508d6f86aa/updates

[root@k8smaster updates]#  sed -i 's/https:\/\/updates.jenkins.io\/download/https:\/\/mirrors.tuna.tsinghua.edu.cn\/jenkins/g' default.json

[root@k8smaster updates]# sed -i 's/http:\/\/www.google.com/https:\/\/www.baidu.com/g' default.json

 #重启jenkins
[root@k8smaster updates]# kubectl delete pod jenkins-f656474b8-dxhvk -n ops
pod "jenkins-f656474b8-dxhvk" deleted

[root@k8smaster updates]# kubectl get pods -n ops                          
NAME                      READY   STATUS    RESTARTS   AGE
jenkins-f656474b8-5gmc7   1/1     Running   0          24s

安装相关插件

Git Parameter:Git参数化构建
Git:拉取代码
Pipeline:流水线
kubernetes:连接Kubernetes动态创建Slave代理
Config File Provider:存储kubectl用于连接k8s集群的kubeconfig配置文件
---------------------------------------------------------------------------------

添加k8s集群

进入配置页面

1638153834743.png

Configure Clouds

#Kubernetes 地址
[root@k8smaster cicd]# kubectl get svc -n default
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   29d

https://kubernetes.default
---------------------------------------------------------------------------------

#Jenkins 地址
[root@k8smaster cicd]# kubectl get svc -n ops
NAME      TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)                        AGE
jenkins   NodePort   10.109.120.192   <none>        80:30008/TCP,50000:31434/TCP   56m

http://jenkins.ops

注意:一定是http://jenkins.ops而不是https://jenkins.ops
---------------------------------------------------------------------------------

#测试连接
Connected to Kubernetes v1.19.0

1638160506610.png

Jenkins Pipeline

testjenkins脚本

pipeline {
  agent {
    kubernetes {
        label "jenkins-slave"
        yaml """
kind: Pod
metadata:
  name: jenkins-slave
spec:
  containers:
  - name: jnlp
    image: "192.168.153.27/library/jenkins-slave-jdk:1.8"
"""
      }     
    }
    stages {
        stage('第一步测试'){
            steps {
                sh 'hostname'
            }
        }
    }
}

pipeline执行过程

##构建过程拉起一个jenkins-slave的pod
[root@k8smaster cicd]# kubectl get pod -n ops
NAME                        READY   STATUS              RESTARTS   AGE
jenkins-f656474b8-5gmc7     1/1     Running             0          41m
jenkins-slave-jmkq8-8bnvj   0/1     ContainerCreating   0          11s

##完成后jenkins-slave的pod自动消失
[root@k8smaster cicd]# kubectl get pod -n ops
NAME                        READY   STATUS              RESTARTS   AGE
jenkins-f656474b8-5gmc7     1/1     Running             0          41m

1638160600399.png

项目搭建

凭据

git-auth :ff221d86-51db-429f-b0e2-ad5ba09d5cb0 
harbor-auth:ab69906e-3549-4e3a-bc7c-ace44bccbab6
1638165480783.png

配置文件

[root@k8smaster jenkins-slave]# cat /root/.kube/config 

Managed files:26c9cacb-e481-46fc-bf31-0c6fe4455d1f
1638165795092.png
1638165854653.png

1638165905443.png

1638166110155.png

创建registry-pull-secret

[root@k8smaster jenkins-slave]# kubectl create namespace dev
namespace/dev created
[root@k8smaster jenkins-slave]# kubectl create secret docker-registry registry-pull-secret --docker-username=admin --docker-password=Harbor12345 --docker-server=192.168.153.25 -n dev
secret/registry-pull-secret created

pipeline脚本

// 公共
def registry = "192.168.153.27"
// 项目
def project = "demo"
def app_name = "java-demo"
def image_name = "${registry}/${project}/${app_name}:${BUILD_NUMBER}"
def git_address = "http://192.168.153.18/root/javademo2.git"
// 认证
def secret_name = "registry-pull-secret"
def docker_registry_auth = "ab69906e-3549-4e3a-bc7c-ace44bccbab6"
def git_auth = "ff221d86-51db-429f-b0e2-ad5ba09d5cb0"
def k8s_auth = "26c9cacb-e481-46fc-bf31-0c6fe4455d1f"

pipeline {
  agent {
    kubernetes {
        label "jenkins-slave"
        yaml """
kind: Pod
metadata:
  name: jenkins-slave
spec:
  containers:
  - name: jnlp
    image: "${registry}/library/jenkins-slave-jdk:1.8"
    imagePullPolicy: Always
    volumeMounts:
      - name: docker-cmd
        mountPath: /usr/bin/docker
      - name: docker-sock
        mountPath: /var/run/docker.sock
      - name: maven-cache
        mountPath: /root/.m2
  volumes:
    - name: docker-cmd
      hostPath:
        path: /usr/bin/docker
    - name: docker-sock
      hostPath:
        path: /var/run/docker.sock
    - name: maven-cache
      hostPath:
        path: /tmp/m2
"""
        }
      
      }
    parameters {    
        gitParameter branch: '', branchFilter: '.*', defaultValue: 'master', description: '选择发布的分支', name: 'Branch', quickFilterEnabled: false, selectedValue: 'NONE', sortMode: 'NONE', tagFilter: '*', type: 'PT_BRANCH'
        choice (choices: ['1', '3', '5', '7'], description: '副本数', name: 'ReplicaCount')
        choice (choices: ['dev','test','prod'], description: '命名空间', name: 'Namespace')
    }
    stages {
        stage('拉取代码'){
            steps {
                checkout([$class: 'GitSCM', 
                branches: [[name: "${params.Branch}"]], 
                doGenerateSubmoduleConfigurations: false, 
                extensions: [], submoduleCfg: [], 
                userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_address}"]]
                ])
            }
        }

        stage('代码编译'){
           steps {
             sh """
                mvn clean package -Dmaven.test.skip=true
                """ 
           }
        }

        stage('构建镜像'){
           steps {
                withCredentials([usernamePassword(credentialsId: "${docker_registry_auth}", passwordVariable: 'password', usernameVariable: 'username')]) {
                sh """
                  echo '
                    FROM lizhenliang/tomcat
                    LABEL maitainer lizhenliang
                    ADD target/*.war /usr/local/tomcat/webapps/ROOT.war
                  ' > Dockerfile
                  docker build -t ${image_name} .
                  docker login -u ${username} -p '${password}' ${registry}
                  docker push ${image_name}
                """
                }
           } 
        }
        stage('部署到K8S平台'){
          steps {
              configFileProvider([configFile(fileId: "${k8s_auth}", targetLocation: "admin.kubeconfig")]){
                sh """
                  sed -i 's#IMAGE_NAME#${image_name}#' deploy.yaml
                  sed -i 's#SECRET_NAME#${secret_name}#' deploy.yaml
                  sed -i 's#REPLICAS#${ReplicaCount}#' deploy.yaml
                  kubectl apply -f deploy.yaml -n ${Namespace} --kubeconfig=admin.kubeconfig
                """
              }
          }
        }
    }
}

Gitlab

创建deploy.yaml文件

apiVersion: apps/v1
kind: Deployment
metadata:
  name: java-demo
spec:
  replicas: REPLICAS
  selector:
    matchLabels:
      project: www
      app: java-demo
  template:
    metadata:
      labels:
        project: www
        app: java-demo
    spec:
      imagePullSecrets:
      - name: SECRET_NAME
      containers:
      - image: IMAGE_NAME 
        name: java-demo
        resources:
          requests:
            cpu: 0.5
            memory: 500Mi
          limits: 
            cpu: 1
            memory: 1Gi
        livenessProbe:
          httpGet:
            path: /
            port: 8080
          initialDelaySeconds: 50
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /
            port: 8080
          initialDelaySeconds: 50
          periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
  name: java-demo 
spec:
  selector:
    project: www
    app: java-demo
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
  type: NodePort    

1638167264610.png

编译构建

1638168686826.png

1638168659656.png

查看结果

[root@k8smaster cicd]# kubectl get pod,svc  -n dev                           
NAME                             READY   STATUS    RESTARTS   AGE
pod/java-demo-6668db84f7-2dxnw   1/1     Running   0          4m4s

NAME                TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
service/java-demo   NodePort   10.107.64.65   <none>        80:32495/TCP   4m4s

流水线即代码

Jenkinsfile放入Gitlab

1638176758016.png

编辑Pipeline

1638176877578.png

编译构建

1638176945000.png

1638176971107.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容