1. Tổng quan
K8s là một hệ thống, gồm nhiều thành phần tương tác với nhau. Tuy không tới nỗi phức tạp như cài một hệ thống cloud IaaS như OpenStack, nhưng cũng không phải chỉ gõ 3, 5 cái là xong. Vậy là người ta đẻ ra hàng chục cách khác nhau để cài K8s, đang kể nhất có:
- Minikube để cài 1 cluster test chơi chơi trên máy của bạn
- Kubeadm đang trong giai đoạn phát triển, để cài trên hệ thống máy vật lý/máy ảo dùng Ubuntu 16.04 hay CentOS 7
- Kargo là phần mềm dựa trên Ansible để cài trên rất nhiều nơi bao gồm cả máy vật lý/máy ảo/AWS/GCE
- Dùng SaltStack để cài https://github.com/kubernetes/kubernetes/tree/master/cluster/saltbase/
- Cài bằng tay trên CoreOS Container Linux
- Kops để cài trên AWS (Amazon cloud)
- Và rất nhiều các giải pháp khác nữa xem tại đây
Dưới đây mình hướng dẫn các bạn cài bằng Kubeadm nhé. Với hướng dẫn này các bạn sẽ có 1 Kubernete Cluster 1 node thoải mái để làm lab.
2. Cài đăt containerd
– Đặt hostname
hostnamectl set-hostname k8s-standalone
– Update hệ thống
sudo apt update -y
sudo apt upgrade -y
– Reboot lại os
init 6
– Cài đặt các gói bổ sung.
sudo apt-get install ca-certificates curl gnupg lsb-release -y
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
– Update lại hệ thống
sudo apt-get update -y && sudo apt-get upgrade -y
– Cài đặt containerd
sudo apt-get install containerd.io -y
– Kiểm tra version
root@k8s-standalone:~# containerd -v
containerd containerd.io 1.6.8 9cd3357b7fd7218e4aec3eae239db1f68a5a6ec6
3. Cài đặt Kubernete
– Mình sử dụng phiên bản 1.23.8 nhé, các bạn có thể sử dụng các phiên bản khác tùy thích
curl -s https://packages.cloud.google.com/apt/dists/kubernetes-xenial/main/binary-amd64/Packages | grep Version | tail -5
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add - && \
echo 'deb http://apt.kubernetes.io/ kubernetes-xenial main' | sudo tee /etc/apt/sources.list.d/kubernetes.list && \
sudo apt-get update -y && sudo apt-get upgrade -y && \
sudo apt-get install -y kubelet=1.23.8-00 kubectl=1.23.8-00 kubeadm=1.23.8-00
– Kiểm tra version
root@k8s-standalone:~# kubectl version --client
Client Version: version.Info{Major:"1", Minor:"23", GitVersion:"v1.23.8", GitCommit:"a12b886b1da059e0190c54d09c5eab5219dd7acf", GitTreeState:"clean", BuildDate:"2022-06-16T05:57:43Z", GoVersion:"go1.17.11", Compiler:"gc", Platform:"linux/amd64"}
4. Chuẩn bị cấu hình
– Cấu hình bridge network
sudo tee /etc/sysctl.d/kubernetes.conf<<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF
echo "net.netfilter.nf_conntrack_max=1000000" >> /etc/sysctl.conf
sudo sysctl --system
– Cấu hình containerd network
sudo tee /etc/modules-load.d/containerd.conf <<EOF
overlay
br_netfilter
EOF
– Cập nhật các thay đổi
sudo modprobe overlay
sudo modprobe br_netfilter
sudo sysctl --system
– Tắt swap
sudo sed -i "/ swap / s/^\(.*\)$/#\1/g" /etc/fstab || sudo sed -i '/swap/d' /etc/fstab
sudo swapoff -a
– Tạo thư mục containerd và file config.toml với nội dung dưới
sudo mkdir -p /etc/containerd
sudo containerd config default > /etc/containerd/config.toml
– Khởi động containerd
sudo systemctl enable containerd
sudo systemctl restart containerd
– Pull images
sudo kubeadm config images pull
5. Khởi tạo cluster.
kubeadm init –control-plane-endpoint “<ip_node>:6443” –upload-certs –pod-network-cidr=<pod_subnet>
Với ip_node là ip của máy master khởi tạo ban đầu và pod_subnet là một dải ip bất kỳ để các pod liên lạc với nhau, ví dụ:
kubeadm init --control-plane-endpoint "192.168.13.238:6443" --upload-certs --pod-network-cidr="10.244.0.0/16"
Sau khi khởi tạo xong chúng ta nhận được thông báo như dưới. Ở nội dung này ta để ý tới các chỉ mục mà mình đã khoanh dấu.
– Ta thực hiện các lệnh theo yêu cầu như mục 1 để có thể sử dụng cluster
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Nếu không thực hiện yêu cầu ở mục 1 thì khi chúng ta thực hiện 1 lệnh bất kỳ của Kubernetes sẽ báo lỗi như dưới
root@k8s-standalone:~# kubectl get node -A
The connection to the server localhost:8080 was refused - did you specify the right host or port?
Và sau khi thực hiện config theo yêu cầu ta check lại kết quả ta có 1 master node có tên k8s-standalone, lý do status NotReady ta sẽ xử lý tiếp ở phần tiếp theo.
root@k8s-standalone:~# mkdir -p $HOME/.kube
root@k8s-standalone:~# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
root@k8s-standalone:~# sudo chown $(id -u):$(id -g) $HOME/.kube/config
root@k8s-standalone:~#
root@k8s-standalone:~# kubectl get node -A
NAME STATUS ROLES AGE VERSION
k8s-standalone NotReady control-plane,master 7m58s v1.23.8
– Để Join thêm master ta sử dụng lệnh (2) trên node master mới như yêu cầu ở trên , mình chỉ sử dụng 1 master nên mình không chạy lệnh này
kubeadm join 192.168.13.238:6443 --token k1ocwr.83ucrqnzaq55uiqw \
--discovery-token-ca-cert-hash sha256:5488ad3b0925c78ba91c4b968bcc87ba9571556f2d2421df0af64b5702369747 \
--control-plane --certificate-key 6d7d59e727472afd2444819eb1f5eb0d0649815387ec3b5927aebd4f4a242d1f
– Tương tự để join thêm worker thì sử dụng lệnh (3) trên node worker mới, mình lấy master node để làm worker luôn nên mình không chạy lệnhh này
kubeadm join 192.168.13.238:6443 --token k1ocwr.83ucrqnzaq55uiqw \
--discovery-token-ca-cert-hash sha256:5488ad3b0925c78ba91c4b968bcc87ba9571556f2d2421df0af64b5702369747
– Vì lý do là cụm 1 node nên ta dụng lệnh sau để cho phép pod được triển khai lên master
kubectl taint node <master_node_name> node-role.kubernetes.io/master-
– Ví dụ
root@k8s-standalone:~# kubectl taint node k8s-standalone node-role.kubernetes.io/master-
node/k8s-standalone untainted
– Sau này nếu cụm chúng ta có nhiều worker, sử dụng lệnh dưới để ngừng cho phép pod triển khai lên master
kubectl taint nodes <master_node_name> node-role.kubernetes.io/master=false:NoSchedule
6. Triển khai Calico network lên cụm
– Như lúc nãy mình có nói, khi triển khai xong thì node k8s-standalone có trạng thái NotReady và thẩm chí là các port liên quan đến coredns cũng bị pending, vậy để node này có thể Ready chúng ta cần triển khai network cho cụm, mình sẽ sử dụng Calico để triển khai network cho cụm.
root@k8s-standalone:~# kubectl get node,pods -A
NAME STATUS ROLES AGE VERSION
node/k8s-standalone NotReady control-plane,master 14m v1.23.8
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system pod/coredns-64897985d-2vvw5 0/1 Pending 0 14m
kube-system pod/coredns-64897985d-cd274 0/1 Pending 0 14m
kube-system pod/etcd-k8s-standalone 1/1 Running 0 14m
kube-system pod/kube-apiserver-k8s-standalone 1/1 Running 0 14m
kube-system pod/kube-controller-manager-k8s-standalone 1/1 Running 0 14m
kube-system pod/kube-proxy-zhx9f 1/1 Running 0 14m
kube-system pod/kube-scheduler-k8s-standalone 1/1 Running 0 14m
– Tải file calico.yaml về máy
wget https://docs.projectcalico.org/v3.21/manifests/calico.yaml
– Mở file vừa tải về lên và sửa đổi nội dung như sau
+ Tìm đến # – name: CALICO_IPV4POOL_CIDR và bỏ comment cho nó
sudo sed -i 's/# - name: CALICO_IPV4POOL_CIDR/- name: CALICO_IPV4POOL_CIDR/' calico.yaml
+ Thay đổi pod network cidr
sudo sed -i 's|# value:.*| value: "10.244.0.0/16"|g' calico.yaml
Tùy thời điểm thì file calico.yaml có thể đổi format, nếu file đổi format có thể command sed sẽ chạy không thành công, bạn có thể vào tự thay đổi như mình đã khoanh đỏ ở dưới nhé
+ Triển khai file vừa chỉnh sửa
root@k8s-standalone:~# kubectl apply -f calico.yaml
configmap/calico-config created
customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/blockaffinities.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/caliconodestatuses.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/clusterinformations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/felixconfigurations.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/hostendpoints.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamblocks.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamconfigs.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamhandles.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipreservations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/kubecontrollersconfigurations.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
poddisruptionbudget.policy/calico-kube-controllers created
– Sau khi triển khai xong network ta có thể thấy các pod đang từ từ được khởi tạo, chờ trong giây lát chúng ta sẽ có 1 cluster k8s standalone để sử dụng.
root@k8s-standalone:~# kubectl get node,pods -A
NAME STATUS ROLES AGE VERSION
node/k8s-standalone NotReady control-plane,master 25m v1.23.8
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system pod/calico-kube-controllers-7f76d48f74-kb5lk 0/1 Pending 0 26s
kube-system pod/calico-node-nz4zd 0/1 Init:2/3 0 26s
kube-system pod/coredns-64897985d-2vvw5 0/1 Pending 0 24m
kube-system pod/coredns-64897985d-cd274 0/1 Pending 0 24m
kube-system pod/etcd-k8s-standalone 1/1 Running 0 24m
kube-system pod/kube-apiserver-k8s-standalone 1/1 Running 0 24m
kube-system pod/kube-controller-manager-k8s-standalone 1/1 Running 0 24m
kube-system pod/kube-proxy-zhx9f 1/1 Running 0 24m
kube-system pod/kube-scheduler-k8s-standalone 1/1 Running 0 24m
Sau vài phút chúng ta sẽ có 1 k8s standalone như dưới.
root@k8s-standalone:~# kubectl get node,pods -A
NAME STATUS ROLES AGE VERSION
node/k8s-standalone Ready control-plane,master 53m v1.23.8
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system pod/calico-kube-controllers-7f76d48f74-kb5lk 1/1 Running 0 28m
kube-system pod/calico-node-nz4zd 1/1 Running 0 28m
kube-system pod/coredns-64897985d-2vvw5 1/1 Running 0 52m
kube-system pod/coredns-64897985d-cd274 1/1 Running 0 52m
kube-system pod/etcd-k8s-standalone 1/1 Running 0 52m
kube-system pod/kube-apiserver-k8s-standalone 1/1 Running 0 52m
kube-system pod/kube-controller-manager-k8s-standalone 1/1 Running 0 52m
kube-system pod/kube-proxy-zhx9f 1/1 Running 0 52m
kube-system pod/kube-scheduler-k8s-standalone 1/1 Running 0 52m
Đến đây mình đã hướng dẫn cho các bạn triển khai 1 cụm Kubernete với 1 node để test ứng dụng. Chúc các bạn thành công.