• kubernetes集群基于kubeadm部署以及常见问题解决


    kubernetes有多种部署方式,目前主流的方式有kubeadm、minikube、二进制包。本文基于kubeadm安装。

    集群类型

    • Kubernetes集群大致分为两类:一主多从和多主多从。
      • 一主多从:一个Master节点和多个Node节点,搭建简单,但是有单机故障风险(Master),适合测试环境。
      • 多主多从:多台Master节点和多台Node节点,搭建复杂,安全性高,适用于生产环境。
        在这里插入图片描述

    主机规划

    本次环境搭建需要三台CentOS服务器(一主二从),然后在每台服务器中分别安装Docker(20.10.0)、kubeadm(1.21.10)、kubectl(1.21.10)和kubelet(1.21.10)。

    角色IP地址操作系统配置
    Master172.16.11.12CentOS7.8+,基础设施服务器72核CPU,62G内存,1TB硬盘
    node1172.16.11.13CentOS7.8+,基础设施服务器72核CPU,62G内存,1TB硬盘
    node2172.16.11.14CentOS7.8+,基础设施服务器72核CPU,62G内存,1TB硬盘

    环境初始化

    检查操作系统版本

    • 检查操作系统版本
    cat /etc/redhat-release
    
    • 1

    在这里插入图片描述

    • 要求操作系统的版本至少在7.5以上,如果版本低于7.5,需要升级系统内核。

    关闭防火墙

    • 关闭防火墙:
    systemctl stop firewalld
    
    • 1
    • 禁止防火墙开机启动:
    systemctl disable firewalld
    
    • 1

    设置主机名

    hostnamectl set-hostname <hostname>
    
    • 1
    # 设置 172.16.11.12 的主机名
    hostnamectl set-hostname Master
    # 设置 172.16.11.13 的主机名
    hostnamectl set-hostname node1
    # 设置 172.16.11.14 的主机名
    hostnamectl set-hostname node2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    主机名解析

    • 集群节点间的直接调用,需要在hosts (/etc/hosts)配置一下主机名解析。
    cat >> /etc/hosts << EOF
    172.16.11.12 master
    172.16.11.13 node1
    172.16.11.14 node2
    EOF
    
    • 1
    • 2
    • 3
    • 4
    • 5

    时间同步

    • kubernetes要求集群中的节点时间必须精确一致,所以在每个节点上添加时间同步:
    yum install ntpdate -y
    
    • 1
    ntpdate time.windows.com
    
    • 1

    关闭 SELinux

    SELinux(Security-Enhanced Linux) 是美国国家安全局(NSA)对于强制访问控制的实现,是 Linux历史上最杰出的新安全子系统。

    • 查看selinux是否开启:
    getenforce
    
    • 1
    • 永久关闭 SELinux ,需要重启:
    sed -i 's/enforcing/disabled/' /etc/selinux/config
    
    • 1
    • 临时关闭selinux,重启之后,无效:
    setenforce 0
    
    • 1

    关闭 swap 分区

    • 永久关闭 swap ,需要重启:
    sed -ri 's/.*swap.*/#&/' /etc/fstab
    
    • 1
    • 关闭当前会话的 swap ,重启之后无效:
    swapoff -a
    
    • 1

    将桥接的IPv4流量传递到iptables的链

    • 修改 /etc/sysctl.conf 文件:
    # 如果有配置,则修改
    sed -i "s#^net.ipv4.ip_forward.*#net.ipv4.ip_forward=1#g"  /etc/sysctl.conf
    sed -i "s#^net.bridge.bridge-nf-call-ip6tables.*#net.bridge.bridge-nf-call-ip6tables=1#g"  /etc/sysctl.conf
    sed -i "s#^net.bridge.bridge-nf-call-iptables.*#net.bridge.bridge-nf-call-iptables=1#g"  /etc/sysctl.conf
    sed -i "s#^net.ipv6.conf.all.disable_ipv6.*#net.ipv6.conf.all.disable_ipv6=1#g"  /etc/sysctl.conf
    sed -i "s#^net.ipv6.conf.default.disable_ipv6.*#net.ipv6.conf.default.disable_ipv6=1#g"  /etc/sysctl.conf
    sed -i "s#^net.ipv6.conf.lo.disable_ipv6.*#net.ipv6.conf.lo.disable_ipv6=1#g"  /etc/sysctl.conf
    sed -i "s#^net.ipv6.conf.all.forwarding.*#net.ipv6.conf.all.forwarding=1#g"  /etc/sysctl.conf
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    # 可能没有,追加
    echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
    echo "net.bridge.bridge-nf-call-ip6tables = 1" >> /etc/sysctl.conf
    echo "net.bridge.bridge-nf-call-iptables = 1" >> /etc/sysctl.conf
    echo "net.ipv6.conf.all.disable_ipv6 = 1" >> /etc/sysctl.conf
    echo "net.ipv6.conf.default.disable_ipv6 = 1" >> /etc/sysctl.conf
    echo "net.ipv6.conf.lo.disable_ipv6 = 1" >> /etc/sysctl.conf
    echo "net.ipv6.conf.all.forwarding = 1"  >> /etc/sysctl.conf
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    # 加载br_netfilter模块
    modprobe br_netfilter
    
    • 1
    • 2
    # 查看是否加载
    lsmod | grep br_netfilter
    
    • 1
    • 2
    # 生效
    sysctl --system
    
    • 1
    • 2

    开启ipvs

    • 在kubernetes中service有两种代理模型,一种是基于iptables,另一种是基于ipvs的。ipvs的性能要高于iptables的,但是如果要使用它,需要手动载入ipvs模块。

    • 安装ipset和ipvsadm:

    yum -y install ipset ipvsadm
    
    • 1
    • 执行如下脚本:
    cat > /etc/sysconfig/modules/ipvs.modules <<EOF
    #!/bin/bash
    modprobe -- ip_vs
    modprobe -- ip_vs_rr
    modprobe -- ip_vs_wrr
    modprobe -- ip_vs_sh
    modprobe -- nf_conntrack
    EOF
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 授权、运行、检查是否加载:
    chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -e nf_conntrack_ipv4
    
    • 1

    安装容器运行时(Docker)

    卸载Docker旧版本:

    sudo yum remove docker \
                      docker-client \
                      docker-client-latest \
                      docker-common \
                      docker-latest \
                      docker-latest-logrotate \
                      docker-logrotate \
                      docker-engine
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    安装 gcc 相关

    yum -y install gcc
    
    • 1
    yum -y install gcc-c++
    
    • 1
    • 安装所需要的软件包
    yum -y install yum-utils
    
    • 1

    安装Docker

    • 设置 stable 镜像仓库
    yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
    
    • 1
    • 更新 yum 软件包索引
    yum makecache fast
    
    • 1
    • 查看存储库中 Docker 的版本
    yum list docker-ce --showduplicates | sort -r
    
    • 1
    • 安装指定版本的 Docker(v20.10)
    yum -y install docker-ce-3:20.10.8-3.el7.x86_64 docker-ce-cli-1:20.10.8-3.el7.x86_64 containerd.io
    
    • 1
    • 启动 Docker
    # 启动 Docker 
    systemctl start docker
    
    • 1
    • 2
    # 开启自动启动
    systemctl enable docker
    
    • 1
    • 2
    • 验证 Docker 是否安装成功
    docker version
    
    • 1

    设置阿里云镜像加速

    sudo mkdir -p /etc/docker
    
    • 1
    sudo tee /etc/docker/daemon.json <<-'EOF'
    {
      "exec-opts": ["native.cgroupdriver=systemd"],	
      "registry-mirrors": [
        "https://du3ia00u.mirror.aliyuncs.com",
        "https://hub-mirror.c.163.com",
        "https://mirror.baidubce.com"
      ],
      "live-restore": true,
      "log-driver":"json-file",
      "log-opts": {"max-size":"500m", "max-file":"3"},
      "max-concurrent-downloads": 10,
      "max-concurrent-uploads": 5,
      "storage-driver": "overlay2"
    }
    EOF
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    sudo systemctl daemon-reload
    
    • 1
    sudo systemctl restart docker
    
    • 1

    安装kubernetes基础环境

    添加阿里云的YUM软件源

    cat > /etc/yum.repos.d/kubernetes.repo << EOF
    [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
    EOF
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    安装 kubelet 、kubeadm 和 kubectl

    yum install -y kubelet-1.21.10 kubeadm-1.21.10 kubectl-1.21.10
    
    • 1
    • Docker 使用的 cgroup drvier 和 kubelet 使用的 cgroup drver 一致,修改 /etc/sysconfig/kubelet 文件的内容:
    vi /etc/sysconfig/kubelet
    
    • 1
    # 修改
    KUBELET_EXTRA_ARGS="--cgroup-driver=systemd"
    KUBE_PROXY_MODE="ipvs"
    
    • 1
    • 2
    • 3
    • 设置为开机自启动即可,由于没有生成配置文件,集群初始化后自动启动:
    systemctl enable kubelet
    
    • 1

    下载 Kubernetes 安装所需镜像

    • 查看k8s所需镜像
    kubeadm config images list
    
    • 1
    docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.21.10
    docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager:v1.21.10
    docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:v1.21.10
    docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:v1.21.10
    docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.4.1
    docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:3.4.13-0
    docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:v1.8.0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • coredns 镜像重新打 tag :
    docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:v1.8.0 registry.cn-hangzhou.aliyuncs.com/google_containers/coredns/coredns:v1.8.0
    
    • 1

    注意:以上步骤kubernetes集群中的每个节点都需要执行,下面的步骤按节点执行。

    部署Master节点

    • 在 172.16.11.12 (Master)机器上部署 Kubernetes 的 Master 节点:
    # 由于默认拉取镜像地址k8s.gcr.io国内无法访问,这里需要指定阿里云镜像仓库地址
    kubeadm init \
      --apiserver-advertise-address=172.16.11.12 \
      --image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers \
      --kubernetes-version=v1.21.10 \
      --service-cidr=10.96.0.0/16 \
      --pod-network-cidr=10.244.0.0/16
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    注意:

    • apiserver-advertise-address 一定要是主机的 IP 地址。
    • apiserver-advertise-address 、service-cidr 和 pod-network-cidr 不能在同一个网络范围内。
    • 不要使用 172.17.0.1/16 网段范围,因为这是 Docker 默认使用的。

    根据提示消息,在Master节点上使用kubectl工具:

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

    部署Node节点

    • 在 172.16.11.13 和 172.16.11.14 执行如下命令:
    # 需要根据Master初始化完成后生成
    kubeadm join 172.16.11.12:6443 --token tluojk.1n43p0wemwehcmmh \
    	--discovery-token-ca-cert-hash sha256:c50b25a5e00e1a06cef46fa5d885265598b51303f1154f4b582e0df21abfa7cb
    
    • 1
    • 2
    • 3
    • 默认的 token 有效期为 2 小时,当过期之后,该 token 就不能用了,这时可以使用如下的命令在Master创建 token :
    kubeadm token create --print-join-command
    
    • 1
    # 生成一个永不过期的token
    kubeadm token create --ttl 0 --print-join-command
    
    • 1
    • 2

    部署CNI网络插件

    • Kubernetes 支持多种网络插件,比如 flannel、calico、canal 等,任选一种即可,本次选择 calico(在 172.16.11.12 Master节点上执行)。
    wget https://projectcalico.docs.tigera.io/v3.19/manifests/calico.yaml
    
    • 1
    kubectl apply -f calico.yaml
    
    • 1
    • 查看部署 CNI 网络插件进度:
    kubectl get pods -n kube-system
    
    • 1
    watch kubectl get pods -n kube-system
    
    • 1

    查看节点状态

    kubectl get nodes
    
    • 1

    默认情况下,只有 Master 节点才有 kubectl 命令。

    如果上述操作完成后,还存在某个节点处于 NotReady 状态,可以在 Master 将该节点删除。

    # 将 node1 节点删除 【master 节点上操作】 
    kubectl delete node node1
    
    # 将 node1 节点进行重置【在 node1 节点上操作】
    kubeadm reset
    # 将 node1 节点加入集群【在 node1 节点上操作】
    kubeadm join 172.16.11.12:6443 --token tluojk.1n43p0wemwehcmmh \
    	--discovery-token-ca-cert-hash sha256:c50b25a5e00e1a06cef46fa5d885265598b51303f1154f4b582e0df21abfa7cb
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    完全卸载Kubectl环境

    sudo yum remove -y kubelet kubeadm kubectl
    kubeadm reset -f
    modprobe -r ipip
    lsmod
    sudo rm -rf ~/.kube/
    sudo rm -rf /etc/kubernetes/
    sudo rm -rf /etc/systemd/system/kubelet.service.d
    sudo rm -rf /etc/systemd/system/kubelet.service
    sudo rm -rf /usr/bin/kube*
    sudo rm -rf /etc/cni
    sudo rm -rf /opt/cni
    sudo rm -rf /var/lib/etcd
    sudo rm -rf /var/etcd
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    常见问题解决方案

    • 查看kubelet状态
    systemctl status kubelet
    
    • 1
    • 查看kubelet系统日志
    journalctl -xefu kubelet
    
    • 1

    错误一

    • 在给 node1 节点使用 kubeadm join命令的时候,出现以下错误
    error execution phase preflight: [preflight] Some fatal errors occurred:
        [ERROR Swap]: running with swap on is not supported. Please disable swap
    
    • 1
    • 2
    • 错误原因是我们需要关闭 swap【可能是永久关闭 swap 时没有重启生效】
    # 关闭 swap
    # 临时关闭【立即生效】
    swapoff -a 
    # 永久关闭【重启生效】
    sed -ri 's/.*swap.*/#&/' /etc/fstab
    
    • 1
    • 2
    • 3
    • 4
    • 5

    错误二

    • 在给 node 节点使用 kubeadm join命令的时候,出现以下错误
    The HTTP call equal to 'curl -sSL http://localhost:10248/healthz' failed with error: Get http://localhost:10248/healthz: dial tcp [::1]:10248: connect: connection refused
    
    • 1
    • Docker是用yum安装的,docker的cgroup驱动程序默认设置为system。默认情况下Kubernetes cgroup为systemd,我们需要更改Docker cgroup驱动。
    vim /etc/docker/daemon.json
    
    {
      "exec-opts": ["native.cgroupdriver=systemd"]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    # 重启docker
    systemctl restart docker
    
    • 1
    • 2

    错误三

    • 部署CNI网络插件之后,使用kubectl get pod -n kube-system 发现有calico的pod启动不成功。使用kubectl describe pod calico-node-gdkvg -n kube-system 查看pod,发现pod出现以下错误。
    calico/node is not ready: BIRD is not ready: BGP not established withxxx
    
    • 1
    • 使用ifconfig 查看集群机器台机器的网卡分别是 enp6s0, eno1 发现都是 en开头 然后修改 calico 的配置文件:
    kubectl edit daemonset calico-node -n kube-system
    
    • 1
    • 对应位置,增加以下配置:(注意这儿需要根据自己的网卡前缀具体修改)
     - name: IP_AUTODETECTION_METHOD
          value: interface=ens*      
    
    • 1
    • 2
    • 修改后的配置文件为:

    在这里插入图片描述

    • 稍等一两分钟,calico的pod也就处于ready状态了。

    • 持续补充中…

    你知道的越多,你不知道的越多。

  • 相关阅读:
    DIYGW-UI-PHP是一款基于thinkphp framework和 element admin开发而成的前后端分离系统
    【realme x2手机解锁BootLoader(简称BL)】
    Apollo微服务配置中心详解
    Unity如何生成随机数(设置种子)
    RCA关键清洗流程
    家政服务小程序,家政系统开发
    使用EasyExcel 导入数据,失败原因数据导出
    会议通知和代开会议
    JAVA for 循环训练 Pattern
    MyBatis select标签
  • 原文地址:https://blog.csdn.net/qq_40722827/article/details/127909779