Add Kubernetes Cluster

How to connect your Kubernetes cluster to the Codefresh dashboard

Codefresh offers its own Kubernetes dashboard that allows you to inspect the services and namespaces in your cluster. To activate this dashboard you need to connect your cluster to your Codefresh account first.

Start by going into your Account Configuration, by clicking on Account Settings on the left sidebar. On the first section called Integrations click the Configure button next to Kubernetes.

Codefresh integrations

Codefresh integrations

In the Kubernetes integration window, you will be able to add a cluster from known providers such as Google, Azure, Amazon etc. You can also add any generic Kubernetes cluster by manually entering your cluster settings.

Adding GKE Cluster

Adding a cluster in GKE can be done by clicking the Add cluster button under Google Cloud Provider and selecting the desired project and cluster.

If this is your first time you’ll be prompted to authenticate using your Google credentials, make sure you’re doing so with a user that have access to your GKE projects.

Make sure that your cluster has basic authentication enabled. You can change this setting after cluster creation by editing and changing the setting from the drop-down list.

Enabling GKE basic authentication

Enabling GKE basic authentication

If you are a new customer of Google Cloud, you are also eligible to receive a Codefresh offer to get up to $500 in Google credits. As soon at the GKE integration is complete within Codefresh, you will get an email with extra details on how to claim your credits.

Follow the link in the email to fill in an application for the free credits. Once Google approves the application (usually within 1-2 days) your credits will be available to your account. Make sure to check your spam folder for that email.

Adding AKS cluster

To add an Azure cluster, select Azure AKS from the drop-down menu. Click the Authenticate button and enter your Azure credentials. You will see a description of all permissions that Codefresh needs in order to access your cluster. Accept them and Codefresh will connect to Azure to get the cluster information.

If you experience difficulties at this point try logging into Azure first in your browser before clicking the authenticate button. Also make sure that you are using an organizational/company Azure account and not a personal one. We are currently working with Microsoft to improve this integration.

If everything is ready you will see a dialog that allows you to select your Azure subscription and the cluster name that you wish to use.

Selecting the Azure cluster

Selecting the Azure cluster

Codefresh will query the cluster and show its nodes. You are now ready to deploy to Azure kubernetes.

If you wish for any reason to revoke the granted access from the Azure side, visit https://account.activedirectory.windowsazure.com/r#/applications and remove “Codefresh” from the list.

Adding EKS Cluster

To add an Amazon EKS cluster, you must first create a service account and obtain a token used to manage the integration.

The official Amazon-provided guide on EKS can be found here.

In order to use your cluster locally with kubectl, you must first install the heptio-authenticator-aws binary. Your version of kubectl must also be 1.10+ for this to work.

Next, create a kubeconfig file, such as ~/.kube/eks, replacing <endpoint-url>, <base64-encoded-ca-cert>, and <cluster-name> with information on your EKS cluster obtained in the AWS console:

apiVersion: v1
clusters:
- cluster:
    server: <endpoint-url>
    certificate-authority-data: <base64-encoded-ca-cert>
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    user: aws
  name: aws
current-context: aws
kind: Config
preferences: {}
users:
- name: aws
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1alpha1
      command: heptio-authenticator-aws
      args:
        - "token"
        - "-i"
        - "<cluster-name>"

Then, in an environment that has access to your AWS account, run the following command to create an admin user service account and necessary role binding:

cat <<EOF | kubectl --kubeconfig="$HOME/.kube/eks" apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: admin-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: admin-user
  namespace: kube-system
EOF

Finally, use the following command to obtain the service account token:

kubectl --kubeconfig="$HOME/.kube/eks" -n="kube-system" get secret \
  $(kubectl --kubeconfig="$HOME/.kube/eks" -n="kube-system" get secret | \
    grep admin-user | awk '{print $1}') -o jsonpath="{.data.token}"

Once you have this token, follow the steps in the section below, using this token for item #4.

Adding any other cluster type (not dependent on any provider)

Go to your Account Configuration, by clicking on Account Settings on the left sidebar. On the first section called Integrations click the Configure button next to Kubernetes.

In order to add any other type of cluster, outside of GKE, use Custom Providers

Adding a custom cluster in Codefresh

Adding a custom K8s cluster in Codefresh

The integration between Codefresh and your Kubernetes cluster is API based and relies on a Kubernetes service account of your choosing that will be used to manage the integration.

The configurations you’ll be required to add are:

  1. Name - Any name of your choosing, that will represent your cluster context in Codefresh.
  1. Host - The full URL of the Kubernetes API endpoints including protocol and port
  1. Certificate - The Kubernetes service account certificate used for the integration with Codefresh (base64 encoded)
  1. Token - The Kubernetes service account token used for the integration with Codefresh (base64 encoded)

Adding a custom cluster in Codefresh - details

Adding a custom cluster in Codefresh - details

In the section below we’ll provide you with easy instructions how to get all your cluster configurations in order to add it to Codefresh.

Get cluster configuration manually

Codefresh accesses any custom cluster using a service account. You can define the privileges Codefresh has on your cluster using the standard authorization methods (i.e. RBAC) supported by your Kubernetes infrastructure.

You need a terminal with kubectl access on your cluster. You can even use the “cloud shell” of your cloud provider for this purpose.

The easy and insecure way

If you are evaluating Codefresh and want to connect your cluster as fast as possible with no issues follow these steps:

Note that this method is only suggested for non-production clusters, and quick demos. See the next section for the proper way to use Codefresh in production environments.

First make sure that you are giving commands to the appropriate cluster if you have more than one:

Choose cluster

kubectl config use-context <my-cluster-name>

Then give full admin privileges to the default account.

Make default account cluster administrator

kubectl create clusterrolebinding default-admin --clusterrole cluster-admin --serviceaccount=default:default

Finally run the following commands and copy-paste the result to each Codefresh field in the UI:

Host IP

export CURRENT_CONTEXT=$(kubectl config current-context) && export CURRENT_CLUSTER=$(kubectl config view -o go-template="{{\$curr_context := \"$CURRENT_CONTEXT\" }}{{range .contexts}}{{if eq .name \$curr_context}}{{.context.cluster}}{{end}}{{end}}") && echo $(kubectl config view -o go-template="{{\$cluster_context := \"$CURRENT_CLUSTER\"}}{{range .clusters}}{{if eq .name \$cluster_context}}{{.cluster.server}}{{end}}{{end}}")

Certificate

echo $(kubectl get secret -o go-template='{{index .data "ca.crt" }}' $(kubectl get sa default -o go-template="{{range .secrets}}{{.name}}{{end}}"))

Token

echo $(kubectl get secret -o go-template='{{index .data "token" }}' $(kubectl get sa default -o go-template="{{range .secrets}}{{.name}}{{end}}"))

Once the cluster been added successfully you can go to the Kubernetes tab to start working with the services of your cluster.

The proper/secure way

For production environments you should create a service account and/or role for Codefresh access. The minimum permissions Codefresh needs to work with the cluster are the following:

codefresh-role.yml

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: codefresh-role
rules:
  - apiGroups: [""]
    resources: ["*"]
    verbs: ["list", "watch", "get"] 

Note that these permissions will only allow Codefresh to read the cluster resources and populate the respective dashboards. You need to give more privileges for actual deployments.

Here is an example with role + service account + binding.

codefresh-role-sa-bind.yml

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: codefresh-role
rules:
  - apiGroups: [""]
    resources: ["*"]
    verbs: ["list", "watch", "get"] 
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: codefresh-user
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: codefresh-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: codefresh-role
subjects:
- kind: ServiceAccount
  name: codefresh-user
  namespace: kube-system

Select the appropriate cluster if you have more than one:

Choose cluster

kubectl config use-context <my-cluster-name>

Create the Codefresh user/role:

Apply Codefresh access rules

kubectl apply -f codefresh-role-sa-bind.yml

Finally run the following commands and copy-paste the result to each Codefresh field in the UI:

Host IP

export CURRENT_CONTEXT=$(kubectl config current-context) && export CURRENT_CLUSTER=$(kubectl config view -o go-template="{{\$curr_context := \"$CURRENT_CONTEXT\" }}{{range .contexts}}{{if eq .name \$curr_context}}{{.context.cluster}}{{end}}{{end}}") && echo $(kubectl config view -o go-template="{{\$cluster_context := \"$CURRENT_CLUSTER\"}}{{range .clusters}}{{if eq .name \$cluster_context}}{{.cluster.server}}{{end}}{{end}}")

Certificate

echo $(kubectl get secret -n kube-system -o go-template='{{index .data "ca.crt" }}' $(kubectl get sa codefresh-user -n kube-system -o go-template="{{range .secrets}}{{.name}}{{end}}"))

Token

echo $(kubectl get secret -n kube-system -o go-template='{{index .data "token" }}' $(kubectl get sa codefresh-user -n kube-system -o go-template="{{range .secrets}}{{.name}}{{end}}"))

Adding a Rancher cluster

Rancher clusters are currently supported as generic clusters. Rancher clusters have a specific authentication configuration (the details are here: https://rancher.com/kubernetes-authentication-in-rancher-and-rbac for Rancher 1.x and at https://rancher.com/blog/2018/2018-05-04-authentication-authorization-rancher2/ for Rancher 2.x).

Authentication using a token of a Kubernetes Service Account, which is usually used by Codefresh, doesn’t work with Rancher clusters. Also, Rancher doesn’t do proper TLS termination out-of-the-box for Kubernetes clusters hosted on it, so one needs to configure a load balancer for that purpose.

In summary, the following conditions should be met in order to add the cluster, hosted on Rancher to Codefresh:

For Rancher version 1.x

  1. The token should be taken from the kubeconfig provided by Rancher and it has to be encoded with base64 before putting it into Codefresh. Be careful with the ‘\n’ characters when encoding. The command for Linux is: echo <rancher_token> | tr -d '\n' | base64 | tr -d '\n'
  2. The CA certificate should be the CA of the Load Balancer standing in front of Rancher
  3. The hostname and port should be corresponding to your Load Balancer

Getting the Rancher token

Getting the Rancher token

For Rancher version 2.x

  1. Kubernetes HOST is in the kubeconfig provided by Rancher for the Kubernetes cluster based on the domain name of Rancher + the Kubernetes cluster endpoint exposed through Rancher in cluster -> server. Example: https://rancher.localhost/k8s/clusters/c-npft4
  2. The token should be taken from the kubeconfig provided by Rancher under user -> token section of YAML and it has to be encoded with base64 before putting it into Codefresh. Be careful with the ‘\n’ characters when encoding, do not wrap token in quotes when running echo command. The command for Linux is: echo <rancher_token> | tr -d '\n' | base64 | tr -d '\n' Example: kubeconfig-user-xtnt4:cppxv6db…
  3. The CA certificate should be the CA of the Load Balancer standing in front of Rancher base64 encoded openssl base64 -in cert -out b64. And then run this command on the file to remove any white space. cat b64 | tr -d '\040\011\012\015' > b64_cert then copy and paste this base64 encoded value into Codefresh UI Cert field.
  4. The hostname and port should be corresponding to your Load Balancer

Rancher 2.x cluster details

Rancher 2.x cluster details

Once you have all the information follow the instructions for adding a generic Kubernetes cluster in Codefresh as described in the previous section.

Troubleshooting cluster addition

After adding your cluster configurations and in case the test fails, click “Save” to get the error message back.

click-save.png

Error: Cannot list namespaces

Add Cluster Error

Failed to add cluster: namespaces is forbidden: User "system:serviceaccount:default:default" cannot list namespaces at the cluster scope

The service account used for the integration doesn’t have the minimal permissions required. To fix this add a service account that have the required permissions.

The easiest way to do this is to create a cluster binding role between the default service account and cluster-admin role:

Create cluster binding with admin permissions

kubectl create clusterrolebinding default-admin --clusterrole cluster-admin --serviceaccount=default:default

Kubernetes cluster - using an external reverse proxy (edge case)

In case you’re using an external reverse proxy to manage inbound traffic to your Kubernetes API, please read this article to make sure your certificate setup are managed correctly in order to add your cluster successfully to Codefresh.

Multiple CAs in certificate chain

Ideally your Kubernetes cluster will have a single certificate which is used directly on the API endpoint. Some organizations place clusters behind a load balancer or other proxy mechanism that uses a chain or certificates.

When that happens and you more than one CA in your certification chain, you need to provide Codefresh with a Certificate bundle (a file that containers the intermediate CAs as well).

You will know when this is the case as this error will appear when you try to connect your cluster:

{"status":400,"code":"1004","name":"BAD_REQUEST_ERROR","message":"Failed to add cluster: unable to get local issuer certificate","context":{}}

To get the whole certificate open the URL of your Kubernetes in Chrome or Firefox and export all individual certificates as files

A Certificate chain

A Certificate chain

The steps needed are:

  1. Connect all certificates (apart from the API/endpoint one) to a bundle: cat rootCA.crt intermediateCA.crt > ca_bundle_cert
  2. Run the following to check the validity of the certificate: openssl verify -verbose -CAfile ca_bundle_cert k8_server_cert
  3. If the check above passes fine, go on and run the following on your CA bundle file: base64 ca_bundle_cert | tr -d '\n'
  4. Copy the output string (be careful when copying) and check whether you have copied it correctly: openssl x509 -text -in <(echo <copied_string> | base64 -d) - you should see the contents of your CA bundle file
  5. Put the copied string into the Codefresh Kubernetes integration form and test the connection.

Please make sure the certs are in order Root -> Intermediate -> Server.