文本主要内容
按照最小集群的要求,我们需要 3 台一模一样的空白的 Linux 虚拟机做好准备,然后选择其中一台作为 Control Plane
注意
要继续阅读请先阅读 Hyper-V 创建虚拟机的前文
上述步骤完成之后只是创建了一台 Ubuntu 的虚拟机它具备了如下特性:
因此,接下来你要做的是给它安装 Kubernetes 所需要的组件,然后用 Hyper-V 自带的虚拟机复制功能,复制 2 台 Linux Server 当作 Worker Node
在复制虚拟机之前,我们还需要进行一些准备工作
$ sudo swapoff -a $ sudo rm /swap.img
$ sudo vi /etc/hostname
把 hostname 改成 kube-master
再修改 hosts
$ sudo vi /etc/hosts
改成如下内容
127.0.0.1 localhost 127.0.1.1 kube-master # The following lines are desirable for IPv6 capable hosts ::1 ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters
这里必须重启一次
$ sudo reboot # 这里必须重启第一次
$ sudo vi /etc/netplan/00-installer-config.yaml
把内容换成以下:
yaml# This is the network config written by 'subiquity' network: version: 2 renderer: networkd ethernets: eth0: addresses: - 192.168.137.100/24 nameservers: addresses: [192.168.137.1] # 这个是 Windows 宿主机在当前虚拟交换机下的 IP routes: - to: default via: 192.168.137.1
如此设置是为了让虚拟机能够依赖宿主机访问外网和 dns 解析。
注意1
这里需要格外的几点:
192.168.137.1: 这个 IP 是你之前设置 内网交换机时,Windows 宿主机在这个内网下的 IP
在 Windows 找到网络设置,如下图
注意2
192.168.137.100/24 : 这个 IP 是你当前虚拟机的 IP
在 Linux 虚拟机执行:
$ ip r
如下图
至此,第一步网络设置基本完成,接下来我们要安装 kubernetes 的运行时
注意
这里我选用了 docker 作为容器运行时,其实现在 Kubernetes 官方已经不推荐了,只是我已经习惯了 docker,因此我选用它
$ sudo apt-get update $ sudo apt-get install \ ca-certificates \ curl \ gnupg \ lsb-release $ sudo mkdir -p /etc/apt/keyrings $ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg $ echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null $ sudo apt-get update $ sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin $ sudo groupadd docker $ sudo usermod -aG docker $USER
执行上面的命令之后再次重启
$ sudo reboot # 这里必须第二次重启
https://github.com/Mirantis/cri-dockerd 项目是专门解决 docker 不遵循 kubernetes 标准容器协议问题而开发的组件,使得 kubernetes 能够和 docker 协作
这里有两种方法安装 cri-docker
打开 releases 界面https://github.com/Mirantis/cri-dockerd/releases 找到 cri-dockerd_0.2.6.3-0.ubuntu-jammy_amd64.deb
(注意版本号,找到 ubuntu-xxx_amd64.deb 的版本即可)
shell$ wget https://github.com/Mirantis/cri-dockerd/releases/download/v0.2.6/cri-dockerd_0.2.6.3-0.ubuntu-jammy_amd64.deb # 如果你宿主机有代理则可以如下 # curl -L https://github.com/Mirantis/cri-dockerd/releases/download/v0.2.6/cri-dockerd_0.2.6.3-0.ubuntu-jammy_amd64.deb --proxy "http://192.168.137.1:7890" --output cri-dockerd_0.2.6.3-0.ubuntu-jammy_amd64.deb
安装
shell$ sudo apt install ./cri-dockerd_0.2.6.3-0.ubuntu-jammy_amd64.deb
shell$ sudo reboot
官方教程里面建议你从源码进行编译,这里对大陆用户有一个难点就是编译的时候需要下载最新版本的 go 语言的编译器和运行时,所以我这里推荐你可以从 apt install 先安装 go 语言的环境:
shell$ sudo apt intsall golang-go
执行 sudo -s
获取 root 权限
shell$ git clone https://github.com/Mirantis/cri-dockerd.git $ cd cri-dockerd $ mkdir bin $ go build -o bin/cri-dockerd $ mkdir -p /usr/local/bin $ install -o root -g root -m 0755 bin/cri-dockerd /usr/local/bin/cri-dockerd $ cp -a packaging/systemd/* /etc/systemd/system sed -i -e 's,/usr/bin/cri-dockerd,/usr/local/bin/cri-dockerd,' /etc/systemd/system/cri-docker.service $ systemctl daemon-reload $ systemctl enable cri-docker.service $ systemctl enable --now cri-docker.socket
以上两种方式均可,安装完成之后校验服务运行状态:
shell$ sudo systemctl status docker $ sudo systemctl status cri-docker
shell[email protected]:~$ systemctl status docker ● docker.service - Docker Application Container Engine Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled) Active: active (running) since Tue 2022-11-08 08:12:00 UTC; 1min 54s ago TriggeredBy: ● docker.socket Docs: https://docs.docker.com Main PID: 759 (dockerd) Tasks: 81 Memory: 51.0M CPU: 1.176s CGroup: /system.slice/docker.service ├─ 759 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock [email protected]:~$ systemctl status cri-docker ● cri-docker.service - CRI Interface for Docker Application Container Engine Loaded: loaded (/lib/systemd/system/cri-docker.service; enabled; vendor preset: enabled) Active: active (running) since Tue 2022-11-08 08:12:00 UTC; 1min 59s ago TriggeredBy: ● cri-docker.socket Docs: https://docs.mirantis.com Main PID: 1715 (cri-dockerd) Tasks: 7 Memory: 11.2M CPU: 78ms CGroup: /system.slice/cri-docker.service └─1715 /usr/bin/cri-dockerd --container-runtime-endpoint fd:// lines 1-11...skipping... ● cri-docker.service - CRI Interface for Docker Application Container Engine Loaded: loaded (/lib/systemd/system/cri-docker.service; enabled; vendor preset: enabled) Active: active (running) since Tue 2022-11-08 08:12:00 UTC; 1min 59s ago TriggeredBy: ● cri-docker.socket Docs: https://docs.mirantis.com Main PID: 1715 (cri-dockerd) Tasks: 7 Memory: 11.2M CPU: 78ms CGroup: /system.slice/cri-docker.service └─1715 /usr/bin/cri-dockerd --container-runtime-endpoint fd://
这里我建议尽量在你宿主机 Windows 安装一个梯子,保证你能链接到 google 服务器:
假设你在 Windows 宿主机上有一个梯子监听的是 7890 端口 那么你在 Linux 虚拟机内部执行 apt 命令的时候都可以加一个参数让 Linux 虚拟机都可以享受到你宿主机梯子的便利
shell$ sudo apt install --option Acquire::HTTP::Proxy="http://192.168.137.1:7890"
注意
如下的命令行在执行 apt-get | update | install 的时候请一定记得加上如上的代理参数
shell$ sudo apt-get update $ sudo apt-get install -y apt-transport-https ca-certificates curl $ sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg $ echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | 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
注意
至此一台完全准备好的 Kubernetes Node 服务器已经就绪,它即可以作为 Control Plane 也可以作为 Worker Node
接下来要使用 Hyper-V 复制出 2 台机器,用来组成 Control Plane ✖ 1 + Worker Node ✖ 2 的最小集群
这里推荐阅读微软官方文档->https://learn.microsoft.com/zh-cn/windows-server/virtualization/hyper-v/deploy/export-and-import-virtual-machines
$ sudo vi /etc/hostname
把 hostname 改成 kube-worker-1
(第二台改成 kube-worker-2
)
再修改 hosts
$ sudo vi /etc/hosts
改成如下内容
127.0.0.1 localhost 127.0.1.1 kube-worker-1 # The following lines are desirable for IPv6 capable hosts ::1 ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters
(第二台改成 127.0.1.1 kube-worker-2
)
$ sudo reboot # 这里必须重启第一次
shell$ sudo vi /etc/netplan/00-installer-config.yaml
yaml# This is the network config written by 'subiquity' network: version: 2 renderer: networkd ethernets: eth0: addresses: - 192.168.137.101/24 nameservers: addresses: [192.168.137.1] routes: - to: default via: 192.168.137.1
kube-worker-1 的 IP 改为 192.168.137.101/24
kube-worker-2 的 IP 改为 192.168.137.102/24
两台机器再次分别重启
shell$ sudo reboot # 这里必须重启第一次
shell$ ssh [email protected]
要执行初始化集群,中国区的用户在这一步会卡住,因为 kubenetes 的官方镜像是存储在 google 的自己的服务器上的,因为众所周知的原因,我们有如下 2 个方案解决:
shell$ sudo vi /lib/systemd/system/docker.service
将 [Service] 的内容添加如下几行:
yamlEnvironment="HTTP_PROXY=http://192.168.137.1:7890" Environment="HTTPS_PROXY=http://192.168.137.1:7890" Environment="NO_PROXY=127.0.0.0/8,172.17.0.0/16"
然后重启 docker 服务
shell$ sudo systemctl daemon-reload $ sudo systemctl restart docker.service
shell$ sudo -s $ kubeadm init --cri-socket=unix:///var/run/cri-dockerd.sock --apiserver-advertise-address=192.168.137.100 --pod-network-cidr=10.244.0.0/16
安装成功之后,启用 kubectl
shell$ mkdir -p $HOME/.kube $ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config $ sudo chown $(id -u):$(id -g) $HOME/.kube/config
官方文档 -> https://github.com/flannel-io/flannel
shell$ kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
shell$ kubectl get nodes
shell$ [email protected]:~$ kubectl get nodes NAME STATUS ROLES AGE VERSION kube-master Ready control-plane 10m v1.25.3
来到 worker-1 机器内
shell$ ssh [email protected]
加入刚才创建的集群,如果你刚刚创建完集群,它会打印 kubeadm join 的命令行,让你在 worker node 上加入到集群,如果你超过了 1 天再来加入集群需要重新获取 token,在 control plane 节点上执行:
shell$ kubeadm token list
会得到如下输出
outputTOKEN TTL EXPIRES USAGES DESCRIPTION EXTRA GROUPS os00ln.sgr4pcrvpzlehze0 20h 2022-11-16T11:50:52Z authentication,signing The default bootstrap token generated by 'kubeadm init'. system:bootstrappers:kubeadm:default-node-token
然后获取一下获取 ca 证书 sha256 编码 hash 值
shell$ openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
output162e0ea67395442de0a5eeeeaa0a6bf0b0e8f543e557a05cdab68af8363500b2
再回到你要加入集群的 worker node 上执行如下:
shell$ sudo -s $ kubeadm join 192.168.137.100:6443 --token os00ln.sgr4pcrvpzlehze0 \ --discovery-token-ca-cert-hash sha256:162e0ea67395442de0a5eeeeaa0a6bf0b0e8f543e557a05cdab68af8363500b2 \ --cri-socket=unix:///var/run/cri-dockerd.sock
短暂的几秒之后,你就可以执行
shell$ kubectl get nodes
查看节点是否已经成功加入并且准备就绪。
官方文档 -> https://metallb.universe.tf/installation/
shell$ kubectl edit configmap -n kube-system kube-proxy
修改关键内容:
yamlapiVersion: kubeproxy.config.k8s.io/v1alpha1 kind: KubeProxyConfiguration mode: "ipvs" ipvs: strictARP: true
然后安装
shell$ kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.7/config/manifests/metallb-native.yaml
设置 IP pool 的范围,这里十分重要
创建文件 metallb-config.yaml
yamlapiVersion: metallb.io/v1beta1 kind: IPAddressPool metadata: name: first-pool namespace: metallb-system spec: addresses: - 192.168.137.120-192.168.137.180 --- apiVersion: metallb.io/v1beta1 kind: L2Advertisement metadata: name: use-eth0 namespace: metallb-system spec: ipAddressPools: - first-pool interfaces: - eth0
需要格外注意的配置项是:
yamladdresses: - 192.168.137.120-192.168.137.180
这个配置必须跟你宿主机以及你 3 台集群的 IP 都在一个子网段内
以及
yamlinterfaces: - eth0
必须跟你虚拟机的 IP 设置里面的
yamlnetwork: version: 2 renderer: networkd ethernets: eth0: addresses: - 192.168.137.100/24 nameservers: addresses: [192.168.137.1] # 这个是 Windows 宿主机在当前虚拟交换机下的 IP routes: - to: default via: 192.168.137.1
里面的
yamlethernets: eth0:
保持一致。
Q. 如何重置当前节点?比如退出集群?
## reset ```shell $ sudo kubeadm reset --cri-socket=unix:///var/run/cri-dockerd.sock