直接使用kubectl和yaml部署文件

所有 Jenkins Kubernetes 清单文件都托管在 GitHub仓库上

1、创建命令空间

kubectl create namespace devops-tools

2、创建service account

创建一个 'jenkins-01-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

'jenkins-01-serviceAccount.yaml' 创建了一个 'jenkins-admin' clusterRole、'jenkins-admin' ServiceAccount,并将 'clusterRole' 绑定到服务账户上。

'jenkins-admin' 集群角色拥有管理集群组件的所有权限。您还可以通过指定单个资源操作来限制访问。

kubectl apply -f jenkins-01-serviceAccount.yaml

3、创建PV卷

创建 'jenkins-02-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
kubectl create -f jenkins-02-volume.yaml

4、创建deployment

创建一个名为"jenkins-03-deployment.yaml"的 Deployment 文件,并复制以下部署清单。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: jenkins
  namespace: devops-tools
spec:
  replicas: 1
  selector:
    matchLabels:
      app: jenkins-server
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: jenkins-server
    spec:
      securityContext:
            # Note: fsGroup may be customized for a bit of better
            # filesystem security on the shared host
            fsGroup: 1000
            runAsUser: 1000
            ### runAsGroup: 1000
      serviceAccountName: jenkins-admin
      containers:
        - name: jenkins
          image: jenkins/jenkins:lts
          # OPTIONAL: check for new floating-tag LTS releases whenever the pod is restarted:
          imagePullPolicy: Always
          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 pod 设置 'securityContext' 以使其能够写入本地持久卷。

fsGroup 指定用于挂载文件系统访问的组 ID,而 runAsUserrunAsGroup 指定所有进程以何种账户 ID 运行(既对主机操作系统可见,也对容器客机操作系统环境可见)。没有 fsUser 的对应项。

有一个需要注意的地方是,Jenkins 容器在其 /etc/passwd/etc/group 文件中定义了 ID 1000,而例如 git 程序要求运行时用户标识符必须可解析。虽然通过创建一个派生容器(例如 FROM jenkins:lts 创建)来定义所需账户并根据站点偏好以账户运行是轻而易举的,但默认情况下操作起来不太方便。

kubectl apply -f jenkins-03-deployment.yaml
kubectl get deployments -n devops-tools

5、创建service

创建 'jenkins-04-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',这将使 Jenkins 在所有 kubernetes 节点的 IP 地址上的 32000 端口上公开。如果您已经设置了 ingress,可以创建一个 ingress 规则来访问 Jenkins。此外,如果您在 AWS、Google 或 Azure 云上运行集群,可以将 Jenkins 服务作为负载均衡器公开。

kubectl apply -f jenkins-04-service.yaml

查看初始化密码

kubectl exec -it "deployment.apps/jenkins" cat /var/jenkins_home/secrets/initialAdminPassword -n devops-tools

使用helm部署

添加helm仓库

helm repo add jenkinsci https://charts.jenkins.io
helm repo update
helm search repo jenkinsci
helm fetch jenkinsci/jenkins --untar --version 5.8.101

官方Github仓库

根据我们的需要编写value.yaml文件

获取admin用户密码

jsonpath="{.data.jenkins-admin-password}"
secret=$(kubectl get secret -n jenkins jenkins -o jsonpath=$jsonpath)
echo $(echo $secret | base64 --decode)

获取登录URL

jsonpath="{.spec.ports[0].nodePort}"
NODE_PORT=$(kubectl get -n jenkins -o jsonpath=$jsonpath services jenkins)
jsonpath="{.items[0].status.addresses[0].address}"
NODE_IP=$(kubectl get nodes -n jenkins -o jsonpath=$jsonpath)
echo http://$NODE_IP:$NODE_PORT/login

使用Operator部署

Jenkins Operator 是一个 Kubernetes 原生的 Operator,用于管理 Kubernetes 上的 Jenkins 操作。

它旨在通过不可变性和将声明式配置作为代码来构建,以自动化在 Kubernetes 上部署和运行 Jenkins 所需的许多手动任务。

Jenkins Operator 通过应用几个 yaml 文件或使用 Helm 就很容易安装。

有关在您的 Kubernetes 集群上安装 Jenkins Operator 以及在那里部署和配置 Jenkins 的说明,请参阅 Jenkins Operator 的官方文档

查看密码

sudo cat /var/lib/jenkins/secrets/initialAdminPassword 将在控制台打印密码