Kubernetes 兩步安裝一次上手

介紹如何透過 Kubeadm 在短時間內安裝 Kubernetes

ta-ching chen

3 minute read

 文章目錄

前言 

古早時期安裝完整 Kubernetes 的步驟十分繁複,Kubernetes 1.4 之後推出 kubeadm 讓整個安裝過程能在幾分鐘內完成,以下將介紹使用 kubeadm 安裝 Kubernetes 的過程。

前置步驟 

  • Ubuntu 16.04

安裝 

  • install.sh
#!/bin/bash
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 http://apt.kubernetes.io/ kubernetes-xenial main
EOF
apt-get update
# Install docker if you don't have it already.
apt-get install -y docker.io
apt-get install -y kubelet kubeadm kubectl kubernetes-cni

安裝基本的相依套件 

$ chmod +x install.sh
$ sudo ./install.sh

安裝 Kubernetes 核心套件 

$ sudo kubeadm init

這裡我們使用 flannel 作為展示,若要使用其他 CNI 請查看對應安裝文件。

$ kubeadm init --pod-network-cidr=10.244.0.0/16
$ kubectl create -f https://raw.githubusercontent.com/coreos/flannel/v0.12.0/Documentation/kube-flannel.yml

其他常用 Optional 設定

--apiserver-advertise-address: Api server 服務 IP 位址
--apiserver-bind-port: Api server 服務埠號,預設 6443
--pod-network-cidr: Pod 的虛擬 IP 範圍 (CIDR)
--kubernetes-version: 指定 Kubernetes 版本,建議 1.6+

至此 Kubernetes 已經安裝完成摟!

設定 Kubectl 

接著我們要設定讓 kubectl 連到 Kubernetes,首先將設定複製到 $HOME/.kube/config 底下,kubectl 執行時會自動至該目錄下取得 Api server 位置等相關資料。

$ mkdir -p $HOME/.kube/config/
$ sudo cp /etc/kubernetes/admin.conf $HOME/.kube/config/
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config/admin.conf
$ kubectl get nodes

Kubernetes 叢集自動恢復 

主機重啟後預設 Kubernetes 叢集是不會自動啟動,需要額外以下設定

$ sudo swapoff -a
# 註解掉 /etc/fstab 內的 swap 部分,確保重啟後不會重新掛載 
$ sudo sed -i 's/.*swap.*/#&/' /etc/fstab
$ sudo systemctl enable kubelet

如此一來就會在主機重啟時自動帶起預先安裝的叢集。

若仍然沒有成功且 /var/log/syslog 秀出類似 AppArmor policy 的訊息

createPodSandbox for pod "kube-apiserver-template_kube-system(b1446568d75d2d0f4098b4b73cd39699)" 
failed: rpc error: code = Unknown desc = failed to start sandbox container for pod "kube-apiserver-template": 
Error response from daemon: OCI runtime create failed: container_linux.go:345: starting container process caused 
"process_linux.go:281: applying cgroup configuration for process caused \"An AppArmor policy prevents this sender from 
sending this message to this recipient; type=\\\"method_call\\\", sender=\\\":1.981\\\" (uid=0 pid=13495 comm=\\\"runc 
...........

請確認機器的 Docker daemon 是否為利用 snap 所安裝。

sudo snap list
Name    Version    Rev   Tracking  Publisher   Notes
docker  18.09.9    423   stable    canonical✓  -

通常這是透過 Ubuntu snap 所安裝導致的權限問題,可以參照官方教學, 或是移除後以非 snap 方式安裝即可。

Troubleshooting 

  • 節點由於 cni config uninitialized 導致處於 NotReady 狀態或 Pod 無法存取外部網路
$ kubectl describe nodes
...
KubeletNotReady runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:docker: network plugin is not ready: cni config uninitialized
...

Kubernetes v1.6 引入 RBAC 的權限管理,我們需要建立對應的 Service Account、RBAC 設定以及 flannel daemonset 才能讓 kubelet 和 api server 正常溝通連線。執行以下指令並等待幾秒鐘後,節點就會變成 Ready 狀態。

這邊我們使用 flannel 作為 Kubernetes 的 CNI plugin,如果想直接使用官方 manifest 的話,記得在 init 時加上 --pod-network-cidr=10.244.0.0/16。若需要想要使用自定義的 CIDR,更改 manifest 內 net-conf.jsonNetwork 並用新的 CIDR init 即可。

$ kubeadm init --pod-network-cidr=10.244.0.0/16
$ kubectl create -f https://raw.githubusercontent.com/coreos/flannel/v0.12.0/Documentation/kube-flannel.yml
  • 執行 kubeadm init 時的 preflight 出現警告
[preflight] WARNING: Running with swap on is not supported. Please disable swap or set kubelet's --fail-swap-on flag to false.
...
[kubelet-check] The HTTP call equal to 'curl -sSL http://localhost:10255/healthz' failed with error: Get http://localhost:10255/healthz: dial tcp [::1]:10255: getsockopt: connection refused.

這是由於目前尚不支援 swap 分區,執行下列指令將 swap 關閉即可

$ sudo swapoff -a
  • Flannel 無法正常運作
$ kubectl --namespace kube-system get pod
NAME                             READY     STATUS              RESTARTS   AGE
etcd-ubuntu                      1/1       Running             0          13m
kube-apiserver-ubuntu            1/1       Running             0          13m
kube-controller-manager-ubuntu   1/1       Running             0          13m
kube-dns-545bc4bfd4-4csqc        0/3       ContainerCreating   0          14m
kube-flannel-ds-bdg8j            0/1       Error               1          6s
kube-proxy-9brgj                 1/1       Running             0          14m
kube-scheduler-ubuntu            1/1       Running             0          13m

Flannel daemonset 無法正常啟動,看 log 會出現以下訊息

$ kubectl --namespace kube-system logs -f kube-flannel-ds-bdg8j
...
E1102 06:37:57.177991       1 main.go:280] Error registering network: failed to acquire lease: node "ubuntu" pod cidr not assigned
...

需要指定 Pod CIDR 範圍 (ex. 10.244.0.0/16)

$ sudo kubeadm init --pod-network-cidr=10.244.0.0/16
  • Pod 訊息出現 PodToleratesNodeTaints

出現 PodToleratesNodeTaints 是由於 kubadm 預設安裝時會設定 master 節點不能被用來部署 Pod

$ kubectl describe pod xxx-698c5969c6-rtvht
...
Events:
  Type     Reason            Age               From               Message
  ----     ------            ----              ----               -------
  Warning  FailedScheduling  7s (x6 over 22s)  default-scheduler  No nodes are available that match all of the predicates: PodToleratesNodeTaints (1).

若需要讓 master 也能被部署 Pod,請執行以下指令

$ kubectl taint nodes <node name> <node label>:NoSchedule-

範例:

$ kubectl get nodes --show-labels
NAME      STATUS    ROLES     AGE       VERSION   LABELS
ubuntu    Ready     master    33m       v1.8.2    beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/hostname=ubuntu,node-role.kubernetes.io/master=

$ kubectl taint nodes ubuntu node-role.kubernetes.io/master:NoSchedule-
node "ubuntu" untainted

進階指令 

移除 Kubernetes 

  • 注意: 此指令會移除所有 Kubernetes 相關服務及資料
$ sudo kubeadm reset

新增其他運算節點 

在一開始 kubeadm init 最後會從 console 印出加入節點的指令,請額外記錄下來以便加入。

$ sudo kubeadm join --token <token> <api server ip>:<port>

連線至遠端 Kubernetes Api Server 

$ cp admin.conf <path>/admin.conf
$ kubectl --kubeconfig <path>/admin.conf proxy
Starting to serve on 127.0.0.1:8001
$ kubectl get pod --server=127.0.0.1:8001

參考連結 

相關文章

文章內容的轉載、重製、發佈,請註明出處: https://tachingchen.com/tw/
comments powered by Disqus