天天看點

kubeadm 安裝k8s1.環境初始化(每個節點都要安裝)2. 安裝配置master節點3 初始化node4 安裝dashboard5 删除節點問題

在學習《kubernets 權威指南》的時候,遇到了kubeadm安裝k8s叢集的問題。看書過了一遍,感覺似乎并沒有啥難點。本來想就不再手動去安裝一次了,但糾結了半天,我該死的強迫症還是讓我又回頭手動搭建了一次。這一搭建才發現,原來坑還是挺多的,是以就把自己的搭建過程寫了下來,供學習交流使用。

1.環境初始化(每個節點都要安裝)

1.1 安裝并配置docker

1.1.1 docker安裝

參考docker安裝安裝docker

1.1.2 配置cgroup driver

為啥要配置cgroup driver?因為使用systemd作為init system的Linux的發行版,使用systemd作為docker的cgroup driver可以確定伺服器節點在資源緊張的情況更加穩定。

編輯/etc/docker/daemon.json檔案(如果沒有則建立),添加如下内容:

{
  "exec-opts": ["native.cgroupdriver=systemd"]
}
           

1.1.3 配置國内registery

在/etc/docker/daemon.json的json段中,添加如下内容:

{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "registery-mirrors":["https://http://hub-mirror.c.163.com"]
}
           

最終如下:

{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "registery-mirrors":["https://http://hub-mirror.c.163.com"]
}
           

1.1.4 啟動檢查服務

啟動docker。

檢查cgroup driver是否生效:

docker info |grep Cgroup
    Cgroup Driver: systemd
           

1.2 初始化主機名和hosts

1.2.1 初始化主機名

有時候,某些伺服器的主機名會帶一些奇怪的字元串,為了環境更标準,我們非常建議将主機名初始化一下,比如:

hostnamectl set-hostname --static kubadmcli
           

1.2.2 配置hosts

根據初始化主機名那一步的主機名配置hosts:

172.24.15.212 kubadmcli
           
注:主機名或者hosts沒有的話,可能會出現如下提示:
[WARNING Hostname]: hostname "kubadmcli.novalocal" could not be reached
	[WARNING Hostname]: hostname "kubadmcli.novalocal": lookup kubadmcli.novalocal on 114.114.114.114:53: no such host
           

2. 安裝配置master節點

2.1 安裝kubeadm

2.1.1 配置yum源

在/etc/yum.repos.d/目錄下,建立kubernetes.repo檔案,添加如下内容:

[kubernetes]
name=kubernetes
baseurl=https://mirrors.tuna.tsinghua.edu.cn/kubernetes/yum/repos/kubernetes-el7-$basearch
enabled=1
gpgcheck=0
           

重建緩存:

yum clean all
yum makecache
           

2.1.2 安裝kubeadm

yum -y install kubelet kubeadm kubectl
           
注:這裡沒有指定版本,安裝後預設為最新版本。在配置kubeadm config的時候,我們會指定kubernetesVersion的版本。如果指定的版本和這裡安裝的版本不一緻,會出現如下報錯:
error execution phase preflight: [preflight] Some fatal errors occurred:
	[ERROR KubeletVersion]: the kubelet version is higher than the control plane version. This is not a supported version skew and may lead to a malfunctional cluster. Kubelet version: "1.21.0" Control plane version: "1.20.5"
[preflight] If you know what you are doing, you can make a check non-fatal with `--ignore-preflight-errors=...`
To see the stack trace of this error execute with --v=5 or higher
           
是以,我們建議,安裝kubelet、kubeadm和kubectl的時候,可以通過如下方式指定版本:
yum -y install kubelet-1.20.5 kubeadm-1.20.5 kubectl-1.20.5
           

安裝完成以後,由于叢集還沒有建立,是以目前還無法啟動kubelet服務。這個和《kubernets權威指南》上是不一樣的,指南上是說安裝完以後,就可以啟動kubelet服務了,但實際不行。我們可以把kubelet服務暫時加入開機啟動:

systemctl enable kubelet
           

2.2 配置kubeadm config

kubeadm config可以如下2種方式:

  • 配置檔案方式
  • 指令行傳參

2.2.1 配置檔案方式

我們可以通過如下方式,擷取預設配置:

kubeadm config print init-defaults > init.default.yaml
           

會在目前目錄下生成init.default.yaml檔案,内容如下:

apiVersion: kubeadm.k8s.io/v1beta2
bootstrapTokens:
- groups:
  - system:bootstrappers:kubeadm:default-node-token
  token: abcdef.0123456789abcdef
  ttl: 24h0m0s
  usages:
  - signing
  - authentication
kind: InitConfiguration
localAPIEndpoint:
  advertiseAddress: 1.2.3.4
  bindPort: 6443
nodeRegistration:
  criSocket: /var/run/dockershim.sock
  name: master
  taints:
  - effect: NoSchedule
    key: node-role.kubernetes.io/master
---
apiServer:
  timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta2
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns:
  type: CoreDNS
etcd:
  local:
    dataDir: /var/lib/etcd
imageRepository: k8s.gcr.io
kind: ClusterConfiguration
kubernetesVersion: v1.20.0
networking:
  dnsDomain: cluster.local
  serviceSubnet: 10.96.0.0/12
scheduler: {}
           

這裡,我們主要關注以下幾個内容:

apiVersion: kubeadm.k8s.io/v1beta2
imageRepository: k8s.gcr.io
kind: ClusterConfiguration
kubernetesVersion: v1.20.0
networking:
  serviceSubnet: 10.96.0.0/12
           

從預設配置中,我們可以看到

  • imageRepository使用的是k8s.gcr.io,我們建議改成國内的鏡像站
  • kubernetesVersion使用的是v1.20.0,我們可以改成自己想要的版本
  • networking中隻有serviceSubnet,可能我們還關心pod的網絡,pod網絡可以使用podSubnet指定

2.2.1.1 我們使用如下配置:

apiVersion: kubeadm.k8s.io/v1beta2
imageRepository: registry.aliyuncs.com/google_containers
kind: ClusterConfiguration
kubernetesVersion: v1.20.5
networking:
  podSubnet: 192.168.16.0/20
  serviceSubnet: 192.168.0.0/20
           

2.2.2 指令參數方法

對應到config方式,猶如下幾個參數預支對應:

  • –kubernetes-version:指定Kubernetes版本
  • –image-repository:由于kubeadm預設是從官網k8s.grc.io下載下傳所需鏡像,國内無法通路,是以這裡通過–image-repository指定為163鏡像站
  • –pod-network-cidr:指定pod網絡段
  • –service-cidr:指定service網絡段
  • –ignore-preflight-errors=Swap 将報錯資訊設定為Swap。當然,如果你環境配置得當,不需要它

指令行參數的方式,需要在下一步kubeadm init的時候一起執行

2.3 拉取鏡像

kubeadm config images pull --config=init.yaml
           
注:這一步在指南上是有的,不過我們也可以不執行,這樣在kubeadm init的時候,會自動下載下傳鏡像。
結果如下
[config/images] Pulled registry.aliyuncs.com/google_containers/kube-apiserver:v1.20.5
[config/images] Pulled registry.aliyuncs.com/google_containers/kube-controller-manager:v1.20.5
[config/images] Pulled registry.aliyuncs.com/google_containers/kube-scheduler:v1.20.5
[config/images] Pulled registry.aliyuncs.com/google_containers/kube-proxy:v1.20.5
[config/images] Pulled registry.aliyuncs.com/google_containers/pause:3.2
[config/images] Pulled registry.aliyuncs.com/google_containers/etcd:3.4.13-0
[config/images] Pulled registry.aliyuncs.com/google_containers/coredns:1.7.0
           

通過[docker images]檢視本地鏡像:

[[email protected] ~]# docker images
REPOSITORY                                                        TAG                 IMAGE ID            CREATED             SIZE
registry.aliyuncs.com/google_containers/kube-proxy                v1.20.5             5384b1650507        2 weeks ago         118MB
registry.aliyuncs.com/google_containers/kube-apiserver            v1.20.5             d7e24aeb3b10        2 weeks ago         122MB
registry.aliyuncs.com/google_containers/kube-controller-manager   v1.20.5             6f0c3da8c99e        2 weeks ago         116MB
registry.aliyuncs.com/google_containers/kube-scheduler            v1.20.5             8d13f1db8bfb        2 weeks ago         47.3MB
registry.aliyuncs.com/google_containers/etcd                      3.4.13-0            0369cf4303ff        7 months ago        253MB
registry.aliyuncs.com/google_containers/coredns                   1.7.0               bfe3a36ebd25        9 months ago        45.2MB
registry.aliyuncs.com/google_containers/pause                     3.2                 80d28bedfe5d        13 months ago       683kB
           

2.4 初始化master

2.4.1 使用配置檔案方式

kubeadm init --config=init.yaml
           

2.4.2 使用指令行傳參方式

kubeadm init --kubernetes-version=v1.20.5 \
             --image-repository=registry.aliyuncs.com/google_containers \
             --pod-network-cidr=192.168.16.0/20 \
             --service-cidr=192.168.0.0/20 \
            #--ignore-preflight-errors=Swap
           

結果如下:

init] Using Kubernetes version: v1.20.5
[preflight] Running pre-flight checks
[preflight] Pulling images required for setting up a Kubernetes cluster[certs]
......
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 172.24.14.91:6443 --token yvhauq.sxcuhh300d5vpvhy \
    --discovery-token-ca-cert-hash sha256:439f9df853943ead685dc63d8af0d04c32e7b9b8dc4e148e0fb41dab33997c11
           

從上述提示中我們可以獲得一下資訊:

  • initialize successfully說明已經初始化完
  • 叢集能被正常使用者正常使用,還需要執行提示中所說的内容。
  • kubectl apply -f 可以讓我們初始化網插件。支援網絡插件可以在給出的url裡查到
  • 最後一段包含了後面我們需要使用kubeadm join指令将來node加入到叢集所需要token等資訊
注:執行完kubeadm init以後,我們會發現,kubelet服務已經正常啟動了。如下:
[[email protected] ~]# systemctl status kubelet
● kubelet.service - kubelet: The Kubernetes Node Agent
   Loaded: loaded (/usr/lib/systemd/system/kubelet.service; enabled; vendor preset: disabled)
  Drop-In: /usr/lib/systemd/system/kubelet.service.d
           └─10-kubeadm.conf
   Active: active (running) since Wed 2021-05-12 10:38:33 CST; 7s ago
     Docs: https://kubernetes.io/docs/
 Main PID: 2949 (kubelet)
    Tasks: 18
   Memory: 38.0M
   CGroup: /system.slice/kubelet.service
           └─2949 /usr/bin/kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --k...

May 12 10:38:34 kubeadmcli kubelet[2949]: I0512 10:38:34.433442    2949 reconciler.go:224] opera...46")
......
May 12 10:38:39 kubeadmcli kubelet[2949]: E0512 10:38:39.213486    2949 kubelet.go:2188] Contain...ized
Hint: Some lines were ellipsized, use -l to show in full.
           

2.4.3 配置使用者環境

以root使用者為例,我們在/root/目錄下執行如下指令:

#root用的$HOME變量為/root
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
           

這個時候,我們使用如下指令,檢視一下叢集節點:

kubectl get nodes
           

結果如下:

NAME         STATUS     ROLES                  AGE     VERSION
kubeadmcli   NotReady   control-plane,master   3m30s   v1.20.5
           

從輸出中,我們可以發現,STATUS還處于[NotReady]的狀态,這是因為我們還沒有初始化網絡插件

2.5 初始網絡插件

以flannel為例,從提示文本中,我們可以看到,支援的網絡插件都位于:

https://kubernetes.io/docs/concepts/cluster-administration/addons/

打開以後,我們選擇flannel,會跳轉到flanne項目的githu位址。我們選擇進入到flannel項目的主目錄,裡面有flannel插件的使用方式。從說明中,我們可以看到**大于1.17**版本的k8s,使用如下yml檔案:

https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
注:如果網絡不好,可以使用wget或者curl先把yaml檔案下載下傳下來,放到本地執行。

注:該yaml配置檔案中, 有flannel的image倉庫位址。預設為**quay.io/coreos/**,如果自己的網絡不通,可以将改位址替換掉:

sed -i ‘s/quay.io\/coreos/registry.aliyuncs.com\/google_containers/g’ flannel.yaml。不過實際情況好像阿裡并沒有flannel的鏡像,可能是我使用的姿勢不對,後面慢慢研究吧。好在預設位址是通的。

我們将yml檔案儲存到本地,名為flannel.yaml。執行如下指令初始化flannel:

kubectl apply -f flannel.yaml
           

輸出如下:

podsecuritypolicy.policy/psp.flannel.unprivileged created
clusterrole.rbac.authorization.k8s.io/flannel created
clusterrolebinding.rbac.authorization.k8s.io/flannel created
serviceaccount/flannel created
configmap/kube-flannel-cfg created
daemonset.apps/kube-flannel-ds created
           

完成以後,本地鏡像會多出來flannel的鏡像:

[[email protected] ~]# docker images
REPOSITORY                                                        TAG                 IMAGE ID            CREATED             SIZE
...
quay.io/coreos/flannel                                            v0.13.1-rc2         dee1cac4dd20        2 months ago        64.3MB
...
           

這時候,我們再kubectl get nodes會發現,STATUS已經處于[Ready]狀态了

NAME         STATUS   ROLES                  AGE    VERSION
kubeadmcli   Ready    control-plane,master   111m   v1.20.5
           

3 初始化node

3.1 安裝kubelet和kubeadm

和主節點不一樣的是,node不需要安裝kubectl

yum -y install kubelet-1.20.5 kubeadm-1.20.5
           

3.2 初始化node

和初始化master一樣,我們可以通過如下兩種方式,來初始化node節點:

  • 使用配置檔案方式
  • 指令行傳參方式

3.2.1 指令行方式

初始化master節點的時候,從輸出資訊中,已經給出了初始化node節點的方式:

kubeadm join 172.24.15.212:6443 --token yvhauq.sxcuhh300d5vpvhy \
    --discovery-token-ca-cert-hash sha256:439f9df853943ead685dc63d8af0d04c32e7b9b8dc4e148e0fb41dab33997c11
           

3.1.2 配置檔案方式

同樣,我們可以通過kubeadm config print指令輸出init node節點的預設配置:

kubeadm config print join-defaults
           

輸出如下:

apiVersion: kubeadm.k8s.io/v1beta2
caCertPath: /etc/kubernetes/pki/ca.crt
discovery:
  bootstrapToken:
    apiServerEndpoint: kube-apiserver:6443
    token: abcdef.0123456789abcdef
    unsafeSkipCAVerification: true
  timeout: 5m0s
  tlsBootstrapToken: abcdef.0123456789abcdef
kind: JoinConfiguration
nodeRegistration:
  criSocket: /var/run/dockershim.sock
  name: kubeadmclinode02
  taints: null
           

我們主要關注如下幾項,并将apiServerEndpoint、token、tlsBootstrapToken改成master節點資訊。

apiVersion: kubeadm.k8s.io/v1beta2
discovery:
  bootstrapToken:
    apiServerEndpoint: 172.24.14.91:6443
    token: yvhauq.sxcuhh300d5vpvhy
    unsafeSkipCAVerification: true
  tlsBootstrapToken: yvhauq.sxcuhh300d5vpvhy
kind: JoinConfiguration
           

将上述内容儲存為init_node.yaml.然後使用如下指令初始化節點:

kubeadm join --config=init_node.yaml
           

上面兩種方法都出現如下輸出的時候,說明正确了:

This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.

Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
           

此時node上的kubelet也将正常運作。可能這時候你在master上執行[kubelet get nodes]的時候,該node還處于NotReady的狀态,别着急,一會就回重新整理過來。

4 安裝dashboard

以後有時間再說

5 删除節點

如果我們的某個節點出故障了,我們可以将節點剔出叢集,剔出叢集使用如下指令:

kubectl drain [your-node-name] --delete-local-data --force --ignore-daemonsets
kubectl delete node [your-node-name]
           

然後在節點上執行:

kubeadm reset
           

問題

問題1:kubeadm報錯:cannot automatically set CgroupDriver when starting the Kubelet: cannot execute ‘docker info -f {{.CgroupDriver}}’: executable file not found in $PATH

kubeadm的架構是:kubeapi、prox、ctl、manager等元件都是使用容器。是以主節點也是需要正确安裝容器服務的。并且需要配置容器伺服器的cgroup driver。

根據文檔CRI installation中的内容,對于使用systemd作為init system的Linux的發行版,使用systemd作為docker的cgroup driver可以確定伺服器節點在資源緊張的情況更加穩定,是以這裡修改各個節點上docker的cgroup driver為systemd。

解決方法

建立/etc/docker/daemon.json檔案,添加如下内容:

{
  "exec-opts": ["native.cgroupdriver=systemd"]
}
           
注:docker預設使用的cgroup driver為cgroupfs

配置以後,需要重新開機docker服務。

問題2:The connection to the server localhost:8080 was refused - did you specify the right host or port?

需要配置k8s的使用者環境:

#root用的$HOME變量為/root
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
           

繼續閱讀