在《PVE 中虚拟化万兆网卡》中我有提到自己攒了台双路的机器放在家里,长期以来作为我远程的 Power 机器,在上面用 Docker-Compose 跑我的各种服务。从攒好机器到现在,反复多次搭建 Kubernetes,最终都放弃了:上手成本的确高。
是否要用 Kubernetes 取代 Docker-Compose ?
从理性的角度来说,Docker-Compose 完全胜任,简单,好用,完全没必要。然而在 Kubernetes 大行其道的今天,感性方面告诉我一定要跟着大家上高端的 Kubernetes…
最近有又冒出了想用 Kubernetes 的想法,在几经犹豫之后,最终决定本次一定不能中途放弃!!!为了减少搭建复杂度和资源的占用,本次选择了K3s。
The certified Kubernetes distribution built for IoT & Edge computing.
K3s 是一个 Kubernetes 认证的发行版,可以理解为一个轻量级的 K8s,K3s 的架构如下:
集群规划有两点需要考虑:
我的规划中,共4个节点,每个节点相同配置:4C 8G,细节如下:
HostName | CPU | Memory | Disk | OS | IP |
---|---|---|---|---|---|
k3s-server | 4 | 8G | 5G | Debian 10 (5.10.40-1~bpo10+1) | 192.168.2.21 |
k3s-worker-01 | 4 | 8G | 5G | Debian 10 (5.10.40-1~bpo10+1) | 192.168.2.22 |
k3s-worker-02 | 4 | 8G | 5G | Debian 10 (5.10.40-1~bpo10+1) | 192.168.2.23 |
k3s-worker-03 | 4 | 8G | 5G | Debian 10 (5.10.40-1~bpo10+1) | 192.168.2.24 |
以下为 k3s-server 的配置,其他 worker 节点同理,手动配置略麻烦,有兴趣的可以使用 ansible 批量操作。
k3s-server # cat /etc/hosts
...
192.168.2.6 nas # 我自建的NAS
192.168.2.22 k3s-worker-01
192.168.2.23 k3s-worker-02
192.168.2.24 k3s-worker-03
...
网络问题真的令人头疼,虽然 K3s 跑起来很简单,但避免不了后续需要从以上几个 Registry 中拉取镜像,所以建议第一步先 自建一个统一的代理,可以使用我整理的一键安装脚本,详见: registry on k3s
以下为该安装脚本的使用步骤:
拥有一台可以访问 gcr.io, k8s-gcr.io… 并且有公网 IP 的机器
在机器上拉取本仓库:
git clone https://github.com/eightpigs/proxy_registry_k3s
根据代理情况修改
run.sh
的前几行配置,默认创建 hub.docker.io, gcr.io, k8s-gcr.io 3个代理如果要代理 hub.docker.io 请自行更换以下信息:
- UserName :
pod-hub-registry.yaml:72
- Password:
pod-hub-registry.yaml:74
运行:
./run.sh
,运行结束后会有如下输出表示相关仓库配置成功:hub-k3s.io => HTTP/1.1 200 OK gcr-k3s.io => HTTP/1.1 200 OK k8s-gcr-k3s.io => HTTP/1.1 200 OK
使用 ansible 对自有 K3s 集群的所有节点配置代理
- 记得在
$ANSIBLE_INVENTORY
中配置 k3s 相关 hosts- 运行过程中,会询问 第一步 服务器的公网IP,填入即可
ansible-playbook ansible-add-registry.yaml -K
- Enjoy it
相比使用 kubeadm 搭建 K8s 集群的复杂度而言,K3s 集群搭建是真的简单,仅一行命令:
# 创建 server
k3s-server # curl -sfL https://get.k3s.io | sh -
# 运行 worker 并加入 集群
k3s-workers # curl -sfL https://get.k3s.io | K3S_URL=https://k3s-server:6443 K3S_TOKEN=mynodetoken sh -
看起来如此简单,但当我将集群配置好开始运行 Pod 时,不同节点的 Pod 无论如何也不能互相访问,困扰了我好几天,最终我选择放弃研究(开始萌生退意了),打算不再使用官方的一键安装脚本,转而手动安装并使用 Wireguard 来做 flannel-backend。
由于安装脚本较长,限于篇幅,可以在此 Github 仓库查看整理好的 Playbook,详见: k3s-ansible-playbooks
K3s 运行仅需要一个编译好的单文件,所以手动搭建过程主要分为2步:
# 下载 k3s 二进制文件 && 安装 Wireguard
- hosts: k3s
remote_user: dev
become: yes
gather_facts: False
tasks:
- set_fact:
k3s_version: "v1.21.2+k3s1"
ip_link: ens18
- name: Output K3s Version
debug: msg="{{ k3s_version }}"
when: k3s_version is defined
- name: Download K3s
shell: |
ls /usr/local/bin/k3s > /dev/null 2>&1 || wget "https://github.com/k3s-io/k3s/releases/download/{{ k3s_version }}/k3s" -O /usr/local/bin/k3s
chmod +x /usr/local/bin/k3s
when: k3s_version is defined
- name: Install Wireguard
shell: |
which wg > /dev/null 2>&1 || apt install wireguard -y
以下仅是 k3s-server,k3s-workers 安装详见 Github 仓库: k3s-ansible-playbooks
# 配置 k3s-server Systemd
- hosts: k3s-master
remote_user: dev
become: yes
gather_facts: False
tasks:
- name: Check K3s Server Installed
shell: ls /etc/systemd/system/k3s.service > /dev/null 2>&1 && echo 1 || echo 0
register: server_installed
- name: Get IP
shell: ip addr show {{ ip_link }} | grep inet | head -n 1 | awk '{print $2}' | sed -e 's/\/[0-9]\+//g'
register: ip_addr
- name: Output IP Addr
debug: msg="IP {{ ip_addr.stdout }}; Installed {{ server_installed.stdout }}"
when: ip_addr is defined and ip_addr.rc == 0
- name: Create K3s.service.env
command: touch /etc/systemd/system/k3s.service.env
when: server_installed is defined and server_installed.stdout == '0'
- name: Create K3s Server System Unit
when: ip_addr is defined and ip_addr.rc == 0 and server_installed is defined and server_installed.stdout == '0'
shell: |
cat > /etc/systemd/system/k3s.service <<EOF
[Unit]
Description=Lightweight Kubernetes
Documentation=https://k3s.io
Wants=network-online.target
[Install]
WantedBy=multi-user.target
[Service]
Type=notify
EnvironmentFile=/etc/systemd/system/k3s.service.env
KillMode=process
Delegate=yes
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNOFILE=1048576
LimitNPROC=infinity
LimitCORE=infinity
TasksMax=infinity
TimeoutStartSec=0
Restart=always
RestartSec=5s
ExecStartPre=-/sbin/modprobe br_netfilter
ExecStartPre=-/sbin/modprobe overlay
ExecStart=/usr/local/bin/k3s \
server \
--tls-san {{ ip_addr.stdout }} \
--node-ip {{ ip_addr.stdout }} \
--node-external-ip {{ ip_addr.stdout }} \
--no-deploy servicelb \
--write-kubeconfig-mode=644 \
--flannel-backend wireguard \
--kube-proxy-arg "proxy-mode=ipvs" "masquerade-all=true" \
--kube-proxy-arg "metrics-bind-address=0.0.0.0"
EOF
- name: Enable K3s Systemed
command: systemctl enable k3s --now
when: server_installed is defined and server_installed.stdout == '0'
- name: get server token
command: cat /var/lib/rancher/k3s/server/node-token
register: server_token
- name: output server token
debug: msg="{{ server_token.stdout }}"
when: server_token is defined and server_token.rc == 0
安装完成后,可以使用 kubectl get nodes -o wide
查看所有节点信息
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
k3s-worker-02 Ready <none> 46d v1.21.2+k3s1 192.168.2.23 <none> Debian GNU/Linux 10 (buster) 5.10.0-0.bpo.7-amd64 containerd://1.4.4-k3s2
k3s-master Ready control-plane,master 46d v1.21.2+k3s1 192.168.2.21 <none> Debian GNU/Linux 10 (buster) 5.10.0-0.bpo.7-amd64 containerd://1.4.4-k3s2
k3s-worker-01 Ready <none> 46d v1.21.2+k3s1 192.168.2.22 <none> Debian GNU/Linux 10 (buster) 5.10.0-0.bpo.7-amd64 containerd://1.4.4-k3s2
k3s-worker-03 Ready <none> 46d v1.21.2+k3s1 192.168.2.24 <none> Debian GNU/Linux 10 (buster) 5.10.0-0.bpo.7-amd64 containerd://1.4.4-k3s2
Next: K3s 上手 - NFS 存储配置