在 Kubernetes 集群上托管 Jenkins 有利于基于 Kubernetes 的部署和基于动态容器的可扩展 Jenkins 代理。
在本指南中,我解释了在Kubernetes 集群上设置 Jenkins 的分步过程。
为了在 Kubernetes 上设置Jenkins集群,我们将执行以下操作。
注意:本教程不使用本地持久卷,因为这是一个通用指南。要为 Jenkins 数据使用持久卷,您需要创建相关云或本地数据中心的卷并对其进行配置。
本博客中使用的所有 Jenkins Kubernetes 清单文件都托管在 Github 上。如果您在从博客复制清单时遇到问题,请克隆存储库。
git clone https://github.com/scriptcamp/kubernetes-jenkins
使用 Github 文件作为参考,并按照下一节中的步骤进行操作
这是我们将要做什么的高级视图。
让我们开始在 Kubernetes 上部署 Jenkins。
第 1 步:为 Jenkins 创建一个命名空间。最好将所有devops 工具分类为与其他应用程序分开的命名空间。
kubectl create namespace devops-tools
第 2 步:创建一个serviceAccount.yaml
文件并复制以下管理员服务帐户清单。
- ---
- apiVersion: rbac.authorization.k8s.io/v1
- kind: ClusterRole
- metadata:
- name: jenkins-admin
- rules:
- - apiGroups: [""]
- resources: ["*"]
- verbs: ["*"]
-
- ---
- apiVersion: v1
- kind: ServiceAccount
- metadata:
- name: jenkins-admin
- namespace: devops-tools
-
- ---
- apiVersion: rbac.authorization.k8s.io/v1
- kind: ClusterRoleBinding
- metadata:
- name: jenkins-admin
- roleRef:
- apiGroup: rbac.authorization.k8s.io
- kind: ClusterRole
- name: jenkins-admin
- subjects:
- - kind: ServiceAccount
- name: jenkins-admin
- namespace: devops-tools
serviceAccount.yaml
创建一个jenkins-admin
clusterRole、jenkins-admin
ServiceAccount并将其绑定clusterRole
到服务帐户。
集群角色拥有管理集群组件的jenkins-admin
所有权限。您还可以通过指定单个资源操作来限制访问。
现在使用 kubectl 创建服务帐户。
kubectl apply -f serviceAccount.yaml
第 3 步:创建volume.yaml
并复制以下持久卷清单。
- kind: StorageClass
- apiVersion: storage.k8s.io/v1
- metadata:
- name: local-storage
- provisioner: kubernetes.io/no-provisioner
- volumeBindingMode: WaitForFirstConsumer
-
- ---
- apiVersion: v1
- kind: PersistentVolume
- metadata:
- name: jenkins-pv-volume
- labels:
- type: local
- spec:
- storageClassName: local-storage
- claimRef:
- name: jenkins-pv-claim
- namespace: devops-tools
- capacity:
- storage: 10Gi
- accessModes:
- - ReadWriteOnce
- local:
- path: /mnt
- nodeAffinity:
- required:
- nodeSelectorTerms:
- - matchExpressions:
- - key: kubernetes.io/hostname
- operator: In
- values:
- - worker-node01
-
- ---
- apiVersion: v1
- kind: PersistentVolumeClaim
- metadata:
- name: jenkins-pv-claim
- namespace: devops-tools
- spec:
- storageClassName: local-storage
- accessModes:
- - ReadWriteOnce
- resources:
- requests:
- storage: 3Gi
重要提示:替换
worker-node01
为任何一个集群工作程序节点主机名。
您可以使用 kubectl 获取工作程序节点主机名。
kubectl get nodes
对于卷,我使用local
存储类来进行演示。意思是,它在locationPersistentVolume
下的特定节点中创建一个卷。/mnt
由于local
存储类需要节点选择器,因此您需要正确指定工作节点名称,以便 Jenkins pod 在特定节点中进行调度。
如果 pod 被删除或重新启动,数据将保留在节点卷中。但是,如果节点被删除,您将丢失所有数据。
理想情况下,您应该使用具有云提供商或集群管理员提供的可用存储类的持久卷来持久化节点故障数据。
让我们使用 kubectl 创建卷
kubectl create -f volume.yaml
第 2 步:创建一个名为的部署文件deployment.yaml
并复制以下部署清单。
在这里,我们使用来自 Docker 中心的最新Jenkins LT S docker 镜像。
- apiVersion: apps/v1
- kind: Deployment
- metadata:
- name: jenkins
- namespace: devops-tools
- spec:
- replicas: 1
- selector:
- matchLabels:
- app: jenkins-server
- template:
- metadata:
- labels:
- app: jenkins-server
- spec:
- securityContext:
- fsGroup: 1000
- runAsUser: 1000
- serviceAccountName: jenkins-admin
- containers:
- - name: jenkins
- image: jenkins/jenkins:lts
- resources:
- limits:
- memory: "2Gi"
- cpu: "1000m"
- requests:
- memory: "500Mi"
- cpu: "500m"
- ports:
- - name: httpport
- containerPort: 8080
- - name: jnlpport
- containerPort: 50000
- livenessProbe:
- httpGet:
- path: "/login"
- port: 8080
- initialDelaySeconds: 90
- periodSeconds: 10
- timeoutSeconds: 5
- failureThreshold: 5
- readinessProbe:
- httpGet:
- path: "/login"
- port: 8080
- initialDelaySeconds: 60
- periodSeconds: 10
- timeoutSeconds: 5
- failureThreshold: 3
- volumeMounts:
- - name: jenkins-data
- mountPath: /var/jenkins_home
- volumes:
- - name: jenkins-data
- persistentVolumeClaim:
- claimName: jenkins-pv-claim
在这个 Jenkins Kubernetes 部署中,我们使用了以下内容。
securityContext
让 Jenkins pod 能够写入本地持久卷。/var/jenkins_home
注意:部署文件使用本地存储类持久卷来存储 Jenkins 数据。
如果你不想要本地存储持久化卷,可以将部署中的卷定义替换为主机目录,如下所示。
- volumes:
- - name: jenkins-data
- emptyDir: {}
使用 kubectl 创建部署。
kubectl apply -f deployment.yaml
检查部署状态。
kubectl get deployments -n devops-tools
现在,您可以使用以下命令获取部署详细信息。
kubectl describe deployments --namespace=devops-tools
此外,您可以从 kubernetes 仪表板获取详细信息,如下所示。
我们已经创建了一个部署。但是,外界无法访问它。为了从外部访问 Jenkins 部署,我们应该创建一个服务并将其映射到部署。
第 1 步:创建service.yaml
并复制以下服务清单。
- apiVersion: v1
- kind: Service
- metadata:
- name: jenkins-service
- namespace: devops-tools
- annotations:
- prometheus.io/scrape: 'true'
- prometheus.io/path: /
- prometheus.io/port: '8080'
- spec:
- selector:
- app: jenkins-server
- type: NodePort
- ports:
- - port: 8080
- targetPort: 8080
- nodePort: 32000
注意:在这里,我们使用的类型
NodePort
将在端口 32000 上的所有 kubernetes 节点 IP 上公开 Jenkins。如果您有入口设置,则可以创建入口规则来访问 Jenkins。此外,如果您在 AWS、Google 或 Azure 云上运行集群,您可以将 Jenkins 服务公开为负载均衡器。
使用 kubectl 创建 Jenkins 服务。
kubectl apply -f service.yaml
现在,如果您浏览到 port 上的任何一个节点 IP 32000
,您将能够访问 Jenkins 仪表板。
http://:32000
当您第一次访问仪表板时,Jenkins 会询问初始管理员密码。
您可以从 Kubernetes 仪表板或 CLI 的 pod 日志中获取它。您可以使用以下 CLI 命令获取 pod 详细信息。
kubectl get pods --namespace=devops-tools
使用 pod 名称,您可以获得如下所示的日志。将 pod 名称替换为您的 pod 名称。
kubectl logs jenkins-deployment-2539456353-j00w5 --namespace=jenkins
密码可以在日志末尾找到,如下所示。
或者,您可以运行 exec 命令直接从位置获取密码,如下所示。
kubectl exec -it jenkins-559d8cd85c-cfcgk cat /var/jenkins_home/secrets/initialAdminPassword -n devops-tools
输入密码后,您可以继续安装建议的插件并创建管理员用户。所有这些步骤都可以从 Jenkins 仪表板中一目了然。
当您在 Kubernetes 上托管 Jenkins 用于生产工作负载时,您需要考虑设置一个高可用的持久卷,以避免在 pod 或节点删除期间丢失数据。
在 Kubernetes 环境中随时可能发生 pod 或节点删除。它可能是修补活动或缩减活动。
希望这个分步指南可以帮助您学习和理解在 Kubernetes 集群上设置 Jenkins 服务器所涉及的组件。