我在Mac上通过虚拟机的方式,搭建了一个k8s集群(1个master,2个node,版本1.26)。搭建过程中遇到了各方面的问题,踩了很多坑,参考了很多资料。在此将搭建过程详细记录下来,供参考。

环境介绍

硬件环境(MacBook Pro)

        CPU:M1 Pro

        内存:32G

        OS:macOS 13.1

虚拟机

        使用Vmware Fusion 13 Pro创建虚拟机,规格:

        CPU:2核

        内存:4G

        硬盘:20G

        OS:Ubuntu Server 20.04.5 (arm64)

创建虚拟机

使用Vmware Fusion 13 Pro创建虚拟机,该版本于2022年11月18日正式发布,支持 macOS Ventura 13,支持在 Apple Silicon Mac 上运行 ARM 虚拟机。安装时,可免费申请个人license,但激活后的版本是player版,没有克隆虚拟机等高级功能(此功能可极大方便后面创建多节点),想使用pro版需要使用pro版的license,可在网上搜到。

创建虚拟机的过程比较简单,就是下载系统镜像->在Vmware Fusion点击创建虚拟机->选择镜像->修改配置,就完成了虚拟机的创建。开机后,按照提示完成虚拟机操作系统安装,重启即可。(重启时注意要断开与镜像文件的连接,否则又会进入到安装页面)

原本想使用最新的Ubuntu Server22.04版本的操作系统,但启动后无法进入安装页面,无奈只好使用Ubuntu Server20.04。有人也遇到该问题,持续关注:https://askubuntu.com/questions/1444500/cannot-install-ubuntu-22-04-live-server-arm64-with-vmware-fusion-13-or-tech-pr

基础环境安装

虚拟机创建后,需要安装一些基本的软件,做一些基本的设置,以满足k8s的安装条件。

1.切换root用户

Bash
su root

如果没有创建root用户,使用以下命令设置root密码:

Bash
sudo passwd root

2.设置静态ip地址

打开/etc/netplan/00-installer-config.yaml文件,关闭dhcp,并设置固定的网关和IP地址:

Bash
network:
  ethernets:
    ens160:
      dhcp4: no
      addresses:
        - 172.16.254.132/24
      gateway4: 172.16.254.2
  version: 2

使配置生效:

Bash
netplan apply

3.修改主机名和host文件

修改主机名,改成有意义的名称,如主节点用m1、m2...,工作节点用n1、n2等:

Bash
vim /etc/hostname

修改hosts文件,将集群中主机名与ip写入该文件

Bash
vim /etc/hosts

类似这样:

Bash
172.16.254.130 m1
172.16.254.131 n1
172.16.254.132 n2

4.转发 IPv4 并让 iptables 看到桥接流量

参考k8s官网安装教程设置:

Bash
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

5.关闭交换空间swap

Bash
swapoff -a

通过top命令,查看swap空间是否为0K,判断是否关闭成功。

6.安装docker

根据官方文档,安装docker。可以使用脚本安装,方便快捷:

Bash
curl -fsSL https://get.docker.com -o get-docker.sh
DRY_RUN=1 sudo sh ./get-docker.sh

7.安装docker的容器运行时

Kubernetes 使用 容器运行时接口(Container Runtime Interface,CRI) 与容器运行时交互。当使用docker engine作为容器的运行时,有两种cri的方案:

1)使用docker engine底层的containerd作为容器运行时,k8s直接与containerd进行交互。此时无需安装其它插件,只需在containerd的配置文件中,将cri的禁用限制取消即可,这也是k8s推荐的方案:

打开containerd的配置文件,把containerd的禁用cri取消掉

Plain Text
vim /etc/containerd/config.toml

在 disabled_plugins = ["cri"] 前面加个# ,注释掉这一行

然后重启containerd

Plain Text
systemctl restart containerd

2)另一种方法是安装一个名为cri-dockerd的插件(前身是docker-shim)。它相当于是k8s与docker engine之间进行容器管理操作的一个接口转换器,cri-dockerd实现了cri的标准,k8s通过cri-dockerd间接地与docker engine交互。使用这种方法时,每个节点上运行的容器仍可通过熟悉的docker ps等命令查看和管理,但相比于直接使用底层的containerd作为运行时,也会带来一定的性能损耗。

具体的安装方法,可以参考github仓库页面,需要安装go环境。对于该方法产生的背景,可查看这篇文章,K8s 为什么要弃用 Docker?

以上两种方法,其cri对应的socket名称分别为:

点击图片可查看完整电子表格

8.设置cgroup驱动

k8s要求kubelet与容器运行时的cgroup驱动要相同,kubelet的cgroup驱动是systemd,而docker engine的默认驱动是cgroupfs。k8s推荐使用 systemd 驱动,不推荐 cgroupfs 驱动,因此需要将docker engine的cgroup驱动改为systemd。

修改方式很简单,执行下面的命令,在文件/etc/docker/daemon.json添加相应内容即可:

Bash
cat > /etc/docker/daemon.json <<EOF
{
  "exec-opts": ["native.cgroupdriver=systemd"]
}
EOF
systemctl daemon-reload
systemctl restart docker

9.安装k8s基本软件

通过阿里云的源,安装kubelet kubeadm kubectl三个软件:

Bash
apt-get update && apt-get install -y apt-transport-https
curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
EOF

apt-get update
apt-get install -y kubelet kubeadm kubectl

通过以上的步骤,就完成了基础环境的安装。使用虚拟机安装k8s的朋友,到这里可以将虚拟机进行关机并克隆,后续的操作,控制节点和工作节点会不一样。

注意:克隆后的虚拟机,需要修改网卡mac地址,修改hostname,修改ip地址,这里不再赘述。

k8s安装

管理节点

1.安装控制节点组件

在管理节点上运行下面的命令,安装k8s各个组件(pod)。

Bash
kubeadm init --pod-network-cidr=10.244.0.0/16 \
--cri-socket=unix:///var/run/cri-dockerd.sock \
--image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers \
--kubernetes-version=1.26.0

上面的命令中,--pod-network-cidr表示创建pod的网络号,--cri-socket表示使用的cri的socket地址(这里用的是cri-dockerd),--image-repository表示镜像仓库地址,避免网络不通的问题,--kubernetes-version则是指定需要安装的版本。

安装的过程会比较久,主要是拉取镜像时间较长

安装成功后,命令行会出现如下语句,该语句用于工作节点加入k8s集群时使用:

Bash
kubeadm join 172.16.254.130:6443 --token 8s2zmo.ufy8u3w99napxrmi \
        --discovery-token-ca-cert-hash sha256:5a29bb75ce3b605d16725bfcfb02f7405cc3802ebd171209b49a4ce762717e07

安装成功后,管理节点上运行了apiserver,scheduler,coredns,controller,etcd等pod,其中coredns处于未就绪状态,需要安装完网络组件后,才能正常使用。

2.安装网络组件

k8s支持很多cni网络组件,这里选择flannel这个组件,安装方法是使用kubectl apply命令:

Bash
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/v0.20.2/Documentation/kube-flannel.yml

等待kube-flannel的pod处于running状态,并且coredns的pod也处于running状态后,说明网络组件安装完成。

工作节点

1.加入集群

在工作节点运行管理节点安装完成后产生的命令:

Bash
kubeadm join 172.16.254.130:6443 --token 8s2zmo.ufy8u3w99napxrmi \
        --discovery-token-ca-cert-hash sha256:5a29bb75ce3b605d16725bfcfb02f7405cc3802ebd171209b49a4ce762717e07

等待一段时间后,即可在控制节点通过kubectl get node查看到新加入的节点,若节点的状态为Ready,则说明新的节点创建成功。

本地访问集群

如果要通过kubectl从宿主机访问安装在虚拟机里的k8s集群,则首先要在本地安装kubectl,然后将管理节点上的配置文件复制到本地:

Bash
mkdir ~/.kube
cp /etc/kubernetes/admin.conf  ~/.kube/config

遇到的问题

1.kubeadm init长时间未完成,执行中断

通过tail -f /var/log/syslog查看kubectl的日志可以看到,kubeadm init需要拉取pause:3.6的镜像,但由于网络原因,拉取失败。

解决方案:手动从国内仓库拉取镜像,然后使用docker tag命令改名,再次执行就不会报错了。

Bash
docker image pull registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.6
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.6 registry.k8s.io/pause:3.6

2.拉取镜像速度缓慢或无法拉取

由于网络原因,一些docker镜像的地址在国内无法访问,需要通过镜像仓库或者使用代理:

  • 配置镜像仓库:

打开/etc/docker/daemon.json,配置registry-mirrors参数:

Bash
{
  "registry-mirrors": [
    "https://registry.docker-cn.com",
    "http://hub-mirror.c.163.com",
    "https://docker.mirrors.ustc.edu.cn"
  ]
}

  • 使用代理

打开/usr/lib/systemd/system/docker.service,在[Service]的Type参数后,增加Environment参数,设置本机代理的地址:

Bash
Environment="HTTP_PROXY=http://172.16.254.1:7890"
Environment="HTTPS_PROXY=http://172.16.254.1:7890"
Environment="ALL_PROXY=socks5://172.16.254.1:7890"
Environment="NO_PROXY=127.0.0.0/8,172.17.0.0/16,172.29.0.0/16,10.244.0.0/16,192.168.0.0/16"

其中,172.16.254.1是物理机vmware虚拟网卡的地址,与虚拟机地址同一个网段。代理软件需开启“允许局域网连接”选项。

以上配置修改后均需重启docker:

Bash
systemctl daemon-reload
systemctl restart docker

3.kubeadm执行失败后重新执行

重新执行时,需要清理kubeadm init已经产生的一些操作:

Bash
kubeadm --cri-socket=unix:///var/run/cri-dockerd.sock reset
rm -rf /etc/kubernetes/manifests

然后再使用kubeadm init重新安装。

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐