使用 kubeadm 安装 kubernetes 集群

使用 kubeadm 安装 kubernetes 集群

对于需要学习 kubernetes 的同学来说,必须需要先学会如何搭建一个学习环境(即 kubernetes 集群),然后才能学习更多相关 kubernetes 及云原生的知识。目前随着社区的不断发展,kubernetes 的搭建已经非常方便,有基于 minikube/kind 等工具搭建的单节点集群,其搭建速度非常快(除去拉去镜像的时间,集群本身的搭建时间在分钟级别以内就能完成),但是单节点的 kubernetes 集群只能在本地学习的时候使用,没法部署到线上环境且也不支持多个节点的部署。而 kubeadm 正好为多个节点的 kubernetes 集群的搭建提供了工具,且能使用在大规模的生产环境中进行集群的搭建和部署。kubeadm 提供了简单便捷的方式来安装 kubernetes 集群,用户只需要使用 kubeadm 提供的简单命令来管理集群,如:

  • kubeadm init 命令用来初始化一个集群
  • kubeadm join 命令用来给已有的一个集群添加新的节点
  • kubeadm reset 命令用来给已有的集群做重置操作,相当于删出一个已有集群,注意这个操作会将已有集群中的相关配置全部删除,请谨慎操作!!
    下面的实操将以 kubeadm 来安装一个多个节点的 kubernetes 集群。kubeadm 的工作流程可参考:https://www.jianshu.com/p/029465088933

部署环境

本次部署环境在 ubuntu 系统上进行操作,系统版本为 22.04 版本。
必要条件:

  • master 节点:必须提供至少 2C CPU 和 8GiB 的内存资源。
  • node 节点:必须提供至少 1C CPU 和 1GiB 的内存资源。

安装步骤

初始化操作(所有节点都必须要执行)

所有的节点都必须执行下面脚本,才能安装成功。注意如下脚本都需要在 root 账户下运行。

  • 关闭系统服务
    在节点上创建文件 init.sh 脚本,将如下代码拷贝到 init.sh 里面执行初始化操作。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    #!/bin/bash

    echo "修改DNS配置如有需要"
    chattr -i /etc/resolv.conf
    cat <<EOF >> /etc/resolv.conf
    nameserver 10.10.10.10 # 改成自己需要的
    nameserver 10.10.10.11 # 改成自己需要的
    EOF


    ### 关闭swap分区
    echo "swapoff ## 临时生效"
    swapoff -a

    ## 永久生效可以编辑/etc/fstab文件 注释掉swap那行 https://www.idceval.com/111.html
    sed -ri 's/.*swap.*/#&/' /etc/fstab

    echo "关闭防火墙"
    ufw disable

    echo "关闭selinux"
    setenforce 0
    sed -i 's/enforcing/disabled/' /etc/selinux/config
  • 安装必要的软件
    在节点上创建文件 run.sh 脚本,将如下代码拷贝到 run.sh 里面执行安装必须的软件,如 docker、kubelet、kubeadm、kubectl 等工具。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    #!/bin/bash

    sudo apt update -y && sudo apt upgrade -y
    sudo apt-get install -y ca-certificates curl gnupg lsb-release
    sudo install -m 0755 -d /etc/apt/keyrings

    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
    sudo chmod a+r /etc/apt/keyrings/docker.gpg

    # Add the repository to Apt sources:
    echo \
    "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
    "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \

    sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
    sudo apt-get update

    sudo apt-get -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

    systemctl enable docker.service
    systemctl start docker.service

    cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
    overlay
    br_netfilter
    EOF

    sudo modprobe overlay
    sudo modprobe br_netfilter

    # sysctl params required by setup, params persist across reboots
    cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
    net.bridge.bridge-nf-call-iptables = 1
    net.bridge.bridge-nf-call-ip6tables = 1
    net.ipv4.ip_forward = 1
    EOF

    # Apply sysctl params without reboot
    sudo sysctl --system

    lsmod | grep br_netfilter
    lsmod | grep overlay

    sysctl net.bridge.bridge-nf-call-iptables net.bridge.bridge-nf-call-ip6tables net.ipv4.ip_forward

    cat <<EOF | sudo tee /etc/docker/daemon.json
    {
    "exec-opts": ["native.cgroupdriver=systemd"],
    "log-driver": "json-file",
    "log-opts": {
    "max-size": "100m"
    },
    "storage-driver": "overlay2"
    }
    EOF

    sudo systemctl enable docker
    sudo systemctl daemon-reload
    sudo systemctl restart docker

    sudo apt-get update
    sudo apt-get install -y apt-transport-https ca-certificates curl gpg

    curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg

    echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.28/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list

    sudo apt-get update
    sudo apt-get install -y kubelet kubeadm kubectl
    sudo apt-mark hold kubelet kubeadm kubectl

    # containerd config
    rm -rf /etc/containerd/config.toml
    containerd config default > /etc/containerd/config.toml
    sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
    systemctl daemon-reload && systemctl restart containerd

master 节点上搭建集群

部署服务

在一个 master 节点上创建新的 kubernetes 集群,部署服务之前请确保 初始化操作 都已完成。

  • 修改节点hostname,方便统一管理。

    1
    hostnamectl set-hostname k8s-master-01
  • 在 master 节点上通过 kube init 命令创建集群。

    1
    kubeadm init --image-repository=registry.aliyuncs.com/google_containers --pod-network-cidr=10.244.0.0/16 --kubernetes-version stable
  • 拷贝kube/config文件 这样在当前节点可以执行 kubectl指令。

    1
    2
    3
    mkdir -p $HOME/.kube
    sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
    sudo chown $(id -u):$(id -g) $HOME/.kube/config
  • 在master 节点上安装网络组件。

    1
    kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
  • 查看服务是否正常

    1
    kubectl get pods --all-namespaces

安装过程中遇到的问题

  • 由于 kubeadm 要在多个几节点创建集群,集群内 pod 之间的通信需要通过 kubernetes 的cni plugin 来提供,因此需要选择合适的 cni 插件来初始化集群,通过 –pod-network-cidr 参数来指定 pod 的网段。此处选择使用 flannel 网络插件,其他的可参考
  • 由于 kubeadm 初始化时,docker 默认选择 registry.k8s.io 镜像仓库拉取镜像,这个仓库对国内环境不可访问,因此可以指定默认仓库为阿里云的镜像仓库。
  • 经过上述两步操作后,集群搭建可能会成功,如果仍报 “registry.k8s.io/pause:3.6” 错误,是因为 kubelet 在创建容器时会去默认仓库(sandbox_image = “registry.k8s.io)拉取镜像,需要将 containerd 中的默认仓库地址修改为阿里云的地址(sandbox_image = “registry.aliyuncs.com/google_containers/pause:3.9”),可参考
  • 解决网络问题及默认仓库后,服务不一定正常启动,碰到的问题可参考,其主要原因是 kubelet 使用 etcd 的静态文件(/etc/kubernetes/manifests)创建静态 pod 的时候会失败,导致集群的 kube-apiserver、kube-controller-manager 等组件一直重启,可以使用 crictl ps -acrictl logs 查看相关容器的日志。最终的原因是 ectd 服务不断重启是由于 containerd 中的 /etc/containerd/config.toml 文件配置不正确,需要将文件中的 SystemdCgroup = false 改为 SystemdCgroup = true,再执行 systemctl restart containerd.service 重启 containerd 服务。

添加新的 master 到集群

添加新 master 节点到 kubernetes 集群之前请确保 初始化操作 都已完成,可参考

  • 修改节点hostname,方便统一管理。

    1
    hostnamectl set-hostname k8s-master-01
  • 在集群的 master 节点中执行如下命令,获取添加 node 的命令。

    1
    kubeadm token create --print-join-command

    然后,再在 node 节点上执行上述获取的命令,即可将新 node 添加到集群中

  • 在 master上生成用于新 master 加入的证书

    1
    kubeadm init phase upload-certs --experimental-upload-certs
  • 添加新 master,把新生成的 certificate key 加到 –experimental-control-plane –certificate-key 参数后,执行如下命令:

    1
    kubeadm join {apiserver-IP:Port} --token {token-key} --discovery-token-ca-cert-hash {ca-cert-key} --experimental-control-plane --certificate-key {certificate-key}

添加新 node 节点到集群

添加新节点到 kubernetes 集群之前请确保 初始化操作 都已完成。

  • 修改节点hostname,方便统一管理。

    1
    hostnamectl set-hostname k8s-node-01
  • 在集群的 master 节点中执行如下命令,获取添加 node 的命令。

    1
    kubeadm token create --print-join-command
  • 再在 node 节点上执行上述获取的命令,即可将新 node 添加到集群中:

    1
    kubeadm join {apiserver-IP:Port} --token {token-key} --discovery-token-ca-cert-hash {ca-cert-key}

卸载集群

  • 驱逐 master/node 上的所有 pod 以及服务。

    1
    kubectl drain <node_name> --ignore-daemonsets
  • 将 node 节点从集群中剔除出去

    1
    kubectl delete node <worker node name>
  • 执行清理工作,会删除 /etc/kubernetes 中的所有文件

    1
    kubeadm reset -f
  • 删除网络插件中的数据

    1
    rm /etc/cni/net.d/* -rf

参考:


使用 kubeadm 安装 kubernetes 集群
https://qingwei8.github.io/2024/01/05/cloud-native-k8s-install-kubeadm-2024-01-05-kubeadm/
作者
qingwei
发布于
2024年1月5日
许可协议