一、部署前准备
1、创建虚拟机并做基本配置
在Proxmox中,通过Rocky Linux 10的模版克隆虚拟机
qm clone 103 104 \
--name master02 \
--full 1 \
--storage local-lvm \
--format raw为虚拟机分配IP,DNS和搜索域
qm set 104 --ipconfig0 ip=192.168.2.180/24,gw=192.168.2.101 --nameserver 192.168.3.200 --searchdomain k3s.ocp.local启动并为虚拟机添加上IP地址的Tag
qm start 104
qm set 104 --tags "192.168.2.180" 2、虚拟机磁盘扩容
通过模版部署的虚拟机磁盘默认只有10G,扩容到30G,以备使用
qm resize 104 scsi0 +20G
parted -f -s /dev/sda resizepart 4 100%
pvresize /dev/sda4
lvextend -l +100%FREE /dev/rocky/lvroot
xfs_growfs /
df -hT 3、kube-vip的介绍和使用
作为传统的Keepavlied+HAProxy方案的替代方案,kube-vip在一个服务中同时实现了VIP的管理和负载均衡。其在控制平面节点上(其会作为管理节点上的静态Pod运行)提供了K8S原生的HA负载均衡,我们不需要再在外部配置HAProxy+Keepalived来实现集群的高可用。注意kube-vip除了提供控制平面HA功能,还可以为K8S集群提供LoadBalancer Service。其可以工作在:
- 二层:使用ARP和选举机制实现。当某个实例被选举为leader时,它会将VIP绑定到指定的接口同时发送免费ARP报文到网络中以宣告VIP和MAC的绑定关系。当leader节点宕掉后,会选举新的leader节点,绑定VIP到指定的接口并发送新的免费ARP报文绑定VIP到自己的MAC
优缺点:这种模式仅适用于节点在同一个二层网络环境中,无法跨越子网
- 三层:使用BGP实现。在此模式下,每个节点作为一个BGP路由器,其上的kube-vip(使用gobgpd)会将VIP绑定到节点的网络接口上(通常绑定到lo接口上),然后向外部路由器宣告VIP。多个管理节点上的kube-vip都会进行BGP宣告,外部路由器根据BGP的路由选择选择目标节点,由于每个路由器都宣告了VIP的路由,所以外部路由器的路由表中有3条到VIP的路由条目,这样就实现了流量的负载均衡。当一个Master节点故障时,剩下的2条路由条目可以继续处理流量,这样实现了高可用
优缺点:这种模式可以跨越子网,适合复杂的网络拓扑。同时其切换延迟比ARP模式优秀(BGP模式在0.02-0.06ms,ARP模式在0.2-0.4ms)。但是其需要设备支持BGP,配置复杂度较高
- Routing Tables:可以支持高级的路由特性,例如ECMP等,其允许kube-vip管理节点路由表中地址的添加和删除,以让节点可以接受正确的流量
下载部署kube-vip需要设置的RBAC文件,导出VIP和绑定VIP的网卡的环境变量,同时设置运行kube-vip容器的命令别名
cd k3s-offline/
curl https://kube-vip.io/manifests/rbac.yaml > kube-vip.yaml
export VIP=192.168.3.184
export INTERFACE=ens192
KVVERSION=$(curl -sL https://api.github.com/repos/kube-vip/kube-vip/releases | jq -r ".[0].name")
alias kube-vip="docker run --network host --rm ghcr.io/kube-vip/kube-vip:$KVVERSION"生成kube-vip的静态Pod所需的manifest
echo "---" >> kube-vip.yaml
kube-vip manifest daemonset \
--image artifactory.ocp.local/gitlab/k3s/kube-vip \
--interface $INTERFACE \
--address $VIP \
--inCluster \
--taint \
--controlplane \
--services \
--arp \
--leaderElection >> kube-vip.yaml在使用cilium作为CNI时,由于kube-vip部署时还没有CNI,导致其无法通过API Server进行锁的获取以进行选举,这里要手动修改manifests配置,设置API Server的地址为本地
vim /var/lib/rancher/k3s/server/manifests/kube-vip.yaml
containers:
env:
- name: KUBERNETES_SERVICE_HOST
value: "127.0.0.1"
- name: KUBERNETES_SERVICE_PORT
value: "6443"4、离线部署介质的准备
创建离线介质存储目录,并下载K3S集群部署所需的离线介质
mkdir -pv k3s-offline && cd $_
curl -LO https://github.com/k3s-io/k3s/releases/download/v1.35.1%2Bk3s1/k3s-airgap-images-amd64.tar.gz
curl -LO https://github.com/k3s-io/k3s/releases/download/v1.35.1%2Bk3s1/k3s
curl -Lo k3s-install.sh https://get.k3s.io/
chmod +x k3s k3s-install.sh把离线介质分发到各个节点,同时在Master节点创建kube-vip静态Pod manifests存储目录,并把kube-vip的资源定义文件拷贝到其中
ssh root@192.168.3.180 "mkdir -pv /var/lib/rancher/k3s/server/manifests/"
scp kube-vip.yaml root@192.168.3.180:/var/lib/rancher/k3s/server/manifests/ 5、集群节点初始化
关闭swap
swapoff -a
sed -i '/rl-swap/s/^/#/' /etc/fstab加载必要的内核模块
cat >> /etc/modules-load.d/k8s.conf <<-EOF
overlay
br_netfilter
EOF
cat /etc/modules-load.d/k8s.conf | xargs -n 1 modprobe 设置内核参数
cat >> /etc/sysctl.conf <<-EOF
vm.swappiness = 0
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl -p二、K3S集群部署
1、第一台Server节点部署
第一台Server节点的部署
env INSTALL_K3S_SKIP_DOWNLOAD=true k3s-install.sh server \
--cluster-init \
--tls-san=192.168.3.184 \
--cluster-cidr 10.10.1.0/21 \
--service-cidr 10.11.1.0/21 \
--kube-controller-manager-arg=node-cidr-mask-size-ipv4=26 \
--kubelet-arg=max-pods=30 \
--flannel-backend=none \
--disable=traefik \
--disable=servicelb \
--disable-network-policy \
--disable-kube-proxy \
--disable-helm-controller获取接入集群节点所需的Token
cat /var/lib/rancher/k3s/server/token2、其他Server节点部署
第2台和第3台Server节点的部署
TOKEN=K104c402d15062584d3016de28a7423c8125fce142fxxx6641f789083479877c8784::server:075157fed0b0da613e78a349ae1dd770
env INSTALL_K3S_SKIP_DOWNLOAD=true k3s-install.sh server \
--server https://192.168.3.180:6443 \
--cluster-init \
--tls-san=192.168.3.184 \
--cluster-cidr 10.10.1.0/21 \
--service-cidr 10.11.1.0/21 \
--kube-controller-manager-arg=node-cidr-mask-size-ipv4=26 \
--kubelet-arg=max-pods=30 \
--flannel-backend=none \
--disable=traefik \
--disable=servicelb \
--disable-network-policy \
--disable-kube-proxy \
--disable-helm-controller \
--token $TOKEN 查看3台Server节点是否接入成功
kubectl get nodes 
3、Cilium的部署
在Cilium中集群Pod可以通过如下方式进行通讯:
- VxLAN封装:如果未指定运行模式,Cilium默认在此模式下运行,这种方式对底层基础设置要求最低,所有节点使用基于UDP的VxLAN或Geneve隧道,节点之间的流量都经过封装。由于封装了额外的协议头,导致特定网络连接的最大吞吐率降低
Native原生路由:通过Linux内核的路由子系统路由数据包,如果集群所有节点位于同一个二层网络,可以开启autoDirectNodeRoutes直接路由
由于后面会接入公有云节点作为Agent节点,这里使用VxLAN封装方式
生成kubeconfig文件,否则下面通过cilium命令行时无法安装
mkdir -pv $HOME/.kube
cp /etc/rancher/k3s/k3s.yaml $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
echo "export KUBECONFIG=$HOME/.kube/config" >> $HOME/.bashrc
. $HOME/.bashrcCilium相关命令行工具下载
CILIUM_CLI_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/cilium-cli/main/stable.txt)
CLI_ARCH=amd64
curl -LO https://github.com/cilium/cilium-cli/releases/download/${CILIUM_CLI_VERSION}/cilium-linux-${CLI_ARCH}.tar.gz
tar -zxvf cilium-linux-${CLI_ARCH}.tar.gz -C /usr/local/bin/
HUBBLE_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/hubble/master/stable.txt)
HUBBLE_ARCH=amd64
curl -LO https://github.com/cilium/hubble/releases/download/$HUBBLE_VERSION/hubble-linux-${HUBBLE_ARCH}.tar.gz
tar -zxvf hubble-linux-${HUBBLE_ARCH}.tar.gz -C /usr/local/bin/部署cilium
API_SERVER_IP=192.168.3.184
API_SERVER_PORT=6443
kubectl create ns cilium-system
cilium install \
--namespace cilium-system \
--set cluster.id=1 \
--set cluster.name=k3s \
--set routingMode=tunnel \
--set tunnelProtocol=geneve \
--set bpf.hostRouting=true \
--set bpf.masquerade=true \
--set k8sServiceHost=${API_SERVER_IP} \
--set k8sServicePort=${API_SERVER_PORT} \
--set ipam.operator.clusterPoolIPv4PodCIDRList=10.10.1.0/21 \
--set ipam.operator.clusterPoolIPv4MaskSize=26 \
--set kubeProxyReplacement=true \
--set hubble.enabled=true \
--set hubble.relay.enabled=true \
--set hubble.ui.enabled=true \
--set hubble.ui.service.type=NodePort \
--set hubble.ui.service.nodePort=30001 \
--set hubble.ui.ingress.enabled=true \
--set hubble.ui.ingress.hosts[0]="hubble.k3s.ocp.local"查看集群的状态
kubectl get pods -A
kubectl get nodes
cilium status -n cilium-system
4、Agent节点部署
接入所有Agent节点
TOKEN=K104c402d15062584d3016de28a7423c8125fce142fxxx6641f789083479877c8784::server:075157fed0b0da613e78a349ae1dd770
env INSTALL_K3S_SKIP_DOWNLOAD=true k3s-install.sh agent \
--server https://192.168.3.184:6443 \
--kubelet-arg=max-pods=60 \
--token $TOKEN查看集群所有节点状态
kubectl get nodes
5、部署测试应用
K3S默认允许Master节点可以正常调度工作负载,为Master节点打上污点,禁止其调度
kubectl taint nodes master01.k3s.ocp.local node-role.kubernetes.io/control-plane:NoSchedule创建测试应用
kubectl create deploy hello-server --image=artifactory.ocp.local/gitlab/google-samples/hello-app:1.0
kubectl expose deploy hello-server --type LoadBalancer --port 8080 --target-port 8080 --load-balancer-ip=192.168.3.185
kubectl scale --replicas=6 deploy hello-server
for i in {1..6}; do curl http://192.168.3.185:8080; done
hubble observe -f --protocol tcp --from-pod default/hello-server-7475f95cc6-2dtmv 三、Higress的部署
1、下载Helm
下载helm的二进制包,并把helm二进制解压到系统PATH路径下
curl -LO https://get.helm.sh/helm-v4.1.1-linux-amd64.tar.gz
tar -zxvf helm-v4.1.1-linux-amd64.tar.gz --strip-component=1 -C /usr/local/bin/ linux-amd64/helm
helm list -A2、Higress的部署
添加higress的helm仓库
helm repo add higress https://higress.cn/helm-charts
helm search repo higress/higress --versions
helm pull higress/higress --version 2.2.0 --untar 通过helm安装higress
helm upgrade --install higress higress/higress -n higress-system \
--create-namespace \
--render-subchart-notes \
--set global.local=true \
--set global.o11y.enabled=false \
--set higress-core.gateway.service.type=LoadBalancer \
--set higress-core.gateway.service.loadBalancerIP=192.168.3.185 \
--set higress-console.service.type=NodePort