本作品Galen Suen採用知識共享署名-非商業性使用-禁止演繹 4.0 國際許可協議進行許可。由原作者轉載自個人站點

概述

本文用於整理基於Debian作業系統使用kubeadm工具部署Kubernetes叢集的操作過程。該叢集部署於一組本地虛擬伺服器上,用於學習Kubernetes的基礎概念和基本操作,並作為今後其他學習內容的實踐部署提供環境。

考慮到不同的網路環境,本文中一些步驟會記錄兩種操作方式,通過映象等方式加快部署效率、避免部署錯誤。有關映象同步的方案,可參考附件內容中的同步所需映象

隨著作業系統和各相關元件版本的更新,筆者將在驗證通過後對本文進行補充和更新。

伺服器

受限於本地物理伺服器的配置,虛擬伺服器配置規劃如下表。

Host OS IP CPU RAM K8s Roles
k8s-n0 Debian 10.10 10.0.0.50 2 vCPUs 4 GB v1.22.1 control-plane, master
k8s-n1 Debian 10.10 10.0.0.51 4 vCPUs 6 GB v1.22.1
k8s-n2 Debian 10.10 10.0.0.52 4 vCPUs 6 GB v1.22.1
k8s-n3 Debian 10.10 10.0.0.53 4 vCPUs 6 GB v1.22.1

所有虛擬伺服器CPU均為amd64架構。

截止本文釋出時,筆者基於最新Debian 11 ("bullseye")部署的叢集仍然存在一些問題,故暫且釋出基於Debian 10 ("buster")的筆記。

網路環境

本地網路IP地址範圍為10.0.0.0/24,其中:

  • 10.0.0.2-10.0.0.99為靜態分配,供虛擬伺服器使用
  • 10.0.0.100-10.0.0.200用於DHCP自動分配
  • 10.0.0.201-10.0.0.254為靜態分配,供負載均衡器使用

其他元件

準備工作

伺服器配置

本文假設伺服器硬體和作業系統已經配置完畢,所有伺服器上都已經正確配置了ssh服務和sudo許可權。

作為參考,這裡記錄筆者配置sudo許可權和ssh服務的過程。

  • 配置sudo許可權

    如操作人員的登入使用者已經被正確配置了sudo許可權,可跳過此步驟。

    本示例中,操作人員的登入使用者名稱為tiscs,需要實際環境情況進行替換。

    # 使用root使用者登入系統
    # 安裝sudo,並配置sudo許可權
    apt update
    apt install sudo
    echo "tiscs ALL=(ALL) NOPASSWD: ALL" | tee /etc/sudoers.d/tiscs # 這在生產環境絕不是個好主意,僅僅是為了演練環境操作方便
  • 配置ssh服務

    # 安裝openssh-server,並配置ssh服務為自動啟動
    sudo apt update
    sudo apt install openssh-server
    sudo systemctl enable ssh --now

配置過程

安裝容器執行時

本文配置的叢集選擇containerd作為容器執行時。

在所有節點上執行如下操作。

  • 配置模組載入

    cat <<EOF | sudo tee /etc/modules-load.d/containerd.conf
    overlay
    br_netfilter
    EOF sudo modprobe overlay
    sudo modprobe br_netfilter
  • 配置sysctl引數

    cat <<EOF | sudo tee /etc/sysctl.d/99-kubernetes-cri.conf
    net.bridge.bridge-nf-call-iptables = 1
    net.ipv4.ip_forward = 1
    net.bridge.bridge-nf-call-ip6tables = 1
    EOF sudo sysctl --system
  • 配置APT源

    # 安裝依賴項
    sudo apt install -y apt-transport-https ca-certificates curl gnupg lsb-release
    # 根據網路環境選擇官方源或映象源
    
    # 1. 配置Docker官方源
    curl -fsSL https://download.docker.com/linux/debian/gpg \
    | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/docker-archive-keyring.gpg
    echo "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable" \
    | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null # 2. 配置Aliyun映象源
    curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/debian/gpg \
    | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/docker-archive-keyring.gpg
    echo "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/debian $(lsb_release -cs) stable" \
    | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
  • 安裝containerd

    sudo apt update
    sudo apt install -y containerd.io
  • 初始化配置

    sudo mkdir -p /etc/containerd
    containerd config default | sudo tee /etc/containerd/config.toml
    # 配置systemd cgroup驅動
    sudo sed -i 's|\(\s\+\)\[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options\]|\1\[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options\]\n\1 SystemdCgroup = true|g' /etc/containerd/config.toml
    # (可選)配置阿里雲容器映象源
    sudo sed -i 's/registry-1.docker.io/xrb7j2ja.mirror.aliyuncs.com/g' /etc/containerd/config.toml
    # (可選)配置sandbox image地址
    # 為了方便,這裡配置為與kubelet所需相同的版本(可以使用kubeadm config images list命令檢視)
    sudo sed -i 's|k8s.gcr.io/pause:.\+|registry.cn-beijing.aliyuncs.com/choral-k8s/pause:3.5|g' /etc/containerd/config.toml
    # 重啟containerd服務
    sudo systemctl restart containerd

安裝kubeadm

在所有節點上執行如下操作。

  • 配置APT源

    # 根據網路環境選擇官方源或映象源
    
    # 1. 配置Docker官方源
    curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg \
    | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/kubernetes-archive-keyring.gpg
    echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" \
    | sudo tee /etc/apt/sources.list.d/kubernetes.list # 2. 配置Aliyun映象源
    curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/debian/gpg \
    | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/kubernetes-archive-keyring.gpg
    echo "deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main" \
    | sudo tee /etc/apt/sources.list.d/kubernetes.list
  • 安裝kubeadmkubeletkubectl

    sudo apt install -y kubelet=1.22.1-00 kubeadm=1.22.1-00 kubectl=1.22.1-00
    sudo apt-mark hold kubelet kubeadm kubectl
  • 安裝並配置crictl(可選)

    可以安裝並配置crictl,便於在k8s節點上管理容器執行時。

    # 安裝crictl工具
    sudo apt install -y cri-tools # 配置crictl使用containerd執行時
    cat <<EOF | sudo tee /etc/crictl.yaml
    runtime-endpoint: unix:///run/containerd/containerd.sock
    image-endpoint: unix:///run/containerd/containerd.sock
    timeout: 10
    debug: false
    EOF # 驗證crictl配置
    sudo crictl images # 列出所有映象

配置控制平面節點

k8s-n0節點上執行如下操作。

  • 預先下載所需映象

    # 檢視所需的映象列表
    kubeadm config images list --kubernetes-version=v1.22.1 # --image-repository registry.cn-beijing.aliyuncs.com/choral-k8s # 1. 使用預設容器映象倉庫
    sudo kubeadm config images pull --kubernetes-version=v1.22.1 # 2. 使用自建容器映象倉庫
    sudo kubeadm config images pull --kubernetes-version=v1.22.1 \
    --image-repository registry.cn-beijing.aliyuncs.com/choral-k8s
  • 初始化控制平面節點

    # --apiserver-advertise-address: 當前節點IP地址
    # --pod-network-cidr : Pod網路地址段(CIDR: https://datatracker.ietf.org/doc/html/rfc4632) # 1. 使用預設容器映象倉庫
    sudo kubeadm init --apiserver-advertise-address 10.0.0.50 \
    --pod-network-cidr=10.244.0.0/16 --kubernetes-version=v1.22.1 # 2. 使用自建容器映象倉庫
    sudo kubeadm init --apiserver-advertise-address 10.0.0.50 \
    --pod-network-cidr=10.244.0.0/16 --kubernetes-version=v1.22.1 \
    --image-repository registry.cn-beijing.aliyuncs.com/choral-k8s

    執行完上述操作後,kubeadm init命令會輸出用於新增節點到叢集中的說明,請儲存該說明中的內容。示例如下:

    sudo kubeadm join 10.0.0.50:6443 \
    --token vafq03.5dl6j1cbcd1yzf3c \
    --discovery-token-ca-cert-hash sha256:6a725d98e0f6bda713c9f93b8441a735cc60e8ec7454fbe960c74ab80683f938
  • 新增kubectl配置(可選)

    mkdir -p ~/.kube
    sudo cp -i /etc/kubernetes/admin.conf ~/.kube/config
    sudo chown $(id -u):$(id -g) ~/.kube/config
  • 安裝網路元件

    # 1. 使用預設映象倉庫(quay.io/coreos)安裝
    kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml # 2. 使用給自定義映象倉庫安裝
    kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml \
    | sed -e 's|quay.io/coreos|registry.cn-beijing.aliyuncs.com/choral-k8s|g' | kubectl apply -f - # 2.1 如果訪問raw.githubusercontent.com上的檔案存在網路問題
    # 可以使用jsdelivr提供的GitHub CDN地址(https://www.jsdelivr.com/github)
    curl -s https://cdn.jsdelivr.net/gh/coreos/flannel@master/Documentation/kube-flannel.yml \
    | sed -e 's|quay.io/coreos|registry.cn-beijing.aliyuncs.com/choral-k8s|g' | kubectl apply -f -

新增工作節點

k8s-n1k8s-n2k8s-n3節點上執行如下操作。該操作中需要的token值和hash值通過上述步驟中的kubeadm init操作獲取。

  • 新增工作節點

    sudo kubeadm join 10.0.0.50:6443 \
    --token vafq03.5dl6j1cbcd1yzf3c \
    --discovery-token-ca-cert-hash sha256:6a725d98e0f6bda713c9f93b8441a735cc60e8ec7454fbe960c74ab80683f938
  • 檢視節點狀態

    k8s-n0節點上執行如下操作。

    kubectl get nodes
    kubectl top nodes

安裝Helm工具(可選)

本文暫不涉及使用helm執行的操作,該步驟可選。

  • 安裝Helm工具

    # 下載並安裝
    curl -sL https://get.helm.sh/helm-v3.6.3-linux-amd64.tar.gz | tar xzf - linux-amd64/helm
    sudo cp ./linux-amd64/helm /usr/local/bin/helm
    rm -rf ./linux-amd64
    sudo chown root:root /usr/local/bin/helm
    sudo chmod 755 /usr/local/bin/helm # 驗證helm安裝
    helm version

安裝Metrics Server(可選)

部署metrics server以啟用指標服務,未安裝metrics server前,kubectl top命令無法正常執行。

k8s-n0節點上執行如下操作。

  • 執行清單檔案

    這裡需要注意,為解決證書錯誤,需要新增metrics-server容器的引數--kubelet-insecure-tls,這裡選擇通過sed命令修改清單檔案後再使用kubectl執行。

    # 1. 使用官方映象地址直接安裝
    curl -sL https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml \
    | sed -e "s|\(\s\+\)- args:|\1- args:\n\1 - --kubelet-insecure-tls|" | kubectl apply -f -
    # 1.1 為避免特殊網路環境中的清單檔案載入問題,可以使用FastGit提供的加速方案
    curl -sL https://endpoint.fastgit.org/https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml \
    | sed -e "s|\(\s\+\)- args:|\1- args:\n\1 - --kubelet-insecure-tls|" | kubectl apply -f - # 2. 使用自定義映象地址安裝
    curl -sL https://endpoint.fastgit.org/https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml \
    | sed \
    -e "s|\(\s\+\)- args:|\1- args:\n\1 - --kubelet-insecure-tls|" \
    -e "s|k8s.gcr.io/metrics-server|registry.cn-beijing.aliyuncs.com/choral-k8s|g" \
    | kubectl apply -f -
    #

安裝負載均衡元件

由雲服務商提供的Kubernetes服務,通常會提供內建的負載均衡實現。而筆者部署環境為私有環境,需要一個輕量的負載均衡實現以支撐LoadBalancer型別的服務。

筆者選擇MetalLB作為負載均衡實現,配置為二層網路模式。LoadBalancer地址範圍配置為10.0.0.201-10.0.0.254,需根據具體網路環境進行修改。

k8s-n0節點上執行如下操作。

  • 安裝MetalLB

    # 建立用於部署MetalLB的名稱空間
    kubectl create namespace metallb-system # 建立必須的配置檔案
    cat <<EOF | kubectl apply -f - --dry-run=client
    apiVersion: v1
    kind: ConfigMap
    metadata:
    namespace: metallb-system
    name: config
    data:
    config: |
    address-pools:
    - name: default
    protocol: layer2
    addresses:
    - 10.0.0.201-10.0.0.254
    EOF # 1. 直接執行清單檔案
    kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.10.2/manifests/metallb.yaml
    # 1.1 為避免特殊網路環境中的清單檔案載入問題,可以使用jsdelivr提供的加速方案加速地址
    kubectl apply -f https://cdn.jsdelivr.net/gh/metallb/[email protected]/manifests/metallb.yaml # 2. 替換名稱空間。名稱空間需要與剛剛建立的ConfigMap相同。
    curl -sL https://cdn.jsdelivr.net/gh/metallb/[email protected]/manifests/metallb.yaml \
    | sed -e "s|namespace: metallb-system|namespace: kube-system|g" | kubectl apply -f -

安裝持久卷供應程式

Kubernetes內建的local-storage儲存類無法動態供應卷,為便於基於該環境演練時自動建立持久卷,選擇使用local-path-provisioner作為持久卷供應程式。

  • 建立所需的目錄

    在所有節點上執行如下操作。

    sudo mkdir -p /opt/local-path-provisioner
  • 安裝local-path-provisioner

    k8s-n0節點上執行如下操作。

    # 1. 使用官方清單檔案地址直接安裝
    kubectl apply -f https://raw.githubusercontent.com/rancher/local-path-provisioner/master/deploy/local-path-storage.yaml
    # 1.1 同樣可以使用jsdelivr提供的加速方案
    kubectl apply -f https://cdn.jsdelivr.net/gh/rancher/local-path-provisioner@master/deploy/local-path-storage.yaml # 2. 替換名稱空間
    curl -s https://cdn.jsdelivr.net/gh/rancher/local-path-provisioner@master/deploy/local-path-storage.yaml \
    | sed \
    -e "1,6d" \
    -e "s/local-path-storage/kube-system/" \
    | kubectl apply -f -
  • 配置預設儲存類

    kubectl patch storageclass local-path -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'

檢查叢集工作狀態

k8s-n0節點上執行如下操作。

  • 檢視節點狀態

    kubectl get nodes
    kubectl top nodes
  • 檢視Pod狀態

    kubectl get pods -A
    kubectl top pods -A

附加內容

同步所需映象

由於特殊網路環境問題,需要同步kubelet所需映象至其他映象倉庫的,可參考如下操作。

筆者開發環境中使用podman管理容器和映象,已將docker設定為podman的別名(alias docker=podman)。

  • 同步kubelet所需映象

    首先,需要建立私有映象倉庫認證憑據。

    # 根據需要將`registry.cn-beijing.aliyuncs.com`替換為私有映象倉庫地址
    docker login registry.cn-beijing.aliyuncs.com

    建立一個指令碼gcr_mirror_sync.sh,內容如下。

    # gcr_mirror_sync.sh
    # 根據需要將`registry.cn-beijing.aliyuncs.com/choral-k8s/`替換為私有映象倉庫地址
    while read o
    do {
    t=$(echo $o | sed 's|k8s.gcr.io.*/|registry.cn-beijing.aliyuncs.com/choral-k8s/|g')
    docker pull $o
    docker tag $o $t
    docker push $t
    docker rmi $o
    docker rmi $t
    }
    done < "${1:-/dev/stdin}"

    該指令碼有兩種使用方法。

    kubeadm config images list --kubernetes-version=v1.22.1 | bash gcr_mirror_sync.sh
    # 列出所需映象列表並儲存到檔案
    kubeadm config images list --kubernetes-version=v1.22.1 > gcr-image-list
    # 拷貝該檔案至gcr_mirror_sync.sh所在主機,然後執行該指令碼
    bash gcr_mirror_sync.sh gcr-image-list
  • 同步附加元件映象

    # 根據需要將`registry.cn-beijing.aliyuncs.com/choral-k8s/`替換為私有映象倉庫地址。
    
    # 同步metrics server所需映象
    docker pull k8s.gcr.io/metrics-server/metrics-server:v0.5.0
    docker tag k8s.gcr.io/metrics-server/metrics-server:v0.5.0 registry.cn-beijing.aliyuncs.com/choral-k8s/metrics-server:v0.5.0
    docker push registry.cn-beijing.aliyuncs.com/choral-k8s/metrics-server:v0.5.0
    docker rmi k8s.gcr.io/metrics-server/metrics-server:v0.5.0
    docker rmi registry.cn-beijing.aliyuncs.com/choral-k8s/metrics-server:v0.5.0 # 同步flannel所需映象
    docker pull quay.io/coreos/flannel:v0.14.0
    docker tag quay.io/coreos/flannel:v0.14.0 registry.cn-beijing.aliyuncs.com/choral-k8s/flannel:v0.14.0
    docker push registry.cn-beijing.aliyuncs.com/choral-k8s/flannel:v0.14.0
    docker rmi quay.io/coreos/flannel:v0.14.0
    docker rmi registry.cn-beijing.aliyuncs.com/choral-k8s/flannel:v0.14.0

參考資料