用 kubeadm 在 Debian 或 Ubuntu 中創建 k8s 集群


本文根據官方教程修改而來。

一、准備

要遵循本指南,你需要:

  • 一個或多個 Debian 9 / Ubuntu 18.04 虛擬機,物理機當然更好
  • 每台機器 2GB 以上的內存
  • 用作控制平台節點的虛擬機至少有 2 個CPU
  • 集群中所有計算機之間具有完全的網絡連接

更改主節點 hostname 為 k8s-master,子節點根據數量修改 hostname 為 k8s-node-n,每個節點都要修改 hosts文件,添加所有節點的 ip 和 hostname 的映射關系,如:

# k8s cluster nodes start
192.168.31.221 k8s-master
192.168.31.222 k8s-node-1
192.168.31.231 k8s-node-2
# k8s cluster nodes end

關閉 swap

sudo swapoff -a

上面只是臨時關閉,永久關閉還需刪除/etc/fstab 中有關 swap 分區的項目。

sudo cp /etc/fstab /etc/fstab.bak
sudo sed -i "/^\/swap/d" /etc/fstab

修改完 fstab 文件后,重啟主機。

二、教程開始

1 安裝 kubeadm

1.1 允許 iptables 檢查橋接流量

確保 br_netfilter 模塊被加載。這一操作可以通過運行 lsmod | grep br_netfilter 來完成。若要顯式加載該模塊,可執行 sudo modprobe br_netfilter

為了讓你的 Linux 節點上的 iptables 能夠正確地查看橋接流量,你需要確保在你的 sysctl 配置中將 net.bridge.bridge-nf-call-iptables 設置為 1。例如:

cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF

cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sudo sysctl --system

1.2 安裝 Docker

參考 docker-ce | 鏡像站使用幫助 | 北京外國語大學開源軟件鏡像站 | BFSU Open Source Mirror

不再細述。

1.3 安裝 kubeadm、kubelet 和 kubectl

你需要在每台機器上安裝下面的軟件包:

  • kubeadm:用來初始化集群的指令。
  • kubelet:在集群中的每個節點上用來啟動 Pod 和容器等。
  • kubectl:用來與集群通信的命令行工具。

kubeadm 不能 幫你安裝或者管理 kubeletkubectl,所以你需要 確保它們與通過 kubeadm 安裝的控制平面的版本相匹配。 如果不這樣做,則存在發生版本偏差的風險,可能會導致一些預料之外的錯誤和問題。 然而,控制平面與 kubelet 間的相差一個次要版本不一致是支持的,但 kubelet 的版本不可以超過 API 服務器的版本。 例如,1.7.0 版本的 kubelet 可以完全兼容 1.8.0 版本的 API 服務器,反之則不可以。

安裝過程

  1. 更新 apt 包索引並安裝使用 Kubernetes apt 倉庫所需要的包:

    sudo apt-get update
    sudo apt-get install -y apt-transport-https ca-certificates curl
    
  2. 下載並添加簽名密鑰,我將谷歌 key 上傳到了 gitee,方便國內使用:

    curl -s https://gitee.com/thepoy/k8s/raw/master/apt-key.gpg | sudo apt-key add -
    
  3. 添加 Kubernetes apt 倉庫,這里使用清華鏡像,但清華鏡像不穩定,有時會沒有網速:

    cat <<EOF | sudo tee /etc/apt/sources.list.d/kubernetes.list 
    deb https://mirrors.tuna.tsinghua.edu.cn/kubernetes/apt kubernetes-xenial main
    EOF
    

    這里需要注意,kubernetes-xenial不改變,版本代碼一改變,將無法在 apt 倉庫中找到 kubeadm 和kubelet。而 apt 倉庫中保存的是通用 DEB 包, Debian 和 Ubuntu 不區分版本都可以用,所以不要改動此處。我用的是 Debian 9,將其改為kubernetes-stretch后就遇到了此問題,改為kubernetes-xenial才順利安裝。

  4. 更新 apt 包索引,安裝 kubelet、kubeadm 和 kubectl,並鎖定其版本:

    sudo apt-get update
    sudo apt-get install -y kubelet kubeadm kubectl
    sudo apt-mark hold kubelet kubeadm kubectl
    

第一小節內容所有虛擬機上都要操作一次。

2 創建集群

2.1 查看 kubeadm 初始化所需鏡像

kubeadm 初始化時會拉取一些 docker 鏡像,查看fmd要的鏡像列表:

➜  ~ kubeadm config images list
k8s.gcr.io/kube-apiserver:v1.21.1
k8s.gcr.io/kube-controller-manager:v1.21.1
k8s.gcr.io/kube-scheduler:v1.21.1
k8s.gcr.io/kube-proxy:v1.21.1
k8s.gcr.io/pause:3.4.1
k8s.gcr.io/etcd:3.4.13-0
k8s.gcr.io/coredns/coredns:v1.8.0

可以看到,使用的鏡像倉庫是國內無法正常訪問的k8s.gcr.io,所以需要另想辦法完成鏡像拉取。

主節點需要拉取所有鏡像子節點只需要pausekube-proxy兩個鏡像就能正常工作。

2.2 拉取鏡像

配置好 docker 鏡像倉庫,通常都使用阿里雲加速。

docker hub 中逐一搜索對應的鏡像,並將所需標簽的鏡像 pull 到本地。

kube-apiserver為例,pull 到本地后,修改其本地標簽:

docker tag 8522d622299c k8s.gcr.io/kube-apiserver:v1.21.1

2.3 kubeadm 初始化

kubeadm需要使用 root 賬戶或 root 權限運行。

kubeadm 需要使用 systemd 來管理容器的 cgroup。

初始化前修改 docker 的 daemon.json,添加一行"exec-opts": ["native.cgroupdriver=systemd"],最終類似於:

{
	"exec-opts": ["native.cgroupdriver=systemd"],
	"registry-mirrors": [
		      "xxxxx.mirror.aliyuncs.com"  // 這里的鏡像倉庫需要改成自己的
	]
}
sudo systemctl daemon-reload
sudo systemctl restart docker

初始化命令:

sudo kubeadm init \
  --apiserver-advertise-address=192.168.31.221 \
  --service-cidr=10.96.0.0/12 \
  --pod-network-cidr=10.244.0.0/16
  • 第一個參數是主節點的 ip 地址
  • 第二個參數是為 service 另指定一個 ip 地址段
  • 第三個參數是為 pod 網絡指定的 ip 地址段

初始化成功后,最后會輸出類似下面的結果:

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

Alternatively, if you are the root user, you can run:

  export KUBECONFIG=/etc/kubernetes/admin.conf

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 192.168.31.221:6443 --token jc2ohi.sot5cfuqtvyx4bsk \
	--discovery-token-ca-cert-hash sha256:584a842a831fe3226341ce0f5812a94eb6042188e070e4946af7127c689cb13b

最后的命令就是子節點加入集群的命令,在子節點中以 root 權限運行即可:

sudo kubeadm join 192.168.31.221:6443 --token jc2ohi.sot5cfuqtvyx4bsk \
	--discovery-token-ca-cert-hash sha256:584a842a831fe3226341ce0f5812a94eb6042188e070e4946af7127c689cb13b

然后在主節點中用普通用戶運行下面的命令:

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

最后在主節點中查看全部節點:

➜  ~ kubectl get nodes
NAME         STATUS   ROLES                  AGE     VERSION
k8s-master   Ready    control-plane,master   10m     v1.21.1
k8s-node-1   Ready    <none>                 9m26s   v1.21.1
k8s-node-2   Ready    <none>                 9m2s    v1.21.1

集群中所有節點都已准備好了。

可選:

kubectl get cs已被棄用。

可以檢查一下集群是否正常:

kubectl get cs

可能你會得到下面的響應:

NAME                 STATUS      MESSAGE                                                                                       ERROR
scheduler            Unhealthy   Get "http://127.0.0.1:10251/healthz": dial tcp 127.0.0.1:10251: connect: connection refused
controller-manager   Unhealthy   Get "http://127.0.0.1:10252/healthz": dial tcp 127.0.0.1:10252: connect: connection refused
etcd-0               Healthy     {"health":"true"}

出現這種情況,是/etc/kubernetes/manifests下的kube-controller-manager.yamlkube-scheduler.yaml設置的默認端口是 0,在文件中注釋掉或刪除掉相關參數就可以了。

3 安裝 Pod 網絡附加組件

你必須部署一個基於 Pod 網絡插件的 容器網絡接口 (CNI),以便你的 Pod 可以相互通信。 在安裝網絡之前,集群 DNS (CoreDNS) 將不會啟動。

可用的第三方 CNI 列表見 CNI | Kubernetes

本文使用Flannel

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

安裝過程很快,完成后即可查看 coredns 狀態:

kubectl get pods -n kube-system

結果:

NAME                                 READY   STATUS    RESTARTS   AGE
coredns-54695bfdf-24whr              1/1     Running   0          29m
coredns-54695bfdf-p8knz              1/1     Running   0          29m
etcd-k8s-master                      1/1     Running   0          29m
kube-apiserver-k8s-master            1/1     Running   0          29m
kube-controller-manager-k8s-master   1/1     Running   0          29m
kube-flannel-ds-4w2lt                1/1     Running   0          16s
kube-flannel-ds-7x9w7                1/1     Running   0          16s
kube-flannel-ds-rgcxl                1/1     Running   0          16s
kube-proxy-gtf4d                     1/1     Running   0          29m
kube-proxy-pvhbp                     1/1     Running   0          28m
kube-proxy-s6xj9                     1/1     Running   0          28m
kube-scheduler-k8s-master            1/1     Running   0          29m

使用 API 檢查集群健康狀態:

curl -k https://localhost:6443/livez\?verbose
curl -k https://localhost:6443/readyz\?verbose
[+]ping ok
[+]log ok
[+]etcd ok
[+]poststarthook/start-kube-apiserver-admission-initializer ok
[+]poststarthook/generic-apiserver-start-informers ok
[+]poststarthook/priority-and-fairness-config-consumer ok
[+]poststarthook/priority-and-fairness-filter ok
[+]poststarthook/start-apiextensions-informers ok
[+]poststarthook/start-apiextensions-controllers ok
[+]poststarthook/crd-informer-synced ok
[+]poststarthook/bootstrap-controller ok
[+]poststarthook/rbac/bootstrap-roles ok
[+]poststarthook/scheduling/bootstrap-system-priority-classes ok
[+]poststarthook/priority-and-fairness-config-producer ok
[+]poststarthook/start-cluster-authentication-info-controller ok
[+]poststarthook/aggregator-reload-proxy-client-cert ok
[+]poststarthook/start-kube-aggregator-informers ok
[+]poststarthook/apiservice-registration-controller ok
[+]poststarthook/apiservice-status-available-controller ok
[+]poststarthook/kube-apiserver-autoregistration ok
[+]autoregister-completion ok
[+]poststarthook/apiservice-openapi-controller ok
livez check passed
[+]ping ok
[+]log ok
[+]etcd ok
[+]informer-sync ok
[+]poststarthook/start-kube-apiserver-admission-initializer ok
[+]poststarthook/generic-apiserver-start-informers ok
[+]poststarthook/priority-and-fairness-config-consumer ok
[+]poststarthook/priority-and-fairness-filter ok
[+]poststarthook/start-apiextensions-informers ok
[+]poststarthook/start-apiextensions-controllers ok
[+]poststarthook/crd-informer-synced ok
[+]poststarthook/bootstrap-controller ok
[+]poststarthook/rbac/bootstrap-roles ok
[+]poststarthook/scheduling/bootstrap-system-priority-classes ok
[+]poststarthook/priority-and-fairness-config-producer ok
[+]poststarthook/start-cluster-authentication-info-controller ok
[+]poststarthook/aggregator-reload-proxy-client-cert ok
[+]poststarthook/start-kube-aggregator-informers ok
[+]poststarthook/apiservice-registration-controller ok
[+]poststarthook/apiservice-status-available-controller ok
[+]poststarthook/kube-apiserver-autoregistration ok
[+]autoregister-completion ok
[+]poststarthook/apiservice-openapi-controller ok
[+]shutdown ok
readyz check passed

查看集群信息:

kubectl cluster-info
Kubernetes control plane is running at https://192.168.31.221:6443
CoreDNS is running at https://192.168.31.221:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.


免責聲明!

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



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