使用 jenkins 实现 Kubernetes CI
部署 Jenkins
rbac.yaml
创建 ServiceAccount: jenkins-ci 授予 cluster-admin 权限, jenkins 在 kubernetes 集群中创建工作节点需要权限
你也可以在 kubernetes 插件中配置验证信息
apiVersion: v1
kind: ServiceAccount
metadata:
  name: jenkins-ci
  namespace: devops
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: jenkins-ci
  namespace: devops
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: admin
subjects:
- kind: ServiceAccount
  name: jenkins-ci
  namespace: devopspvc.yaml
为 jenkins 划分一块存储,用于持久化 jenkins 数据
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: jenkins-data
  namespace: devops
spec:
  storageClassName: managed-nfs-storage
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 5Gijenkins-ci.yml
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: jenkins
  namespace: devops
spec:
  selector:
    matchLabels:
      app: jenkins
  template:
    metadata:
      labels:
        app: jenkins
    spec:
      terminationGracePeriodSeconds: 10
      securityContext:
        runAsUser: 0
      containers:
      - name: jenkins
        image: jenkinsci/blueocean:1.24.6
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080
          name: web
          protocol: TCP
        - containerPort: 50000
          name: agent
          protocol: TCP
        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: data
          mountPath: /var/jenkins_home
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: jenkins-data
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: jenkins
  name: jenkins
  namespace: devops
spec:
  ports:
  - name: "web"
    port: 8080
    protocol: TCP
    targetPort: 8080
  - name: "agent"
    port: 50000
    protocol: TCP
    targetPort: 50000
  selector:
    app: jenkins
  type: ClusterIPingress-route.yml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: jenkins
  namespace: devops
spec:
  entryPoints:
    - web
  routes:
  - match: Host(`jenkins.host.com`)
    kind: Rule
    services:
    - name: jenkins
      port: 8080应用资源配置清单
kubectl apply -f rbac.yaml
kubectl apply -f pvc.yaml
kubectl apply -f configmap.yml
kubectl apply -f jenkins-ci.yml
kubectl apply -f ingress-route.yml配置 jenkins
首次登录配置
在浏览器打开 http://jenkins.host.com 开始配置 jenkins

下一步安装推荐插件即可,等待插件安装完成

创建管理用户

配置管理节点 (kubernetes)
kubernetes Cloud
通过 kubernetes 插件可以让 jenkins 在 kubernetes 集群以 pod 的方式运行工作节点,下面我们安装 kubernetes 插件, 安装完成后重启生效

现在我们配置 Jenkins 使用 Kubernetes Pod 运行管理节点
依次点击 系统管理 -> 节点管理 -> Configure Clouds -> Add a new cloud 添加 kubernetes 集群
点击 Kubernetes Cloud details 配置 kubernetes 集群
- Kubernetes 地址: https://kubernetes.default.svc
- Jenkins 地址: http://jenkins.devops.svc.cluster.local:8080
- Jenkins 通道: jenkins.devops.svc.cluster.local:50000
点击 Save 保存

POD 模板
在配置 POD 模板之前,我们需要规划好需要此 POD 工作节点执行哪些操作?
- 对项目进行编译 (以 Java项目为例, 使用maven完成)
- 将编译好的项目制作成 Docker镜像并推送至harbor仓库 (需要调用 docker 命令)
- 更新 kubernetes资源配置清单,并应用至kubernetes集群中 (需要调用 kubectl 命令)
理清楚步骤后我们开始配置 POD 模板,
依次点击 系统管理 -> 节点管理 -> Configure Clouds -> POD Template -> 添加 POD 模板
- 名称: maven-3.6
- 命名空间: devops(默认就是这个;和 jenkins 部署所在 namespace 一致)
- 容器名: maven
- Docker 镜像: maven:3.6-openjdk-11

准备挂载 (mount) 资源
给 maven POD 分配一个存储用于缓存从互联网下载的的资源,以便重复利用减少网络带宽占用节约等待时间
maven-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: maven-data
  namespace: devops
spec:
  storageClassName: managed-nfs-storage
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 5Gi创建 PVC
kubectl apply -f maven-pvc.yaml配置 docker push 镜像时所需要的验证信息,并挂载至 pod 容器的 /root/.docker 目录
docker 验证配置以 configmap 的形式存放在 集群中: configmap.yaml
apiVersion: v1
data:
  config.json: "{\n\t\"auths\": {\n\t\t\"harbor.wfugui.com\": {\n\t\t\t\"auth\": \"YWRtaW46SGFyYm9yMTIzNDU=\"\n\t\t}\n\t},\n\t\"HttpHeaders\":
    {\n\t\t\"User-Agent\": \"Docker-Client/19.03.15 (linux)\"\n\t}\n}"
kind: ConfigMap
metadata:
  creationTimestamp: null
  name: docker-auth
  namespace: devops创建 configmap
kubectl apply -f configmap.yaml点击添加卷,添加如下卷
- Persistent Volume Claim- 申请值: maven-data
- 挂载路径: /root/.m2
 
- 申请值: 
- Config Map Volume:- Config Map 名称: docker-auth
- 挂载路径: /root/.docker
 
- Config Map 名称: 
- Host Path Volume:- 主机路径: /var/run/docker.sock
- 挂载路径: /root/.docker
 
- 主机路径: 
- Host Path Volume:- 主机路径: /usr/bin/docker
- 挂载路径: /usr/bin/docker
 
- 主机路径: 
- Host Path Volume:- 主机路径: /usr/bin/kubectl
- 挂载路径: /usr/bin/kubectl
 
- 主机路径: 
配置 Server Account 为 jenkins-ci

使用 Jenkins 实现 CI
准备测试项目
- 登录 http://git.host.com, 创建一个test组织,
- 克隆 https://github.com/liwanggui/spring-boot-helloworld项目到test组织下
- 创建一个名 jenkins的用户,将其加入到 test 组织中
项目文件结构
├── Dockerfile          # 使用此 Dockerfile build docker 镜像
├── jenkins
│   ├── deliver.sh      # jenkins 流水线中会调用此脚本
│   ├── Jenkinsfile     # jenkins 声明式流水线配置
│   └── k8s             # 项目 kubernetes 资源配置清单
│       ├── deployment.yaml
│       ├── ingress.yaml
│       └── service.yaml
├── pom.xml
├── README.md
└── src
    ├── main
    │   └── java
    │       └── hello
    │           ├── Application.java
    │           └── HelloController.java
    └── test
        └── java
            └── hello
                ├── HelloControllerIT.java
                └── HelloControllerTest.java配置流水线
在 Jenkins 管理界面,点击新建任务创建一个名称为 spring-boot-helloworld 类型为流水线(pipeline)的任务
配置 spring-boot-helloworld 任务配置界面点击流水线,选择 Pipenline script from SCM
- SCM: Git- Repository Url: http://gogs.devops.svc.cluster.local:3000/test/spring-boot-helloworld
- Credentials: 配置 git 仓库验证信息,使用上面创建的 jenkins 用户
脚本本路径: jenkins/Jenkinsfile
 
- Repository Url: 
保存

构建项目和查看结果
点击开始构建,在构建过程可以点进去查看实时输出日志信息