Featured image of post Kubernetes 安裝筆記(2020 年版):使用 Docker-CE 作為 CRI

Kubernetes 安裝筆記(2020 年版):使用 Docker-CE 作為 CRI

注意: 這份筆記是 2020 年的安裝記錄。Kubernetes 1.24 之後已移除 dockershim,Docker 不再作為 CRI 直接支援。現行安裝請考慮改用 containerd 或 CRI-O。

環境

  • Ubuntu 18.04 / 20.04 LTS
  • Docker(Container Runtime)
  • Kubernetes 版本:1.17.x ~ 1.19.x

Step.1 安裝 Docker

CRI(Container Runtime Interface)除了 Docker,還有 CRI-O、containerd、rkt、Kata Containers 等選擇。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
apt update
apt install -y docker.io

# 設定 Docker daemon:cgroup driver 使用 systemd(Kubernetes 要求)
cat > /etc/docker/daemon.json <<EOF
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2"
}
EOF

mkdir -p /etc/systemd/system/docker.service.d
systemctl enable docker.service
systemctl daemon-reload
systemctl restart docker

確認版本:

1
2
docker version
# Client: 19.03.8 / Server Engine: 19.03.8

Step.2 安裝 kubeadm、kubelet、kubectl

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
apt update && apt install -y apt-transport-https curl

curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -

echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | tee -a /etc/apt/sources.list.d/kubernetes.list

apt update
apt install -y kubelet kubeadm kubectl bash-completion

# 鎖定套件,避免自動更新
apt-mark hold kubelet kubeadm kubectl

啟用 kubectl shell 自動補全:

1
kubectl completion bash > /etc/bash_completion.d/kubectl

確認版本:

1
2
3
4
5
kubeadm version
# kubeadm version: v1.19.2

kubectl version --client
# Client Version: v1.19.2

若還未設定連線叢集,kubectl version 會出現 localhost:8080 was refused 錯誤,可先忽略。


Step.3 預先下載 Image(可選)

初始化 Master Node 時需要 pull 多個 image,可提前下載:

1
2
3
4
kubeadm config images pull
# [config/images] Pulled k8s.gcr.io/kube-apiserver:v1.19.2
# [config/images] Pulled k8s.gcr.io/kube-controller-manager:v1.19.2
# ...

Step.4 初始化 Control Plane(Master Node)

先關閉 SWAP(Kubernetes 強制要求):

1
swapoff -a

執行初始化:

1
kubeadm init --pod-network-cidr=10.244.0.0/16

順利的話約 2-3 分鐘完成,輸出末尾會出現:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
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

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 172.16.1.20:6443 --token <token> \
    --discovery-token-ca-cert-hash sha256:<hash>

設定 kubectl config:

1
2
3
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

Step.5 佈署 CNI(Cilium)

初始化完成後 Master Node 狀態會是 NotReady,原因是 CNI 尚未安裝:

1
2
3
kubectl get nodes
# NAME         STATUS     ROLES    AGE   VERSION
# k8s-master   NotReady   master   26m   v1.19.2

安裝 Cilium CNI:

1
kubectl create -f https://raw.githubusercontent.com/cilium/cilium/HEAD/install/kubernetes/quick-install.yaml

等待 pods 就緒:

1
kubectl get pods -n kube-system --watch

Cilium 啟動後,coredns 也會一起帶起,Master Node 變為 Ready


Step.6 加入 Worker Node

在 Master Node:取得 join 指令

1
2
kubeadm token create --print-join-command
# kubeadm join 172.16.1.20:6443 --token <token> --discovery-token-ca-cert-hash sha256:<hash>

在 Worker Node:執行前置安裝

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
swapoff -a
apt update
apt install -y docker.io
cat > /etc/docker/daemon.json <<EOF
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {"max-size": "100m"},
  "storage-driver": "overlay2"
}
EOF
mkdir -p /etc/systemd/system/docker.service.d
systemctl enable docker.service
systemctl daemon-reload
systemctl restart docker

apt update && apt install -y apt-transport-https curl
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | tee -a /etc/apt/sources.list.d/kubernetes.list
apt update
apt install -y kubelet kubeadm kubectl
apt-mark hold kubelet kubeadm kubectl

設定 hostname 並重啟:

1
2
3
hostnamectl set-hostname k8s-node-1
echo "127.0.0.1\t$(hostname)" | tee -a /etc/hosts
reboot

加入叢集:

1
2
kubeadm join 172.16.1.20:6443 --token <token> \
    --discovery-token-ca-cert-hash sha256:<hash>

驗證

回到 Master Node 確認 node 已加入:

1
2
3
4
5
kubectl get nodes
# NAME         STATUS   ROLES    AGE     VERSION
# k8s-master   Ready    master   4h30m   v1.19.2
# k8s-node-1   Ready    <none>   4m54s   v1.19.2
# k8s-node-2   Ready    <none>   4m23s   v1.19.2

Step.7 安裝 Kubernetes Dashboard

1
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.4/aio/deploy/recommended.yaml

建立 admin-user ServiceAccount:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kubernetes-dashboard
EOF

cat <<EOF | kubectl apply -f -
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: kubernetes-dashboard
EOF

取得登入 token:

1
2
kubectl -n kubernetes-dashboard describe secret \
  $(kubectl -n kubernetes-dashboard get secret | grep admin-user | awk '{print $1}')

開啟 proxy:

1
kubectl proxy

瀏覽器連到:http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/

若透過 SSH 連到 Master Node,建立 SSH tunnel:ssh username@<master-ip> -NfL 8001:localhost:8001


Step.8 安裝 Rook(Ceph 儲存)

⚠️ 以下記錄未完成:OSD 無法建立,僅作參考。

安裝 Rook Operator

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 安裝 common.yaml(處理 RBAC 版本相容問題)
curl https://raw.githubusercontent.com/rook/rook/release-1.4/cluster/examples/kubernetes/ceph/common.yaml \
    | sed 's/rbac.authorization.k8s.io\/v1beta1/rbac.authorization.k8s.io\/v1/g' \
    | kubectl apply -f -

# 安裝 operator
kubectl apply -f https://raw.githubusercontent.com/rook/rook/release-1.4/cluster/examples/kubernetes/ceph/operator.yaml

# 等待 operator 就緒後,安裝 Ceph cluster
kubectl apply -f https://github.com/rook/rook/raw/release-1.4/cluster/examples/kubernetes/ceph/cluster.yaml

安裝 Toolbox 並查看狀態

1
2
3
4
5
6
7
kubectl apply -f https://github.com/rook/rook/raw/release-1.4/cluster/examples/kubernetes/ceph/toolbox.yaml

kubectl -n rook-ceph exec -it \
    $(kubectl -n rook-ceph get pod -l "app=rook-ceph-tools" -o jsonpath='{.items[0].metadata.name}') \
    -- bash

# 常用指令:ceph status / ceph osd status / ceph df / rados df

若遇到 FailedScheduling

1
kubectl taint nodes --all node-role.kubernetes.io/master-

故障排除

Swap 未關閉

錯誤訊息:

1
[ERROR Swap]: running with swap on is not supported. Please disable swap

解法 (臨時性):

1
swapoff -a

開機後需再次執行,或編輯 /etc/fstab 永久停用。

Docker service 未啟用

錯誤訊息:

1
[WARNING Service-Docker]: docker service is not enabled

解法:

1
systemctl enable docker.service

References

comments powered by Disqus