开始之前先要安装 Docker ,安装教程可参考我的另一篇文章 CentOS环境下安装Docker

安装前准备

  1. 关闭 swap 交换区

    # 临时关闭
    sudo swapoff -a
    # 永久关闭: 把 /etc/fstab 中的swap注释掉
    sudo sed -i 's/.*swap.*/#&/' /etc/fstab

    或编辑文件 /etc/fstab ,将 swap 注释掉即可;

  2. 禁用 selinux

    # 临时关闭
    setenforce 0
    # 永久关闭
    sudo sed -i "s/^SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config

    或编辑文件 /etc/selinux/config

    SELINUX=disabled
  3. 关闭防火墙

    systemctl stop iptables
  4. 允许 iptables 检查桥接流量

    编辑文件 /etc/sysctl.d/k8s.conf

    vi /etc/sysctl.d/k8s.conf

    在文件中添加以下内容:

    net.bridge.bridge-nf-call-ip6tables = 1
    net.bridge.bridge-nf-call-iptables = 1
    net.ipv4.ip_forward = 1

    执行命令

    sysctl -p /etc/sysctl.d/k8s.conf
  5. 配置阿里云镜像源加速器

    加速器地址可登录阿里云官网,访问 镜像加速器 获取;

    sudo mkdir -p /etc/docker
    sudo tee /etc/docker/daemon.json <<-'EOF'
    {
      "registry-mirrors": ["https://1bk7ry6i.mirror.aliyuncs.com"]
    }
    EOF
    sudo systemctl daemon-reload
    sudo systemctl restart docker

安装K8S

配置安装源

sudo curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo

如果是 CentOS 8,则使用以下命令:

sudo curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-8.repo

添加K8S安装源,使用阿里云镜像;

cat <<EOF > /etc/yum.repos.d/kubernetes.repo 
[kubernetes] 
name=Kubernetes 
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
    http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

安装 kubeadm、kubelet、kubectl 组件

yum install -y kubeadm kubelet kubectl

若安装指定版本,在命令中添加版本号即可:

yum install -y kubeadm-1.18.0

启动 kubelet 服务

systemctl enable kubelet && systemctl start kubelet

初始化主节点

kubeadm init --image-repository registry.aliyuncs.com/google_containers --apiserver-advertise-address 192.168.1.3 --pod-network-cidr=10.244.0.0/16

云服务使用公网IP的使用以下命令:

kubeadm init --image-repository registry.aliyuncs.com/google_containers --pod-network-cidr=10.244.0.0/16

由于默认拉取镜像地址 k8s.gcr.io 国内无法访问,这里添加参数 --image-repository 指定阿里云镜像仓库地址。

注意:若主机是阿里云、腾讯云的ECS,--apiserver-advertise-address 设置的IP不能是公网IP,否则会初始化失败,原因及解决方法看以下的【错误汇总:2. Initial timeout of 40s passed.】,因此要写内网IP或不配置此参数。

可选参数说明:

  • --apiserver-advertise-address : master 和 worker 间能互相通信的 IP
  • --kubernetes-version : 指定版本
  • --token-ttl=0 :token 永不过期
  • --apiserver-cert-extra-sans:节点验证证书阶段忽略错误

此过程需要几分钟,请耐心等待。安装完成后,输出如下,其中会返回 node 节点添加到集群的命令,你只需复制保存即可,如果忘记可使用命令 kubeadm token create --print-join-command 查看。

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
...  

kubeadm join 192.168.1.3:6443 --token qzpag0.9to4x04asdd383o \
    --discovery-token-ca-cert-hash sha256:21611a589d89ad6218e7154asda5sda6e0bf78657dbeb9e10a80fd

要使用集群,我们还得按提示执行以下命令:

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

至此,master 节点安装完成,我们可以使用 kubectl get nodes 查看,此时 master 处于 NotReady 状态。

[root@lanweihong yum.repos.d]# kubectl get nodes
NAME                      STATUS     ROLES                  AGE     VERSION
lanweihong   NotReady   control-plane,master   6m24s   v1.18.0

等待一两分钟左右,再次使用命令 kubectl get node 查看,发现状态已为 Ready ,此时集群状态正常。

若初始化k8s集群失败,在下一次执行 kubeadm init 初始化命令前,先执行 kubeadm reset 命令重置节点,清理环境。否则再次 kubeadm init 初始化时会报 Port 10250 is in use 等错误。

kubeadm reset

安装 pod 网络附加组件 flannel

flannel Github地址:https://github.com/flannel-io/flannel

Kubernetes v1.17及以上 使用以下命令安装 flannel

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

配置 iptables 转发 IP ,使云服务器网络互通

由于初始化时删除了 --apiserver-advertise-address 参数,返回的节点加入集群命令为内网IP,但几个云服务器内网不互通,所以我们需要使用 iptables 进行 IP 转发,将主节点公网IP转发至内网IP,由于node节点加入集群的命令是内网IP,因此还需要配置 node 节点将主节点的内网IP转发至主节点的公网IP

# 在主节点 master
sudo iptables -t nat -A OUTPUT -d <主节点公网IP> -j DNAT --to-destination <主节点私有IP>

# 在 node 节点上
sudo iptables -t nat -A OUTPUT -d <主节点私有IP> -j DNAT --to-destination <主节点公网IP>

对于公网IP初始化集群时失败,网上还有另一种解决方案,就是修改 /etc/kubernetes/manifests/etcd.yaml 配置,将 --listen-client-urls--listen-peer-urls 的IP改为 0.0.0.0。这方法我试过几次,但每次都是失败,后来就采用 iptables 转发 IP 方式。此方案具体操作可看 [解决阿里云ECS下kubeadm部署k8s无法指定公网IP(作废)] 。

安装工作节点并加入集群

工作节点安装可参考以上操作,最后使用初始化 master 节点成功返回的添加命令即可,注意主节点云服务器安全组要开放 6443 端口,腾讯云服务器安全组出站要开放 6443 端口

kubeadm join <主节点公网IP>:6443 --token fcuu2m.1d01193ud9dfbzdx \
    --discovery-token-ca-cert-hash sha256:4e7f9e6717a87b6702b466ac3f8026818330463c7a1f4cf0f976f90054dc6038

命令后加参数 --v=2--v=5 可以查看日志。

若 token 超时,我们可在 k8s 主节点上执行以下命令重新生成

kubeadm token create --print-join-command

加入集群成功后,我们在主节点上使用 kubectl get nodes 命令查看节点信息:

[root@lanweihong lanweihong]# kubectl get nodes
NAME                      STATUS   ROLES    AGE     VERSION
i8mal9fj9qz   Ready    <none>   8m      v1.18.0
izk9mmdz        Ready    master   4h58m   v1.18.0
vm-123-a6     Ready    <none>   4m5s    v1.18.0

错误汇总

1. Port 10250 is in use

[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/
error execution phase preflight: [preflight] Some fatal errors occurred:
    [ERROR Port-10259]: Port 10259 is in use
    [ERROR Port-10257]: Port 10257 is in use
    [ERROR FileAvailable--etc-kubernetes-manifests-kube-apiserver.yaml]: /etc/kubernetes/manifests/kube-apiserver.yaml already exists
    [ERROR FileAvailable--etc-kubernetes-manifests-kube-controller-manager.yaml]: /etc/kubernetes/manifests/kube-controller-manager.yaml already exists
    [ERROR FileAvailable--etc-kubernetes-manifests-kube-scheduler.yaml]: /etc/kubernetes/manifests/kube-scheduler.yaml already exists
    [ERROR FileAvailable--etc-kubernetes-manifests-etcd.yaml]: /etc/kubernetes/manifests/etcd.yaml already exists
    [ERROR Port-10250]: Port 10250 is in use

解决方法

可执行以下命令才释放这些端口和文件即可:

kubeadm reset

2. Initial timeout of 40s passed.

使用 kubeadm init 初始化时使用公网IP配置会出现以下问题:

[kubelet-start] Starting the kubelet
[control-plane] Using manifest folder "/etc/kubernetes/manifests"
[control-plane] Creating static Pod manifest for "kube-apiserver"
[control-plane] Creating static Pod manifest for "kube-controller-manager"
[control-plane] Creating static Pod manifest for "kube-scheduler"
[etcd] Creating static Pod manifest for local etcd in "/etc/kubernetes/manifests"
[wait-control-plane] Waiting for the kubelet to boot up the control plane as static Pods from directory "/etc/kubernetes/manifests". This can take up to 4m0s
[kubelet-check] Initial timeout of 40s passed.

问题分析

因为阿里云主机网络是VPC,公网IP只能在控制台上看到,在系统里面看到的是内部网卡的IP,阿里云采用NAT方式将公网IP映射到ECS的位于私网的网卡上,所以在网卡上看不到公网IP,使用 ifconfig 查看到的也是私有网卡的IP,导致 etcd 无法启动。

解决方法

删除初始化命令中的 --apiserver-advertise-address 参数或使用内网IP,然后重新初始化,主机之间的通信采用 iptables 转发。

3. Failed to request cluster info, will try again

节点加入集群时出现以下错误:

[discovery] Failed to request cluster info, will try again: [Get https://<私有IP>:6443/api/v1/namespaces/kube-public/configmaps/cluster-info: dial tcp <私有IP>:6443: i/o timeout]

问题分析

使用参数 --v=5 查看详细的日志后发现,node 还是会去请求 master 内网IP的地址,所以肯定会连接超时;

I0411 16:28:33.060242    5363 join.go:447] [preflight] Fetching init configuration
I0411 16:28:33.060251    5363 join.go:485] [preflight] Retrieving KubeConfig objects
[preflight] Reading configuration from the cluster...
[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml'
Get https://<私有IP>:6443/api/v1/namespaces/kube-system/configmaps/kubeadm-config: dial tcp <私有IP>:6443: i/o timeout
failed to get config map

解决方法

因此我们需要在工作节点上进行IP转发,将master内网IP请求的地址转到master公网IP:

sudo iptables -t nat -A OUTPUT -d <master的私有IP> -j DNAT --to-destination <master的公网IP>

再次使用kubeadm join 加入集群,发现已连接到集群,在主节点上使用 kubectl get nodes 查看,可看到已连接节点信息;

[root@lanweihong lanweihong]# kubectl get nodes
NAME                      STATUS   ROLES    AGE     VERSION
i8mal9fj9qz   Ready    <none>   8m      v1.18.0
izk9mas82mdz  Ready    master   4h58m   v1.18.0
vm-123-a6     Ready    <none>   4m5s    v1.18.0

参考文献

  1. https://support.huaweicloud.com/dpmg-kunpengcpfs/kunpengk8s_04_0006.html

  2. https://github.com/kubernetes/kubeadm/issues/1390

  3. https://blog.csdn.net/curry10086/article/details/107579113

文章目录