Jenkins slave with custom docker image is not connecting with master in minikube

4/8/2018

Summary: Jenkins in K8s minikkube works fine and scales well in case of default jnlp agent but stuck with "Waiting for agent to connect" in case of custom jnlp image.

Detailed description:

I'm running the local minikube with Jenkins setup.

Jenkins master dockerfile:

from jenkins/jenkins:alpine

# Distributed Builds plugins
RUN /usr/local/bin/install-plugins.sh ssh-slaves

# install Notifications and Publishing plugins
RUN /usr/local/bin/install-plugins.sh email-ext
RUN /usr/local/bin/install-plugins.sh mailer
RUN /usr/local/bin/install-plugins.sh slack

# Artifacts
RUN /usr/local/bin/install-plugins.sh htmlpublisher

# UI
RUN /usr/local/bin/install-plugins.sh greenballs
RUN /usr/local/bin/install-plugins.sh simple-theme-plugin

# Scaling
RUN /usr/local/bin/install-plugins.sh kubernetes

# install Maven
USER root
RUN apk update && \
    apk upgrade && \
    apk add maven
USER jenkins

Deployment:

 apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
      name: jenkins
    spec:
      replicas: 1
      template:
        metadata:
          labels:
            app: jenkins
        spec:
          containers:
            - name: jenkins
              image: ybushnev/my-jenkins-image:1.3
              env:
                - name: JAVA_OPTS
                  value: -Djenkins.install.runSetupWizard=false
              ports:
                - name: http-port
                  containerPort: 8080
                - name: jnlp-port
                  containerPort: 50000
              volumeMounts:
                - name: jenkins-home
                  mountPath: /var/jenkins_home
          volumes:
            - name: jenkins-home
              emptyDir: {}

Service:

apiVersion: v1
kind: Service
metadata:
  name: jenkins
spec:
  type: NodePort
  ports:
    - port: 8080
      name: "http"
      targetPort: 8080
    - port: 50000
      name: "slave"
      targetPort: 50000
  selector:
    app: jenkins

After deployment I have such services:

Yuris-MBP-2% kubectl get services       
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)                          AGE
jenkins      NodePort    10.108.30.10   <none>        8080:30267/TCP,50000:31588/TCP   1h
kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP                          1h

Kubernetes master running on:

Yuris-MBP-2%  kubectl cluster-info | grep master
Kubernetes master is running at https://192.168.99.100:8443

Based on configuration above I specify the cloud config in Jenkins:

enter image description here

And finally I put such configuration for slave pod template: enter image description here

As a result, via k8s logs I see such logs on the master:

Waiting for agent to connect (41/100): kubernetes-agent-tgskx
Waiting for agent to connect (42/100): kubernetes-agent-tgskx
Waiting for agent to connect (43/100): kubernetes-agent-tgskx
Waiting for agent to connect (44/100): kubernetes-agent-tgskx
Waiting for agent to connect (45/100): kubernetes-agent-tgskx

Jenkins container seems to be green. No logs in K8s but there are such events happened:

Successfully assigned kubernetes-agent-517tl to minikube
MountVolume.SetUp succeeded for volume "workspace-volume"
MountVolume.SetUp succeeded for volume "default-token-8sgh6"

IMPORTANT If I do not put 'jnlp' inside the container name (I guess this is the important as in another case it takes some default jnlp agent image) slave is spinning up and connecting to the master just fine but even if I have custom docker image inside the 'Docker image' field it doesn't take it as a reference as I can see that Jenkins slave doesn't have such tools/files which it suppose to have based in provided image. Last time I tried to use this image: "gcr.io/cloud-solutions-images/jenkins-k8s-slave" but for me it fails for any image in case I put 'jnlp' as container template name. I tried to play with many images with no luck... Will be very glad for any hint!

-- Yuri Bushnev
jenkins
jenkins-slave
kubernetes

2 Answers

4/10/2018

I think you should set credentials for your master jenkins to start new pods.

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: jenkins
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: jenkins
rules:
- 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: RoleBinding
metadata:
  name: jenkins
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: jenkins
subjects:
- kind: ServiceAccount
  name: jenkins

And then in your Deployment use the account:

spec:           
      serviceAccountName: jenkins

Take a look to my previous answer at https://stackoverflow.com/a/47874390/2718151

I hope this helps.

-- Nicola Ben
Source: StackOverflow

8/8/2018

Under the "container template", You need to change the name "jnlp" to something else.

Kubernetes plugin will run a sidecar container with the name jnlp for connecting to the master server. If you use the name jnlp for the main container, it will conflict.

-- Akhil KM
Source: StackOverflow