Summary
In this post, I will introduce how to create a single control-node Kubernetes cluster with version v1.15.x and enable an accessible dashboard. With this post, you can easily deploy a cluster from scratch for testing.
Details
Before we start, note that there are problems like single node failure and security, which makes the deployment not production-ready.
1. Prerequest
1). Operation Systems
The most common ones are
OS | Version |
---|---|
Ubuntu | 16.04+ |
Debian | 9 |
CentOS | 7 |
There will be many compatibility issues in some packages if you are using the old version of systems. I took a lot of effort and tried to solve the compatibility issues manually in Ubuntu 14.04 but failed. Please consider upgrading the system first if possible.
2). Required Ports
Control-plane node(s)
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 |
Worker node(s)
Protocol | Direction | Port Range | Purpose | Used By |
---|---|---|---|---|
TCP | Inbound | 10250 | Kubelet API | Self, Control plane |
TCP | Inbound | 30000-32767 | NodePort Services** | All |
It is very import to open these ports especially when you are using provided virtual machines like EC2, where typically the required ports are closed.
3). Runtime
Install docker.
# Uninstall old versions
sudo apt-get remove docker docker-engine docker-ce docker.io
sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo apt-key fingerprint 0EBFCD88
# pub rsa4096 2017-02-22 [SCEA]
# 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88
# uid [ unknown] Docker Release (CE deb) <docker@docker.com>
# sub rsa4096 2017-02-22 [S]
sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
docker --version
# Set up the Docker daemon
cat <<EOF | sudo tee /etc/docker/daemon.json
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2"
}
EOF
sudo mkdir -p /etc/systemd/system/docker.service.d
# Restart Docker
sudo systemctl daemon-reload
sudo systemctl restart docker
sudo systemctl enable docker
2. Install kubeadm, kubelet, and kubectl
You will install these packages on all of your machines:
kubeadm
: the command to bootstrap the cluster.kubelet
: the component that runs on all of the machines in your cluster and does things like starting pods and containers.kubectl
: the command line util to talk to your cluster.
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
3. Init Cluster and Add Network Add-on
Before you apply any other configurations, you should apply the network add-ons. Here we use Calico, which provides networking and network security solutions for containers in Kubernetes. Remember that your cluster will not work without network add-ons.
# swap off
root@ubuntu:/home/ubuntu# sudo swapoff -a
root@ubuntu:/home/ubuntu# sudo kubeadm init --pod-network-cidr=192.168.0.0/16
root@ubuntu:/home/ubuntu# kubectl apply -f https://docs.projectcalico.org/v3.8/manifests/calico.yaml
You will see the following outputs.
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:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
Then you can join any number of worker nodes by running the following on each node as root:
kubeadm join x.x.x.x:6443 --token xxx \
--discovery-token-ca-cert-hash sha256:xxx
Now you can log in to other machines and join in the clusters. To verify your cluster, on any node, run
sudo kubectl get nodes
If the node is not ready, check the problem, use
sudo kubectl describe node irp125a-v36g01
Note that the token will expire in 24 hours. You can create a new one on the master node by
kubeadm token create --print-join-command
You may also want to taint the master node so that you can deploy pods on the master node.
root@ubuntu:/home/ubuntu#~$ sudo kubectl taint nodes --all node-role.kubernetes.io/master-
node/xxx untainted
error: taint "node-role.kubernetes.io/master:" not found
4. Start Dashboard
We use the fastest set-up.
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v1.10.1/src/deploy/recommended/kubernetes-dashboard.yaml
However, for now, the dashboard is only available by the localhost. Apply the following snippets if you want to remote access.
# dashboard-adminuser.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
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
root@ubuntu: sudo kubectl apply -f dashboard-adminuser.yaml
Then you can get token by using
root@ubuntu: sudo kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep admin-user | awk '{print $1}')
Note that you may get many tokens, any of them is good to use.
After that, we should expose the dashboard. NodePort is a good choice.
root@ubuntu: sudo kubectl -n kube-system edit service kubernetes-dashboard
You will get the following output.
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
...
name: kubernetes-dashboard
namespace: kube-system
resourceVersion: "343478"
selfLink: /api/v1/namespaces/kube-system/services/kubernetes-dashboard-head
uid: 8e48f478-993d-11e7-87e0-901b0e532516
spec:
clusterIP: 10.100.124.90
externalTrafficPolicy: Cluster
ports:
- port: 443
protocol: TCP
targetPort: 8443
nodePort: 30001 # specify your desired port
selector:
k8s-app: kubernetes-dashboard
sessionAffinity: None
type: NodePort # change this line
status:
loadBalancer: {}
Verify the dashboard by
root@ubuntu:~$ sudo kubectl -n kube-system get service kubernetes-dashboard
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes-dashboard NodePort x.x.x.x <none> 443:30001/TCP 7m58s
443:30001/TCP
means it is exposed to external networks.
Open your browser and type https://x.x.x.x:30001
, where x.x.x.x
is the public IP of any node.
Remember it is https
and use the token you get from dashboard-adminuser
.