使用 Virtualbox 创建 VM k8s 集群

前期准备

实验环境

  • macOS Catalina

整体流程

  1. 创建 master 虚拟机
  2. 安装 CentOS 系统
  3. 对系统进行必要的设置
  4. 安装 k8s 工作组件
  5. 克隆虚拟机,创建工作节点
  6. 创建集群

实践

(一) 创建 master 虚拟机

  1. 打开 Virtualbox,点击新建
    • 名称 k8s-master
    • 类型 Linux
    • 版本 Red Hat(64-bit)
  2. 使用建议的内存
  3. 创建虚拟硬盘
    • 现在创建虚拟硬盘
    • VDI(Virtualbox磁盘映像)
    • 动态分配
    • 6.00 GB

按照向导提示,选择上面指定的选项,到这里就完成了虚拟机的创建。

接下来还有一些必要的设置:

  1. 选中虚拟机,点击设置
  2. 系统 - 处理器 - 处理器数量 2
  3. 网络 - 连接方式 - 桥接网卡

这里将处理器数量设置为 2,是因为后面在启动 k8s 相关服务的时候,1核 CPU 是无法正常运行的。当然这个值随时可以更改,也可以遇到问题再修改。

选择桥接网卡模式,是为了将多个虚拟机组成一个局域网,使每个虚拟机能拥有自己独立的 IP

这样,master 节点的虚拟机就创建好了。

(二) 安装 CentOS 7

  1. 在 Virtualbox 主界面,选中创建好的虚拟机,点击[光驱]没有盘片,装载系统镜像
  2. 完成上一步操作后,点击启动
  3. 启动界面,选择 Install CentOS 7
  4. 语言和键盘建议选择 English (避免出现无法输入中文或者中文路径导致异常的情况),continue 继续
  5. 到了 Install Summary 的界面,这里要进行的操作比较多
    • DATE & TIME 修改为Asia/ShangHai
    • INSTALLATION DESTINATION 点进去直接 Done 再回来
    • NETWORK & HOST NAME 点进去,右侧的开关切换到 ON 的状态,然后下方 Host name 修改为 master.k8s
  6. 完成上一步设置后,可以点击 Begin Installation 开始安装
  7. 经过漫长的等待之后,就可以点击 REBOOT 重启了,这样系统就安装完成了

(三) 必要的系统设置

安装k8s相关组件的时候,有以下设置必须完成:

  • 关闭 SELinux
  • 关闭 Firewalld
  • 关闭 Swap
  • 开启 net.bridge.bridge-nf-call-iptables 内核选项

1. 关闭 SELinux

由于 VM 里面还没有安装 Vim,可以选择先安装,或者直接使用 Vi 进行编辑

修改 /etc/selinux/config, 将文件中的 SELINUX=enforcing 一行,修改为 SELINUX=permissive

2. 关闭 Firewalld

1
$ systemctl disable firewalld && systemctl stop firewalld

3. 关闭 Swap

1
$ swapoff -a && sed -i '/ swap / s/^/#/' /etc/fstab

可以使用 free -w 来查看完整的内存信息,可以看到 swap 的状态

4. 开启 net.bridge.bridge-nf-call-iptables 内核设置

这一步在这里还不能执行,需要等到启动 docker 和 kubelet 服务之后,才能正确执行

1
2
$ sysctl -w net.bridge.bridge-nf-call-iptables=1
$ echo "net.bridge.bridge-nf-call-iptables=1" > /etc/sysctl.d/k8s.conf

(四) 安装 k8s 工作组件

由于无法访问 google 源,并且 k8s 拉取镜像时会默认访问境外的 Docker 镜像仓库,从这里开始会遇到一些坑,需要手动去完成操作。

1. 添加 kubernetes yum源

这里选择阿里云的 yum 源

1
2
3
4
5
6
7
8
9
10
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
exclude=kube*
EOF

2. 安装必要组件

1
yum install -y docker kubelet kubeadm kubectl kubernetes-cni --disableexcludes=kubernetes

3. 启动必要服务

1
2
$ systemctl enable docker && systemctl start docker
$ systemctl enable kubelet && systemctl start kubelet

在这里执行 net.bridge.bridge-nf-call-iptables 的相关设置

(五) 克隆虚拟机,创建工作节点

  1. 首先 shutdown now 关闭当前 master 虚拟机
  2. 在 Virtualbox 主界面选中 master 虚拟机,右键,选择复制
    • 名称 m8s-node1
    • MAC 地址设定 为所有网卡重新生成 MAC 地址
    • 点击继续, 选择完全复制
  3. 参照步骤 2,克隆 k8s-node2
  4. 启动所有节点
  5. 使用 hostnamectl --static set-hostname node1.k8s 修改 node1 的名称(node2同理),重启就可以看到效果了
  6. 使用 ip addr 命令查看每一台虚拟机的 IP 地址,按照如下格式追加到所有节点的 /etc/hosts 文件中
1
2
3
192.168.0.104 master.k8s
192.168.0.105 node1.k8s
192.168.0.106 node2.k8s

(六) 创建集群

1. 手动拉取 docker 镜像

原本直接使用 kubeadm init 就可以初始化集群的 master 节点,但是由于 k8s 默认拉取镜像的源被墙,直接运行命令完全没办法继续。

因此,这里我们参考 这篇文章 的方法,使用 shell 脚本的方式手动获取镜像。

为了稍微少打几行字,我们可以 kubeadm config images list > manualpull.sh 将镜像名称输入到文件。

然后使用参考文章中给出的脚本手动拉取 docker 镜像。

脚本内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
images=(
kube-apiserver:v1.12.1
kube-controller-manager:v1.12.1
kube-scheduler:v1.12.1
kube-proxy:v1.12.1
pause:3.1
etcd:3.2.24
coredns:1.2.2
)

for imageName in ${images[@]} ; do
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName k8s.gcr.io/$imageName
docker rmi registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName
done

这里拉取的 docker 镜像每个节点都需要,因此可以选择先拉取镜像,再克隆节点。也可以通过 scp 发送脚本在各节点中单独拉取。

2. 集群 master 节点初始化

执行命令进行初始化

1
kubeadm init > initialization.log

这里把输出写入文件主要是因为 VM 里面不方便复制粘贴和滚屏,写文件比较容易编辑

3. 设置 kubectl 环境变量

1
$ export KUBECONFIG=/etc/kubernetes/admin.conf

将上面这行写入 /etc/profile 文件中,然后执行如下命令使修改生效

1
$ source /etc/profile

4. 将工作节点加入集群

执行 tail -n 2 > joinode.shinitialization.log 文件末尾两行的命令写入文件,发送到工作节点中。 格式如下:

1
kubeadm join 192.168.0.104:6443 --token ezalac.umfjciqd2lumq1yl --discovery-token-ca-cert-hash sha256:b104b5832b0ab52871161dec0156c7f2ee3456ed90900a153377a3155a6baed6

在 node1, node2 分别执行 bash joinode.sh

然后在 master 节点中,使用命令 kubectl get nodes 就可以查看到新加入的两个子节点了。

不过这个时候状态还是 Not Ready,还需要给 master 节点安装网络插件

5. 为 master 节点安装网络插件

1
$ kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')

6. 拷贝配置文件

首先将配置文件拷贝到工作节点 node1 和 node2

1
$ scp -P 22 /etc/kubernetes/admin.conf root@192.168.0.104:/etc/kubernetes/admin.conf

然后用和上面同样的方式,设置好环境变量。

以上设置完成之后,可以在 master 节点使用 kubectl get nodes 命令看到,节点都已经变成了 ready 的状态,这样,一个虚拟机组成的练手集群就搭建完成了。

参考资料

  1. 《Kubernetes in Action》 - Appendix B
  2. kubernetes安装(国内环境)- soolaugust[知乎]