1.在k8s-master节点执行命令安装nfs
yum -y install nfs-utils rpcbind
创建NFS共享文件夹
[root@k8s-master ~]# mkdir /jenkins_data
2.配置共享文件夹
[root@k8s-master ~]# cat /etc/exports
/jenkins_data *(rw,sync,no_root_squash)
使配置生效
[root@k8s-master ~]# exportfs -r
查看所有配置
[root@k8s-master ~]# exportfs -v
/jenkins_data <world>(sync,wdelay,hide,no_subtree_check,sec=sys,rw,no_root_squash,no_all_squash)
3 启动nfs
[root@k8s-master ~]# systemctl enable nfs-server
Created symlink from /etc/systemd/system/multi-user.target.wants/nfs-server.service to /usr/lib/systemd/system/nfs-server.service.
[root@k8s-master ~]# systemctl start nfs-server
[root@k8s-master ~]# systemctl enable rpcbind
[root@k8s-master ~]# systemctl restart rpcbind
4 其他节点安装nfs-utils
[root@k8s-node01 ~]# yum -y install nfs-utils
[root@k8s-node02 ~]# yum -y install nfs-utils
5、创建PVC卷
PVC是资源的申请,用来声明对存储空间、访问模式、存储类别需求信息。在创建PVC卷之前,需要创建NFS客户端、NFS 客户端sa授权和StoreClass存储类。
创建namespace
[root@k8s-master ~]# kubectl create ns jenkins
namespace/jenkins created
6 创建nfs 客户端sa授权
[root@k8s-master nfs]# cat nfs-storage-class-rabc.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: jenkins
---
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: ServiceAccount
name: nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: jenkins
roleRef:
kind: ClusterRole
name: nfs-client-provisioner-runner
apiGroup: 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 deployed
namespace: jenkins
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 deployed
namespace: jenkins
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: jenkins
roleRef:
kind: Role
name: leader-locking-nfs-client-provisioner
apiGroup: rbac.authorization.k8s.io
[root@k8s-master nfs]# kubectl apply -f nfs-storage-class-rabc.yaml
serviceaccount/nfs-client-provisioner created
clusterrole.rbac.authorization.k8s.io/nfs-client-provisioner-runner created
clusterrolebinding.rbac.authorization.k8s.io/run-nfs-client-provisioner created
role.rbac.authorization.k8s.io/leader-locking-nfs-client-provisioner created
rolebinding.rbac.authorization.k8s.io/leader-locking-nfs-client-provisioner created
7 创建nfs 客户端
[root@k8s-master nfs]# cat nfs-storage.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-storage
annotations:
storageclass.kubernetes.io/is-default-class: "true"
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner
parameters:
archiveOnDelete: "true"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nfs-client-provisioner
namespace: jenkins
labels:
app: nfs-client-provisioner
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: nfs-client-provisioner
template:
metadata:
labels:
app: nfs-client-provisioner
spec:
serviceAccountName: nfs-client-provisioner
containers:
- name: nfs-client-provisioner
image: registry.cn-hangzhou.aliyuncs.com/cm_ns01/nfs-subdir-external-provisioner:v4.0.2
imagePullPolicy: IfNotPresent
volumeMounts:
- name: nfs-client-root
mountPath: /persistentvolumes
env:
- name: PROVISIONER_NAME
value: k8s-sigs.io/nfs-subdir-external-provisioner # 此处供应者名字供storageclass调用
- name: NFS_SERVER
value: k8s-master # 填入NFS的地址
- name: NFS_PATH
value: /jenkins_data # 填入NFS挂载的目录
volumes:
- name: nfs-client-root
nfs:
server: k8s-master # 填入NFS的地址
path: /jenkins_data # 填入NFS挂载的目录
[root@k8s-master nfs]# kubectl apply -f nfs-storage.yaml
storageclass.storage.k8s.io/nfs-storage created
deployment.apps/nfs-client-provisioner created
8 创建PVC卷
[root@k8s-master nfs]# cat jenkins.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: jenkins-pvc
namespace: jenkins
spec:
storageClassName: nfs-storage
resources:
requests:
storage: 20Gi #设置 pvc 存储资源大小
accessModes:
- ReadWriteOnce
[root@k8s-master nfs]# kubectl apply -f jenkins-pvc.yaml
persistentvolumeclaim/jenkins-pvc created
9、创建Service和deployment
[root@k8s-master jenkins]# cat jenkins-deployment-service.yaml
kind: Deployment
apiVersion: apps/v1
metadata:
name: jenkins
namespace: jenkins
spec:
replicas: 1
selector:
matchLabels:
app: jenkins
template:
metadata:
labels:
app: jenkins
spec:
containers:
- name: jenkins
image: jenkins/jenkins:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
name: web
protocol: TCP
- containerPort: 50000
name: agent
protocol: TCP
resources:
limits:
cpu: 2000m
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-data
mountPath: /var/jenkins_home
volumes:
- name: jenkins-data
persistentVolumeClaim:
claimName: jenkins-pvc
readOnly: false
---
apiVersion: v1
kind: Service
metadata:
name: jenkins-svc
namespace: jenkins
labels:
app: jenkins
spec:
selector:
app: jenkins
type: NodePort
ports:
- name: web
port: 8080
targetPort: web
nodePort: 30667
- name: agent
port: 50000
targetPort: agent
如果50000端口没挂载上,需要修改kube-apiserver.yaml
[root@k8s-master jenkins]# kubectl create -f jenkins-deployment-service.yaml
service/jenkins-service created
vim /etc/kubernetes/manifests/kube-apiserver.yaml
- --service-node-port-range=3000-60000
修改完成后,重启kubelet
[root@k8s-master ~]# systemctl restart kubelet
[root@k8s-master jenkins]# kubectl get po,svc -n jenkins
NAME READY STATUS RESTARTS AGE
pod/jenkins-794bd5df69-kt2vn 1/1 Running 1 (12m ago) 22h
pod/nfs-client-provisioner-7878f6566b-5x24k 1/1 Running 1 (22h ago) 23h
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/jenkins-svc NodePort 10.109.242.224 <none> 8080:30667/TCP,50000:30135/TCP 22h