K8s集群部署最新Jenkins 2.387.1
- 概述
- 环境准备
- 设置存储目录并启动NFS服务
- 安装 NFS 服务端
- 动态创建 NFS存储(动态存储)
- 部署jenkins服务
概述
Jenkins是一个开源软件项目,是基于Java开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件项目可以进行持续集成。在Devops时代Jenkins有着不可缺失地位,也体现了Jenkins的亮点,废话不多说,我们进入在k8s环境下安装最新的Jenkins。
环境准备
一般k8s的数据都会存放于远程存储服务器上来保证安全,采用的方式也有很多,如nfs,ceph等等多种,这里我们介绍nfs存储。nfs存储配置简单,但存是储量特别大,传输特别频繁的情况下难免会出现传输延迟,难以保证高并发时的数据完整性和高性能等问题,但是很多公司的基本要求还是可以满足的。
这里我们需要先创建一台虚拟机或者服务器作为NFS服务器,这里笔者已经提前创建好了网段和k8s环境一样,然后往k8s所有master节点和worker节点host加入nfs主机映射,在hosts文件加入如下内容:
#nfs主机的ip 后面挂在会用到name
10.211.55.6 storage
设置存储目录并启动NFS服务
我们先创建共享目录,比如这里需要创建/data/k8s 目录,需要提前创建,然后往/etc/exports文件加入对应的nfs共享配置,具体操作如下:
#创建nfs共享目录
mkdir -p /data/k8s
#修改权限
chmod 777 -R 777 /data
#往exports文件写入配置,然后保存
vi /etc/exports
/data/k8s 10.211.55.0/24(rw,no_root_squash,sync)
#配置生效
exportfs -r
#查看生效
exportfs#安装nfs服务
yum -y install nfs-utils
#启动rpcbind、nfs服务
systemctl restart rpcbind && systemctl enable rpcbind
systemctl restart nfs && systemctl enable nf
安装 NFS 服务端
我们在worker节点安装nfs服务,不需要启动,这里只是需要测试挂载,如果已经安装请忽略即可。
#所有worker节点安装客户端,不需要启动
yum -y install nfs-utils
# worker节点测试挂载storage=nfs服务地址
mount -t nfs storage:/data/k8s /mnt
# 卸载
umount /mnt
动态创建 NFS存储(动态存储)
mkdir my-nfs-client-provisioner && cd my-nfs-client-provisioner
#nfs rbac
cat > rbac.yaml << EOF
apiVersion: v1
kind: ServiceAccount
metadata:name: nfs-client-provisioner# replace with namespace where provisioner is deployednamespace: default
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:name: nfs-client-provisioner-runner
rules:- apiGroups: [""]resources: ["persistentvolumes"]verbs: ["get", "list", "watch", "create", "delete"]- apiGroups: [""]resources: ["persistentvolumeclaims"]verbs: ["get", "list", "watch", "update"]- apiGroups: ["storage.k8s.io"]resources: ["storageclasses"]verbs: ["get", "list", "watch"]- apiGroups: [""]resources: ["events"]verbs: ["create", "update", "patch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:name: run-nfs-client-provisioner
subjects:- kind: ServiceAccountname: nfs-client-provisioner# replace with namespace where provisioner is deployednamespace: default
roleRef:kind: ClusterRolename: nfs-client-provisioner-runnerapiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:name: leader-locking-nfs-client-provisioner# replace with namespace where provisioner is deployednamespace: default
rules:- apiGroups: [""]resources: ["endpoints"]verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:name: leader-locking-nfs-client-provisioner# replace with namespace where provisioner is deployednamespace: default
subjects:- kind: ServiceAccountname: nfs-client-provisioner# replace with namespace where provisioner is deployednamespace: default
roleRef:kind: Rolename: leader-locking-nfs-client-provisionerapiGroup: rbac.authorization.k8s.io
EOF# nfs deployment
cat > deployment.yaml << EOF
apiVersion: apps/v1
kind: Deployment
metadata:name: nfs-client-provisionerlabels:app: nfs-client-provisioner# replace with namespace where provisioner is deployednamespace: default
spec:replicas: 1strategy:type: Recreateselector:matchLabels:app: nfs-client-provisionertemplate:metadata:labels:app: nfs-client-provisionerspec:serviceAccountName: nfs-client-provisionercontainers:- name: nfs-client-provisionerimage: dyrnq/nfs-subdir-external-provisioner:v4.0.2volumeMounts:- name: nfs-client-rootmountPath: /persistentvolumesenv:- name: PROVISIONER_NAMEvalue: fuseim.pri/ifs- name: NFS_SERVERvalue: storage # 注意此处修改- name: NFS_PATHvalue: /data/k8s # 注意此处修改volumes:- name: nfs-client-rootnfs:server: storage # 注意此处修改path: /data/k8s # 注意此处修改
EOF# nfs class
cat > class.yaml << EOF
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:name: managed-nfs-storage
provisioner: fuseim.pri/ifs # or choose another name, must match deployment's env PROVISIONER_NAME'
parameters:archiveOnDelete: "false"
EOF
部署jenkins服务
mkdir jenkins & cd jenkins#jenkins rbac
cat > Jenkins-rbac.yaml << EOF
apiVersion: v1
kind: Namespace
metadata:name: jenkins
---
apiVersion: v1
kind: ServiceAccount
metadata:name: jenkinsnamespace: jenkins
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:annotations:rbac.authorization.kubernetes.io/autoupdate: "true"labels:kubernetes.io/bootstrapping: rbac-defaultsname: jenkins
rules:
- apiGroups:- '*'resources:- statefulsets- services- replicationcontrollers- replicasets- podtemplates- podsecuritypolicies- pods- pods/log- pods/exec- podpreset- poddisruptionbudget- persistentvolumes- persistentvolumeclaims- jobs- endpoints- deployments- deployments/scale- daemonsets- cronjobs- configmaps- namespaces- events- secretsverbs:- create- get- watch- delete- list- patch- update
- apiGroups:- ""resources:- nodesverbs:- get- list- watch- update
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:annotations:rbac.authorization.kubernetes.io/autoupdate: "true"labels:kubernetes.io/bootstrapping: rbac-defaultsname: jenkins
roleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: jenkins
subjects:
- apiGroup: rbac.authorization.k8s.iokind: Groupname: system:serviceaccounts:jenkins
EOF#jenkins deployment
cat > Jenkins-Deployment.yaml << EOF
apiVersion: apps/v1
kind: Deployment
metadata:name: jenkinsnamespace: jenkinslabels:app: jenkins
spec:replicas: 1selector:matchLabels:app: jenkinstemplate:metadata:labels:app: jenkinsspec:containers:- name: jenkinsimage: jenkins/jenkins:lts-jdk11ports:- containerPort: 8080name: webprotocol: TCP- containerPort: 50000name: agentprotocol: TCP#resources:#limits:#memory: 4Gi#cpu: "2000m"#requests:#memory: 4Gi#cpu: "2000m"env:- name: LIMITS_MEMORYvalueFrom:resourceFieldRef:resource: limits.memorydivisor: 1Mi- name: JAVA_OPTSvalue: -Dhudson.security.csrf.GlobalCrumbIssuerConfiguration.DISABLE_CSRF_PROTECTION=truevolumeMounts:- name: jenkins-homemountPath: /var/jenkins_homevolumes:- name: jenkins-homepersistentVolumeClaim:claimName: jenkins-home
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: jenkins-homenamespace: jenkins
spec:storageClassName: "jenkins-nfs-sc"accessModes: [ReadWriteOnce]resources:requests:storage: 20Gi
EOF#jenkins service
cat > Jenkins-Service.yaml << EOF
apiVersion: v1
kind: Service
metadata:name: jenkinsnamespace: jenkinslabels:app: jenkins
spec:selector:app: jenkinsports:- name: webport: 8080targetPort: web- name: agentport: 50000targetPort: agent
EOF#jenkins nfs
cat > jenkins-nfs-sc.yml << EOF
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:name: jenkins-nfs-sc
provisioner: fuseim.pri/ifs
parameters:archiveOnDelete: "false"
EOF#先部署jenkins nfs
kubectl apply -f jenkins-nfs-sc.yml
执行部署
kubectl apply -f Jenkins-rbac.yaml -f Jenkins-Deployment.yaml -f Jenkins-Service.yaml
查看jenkins初始化信息
kubectl get pods -n jenkins -l app=jenkinskubectl logs -f jenkins-xxxx-xxxx -n jenkins #初始化密钥就在日志里面
通过NodePort暴露端口
注意,也可以通过ingress通过域名方式暴露(推荐)
# kubectl edit svc jenkins -n jenkins# kubectl get svc -n jenkins
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
jenkins NodePort 10.100.241.123 <none> 8080:32767/TCP,50000:30750/TCP 9m38s
访问:http://10.211.55.3:30002/