November 05, 2018
This lab shows how to orchestrate an EC2 cluster of 3 instances (1 master, 2 workers) using kubeadm, how to deploy an app as Pod in the cluster and demonstrates the key feature of Kubernetes system - automatic desired state management by accidentally shutting down one worker node. The lab also demonstrates how to scale up/down the replicas of app using kubectl.
Protocol | Direction | Port Range | Purpose | Used By |
---|---|---|---|---|
TCP | Inbound | 6443* | Kubernetes API server | All |
TCP | Inbound | 2379-2380 | etcd server client API | kube-apiserver, etcd |
TCP | Inbound | 10250 | Kubelet API | Self, Control plane |
TCP | Inbound | 10251 | kube-scheduler | Self |
TCP | Inbound | 10252 | kube-controller-manager | Self |
Protocol | Direction | Port Range | Purpose | Used By |
---|---|---|---|---|
TCP | Inbound | 10250 | Kubelet API | Self, Control plane |
TCP | Inbound | 30000-32767 | NodePort Services** | All |
sudo apt update
sudo install a few prerequisite packages which let apt use packages over HTTPS
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable"
sudo apt update
apt-cache policy docker-ce
sudo apt install docker-ce
apt-get update && apt-get install -y apt-transport-https curl
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb https://apt.kubernetes.io/ kubernetes-xenial main
EOF
apt-get update
apt-get install -y kubelet kubeadm kubectl
apt-mark hold kubelet kubeadm kubectl
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
exclude=kube*
EOF
# Set SELinux in permissive mode (effectively disabling it)
setenforce 0
sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
systemctl enable kubelet && systemctl start kubelet
kubeadm init --pod-network-cidr=10.244.0.0/16
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
kubectl apply -f https://docs.projectcalico.org/v3.3/getting-started/kubernetes/installation/hosted/canal/rbac.yaml
kubectl apply -f https://docs.projectcalico.org/v3.3/getting-started/kubernetes/installation/hosted/canal/canal.yaml
kubeadm join --token <token> <master-ip>:<master-port> --discovery-token-ca-cert-hash sha256:<hash>
kubectl get nodes
NAME STATUS ROLES AGE VERSION
ip-172-31-83-103 Ready <none> 32m v1.12.2
ip-172-31-88-100 Ready master 35m v1.12.2
ip-172-31-92-89 Ready <none> 31m v1.12.2
kubectl run hello-world --replicas=2 --labels="run=load-balancer-example" \
--image=gcr.io/google-samples/node-hello:1.0 --port=8080
The preceding command creates a Deployment object and an associated ReplicaSet object. The ReplicaSet has two Pods, each of which runs the Hello World application.
kubectl get deployments hello-world
kubectl describe deployments hello-world
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
hello-world 2 2 2 2 72s
kubectl get replicasets
kubectl describe replicasets
NAME DESIRED CURRENT READY AGE
hello-world-78f6dc68cf 2 2 2 115s
kubectl expose deployment hello-world --type=NodePort --name=example-service
kubectl describe services example-service
kubectl get pods --selector="run=load-balancer-example" --output=wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE
hello-world-78f6dc68cf-9h4nl 1/1 Running 0 3m35s 10.244.1.2 ip-172-31-83-103 <none>
hello-world-78f6dc68cf-px29p 1/1 Running 0 3m35s 10.244.3.2 ip-172-31-92-89 <none>
curl http://172.31.83.103:31334
Hello Kubernetes!
Let’s try shutting down a worker node without notifying the master node in order to see the desired state management supplied by Kubernetes.
kubectl get pods --selector="run=load-balancer-example" --output=wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE
hello-world-78f6dc68cf-gzn7h 1/1 Unknown 0 8m51s 10.244.3.4 ip-172-31-92-89 <none>
hello-world-78f6dc68cf-txbwk 1/1 Running 0 8m51s 10.244.1.4 ip-172-31-83-103 <none>
hello-world-78f6dc68cf-xzq86 0/1 ContainerCreating 0 14s <none> ip-172-31-83-103 <none>
In a few minutes, the desired state of deployment (2 replicas) is recovered on the only 1 worker node that is still alive.
kubectl get pods --selector="run=load-balancer-example" --output=wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE
hello-world-78f6dc68cf-gzn7h 1/1 Unknown 0 19m 10.244.3.4 ip-172-31-92-89 <none>
hello-world-78f6dc68cf-txbwk 1/1 Running 0 19m 10.244.1.4 ip-172-31-83-103 <none>
hello-world-78f6dc68cf-xzq86 1/1 Running 0 11m 10.244.1.5 ip-172-31-83-103 <none>
kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
hello-world 2 2 2 2 25m
kubectl scale deployments/hello-world --replicas=4
kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE
hello-world-78f6dc68cf-7n5dm 1/1 Running 0 30s 10.244.1.3 ip-172-31-83-103 <none>
hello-world-78f6dc68cf-9h4nl 1/1 Running 0 27m 10.244.1.2 ip-172-31-83-103 <none>
hello-world-78f6dc68cf-k77s5 1/1 Running 0 30s 10.244.3.3 ip-172-31-92-89 <none>
hello-world-78f6dc68cf-px29p 1/1 Running 0 27m 10.244.3.2 ip-172-31-92-89 <none>
kubectl scale deployments/hello-world --replicas=2
kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE
hello-world-78f6dc68cf-7n5dm 1/1 Terminating 0 8m34s 10.244.1.3 ip-172-31-83-103 <none>
hello-world-78f6dc68cf-9h4nl 1/1 Running 0 35m 10.244.1.2 ip-172-31-83-103 <none>
hello-world-78f6dc68cf-k77s5 1/1 Terminating 0 8m34s 10.244.3.3 ip-172-31-92-89 <none>
hello-world-78f6dc68cf-px29p 1/1 Running 0 35m 10.244.3.2 ip-172-31-92-89 <none>
kubectl describe deployments/hello-world
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 37m deployment-controller Scaled up replica set hello-world-78f6dc68cf to 2
Normal ScalingReplicaSet 10m deployment-controller Scaled up replica set hello-world-78f6dc68cf to 4
Normal ScalingReplicaSet 2m44s deployment-controller Scaled down replica set hello-world-78f6dc68cf to 2
kubectl delete services example-service
kubectl delete deployment hello-world
Written by Warren who studies distributed systems at George Washington University. You might wanna follow him on Github