Kubernetes+Jenkins+gitea实现DevOps

Kubernetes+Jenkins+gitea实现DevOps

1:主机信息

主机 软件 版本
10.0.0.10 Kubernetes-master 1.23.1
10.0.0.11 Kubernetes-worker-1 1.23.1
10.0.0.12 Kubernetes-worker-2 1.23.1
10.0.0.13 Harbor 2.0
10.0.0.14 NFS存储 v4
10.0.0.15 Gitea 1.15.9

2:Harbor部署

参照以下链接

Kubernetes+Harbor部署

3:NFS持久化部署

Kubernetes部署动态存储

4:部署Gitlab(文章内没用到)

# yaml如下
[root@k8s-master mnt]# cat gitlab.yaml 
kind: Namespace
apiVersion: v1
metadata:
  name: devops
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: gitlab-conf
  namespace: devops
spec:
  storageClassName: "managed-nfs-storage"
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 5Gi
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: gitlab-logs
  namespace: devops
spec:
  storageClassName: "managed-nfs-storage"
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 5Gi
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: gitlab-data
  namespace: devops
spec:
  storageClassName: "managed-nfs-storage"
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 5Gi
---
kind: Deployment
apiVersion: apps/v1
metadata:
  name: gitlab
  namespace: devops
spec:
  replicas: 1
  selector:
    matchLabels:
      app: gitlab
  template:
    metadata:
      labels:
        app: gitlab
    spec:
      imagePullSecrets:
      - name: harbor
      containers:
      - name: gitlab
        image: registry.kubernetes.com/library/gitlab-ce:latest
        ports:
        - containerPort: 80
          name: http
        - containerPort: 443
          name: https
        - containerPort: 2222
          name: ssh
        volumeMounts:
        - name: conf
          mountPath: /etc/gitlab
        - name: logs
          mountPath: /var/log/gitlab
        - name: data
          mountPath: /var/opt/gitlab
      volumes:
      - name: conf
        persistentVolumeClaim:
          claimName: gitlab-conf
      - name: logs
        persistentVolumeClaim:
          claimName: gitlab-logs
      - name: data
        persistentVolumeClaim:
          claimName: gitlab-data
---
apiVersion: v1
kind: Service
metadata:
  name: gitlab-svc
  namespace: devops
spec:
  type: NodePort
  ports:
  - name: http
    port: 80
    targetPort: 80
    nodePort: 30080
  - name: https
    port: 443
    targetPort: 443
    nodePort: 30443
  - name: ssh
    port: 2222
    targetPort: 2222
    nodePort: 32222
  selector:
    app: gitlab

[root@k8s-master mnt]# kubectl apply -f gitlab.yaml 
namespace/devops create
persistentvolumeclaim/gitlab-conf create
persistentvolumeclaim/gitlab-logs create
persistentvolumeclaim/gitlab-data create
deployment.apps/gitlab create
service/gitlab-svc create

# 因为我这里配置太低,我选择再新的服务器上去跑Gitea了
[root@virtual_host ~]# docker run -d --name gitea -v /gitea:/data -p 2222:22 -p 3000:3000 registry.kubernetes.com/library/gitea:latest
# 然后访问

image
image

5:在 Kubernetes 中部署 Jenkins

[root@k8s-master jenkins]# cat jenkins.yaml 
apiVersion: v1
kind: Namespace
metadata:
  name: gitops
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: jenkins
  namespace: gitops
spec:
  storageClassName: "managed-nfs-storage"
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 5Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: jenkins
  namespace: gitops
spec:
  replicas: 1
  selector:
    matchLabels:
      name: jenkins 
  template:
    metadata:
      name: jenkins
      labels:
        name: jenkins
    spec:
      serviceAccountName: jenkins
      imagePullSecrets:
      - name: harbor
      containers:
        - name: jenkins
          image: registry.kubernetes.com/library/jenkins:lts
          ports:
            - containerPort: 8080
            - containerPort: 50000
          resources:
            limits:
              cpu: 2
              memory: 4Gi
            requests:
              cpu: 1
              memory: 1Gi
          env:
            - name: LIMITS_MEMORY
              valueFrom:
                resourceFieldRef:
                  resource: limits.memory
                  divisor: 1Mi
            - name: JAVA_OPTS
              value: -Xmx$(LIMITS_MEMORY)m -XshowSettings:vm -Dhudson.slaves.NodeProvisioner.initialDelay=0 -Dhudson.slaves.NodeProvisioner.MARGIN=50 -Dhudson.slaves.NodeProvisioner.MARGIN0=0.85
          volumeMounts:
            - name: config
              mountPath: /var/jenkins_home
      securityContext:
        fsGroup: 1000
      volumes:
      - name: config
        persistentVolumeClaim:
          claimName: jenkins
---
apiVersion: v1
kind: Service
metadata:
  name: jenkins
  namespace: gitops
spec:
  selector:
    name: jenkins
  type: NodePort
  ports:
    - name: http
      port: 80
      targetPort: 8080
      protocol: TCP
      nodePort: 30008
    - name: agent
      port: 50000
      protocol: TCP
---
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: jenkins
  namespace: gitops
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: jenkins
  namespace: gitops
rules:
- apiGroups: [""]
  resources: ["pods","events"]
  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","events"]
  verbs: ["get"]

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: jenkins
  namespace: gitops
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: jenkins
subjects:
- kind: ServiceAccount
  name: jenkins
  
  
[root@k8s-master jenkins]# kubectl apply -f jenkins.yaml 
namespace/gitops created
persistentvolumeclaim/jenkins created
deployment.apps/jenkins created
service/jenkins created
serviceaccount/jenkins created
role.rbac.authorization.k8s.io/jenkins created
rolebinding.rbac.authorization.k8s.io/jenkins created


[root@k8s-master jenkins]# kubectl get pod,svc,pvc -n gitops 
NAME                          READY   STATUS    RESTARTS   AGE
pod/jenkins-6d6575f97-66qnl   1/1     Running   0          71s

NAME              TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)                        AGE
service/jenkins   NodePort   172.1.87.236   <none>        80:30008/TCP,50000:30115/TCP   72s

NAME                            STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS          AGE
persistentvolumeclaim/jenkins   Bound    pvc-82475fb0-9ceb-44a3-9a87-9100b370c5e5   5Gi        RWX            managed-nfs-storage   72s

[root@k8s-master jenkins]# kubectl logs -f -n gitops jenkins-6d6575f97-66qnl
# 寻找token
Jenkins initial setup is required. An admin user has been created and a password generated.
Please use the following password to proceed to installation:

9690339aedae45a2a6ebec8d6e2c0a36

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

image
image
image
image
image
image
image

# 配置插件源
默认从国外网络下载插件,会比较慢,建议修改成国内源:
只需要到nfs上,修改PVC挂载的内容即可

[root@k8s-nfs data]# cd gitops-jenkins-pvc-82475fb0-9ceb-44a3-9a87-9100b370c5e5/
[root@k8s-nfs gitops-jenkins-pvc-82475fb0-9ceb-44a3-9a87-9100b370c5e5]# cd updates/
[root@k8s-nfs updates]# ls
default.json  hudson.tasks.Maven.MavenInstaller
#先备份好配置文件
[root@k8s-nfs updates]# cp default.json default.json-bak
#修改插件的下载地址为国内的地址
[root@k8s-nfs updates]# sed -i s#https://updates.jenkins.io/download#https://mirrors.tuna.tsinghua.edu.cn/jenkins#g default.json
#修改jenkins启动时检测的URL网址,改为国内baidu的地址
[root@k8s-nfs updates]# sed -i s#http://www.google.com#https://www.baidu.com#g default.json default.json
删除pod重建(pod名称改成你实际的)
[root@k8s-master jenkins]# kubectl delete pod -n gitops jenkins-9c7ff5ccf-qrpfv 
pod "jenkins-9c7ff5ccf-qrpfv" deleted
[root@k8s-master jenkins]# kubectl get pod -A
NAMESPACE        NAME                                       READY   STATUS    RESTARTS      AGE
default          nfs-client-provisioner-6c6cc8fc79-95lck    1/1     Running   4             40h
gitops           jenkins-9c7ff5ccf-4274z                    1/1     Running   0             6s

修改完后,jenkins 会重建,打开浏览器访问: http://NodePort:30008
输入账户密码从新登陆jenkins控制台

image

依次点击 管理Jenkins(Manage Jenkins)->系统配置(System Configuration)-->管理插件(Manage Pluglns)-->

image

分别搜索 Git/Git Parameter/Pipeline/kubernetes/Config File Provider,选中点击安装。

image
image

安装插件可能会失败,多试几次就好了,安装完记得重启Pod

image

6:jenkins在K8S中动态创建代理

image
image

在jenkins中添加kubernetes
管理Jenkins->Manage Nodes and Clouds->configureClouds->Add
输入Kubernetes 地址: https://kubernetes.default ,点击连接测试,测试通过的话,会显示k8s的版本信息

image
image
image

注:配置地址时看清jenkins端口,这里我用的80所以没有加端口

image
image

构建Jenkins-Slave镜像
PS: jenkins 官方有jenkins-slave 制作好的镜像,可以直接 docker pull jenkins/jnlp-slave 下载到本地并上传本地私有镜像厂库。官方的镜像好处就是不需要再单独安装maven,kubectl 这样的命令了,可以直接使用,不过我推荐使用:jenkins/inbound-agent:latest这个镜像
[root@k8s-master jenkins]# docker pull jenkins/jnlp-slave
Using default tag: latest
latest: Pulling from jenkins/jnlp-slave
0bc3020d05f1: Pull complete 
ee3587ec32c3: Pull complete 
0bd0b3e8a1ee: Pull complete 
1fa8464ca717: Pull complete 
7d14d7239e34: Pull complete 
b93ce180cea6: Pull complete 
30148198bfd1: Pull complete 
320290e2da01: Pull complete 
6ec915afa1f9: Pull complete 
594bdbdc48b5: Pull complete 
Digest: sha256:b47df39ab0f03ec8003e853e9bd31d5cd1cf49955fa0d15173868f474f503de7
Status: Downloaded newer image for jenkins/jnlp-slave:latest
docker.io/jenkins/jnlp-slave:latest
[root@k8s-master jenkins]# docker tag jenkins/jnlp-slave:latest registry.kubernetes.com/library/jenkins:slave
[root@k8s-master jenkins]# docker push registry.kubernetes.com/library/jenkins:slave 
The push refers to repository [registry.kubernetes.com/library/jenkins]
d5af25323a5c: Pushed 
0053d86c4d81: Pushed 
4cb0baa801b1: Pushed 
3f01ba93adcb: Pushed 
3dee86c3d230: Pushed 
5ccb7c9ecca8: Pushed 
8a510d97a0f7: Pushed 
3f948fda930d: Pushed 
cf7a8ba4ff71: Pushed 
4e006334a6fd: Pushed 
slave: digest: sha256:b47df39ab0f03ec8003e853e9bd31d5cd1cf49955fa0d15173868f474f503de7 size: 2415
# 在jenkins 中创建一个流水线项目,测试jenkins-slave 是否功能

image
image

在pipeline 中 编写脚本,pipeline 脚本分为 声明式 和 脚本式
需要注意的是,spec 中定义containers的名字一定要写jnlp

image

pipeline {
    agent {
        kubernetes {
            yaml '''
apiVersion: v1
kind: Pod
metadata:
  name: jenkins-slave
  namespace: gitops
spec:
  imagesPullSecrets:
  - name: harbor
  containers:
  - name: jnlp
    image: "registry.kubernetes.com/library/jenkins:slave"
'''

        }
    }
    stages {
        stage('测试') {
            steps {
                sh 'hostname'
            }
        }
    }
}

点击Build New 按钮,开始构建

image
image
image

同时在构建的时候,K8S 集群中的gitops 命名空间下,临时起了一个pod,这个Pod就是 jenkins 动态创建的代理,用于执行jenkins master 下发的任务
当jenkins 构建的任务完成后,这个pod会自动销毁

# 为jenkins-slave做持久化
原因:因为每次maven 打包会产生依赖的库文件,为了加快每次编译打包的速度,可以创建一个pvc 用来存储maven 每次打包产生的依赖文件。以及 我们需要将 k8s 集群 node 主机上的docker 命令挂载到Pod 中,用于镜像的打包 ,推送

# pvc如下
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: jenkins-slave
  namespce: gitops
spec:
  storageClassName: "managed-nfs-storage"
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 5Gi
# 创建
[root@k8s-master jenkins]# kubectl apply -f jenkins-slave-pvc.yaml 
persistentvolumeclaim/jenkins-slave created

挂载到jenkins-slave的pod下
apiVersion: v1
kind: Pod
metadata:
  name: jenkins-slave
  namespace: gitops
spec:
  imagePullSecrets:
  - name: harbor
  containers:
  - name: jnlp
    image: "registry.kubernetes.com/library/slave:latest"
    volumeMounts:
      - name: docker-command
        mountPath: /usr/bin/docker
      - name: docker-sock
        mountPath: /var/run/docker.sock
      - name: maven-cache
        mountPath: /root/.m2
  volumes:
    - name: docker-command
      hostPath:
        path: /usr/bin/docker
    - name: docker-sock
      hostPath:
        path: /var/run/docker.sock
    - name: maven-cache
      persistentVolumeClaim:
        claimName: jenkins-slave

7:Jenkins在Kubernetes中持续部署

使用Jenkins在Kubernetes中持续部署一个无状态的flask网页(此处没有用到maven)
[root@k8s-master devops]# cat app.py 
from flask import Flask

app = Flask(__name__)

@app.route('/')
def index ():
    return "Hello DevOps"

if __name__=='__main__':
    app.run(host='0.0.0.0',port='8080')
[root@k8s-master flask]# cd devops/
[root@k8s-master devops]# ls
app.py
[root@k8s-master devops]# git add .
[root@k8s-master devops]# git commit -m "devopsv1"

*** Please tell me who you are.

Run

  git config --global user.email "you@example.com"
  git config --global user.name "Your Name"

to set your account's default identity.
Omit --global to set the identity only in this repository.

fatal: unable to auto-detect email address (got 'root@k8s-master.(none)')
[root@k8s-master devops]# git config --global user.email "devops@kubernetes.com"
[root@k8s-master devops]# git config --global user.name "devops"
[root@k8s-master devops]# git commit -m "devopsv1"
[master (root-commit) 3198983] devopsv1
 1 file changed, 10 insertions(+)
 create mode 100644 app.py
[root@k8s-master devops]# git push origin 
HEAD     master   
[root@k8s-master devops]# git push origin master 
Username for 'http://10.0.0.15:3000': devops
Password for 'http://devops@10.0.0.15:3000': 
Counting objects: 3, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 334 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote: . Processing 1 references
remote: Processed 1 references in total
To http://10.0.0.15:3000/devops/devops.git
 * [new branch]      master -> master

image

生成拉取git 代码的Pipeline 脚本
登陆jenkins 控制器,使用凭据的方式保存 git 账户信息,用于jenkins 拉取代码
Manage Jenkins -> Manage Credentials -> 全局凭据 (unrestricted) -> Add Credentials

image
image
image

这里选择Kind 类型 为 Username with passwd

image

pipeline 生成 git 拉取代码的语法(jenkins 官方提供一个pipeline 语法的生成器)
创建一个pipline项目

image

在pipeline 选项那里点击 , pipeline Syntax

image

1:点击片段生成器,在sample step 下拉选项框 中 找到 checkout: check out from version control
2:输入Repository URL(代码仓库地址): http://10.0.0.15:3000/devops/devops.git
3:点击Credentials 选择 刚刚创建的git 的用户凭证
4:最后点击 Generate Pipeline Script 生产pipeline 语法

image
image

checkout([$class: 'GitSCM', branches: [[name: '*/master']], extensions: [], userRemoteConfigs: [[credentialsId: '552986f7-f727-49ce-b6c4-993e24fd6dd3', url: 'http://10.0.0.15:3000/devops/devops.git']]])

@checkout([$class: 'GitSCM', branches: [[name: '*/master']], extensions: [], userRemoteConfigs: [[credentialsId: '552986f7-f727-49ce-b6c4-993e24fd6dd3', url: 'http://10.0.0.15:3000/devops/devops.git']]])

# 打包镜像测试
[root@k8s-master devops]# cat dockerfile 
FROM centos:7.9.2009

RUN yum install -y python3 python3-devel && pip3 install flask -i "https://mirrors.aliyun.com/pypi/simple"

COPY ./app.py /opt/

EXPOSE 8080
CMD ["python3","/opt/app.py"]
[root@k8s-master devops]# docker run -d --name flask -p 8080:8080 registry.kubernetes.com/library/flask:v1 
5908c4d41a05b00170cf01e213ebdcf8ddcbc655a23fbdeab5471ad1c5678a52
[root@k8s-master devops]# curl 10.0.0.10:8080
Hello DevOps

构建镜像 :
docker build -t ${image_name} .
登陆Harbor仓库:
docker login -u ${username} -p '${password}' ${registry} 
上传到镜像仓库: docker push ${image_name}
变量解释:
${image_name} 表示构建后的镜像名称(这里的镜像名称的标签名,每次都是不一样的,BUILD_NUMBER 为 jenkins 内置变量,jenkins 构建编号)
${username} 表示登陆Harbor的用户名
${password} 表示登陆Harbor的密码
${registry} 表示Harbor镜像仓库地址

在Jenkins pipeline中,有时需要带用户名密码执行命令,如docker login,将用户名密码以明文方式放到pipeline中显然是不安全的。这时可以通过credential插件实现。下面介绍具体方法:
第一步 安装Jenkins插件 在Jenkins中安装 ‘Credentials Plugin’插件
第二步 在凭证中配置docker 连接harbor 的用户名密码, 用于docker 从Harbor 镜像仓库中 上传,下载 镜像
Manage Jenkins -> Manage Credentials -> 全局凭据 (unrestricted) -> Add Credentials

image

第三步 pipeline中引用示例
steps {
               withCredentials([usernamePassword(credentialsId: "${docker_registry_auth}", passwordVariable: 'password', usernameVariable: 'username')]) {
               sh """
               docker build -t ${image_name} .
               docker login -u ${username} -p '${password}' ${registry}
               docker push ${image_name}
               """
               }
}

创建kubeconfig 文件,编写deploy.yaml pod模板文件
在上面构建Jenkins-Slave镜像的时候,我们已经在镜像里安装了kubectl 命令,只需要再添加一个kubeconfig 文件去连接K8S 集群,创建标准的 deployment.yaml ,servies.yaml 文件 就可以使用 kubectl apply XXX.yaml 文件从而生成pod

# 拿出kubeconfig文件 上传至jenkins
存储kubectl用于连接k8s集群的kubeconfig配置文件,需要安装 Config File Provider 这个插件, 上面在部署jenkins 环境初始化的时候,已经安装好了该插件
Manage Jenkins -> Managed files -> Add a new Config -> Custom file(自定义文件)

image
image
image
image

把Managed files 中的配置文件 转换成pipeline 语法
同样适用 jenkins 官方提供一个pipeline 语法的生成器
点击片段生成器,Sample Step 下拉选项框中 选择 configFileProvider: Provide Configuration files

在File 下拉选项框中,选中 刚刚创建的 自定义文件 k8s-kubeconfig

在Target 中 输入 admin.kubeconfig (target 表示把 自定义的文件 挂载到 jenkin-slave 镜像的什么路径下,这边定义了文件名称,就相当于把 admin.kubeconfig 文件 放在 jenkin-slave 镜像 的默认工作路径下/home/jenkins/agent/workspace/XX 下面 )

最后点击 Generate Pipeline Script 生产pipeline 语法

image

编写标准的deploy.yaml 模板
apiVersion: apps/v1
kind: Deployment
metadata:
  name: flask
spec:
  replicas: REPLICAS
  selector:
    matchLabels:
      app: flask
  template:
    metadata:
      labels:
        app: flask
    spec:
      imagePullSecrets:
      - name: SECRET_NAME
      containers:
      - image: IMAGE_NAME
        name: flask
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: flask-svc 
spec:
  selector:
    app: flask
  type: NodePort
  ports:
    - protocol: TCP
      port: 8080
      targetPort: 8080

定义环境变量,使用参数化构建,修改deploy.yaml文件
//定义harbor的地址
def registry = "registry.kubernetes.com"

// 项目,BUILD_NUMBER jenkins 内置变量,jenkins 构建编号
def project = "library"
def app_name = "flask"
def image_name = "${registry}/${project}/${app_name}:${BUILD_NUMBER}"
def git_address = "http://10.0.0.15:3000/devops/devops.git"

// 认证
//k8s 连接harbor 证书
def secret_name = "harbor"

//jenkins中定义docker连接harbor的用户密码凭证
def docker_registry_auth = "f175b48e-3be9-400a-b8a6-6fac1c35eab7"

//jenkins中定义git连接gitlab的用户密码凭证
def git_auth = "552986f7-f727-49ce-b6c4-993e24fd6dd3"

//jenkins中Config File Provider插件 定义的kubeconfig 文件内容
def k8s_auth = "d5a46a6e-8fa9-4147-a39d-1f5bd396c861"

发布分支(prod,dev)
副本数(1,3,5,7)
命名空间(prod,dev)

一个标准的deploy.yaml模板文件,需要把修改的内容:
#修改deploy.yaml 中镜像名称
sed -i 's#IMAGE_NAME#${image_name}#' flask.yaml

#修改deploy.yaml 中k8s连接harbor连接的secret
sed -i 's#SECRET_NAME#${secret_name}#' flask.yaml

#修改deploy.yaml 中副本的数量
sed -i 's#REPLICAS#${ReplicaCount}#' flask.yaml

#指定pod 创建在哪个命名空间下
kubectl apply -f flask.yaml -n ${Namespace} --kubeconfig=admin.kubeconfig

pipeline中引用示例:
//参数化构建
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: ['default'], description: '命名空间', name: 'Namespace')
    }

//部署pod需要修改的内容
sh """
sed -i 's#IMAGE_NAME#${image_name}#' flask.yaml
sed -i 's#SECRET_NAME#${secret_name}#' flask.yaml
sed -i 's#REPLICAS#${ReplicaCount}#' flask.yaml
kubectl apply -f deploy.yaml -n ${Namespace} --kubeconfig=admin.kubeconfig
"""
# 完整的pipeline 流水线 脚本

def registry = "registry.kubernetes.com"
def project = "library"
def app_name = "flask"
def image_name = "${registry}/${project}/${app_name}:${BUILD_NUMBER}"
def git_address = "http://10.0.0.15:3000/devops/devops.git"
def secret_name = "harbor"
def docker_registry_auth = "f175b48e-3be9-400a-b8a6-6fac1c35eab7"
def git_auth = "552986f7-f727-49ce-b6c4-993e24fd6dd3"
def k8s_auth = "d5a46a6e-8fa9-4147-a39d-1f5bd396c861"

pipeline {
    agent {
        kubernetes {
            yaml '''
apiVersion: v1
kind: Pod
metadata:
  name: jenkins-slave
  namespace: gitops
spec:
  imagePullSecrets:
  - name: harbor
  containers:
  - name: jnlp
    image: "registry.kubernetes.com/library/slave:latest"
    volumeMounts:
      - name: docker-command
        mountPath: /usr/bin/docker
      - name: docker-sock
        mountPath: /var/run/docker.sock
      - name: maven-cache
        mountPath: /root/.m2
  volumes:
    - name: docker-command
      hostPath:
        path: /usr/bin/docker
    - name: docker-sock
      hostPath:
        path: /var/run/docker.sock
    - name: maven-cache
      persistentVolumeClaim:
        claimName: jenkins-slave
'''
        }
    }
    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: ['default'], 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 {
                withCredentials([usernamePassword(credentialsId: "${docker_registry_auth}", passwordVariable: 'password', usernameVariable: 'username')]) {
                sh """
                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}#' flask.yaml
                  sed -i 's#SECRET_NAME#${secret_name}#' flask.yaml
                  sed -i 's#REPLICAS#${ReplicaCount}#' flask.yaml
                  kubectl apply -f flask.yaml -n ${Namespace} --kubeconfig=admin.kubeconfig
                  sleep 120
                  kubectl get pods,svc -n ${Namespace} --kubeconfig=admin.kubeconfig
                """
              }
          }
        }
    }
}

image
image

变更代码提交到仓库,重新构建测试
[root@k8s-master devops]# cat app.py 
from flask import Flask

app = Flask(__name__)

@app.route('/')
def index ():
    return "<h1><a href="https://www.cnblogs.com/devopsdu">DevOps_v2</a></h1>"

if __name__=='__main__':
    app.run(host='0.0.0.0',port='8080')
[root@k8s-master devops]# git add .
[root@k8s-master devops]# git commit -m "flask v2"
[master 4410221] flask v2
 1 file changed, 1 insertion(+), 1 deletion(-)
[root@k8s-master devops]# git push origin master 
Username for 'http://10.0.0.15:3000': devops
Password for 'http://devops@10.0.0.15:3000': 
Counting objects: 5, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 364 bytes | 0 bytes/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: . Processing 1 references
remote: Processed 1 references in total
To http://10.0.0.15:3000/devops/devops.git
   4475897..4410221  master -> master

image
image
image

到此迭代更新就完成了!!!
posted @ 2022-03-20 20:06  Layzer  阅读(846)  评论(0编辑  收藏  举报