重学kubernetes(二):使用kubeadm安装kubernetes

前言

之前使用rancher的命令快速构建了一个kubernetes集群,但是对于kubernetes内部组件的构建是缺失的,这次准备用kubernetes官方的工具kubeadm搭建一套kubernetes集群。
主要分为以下步骤:

  • 机器准备和环境准备
  • 安装kubeadm
  • 使用kubeadm创建集群
  • 使用kubeadm API定制组件
  • 高可用了解

机器准备和环境准备

这里准备了5台2核4G的机器,然后用1台作为主节点,其他4台作为工作节点。

准备开始

  • 一台兼容的 Linux 主机。Kubernetes 项目为基于 Debian 和 Red Hat 的 Linux 发行版以及一些不提供包管理器的发行版提供通用的指令。我这里使用的是centos7.9的5台机器
  • 每台机器 2 GB 或更多的 RAM(如果少于这个数字将会影响你应用的运行内存)。每台机器2核4G符合要求
  • CPU 2 核心及以上。每台机器2核4G符合要求
  • 集群中的所有机器的网络彼此均能相互连接(公网和内网都可以)。这些机器都在一个vpc内网。
  • 节点之中不可以有重复的主机名、MAC 地址或 product_uuid。使用ifconfig -asudo cat /sys/class/dmi/id/product_uuid q确认了MAC地址和product uuid是唯一的。
  • 开启机器上的某些端口。主要是6443端口,使用nc -l 6443 -v 监听6443端口,然后另一台机器 nc x.x.x.x 6443命令确认网络连通性,我这里直接在云主机后台修改安全组规则即可生效。
  • 禁用交换分区。为了保证 kubelet 正常工作,必须禁用交换分区。查看交换分区状态swapon --show, 临时禁用swapoff -a,永久禁用编辑 ​​/etc/fstab​​ 文件,注释 swap 类型的行。

容器运行时

为了在 Pod 中运行容器,Kubernetes 使用 容器运行时(Container Runtime)。
默认情况下,Kubernetes 使用 容器运行时接口(Container Runtime Interface,CRI) 来与你所选择的容器运行时交互。
如果你不指定运行时,kubeadm 会自动尝试通过扫描已知的端点列表来检测已安装的容器运行时。
在linux环境下需要以下的容器运行时套接字:

运行时 Unix 域套接字
containerd unix:///var/run/containerd/containerd.sock
CRI-O unix:///var/run/crio/crio.sock
Docker Engine(使用 cri-dockerd) unix:///var/run/cri-dockerd.sock

这里我是选择了docker ce ,但也改了containerd参数:

1
2
3
4
5
6
7
8
9
10
11
12
sudo yum remove docker   docker-client   docker-client-latest  docker-common   docker-latest   docker-latest-logrotate  docker-logrotate   docker-engine
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

sudo yum -y install docker-ce docker-ce-cli containerd.io docker-compose-plugin
##containerd systemd
mkdir /etc/containerd
containerd config default > /etc/containerd/config.toml
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml
systemctl enable containerd --now
systemctl restart containerd --now

为了让 Linux 节点的 iptables 能够正确查看桥接流量,请确认 sysctl 配置中的 net.bridge.bridge-nf-call-iptables 设置为 1。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF

sudo modprobe overlay
sudo modprobe br_netfilter

# 设置所需的 sysctl 参数,参数在重新启动后保持不变
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

# 应用 sysctl 参数而不重新启动
sudo sysctl --system

安装kubeadm、kubelet 和 kubectl

需要在每台机器上安装以下的软件包:

  • kubeadm:用来初始化集群的指令。
  • kubelet:在集群中的每个节点上用来启动 Pod 和容器等。
  • kubectl:用来与集群通信的命令行工具。
    使用以下命令安装以上三个工具(这里使用阿里云的镜像站,谷歌官方的因为网络原因无法正常连接)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
    [kubernetes]
    name=Kubernetes
    baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-\$basearch
    enabled=1
    gpgcheck=1
    gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
    exclude=kubelet kubeadm kubectl
    EOF

    # 将 SELinux 设置为 permissive 模式(相当于将其禁用)
    sudo setenforce 0
    sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config

    sudo yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes

    sudo systemctl enable --now kubelet


    对于kubeadm安装的问题排查可以使用下面的链接查询 troubleshooting

使用kubeadm创建集群

下载集群镜像(可忽略)

由于国内网络原因,我这里准备了一个镜像拉取脚本用于拉取阿里云镜像替换默认谷歌镜像:

1
2
3
4
5
6
7
8
9
#!/bin/bash
url=registry.cn-hangzhou.aliyuncs.com/google_containers
version=v1.25.4
images=(`kubeadm config images list --kubernetes-version=$version|awk -F '/' '{print $2}'`)
for imagename in ${images[@]} ; do
ctr images pull $url/$imagename
ctr images tag $url/$imagename registry.k8s.io/$imagename

done

将脚本复制到机器并授权执行:
1
2
3
chmod u+x image.sh
./image.sh
ctr images

执行后如图所示:images
在每台机器都如此操作一次。

初始化master

通过ifconfig -a 命令确定master节点的内网ip和公网ip,然后使用以下命令初始化master节点,我这里使用的是flannel网络,所以是10.244.0.0:

1
kubeadm init  --image-repository=registry.aliyuncs.com/google_containers --apiserver-advertise-address x.x.x.x --apiserver-cert-extra-sans x.x.x.x --pod-network-cidr 10.244.0.0/16   --v=5

apiserver-advertise-address指定master的interface,pod-network-cidr指定Pod网络的范围
apiserver-cert-extra-sans strings用于 API Server 服务证书的可选附加主题备用名称(SAN)。可以是 IP 地址和 DNS 名称,这里将公网ip加入证书信息,以便公网连接api server。
中间还是有pause镜像问题,单独拉取了pause镜像:

1
2
3
ctr -n k8s.io image pull registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.6
ctr -n k8s.io image tag registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.6 k8s.gcr.io/pause:3.6
ctr -n k8s.io image tag registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.6 registry.k8s.io/pause:3.6

同时centos有libseccomp版本问题,需要手工安装高版本:
1
2
wget http://rpmfind.net/linux/centos/8-stream/BaseOS/x86_64/os/Packages/libseccomp-2.5.1-1.el8.x86_64.rpm
rpm -ivh libseccomp-2.5.1-1.el8.x86_64.rpm

安装完毕截图如下:
images
接着按照提示执行复制kube config:

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

安装pod网络

初始化master之后就是安装集群网络了,我这里使用的是flannel网络:

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

images

Node节点加入集群

接着便是安装kubeadm的提示安装node节点

1
2
kubeadm join x.x.x.x:6443 --token xxxx   --discovery-token-ca-cert-hash sha256:xxxxxx


执行完毕如图:
images

最终在master 节点执行kubectl get nodes结果如图,一个主节点四个工作节点的kubernetes集群就安装好了:

images