jenkinsci / kubernetes-cli-plugin

Allows you to setup kubectl to access Kubernetes clusters from your Jenkins jobs.
https://plugins.jenkins.io/kubernetes-cli/
Apache License 2.0
89 stars 48 forks source link
kubernetes

Kubernetes CLI Plugin

Jenkins Plugin coveralls Jenkins Plugin installs

Allows you to configure kubectl to interact with Kubernetes clusters from within your jobs. Any tool built on top of kubectl can then be used from your pipelines to perform deployments, e.g. Shopify/krane or Helm.

Initially extracted and rewritten from the Kubernetes Plugin.

// Example when used in a pipeline
node {
  stage('Apply Kubernetes files') {
    withKubeConfig([credentialsId: 'user1', serverUrl: 'https://api.k8s.my-company.com']) {
      sh 'kubectl apply -f my-kubernetes-directory'
    }
  }
}

Prerequisites

How it works

The plugin generates a kubeconfig file based on the parameters that were provided in the build. This file is stored in a temporary file inside the build workspace and the exact path can be found in the KUBECONFIG environment variable. kubectl automatically picks up the path from this environment variable. Once the build is finished (or the pipeline block is exited), the temporary kubeconfig file is automatically removed.

Supported Credentials

The following types of credentials are supported and can be used to authenticate against Kubernetes clusters:

If the Jenkins Agent is running within a Pod (e.g. by using the Kubernetes Plugin), you can fallback to the Pod's ServiceAccount by not setting any credentials.

Quick Usage Quide

The parameters have a slightly different effect depending if a plain KubeConfig file is provided.

Parameters (without KubeConfig File)

Name Mandatory Description
credentialsId yes The Jenkins ID of the credentials.
serverUrl yes URL of the API server's.
caCertificate no Cluster Certificate Authority used to validate the API server's certificate. The validation is skipped if the parameter is not provided.
clusterName no Name of the generated Cluster configuration. (default: k8s)
namespace no Namespace for the Context.
contextName no Name of the generated Context configuration. (default: k8s)
restrictKubeConfigAccess no Only allow Jenkins user to read the KubeConfig file. (default: false)(doesn't work on Windows)

Parameters (with KubeConfig File)

The plugin writes the plain KubeConfig file and doesn't change any other field if only credentialsId is filled. The recommended way to use a single KubeConfig file with multiples clusters, users, and default namespaces is to configure a Context for each of them, and use the contextName parameter to switch between them (see Kubernetes documentation).

Name Mandatory Description
credentialsId yes The Jenkins ID of the plain KubeConfig file.
serverUrl no URL of the API server's. This will create a new cluster block and modify the current Context to use it.
caCertificate no Cluster Certificate Authority used to validate the API server's certificate if a serverUrl was provided. The validation is skipped if the parameter is not provided.
clusterName no Modifies the Cluster of the current Context. Also used for the generated cluster block if a serverUrl was provided.
namespace no Modifies the Namespace of the current Context.
contextName no Switch the current Context to this name. The Context must already exist in the KubeConfig file.
restrictKubeConfigAccess no Only allow Jenkins user to read the KubeConfig file. (default: false)(doesn't work on Windows)

Parameters (when running inside a Pod)

Name Mandatory Description
namespace no Namespace for the Context.
contextName no Name of the generated Context configuration. (default: k8s)
restrictKubeConfigAccess no Only allow Jenkins user to read the KubeConfig file. (default: false)(doesn't work on Windows)

Using Environment Variables

The parameters serverUrl, clusterName , namespace and contextName can contain environment variables and are interpolated before writing the configuration file to disk.

Using the Plugin in a Pipeline

The kubernetes-cli plugin provides the function withKubeConfig() for Jenkins Pipeline support. You can go to the Snippet Generator page under the Pipeline Syntax section in Jenkins, select withKubeConfig: Setup Kubernetes CLI from the Sample Step dropdown, and it will provide you configuration interface for the plugin. After filling the entries and click Generate Pipeline Script button, you will get the sample scripts which can be used in your Pipeline definition.

Example:

node {
  stage('List pods') {
    withKubeConfig([credentialsId: '<credential-id>',
                    caCertificate: '<ca-certificate>',
                    serverUrl: '<api-server-address>',
                    contextName: '<context-name>',
                    clusterName: '<cluster-name>',
                    namespace: '<namespace>'
                    ]) {
      sh 'kubectl get pods'
    }
  }
}
Usage with multiple Credentials

If you need to use more than one credential at the same time, you can use withKubeCredentials. It takes an array of the parameters as described for withKubeConfig, e.g.:

node {
  stage('Dump merged config') {
    withKubeCredentials([
        [credentialsId: '<credential-id-1>', serverUrl: '<api-server-address>'],
        [credentialsId: '<credential-id-2>', contextName: '<context-name>']
    ]) {
      sh 'kubectl config view'
    }
  }
}

The merging is done by kubectl itself, refer to its documentation for details. When providing more than one credential is provided no context will be set by default.

Usage when running inside a Pod

If you're running your pipelines within Kubernetes Pods, you could use those Pod's ServiceAccount instead of providing dedicated credentials. To do so, don't specify any credentialsId when calling withKubeConfig().

podTemplate(inheritFrom: 'default')
{
    node(POD_LABEL){
      stage('List Configmaps') {
        withKubeConfig([namespace: "this-other-namespace"]) {
          sh 'kubectl get configmap'
        }
  }
    }
}

Note: You may also want to call podTemplate() with a dedicated ServiceAccount that has the permissions required by your pipeline.

Using the Plugin from the Web Interface

  1. Within the Jenkins dashboard, select a Job and then select "Configure"
  2. Scroll down to the "Build Environment" section
  3. Select "Configure Kubernetes CLI (kubectl) with multiple credentials"
  4. In the "Credential" dropdown, select the credentials to authenticate on the cluster or the kubeconfig stored in Jenkins.
  5. Repeat 4 as necessary

webui

Generating Kubernetes Credentials

The following example describes how you could use the token of a ServiceAccount to access the Kubernetes cluster from Jenkins. The result depends of course on the permissions you have.

# Create a ServiceAccount named `jenkins-robot` in a given namespace.
$ kubectl -n <namespace> create serviceaccount jenkins-robot

# The next line gives `jenkins-robot` administator permissions for this namespace.
# * You can make it an admin over all namespaces by creating a `ClusterRoleBinding` instead of a `RoleBinding`.
# * You can also give it different permissions by binding it to a different `(Cluster)Role`.
$ kubectl -n <namespace> create rolebinding jenkins-robot-binding --clusterrole=cluster-admin --serviceaccount=<namespace>:jenkins-robot

# Get the name of the token that was automatically generated for the ServiceAccount `jenkins-robot`.
$ kubectl -n <namespace> get serviceaccount jenkins-robot -o go-template --template='{{range .secrets}}{{.name}}{{"\n"}}{{end}}'
jenkins-robot-token-d6d8z

# Retrieve the token and decode it using base64.
$ kubectl -n <namespace> get secrets jenkins-robot-token-d6d8z -o go-template --template '{{index .data "token"}}' | base64 -d
eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2V[...]

On Jenkins, navigate in the folder you want to add the token in, or go on the main page. Then click on the "Credentials" item in the left menu and find or create the "Domain" you want. Finally, paste your token into a Secret text credential. The ID is the credentialsId you need to use in the plugin configuration.

Development

Building and testing

To build the extension, run:

mvn clean package

and upload target/kubernetes-cli.hpi to your Jenkins installation.

To run the tests:

mvn clean test

Performing a Release

mvn release:prepare release:perform