One place for hosting & domains


      Installing the Linode CCM on an Unmanaged Kubernetes Cluster – A Tutorial

      Updated by Linode Contributed by Linode

      What is the Linode CCM?

      The Linode Cloud Controller Manager (CCM) provides a way for Kubernetes clusters to access additional Linode services. Linode’s CCM provides access to Linode’s load balancing service, Linode NodeBalancers.

      NodeBalancers provide your Kubernetes cluster with a reliable way of exposing resources to the public internet. The Linode CCM handles the creation and deletion of the NodeBalancer, and, along with other Master Plane components, correctly identifies the resources, and their networking, that the NodeBalancer will route traffic to. Whenever a Kubernetes Service of the LoadBalancer type is created, your Kubernetes cluster will create a Linode NodeBalancer service with the help of the Linode CCM.


      This guide will show you how to manually install the Linode CCM on an unmanaged Kubernetes cluster. This guide exists to support special use cases. For example, if you would like to experiment with various elements of a Kubernetes control plane.

      If you would like to use Kubernetes for production scenarios and make use of Linode NodeBalancers to expose your cluster’s resources, it is recommended that you use the Linode Kubernetes Engine to deploy your cluster. An LKE cluster’s control plane has the Linode CCM preinstalled and does not require any of the steps included in this guide.

      Similarly, if you would like to deploy an unmanaged Kubernetes cluster on Linode, the best way to accomplish that is using Terraform and the Linode K8s module. The Linode K8s module will also include the Linode CCM preinstalled on the Kubernetes master’s control plane and does not require any of the steps included in this guide.

      If you have used the Linode Kubernetes Engine (LKE) or the Linode Terraform K8s module to deploy your cluster, you should instead refer to the Getting Started with Load Balancing on a Linode Kubernetes Engine (LKE) Cluster guide for steps on adding and configuring NodeBalancers on your Kubernetes cluster.

      In this Guide

      You will manually install the Linode CCM on your unmanaged Kubernetes cluster. This will include:

      Before You Begin

      1. Deploy a new unmanaged Kubernetes cluster. You can deploy an unmanaged Kubernetes cluster on Linode by following the Getting Started with Kubernetes: Use kubeadm to Deploy a Cluster on Linode


        It is recommended that you install the Linode CCM on a new Kubernetes cluster, as there are a number of issues that prevent the CCM from running on Nodes that are in the “Ready” state.

      2. Ensure you have kubectl installed on your local computer and you can access your Kubernetes cluster with it.

      3. Install Git on your local computer.

      4. Generate a Linode APIv4 token.

      Running the Linode Cloud Controller Manager

      Update Your Cluster Configuration

      In order to run the Linode Cloud Controller Manager:

      • You must start kubelet with the --cloud-provider=external flag.
      • kube-apiserver and kube-controller-manager must NOT supply the --cloud-provider flag.

      These configurations will change the behavior of your cluster and how it interacts with its Nodes. For more details, visit the upstream Cloud Controller documentation.

      Install the Linode CCM

      The Linode CCM’s GitHub repository provides a helper script that creates a Kubernetes manifest file that you can use to install the CCM on your cluster. These steps should be run on your local computer and were tested on a macOS.


      You will need your Linode APIv4 token to complete the steps in this section.
      1. Clone the Linode CCM’s GitHub repository.

        git clone [email protected]:linode/linode-cloud-controller-manager.git
      2. Move into the CCM repository’s deploy directory.

        cd linode-cloud-controller-manager/deploy/
      3. Run the script. Ensure you replace $LINODE_API_TOKEN with your own Linode APIv4 token and us-east with the Linode region where your cluster resides. To view a list of regions, you can use the Linode CLI, or you can view the Regions API endpoint.

        ./ $LINODE_API_TOKEN us-east

        After running the script, you should have a new manifest file in the repo’s deploy directory, ccm-linode.yaml.

      4. Apply the manifest file to your cluster in order to install the Linode CCM and the required supporting resources.

        kubectl create -f ccm-linode.yaml


        You can create your own ccm-linode.yaml manifest file by editing the contents of the ccm-linode-template.yaml file and changing the values of the data.apiToken and data.region fields with your own desired values. This template file is located in the deploy directory of the Linode CCM repository.

      Updating the Linode CCM

      The easiest way to update the Linode CCM is to edit the DaemonSet that creates the Linode CCM Pod. To do so:

      1. Run the edit command to make changes to the CCM Daemonset.

        kubectl edit ds -n kube-system ccm-linode
      2. The CCM Daemonset manifest will appear in vim. Press i to enter insert mode. Navigate to spec.template.spec.image and change the field’s value to the desired version tag. For instance, if you had the following image:

        image: linode/linode-cloud-controller-manager:v0.2.2

        You could update the image to v0.2.3 by changing the image tag:

        image: linode/linode-cloud-controller-manager:v0.2.3

        For a complete list of CCM version tags, visit the CCM DockerHub page.


        The CCM Daemonset manifest may list latest as the image version tag. This may or may not be pointed at the latest version. To ensure the latest version, it is recommended to first check the CCM DockerHub page, then use the most recent release.
      3. Press escape to exit insert mode, then type :wq and press enter to save your changes. A new Pod will be created with the new image, and the old Pod will be deleted.

      Next Steps

      Now that you have the Linode CCM installed on your Kubernetes cluster, you can learn how to add and configure Linode NodeBalancers on your cluster.

      This guide is published under a CC BY-ND 4.0 license.

      Source link

      How to Provision an Unmanaged Kubernetes Cluster using Terraform

      Updated by Linode

      Contributed by

      Use Terraform, the popular orchestration tool by HaschiCorp, to deploy a Kubernetes cluster on Linode. Linode’s Terraform K8s module creates a Kubernetes cluster running on the CoreOS ContainerLinux operating system. After creating a Master and worker nodes, the module connects through SSH to these instances and installs kubeadm, kubectl, and other Kubernetes binaries to /opt/bin. It also handles initializing kubeadm, joining worker nodes to the master, and configuring kubectl. For the cluster’s container networking interface, Calico is installed. Finally, a kubectl admin config file is installed to the local environment, which you can use to connect to your cluster’s API server.

      Using Linode’s Terraform k8s module simplifies many of the steps involved in manually deploying a Kubernetes cluster with kubeadm. To learn more about kubeadm, see our Getting Started with Kubernetes: Use kubeadm to Deploy a Cluster on Linode guide.


      Currently, Linode’s Terraform k8s module only supports Kubernetes version 1.1.14. Development work to update this module is currently in progress. The latest updates can be found in the project’s corresponding GitHub repository.

      Before You Begin

      1. If you are new to Terraform, read through our A Beginner’s Guide to Terraform guide to familiarize yourself with key concepts.

      2. For an introduction to Kubernetes concepts, see our A Beginner’s Guide to Kubernetes series of guides.

      3. You need a personal access token for Linode’s v4 API to use with Terraform. Follow the Getting Started with the Linode API to get a token.


        When you create a personal access token ensure that you set Read/Write access because you are creating new Linode servers.

      4. Install Terraform on your computer.


      5. Install kubectl on your computer. You need kubectl to connect to and manage your Kubernetes cluster. Deployment of your cluster using this Terraform module fails if kubectl is not installed locally.

      In this Guide

      You will complete the following tasks:

      Configure your Local Environment

      Linode’s k8s Terraform module requires a local environment with a kubectl instance, a system-wide installation of Python, SSH keys, SSH keys configured with your SSH agent, and the sed and scp command line utilities. The module’s script verifies that all these requirements are installed on your local environment and generates a $var not found error if any of the tools are missing. This section shows how to install and configure kubectl, set up your SSH agent, and create an environment variable to store your API v4 token for easy reuse.

      If you receive an error that your system is missing Python, scp, or sed, use your operating system’s package manager to install the missing utilities.

      Create a Python Alias

      If your Python installation is invoked using python3, you can alias the command so that Terraform can execute scripts locally using Python as its interpreter.

      Using the text editor of your choice, edit your ~/.bashrc file to include the following alias:

      Then, reinitialize your ~/.bashrc file for the changes to take effect.

      source ~/.bashrc

      Install kubectl


      Install via Homebrew:

      brew install kubernetes-cli

      If you don’t have Homebrew installed, visit the Homebrew home page for instructions. Alternatively, you can manually install the binary; visit the Kubernetes documentation for instructions.


      1. Download the latest kubectl release:

        curl -LO$(curl -s
      2. Make the downloaded file executable:

        chmod +x ./kubectl
      3. Move the command into your PATH:

        sudo mv ./kubectl /usr/local/bin/kubectl



      Visit the Kubernetes documentation for a link to the most recent Windows release.

      SSH Agent

      By default, Terraform uses your operating system’s SSH agent to connect to a Linode instance through SSH. This section shows how to run the SSH agent and add your SSH keys to it.

      1. Run your SSH agent with the following command:

        eval `ssh-agent`

        The output is similar to:

        Agent pid 11308
      2. Add your SSH keys to the agent. For more information, see creating an authentication key-pair. This command adds keys from the default location, ~/.ssh/


        The output is similar to:

        Identity added: /home/example_user/.ssh/id_rsa (/home/example_user/.ssh/id_rsa)

      Create an API Token Environment Variable

      When you run terraform commands that need to communicate with Linode’s API v4, you need to issue the command along with your Linode token. In this section, you create an environment variable to store the token for easy reuse.

      1. Create the TF_VAR_linode_token environment variable to store your Linode API v4 token. Enter your token after the prompt.

        read -sp "Linode Token: " TF_VAR_linode_token # Enter your Linode Token (it will be hidden)
        export TF_VAR_linode_token


        To use your environment variable, add the -var flag. For example, when you run the terraform apply command, you would do so using:

        terraform apply -var linode_token=$LINODE_TOKEN

      Create your Terraform Configuration Files

      1. In the directory where you installed terraform, create a new directory to store your Kubernetes cluster’s configuration files.

        cd terraform
        mkdir k8s-cluster
      2. Using the text editor of your choice, create your cluster’s main configuration file named Add the following contents to the file.

        module "k8s" {
          source             = "linode/k8s/linode"
          version            = "0.1.2"
          linode_token       = var.linode_token
          server_type_master = var.server_type_master
          server_type_node   = var.server_type_node
          cluster_name       = var.cluster_name
          k8s_version        = var.k8s_version
          region             = var.region
          nodes              = var.nodes

        This file contains your cluster’s main configuration arguments. The only required configurations are source and linode_token. source calls Linode’s k8s module, while the linode_token will give you access to viewing, creating, and destroying Linode resources.

        The rest of the configurations are optional and have sane default values. In this example, however, you make use of Terraform’s input variables so that your configuration can be easily reused across different clusters, if desired.

      3. Create your input variables file, named, with the example content.

        variable "linode_token" {
          description = " Linode API token"
        variable "server_type_master" {
          default     = "g6-standard-2"
          description = " Linode API token"
        variable "cluster_name" {
          description = " Linode API token"
          default     = "example-cluster-1"
        variable "server_type_node" {
          description = " Linode API token"
          default     = "g6-standard-1"
        variable "k8s_version" {
          description = " Linode API token"
          default     = "v1.14.0"
        variable "region" {
          description = "Values: us-east, ap-west, etc."
          default     = "us-east"
        variable "nodes" {
          description = " Linode API token"
          default     = 3

        The example file creates input variables which are referenced in your main configuration file that you created in the previous step. The values for those variables are assigned in a separate file in the next step. You can override the k8s module’s default values and provide your own defaults, as done in the example file. For more details about input variables, see the Input Variables section in our A Beginner’s Guide to Terraform guide.

      4. Create your input variables values file to provide your main configuration file with values that differ from your input variable file’s defaults.

        server_type_master = "g6-standard-4"
        cluster_name = "example-cluster-2"

        In this example, your cluster’s master node uses a g6-standard-4 Linode plan, instead of the default g6-standard-2, and the cluster_name is set to example-cluster-2, instead of example-cluster-1.

      Deploy Your Kubernetes Cluster

      1. Change to ~/terraform/k8s-cluster/ directory and initialize Terraform to install the Linode K8s module.

        terraform init
      2. Verify that Terraform creates your cluster’s resources as you expect them to be created before making any actual changes to your infrastructure. To do this, run the plan command:

        terraform plan

        This command generates a report detailing what actions Terraform will take to set up your Kubernetes cluster.

      3. If you are satisfied with the generated report, run the apply command to create your Kubernetes cluster. This command prompts you to confirm that you want to proceed.

        terraform apply -var-file="terraform.tfvars"

        After a few minutes, when Terraform has finished applying your configuration, it displays a report of what actions were taken and your Kubernetes cluster is ready for you to connect to it.

      Connect to Your Kubernetes Cluster with kubectl

      After Terraform finishes deploying your Kubernetes cluster, your ~/terraform/k8s-cluster/ directory should have a file named default.conf. This file contains your kubeconfig file. You can use kubectl, along with this file, to gain access to your Kubernetes cluster.

      1. Save your kubeconfig file’s path to the $KUBECONFIG environment variable. In the example command, the kubeconfig file is located in the Terraform directory you created at the beginning of this guide. Ensure that you update the command with the location of your default.conf file

        export KUBECONFIG=~/terraform/k8s-cluster/default.conf


        It is common practice to store your kubeconfig files in ~/.kube directory. By default, kubectl searches for a kubeconfig file named config that is located in the ~/.kube directory. You can specify other kubeconfig files by setting the $KUBECONFIG environment variable, as done in the step above.

      2. View your cluster’s nodes using kubectl.

        kubectl get nodes


        If your kubectl commands are not returning the resources and information you expect, then your client may be assigned to the wrong cluster context. Visit our Troubleshooting Kubernetes guide to learn how to switch cluster contexts.

        You are now ready to manage your cluster using kubectl. For more information about using kubectl, see Kubernetes’ Overview of kubectl guide.

      Persist the Kubeconfig Context

      If you open a new terminal window, it does not have access to the context that you specified using the previous instructions. This context information can be made persistent between new terminals by setting the KUBECONFIG environment variable in your shell’s configuration file.


      These instructions are for the Bash terminal. They are similar for other terminals that you may use:

      1. Navigate to the $HOME/.kube directory:

        cd $HOME/.kube
      2. Create a directory called configs within $HOME/.kube. You can use this directory to store your kubeconfig files.

        mkdir configs
      3. Copy your default.conf file to the $HOME/.kube/configs directory.

        cp ~/terraform/k8s-cluster/default.conf $HOME/.kube/configs/default.conf


        Optionally, you can give the copied file a different name to help distinguish it from other files in the configs directory.

      4. Open up your Bash profile (e.g. ~/.bashrc) in the text editor of your choice and add your configuration file to the $KUBECONFIG PATH variable.

        If an export KUBECONFIG line is already present in the file, append to the end of this line as follows; if it is not present, add this line to the end of your file:

        export KUBECONFIG=$KUBECONFIG:$HOME/.kube/config:$HOME/.kube/configs/default.conf
      5. Close your terminal window and open a new window to receive the changes to the $KUBECONFIG variable.

      6. Use the config get-contexts command for kubectl to view the available cluster contexts:

        kubectl config get-contexts

        You should see output similar to the following:

        CURRENT   NAME                                 CLUSTER             AUTHINFO           NAMESPACE
        *         [email protected]   example-cluster-1   kubernetes-admin
      7. If your context is not already selected, (denoted by an asterisk in the current column), switch to this context using the config use-context command. Supply the full name of the cluster (including the authorized user and the cluster):

        kubectl config use-context [email protected]

        You should see output similar to the following:

        Switched to context "[email protected]".
      8. You are now ready to interact with your cluster using kubectl. You can test the ability to interact with the cluster by retrieving a list of Pods. Use the get pods command with the -A flag to see all pods running across all namespaces:

        kubectl get pods -A

        You should see output like the following:

        NAMESPACE            NAME                                               READY   STATUS    RESTARTS   AGE
        kube-system          calico-node-5bkc6                                  2/2     Running   0          17m
        kube-system          calico-node-gp5ls                                  2/2     Running   0          17m
        kube-system          calico-node-grpnj                                  2/2     Running   0          17m
        kube-system          calico-node-qd85t                                  2/2     Running   0          17m
        kube-system          ccm-linode-mjgzz                                   1/1     Running   0          17m
        kube-system          coredns-fb8b8dccf-5tlbm                            1/1     Running   0          17m
        kube-system          coredns-fb8b8dccf-7tpgf                            1/1     Running   0          17m
        kube-system          csi-linode-controller-0                            3/3     Running   0          17m
        kube-system          csi-linode-node-gfd8m                              2/2     Running   0          17m
        kube-system          csi-linode-node-hrfnd                              2/2     Running   0          16m
        kube-system          csi-linode-node-q6fmd                              2/2     Running   0          17m
        kube-system          etcd-mytestcluster-master-1                        1/1     Running   0          16m
        kube-system          external-dns-7885f88564-tvpjf                      1/1     Running   0          17m
        kube-system          kube-apiserver-mytestcluster-master-1              1/1     Running   0          16m
        kube-system          kube-controller-manager-mytestcluster-master-1     1/1     Running   0          16m
        kube-system          kube-proxy-cs9tm                                   1/1     Running   0          17m
        kube-system          kube-proxy-qljn5                                   1/1     Running   0          17m
        kube-system          kube-proxy-sr5h8                                   1/1     Running   0          17m
        kube-system          kube-proxy-ww2tx                                   1/1     Running   0          17m
        kube-system          kube-scheduler-mytestcluster-master-1              1/1     Running   0          16m
        kube-system          kubernetes-dashboard-5f7b999d65-jk99z              1/1     Running   0          17m
        kube-system          metrics-server-58db9f9647-tz8f8                    1/1     Running   0          17m
        reboot-coordinator   container-linux-update-agent-6kgqm                 1/1     Running   0          16m
        reboot-coordinator   container-linux-update-agent-7nck5                 1/1     Running   0          17m
        reboot-coordinator   container-linux-update-agent-nhlxj                 1/1     Running   0          17m
        reboot-coordinator   container-linux-update-agent-vv8db                 1/1     Running   0          17m
        reboot-coordinator   container-linux-update-operator-5c9d67d4cf-78wbp   1/1     Running   0          17m

      More Information

      You may wish to consult the following resources for additional information on this topic. While these are provided in the hope that they will be useful, please note that we cannot vouch for the accuracy or timeliness of externally hosted materials.

      This guide is published under a CC BY-ND 4.0 license.

      Source link