Installing jenkins in k8s and realizing dynamic generation of jenkins slave

Posted by passagewds on Wed, 04 Sep 2019 17:14:12 +0200

Install jenkins
1. Create a namespace
$ kubectl create namespace kube-ops
2. Create pvc for jenkins (you can also use storage classes)

apiVersion: v1
kind: PersistentVolume
metadata:
  name: opspv
spec:
  capacity:
    storage: 2Gi
  accessModes:
  - ReadWriteMany
  persistentVolumeReclaimPolicy: Delete
  nfs:
    server: 192.168.1.244
    path: /data/k8s
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: opspvc
  namespace: kube-ops
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 2Gi

3. rbac permissions required to create jenkins

apiVersion: v1
kind: ServiceAccount
metadata:
  name: jenkins2
  namespace: kube-ops
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: jenkins2
rules:
  - apiGroups: ["extensions", "apps"]
    resources: ["deployments"]
    verbs: ["create", "delete", "get", "list", "watch", "patch", "update"]
  - apiGroups: [""]
    resources: ["services"]
    verbs: ["create", "delete", "get", "list", "watch", "patch", "update"]
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["create","delete","get","list","patch","update","watch"]
  - apiGroups: [""]
    resources: ["pods/exec"]
    verbs: ["create","delete","get","list","patch","update","watch"]
  - apiGroups: [""]
    resources: ["pods/log"]
    verbs: ["get","list","watch"]
  - apiGroups: [""]
    resources: ["secrets"]
    verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: jenkins2
  namespace: kube-ops
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: jenkins2
subjects:
  - kind: ServiceAccount
    name: jenkins2
    namespace: kube-ops

You can also bind existing cluster-admin cluster role permissions for a system for Service Accoun
4. Create jenkins pod
$ docker pull docker.io/jenkins/jenkins:lts
$ docker pull cnych/jenkins:jnlp6

---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: jenkins2
  namespace: kube-ops
spec:
  template:
    metadata:
      labels:
        app: jenkins2
    spec:
      terminationGracePeriodSeconds: 10
      serviceAccount: jenkins2
      containers:
      - name: jenkins
        image: docker.io/jenkins/jenkins:lts
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080
          name: web
          protocol: TCP
        - containerPort: 50000
          name: agent
          protocol: TCP
        resources:
          limits:
            cpu: 1000m
            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: jenkinshome
          subPath: jenkins2
          mountPath: /var/jenkins_home
        env:
        - name: LIMITS_MEMORY
          valueFrom:
            resourceFieldRef:
              resource: limits.memory
              divisor: 1Mi
        - name: JAVA_OPTS
          value: -Xmx$(LIMITS_MEMORY)m -XshowSettings:vm -Dhudson.slaves.NodeProvision
er.initialDelay=0 -Dhudson.slaves.NodeProvisioner.MARGIN=50 -Dhudson.slaves.NodeProvisioner.MARGIN0=0.85 -Duser.timezone=Asia/Shanghai      securityContext:
        fsGroup: 1000
      volumes:
      - name: jenkinshome
        persistentVolumeClaim:
          claimName: opspvc
---
apiVersion: v1
kind: Service
metadata:
  name: jenkins2
  namespace: kube-ops
  labels:
    app: jenkins2
spec:
  selector:
    app: jenkins2
  type: NodePort
  ports:
  - name: web
    port: 8080
    targetPort: web
    nodePort: 30003
  - name: agent
    port: 50000
    targetPort: agent

$ kubectl apply -f jenkins2.yaml
$ kubectl get pod -n kube-ops
Jenkins 2-76644 dbc9b-llcsp 0/1 Running 0# does not start properly
$ kubectl describe pod jenkins2-76644dbc9b-llcsp -n kube-ops
$ kubectl logs -f jenkins2-76644dbc9b-llcsp -n kube-ops
5. Modify the permissions of the jenkins persistent directory on the nfs server and recreate the jenkins pod
Chown-R 1000/data/k8s/jenkins2 # at 192.168.1.244
$ kubectl delete -f jenkins2.yaml
$ kubectl apply -f jenkins2.yaml
$ kubectl get pod -n kube-ops
jenkins2-76644dbc9b-llcsp 1/1 Running 0
Why 1000?
The Dockerfile file for the above image defines user=jenkins group=jenkins uid=1000 gid=1000
The address of the Dockerfile file:
https://github.com/jenkinsci/docker/blob/master/Dockerfile
ARG user=jenkins
ARG group=jenkins
ARG uid=1000
ARG gid=1000
ARG http_port=8080
ARG agent_port=50000
ARG JENKINS_HOME=/var/jenkins_home
$ kubectl get svc -n kube-ops
jenkins2 NodePort 10.105.121.176 <none> 8080:30003/TCP,50000:30936/TCP
http://192.168.1.243:30003
The initial password is on the nfs server
$ cat /data/k8s/jenkins/secrets/initialAdminPassword

Create kubernetes cloud on jenkins
enkins Master and Jenkins Slave run in Pod form on Node of Kubernetes Cluster. Master runs on one of the nodes and stores its configuration data on a Volume. Slave runs on each node, and it is not always running. It will be created dynamically and automatically according to requirements. delete
When Jenkins Master receives a Build request, it dynamically creates a Jenkins Slave running in Pod and registers it with Master based on the configured Label. After running Job, the Slave will be cancelled and the Pod will be automatically deleted and restored to its original state.
1. Installing plug-ins
Install the kubernetes plugin, click Manage Jenkins - > Manage Plugins - > Available - > Kubernetes plugin
2. Increase the kubernetes cloud
Click Manage Jenkins - > Configure System - > (drag to the bottom) Add a new cloud - > Select Kubernetes, then fill in the configuration information of Kubernetes and Jenkins - - Connection Test
name: kubernetes
Kubernetes address: https://kubernetes.default.svc.cluster.local
Kubernetes namespace: kube-ops
Jenkins address: http://jenkins2.kube-ops.svc.cluster.local:8080 (jenkins2 is svc))
3. Adding pod template
Add a pod template -- Kubernetes Pod Template
Name: jnlp
Namespace: kube-ops
Tag list: dongyali-jnlp
4. Adding Container Template
Add Container - Container Template
Name: jnlp
Docker Mirror: cnych/jenkins:jnlp6 (Jenkins version under 2.176.x Mirror name removed 6)
Working directory: / home/jenkins/agent
Running commands: empty
Command parameters: empty
5. Add two volumes
Add Volume - Host Path Volume
Host path: / var/run/docker.sock
Mount path: / var/run/docker.sock
Host path: / root/.kube
Mount path: / root/.kube
6. Service Account may need to be configured
$ kubectl get sa -n kube-ops
jenkins2 1 14h
Click on the Advanced Service Account below the Add Volume - jenkins2
7. Using shell to test Kubernetes to dynamically generate jenkins slave
New Task - Name - Freestyle
Universal - Check the running node of the restricted project - Label expression: dongyali-jnlp
Build -- Execute the shell -- Enter the following content -- Save the immediate build

echo "test Kubernetes Dynamic Generation jenkins slave"
echo "==============docker in docker==========="
docker info
echo "=============kubectl============="
kubectl get pods

To observe the changes of Pod in Kubernetes cluster:
$ kubectl get pod -n kube-ops
jenkins2-76644dbc9b-llcsp 1/1 Running 0 3h49m
jnlp-tl1km 1/1 Running 0 44s
When the task runs out, the slave pod of jnlp disappears automatically.
8. Using pipeline to test Kubernetes to dynamically generate jenkins slave
New Task - Name - Pipeline
Enter the following in the pipeline script - - Save the immediate build

node('dongyali-jnlp') {
    stage('Clone') {
      echo "1.Clone Stage"
    }
    stage('Test') {
      echo "2.Test Stage"
    }
    stage('Build') {
      echo "3.Build Stage"
    }
    stage('Deploy') {
      echo "4. Deploy Stage"
    }
}

Topics: jenkins Kubernetes Docker shell