通過搭建單控制平面的 k8s 集群來處理各類非線上業務,特別是作為雲原生應用開發、測試、實驗學習等場景,雖然不是 HA 部署但也完全夠用。本文着重記錄單控制平面K8S集群安裝,為應用上雲、轉型雲原生應用進行基礎儲備。
如果資源足夠的話(10台以上服務器,3台用於APIserver、3台用於 etcd 存儲、至少3台用於工作節點、1台作為負載均衡),可以部署多控制平面的高可用集群環境。下面是高可用集群拓補結構,供參考:
安裝步驟不同,但整體思路大同小異,安裝時可參考 官網文檔,文檔清晰明了,也比較好操作。
一、准備工作
硬件資源要求,建議4核心以上CPU,8GB以上內存,Ubuntu 16.04 以上或 CentOS 7以上版本操作系統,確保所有服務器間正常網絡通信,1 台服務器作為控制平面節點,其余若干台服務器作為工作節點,我這里准備了4個工作節點。大致信息如下:
名稱 | CPU | 內存 | IP | OS | 安裝 | 用途 |
---|---|---|---|---|---|---|
CPN-1 | 4U | 8GB | 10.163.10.6 | ubuntu18.04 | docker , kubeadm, kubelet , kubectl | Control Plane Node |
WN-1 | 4U | 8GB | 10.163.10.7 | ubuntu18.04 | docker , kubeadm, kubelet | Worker Node |
WN-2 | 4U | 8GB | 10.163.10.8 | ubuntu18.04 | docker , kubeadm, kubelet | Worker Node |
WN-2 | 4U | 8GB | 10.163.10.9 | ubuntu18.04 | docker , kubeadm, kubelet | Worker Node |
WN-2 | 4U | 8GB | 10.163.10.10 | ubuntu18.04 | docker , kubeadm, kubelet | Worker Node |
安裝 docker
K8S 支持多種容器運行時環境,這里選擇 docker 作為運行時環境,首先為所有節點服務器安裝 docker,目前 kubernetes 最新版(v1.15.2) 可以完全兼容支持的 docker 最高版本為 v18.06,所以這里安裝 v18.06 這個版本。
參考 官網文檔。
# 刪除舊版本docker
$ sudo apt-get remove docker docker-engine docker.io containerd runc
# 更新 apt
$ sudo apt-get update
# 安裝工具包
$ sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common
# 添加Docker官方 GPG key
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# 添加 stable apt 源
$ sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
# 安裝 Docker CE
$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io
如果因網絡環境原因從官網倉庫安裝速度較慢,可以使用阿里雲鏡像倉庫安裝,具體步驟如下:
# step 1: 安裝必要的一些系統工具
sudo apt-get update
sudo apt-get -y install apt-transport-https ca-certificates curl software-properties-common
# step 2: 安裝GPG證書
curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
# Step 3: 寫入軟件源信息
sudo add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
# Step 4: 更新並安裝 Docker-CE
sudo apt-get -y update
# 選擇安裝版本,這里選擇 19.03.5
apt-cache madison docker-ce
# sudo apt-get -y install docker-ce=[version]
sudo apt-get install docker-ce=5:19.03.5~3-0~ubuntu-bionic docker-ce-cli=5:19.03.5~3-0~ubuntu-bionic containerd.io=1.2.10-3
后續操作
1、當前用戶加入"docker"用戶組
$ sudo usermod -aG docker $USER
2、 配置 cgroup 驅動為 systemd
# 創建文件 /etc/docker/daemon.json ,內容如下:
{
"exec-opts": ["native.cgroupdriver=systemd"],
"registry-mirrors": ["https://docker.mirrors.ustc.edu.cn/"]
}
3、重啟服務生效配置
sudo systemctl daemon-reload
sudo systemctl restart docker.service
4、檢查配置是否生效
docker info | grep Cgroup
# ECHO ------
Cgroup Driver: systemd
關閉 swap
swapoff -a && sudo sed -i 's/^.*swap/#&/g' /etc/fstab
安裝 kubelet kubeadm kubectl
由於網絡原因,直接 APT-GET 安裝可能安裝不了,這里需要配置一下鏡像倉庫。
1、配置阿里雲 kubernetes 鏡像倉庫
$ sudo apt-get update && sudo apt-get install -y apt-transport-https
curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | sudo apt-key add -
2、創建文件 /etc/apt/sources.list.d/kubernetes.list
, 內容如下:
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
3、安裝 kubelet kubectl kubeadm
$ sudo apt-get update
$ sudo apt-get install -y kubelet kubeadm kubectl
4、設置kubelet開機啟動
$ sudo systemctl enable kubelet
二、部署控制平面節點
過程中會用到一些列 docker 鏡像文件,這些文件在 Google 的鏡像倉庫,可以通過 kubeadm config images pull
命令驗證網絡是否能夠正常拉取鏡像。國內環境,十有八九無法直接連接,可從其他鏡像倉庫下載,然后再修改鏡像標簽,以便啟動相關 pod。
准備鏡像
列出安裝過程中需要用到的鏡像文件,命令為
kubeadm config images list
# ECHO ------
k8s.gcr.io/kube-apiserver:v1.17.0
k8s.gcr.io/kube-controller-manager:v1.17.0
k8s.gcr.io/kube-scheduler:v1.17.0
k8s.gcr.io/kube-proxy:v1.17.0
k8s.gcr.io/pause:3.1
k8s.gcr.io/etcd:3.4.3-0
k8s.gcr.io/coredns:1.6.5
這里選擇從 docker hub 中的 mirrorgooglecontainers 拉取鏡像副本,然后更新tag,再刪除鏡像副本,腳本如下:
images=(kube-apiserver:v1.17.0 kube-controller-manager:v1.17.0 kube-scheduler:v1.17.0 kube-proxy:v1.17.0 pause:3.1 etcd:3.4.3-0 coredns:1.6.5)
for imageName in ${images[@]} ; do
docker pull gotok8s/$imageName
docker tag gotok8s/$imageName k8s.gcr.io/$imageName
docker rmi gotok8s/$imageName
done
初始化控制平面節點
控制平面節點是控制平面組件運行的機器,包括etcd(集群數據庫)和 API server (kubectl CLI與之通信)。
需要安裝pod網絡插件,才能使得集群 pod 間可以相互通信,必須在任何應用程序之前部署 pod 網絡。此外,CoreDNS將不會在安裝網絡之前啟動。kubeadm僅支持基於容器網絡接口(CNI)的網絡,有幾個項目使用CNI提供了Kubernetes pod網絡,其中一些還支持網絡策略。有關可用網絡加載項的完整列表,請參閱網絡組件頁面。
另外,請注意,Pod網絡不得與任何主機網絡重疊,因為這可能會導致問題。如果發現網絡插件的首選Pod網絡與某些主機網絡之間發生沖突,應為 kubeadm init 指定 --pod-network-cidr 參數配置網絡網絡,並在網絡插件的YAML中修改相應信息。
這里我選擇 calico
網絡,根據 calico 文檔說明,我們需為 kubeadm init
指定 --pod-network-cidr=192.168.0.0/16
參數。現在運行 kubeadm init <args>
sudo kubeadm init \
--kubernetes-version=v1.17.0 \
--apiserver-advertise-address=10.163.10.6 \
--pod-network-cidr=192.168.0.0/16
如果一切正常,安裝成功,將輸入類似下面的結果信息:
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 as root:
kubeadm join 10.163.10.6:6443 --token xxxxxx.xxxxxxxxxxxxxxxx \
--discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
根據提示消息,依次執行以下命令:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
注意記錄輸出結果中的 kubeadm join ***
信息,隨后在添加工作節點到集群時需要用到,可以復制后暫存在某個地方。
安裝網絡
此時,我們通過 kubectl get pods --all-namespaces
命令,應該可以看到 CoreDNS pod 處於 pending 狀態,安裝網網絡以后,它才能處於 running 狀態。我們選擇 calico 為 pod 提供網絡,pod 網絡組件本身以 k8s 應用的形式運行,執行下面命令進行安裝。
kubectl apply -f https://docs.projectcalico.org/v3.11/manifests/calico.yaml
安裝了pod網絡后,可以通過檢查 CoreDNS pod 是否在輸出中運行來確認它是否正常工作 kubectl get pods --all-namespaces
。
kubectl get pods --all-namespaces
# ECHO ----
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system calico-kube-controllers-7bd78b474d-vmq2w 1/1 Running 0 4m57s
kube-system calico-node-2cwtx 1/1 Running 0 4m57s
kube-system coredns-5c98db65d4-gv2j6 1/1 Running 0 10m
kube-system coredns-5c98db65d4-n6lpj 1/1 Running 0 10m
kube-system etcd-vm-10-13-ubuntu 1/1 Running 0 8m54s
kube-system kube-apiserver-vm-10-13-ubuntu 1/1 Running 0 9m10s
kube-system kube-controller-manager-vm-10-13-ubuntu 1/1 Running 0 9m3s
kube-system kube-proxy-qbk66 1/1 Running 0 10m
kube-system kube-scheduler-vm-10-13-ubuntu 1/1 Running 0 9m8s
pod 啟動需要時間,請耐心等待。
三、加入工作節點
CoreDNS pod 啟動並運行后,我們可以為集群添加工作節點。工作節點服務器需安裝 docker 、kubeadm 和 kubelet,安裝過程請參考 master 節點部署流程。
拉取鏡像
工作節點服務器需要至少啟動兩個 pod ,用到的鏡像為 kube-proxy
和 pause
,同理我們無法直接從 k8s.grc.io 下載,需要提前拉取鏡像並修改 tag ,執行下面命令:
images=(kube-proxy:v1.17.0 pause:3.1)
for imageName in ${images[@]} ; do
docker pull gotok8s/$imageName
docker tag gotok8s/$imageName k8s.gcr.io/$imageName
docker rmi gotok8s/$imageName
done
加入集群
執行控制平面節點初始化完成后提供的添加工作節點命令,格式如下:
kubeadm join --token <token> <master-ip>:<master-port> --discovery-token-ca-cert-hash sha256:<hash>
命令中的 --token
和 --discovery-token-ca-cert-hash
在集群master節點部署完成后的結果信息中有體現,直接復制出來即可使用。
可以通過在控制平面節點執行 kubeadm token list
來獲取 token 信息,token 令牌會在 24 小時候失效,如果要創建新的令牌,使用 kubeadm token create
命令。
可以通過下面命令獲取 --discovery-token-ca-cert-hash
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | \
openssl dgst -sha256 -hex | sed 's/^.* //'
注意,如果需要重新執行 kubeadm join
,需在控制平面節點刪除該節點 kubectl delete node node-name
,並在工作節點上執行 kubeadm reset
進行清理工作。
節點執行完 join 命令后,可以在控制平面節點檢查 pod 啟動進度 watch kubectl get pods --all-namespaces -o wide
,觀察新節點服務器上的 pod 狀態,正常啟動則加入成功且節點狀態為 Ready
。參照上述步驟,依次將所有工作節點加入集群。
檢查工作節點狀態
工作節點加入集群后,隨着工作節點上相應 pod 的正常啟動,工作節點狀態會由 NotReady
切換到 Ready
,Pod 啟動需要時間,請耐心等待。所有節點正常加入集群后,可以通過命令查看節點狀態:
kubectl get nodes
# ECHO ------
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
vm-10-6-ubuntu Ready master 9h v1.15.2 10.163.10.13 <none> Ubuntu 18.04.1 LTS 4.15.0-54-generic docker://18.6.3
vm-10-7-ubuntu Ready <none> 9h v1.15.2 10.163.10.12 <none> Ubuntu 18.04.1 LTS 4.15.0-54-generic docker://18.6.3
vm-10-8-ubuntu Ready <none> 9h v1.15.2 10.163.10.9 <none> Ubuntu 18.04.1 LTS 4.15.0-54-generic docker://18.6.3
vm-10-9-ubuntu Ready <none> 8h v1.15.2 10.163.10.7 <none> Ubuntu 18.04.1 LTS 4.15.0-54-generic docker://18.6.3
vm-10-10-ubuntu Ready <none> 120m v1.15.2 10.163.10.2 <none> Ubuntu 18.04.1 LTS 4.15.0-54-generic docker://18.6.3
四、安裝 dashboard
dashboard 不會隨集群一起安裝,需要單獨部署,執行下面命令安裝:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-beta3/aio/deploy/recommended.yaml
這里要注意 dashboard 的版本,並非所有版本的 dashboard 都能和任意版本的 k8s 集群完全兼容。引用官網對照表
Kubernetes version | 1.11 | 1.12 | 1.13 | 1.14 | 1.15 |
---|---|---|---|---|---|
Compatibility | ? | ? | ? | ? | ✓ |
✓ Fully supported version range.
? Due to breaking changes between Kubernetes API versions, some features might not work correctly in the Dashboard.
默認情況下,Dashboard 使用最小 RBAC 配置進行部署。目前,Dashboard 僅支持使用 Bearer Token 登錄。可以按照關於創建示例用戶的指南 進行操作。
關於 dashboard 的使用,隨后會抽時間再詳細寫一篇進行介紹。
五、Inress
-
選擇一個節點,打上
node.k8s.xx.cn/role: ingress
標簽,已實現下一步進行 Pod 調度。 -
安裝下載 ingress-nginx 資源信息
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/baremetal/service-nodeport.yaml
- 修改配置信息
修改 nginx-ingress 安裝文件 mandatory.yaml
,以確保 nginx-ingress-controller 運行在指定節點上。
...
nodeSelector:
kubernetes.io/os: linux
node.k8s.xx.cn/role: ingress
serviceAccountName: nginx-ingress-serviceaccount
...
配置 service 為集群 IP 類型,使用外部 IP 暴露服務。
apiVersion: v1
kind: Service
metadata:
name: ingress-nginx
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
type: ClusterIP
externalIPs:
- 10.163.10.7
ports:
- name: http
port: 80
targetPort: 80
protocol: TCP
- name: https
port: 443
targetPort: 443
protocol: TCP
selector:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
---
- 安裝 ingress-nginx
kubectl apply -f mandatory.yaml
kubectl apply -f service-nodeport.yaml
六、結語
現在我們已經擁有一個 4 工作節點的單控制平面 k8s 集群,本文僅簡單介紹了部署過程,關於集群的管理、使用還會涉及到非常多 k8s 概念及領域知識,官網文檔基本上很詳細的介紹了各類概念,還有詳盡的操作演示,可以多看、多實踐。
最后,祝大家身體健康、工作順利、萬事如意。