Kubernetes Deployment failed due to Context

1/14/2020

I have created context for local deployment.

root@jenkins-linux-vm:/usr/lib# kubectl config get-contexts
CURRENT   NAME                          CLUSTER      AUTHINFO           NAMESPACE
          K8sCluster-CC-pre-release     kubernetes   kubernetes-admin   K8sCluster-CC-pre-release
          PR                            kubernetes   kubernetes-admin   PR
*         kubernetes-admin@kubernetes   kubernetes   kubernetes-admin

When my jenkins is running build i am getting below error, even though i have already created context and its pointing as well (*)for the same.

+ kubectl '--kubeconfig=****' '--context=K8sCluster-CC-pre-release' apply -f ./environment/pre-release '-n=pre-release'
error: context "K8sCluster-CC-pre-release" does not exist
tage('deployment') {
        container('kubectl') {
            withCredentials([kubeconfigFile(credentialsId: 'KUBERNETES_CLUSTER_CONFIG', variable: 'KUBECONFIG')]) {
            def kubectl
            echo 'Deployment Start'
              if(gitBranch == "future-master-fix") {
                 kubectl = "kubectl --kubeconfig=${KUBECONFIG} --context=K8sCluster-CC-pre-release"
                echo 'deploy to PRERELEASE!'
                sh "${kubectl} apply -f ./environment/pre-release -n=pre-release"
                echo 'Deployment End'
              }   
            }
        }
      }
-- Gowthami Viswa
kubernetes

2 Answers

1/14/2020

You can user fabric8.io Kubernetes java client. https://github.com/fabric8io/kubernetes-client . Here you can connect to Kube API server and execute almost all kubectl command easiely with this client

Dependency https://mvnrepository.com/artifact/io.fabric8/kubernetes-client

Creating Deployment example

 public class DeploymentExamples {

      public static void main(String[] args) throws InterruptedException {
        Config config = new ConfigBuilder().withMasterUrl("https://mymaster.com").build();
        KubernetesClient client = new DefaultKubernetesClient(config);
        try {
          // Create a namespace for all our stuff
          Namespace ns = new NamespaceBuilder().withNewMetadata().withName("thisisatest").addToLabels("this", "rocks").endMetadata().build();
          log("Created namespace", client.namespaces().createOrReplace(ns));

            deployment = client.apps().deployments().inNamespace("thisisatest").create(deployment);
            log("Created deployment", deployment);

            System.err.println("Scaling up:" + deployment.getMetadata().getName());
            client.apps().deployments().inNamespace("thisisatest").withName("nginx").scale(2, true);
            log("Created replica sets:", client.apps().replicaSets().inNamespace("thisisatest").list().getItems());
            System.err.println("Deleting:" + deployment.getMetadata().getName());
            client.resource(deployment).delete();
          }
          log("Done.");

        }finally {
          client.namespaces().withName("thisisatest").delete();
          client.close();
        }
      }

Full code

-- UDIT JOSHI
Source: StackOverflow

1/17/2020

When you configured Jenkins you probably used configuration based on Kubeconfig as is more popular.

Based on Kubernetes CLI

The plugin generates a kubeconfig file based on the parameters that were provided in the build. This file is stored in a temporary folder on the Jenkins executor 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.

When you use kubectl config get-contexts you used your local config from ${HOME}/.kube/config.

If you will check kubectl config --help you will get:

  1. If the --kubeconfig flag is set, then only that file is loaded. The flag may only be set once and no merging takes place.
  2. If $KUBECONFIG environment variable is set, then it is used as a list of paths (normal path delimiting rules for your system). These paths are merged. When a value is modified, it is modified in the file that defines the stanza. When a value is created, it is created in the first file that exists. If no files in the chain exist, then it creates the last file in the list.
  3. Otherwise, ${HOME}/.kube/config is used and no merging takes place.

It means that if you are using Kubernetes locally you are using option 3.
In Jenkins you are using option 1, so each time you run kubectl with different config, which do not contain required context.

In this command: kubectl = "kubectl --kubeconfig=${KUBECONFIG} --context=K8sCluster-CC-pre-release" you are overwritting kubeconfig, so it cannot find this context.

Please remove --kubeconfig=${KUBECONFIG} from code and try again. It should work then.

-- PjoterS
Source: StackOverflow