【DevOps】Kubernetes动态生成 Jenkins Slave(一)

文章目录

  • 一、简介
  • 二、k8s中安装Jenkins
    • 1、创建NFS
    • 2、在 kubernetes 中部署 jenkins
      • 2.1 创建命名空间
      • 2.2 创建pv和pvc
      • 2.3 创建sa 账号做 rbac 授权
      • 2.4 通过 deployment 部署 jenkins
      • 2.5 把 jenkins 前端加上 service,提供外部网络访问
  • 三、配置 Jenkins
    • 1、在浏览器访问 jenkins 的 web 界面:
    • 2、获取管理员密码
    • 3、 登录成功
  • 四、配置jenkins 动态的生成 Slave
    • 1、 优化Jenkins插件安装
    • 2、在 Jenkins 中安装 kubernetes 插件
    • 3、 配置 jenkins 连接到我们存在的 k8s 集群
    • 4、配置 pod-template
  • 五、测试动态的生成 Jenkins-Slave

一、简介

Jenkins master和jenkins-slave都运行在k8s集群内,采用如下架构部署:
【DevOps】Kubernetes动态生成 Jenkins Slave(一)_第1张图片

二、k8s中安装Jenkins

名称 IP 版本
k8s-master61 192.168.223.61 1.21.0
k8s-node62 192.168.223.62 1.21.0
jenkins 192.168.223.62 2.332.3

1、创建NFS

安装 nfs 服务,可以选择自己的任意一台机器,我选择的是 k8s 的控制节点 k8s-master61
1.1 在k8s-master61 和 k8s-node62 上安装 nfs 服务

注意:如果已经安装过 nfs,这个步骤可以忽略 
[root@k8s-master61 ~]# yum install nfs-utils -y 
[root@k8s-master61 ~]# systemctl start nfs 
[root@k8s-master61 ~]# systemctl enable nfs 

[root@k8s-node62 ~]# yum install nfs-utils -y 
[root@k8s-node62 ~]# systemctl start nfs 
[root@k8s-node62 ~]# systemctl enable nfs 

1.2 在k8s-master61 上创建一个 nfs 共享目录

#1) 创建共享目录/data/v2

[root@k8s-master61 ~]# mkdir /data/v2 -p
[root@k8s-master61 ~]# cat /etc/exports
/data/v1 192.168.223.0/24(rw,no_root_squash)
/data/v2 192.168.223.0/24(rw,no_root_squash)
/data/nfs_yaml 192.168.223.0/24(rw,no_root_squash)
/data/myImages 192.168.223.0/24(rw,no_root_squash) 

#根据自己需求进行创建
#/data/myImages 存放镜像
#/data/nfs_yaml 存放yaml文件


#2)使配置文件生效
[root@k8s-master61 ~]# exportfs -arv
[root@k8s-master61 ~]# systemctl restart nfs

2、在 kubernetes 中部署 jenkins

2.1 创建命名空间

[root@k8s-master61 ~]# kubectl create namespace jenkins-k8s
namespace/jenkins-k8s created
[root@k8s-master61 ~]# kubectl get ns |grep jenkins-k8s
jenkins-k8s         Active   8s

2.2 创建pv和pvc

# 应用资源配置清单
[root@k8s-master61 k8s-jenkins]# kubectl apply -f pv-pvc.yaml 

[root@k8s-master61 k8s-jenkins]# kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM                            STORAGECLASS       REASON   AGE
jenkins-k8s-pv                             10Gi       RWX            Retain           Available    
#查看创建的pvc
[root@k8s-master61 k8s-jenkins]# kubectl get pvc -n jenkins-k8s
NAME              STATUS   VOLUME           CAPACITY   ACCESS MODES   STORAGECLASS   AGE
jenkins-k8s-pvc   Bound    jenkins-k8s-pv   10Gi       RWX                           43s
  • pv_pvc.yaml 内容
apiVersion: v1
kind: PersistentVolume
metadata:
  name: jenkins-k8s-pv
spec:
  capacity:
    storage: 10Gi
  accessModes:
  - ReadWriteMany
  nfs:
    server: 192.168.223.61
    path: "/data/v2"

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: jenkins-k8s-pvc
  namespace: jenkins-k8s
spec:
  resources:
    requests:
      storage: 10Gi
  accessModes:
  - ReadWriteMany

注意: pvc可以属于某个命名空间,pv不属于任何命名空间
[root@k8s-master61 k8s-jenkins]# kubectl api-resources |grep pv
persistentvolumeclaims pvc v1 true PersistentVolumeClaim
persistentvolumes pv v1 false PersistentVolume

2.3 创建sa 账号做 rbac 授权

应用资源配置清单:

[root@k8s-master61 k8s-jenkins]# kubectl apply -f rbac.yaml
  • rbac.yaml 文件内容
apiVersion: v1
kind: ServiceAccount
metadata:
  name: jenkins-k8s-sa
  namespace: jenkins-k8s

---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: jenkins-k8s-cluseterrole
rules:
  - apiGroups: ["extensions", "apps"]
    resources: ["deployments"]
    verbs: ["create", "delete", "get", "list", "watch", "patch", "update"]
  - apiGroups: [""]
    resources: ["services"]
    verbs: ["create", "delete", "get", "list", "watch", "patch", "update"]
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["create","delete","get","list","patch","update","watch"]
  - apiGroups: [""]
    resources: ["pods/exec"]
    verbs: ["create","delete","get","list","patch","update","watch"]
  - apiGroups: [""]
    resources: ["pods/log"]
    verbs: ["get","list","watch"]
  - apiGroups: [""]
    resources: ["secrets"]
    verbs: ["get"]

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: jenkins-k8s-sa-cluster
  namespace: jenkins-k8s
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: jenkins-k8s-cluseterrole
subjects:
  - kind: ServiceAccount
    name: jenkins-k8s-sa
    namespace: jenkins-k8s

2.4 通过 deployment 部署 jenkins

参考jenkins官方文档:https://www.jenkins.io/doc/book/installing/kubernetes/

#)提前下载了该镜像
# docker pull jenkins/jenkins:2.332.3

#或者上传镜像到k8s 各 node 节点,并手动解压
# gunzip -c jenkins_2.332.3.tar.gz |docker load

更新资源清单文件

[root@k8s-master61 k8s-jenkins]# kubectl apply -f jenkins-deployment.yaml 
deployment.apps/jenkins created
[root@k8s-master61 k8s-jenkins]# kubectl get pod -n jenkins-k8s
NAME                      READY   STATUS             RESTARTS   AGE
jenkins-bddf8d8fb-gpmzr   0/1     CrashLoopBackOff   1          15s


#看到 jenkins-bddf8d8fb-gpmzr 是 CrashLoopBackOff 状态,查看日志: 

[root@k8s-master61 k8s-jenkins]# kubectl logs jenkins-bddf8d8fb-gpmzr -n jenkins-k8s
touch: cannot touch '/var/jenkins_home/copy_reference_file.log': Permission denied
Can not write to /var/jenkins_home/copy_reference_file.log. Wrong volume permissions?

报错显示没有权限操作/var/jenkins_home/copy_reference_file.log 文件,解决办法如下:

#删除创建的pod
[root@k8s-master61 k8s-jenkins]# kubectl delete -f jenkins-deployment.yaml 
deployment.apps "jenkins" deleted
#修改属主数组
[root@k8s-master61 k8s-jenkins]# chown -R 1000.1000 /data/v2
[root@k8s-master61 k8s-jenkins]# kubectl apply -f jenkins-deployment.yaml 
deployment.apps/jenkins created

# 查看创建成功
[root@k8s-master61 k8s-jenkins]# kubectl get pod -n jenkins-k8s
NAME                      READY   STATUS    RESTARTS   AGE
jenkins-bddf8d8fb-2vbn8   0/1     Running   0          15
  • jenkins-deployment.yaml
kind: Deployment
apiVersion: apps/v1
metadata:
  name: jenkins
  namespace: jenkins-k8s
spec:
  replicas: 1
  selector:
    matchLabels:
      app: jenkins
  template:
    metadata:
      labels:
        app: jenkins
    spec:
      serviceAccount: jenkins-k8s-sa
      containers:
      - name: jenkins
        image: jenkins/jenkins:2.332.3
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080
          name: web
          protocol: TCP
        - containerPort: 50000
          name: agent
          protocol: TCP
        resources:
          limits:
            cpu: 1000m
            memory: 1Gi
          requests:
            cpu: 500m
            memory: 512Mi
        livenessProbe:
          httpGet:
            path: /login
            port: 8080
          initialDelaySeconds: 60
          timeoutSeconds: 5
          failureThreshold: 12
        readinessProbe:
          httpGet:
            path: /login
            port: 8080
          initialDelaySeconds: 60
          timeoutSeconds: 5
          failureThreshold: 12
        volumeMounts:
        - name: jenkins-volume
          subPath: jenkins-home
          mountPath: /var/jenkins_home
      volumes:
      - name: jenkins-volume
        persistentVolumeClaim:
          claimName: jenkins-k8s-pvc

2.5 把 jenkins 前端加上 service,提供外部网络访问

更新资源清单文件

[root@k8s-master61 k8s-jenkins]# kubectl apply -f jenkins-service.yaml 
service/jenkins-service created

[root@k8s-master61 k8s-jenkins]# kubectl get svc -n jenkins-k8s
NAME              TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)                          AGE
jenkins-service   NodePort   10.100.119.49   <none>        8080:30002/TCP,50000:30008/TCP   25s

#通过上面可以看到 service 的 8080 端口在物理机映射的端口是 30002
  • jenkins-service.yaml 文件内容如下:
apiVersion: v1
kind: Service
metadata:
  name: jenkins-service
  namespace: jenkins-k8s
  labels:
    app: jenkins
spec:
  selector:
    app: jenkins
  type: NodePort
  ports:
  - name: web
    port: 8080
    targetPort: web
    nodePort: 30002
  - name: agent
    port: 50000
    targetPort: agent

三、配置 Jenkins

1、在浏览器访问 jenkins 的 web 界面:

【DevOps】Kubernetes动态生成 Jenkins Slave(一)_第2张图片

2、获取管理员密码

在 nfs 服务端,也就是我们的 k8s-master61 节点获取密码:

# cat /data/v2/jenkins-home/secrets/initialAdminPassword 
5474b1dba2094710a2ebfb06df922570

3、 登录成功

(1)点击继续,出现如下界面
【DevOps】Kubernetes动态生成 Jenkins Slave(一)_第3张图片

【DevOps】Kubernetes动态生成 Jenkins Slave(一)_第4张图片
(2)插件安装好之后显示如下
【DevOps】Kubernetes动态生成 Jenkins Slave(一)_第5张图片
(3)创建第一个管理员用户
【DevOps】Kubernetes动态生成 Jenkins Slave(一)_第6张图片
(4) 设置密码完成,点击保存并完成,并开始使用
【DevOps】Kubernetes动态生成 Jenkins Slave(一)_第7张图片
【DevOps】Kubernetes动态生成 Jenkins Slave(一)_第8张图片

四、配置jenkins 动态的生成 Slave

接下来我们就需要来配置 Jenkins,让他能够动态的生成 Slave 的 Pod。

1、 优化Jenkins插件安装

(1) 修改配置文件地址

#1) 进入配置目录
[root@k8s-master61 ~]# cd /data/v2/jenkins-home/updates/
[root@k8s-master61 updates]# ll
总用量 2872
-rw-r--r-- 1 1000 1000 2639693 65 23:44 default.json
-rw-r--r-- 1 1000 1000    5569 65 23:58 hudson.tasks.Ant.AntInstaller
-rw-r--r-- 1 1000 1000    6040 65 23:44 hudson.tasks.Maven.MavenInstaller
-rw-r--r-- 1 1000 1000  279724 65 23:58 hudson.tools.JDKInstaller

#2)替换为国内地址
[root@k8s-master61 updates]# sed -i 's/http:\/\/updates.jenkinsci.org\/download/https:\/\/mirrors.tuna.tsinghua.edu.cn\/jenkins/g' default.json
[root@k8s-master61 updates]# sed -i 's/http:\/\/www.google.com/https:\/\/www.baidu.com/g' default.json

(2) 修改页面插件下载地址
最后,系统管理 --> 插件管理 --> 高级,把站点升级改为国内插件下载地址

https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json

【DevOps】Kubernetes动态生成 Jenkins Slave(一)_第9张图片

2、在 Jenkins 中安装 kubernetes 插件

(1)在 jenkins 中安装 k8s 插件

Manage Jnekins------>插件管理------>可选插件------>搜索 kubernetes------>出现如下
【DevOps】Kubernetes动态生成 Jenkins Slave(一)_第10张图片

选中 kubernetes 之后------>点击下面的直接安装------>安装之后选择重新启动 jenkins—> http://192.168.223.61:30002/restart–>重启之后登陆 jenkins,插件即可生效

(2)安装 blueocean 插件

Manage Jnekins------>插件管理------>可选插件------>搜索 blueocean------>出现如下
【DevOps】Kubernetes动态生成 Jenkins Slave(一)_第11张图片

选中 BlueOcean 之后------>点击下面的直接安装------>安装之后选择重新启动 jenkins—> http://192.168.223.61:30002/restart–>重启之后登陆 jenkins,插件即可生效

3、 配置 jenkins 连接到我们存在的 k8s 集群

(1)访问 http://192.168.223.61:30002/configureClouds/
或者如下方式选择:系统管理–>节点管理

【DevOps】Kubernetes动态生成 Jenkins Slave(一)_第12张图片
【DevOps】Kubernetes动态生成 Jenkins Slave(一)_第13张图片
新增一个云,在下拉菜单中选择 kubernets 并添加

(2)填写云 kubernetes 配置内容
【DevOps】Kubernetes动态生成 Jenkins Slave(一)_第14张图片

(3)测试 jenkins 和 k8s 是否可以通信

【DevOps】Kubernetes动态生成 Jenkins Slave(一)_第15张图片
点击连接测试,如果显示 Connection test successful 或者
Connected to Kubernetes v1.21.0,说明测试成功,Jenkins 可以和 k8s 进行通信

在这里插入图片描述

http://jenkins-service.jenkins-k8s.svc.cluster.local:8080
配置 k8s 集群的时候 jenkins 地址需要写上面域名的形式,配置之后执行如下:

应用------>保存

4、配置 pod-template

(1)配置 pod template
访问 http://192.168.40.180:30002/configureClouds/

【DevOps】Kubernetes动态生成 Jenkins Slave(一)_第16张图片
【DevOps】Kubernetes动态生成 Jenkins Slave(一)_第17张图片
【DevOps】Kubernetes动态生成 Jenkins Slave(一)_第18张图片
【DevOps】Kubernetes动态生成 Jenkins Slave(一)_第19张图片

(2)在上面的 pod template 下添加容器
添加容器------>Container Template------>按如下配置------>

【DevOps】Kubernetes动态生成 Jenkins Slave(一)_第20张图片
【DevOps】Kubernetes动态生成 Jenkins Slave(一)_第21张图片

【DevOps】Kubernetes动态生成 Jenkins Slave(一)_第22张图片
在 Service Account 处输入 jenkins-k8s-sa,这个 sa 就是我们最开始安装 jenkins 时的 sa

(3)给上面的 pod template 添加卷
添加卷------>选择 Host Path Volume

【DevOps】Kubernetes动态生成 Jenkins Slave(一)_第23张图片

使容器能够宿主机docker:
/var/run/docker.sock
/var/run/docker.sock
使容器能够使用kubctl
/root/.kube
/home/jenkins/.kube

【DevOps】Kubernetes动态生成 Jenkins Slave(一)_第24张图片
上面配置好之后,Apply(应用)------>Save(保存)
到这里我们的 Kubernetes Plugin 插件就算配置完成了。

五、测试动态的生成 Jenkins-Slave

Kubernetes 插件的配置工作完成了,接下来我们就来添加一个 Job 任务,看是否能够在 Slave Pod 中执行,任务执行完成后看 Pod 是否会被销毁。
在 Jenkins 首页点击create new jobs,创建一个测试的任务,输入任务名称,然后我们选择 Freestyle project 类型的任务:

【DevOps】Kubernetes动态生成 Jenkins Slave(一)_第25张图片
【DevOps】Kubernetes动态生成 Jenkins Slave(一)_第26张图片
【DevOps】Kubernetes动态生成 Jenkins Slave(一)_第27张图片

echo "测试 Kubernetes 动态生成 jenkins slave"
echo "==============docker in docker==========="
docker info

echo "=============kubectl============="
kubectl get pods

【DevOps】Kubernetes动态生成 Jenkins Slave(一)_第28张图片
现在我们直接在页面点击做成的 Build now 触发构建即可,然后观察 Kubernetes 集群中 Pod 的变化

【DevOps】Kubernetes动态生成 Jenkins Slave(一)_第29张图片
查看构建输出也可以看到:
【DevOps】Kubernetes动态生成 Jenkins Slave(一)_第30张图片


下一篇: Jenkins+k8s+github实现DevOps流程

你可能感兴趣的:(DevOps,jenkins,kubernetes,devops)