天天看點

kubeadm安裝kubernetes(v1.18.8)1. 前言2. 環境準備3. 實操過程4. trouble shooting參考文檔

1. 前言

kubernetes版本更新疊代非常快,上一篇寫kubernetes搭建時,版本還是v1.15.0,現在已經更新到v1.18。看kubernetes在github的官方倉庫,8月14日小版本已經到了v1.18.8。本篇文章基于kubeadm搭建kubernetes v1.18.8版。

本篇文章與上篇文章幾點不同之處:

  1. 作業系統采用CentOS。
  2. master采用單節點,如果要搭建多master高可用叢集可以參考上篇文章。
  3. 解決無法通路kubernetes官方容器鏡像倉庫問題,上篇文章直接從kubernetes官方拉取鏡像。
  4. docker加速,解決從dockerhub拉鏡像慢問題。
  5. kube-proxy開啟ivps,使用ipvs替代iptables轉發流量。
  6. 給出了一些常見的錯誤及排錯思路。

    話不多說,那就直奔主題,走起~~~

2. 環境準備

機器名稱 機器配置 機器系統 IP位址 角色
master1 2C4G CentOS7.6 10.13.1.11 主節點
node1 10.13.1.15 工作節點1
node2 10.13.1.16 工作節點2

說明:

硬體配置要求:2C2G +;

作業系統要求:CentOS7 +

防火牆說明:如果使用的是雲廠商的虛拟機,主節點安全組需放行tcp端口6443、2379-2380、10250-12025,工作節點安全組需放行tcp端口:10250、30000-32767

3. 實操過程

3.1 關閉防火牆和selinux

[root@master1 ~]# systemctl stop firewalld
[root@master1 ~]# setenforce 0
[root@master1 ~]# sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config           

3.2 關閉交換分區

[root@master1 ~]# swapoff -a
永久關閉,修改/etc/fstab,注釋掉swap一行           

3.3 修改hosts檔案

[root@master1 ~]# cat >> /etc/hosts << EOF
10.13.1.11 master1
10.13.1.15 node1
10.13.1.16 node2           

3.4 時間同步

[root@master1 ~]# yum install chrony -y
[root@master1 ~]# systemctl start chronyd
[root@master1 ~]# systemctl enable chronyd
[root@master1 ~]# chronyc sources           

3.5 修改核心參數

讓iptables能檢視橋接流量

[root@master1 ~]# cat > /etc/sysctl.d/k8s.conf << EOF
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
[root@master1 ~]# sysctl --system           

3.6 加載ipvs子產品

[root@master1 ~]# modprobe -- ip_vs
[root@master1 ~]# modprobe -- ip_vs_rr
[root@master1 ~]# modprobe -- ip_vs_wrr
[root@master1 ~]# modprobe -- ip_vs_sh
[root@master1 ~]# modprobe -- nf_conntrack_ipv4
[root@master1 ~]# lsmod | grep ip_vs
[root@master1 ~]# lsmod | grep nf_conntrack_ipv4
[root@master1 ~]# yum install -y ipvsadm           

3.7 安裝并配置docker

3.7.1 修改docker的yum源為阿裡源

[root@master1 ~]# wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
或者
[root@master1 ~]# yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo           

3.7.2 安裝docker

[root@master1 ~]# yum install -y docker-ce
[root@master1 ~]# docker --version
Docker version 19.03.12, build 48a66213fe
[root@master1 ~]# systemctl enable docker
[root@master1 ~]# systemctl start docker           

3.7.3 配置docker加速并修改驅動

網上有很多大佬無私地提供了一些dockerhub加速位址,可以選擇幾個使用。

[root@master1 ~]# cat /etc/docker/daemon.json 
{
    "exec-opts": ["native.cgroupdriver=systemd"],
    "registry-mirrors": [
        "https://1nj0zren.mirror.aliyuncs.com",
        "https://kfwkfulq.mirror.aliyuncs.com",
        "https://2lqq34jg.mirror.aliyuncs.com",
        "https://pee6w651.mirror.aliyuncs.com",
        "http://hub-mirror.c.163.com",
        "https://docker.mirrors.ustc.edu.cn",
        "http://f1361db2.m.daocloud.io",
        "https://registry.docker-cn.com"
    ]
}
[root@master1 ~]# systemctl restart docker
[root@master1 ~]# docker info | grep "Cgroup Driver"
 Cgroup Driver: systemd           

kubernetes官方建議docker驅動采用systemd,當然可以不修改,隻是kubeadm init時會有warning([WARNING IsDockerSystemdCheck]: detected "cgroupfs" as the Docker cgroup driver. The recommended driver is "systemd". Please follow the guide at https://kubernetes.io/docs/setup/cri/)

可以忽略,生産環境建議修改,因為更穩定。

3.8 安裝kubernents元件

3.8.1 配置kubernentes的yum源為阿裡源

因為國内無法通路kubernents的官方yum源,是以需要修改

[root@master1 ~]# cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg           

3.8.2 安裝元件

[root@master1 ~]# yum -y install kubelet kubeadm kubectl
[root@master1 ~]# kubelet --version
Kubernetes v1.18.8
[root@master1 ~]# systemctl start kubelet           

此時kubelet處于不斷重新開機狀态,因為叢集還沒有初始化,kubelet等待kubeadm初始化完成後運作狀态正常。

3.9 初始化叢集

3.9.1 檢視初始化需要的鏡像

[root@master1 ~]# kubeadm config images list
W0822 15:58:54.182176   25602 configset.go:202] WARNING: kubeadm cannot validate component configs for API groups [kubelet.config.k8s.io kubeproxy.config.k8s.io]
k8s.gcr.io/kube-apiserver:v1.18.8
k8s.gcr.io/kube-controller-manager:v1.18.8
k8s.gcr.io/kube-scheduler:v1.18.8
k8s.gcr.io/kube-proxy:v1.18.8
k8s.gcr.io/pause:3.2
k8s.gcr.io/etcd:3.4.3-0
k8s.gcr.io/coredns:1.6.7           

3.9.2 kubeadm init介紹

初始化叢集需使用kubeadm init指令,可以指定具體參數初始化,也可以指定配置檔案初始化。

可選參數:

--apiserver-advertise-address apiserver的監聽位址,有多塊網卡時需要指定

--apiserver-bind-port apiserver的監聽端口,預設是6443

--cert-dir 通訊的ssl證書檔案,預設/etc/kubernetes/pki

--control-plane-endpoint 控制台平面的共享終端,可以是負載均衡的ip位址或者dns域名,高可用叢集時需要添加

--image-repository 拉取鏡像的鏡像倉庫,預設是k8s.gcr.io

--kubernetes-version 指定kubernetes版本

--pod-network-cidr pod資源的網段,需與pod網絡插件的值設定一緻

--service-cidr service資源的網段

--service-dns-domain service全域名的字尾,預設是cluster.local

3.9.3 kubeadm指定具體參數初始化

因為以上鏡像都需要從kubernetes官方鏡像倉庫拉取,國内無法通路,是以需要設定國内的阿裡鏡像倉庫。

但是目前至發稿為止,阿裡的kube-apiserver、kube-controller、proxy鏡像隻更新到v1.18.6是以無法拉取到v1.18.8版鏡像。

如果你需要安裝的kubernetes版本是v1.18.6及以下那麼請繼續往下走,如果是v1.18.7及以上請跳過這一步進入下一步。

3.9.3.1 初始化

[root@master1 ~]# kubeadm init --kubernetes-version=v1.18.6  --apiserver-advertise-address 0.0.0.0 --image-repository registry.aliyuncs.com/google_containers --pod-network-cidr 192.168.0.0/16 --service-cidr 10.10.0.0/16
--kubernetes-version 請指定為你需要安裝的v1.18.6及以下的版本。           

初始化成功後會出現如下資訊

kubeadm安裝kubernetes(v1.18.8)1. 前言2. 環境準備3. 實操過程4. trouble shooting參考文檔

3.9.3.2 開啟ipvs

修改kube-proxy的configmap

[root@master1 ~]# kubectl edit cm kube-proxy -n=kube-system
修改mode: ipvs           

3.9.4 kubeadm指定配置檔案初始化

3.9.4.1 下載下傳kubernetes所需的全部鏡像

dockerhub上面已經有大佬已經上傳了最新的1.18.8鏡像,這裡我們直接下載下傳下來即可。

編寫下載下傳腳本

[root@master1 ~]# vim images.txt 
kube-apiserver:v1.18.8                 # node節點不需要
kube-controller-manager:v1.18.8 # node節點不需要
kube-scheduler:v1.18.8                # node節點不需要
kube-proxy:v1.18.8
pause:3.2
etcd:3.4.3-0                                  # node節點不需要
coredns:1.6.7                               # node節點不需要
[root@master1 ~]# vim images.sh 
for image in `cat images.txt`
do
  docker pull gotok8s/$image
  docker tag gotok8s/$image k8s.gcr.io/$image
  docker rmi gotok8s/$image
done
[root@master1 ~]# sh images.sh           

3.9.4.2 配置初始化檔案

[root@master1 ~]# kubeadm config print init-defaults > kubeadm.yaml
[root@master1 ~]# vim kubeadm.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: 0.0.0.0  # 修改為本機ip位址,多塊網卡可以指定具體ip
  bindPort: 6443
nodeRegistration:
  criSocket: /var/run/dockershim.sock
  name: master1
  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.18.8    # 修改為最新版本
networking:
  dnsDomain: cluster.local
  serviceSubnet: 10.10.0.0/16 # service網段
  podSubnet: 192.168.0.0/16   # pod網段,需與網絡插件網段一緻
scheduler: {}
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: ipvs                    # 開啟ipvs
[root@master1 ~]# kubeadm init --config=kubeadm.yaml           

可以看到久違的成功

kubeadm安裝kubernetes(v1.18.8)1. 前言2. 環境準備3. 實操過程4. trouble shooting參考文檔

3.9.4.3 配置kubectl與kube-apiserver互動

[root@master1 ~]# mkdir -p $HOME/.kube
[root@master1 ~]# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
[root@master1 ~]# sudo chown $(id -u):$(id -g) $HOME/.kube/config
至此可以使用kubectl檢視叢集節點狀态了
[root@master1 ~]# kubectl get nodes           
kubeadm安裝kubernetes(v1.18.8)1. 前言2. 環境準備3. 實操過程4. trouble shooting參考文檔

可以看到版本是v1.18.8最新版,但是master狀态是NotReady,因為此時還沒有安裝網絡元件。

3.9.5 安裝網絡元件

[root@master1 ~]# wget https://docs.projectcalico.org/v3.14/manifests/calico.yaml
[root@master1 ~]# kubectl apply -f calico.yaml           

此時再來看節點狀态,已經正常

kubeadm安裝kubernetes(v1.18.8)1. 前言2. 環境準備3. 實操過程4. trouble shooting參考文檔

查元件狀态

[root@master1 ~]# kubectl get cs           
kubeadm安裝kubernetes(v1.18.8)1. 前言2. 環境準備3. 實操過程4. trouble shooting參考文檔

3.10 worker節點加入叢集

[root@node1 ~]# kubeadm join 10.13.1.11:6443 --token abcdef.0123456789abcdef     --discovery-token-ca-cert-hash sha256:c214cf4c42766dd3d4ab2842c11efbefd54aa445993708ccdbdb8f111658445e
同樣的第二個worker節點加入叢集
此次檢視叢集狀态
[root@master1 ~]# kubectl get nodes
[root@master1 ~]# kubectl get pods -A           
kubeadm安裝kubernetes(v1.18.8)1. 前言2. 環境準備3. 實操過程4. trouble shooting參考文檔
kubeadm安裝kubernetes(v1.18.8)1. 前言2. 環境準備3. 實操過程4. trouble shooting參考文檔

如果join的token之前沒有記住,沒關系,在master重新生成一下

[root@master1 ~]# kubeadm token create --print-join-command           

可以看到節點和個元件的pod狀态均正常,至此叢集搭建完畢!

4. trouble shooting

出現了問題不可怕,因為如果不非常仔細,按照文檔敲下來很有可能會出錯。可怕的是,出錯了連去網上多搜尋一下都懶得搜,甚至開始抱怨。kubernets已經很成熟了,網上的資料非常多,出現的問題很多人也遇到過,在網上基本都有大佬給出回答。

4.1 初始化叢集長期卡住,最終報錯

拉鏡像失敗

[ERROR ImagePull]: failed to pull image k8s.gcr.io/kube-apiserver:v1.18.8: output: Error response from daemon: Get https://k8s.gcr.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
, error: exit status 1           
kubeadm安裝kubernetes(v1.18.8)1. 前言2. 環境準備3. 實操過程4. trouble shooting參考文檔

執行拉鏡像腳本

[root@master1 ~]# sh images.sh           

4.2 網橋報錯

W0822 17:05:25.135752    3367 configset.go:202] WARNING: kubeadm cannot validate component configs for API groups [kubelet.config.k8s.io kubeproxy.config.k8s.io]
[init] Using Kubernetes version: v1.18.8
[preflight] Running pre-flight checks
    [WARNING Service-Kubelet]: kubelet service is not enabled, please run 'systemctl enable kubelet.service'
error execution phase preflight: [preflight] Some fatal errors occurred:
    [ERROR FileContent--proc-sys-net-bridge-bridge-nf-call-iptables]: /proc/sys/net/bridge/bridge-nf-call-iptables contents are not set to 1
[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           
kubeadm安裝kubernetes(v1.18.8)1. 前言2. 環境準備3. 實操過程4. trouble shooting參考文檔

檢查前面的核心參數是否修改

net.ipv4.ip_forward = 1

net.bridge.bridge-nf-call-ip6tables = 1

net.bridge.bridge-nf-call-iptables = 1

4.3 kubelet-check健康檢查報錯

[kubelet-check] It seems like the kubelet isn't running or healthy.
[kubelet-check] The HTTP call equal to 'curl -sSL http://localhost:10248/healthz' failed with error: Get http://localhost:10248/healthz: dial tcp: lookup localhost on 198.18.254.40:53: no such host.
[kubelet-check] It seems like the kubelet isn't running or healthy.
[kubelet-check] The HTTP call equal to 'curl -sSL http://localhost:10248/healthz' failed with error: Get http://localhost:10248/healthz: dial tcp: lookup localhost on 198.18.254.40:53: no such host.
[kubelet-check] It seems like the kubelet isn't running or healthy.
[kubelet-check] The HTTP call equal to 'curl -sSL http://localhost:10248/healthz' failed with error: Get http://localhost:10248/healthz: dial tcp: lookup localhost on 198.18.254.40:53: no such host.
[kubelet-check] It seems like the kubelet isn't running or healthy.
[kubelet-check] The HTTP call equal to 'curl -sSL http://localhost:10248/healthz' failed with error: Get http://localhost:10248/healthz: dial tcp: lookup localhost on 198.18.254.40:53: no such host.
[kubelet-check] It seems like the kubelet isn't running or healthy.
[kubelet-check] The HTTP call equal to 'curl -sSL http://localhost:10248/healthz' failed with error: Get http://localhost:10248/healthz: dial tcp: lookup localhost on 198.18.254.40:53: no such host.
           
kubeadm安裝kubernetes(v1.18.8)1. 前言2. 環境準備3. 實操過程4. trouble shooting參考文檔

檢查hosts檔案,本機位址解析是否被删除了

127.0.0.1 localhost

4.4 檢視元件處于不健康狀态

[root@master1 ~]# kubectl get cs

kubeadm安裝kubernetes(v1.18.8)1. 前言2. 環境準備3. 實操過程4. trouble shooting參考文檔

發現controller-manager和scheduler狀态是不健康

如果節點都處于Ready後,實際上該狀态是不影響的。

因為kubeadm v1.18.6及以後的版本,是預設不開啟controller-manager的10252和scheduler的10251端口的,一般10251和10252是監聽在http上面,不需要證書認證,屬于不安全的端口。

檢視機器監聽端口,發現預設這兩個端口沒有監聽

kubeadm安裝kubernetes(v1.18.8)1. 前言2. 環境準備3. 實操過程4. trouble shooting參考文檔

可以将/etc/kubernetes/manifests/kube-controller-manager.yaml、/etc/kubernetes/manifests/kube-scheduler.yaml中--port=0注釋掉,再次kubect get cs元件狀态,這時都是ok了。

預設不監聽http端口,但是用戶端檢視元件狀态有預設是檢查http端口,不知道這算不算是kuberadm的一個小bug呢,哈哈~~~

4.5 worker節點加入叢集後長期處于NotReady

檢視node

kubeadm安裝kubernetes(v1.18.8)1. 前言2. 環境準備3. 實操過程4. trouble shooting參考文檔

檢視pod狀态,kube-proxy一直處于建立狀态,網絡元件calico一直處于初始化

kubeadm安裝kubernetes(v1.18.8)1. 前言2. 環境準備3. 實操過程4. trouble shooting參考文檔

kubect describe pod檢視報錯:FailedCreatePodSandBox

kubeadm安裝kubernetes(v1.18.8)1. 前言2. 環境準備3. 實操過程4. trouble shooting參考文檔

說明節點沒有pull基礎鏡像pause,到相應節點上面去拉取pause鏡像即可。

4.6 node節點運作一段時間後出現錯誤

檢視pod狀态

kubeadm安裝kubernetes(v1.18.8)1. 前言2. 環境準備3. 實操過程4. trouble shooting參考文檔

檢視報錯的pod,發現cgroup報錯

kubeadm安裝kubernetes(v1.18.8)1. 前言2. 環境準備3. 實操過程4. trouble shooting參考文檔

到node節點檢視kubelet也在報錯

kubeadm安裝kubernetes(v1.18.8)1. 前言2. 環境準備3. 實操過程4. trouble shooting參考文檔

原因是docker的驅動改為了systemd,但是kubelet的驅動沒有改

kubelet的驅動是在kubeadm join初始化的時候與docker保持一緻的,docker修改了,kubelet也需要修改

[root@node2 ~]# sed -i 's/--cgroup-driver=cgroupfs/--cgroup-driver=systemd/g' /var/lib/kubelet/kubeadm-flags.env 
[root@node2 ~]# systemctl restart kubelet           

同樣如果node節點處于NotReady,kubelet一直在重新開機,也需要檢查kubelet的cgroup驅動是否和docker的一緻。

kubeadm安裝kubernetes(v1.18.8)1. 前言2. 環境準備3. 實操過程4. trouble shooting參考文檔
kubeadm安裝kubernetes(v1.18.8)1. 前言2. 環境準備3. 實操過程4. trouble shooting參考文檔

4.7 worker節點加入節點後,網絡元件一直不ready,一直重新開機

參考文檔