国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

實(shí)踐:devops之K8s環(huán)境持續(xù)部署

這篇具有很好參考價值的文章主要介紹了實(shí)踐:devops之K8s環(huán)境持續(xù)部署。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報違法"按鈕提交疑問。

實(shí)踐:devops之K8s環(huán)境持續(xù)部署

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

目錄

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

推薦文章

https://www.yuque.com/xyy-onlyone/aevhhf?# 《玩轉(zhuǎn)Typora》

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

1、Kubectl 發(fā)布流水線

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-X2Q6MzL1-1688896509292)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230709101119001.png)]

CI流水線:

  • 下載代碼
  • 構(gòu)建單元測試
  • 代碼掃描
  • 構(gòu)建鏡像
  • 更新發(fā)布文件

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

CD流水線:

  • 輸入版本,從git下載部署文件;
  • 使用kubectl發(fā)布;
  • 使用kubectl回滾;

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

環(huán)境準(zhǔn)備

jenkins

gitlab

sonarQube

harbor

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

使用之前的npm項目
  • 使用之前的npm項目devops6-npm-service

如何構(gòu)建,請看npm構(gòu)建項目部分。

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-r4q8SmS3-1688896509300)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230703121000171.png)]

  • 新建Dockerfile
FROM nginx:1.17.0

COPY index.html /usr/share/nginx/html/

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-lzJ028a5-1688896509300)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230703121318027.png)]

  • 編輯index.html文件
<h1>VERSION: main</h1>

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

  • 配置好sonar參數(shù)

創(chuàng)建sonar-project.properties文件

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

# 定義唯一的關(guān)鍵字
sonar.projectKey=devops6-npm-service

# 定義項目名稱
sonar.projectName=devops6-npm-service

# 定義項目的版本信息
sonar.projectVersion=1.0
 
# 指定掃描代碼的目錄位置(多個逗號分隔)
sonar.sources=src
 
# 執(zhí)行項目編碼
sonar.sourceEncoding=UTF-8

# 指定sonar Server
sonar.host.url=http://172.29.9.101:9000

# 認(rèn)證信息
sonar.login=admin
sonar.password=Admin@123

然后提交項目代碼。

創(chuàng)建一條新pipeline
  • 以原devops6-maven-service_CI為基礎(chǔ)拷貝一條新流水線devops6-npm-service_K8SCI

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-5UIEyAJB-1688896509302)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230703124225860.png)]

?? 注意:但是這里的Git選項參數(shù)一直沒效果,測試不出來,很奇怪。。。因此,就直接用默認(rèn)的選項參數(shù)就好。

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-twPJgr04-1688896509302)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230703124106609.png)]

  • 開始進(jìn)行構(gòu)建

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-jMu8aj2R-1688896509302)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230703124309393.png)]

可以看待,前面幾個過程都是ok的,這里上傳制品過程,不需要。

創(chuàng)建harbor倉庫
  • 鏡像命名規(guī)范:

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-R0WQFu0j-1688896509303)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230704055658325.png)]

  • 創(chuàng)建倉庫

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-bdwXxoa3-1688896509303)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230704055323738.png)]

  • 修改本地 docker 服務(wù)使用 http 協(xié)議和私有倉庫通信(否則會報錯)
#配置可信任(如果倉庫是HTTPS訪問不用配置)
#在 daemon.json 中添加以下參數(shù)
[root@harbor ~]# vim /etc/docker/daemon.json #創(chuàng)建此文件,并寫入以下內(nèi)容
{
"insecure-registries": ["172.29.9.120"] 
}

#重啟docker 服務(wù)
[root@harbor ~]# systemctl daemon-reload && systemctl restart docker

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-diQld9hR-1688896509304)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230704061032271.png)]

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

編寫CI pipeline

  • 創(chuàng)建k8sci.jenkinsfile
@Library("devops06@main") _

//import src/org/devops/xxx.groovy
def checkout = new org.devops.CheckOut()
def build = new org.devops.Build()
def sonar = new org.devops.Sonar()


//使用git 參數(shù)需要格式化
env.branchName = "${env.branchName}" - "origin/"
println(env.branchName)

pipeline {
    agent {label "build"}

    //跳過默認(rèn)的代碼檢出功能
    options {
        skipDefaultCheckout true
    }    
    

    stages{
        stage("CheckOut"){
            steps{
                script{
                    checkout.CheckOut()
                    
                    //獲取commitID
                    env.commitID = checkout.GetCommitID()
                    println("commitID: ${env.commitID}")

                    // Jenkins構(gòu)建顯示信息
                    currentBuild.displayName = "第${BUILD_NUMBER}次構(gòu)建-${env.commitID}"
                    currentBuild.description = "構(gòu)建分支名稱:${env.branchName}"
                    //currentBuild.description = "Trigger by user jenkins \n branch: ${env.branchName}"
                }
            }
        }

        stage("Build"){
            steps{
                script{
                    build.Build()
                }
            }

        }        

        stage("CodeScan"){
            // 是否跳過代碼掃描?
            when {
                environment name: 'skipSonar', value: 'false'
            }
            
            steps{
                script{
                    sonar.SonarScannerByPlugin()        

                }
            }
        }

         stage("ImageBuild"){
            steps{
                script{
                    //PushArtifactByPlugin()
                    //PushArtifactByPluginPOM()

                    // init package info
                    appName = "${JOB_NAME}".split('_')[0] //devops6-maven-service_CI
                    repoName = appName.split('-')[0]   //devops6
  
                    imageName = "${repoName}/${appName}"
                    imageTag = "${env.branchName}-${env.commitID}"
                    sh """
                        #登錄鏡像倉庫
                        docker login -u admin -p Harbor12345 172.29.9.120

                        # 構(gòu)建鏡像
                        docker build -t 172.29.9.120/${imageName}:${imageTag} .

                        # 上傳鏡像
                        docker push 172.29.9.120/${imageName}:${imageTag}

                        # 刪除鏡像
                        sleep 2
                        docker rmi 172.29.9.120/${imageName}:${imageTag}
                    """
                }
            }
    
        }       

    }
}
  • 在回放里運(yùn)行

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-2KOVJP2U-1688896509305)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230704061342760.png)]

  • 然后將代碼提交到共享庫里。

準(zhǔn)備k8s環(huán)境

  • 啟動好k8s環(huán)境

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-elTtOolP-1688896509305)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230704220639938.png)]

  • 在devops06機(jī)器上安裝kubectl工具
cat > /etc/yum.repos.d/kubernetes.repo << EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

[root@Devops6 ~]#yum install -y kubectl-1.20.0 --disableexcludes=kubernetes
  • 然后把k8s集群master節(jié)點(diǎn)下的~/.kube/config文件拷貝到devops6機(jī)器~/.kube/目錄下

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-nEALoTSP-1688896509305)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230704221711066.png)]

  • 然后在k8s的2個節(jié)點(diǎn)先配置好 修改本地 docker 服務(wù)使用 http 協(xié)議和私有倉庫通信(否則會報錯)
#配置可信任(如果倉庫是HTTPS訪問不用配置)
#在 daemon.json 中添加以下參數(shù)
[root@harbor ~]# vim /etc/docker/daemon.json #創(chuàng)建此文件,并寫入以下內(nèi)容
{
"insecure-registries": ["172.29.9.120"] 
}

#重啟docker 服務(wù)
[root@harbor ~]# systemctl daemon-reload && systemctl restart docker

記得:只需要在node1 node2上配置就行。

  • 自己k8s集群需不是一個ingress-controller。

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

這里之前已經(jīng)部署好ingress-controller了。

  • 配置下kubectl的自動補(bǔ)全
#安裝軟件包
yum install -y epel-release bash-completion

#執(zhí)行命令
source /usr/share/bash-completion/bash_completion

source <(kubectl completion bash)
echo "source <(kubectl completion bash)" >> ~/.bashrc
source ~/.bashrc

創(chuàng)建一個devops6-deploy-repo倉庫

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

  • 創(chuàng)建Deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: devops6-npm-service
spec:
  replicas: 3
  revisionHistoryLimit: 3
  selector:
    matchLabels:
      app: devops6-npm-service
  template:
    metadata:
      labels:
        app: devops6-npm-service
    spec:
      containers:
      - image: 172.29.9.120/devops6/devops6-npm-service:main-ed12ce10
        name: devops6-npm-service
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: devops6-npm-service
spec:
  type: ClusterIP
  selector:
    app: devops6-npm-service
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: devops6-npm-service
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - host: devops.test.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: devops6-npm-service
            port: 
              name: http

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

  • 自己部署應(yīng)用測試

創(chuàng)建新命名空間devops6

[root@Devops6 ~]#kubectl create ns devops6

部署應(yīng)用:

[root@Devops6 ~]#kubectl  -n  devops6 apply -f Deployment.yaml 
deployment.apps/devops6-npm-service created
service/devops6-npm-service created
ingress.networking.k8s.io/devops6-npm-service created

注意:這里直接加上命名空間后,應(yīng)用就會直接被部署到此命名空間了。

[root@Devops6 ~]#kubectl get po -ndevops6
NAME                                  READY   STATUS    RESTARTS   AGE
devops6-npm-service-bd4978ff9-27bpp   1/1     Running   0          32s
devops6-npm-service-bd4978ff9-clkhm   1/1     Running   0          32s
devops6-npm-service-bd4978ff9-x2sw8   1/1     Running   0          32s

配置ingress域名解析:

[root@Devops6 ~]#vim /etc/hosts
172.29.9.31 devops.test.com

[root@Devops6 ~]#kubectl get ingress -ndevops6
NAME                  CLASS    HOSTS             ADDRESS       PORTS   AGE
devops6-npm-service   <none>   devops.test.com   172.29.9.31   80      8m11s

測試效果:

[root@Devops6 ~]#curl devops.test.com
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>vuedemo</title>
  </head>
  <body>
    <div id="app">
      <h1>VERSION: main</h1>
    </div>
    <!-- built files will be auto injected -->
  </body>
</html>

新建devops6-npm-service版本分支,特性分支

  • 以main為基礎(chǔ)新建devops6-npm-service版本分支RELEASE-1.1.1

修改index.html的內(nèi)容為RELEASE-1.1.1。

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

  • 運(yùn)行一次CI流水線

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-4kNrjchh-1688896509307)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230705133823641.png)]

要記得改下這里的jenkinsfile文件:

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

成功生成鏡像:

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

  • 我們再來更新一個版本的應(yīng)用程序看下
[root@Devops6 ~]#vim Deployment.yaml
將
- image: 172.29.9.120/devops6/devops6-npm-service:main-ed12ce10
替換為
172.29.9.120/devops6/devops6-npm-service:RELEASE-1.1.1-7d906f68

#然后部署應(yīng)用:
[root@Devops6 ~]#kubectl apply -f Deployment.yaml -ndevops6

#驗證
[root@Devops6 ~]#curl devops.test.com
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>vuedemo</title>
  </head>
  <body>
    <div id="app">
      <h1>VERSION: RELEASE-1.1.1</h1>
    </div>
    <!-- built files will be auto injected -->
  </body>
</html>
#可以看到,已經(jīng)更新成功了。
  • 我們來測試下回滾

回滾命令:

## 查看歷史
kubectl rollout history deployment/anyops-devopsdocker-ui

## 查看具體某一個歷史版本信息
kubectl rollout history deployment/anyops-devopsdocker-ui --revision=2

## 回滾上個版本 
kubectl rollout undo deployment/anyops-devopsdocker-ui -n anyops

## 回滾指定版本
kubectl rollout undo deployment/nginx --to-revision=2

查看當(dāng)前應(yīng)用版本:

[root@Devops6 ~]#kubectl rollout history deployment devops6-npm-service -ndevops6
deployment.apps/devops6-npm-service 
REVISION  CHANGE-CAUSE
1         <none>
2         <none>
#可以看到有2個歷史版本

我們打算回滾到上個歷史版本:

先來查看下當(dāng)前應(yīng)用版本:

watch -n 1 "curl devops.test.com"

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

watch -n 1 "curl -s devops.test.com"

開始回滾:

[root@Devops6 ~]#kubectl rollout undo deployment devops6-npm-service -ndevops6
deployment.apps/devops6-npm-service rolled back

回滾結(jié)果:

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

回滾成功。

  • 這里調(diào)的是gitlab的api

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

調(diào)用gitlab api自動更新配置文件。

  • jenkins裝一個插件HTTP Request

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

  • devops6-npm-service項目ProjectID為11。

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-eHFPfPmU-1688896509312)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230707070500615.png)]

  • 創(chuàng)建devops6-npm-service目錄

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-QSlYcVW9-1688896509312)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230707060343353.png)]

Deployment.yaml里的image改為__IMAGE_NAME__

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

  • pipeline代碼

Gitlab.groovy

package org.devops

//獲取文件內(nèi)容
def GetRepoFile(projectId,filePath,branchName){
   //GET /projects/:id/repository/files/:file_path/raw
   apiUrl = "/projects/${projectId}/repository/files/${filePath}/raw?ref=${branchName}"
   response = HttpReq('GET', apiUrl)
   return response
}

//更新文件內(nèi)容
def UpdateRepoFile(projectId,filePath,fileContent, branchName){
    apiUrl = "projects/${projectId}/repository/files/${filePath}"
    reqBody = """{"branch": "${branchName}","encoding":"base64", "content": "${fileContent}", "commit_message": "update a new file"}"""
    response = HttpReqByPlugin('PUT',apiUrl,reqBody)
    println(response)

}

//創(chuàng)建文件
def CreateRepoFile(projectId,filePath,fileContent, branchName){
    apiUrl = "projects/${projectId}/repository/files/${filePath}"
    reqBody = """{"branch": "${branchName}","encoding":"base64", "content": "${fileContent}", "commit_message": "update a new file"}"""
    response = HttpReqByPlugin('POST',apiUrl,reqBody)
    println(response)

}

// 封裝HTTP
def HttpReqByPlugin(reqType, reqUrl,reqBody ){
    def gitServer = "http://172.29.9.101:8076/api/v4"
    withCredentials([string(credentialsId: '5782c77d-ce9d-44e5-b9ba-1ba2097fc31d', 
                            variable: 'GITLABTOKEN')]) {
        response = httpRequest acceptType: 'APPLICATION_JSON_UTF8', 
                    consoleLogResponseBody: true, 
                    contentType: 'APPLICATION_JSON_UTF8', 
                    customHeaders: [[maskValue: false, name: 'PRIVATE-TOKEN', value: "${GITLABTOKEN}"]], 
                    httpMode: "${reqType}", 
                    url: "${gitServer}/${reqUrl}", 
                    wrapAsMultipart: false,
                    requestBody: "${reqBody}"

    }
    return response
}



//發(fā)起HTTP請求
//調(diào)用gitlab api
def HttpReq(method, apiUrl){

    withCredentials([string(credentialsId: '5782c77d-ce9d-44e5-b9ba-1ba2097fc31d', variable: 'gitlabtoken')]) {
        response = sh  returnStdout: true, 
        script: """ 
        curl --location --request ${method} \
        http://172.29.9.101:8076/api/v4/${apiUrl} \
        --header "PRIVATE-TOKEN: ${gitlabtoken}"
        """
    }

    //新增這段代碼
    try {
        response = readJSON text: response - "\n" //json數(shù)據(jù)的讀取方式
    } catch(e){
        println(e)
    }
    return response    
}

//獲取ProjectID
def GetProjectIDByName(projectName, groupName){
    apiUrl = "projects?search=${projectName}"
    response = HttpReq("GET", apiUrl)
    if (response != []){
        for (p in response) {
            if (p["namespace"]["name"] == groupName){
                return response[0]["id"]
            }
        }
    }
}

//獲取分支CommitID
def GetBranchCommitID(projectID, branchName){
    apiUrl = "projects/${projectID}/repository/branches/${branchName}"
    response = HttpReq("GET", apiUrl)
    return response.commit.short_id
}

k8sci.jenkinsfile

@Library("devops06@main") _

//import src/org/devops/xxx.groovy
def checkout = new org.devops.CheckOut()
def build = new org.devops.Build()
def sonar = new org.devops.Sonar()
def mygit = new org.devops.Gitlab()


//使用git 參數(shù)需要格式化
env.branchName = "${env.branchName}" - "origin/"
println(env.branchName)

pipeline {
    agent {label "build"}

    //跳過默認(rèn)的代碼檢出功能
    options {
        skipDefaultCheckout true
    }    
    

    stages{
        stage("CheckOut"){
            steps{
                script{
                    checkout.CheckOut()
                    
                    //獲取commitID
                    env.commitID = checkout.GetCommitID()
                    println("commitID: ${env.commitID}")

                    // Jenkins構(gòu)建顯示信息
                    currentBuild.displayName = "第${BUILD_NUMBER}次構(gòu)建-${env.commitID}"
                    currentBuild.description = "構(gòu)建分支名稱:${env.branchName}"
                    //currentBuild.description = "Trigger by user jenkins \n branch: ${env.branchName}"
                }
            }
        }

        stage("Build"){
            steps{
                script{
                    build.Build()
                }
            }

        }        

        stage("CodeScan"){
            // 是否跳過代碼掃描?
            when {
                environment name: 'skipSonar', value: 'false'
            }
            
            steps{
                script{
                    sonar.SonarScannerByPlugin()        

                }
            }
        }

        stage("ImageBuild"){
            steps{
                script{
                    //PushArtifactByPlugin()
                    //PushArtifactByPluginPOM()

                    // init package info
                    appName = "${JOB_NAME}".split('_')[0] //devops6-maven-service_CI
                    repoName = appName.split('-')[0]   //devops6
  
                    imageName = "${repoName}/${appName}"
                    imageTag = "${env.branchName}-${env.commitID}"
                    env.fullImageName = "172.29.9.120/${imageName}:${imageTag}"
                    sh """
                        #登錄鏡像倉庫
                        docker login -u admin -p Harbor12345 172.29.9.120

                        # 構(gòu)建鏡像
                        docker build -t ${env.fullImageName} .

                        # 上傳鏡像
                        docker push ${env.fullImageName}

                        # 刪除鏡像
                        sleep 2
                        docker rmi ${env.fullImageName}
                    """
                }
            }
    
        }
        
        stage("UpdateEnvFile"){
            steps{
                script {
                    // 更新部署文件

                    projectId = 11
                    fileName = "Deployment.yaml"  //模板文件
                    branchName = "main"

                    //下載模板文件
                    fileData = mygit.GetRepoFile(projectId,fileName,branchName)
                    sh "rm -fr ${fileName}"

                    //模板文件內(nèi)容保存到本地
                    writeFile file: fileName , text: fileData
                    env.deployFile = fileName
                    //替換鏡像
                    sh "sed -i 's#__IMAGE_NAME__#${env.fullImageName}#g' ${env.deployFile} "
                    sh "ls -l ; cat ${fileName}"

                    //創(chuàng)建/更新發(fā)布文件
                    newYaml = sh returnStdout: true, script: "cat ${env.deployFile}"
                    println(newYaml)
                   
                    //更新gitlab文件內(nèi)容
                    base64Content = newYaml.bytes.encodeBase64().toString()
                    
                    appName = "${JOB_NAME}".split('_')[0] //devops6-npm-service
                    env.groupName = appName.split('-')[0]   //devops6
                    env.projectName = appName

                    // 會有并行問題,同時更新報錯
                    try {
                        mygit.UpdateRepoFile(projectId,"${env.projectName}%2f${env.branchName}.yaml",base64Content, "main")
                    } catch(e){
                        mygit.CreateRepoFile(projectId,"${env.projectName}%2f${env.branchName}.yaml",base64Content, "main")
                    }
                }
            }
        }              

    }
}
  • 再次新建版本分支RELEASE-2.1.1,jenkins里記得配置下該分支名。

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

  • 運(yùn)行

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-Fl78o5Hw-1688896509314)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230707070829381.png)]

點(diǎn)擊approve

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-7IVfeaqS-1688896509315)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230707070202014.png)]

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

符合預(yù)期。

【GitOps最重要的一個特性: 自動更新部署文件

更新生成版本文件

  • 步驟: 拿到 env倉庫中的deployments.yaml模板文件, 然后替換內(nèi)容,更新到版本庫。

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

  • 更新對象:

    • RELEASE_VERSION(鏡像TAG)
  •        stage("UpdateEnvFile"){
                steps{
                    script {
                        // 更新部署文件
          
                        projectId = 11
                        fileName = "Deployment.yaml"  //模板文件
                        branchName = "main"
          
                        //下載模板文件
                        fileData = mygit.GetRepoFile(projectId,fileName,branchName)
                        sh "rm -fr ${fileName}"
          
                        //模板文件內(nèi)容保存到本地
                        writeFile file: fileName , text: fileData
                        env.deployFile = fileName
                        //替換鏡像
                        sh "sed -i 's#__IMAGE_NAME__#${env.fullImageName}#g' ${env.deployFile} "
                        sh "ls -l ; cat ${fileName}"
          
                        //創(chuàng)建/更新發(fā)布文件
                        newYaml = sh returnStdout: true, script: "cat ${env.deployFile}"
                        println(newYaml)
                       
                        //更新gitlab文件內(nèi)容
                        base64Content = newYaml.bytes.encodeBase64().toString()
                        
                        appName = "${JOB_NAME}".split('_')[0] //devops6-npm-service
                        env.groupName = appName.split('-')[0]   //devops6
                        env.projectName = appName
          
                        // 會有并行問題,同時更新報錯
                        try {
                            mygit.UpdateRepoFile(projectId,"${env.projectName}%2f${env.branchName}.yaml",base64Content, "main")
                        } catch(e){
                            mygit.CreateRepoFile(projectId,"${env.projectName}%2f${env.branchName}.yaml",base64Content, "main")
                        }
                    }
                }
            }              
    
  • 更新后的版本文件

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

編寫CD pipeline

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

  • 創(chuàng)建一個CD的job devops6-npm-service_K8SCD

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-4XfROLK7-1688896509317)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230707073334556.png)]

配置git倉庫:

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-tgke6cqI-1688896509317)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230707074103792.png)]

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

  • 編寫pipeline

k8scd.jenkinsfile文件

@Library("devops06@main") _ 

def mygit = new org.devops.Gitlab()

//使用git 參數(shù)需要格式化
env.branchName = "${env.branchName}" - "origin/"
println(env.branchName)

pipeline {
    agent { label "build"}
    options {
        skipDefaultCheckout true
    }
    stages{
        stage("GetManifests"){
            steps{
                script{
                   
                   //下載發(fā)布文件
                    projectId = 11
                    env.deployFile = "${env.branchName}.yaml"  //版本分支RELEASE-2.1.1.yaml
                    env.appName = "${JOB_NAME}".split('_')[0] //devops6-maven-service
                    filePath = "${env.appName}%2f${env.deployFile}" //devops6-npm-service/RELEASE-2.1.1.yaml
                    branchName = "main"
                    fileData = mygit.GetRepoFile(projectId,filePath,branchName)
                    sh "rm -fr ${env.deployFile}"
                    writeFile file: env.deployFile , text: fileData
                    sh "ls -l ; cat ${env.deployFile}"
                }
            }
        }

        stage("Deploy"){
            steps{
                script{
                    env.namespace = "${env.appName}".split('-')[0]   //devops6

                    sh """
                        ## 發(fā)布應(yīng)用
                        kubectl apply -f ${env.deployFile} -n ${env.namespace}

                    """

                    // 獲取應(yīng)用狀態(tài)
                    5.times{
                        sh "sleep 2; kubectl -n ${env.namespace} get pod | grep ${env.appName}"
                    }
                }
            }
        }

        stage("RollBack"){
            input {
                message "是否進(jìn)行回滾"
                ok "提交"
                submitter ""
                parameters {
                    choice(choices: ['yes', 'no'], name: 'opts')
                }
            }
            steps{
                script{
                    switch("${opts}") {
                        case "yes":
                            sh "kubectl rollout undo deployment/${env.appName} -n ${env.namespace} "
                            break
                        case "no":
                            break
                    }
                }
            }
        }
    }
}

  • 運(yùn)行流水線

我們來提前觀察下此時版本:

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-BKX6r4sR-1688896509318)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230707074135231.png)]

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-LUNSLDKn-1688896509318)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230707074148261.png)]

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-NiFkheLy-1688896509319)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230707074204527.png)]

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

符合預(yù)期。

完整代碼

完整代碼如下:

鏈接:https://pan.baidu.com/s/1XFtZ0epIwgVwu0jzQHyJkA?pwd=0820
提取碼:0820

2023.7.9-day9-k8s-ci-cd (kubectl和helm ci-cd)

CI/CD共享庫源碼
前端項目 (Dockerfile)
K8s清單文件代碼倉庫
helm chart倉庫

環(huán)境:

gitlab-ce:15.0.3-ce.0
jenkins:2.346.3-2-lts-jdk11
sonarqube:9.9.0-community
harbor v2.6.2

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-5ofFJYun-1688896509320)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230709083713029.png)]

k8sci.jenkinsfile文件

@Library("devops06@main") _

//import src/org/devops/xxx.groovy
def checkout = new org.devops.CheckOut()
def build = new org.devops.Build()
def sonar = new org.devops.Sonar()
def mygit = new org.devops.Gitlab()


//使用git 參數(shù)需要格式化
env.branchName = "${env.branchName}" - "origin/"
println(env.branchName)

pipeline {
    agent {label "build"}

    //跳過默認(rèn)的代碼檢出功能
    options {
        skipDefaultCheckout true
    }    
    

    stages{
        stage("CheckOut"){
            steps{
                script{
                    checkout.CheckOut()
                    
                    //獲取commitID
                    env.commitID = checkout.GetCommitID()
                    println("commitID: ${env.commitID}")

                    // Jenkins構(gòu)建顯示信息
                    currentBuild.displayName = "第${BUILD_NUMBER}次構(gòu)建-${env.commitID}"
                    currentBuild.description = "構(gòu)建分支名稱:${env.branchName}"
                    //currentBuild.description = "Trigger by user jenkins \n branch: ${env.branchName}"
                }
            }
        }

        stage("Build"){
            steps{
                script{
                    build.Build()
                }
            }

        }        

        stage("CodeScan"){
            // 是否跳過代碼掃描?
            when {
                environment name: 'skipSonar', value: 'false'
            }
            
            steps{
                script{
                    sonar.SonarScannerByPlugin()        

                }
            }
        }

        stage("ImageBuild"){
            steps{
                script{
                    //PushArtifactByPlugin()
                    //PushArtifactByPluginPOM()

                    // init package info
                    appName = "${JOB_NAME}".split('_')[0] //devops6-maven-service_CI
                    repoName = appName.split('-')[0]   //devops6
  
                    imageName = "${repoName}/${appName}"
                    imageTag = "${env.branchName}-${env.commitID}"
                    env.fullImageName = "172.29.9.120/${imageName}:${imageTag}"
                    sh """
                        #登錄鏡像倉庫
                        docker login -u admin -p Harbor12345 172.29.9.120

                        # 構(gòu)建鏡像
                        docker build -t ${env.fullImageName} .

                        # 上傳鏡像
                        docker push ${env.fullImageName}

                        # 刪除鏡像
                        sleep 2
                        docker rmi ${env.fullImageName}
                    """
                }
            }
    
        }
        
        stage("UpdateEnvFile"){
            steps{
                script {
                    // 更新部署文件

                    projectId = 11
                    fileName = "Deployment.yaml"  //模板文件
                    branchName = "main"

                    //下載模板文件
                    fileData = mygit.GetRepoFile(projectId,fileName,branchName)
                    sh "rm -fr ${fileName}"

                    //模板文件內(nèi)容保存到本地
                    writeFile file: fileName , text: fileData
                    env.deployFile = fileName
                    //替換鏡像
                    sh "sed -i 's#__IMAGE_NAME__#${env.fullImageName}#g' ${env.deployFile} "
                    sh "ls -l ; cat ${fileName}"

                    //創(chuàng)建/更新發(fā)布文件
                    newYaml = sh returnStdout: true, script: "cat ${env.deployFile}"
                    println(newYaml)
                   
                    //更新gitlab文件內(nèi)容
                    base64Content = newYaml.bytes.encodeBase64().toString()
                    
                    appName = "${JOB_NAME}".split('_')[0] //devops6-npm-service
                    env.groupName = appName.split('-')[0]   //devops6
                    env.projectName = appName

                    // 會有并行問題,同時更新報錯
                    try {
                        mygit.UpdateRepoFile(projectId,"${env.projectName}%2f${env.branchName}.yaml",base64Content, "main")
                    } catch(e){
                        mygit.CreateRepoFile(projectId,"${env.projectName}%2f${env.branchName}.yaml",base64Content, "main")
                    }
                }
            }
        }              

    }
}

k8scd.jenkinsfile文件:

@Library("devops06@main") _ 

def mygit = new org.devops.Gitlab()

//使用git 參數(shù)需要格式化
env.branchName = "${env.branchName}" - "origin/"
println(env.branchName)

pipeline {
    agent { label "build"}
    options {
        skipDefaultCheckout true
    }
    stages{
        stage("GetManifests"){
            steps{
                script{
                   
                   //下載發(fā)布文件
                    projectId = 11
                    env.deployFile = "${env.branchName}.yaml"  //版本分支RELEASE-2.1.1.yaml
                    env.appName = "${JOB_NAME}".split('_')[0] //devops6-maven-service
                    filePath = "${env.appName}%2f${env.deployFile}" //devops6-npm-service/RELEASE-2.1.1.yaml
                    branchName = "main"
                    fileData = mygit.GetRepoFile(projectId,filePath,branchName)
                    sh "rm -fr ${env.deployFile}"
                    writeFile file: env.deployFile , text: fileData
                    sh "ls -l ; cat ${env.deployFile}"
                }
            }
        }

        stage("Deploy"){
            steps{
                script{
                    env.namespace = "${env.appName}".split('-')[0]   //devops6

                    sh """
                        ## 發(fā)布應(yīng)用
                        kubectl apply -f ${env.deployFile} -n ${env.namespace}

                    """

                    // 獲取應(yīng)用狀態(tài)
                    5.times{
                        sh "sleep 2; kubectl -n ${env.namespace} get pod | grep ${env.appName}"
                    }
                }
            }
        }

        stage("RollBack"){
            input {
                message "是否進(jìn)行回滾"
                ok "提交"
                submitter ""
                parameters {
                    choice(choices: ['yes', 'no'], name: 'opts')
                }
            }
            steps{
                script{
                    switch("${opts}") {
                        case "yes":
                            sh "kubectl rollout undo deployment/${env.appName} -n ${env.namespace} "
                            break
                        case "no":
                            break
                    }
                }
            }
        }
    }
}


2、Helm CI/CD流水線

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-7HKAlX3F-1688896509321)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230709102602647.png)]

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

環(huán)境準(zhǔn)備

刪除devops6命名空間
[root@Devops6 ~]#kubectl delete ns devops6
集群安裝helm
[root@Devops6 ~]#tar xf helm-v3.7.2-linux-amd64.tar.gz
[root@Devops6 ~]#cd linux-amd64/
[root@Devops6 linux-amd64]#cp helm /usr/bin/
[root@Devops6 linux-amd64]#chmod +x  /usr/bin/helm
[root@Devops6 linux-amd64]#helm version
WARNING: Kubernetes configuration file is group-readable. This is insecure. Location: /root/.kube/config
WARNING: Kubernetes configuration file is world-readable. This is insecure. Location: /root/.kube/config
version.BuildInfo{Version:"v3.7.2", GitCommit:"663a896f4a815053445eec4153677ddc24a0a361", GitTreeState:"clean", GoVersion:"go1.16.10"}
[root@Devops6 linux-amd64]#helm repo add stable http://mirror.azure.cn/kubernetes/charts/
WARNING: Kubernetes configuration file is group-readable. This is insecure. Location: /root/.kube/config
WARNING: Kubernetes configuration file is world-readable. This is insecure. Location: /root/.kube/config
"stable" has been added to your repositories
[root@Devops6 linux-amd64]# helm repo list
WARNING: Kubernetes configuration file is group-readable. This is insecure. Location: /root/.kube/config
WARNING: Kubernetes configuration file is world-readable. This is insecure. Location: /root/.kube/config
NAME  	URL                                      
stable	http://mirror.azure.cn/kubernetes/charts/
[root@Devops6 linux-amd64]#echo "source <(helm completion bash)" >> ~/.bashrc
[root@Devops6 linux-amd64]#source ~/.bashrc
WARNING: Kubernetes configuration file is group-readable. This is insecure. Location: /root/.kube/config
WARNING: Kubernetes configuration file is world-readable. This is insecure. Location: /root/.kube/config
[root@Devops6 linux-amd64]#helm list 
WARNING: Kubernetes configuration file is group-readable. This is insecure. Location: /root/.kube/config
WARNING: Kubernetes configuration file is world-readable. This is insecure. Location: /root/.kube/config
NAME	NAMESPACE	REVISION	UPDATED	STATUS	CHART	APP VERSION
[root@Devops6 linux-amd64]#
  • 具體安裝文檔參考鏈接:

https://blog.csdn.net/weixin_39246554/article/details/123955289?ops_request_misc=&request_id=5c6a4510d72e40eabbcc39450945e6e4&biz_id=&utm_medium=distribute.pc_search_result.none-task-blog-2blogkoosearch~default-2-123955289-null-null.268v1control&utm_term=helm&spm=1018.2226.3001.4450

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

創(chuàng)建helm倉庫

devops6-helm-repo

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

helm手動安裝包
  • 生成helm chart
[root@Devops6 ~]#helm create devops6-npm-service
WARNING: Kubernetes configuration file is group-readable. This is insecure. Location: /root/.kube/config
WARNING: Kubernetes configuration file is world-readable. This is insecure. Location: /root/.kube/config
Creating devops6-npm-service
[root@Devops6 ~]#cd devops6-npm-service/
[root@Devops6 devops6-npm-service]#ls
charts  Chart.yaml  templates  values.yaml
  • 編輯values.yaml

修改如下2處地方:

[root@Devops6 devops6-npm-service]#vim values.yaml
image:
  repository: 172.29.9.120/devops6/devops6-npm-service
  pullPolicy: IfNotPresent
  # Overrides the image tag whose default is the chart appVersion.
  tag: "RELEASE-2.1.1-8a398eee"

……
ingress:
  enabled: true
  className: ""
  annotations:
    kubernetes.io/ingress.class: nginx
    # kubernetes.io/tls-acme: "true"
  hosts:
    - host: devops.test.com
      paths:
        - path: /
          pathType: Prefix

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

  • 生成部署文件
[root@Devops6 devops6-npm-service]#helm template --output-dir manifests .
WARNING: Kubernetes configuration file is group-readable. This is insecure. Location: /root/.kube/config
WARNING: Kubernetes configuration file is world-readable. This is insecure. Location: /root/.kube/config
wrote manifests/devops6-npm-service/templates/serviceaccount.yaml
wrote manifests/devops6-npm-service/templates/service.yaml
wrote manifests/devops6-npm-service/templates/deployment.yaml
wrote manifests/devops6-npm-service/templates/ingress.yaml
wrote manifests/devops6-npm-service/templates/tests/test-connection.yaml
  • 部署
[root@Devops6 devops6-npm-service]#helm install devops6-npm-service . -ndevops6 --create-namespace 
WARNING: Kubernetes configuration file is group-readable. This is insecure. Location: /root/.kube/config
WARNING: Kubernetes configuration file is world-readable. This is insecure. Location: /root/.kube/config
NAME: devops6-npm-service
LAST DEPLOYED: Sat Jul  8 10:57:40 2023
NAMESPACE: devops6
STATUS: deployed
REVISION: 1
NOTES:
1. Get the application URL by running these commands:
  http://devops.test.com/
  • 驗證
[root@Devops6 devops6-npm-service]#kubectl get po -ndevops6
NAME                                   READY   STATUS    RESTARTS   AGE
devops6-npm-service-7bcb6c49b5-rls6f   1/1     Running   0          28s

[root@Devops6 devops6-npm-service]#watch -n 1 "curl -s devops.test.com"
Every 1.0s: curl -s devops.test.com             Sat Jul  8 10:58:46 2023                                                                                             
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>vuedemo</title>
  </head>
  <body>
    <div id="app">
      <h1>VERSION: RELEASE-2.1.1</h1>
    </div>
    <!-- built files will be auto injected -->
  </body>
</html>

部署成功。

  • 將次helm chart推送到剛才創(chuàng)建的helm倉庫
#先刪除manifests目錄
[root@Devops6 devops6-npm-service]#pwd
/root/devops6-npm-service
[root@Devops6 devops6-npm-service]#ls
charts  Chart.yaml  manifests  templates  values.yaml
[root@Devops6 devops6-npm-service]#rm -rf manifests/

#推送 (注意:這次試驗這里是master分支)
cd existing_folder
git init
git remote add origin http://172.29.9.101:8076/devops6/devops6-helm-repo.git
git add .
git commit -m "Initial commit"
git push -u origin master

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

harbor上開啟helm chart
  • 默認(rèn)harbor沒有helm chart功能,需要另外配置下才行

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-z3ufZLk3-1688896509323)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230708111712317.png)]

  • 配置
開啟helm charts
./install.sh  --with-chartmuseum
helm repo add devops6repo http://172.29.9.120/chartrepo/devops6/  --username=admin --password=Harbor12345

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

配置完后,harbor界面就出現(xiàn)了helm chart選項了:

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

添加過程:

[root@Devops6 devops6-npm-service]#helm repo list
WARNING: Kubernetes configuration file is group-readable. This is insecure. Location: /root/.kube/config
WARNING: Kubernetes configuration file is world-readable. This is insecure. Location: /root/.kube/config
NAME  	URL                                      
stable	http://mirror.azure.cn/kubernetes/charts/
[root@Devops6 devops6-npm-service]#helm repo add devops6repo http://172.29.9.120/chartrepo/devops6/  --username=admin --password=Harbor12345
WARNING: Kubernetes configuration file is group-readable. This is insecure. Location: /root/.kube/config
WARNING: Kubernetes configuration file is world-readable. This is insecure. Location: /root/.kube/config
"devops6repo" has been added to your repositories
[root@Devops6 devops6-npm-service]#helm repo list
WARNING: Kubernetes configuration file is group-readable. This is insecure. Location: /root/.kube/config
WARNING: Kubernetes configuration file is world-readable. This is insecure. Location: /root/.kube/config
NAME       	URL                                      
stable     	http://mirror.azure.cn/kubernetes/charts/
devops6repo	http://172.29.9.120/chartrepo/devops6/   
helm安裝cm-push軟件

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

CI pipeline

pipeline代碼
創(chuàng)建CI 流水線
  • devops6-npm-service_K8SCI為基礎(chǔ)新創(chuàng)建devops6-npm-service_HELMCI項目

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

修改為helmci.jenkinsfile。

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

  • 最終

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-5zPkUFwi-1688896509328)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230709083045417.png)]

CI 測試

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-0OQCRI7B-1688896509329)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230709083152825.png)]

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

CD pipeline

pipeline代碼
創(chuàng)建CD流水線
  • devops6-npm-service_K8SCD為基礎(chǔ)新創(chuàng)建devops6-npm-service_HELMCD項目

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

修改為helmcd.jenkinsfile

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-yySe5cMn-1688896509330)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230708111355792.png)]

修改選線參數(shù):

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

最終:

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-vAv9AVLO-1688896509330)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230709082857194.png)]

CD測試

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-fduuq5i4-1688896509331)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230709083003688.png)]

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-PVASiBcl-1688896509331)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230709082930825.png)]

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

完整代碼

完整代碼如下:

鏈接:https://pan.baidu.com/s/1XFtZ0epIwgVwu0jzQHyJkA?pwd=0820
提取碼:0820

2023.7.9-day9-k8s-ci-cd (kubectl和helm ci-cd)

CI/CD共享庫源碼
前端項目 (Dockerfile)
K8s清單文件代碼倉庫
helm chart倉庫

環(huán)境:

gitlab-ce:15.0.3-ce.0
jenkins:2.346.3-2-lts-jdk11
sonarqube:9.9.0-community
harbor v2.6.2  

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-3DTfFIZE-1688896509332)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230709084520218.png)]

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

helmci.jenkinsfile文件

@Library("devops06@main") _ 

//import  src/org/devops/Build.groovy
def build = new org.devops.Build()
def sonar = new org.devops.Sonar()
def checkouts = new org.devops.CheckOut()
def mygit = new org.devops.Gitlab()

//使用git 參數(shù)需要格式化
env.branchName = "${env.branchName}" - "origin/"
println(env.branchName)

pipeline {
    agent { label "build"}
    options {
        skipDefaultCheckout true
    }
    stages{
        stage("CheckOut"){
            steps{
                script{
                   checkouts.CheckOut()
                }
            }
        }
        stage("Build"){
            steps{
                script{
                    build.Build()
                }
            }
        }

        stage("CodeScan"){
            steps{
                script{
                    sonar.SonarScannerByPlugin()
                }
            }
        }
        stage("ImageBuild"){
            steps{
                script{
                    //PushArtifactByPlugin()
                    //PushArtifactByPluginPOM()
                    // init package info
                    appName = "${JOB_NAME}".split('_')[0] //devops6-maven-service
                    repoName = appName.split('-')[0]   //devops6
                    
                    //commitID
                    commitID = checkouts.GetCommitID()
                    println(commitID)

                    // Jenkins構(gòu)建顯示信息
                    currentBuild.displayName = "第${BUILD_NUMBER}次構(gòu)建-${commitID}"
                    currentBuild.description = "構(gòu)建分支名稱:${env.branchName}"

                    imageName = "${repoName}/${appName}"
                    env.imageTag = "${env.branchName}-${commitID}"
                    env.fullImageName = "172.29.9.120/${imageName}:${env.imageTag}"
                    sh """
                        #登錄鏡像倉庫
                        docker login -u admin -p Harbor12345 172.29.9.120

                        # 構(gòu)建鏡像
                        docker build -t ${env.fullImageName} .

                        # 上傳鏡像
                        docker push ${env.fullImageName}

                        # 刪除鏡像
                        sleep 2
                        docker rmi ${env.fullImageName}
                    """ 
                }
            }
        }
        stage("UpdateEnvFile"){
            steps{
                script {
                    // 更新部署文件

                    projectId = 12 //helm repo id
                    fileName = "values.yaml"  //模板文件
                    branchName = "master"
                    //下載模板文件
                    fileData = mygit.GetRepoFile(projectId,fileName,branchName)
                    sh "rm -fr ${fileName}"

                    //修改鏡像tag
                    yamlData = readYaml text: fileData
                    yamlData.image.tag = "${env.imageTag}"

                    //模板文件內(nèi)容保存到本地
                    writeYaml file: "${fileName}" , data: yamlData

                
                    //創(chuàng)建/更新發(fā)布文件
                    newYaml = sh returnStdout: true, script: "cat ${fileName}"
                    println(newYaml)
                    //更新gitlab文件內(nèi)容
                    base64Content = newYaml.bytes.encodeBase64().toString()
                    

                    // 會有并行問題,同時更新報錯
                    try {
                        mygit.UpdateRepoFile(projectId,"${fileName}",base64Content, "master")
                    } catch(e){
                        mygit.CreateRepoFile(projectId,"${fileName}",base64Content, "master")
                    }
                }
            }
        }
        stage("HelmPackage"){
            steps{
                script{
                    // helm pakcage & push harbor
                    appName = "${JOB_NAME}".split('_')[0]
                    sh "pwd && ls -l"
                    sh "mkdir -p ${appName} && cd ${appName}"
                    ws("${workspace}/${appName}"){
                        checkout([$class: 'GitSCM', branches: [[name: '*/master']], 
                            extensions: [], 
                            userRemoteConfigs: [[credentialsId: 'gitlab-root', 
                            url: 'http://172.29.9.101:8076/devops6/devops6-helm-repo.git']]])

                        sh "ls -l"
                    }
                    //helm package
                    chartVersion = "${env.branchName}".split("-")[-1]  //1.1.1
                    sh """ 
                        helm package ${appName} --version ${chartVersion}
                        helm-cm-push ${appName}-${chartVersion}.tgz devops6repo
                    """

                }
            }
        }
    }
}

helmcd.jenkinsfile文件

@Library("devops06@main") _ 

def checkout = new org.devops.CheckOut()
def build = new org.devops.Build()

//使用git 參數(shù)需要格式化
env.branchName = "${env.branchName}" - "origin/"
println(env.branchName)

//commitID
env.commitID = checkouts.GetCommitID()
println(commitID)

// Jenkins構(gòu)建顯示信息
currentBuild.displayName = "第${BUILD_NUMBER}次構(gòu)建-${env.commitID}"
currentBuild.description = "構(gòu)建分支名稱:${env.branchName}"

pipeline {
    agent { label "build"}
    options {
        skipDefaultCheckout true
    }
    stages{
        stage("GetHelmChart"){
            steps{
                script{
                    //下載helm chart
                    env.chartVersion = "${env.branchName}".split("-")[-1]
                    env.appName = "${JOB_NAME}".split('_')[0]
                    sh """
                        helm repo update devops6repo
                        helm pull devops6repo/${env.appName} --version ${env.chartVersion}
                    """
                }
            }
        }

        stage("Deploy"){
            steps{
                script{
                    env.namespace = "${env.appName}".split('-')[0]   //devops6

                    sh """
                        ## 發(fā)布應(yīng)用
                        helm upgrade --install --create-namespace  "${env.appName}" ./"${env.appName}"-${env.chartVersion}.tgz -n ${env.namespace}
                        helm history "${env.appName}"  -n ${env.namespace}
                    """

                    // 獲取應(yīng)用狀態(tài)
                    5.times{
                        sh "sleep 2; kubectl -n ${env.namespace} get pod | grep ${env.appName}"
                    }

                    //收集history
                    env.revision = sh returnStdout: true, 
                                      script: """helm history ${env.appName} -n ${env.namespace} | grep -v 'REVISION' | awk '{print \$1}' """
                    println("${env.revision}")
                    println("${env.revision.split('\n').toString()}")
                    env.REVISION = "${env.revision.split('\n').toString()}"
                    println("${env.REVISION}")
                }
            }
        }


        stage("RollOut"){
            input {
                message "是否進(jìn)行回滾"
                ok "提交"
                submitter ""
                parameters {
                    choice(choices: ['yes', 'no'], name: 'opts')
                }
            }

            steps{
                script{

                   switch("${opts}") {
                        case "yes":
                        def result = input  message: "選擇回滾版本?", 
                            parameters: [choice(choices: env.REVISION, name: 'rversion')]

                        println("${result}")
                        sh "helm rollback ${env.appName} ${result} -n ${env.namespace} "
                        break

                        case "no":
                        break
                    }
                }
            }
        }
    }
}

關(guān)于我

我的博客主旨:

  • 排版美觀,語言精煉;
  • 文檔即手冊,步驟明細(xì),拒絕埋坑,提供源碼;
  • 本人實(shí)戰(zhàn)文檔都是親測成功的,各位小伙伴在實(shí)際操作過程中如有什么疑問,可隨時聯(lián)系本人幫您解決問題,讓我們一起進(jìn)步!

?? 微信二維碼
x2675263825 (舍得), qq:2675263825。

?? 微信公眾號
《云原生架構(gòu)師實(shí)戰(zhàn)》

?? 語雀

https://www.yuque.com/xyy-onlyone

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-jcxIcx9Z-1688896509333)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230624093747671.png)]

?? csdn
https://blog.csdn.net/weixin_39246554?spm=1010.2135.3001.5421

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

?? 知乎
https://www.zhihu.com/people/foryouone

實(shí)踐:devops之K8s環(huán)境持續(xù)部署,kubernetes,ci/cd

最后

“”“helm history ${env.appName} -n ${env.namespace} | grep -v ‘REVISION’ | awk ‘{print $1}’ “””
println(“ e n v . r e v i s i o n " ) p r i n t l n ( " {env.revision}") println(" env.revision")println("{env.revision.split(‘\n’).toString()}”)
env.REVISION = “KaTeX parse error: Undefined control sequence: \n at position 22: …evision.split('\?n?').toString()}"…{env.REVISION}”)
}
}
}

    stage("RollOut"){
        input {
            message "是否進(jìn)行回滾"
            ok "提交"
            submitter ""
            parameters {
                choice(choices: ['yes', 'no'], name: 'opts')
            }
        }

        steps{
            script{

               switch("${opts}") {
                    case "yes":
                    def result = input  message: "選擇回滾版本?", 
                        parameters: [choice(choices: env.REVISION, name: 'rversion')]

                    println("${result}")
                    sh "helm rollback ${env.appName} ${result} -n ${env.namespace} "
                    break

                    case "no":
                    break
                }
            }
        }
    }
}

}文章來源地址http://www.zghlxwxcb.cn/news/detail-542067.html


## 關(guān)于我

我的博客主旨:

- 排版美觀,語言精煉;
- 文檔即手冊,步驟明細(xì),拒絕埋坑,提供源碼;
- 本人實(shí)戰(zhàn)文檔都是親測成功的,各位小伙伴在實(shí)際操作過程中如有什么疑問,可隨時聯(lián)系本人幫您解決問題,讓我們一起進(jìn)步!



?? 微信二維碼
x2675263825 (舍得), qq:2675263825。

[外鏈圖片轉(zhuǎn)存中...(img-2zH5h7IE-1688896509332)]



?? 微信公眾號
《云原生架構(gòu)師實(shí)戰(zhàn)》

[外鏈圖片轉(zhuǎn)存中...(img-j8ISJdtA-1688896509332)]



?? 語雀

https://www.yuque.com/xyy-onlyone

[外鏈圖片轉(zhuǎn)存中...(img-jcxIcx9Z-1688896509333)]



?? csdn
[https://blog.csdn.net/weixin_39246554?spm=1010.2135.3001.5421](https://blog.csdn.net/weixin_39246554?spm=1010.2135.3001.5421)

[外鏈圖片轉(zhuǎn)存中...(img-C9UTIB9P-1688896509333)]



?? 知乎
[https://www.zhihu.com/people/foryouone](https://www.zhihu.com/people/foryouone)

[外鏈圖片轉(zhuǎn)存中...(img-UKUKP8qs-1688896509333)]

## 最后

好了,關(guān)于本次就到這里了,感謝大家閱讀,最后祝大家生活快樂,每天都過的有意義哦,我們下期見!

到了這里,關(guān)于實(shí)踐:devops之K8s環(huán)境持續(xù)部署的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 實(shí)踐:devops之云主機(jī)模式持續(xù)部署(ci-cd)

    實(shí)踐:devops之云主機(jī)模式持續(xù)部署(ci-cd)

    https://www.yuque.com/xyy-onlyone/aevhhf?# 《玩轉(zhuǎn)Typora》 2條Jenkins pipeline CI pipeline CD pipeline 標(biāo)準(zhǔn)規(guī)范 項目規(guī)范與總體設(shè)計 公司里面要使用流水線要做持續(xù)集成CI/CD的項目越來越多,這對流水線的設(shè)計和開發(fā)有不同的要求。我們經(jīng)常聽到用戶的反饋: 各種 不同語言的技術(shù)棧, 如何使流

    2024年02月12日
    瀏覽(18)
  • Kubernetes(K8s)基本環(huán)境部署

    Kubernetes(K8s)基本環(huán)境部署

    此處只做學(xué)習(xí)使用,配置單master環(huán)境。 1、ip+主機(jī)規(guī)劃(準(zhǔn)備五臺新機(jī))==修改各個節(jié)點(diǎn)的主機(jī)名 注意:關(guān)閉防火墻與selinux 節(jié)點(diǎn) 主機(jī)名 ip 身份 joshua1 kubernetes-master.openlab.cn 192.168.134.151 master joshua2 kubernetes-work1.openlab.cn 192.168.134.152 work1 joshua3 kubernetes-work2.openlab.cn 192.168.134.153

    2024年02月10日
    瀏覽(27)
  • 前端要了解的k8s、CI/CD、Devops概念

    簡單的理解,k8s就是 docker容器集群的管理工具 。他將容器進(jìn)行更多自動化的操作,自動創(chuàng)建、自動重啟、自動擴(kuò)容等,這個過程稱為 容器編排 。 k8s 抽象了硬件資源 ,將N臺物理機(jī)或云主機(jī)抽象成一個資源池,容器的調(diào)度交給K8S(例如CPU 不夠用就調(diào)度到一臺足夠使用的機(jī)器

    2024年02月03日
    瀏覽(72)
  • DevOps搭建(十九)-Jenkins+K8s自動化CI搭建詳細(xì)步驟

    DevOps搭建(十九)-Jenkins+K8s自動化CI搭建詳細(xì)步驟

    完整的pipeline-auto.yml腳本如下 完整的Jenkinsfile腳本如下 在Jenkins插件管理中搜索GitLab插件進(jìn)行安裝。 進(jìn)入Jenkins項目配置里的 構(gòu)建觸發(fā)器 ,勾選如下選項: 從系統(tǒng)管理-系統(tǒng)配置-Gitlab將驗證去掉,生產(chǎn)最好配置保證安全。 如果是GitLab和Jenkins在同一臺服務(wù)器,需要開啟允許請求

    2024年01月23日
    瀏覽(33)
  • Spring Boot實(shí)踐 --windows環(huán)境下 K8s 部署 Docker

    Spring Boot實(shí)踐 --windows環(huán)境下 K8s 部署 Docker

    Docker 是一個開源的應(yīng)用容器引擎,基于 Go 語言 并遵從 Apache2.0 協(xié)議開源。Docker 從 17.03 版本之后分為 CE(Community Edition: 社區(qū)版) 和 EE(Enterprise Edition: 企業(yè)版),用社區(qū)版就可以了。 Docker 包括三個基本概念: 鏡像(Image):Docker 鏡像(Image),就相當(dāng)于是一個 root 文件系統(tǒng)

    2024年02月06日
    瀏覽(30)
  • 基于K8s的DevOps平臺實(shí)踐(二)

    基于K8s的DevOps平臺實(shí)踐(二)

    工廠的流水線如下: 官方文檔 的流水線如下: 為什么叫做流水線?其實(shí)和工廠產(chǎn)品的生產(chǎn)線類似,pipeline 是從源碼到發(fā)布到線上環(huán)境。 關(guān)于流水線,需要知道的幾個點(diǎn): 重要的功能插件,幫助 Jenkins 定義了一套工作流框架; Pipeline 的實(shí)現(xiàn)方式是一套 Groovy DSL( 領(lǐng)域?qū)S谜Z

    2024年02月02日
    瀏覽(23)
  • 基于K8s的DevOps平臺實(shí)踐(一)

    基于K8s的DevOps平臺實(shí)踐(一)

    本篇文章基于 k8s 集群部署 gitlab、sonarQube、Jenkins 等工具,并把上述工具集成到 Jenkins 中,以 Django 項目和 SpringBoot 項目為例,通過多分支流水線及 Jenkinsfile 實(shí)現(xiàn)項目代碼提交到不同的倉庫分支,實(shí)現(xiàn)自動代碼掃描、單元測試、docker 容器構(gòu)建、k8s 服務(wù)的自動部署。 Continuous

    2024年02月03日
    瀏覽(24)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包