Skip to content

antony@notes:~/kubernetes$ cat "Kubernetes-Cluster-build.md"

Kubernetes-Cluster-build

2022-09-05· kubernetes ·系統工程

Kubernetes-Cluster-build

:::warning

:::spoiler 目錄

[TOC]


:::

將 m1 主機安裝成 Kubernetes 的 Master

# 在 Windows 系統的 cmd 視窗, 執行以下命令
$ ssh bigred@<alp.m1 IP>

安裝 Kubernetes 要用的一些管理命令

$ sudo apk update; sudo apk add kubeadm kubelet kubectl --update-cache --repository http://dl-3.alpinelinux.org/alpine/edge/testing/ --allow-untrusted
  • kubeadm,建置 K8S 會用到的命令
  • kubelet,將 CRI-O 建立出來的 Container 包成 pod 的程式
  • kubectl,controls the Kubernetes cluster manager,kubectl-overview 官網介紹連結
  • apk add 命令補充
    • --repository <REPO>,指定其他套件下載網址
    • --update-cache, Alias for ‘–cache-max-age 1’
    • --allow-untrusted,安裝帶有不受信任簽名或沒有簽名的套件
  • 因為手工建立 K8S 的關係,所以可以用到最新的版本

建立 K8S Master

m1 的 IP

$ echo $IP
192.168.61.4

透過 kubeadm 來設定 Master 主機

$ sudo kubeadm init --service-cidr 10.98.0.0/24 --pod-network-cidr 10.244.0.0/16  --service-dns-domain=k8s.org --apiserver-advertise-address $IP
  • kubeadm init ,設定 Kubernetes control plane ( m1 主機 ),將它初始化
  • --service-cidr 10.98.0.0/24,K8S 對外提供服務的 IP 位址,給我們辦公室的同仁們,機房的其他應用系統,甚至 Internet 上面的使用者,來提供這樣的服務,我們設定的是10.98.0.0/24 ,所以代表我們 Kubernetes 做出來的服務最多可以有 254 個。
  • --pod-network-cidr 10.244.0.0/16,pod 的 IP 位址範圍,可以有 254 * 254 = 64516 個 pod。
  • 以上兩個設定其實只要是私有 IP 就 ok 。
  • --service-dns-domain=k8s.org,因為 K8S 內部有 Service Discovery ,所以要設定 Domain Name ,對外的應用系統連接網址使用此設定名稱,在外面做案子的話,就用公司的 Domain Name 來命名。
  • --apiserver-advertise-address $IP,將 m1 主機的 IP 位址 設定為 Kubernetes Master 的 API Server 的 IP
  • Kubernetes Service Discovery 介紹連結

Kubelet 設定為系統自動啟動

$ sudo rc-update add kubelet default
  • 為何 Kubelet,需設定為系統自動啟動 ? 因為它是一個 Daemon ,需要在背景一直 running 來等待 Scheduler 來找他。

檢查 pod 的 image

$ sudo podman images
REPOSITORY                                                TAG         IMAGE ID      CREATED        SIZE
k8s.gcr.io/kube-apiserver                                 v1.24.3     d521dd763e2e  3 weeks ago    131 MB
k8s.gcr.io/kube-proxy                                     v1.24.3     2ae1ba6417cb  3 weeks ago    112 MB
k8s.gcr.io/kube-controller-manager                        v1.24.3     586c112956df  3 weeks ago    121 MB
k8s.gcr.io/kube-scheduler                                 v1.24.3     3a5aa3a515f5  3 weeks ago    52.3 MB
docker.io/rancher/mirrored-flannelcni-flannel             v0.19.0     c4300d1c88c8  4 weeks ago    63.3 MB
docker.io/rancher/mirrored-flannelcni-flannel-cni-plugin  v1.1.0      fcecffc7ad4a  2 months ago   8.37 MB
k8s.gcr.io/etcd                                           3.5.3-0     aebe758cef4c  3 months ago   301 MB
docker.io/rancher/local-path-provisioner                  v0.0.22     e16d1e3a1066  4 months ago   35.3 MB
k8s.gcr.io/pause                                          3.7         221177c6082a  5 months ago   718 kB
k8s.gcr.io/coredns/coredns                                v1.8.6      a4ca41631cc7  10 months ago  47 MB
registry.k8s.io/pause                                     3.6         6270bb605e12  11 months ago  690 kB
  • docker.io/rancher/mirrored-flannelcni-flannel:v1.1.0
  • docker.io/rancher/mirrored-flannelcni-flannel-cni-plugin:v0.19.0
  • 以上兩片 image 是陳老師先幫我們準備好的

設定 K8S Master

將 bigred 設成 K8S 管理者

$ mkdir -p $HOME/.kube; sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config; sudo chown $(id -u):$(id -g) $HOME/.kube/config
  • 先在使用者家目錄下建立一個 .kube 的目錄
  • 然後拷貝 admin.conf 這個 K8S 管理者的設定檔到 使用者家目錄下 .kube 目錄裡面的 config 這個檔案裡面
  • 最後將 config 的權限設為 當前使用者的權限
  • cp -i ,覆蓋前會提示
  • id -u ,顯示當前使用者的 UID
  • id -g ,顯示當前使用者群組的 GID

設定 K8S Master 可以執行 Pod

$ kubectl taint node m1 node-role.kubernetes.io/control-plane:NoSchedule-
  • K8s 的每個 node 都會有標記 taint ,而 m1 這台 node 在 K8S 初始化的時候會被標記 NoSchedule 的 taint ,有了這個 taint 之後, pod 就不會建在 m1 的 node 上,這時候在規則裡面改成 NoSchedule- , 就能破格。

Kubernetes 1.24.4 版還要再執行以下命令

$ kubectl taint node m1 node-role.kubernetes.io/master:NoSchedule-

安裝 Flannel 網路套件

flannel 網路套件,動用的技術 : Static Route

$ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
  • 因建立 K8S 設定 POD 的 Subnet 為 10.244.0.0/16, 而 flannel 內定網路 ID 為 10.244.0.0/16, 所以不需修改 kube-flannel.yml

安裝好後,將 m1 主機重新開機

$ sudo reboot

檢視 Kubernetes 系統狀態

檢查 node 的狀態

$ kubectl get nodes
NAME   STATUS   ROLES           AGE   VERSION
m1     Ready    control-plane   74m   v1.24.3

檢查 kube-system 這個 Namespace 裡面 pod 的狀態

$ kubectl get pods -n kube-system
NAME                         READY   STATUS    RESTARTS   AGE
coredns-6d4b75cb6d-grkmp     1/1     Running   1          37m
coredns-6d4b75cb6d-xlgfd     1/1     Running   1          37m
etcd-m1                      1/1     Running   1          37m
kube-apiserver-m1            1/1     Running   1          37m
kube-controller-manager-m1   1/1     Running   1          37m
kube-proxy-ftk9d             1/1     Running   1          37m
kube-scheduler-m1            1/1     Running   1          37m

注意!這邊的 Namespace 與 linux 的 namespace 不同

  • -n , namespace ,K8S 系統的運作空間
  • coredns,供外部通訊所使用的 Domain Name Server ( 負責做 Service Discovery )
  • kube-apiserver-m1,負責接收使用者的命令
  • etcd-m1,紀錄 K8S 系統的 Metadata
  • kube-scheduler-m1,負責啟動 Pod
  • kube-controller-manager-m1,負責監控與維護 Pod
  • flannel + kube-proxy 可以讓 pod 在不同 nodes 之間網路能互通有無

看 m1 主機維運系統的 4 個 pod 的 Container 狀態

$ crictl ps -a

output :

CONTAINER           IMAGE                                                              CREATED             STATE               NAME                      ATTEMPT             POD ID              POD
45c3af598722d       a4ca41631cc7ac19ce1be3ebf0314ac5f47af7c711f17066006db82ee3b75b03   9 minutes ago       Running             coredns                   1                   1a9c8965ba001       coredns-6d4b75cb6d-xlgfd
54317fe6de819       a4ca41631cc7ac19ce1be3ebf0314ac5f47af7c711f17066006db82ee3b75b03   9 minutes ago       Running             coredns                   1                   6581b3ba9f2b8       coredns-6d4b75cb6d-grkmp
06f7e1a7dc5c4       252b2c3ee6c86b9cba63c9bddc2d1638d4152b5713009ff9397498014d06178e   10 minutes ago      Running             kube-flannel              1                   b0b014f1d4cb6       kube-flannel-ds-r5p9q
f32b9416f5600       2ae1ba6417cbcd0b381139277508ddbebd0cf055344b710f7ea16e4da954a302   10 minutes ago      Running             kube-proxy                1                   f5b632754d09e       kube-proxy-ftk9d
81fa3b96f83f4       252b2c3ee6c86b9cba63c9bddc2d1638d4152b5713009ff9397498014d06178e   10 minutes ago      Exited              install-cni               1                   b0b014f1d4cb6       kube-flannel-ds-r5p9q
38cdbe521c340       fcecffc7ad4af70c8b436d45688771e0562cbd20f55d98581ba22cf13aad360d   10 minutes ago      Exited              install-cni-plugin        1                   b0b014f1d4cb6       kube-flannel-ds-r5p9q
46ac2b6b44a73       586c112956dfc2de95aef392cbfcbfa2b579c332993079ed4d13108ff2409f2f   10 minutes ago      Running             kube-controller-manager   1                   1132c83fc98fc       kube-controller-manager-m1
adbf8a41e4cb8       d521dd763e2e345a72534dd1503df3f5a14645ccb3fb0c0dd672fdd6da8853db   10 minutes ago      Running             kube-apiserver            1                   e2caae9b8b044       kube-apiserver-m1
ee38c42a981d8       aebe758cef4cd05b9f8cee39758227714d02f42ef3088023c1e3cd454f927a2b   10 minutes ago      Running             etcd                      1                   dc7ecd13048ef       etcd-m1
794fdd119dd8d       3a5aa3a515f5d28b31ac5410cfaa56ddbbec1c4e88cbdf711db9de6bbf6b00b0   10 minutes ago      Running             kube-scheduler            1                   ded0bada61429       kube-scheduler-m1

w1, w2 安裝 kubelet 及 kubeadm 命令

# ssh 到 w1 主機安裝 kubelet 及 kubeadm 命令
$ ssh w1 'sudo apk add kubeadm kubelet --update-cache --repository http://dl-3.alpinelinux.org/alpine/edge/testing/ --allow-untrusted'

# ssh 到 w2 主機安裝 kubelet 及 kubeadm 命令
$ ssh w2 'sudo apk add kubeadm kubelet --update-cache --repository http://dl-3.alpinelinux.org/alpine/edge/testing/ --allow-untrusted'

# ssh 到 w1, w2 主機,將 kubelet 設成 Deamon
$ ssh w1 'sudo rc-update add kubelet default'; ssh w2 'sudo rc-update add kubelet default'
  • work node 不裝 kubectl 的原因是因為我們規劃的管理主機在 m1 ,work node 不需要管理其他機器。

w1, w2 加入 K8S Cluster

在 m1 的終端機, 執行以下命令

# 設定 JOIN 環境變數
$ export JOIN=$(echo " sudo `kubeadm token create --print-join-command 2>/dev/null`")

# 將 w1 主機,join 到 m1 的這個 k8s 的 Cluster
$ ssh w1 "$JOIN"; ssh w2 "$JOIN"

# 將 w2 主機,join 到 m1 的這個 k8s 的 Cluster
$ ssh w1 sudo reboot; ssh w2 sudo reboot

:::info

:::spoiler JOIN 變數解析

描述 : 將 w1 和 w2 的主機,join 到 K8S 系統的命令

$ echo " sudo `kubeadm token create --print-join-command`"
  • --print-join-command,不要只打印令牌,而是打印使用令牌加入集群所需的完整 “kubeadm join” 標誌。

output :

sudo kubeadm join 192.168.61.4:6443 --token tx06v1.le8z0pagl0ltfycz --discovery-token-ca-cert-hash sha256:0f4c243af9e70715a72f30ba0bc5cc44210f1b8fc66447cde16bad3a8c48d691

:::

設定 K8S Worker 標籤

在 m1 終端機, 執行以下命令

$ kubectl get nodes
NAME   STATUS   ROLES           AGE     VERSION
m1     Ready    control-plane   76m     v1.24.3
w1     Ready    <none>          4m21s   v1.24.3
w2     Ready    <none>          79s     v1.24.3

即使此時 w1 和 w2 notready ,也可以貼標籤,因為它是對 etcd 的資料庫作業。

$ kubectl label node w1 node-role.kubernetes.io/worker=; kubectl label node w2 node-role.kubernetes.io/worker=
  • 對 w1 和 w2 node 的 role 貼上 worker 的標籤
  • worker=, worker 的等號後面還可以放更詳細的說明,例如 : Asia, Taipei… 等

檢查是否符合預期

$ kubectl get nodes
NAME   STATUS   ROLES           AGE   VERSION
m1     Ready    control-plane   75m   v1.24.3
w1     Ready    worker          37m   v1.24.3
w2     Ready    worker          36m   v1.24.3

Kubernetes 檢測

建立 K8S POD

kubectl run 產生 pod ,pod 名字 nginx

$ kubectl run nginx --image=quay.io/cloudwalker/nginx
pod/nginx created --> ( 高機率騙人,有可能產生出來是掛的 )
  • kubectl run,Create and run a particular image in a pod.
  • --image='',The image for the container to run.

檢查是否符合預期

$ kubectl get pods
NAME    READY   STATUS              RESTARTS   AGE
nginx   0/1     ContainerCreating   0          8s
$ kubectl get pods
NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          52s

$ kubectl get pods -o wide
NAME    READY   STATUS    RESTARTS   AGE   IP           NODE   NOMINATED NODE   READINESS GATE
nginx   1/1     Running   0          74s   10.244.1.3   w1     <none>     <none>
-o output 
  • READY 的 1/1
  • 分子 -> 幾台正在 running 的 Container ; 分母 1 個 pod 有幾台 Container
  • -o wide ,可以看到 pod 的 ip 位址,和所在的 node
$ curl -s http://10.244.1.3 | grep 'Welcome'
<title>Welcome to nginx!</title>
<h1>Welcome to nginx!</h1>

# 刪除 pod <pod name>
$ kubectl delete pods nginx

$ kubectl run nginx --image=quay.io/cloudwalker/nginx
pod/nginx created

$ kubectl run a1 --image=quay.io/cloudwalker/alpine
pod/a1 created

## 失敗原因是因為 
## quay.io/cloudwalker/alpine 這張光碟片第一個跑的命令是 sh,
## 所以後面給一個虛擬終端機
$ kg pods
NAME    READY   STATUS             RESTARTS      AGE
a1      0/1     CrashLoopBackOff   2 (18s ago)   44s

# -it ,給一個個虛擬終端機
# --rm ,pod 停止就刪除 pod
$ kubectl run a1 --rm --image=quay.io/cloudwalker/alpine -it

$ kubectl exec -it a1 -- sh
## 要對 pod 下達命令一定要在 -- 後面
/ # curl http://10.244.1.3
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...中間省略
</html>

/ # exit
  • 兩個 pod 之間可以互通有無
  • 工作主機 和 master 主機也可以的到 nginx 那台 pod
tags: 系統工程