前言
Jenkins 是一个开源的自动化持续集成和持续交付(CI/CD)工具,旨在帮助开发团队自动化软件构建、测试和部署的过程。它提供了一个灵活的插件系统,允许用户根据项目的需求自定义工作流程。Jenkins的主要功能包括:
- 自动化构建和测试:Jenkins可以自动构建和测试代码,以确保每次更改都能够通过各种测试。
- 插件生态系统:Jenkins拥有一个庞大的插件生态系统,支持各种不同的集成,从版本控制到部署到云服务,都有相应的插件可用。
- 可扩展性:Jenkins是高度可扩展的,可以根据团队和项目的需求添加自定义插件和脚本。
- 分布式构建:Jenkins支持分布式构建,可以将任务分发到多个代理机器上,以提高构建和测试的效率。
- 构建历史和日志:Jenkins会记录构建历史和日志,帮助开发团队跟踪问题和了解构建状态。
目前行业中可以使用的CI/CD的工具有很多,比如 Jenkins、Gitlab CI 等,此系列文章我们以Jenkins来实现在K8s上的CI/CD。
Jenkins
为了基于 Kubernetes 构建 CI/CD,我们可以考虑将 Jenkins 安装到 Kubernetes 集群中。有多种安装方式可选,但我们可以选择手动安装的方式,这样有助于更深入地了解相关细节。以下是对应的资源清单文件示例:
部署清单
我们采用StatefulSet控制器进行部署:
root@master:~/manifests/devops# cat jenkins-sts.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: jenkins
namespace: devops
spec:
volumeClaimTemplates:
- metadata:
name: jenkinshome
spec:
storageClassName: "local-path"
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 3Gi
selector:
matchLabels:
app: jenkins
template:
metadata:
labels:
app: jenkins
spec:
serviceAccount: jenkins
initContainers:
- name: fix-permissions
image: busybox:1.28
command: ["sh", "-c", "chown -R 1000:1000 /var/jenkins_home"]
securityContext:
privileged: true
volumeMounts:
- name: jenkinshome
mountPath: /var/jenkins_home
containers:
- name: jenkins
image: jenkins/jenkins:lts-jdk11
imagePullPolicy: IfNotPresent
env:
- name: JAVA_OPTS
value: -Dhudson.model.DownloadService.noSignatureCheck=true
ports:
- containerPort: 8080
name: web
protocol: TCP
- containerPort: 50000
name: agent
protocol: TCP
# resources:
# limits:
# cpu: 1500m
# memory: 2048Mi
# requests:
# cpu: 1500m
# memory: 2048Mi
readinessProbe:
httpGet:
path: /login
port: 8080
initialDelaySeconds: 60
timeoutSeconds: 5
failureThreshold: 12
volumeMounts:
- name: jenkinshome
mountPath: /var/jenkins_home
---
apiVersion: v1
kind: Service
metadata:
name: jenkins
namespace: devops
labels:
app: jenkins
spec:
selector:
app: jenkins
ports:
- name: web
port: 8080
targetPort: web
- name: agent
port: 50000
targetPort: agent
RBAC授权
另外我们这里还需要使用到一个拥有相关权限的 serviceAccount:jenkins,我们这里只是给 jenkins 赋予了一些必要的权限:
root@master:~/manifests/devops# cat jenkins-rabc.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: jenkins
namespace: devops
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: jenkins
rules:
- apiGroups: ["extensions", "apps"]
resources: ["deployments", "ingresses"]
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", "events"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: jenkins
namespace: devops
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: jenkins
subjects:
- kind: ServiceAccount
name: jenkins
namespace: devops
服务外放
最后我们通过 Ingress来暴露jenkins服务:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: jenkins
namespace: devops
spec:
ingressClassName: nginx
rules:
- host: devops.jenkins.com
http:
paths:
- path: /
pathType: "Prefix"
backend:
service:
name: jenkins
port:
name: web
部署
root@master:~/manifests/devops# kubectl apply -f .
statefulset.apps/jenkins created
serviceaccount/jenkins created
clusterrole.rbac.authorization.k8s.io/jenkins created
clusterrolebinding.rbac.authorization.k8s.io/jenkins created
service/jenkins created
ingress.networking.k8s.io/jenkins created
查看资源状态并配置hosts解析
root@master:~/manifests/devops# kubectl -n devops get pod,svc,ingress
NAME READY STATUS RESTARTS AGE
pod/jenkins-0 1/1 Running 0 11m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/jenkins ClusterIP 10.102.123.200 <none> 8080/TCP,50000/TCP 11m
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress.networking.k8s.io/jenkins nginx devops.jenkins.com 192.168.16.200 80 11m
查看jenkins初始化解锁secret
root@master:~/manifests/devops# kubectl -n devops logs -f jenkins-0
Jenkins initial setup is required. An admin user has been created and a password generated.
Please use the following password to proceed to installation:
c908458303794a10bdccf217b91501e4
This may also be found at: /var/jenkins_home/secrets/initialAdminPassword
*************************************************************
*************************************************************
*************************************************************
2023-09-20 09:56:38.853+0000 [id=28] INFO jenkins.InitReactorRunner$1#onAttained: Completed initialization
2023-09-20 09:56:39.078+0000 [id=22] INFO hudson.WebAppMain$3#run: Jenkins is fully up and running
访问测试
在客户端机器上配置hosts解析,将域名devops.jenkins.com绑定到192.168.16.200,然后在浏览器输入域名访问:
输入上一步拿到的secret,即可进入安装插件页面,然后点解“安装推荐插件”,开始安装插件:
待插件安装完成后,进入创建管理员用户的界面:
到这里我们就完成了Jenkins在k8s上的部署,下一篇我们开始介绍安装一些必要的插件后,演示Jenkins 基于 Kubernetes 的动态和静态节点的使用,欢迎持续关注!!
同时需要学习基于Ansible playbook离线部署kubernetes高可用集群的朋友,可关注微信公众号【IT运维图谱】添加后台管理员咨询获取获取。👇👇👇