Search code examples
kubernetesjenkinsjenkins-plugins

Configure a side car container for Jenkins slave created with jenkinsci kubernetes-plugin


I have this yaml file that configures my Jenkins slave container on k8s via the plugin:

clouds:
  - kubernetes:
      ...
      name: "kubernetes"
      templates:
      - name: jenkins-slave
        containers:
          - image: "..."
            name: "jnlp"
            resourceLimitCpu: "1000m"
            resourceLimitMemory: "4000Mi"
            ...

How can I configure another sidecar container? I want to add buildkit. Adding it like this doesn't work, the plugin just ignores this configMap configuration:

clouds:
  - kubernetes:
      ...
      name: "kubernetes"
      templates:
      - name: jenkins-slave
        containers:
        - image: "..."
          name: "jnlp"
          resourceLimitCpu: "1000m"
          resourceLimitMemory: "4000Mi"
          ...
        - image: "moby/buildkit"
          name: "buildkit"

I saw that in the docs I can configure something like additionalContainers but I can't understand how I can set it.


Solution

  • if you use CASC plugin to configure you agents

    this example can help you

    jenkins:
      clouds:
        - kubernetes:
            name: "advanced-k8s-config"
            serverUrl: "https://advanced-k8s-config:443"
            serverCertificate: "serverCertificate"
            skipTlsVerify: true
            credentialsId: "advanced-k8s-credentials"
            namespace: "default"
            jenkinsUrl: "http://jenkins/"
            jenkinsTunnel: "jenkinsTunnel"
            containerCapStr: 42
            maxRequestsPerHostStr: 64
            retentionTimeout: 5
            connectTimeout: 10
            readTimeout: 20
    
            templates:
              - name: "test"
                serviceAccount: "serviceAccount"
                instanceCap: 1234
                idleMinutes: 0
                label: "label"
                # Enable whether the POD Yaml is displayed in each build log or not, `true` by default.
                showRawYaml: true
                
                volumes:
                  - hostPathVolume:
                      mountPath: "mountPath"
                      hostPath: "hostPath"
    
                containers:
                  - name: "name"
                    image: "image"
                    privileged: true
                    alwaysPullImage: true
                    command: "command"
                    args: "args"
                    workingDir: "workingDir"
                    ttyEnabled: true
                    resourceRequestCpu: "resourceRequestCpu"
                    resourceRequestMemory: "resourceRequestMemory"
                    resourceLimitCpu: "resourceLimitCpu"
                    resourceLimitMemory: "resourceLimitMemory"
                imagePullSecrets:
                  - name: "imagePullSecrets"
    
                envVars:
                  - envVar:
                      key: "FOO"
                      value: "BAR"
    
              - name: "k8s-agent"
                namespace: "default"
                label: "linux-x86_64"
                nodeUsageMode: EXCLUSIVE
                containers:
                  - name: "jnlp"
                    image: "jenkins/inbound-agent:latest"
                    alwaysPullImage: true
                    workingDir: "/home/jenkins"
                    ttyEnabled: true
                    resourceRequestCpu: "500m"
                    resourceLimitCpu: "1000m"
                    resourceRequestMemory: "1Gi"
                    resourceLimitMemory: "2Gi"
                volumes:
                  - emptyDirVolume:
                      memory: false
                      mountPath: "/tmp"
                  # Mount the content of the ConfigMap `configmap-name` with the data `config`.
                  - configMapVolume:
                      configMapName: configmap-name
                      mountPath: /home/jenkins/.aws/config
                      subPath: config
                idleMinutes: "1"
                activeDeadlineSeconds: "120"
                slaveConnectTimeout: "1000"
    

    also you can check documentation here https://plugins.jenkins.io/kubernetes/#plugin-content-pod-template

    ps some names differs to what K8s has, plugin wraps everything

    and all agent should have "jnlp" container - it used by jenkins itself and has java client on it

    you can run any agent you want and switch container in pipeline documentation

    container('your-second-container-name') {
      sh 'hostname'
    }
    

    2 containers in template example:

    jenkins:
      clouds:
        - kubernetes:
            name: "advanced-k8s-config"
            serverUrl: "https://advanced-k8s-config:443"
            serverCertificate: "serverCertificate"
            skipTlsVerify: true
            credentialsId: "advanced-k8s-credentials"
            namespace: "default"
            jenkinsUrl: "http://jenkins/"
            jenkinsTunnel: "jenkinsTunnel"
            containerCapStr: 42
            maxRequestsPerHostStr: 64
            retentionTimeout: 5
            connectTimeout: 10
            readTimeout: 20
            templates:
              - name: "templatename"
                label: "label"
                showRawYaml: true
                containers:
                  - name: "name1"
                    command: "cat"
                    args: ''
                    alwaysPullImage: true
                    image: "anyrandomimage"
                    workingDir: '/home/jenkins/agent'
                    ttyEnabled: true
                  - name: "name2"
                    command: "cat"
                    args: ''
                    alwaysPullImage: true
                    image: "anyrandomimage2"
                    workingDir: '/home/jenkins/agent'
                    ttyEnabled: true
    

    pipeline example:

    pipeline {
      agent {
        kubernetes {
          cloud 'YOUR PREDEFINED CLOUD NAME FROM PLUGIN'
          defaultContainer 'jnlp'
          yaml """
    apiVersion: v1
    kind: Pod
    metadata:
    labels:
      app: myapp
    spec:
      serviceAccountName: k8s-agent
      containers:
        - name: maven
          image: maven:latest
          command:
          - cat
          tty: true
        - name: docker
          image: docker:latest
          command:
          - cat
          tty: true
          volumeMounts:
            - mountPath: /var/run/docker.sock
              name: docker-sock
      volumes:
        - name: docker-sock
          hostPath:
            path: /var/run/docker.sock
    """
    }
      }
      stages {
    
        stage ('build java') {
          steps {
            container('maven') {
              sh 'mvn clean install'
            }
          }
        }
        stage ('build docker image'){
          steps {
            container('docker') {
              sh 'docker build -t image:v1 .'
            }
          }
        }
      }
    }