Updated: Getting Started with Installing Kubernetes
Let’s get you started on your Kubernetes journey with installing Kubernetes and creating a cluster in virtual machines.
Kubernetes is a distributed system, you will be creating a cluster which will have a master node that is in charge of all operations in your cluster. In this walkthrough we’ll create three workers which will run our applications. This cluster topology is, by no means, production ready. If you’re looking for production cluster builds check out Kubernetes documentation. [Here][1] and [here][2]. The primary components that need high availability in a Kubernetes cluster are the [API Server][3] which controls the state of the cluster and the [etcd][4] database which persists the state of the cluster. You can learn more about Kubernetes cluster components [here][5]. If you want to dive into Kubernetes more check out my Pluralsight Courses [here][6]! Where I have a dedicated course on [Installation and Configuration][7].
Get your infrastructure sorted
I’m using 4 Ubuntu Virtual machines in VMware Fusion on my Mac. Each with 2vCPUs and 2GB of RAM running Ubuntu 16.04.5. Ubuntu 18 requires a slightly different install. Documented [here][8]. In there you will add the Docker repository, then install Docker from there. The instructions below get Docker from Ubuntu’s repository. You will also need to disable the swap on any system which you will run the kubelet, which in our case is all systems. To do so you need to turn swap off with sudo swapoff -a and edit /etc/fstab removing or commenting out the swap volume entry.
- c1-master1 – 172.16.94.15
- c1-node1 – DHCP
- c1-node2 – DHCP
- c1-node3 – DHCP
Ensure that each host has a unique name and that all nodes can have network reachability between each other. Take note of the IPs, because you will need to log into each node with SSH. If you need assistance getting your environment ready, check out my training on Pluralsight to get you started [here][9]! I have courses on installation, command line basics all the way up through advanced topics on networking and performance.
Overview of the cluster creation process
-
Install Kubernetes packages on all nodes
-
Add Kubernetes’ apt repositories
-
Install the required software packages for Kubernetes
-
Download deployment files for your Pod Network
-
Create a Kubernetes cluster on the Master
-
We’re going to use a utility called kubeadm to create our cluster with a basic configuration
-
Install a Pod Network
-
Join our three worker nodes to our cluster
Install Kubernetes Packages
Let’s start off with installing the required Kubernetes packages on to all of the nodes in our system. This is going to require logging into each server via SSH (or console), adding the Kubernetes apt repositories and installing the required packages. Perform the following tasks on ALL nodes in your cluster, the master and the three workers. If you add more nodes, you will need to install these packages on those nodes too. Add the gpg key for the Kubernetes apt repository to your local system
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
cat <<EOF | sudo tee /etc/apt/sources.list.d/kubernetes.list
deb https://apt.kubernetes.io/ kubernetes-xenial main
EOF
sudo apt-get update
sudo apt-get install -y docker.io kubelet kubeadm kubectl
sudo apt-mark hold docker.io kubelet kubeadm kubectl
sudo bash -c 'cat > /etc/docker/daemon.json <<EOF { "exec-opts": ["native.cgroupdriver=systemd"], "log-driver": "json-file", "log-opts": { "max-size": "100m" }, "storage-driver": "overlay2" } EOF'
sudo systemctl daemon-reload sudo systemctl restart docker
- kubelet – On each node in the cluster, this is in charge of starting and stopping pods in response to the state defined on the API Server on the master
- kubeadm – Primary command line utility for creating your cluster
- kubectl – Primary command line utility for working with your cluster
- docker – Remember, that Kubernetes is a container orchestrator so we’ll need a container runtime to run your containers. We’re using Docker. You can use other container runtimes if required
Download the YAML files for your Pod Network
wget https://docs.projectcalico.org/master/manifests/calico.yaml
Creating a Kubernetes Cluster
sudo kubeadm init --pod-network-cidr=192.168.0.0/16
- Creates a certificate authority – Kubernetes uses certificates to secure communication between components, verify the identity of Nodes in the cluster and authenticate users.
- Creates kubeconfig files – On the Master, this will create configuration files for various Kubernetes cluster components
- Pulls Control Plane container images – the services implementing the cluster components are deployed into the cluster as containers. Very cool! You can, of course, run these as local system daemons on the hosts, but Kubernetes suggests keeping them inside containers
- Bootstraps the Control Plane Pods – starts up the pods and creates static manifests on the master start automatically when the master node starts up
- Taints the Master to just system pods – this means the master will run (schedule) only system Pods, not user Pods. This is ideal for production. In testing, you may want to untaint the master, you’ll really want to do this if you’re running a single node cluster. See this link for details on that.
- Generates a bootstrap token – used to join worker nodes to the cluster
- Starts any add-ons – the most common add-ons are the DNS pod and the master’s kube-proxy
[init] Using Kubernetes version: v1.16.1 [preflight] Running pre-flight checks [preflight] Pulling images required for setting up a Kubernetes cluster [preflight] This might take a minute or two, depending on the speed of your internet connection
…output omitted… Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at: /docs/concepts/cluster-administration/addons/
Then you can join any number of worker nodes by running the following on each as root: kubeadm join 172.16.94.20:6443 --token czpkcj.ncl6p005orlie95h \ --discovery-token-ca-cert-hash sha256:3e21bb225c0986330ba11dd37c51fcd6542928964832705e13b84354872270bd
The output from your cluster creation is very important, it’s going to give you the code needed to access your cluster, the code needed to create your Pod network and also the code needed to join worker nodes to your cluster (just go ahead and copy this into a text file right now). Let’s go through each of those together.
Configuring your cluster for access from the Master node as a non-privileged user
This will allow you to log into your system with a regular account and administer your cluster.
mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config
Create your Pod network
Now that your cluster is created, you can deploy the YAML files for your Pod network. You must do this prior to adding more nodes to your cluster and certainly before starting any Pods on those nodes. We are going to use kubectl apply -f calico.yaml to deploy the Pod network from the YAML manifest we downloaded earlier.
kubectl apply -f calico.yaml
configmap/calico-config created customresourcedefinition.apiextensions.k8s.io/felixconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamblocks.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/blockaffinities.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamhandles.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamconfigs.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/hostendpoints.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/clusterinformations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworksets.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networksets.crd.projectcalico.org created clusterrole.rbac.authorization.k8s.io/calico-kube-controllers created clusterrolebinding.rbac.authorization.k8s.io/calico-kube-controllers created clusterrole.rbac.authorization.k8s.io/calico-node created clusterrolebinding.rbac.authorization.k8s.io/calico-node created daemonset.apps/calico-node created serviceaccount/calico-node created deployment.apps/calico-kube-controllers created serviceaccount/calico-kube-controllers created
kubectl get pods --all-namespaces NAMESPACE NAME READY STATUS RESTARTS AGE kube-system calico-kube-controllers-7594bb948-4mgqd 1/1 Running 0 2m58s kube-system calico-node-qpcv7 1/1 Running 0 2m58s kube-system coredns-5644d7b6d9-2lxgt 1/1 Running 0 3m42s kube-system coredns-5644d7b6d9-g5tfc 1/1 Running 0 3m42s kube-system etcd-c2-master1 1/1 Running 0 2m50s kube-system kube-apiserver-c2-master1 1/1 Running 0 2m41s kube-system kube-controller-manager-c2-master1 1/1 Running 0 3m5s kube-system kube-proxy-d2c6s 1/1 Running 0 3m42s kube-system kube-scheduler-c2-master1 1/1 Running 0 2m44s
Joining worker nodes to your cluster
sudo kubeadm join 172.16.94.20:6443 \ > --token czpkcj.ncl6p005orlie95h \ > --discovery-token-ca-cert-hash sha256:3e21bb225c0986330ba11dd37c51fcd6542928964832705e13b84354872270bd [sudo] password for aen: [preflight] Running pre-flight checks [preflight] Reading configuration from the cluster... [preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml' [kubelet-start] Downloading configuration for the kubelet from the "kubelet-config-1.16" ConfigMap in the kube-system namespace [kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml" [kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env" [kubelet-start] Activating the kubelet service [kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...This node has joined the cluster:
- Certificate signing request was sent to apiserver and a response was received.
- The Kubelet was informed of the new secure connection details.
Run ‘kubectl get nodes’ on the control-plane to see this node join the cluster.
kubeadm token list
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
kubectl get nodes NAME STATUS ROLES AGE VERSION c1-master1 Ready master 11m v1.16.1 c1-node1 NotReady <none> 63s v1.16.1
c1-node2 NotReady <none> 57s v1.16.1
C1-node3 NotReady <none> 33s v1.16.1
kubectl get nodes NAME STATUS ROLES AGE VERSION c1-master1 Ready master 12m v1.16.1 c1-node1 Ready <none> 3m04s v1.16.1
c1-node2 Ready <none> 2m31s v1.16.1
C1-node3 Ready <none> 1m28s v1.16.1