基於 kubeadm 部署 kubernetes(v1.17.0) 集群


通過搭建單控制平面的 k8s 集群來處理各類非線上業務,特別是作為雲原生應用開發、測試、實驗學習等場景,雖然不是 HA 部署但也完全夠用。本文着重記錄單控制平面K8S集群安裝,為應用上雲、轉型雲原生應用進行基礎儲備。

如果資源足夠的話(10台以上服務器,3台用於APIserver、3台用於 etcd 存儲、至少3台用於工作節點、1台作為負載均衡),可以部署多控制平面的高可用集群環境。下面是高可用集群拓補結構,供參考:

kubeadm-ha-topology-external-etcd

安裝步驟不同,但整體思路大同小異,安裝時可參考 官網文檔,文檔清晰明了,也比較好操作。

一、准備工作

硬件資源要求,建議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-proxypause ,同理我們無法直接從 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

  1. 選擇一個節點,打上 node.k8s.xx.cn/role: ingress 標簽,已實現下一步進行 Pod 調度。

  2. 安裝下載 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
  1. 修改配置信息

修改 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
---
  1. 安裝 ingress-nginx
kubectl apply -f mandatory.yaml
kubectl apply -f service-nodeport.yaml

六、結語

現在我們已經擁有一個 4 工作節點的單控制平面 k8s 集群,本文僅簡單介紹了部署過程,關於集群的管理、使用還會涉及到非常多 k8s 概念及領域知識,官網文檔基本上很詳細的介紹了各類概念,還有詳盡的操作演示,可以多看、多實踐。

最后,祝大家身體健康、工作順利、萬事如意。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM