部署jenkins
这里先直接上yaml文件:
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: jenkinspvc
namespace: devops
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 8Gi
storageClassName: managed-nfs-storage
---
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
app: jenkins
name: jenkins
namespace: devops
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: jenkins
namespace: devops
rules:
- apiGroups: [""]
resources: ["pods","configmaps","namespaces"]
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: RoleBinding
metadata:
name: jenkins
namespace: devops
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: jenkins
subjects:
- kind: ServiceAccount
name: jenkins
namespace: devops
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: jenkins
namespace: devops
spec:
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: jenkins
template:
metadata:
labels:
app: jenkins
spec:
terminationGracePeriodSeconds: 10
serviceAccountName: jenkins
containers:
- name: jenkins
image: jenkins/jenkins:lts
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 8080
protocol: TCP
- name: agent
containerPort: 50000
protocol: TCP
resources:
limits:
cpu: 1000m
memory: 1Gi
requests:
cpu: 500m
memory: 512Mi
livenessProbe:
httpGet:
path: /login
port: http
initialDelaySeconds: 120
periodSeconds: 10
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 5
readinessProbe:
httpGet:
path: /login
port: http
initialDelaySeconds: 120
periodSeconds: 5
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 5
volumeMounts:
- name: jenkins-home
mountPath: /var/jenkins_home
env:
- name: JAVA_OPTS
value: -XshowSettings:vm -Dhudson.slaves.NodeProvisioner.initialDelay=0 -Dhudson.slaves.NodeProvisioner.MARGIN=50 -Dhudson.slaves.NodeProvisioner.MARGIN0=0.85 -Duser.timezone=Asia/Shanghai
securityContext:
fsGroup: 1000
volumes:
- name: jenkins-home
persistentVolumeClaim:
claimName: jenkinspvc
---
apiVersion: v1
kind: Service
metadata:
name: jenkins
namespace: devops
labels:
app: jenkins
spec:
selector:
app: jenkins
type: NodePort
ports:
- name: http
port: 8080
targetPort: http
nodePort: 35080
- name: agent
port: 50000
使用上述yaml文件即可快速部署一个jenkins服务:
步骤上总体可以分为三个部分:
-
PVC持久化存储:
pvc存储这里底层使用的是NFS服务存储,具体使用这里就不详细说明了,使用方法可以参考 NFS Provisioner Github 地址。需要注意的是,NFS服务器上需要提前创建对应的共享文件夹并授权,否则会报无法创建文件,没有权限之类的错误。jenkins容器默认使用用户为jenins(uid 1000),而NFS只认uid,所以只需要NFS服务器上有uid为1000的用户即可,不一定必须是jenkins用户,当然保持一致最好,然后使用setfact命令精确授权:
setfacl -R -m u:1000:rwx /data/jenkins
-
serviceAccount的RBAC授权:
jenkins运行CI/CD任务,肯定会涉及到Pod,访问代理等操作,所以必须要对其进行授权,RBAC授权方式有两种,分别为名称空间级别的授权(这里使用的就是这种),集群级别的授权。具体如何授权根据需求即可。
-
deployment和service部署jenkins
8080为web访问端口,50000作为agent通信端口,Jenkins Service使用NodePort方式,端口为35080,部署完成后可以使用kubectl logs命令获取Jenkins的初始化密钥。
动态创建agent节点
首先需要在jenkins 上安装 kubernetes 插件。
安装成功后,点击 Manage Jenkins -> Configure System -> Cloud(最下面) -> Add a new cloud -> kubernetes,然后配置 Kubernetes 和 Jenkins 相关信息
需要填写的信息主要就是左侧的 Kubernetes 地址,命名空间和 Jenkins 地址,配置完点击一下右边的链接测试,如果出现 kubernetes 版本号就是正常的。我这里kubernetes 地址填写的是 DNS 解析地址,也可以直接填写 ip 地址。
接下来需要配置Pod模板,当有 job 需要被运行的时候会根据这里的 Pod 模板自行创建一个Pod去运行Pipeline。
点击 Pod Templates -> 添加 Pod 模板 -> Pod Templates details。
这里的标签列表非常重要,之后书写 Pipeline 选择运行的节点需要根据这个值来决定。
容器列表里填写运行的 agent 镜像信息,jenkins 会依据这些信息去下载 image 并运行,容器 Template 可以有多个,甚至可以做到每个 stage 运行在不同的容器中。
接下来就可以尝试写一个 Pipeline Demo 来测试一下了
podTemplate {
node("agent") {
stage('Run shell') {
sh 'echo hello world'
}
}
}
运行上面的 Pipeline ,查看控制台:
......
查看控制台的期间也可以看下 K8S 集群:
[root@center-188 devops]# kubectl get pod -n devops
NAME READY STATUS RESTARTS AGE
jenkins-7c76c6f9d6-tzx6b 1/1 Running 2 22h
k8s-jenkins-agent-v669t 2/2 Running 0 13s
可以看到一个名为k8s-jenkins-agent-v669t
自动被创建出来了,控制台还输出了其 Yaml 信息,最后 Agent Pod 就绪后成功输出了 hello world。
其他更多的使用用法可以参考 jenkinsci/kubernetes-plugin 的 github 项目。