kubeadm安裝kubernetes(v18.8.8)

  • 2020 年 8 月 22 日
  • 筆記

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 2C4G CentOS7.6 10.13.1.15 工作節點1
node2 2C4G CentOS7.6 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
[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": [
        "//1nj0zren.mirror.aliyuncs.com",
        "//kfwkfulq.mirror.aliyuncs.com",
        "//2lqq34jg.mirror.aliyuncs.com",
        "//pee6w651.mirror.aliyuncs.com",
        "//hub-mirror.c.163.com",
        "//docker.mirrors.ustc.edu.cn",
        "//f1361db2.m.daocloud.io",
        "//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 //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 //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及以下的版本。

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

 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

可以看到久違的成功

3.9.4.3 配置kubectl與api-server交互

[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

 可以看到版本是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

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

查組件狀態

[root@master1 ~]# kubectl get cs

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

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

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

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

4.  trouble shooting

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

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

拉鏡像失敗

執行拉鏡像腳本

[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

檢查前面的內核參數是否修改
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] The HTTP call equal to 'curl -sSL //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 //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 //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 //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 //localhost:10248/healthz' failed with error: Get http://localhost:10248/healthz: dial tcp: lookup localhost on 198.18.254.40:53: no such host.

檢查hosts文件,本機地址解析是否被刪除了
127.0.0.1 localhost

4.4 查看組件處於不健康狀態

[root@master1 ~]# kubectl get cs

發現controller-manager和scheduler狀態是不健康
如果節點都處於Ready後,實際上該狀態是不影響的。
因為kubeadm v1.18.6及以後的版本,是默認不開啟controller-manager的10252和scheduler的10251埠的,一般10251和10252是監聽在http上面,不需要證書認證,屬於不安全的埠。
查看機器監聽埠,發現默認這兩個埠沒有監聽

可以將/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

查看pod狀態,kube-proxy一直處於創建狀態,網路組建caclio一直處於初始化

kubect describe pod查看報錯:FailedCreatePodSandBox

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

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

查看pod狀態

 查看報錯的pod,發現cgroup報錯

 到node節點查看kubelet也在報錯

原因是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的一致。

4.7 worker節點加入節點後,網路組件一直不ready,一直重啟

該pod一直處於Running和CrashLoopBackOff交替狀態

查看pod日誌,發現有大量的健康檢查錯誤

到node節點上查看hosts文件,本機地址解析是否被刪除了
127.0.0.1 localhost

參考文檔

//kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/
//kubernetes.io/zh/docs/setup/production-environment/tools/kubeadm/install-kubeadm/

 

全劇終