准备环境和工具
- 一套K8s环境,这里我的演示环境是基于v1.18.16版本,关于如何部署可以参考我这篇文章https://blog.51cto.com/4073279/2671639
- 一台NFS服务器,并配置好访问权限我的本地测试环境的NFS地址是: 192.168.137.22 $ cat /etc/exports /ifs/kubernetes *(insecure,rw,sync,no_root_squash,fsid=0) $ chmod 777 -R /ifs/kubernetes/
- (非必选)镜像仓库,可以是自建的也可以是公共的仓库,如果是生产用最好是内部自建一套,推荐使用Harbor搭建
- Helm是采用v3.4.2 版本,放到master节点就可以了
- (非必选,如果你不想通过Ingress访问可以不用配置)部署Ingress部署文件下载连接: 链接:https://share.weiyun.com/IgtuI4xK 密码:tqm9uf
准备镜像
一共用到了两个镜像,一个是官方的Jenkins Master镜像jenkins/jenkins:lts-alpine,一个是基于官方的Slave镜像jenkins/jnlp-slave:latest再重新打包的Slave镜像。
Slave镜像Dockerfile
FROM jenkins/jnlp-slave:latest USER root #配置时区文件,容器启动之后能正确获取到东八区时区信息 RUN echo "/usr/share/zoneinfo/Asia/Shanghai" > /etc/timezone \ && echo "$LANG UTF-8" > /etc/locale.gen \ && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime ENTRYPOINT ["jenkins-slave"]配置Storageclass
这里我采用Helm来部署,一方面Helm部署非常方便,另一方面,我偷懒了。
1.1 准备NFS服务器并配置
$ yum -y install nfs-utils $ mkdir -p /ifs/kubernetes/ $ chmod 777 /ifs/kubernetes/ $ cat /etc/exports /ifs/kubernetes *(insecure,rw,sync,no_root_squash,fsid=0) $ systemctl enable nfs-server $ systemctl start nfs-server1.2 当前K8s集群的所有工作节点部署NFS套件
$ yum -y install nfs-utils $ showmount -e 192.168.137.22 #检查是否NFS部署配置是否正常 $ mount -t nfs 192.168.137.22:/ifs/kubernetes/ /mnt #检查是否能正常挂载 $ cd /mnt && touch abc.txt #检查是否能正常读写1.3 配置国内Chart仓库
- 微软仓库(http://mirror.azure.cn/kubernetes/charts/)这个仓库强烈推荐,基本上官网有的chart这里都有。
- 阿里云仓库(https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts )
- 官方仓库(https://hub.kubeapps.com/charts/incubator)官方chart仓库,国内有点不好使。
添加存储库:
helm repo add stable http://mirror.azure.cn/kubernetes/charts helm repo add aliyun https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts helm repo update查看配置的存储库:
helm repo list helm search repo stable一直在stable存储库中安装charts,你可以配置其他存储库。
删除存储库:
helm repo remove aliyun1.4 当前K8s集群部署NFS动态供给类(Helm部署)
$ helm install nfs-prov --set nfs.server=192.168.137.22 --set nfs.path=/ifs/kubernetes stable/nfs-client-provisioner #stable是仓库名称 $ kubectl get sc NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE nfs-client cluster.local/nfs-prov-nfs-client-provisioner Delete Immediate true 39m这里要注意,不是所有仓库都有nfs-client-provisioner chart包,我这里用的是 https://charts.helm.sh/stable 配置的名称为stable仓库
$ helm repo list NAME URL stable https://charts.helm.sh/stable1.5 测试是否生效
测试案例
$ cat test-pvc.yaml apiVersion: v1 kind: PersistentVolumeClaim metadata: namespace: default name: test-pvc spec: #使用NFS动态供给 storageClassName: nfs-client accessModes: - ReadWriteOnce resources: requests: storage: 10Gi执行完之后,效果如下图所示,pvc能自动绑定pv就说明部署成功了
部署Jenkins
部署配置文件
--- #PVC申请持久化存储资源,因为Jenkins的插件、项目信息要持久化保存 apiVersion: v1 kind: PersistentVolumeClaim metadata: namespace: jenkins name: jenkins-pvc spec: #使用NFS动态供给 storageClassName: nfs-client accessModes: - ReadWriteOnce resources: requests: storage: 10Gi --- #命名空间 apiVersion: v1 kind: Namespace metadata: name: jenkins #配置访问Jenkins所在集群的权限 --- apiVersion: v1 kind: ServiceAccount metadata: labels: k8s-app: jenkins name: jenkins-admin namespace: jenkins --- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata: name: jenkins-admin namespace: jenkins labels: k8s-app: jenkins roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: - kind: ServiceAccount name: jenkins-admin namespace: jenkins --- apiVersion: apps/v1 kind: Deployment metadata: name: jenkins namespace: jenkins labels: app: jenkins spec: replicas: 1 selector: matchLabels: app: jenkins template: metadata: labels: app: jenkins spec: volumes: - name: jenkins-pv-storage persistentVolumeClaim: claimName: jenkins-pvc serviceAccount: "jenkins-admin" containers: - name: jenkins image: jenkins/jenkins:lts-alpine imagePullPolicy: IfNotPresent volumeMounts: - name: jenkins-pv-storage mountPath: /var/jenkins_home ports: - containerPort: 8080 name: web - containerPort: 50000 name: agent --- kind: Service apiVersion: v1 metadata: labels: app: jenkins name: jenkins-svc namespace: jenkins spec: type: ClusterIP ports: - port: 8080 name: web protocol: TCP targetPort: 8080 - port: 50000 name: agent protocol: TCP targetPort: 50000 selector: app: jenkins --- --- apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: jenkins-ingress namespace: jenkins labels: app: jenkins spec: rules: - host: "jenkins.lxq.com" #这个域名记得要映射成你所在woker节点的IP,如果不用Ingress也可以,自行再配置下Service Type为了NodePort就可以了,并去掉这块配置 http: paths: - path: / backend: serviceName: jenkins-svc servicePort: 8080执行应用部署kubectl apply jenkins-deploy.yaml
当jenkins pods 处在running状态之后,就可以访问了
访问地址: http://jenkins.lxq.com/, 初步访问需要安装相关插件,按照默认的安装就可以了,插件安装完成所需时间受限于你所在的网络环境。
配置Jenkins访问Kubernetes
1 安装Kubernetes插件
登录 Jenkins Master 页面,点击 “系统管理” —> “管理插件” —> “可选插件” —> “Kubernetes plugin” 勾选安装
如果下载慢的话,可以将Jenkins的插件源改成国内地址,具体如何修改,请Google相关文档。
2 配置访问Kubernetes集群
登录 Jenkins Master 页面,点击 “系统管理” —> “系统配置” —> “Cloud”
新增一个K8s集群配置
连接测试成功之后,会提示如下信息
最后保存退出就可以了!
测试构建项目
新增一个Pipeline构建测试项目,注意要选流水线项目
在流水线部分新增任务定义
//定义参数 def label = "mypod-${UUID.randomUUID().toString()}" //代理定义 podTemplate(label: label, cloud: 'kubernetes', containers: [ containerTemplate(name: 'jnlp', ttyEnabled: true, image: "10.2.7.40/base/jenkins-slave:latest", alwaysPullImage:true), ]) { node(label) { container('jnlp') { stage('Jenkins 动态构建') { sh 'echo hello world!' } } } }说明: cloud: 'kubernetes' -- 连接的集群名称image: "10.2.7.40/base/jenkins-slave:latest" -- Jenkins Slave镜像名称container('jnlp') -- 生成的agent容器
如图,动态构建可以正常工作
关于Pipeline脚本更详细的解读,我会在后续再补充说明。