k3s 安装笔记
k3s 是轻量级单节点集群,当然也可以加入多节点。
集群引导
单master节点
curl -sfL https://get.k3s.io | sh -
# 中国区加速
curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn sh -
运行完就安装完成了,需要保证 6443 和 443 端口可用。
安装完,集群默认配置文件在/etc/rancher/k3s/k3s.yaml
,如果不想sudo使用的话,可以移动配置文件:
mkdir -p ~/.kube
sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
sudo chown $USER:$USER ~/.kube/config
设置环境变量export KUBECONFIG=~/.kube/config
- 加入agent节点
查看/var/lib/rancher/k3s/server/node-token
得到token,加入
curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn INSTALL_K3S_EXEC='agent --node-ip=10.0.0.14 --node-name=p4' K3S_URL='master url' K3S_TOKEN='token' sh -
# 建议指定--node-ip和-node-name,多网卡下自动获取的node-ip可能不对,而node-name一般不太标准
多主节点
上面的初始化是单master节点的,因为使用的是sqlite,如果要使用多节点,需要在第一台机器上加入--cluster-init
,即:
curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn INSTALL_K3S_EXEC='server --node-ip=10.0.0.21 --node-name=h1 --flannel-backend=none --disable-network-policy --disable=traefik --cluster-init' sh -
# --flannel-backend=none --disable-network-policy --disable=traefik
# 是禁用自带的CNI和网络配置,为后面的cilium做准备
后面的server节点不需要,即:
curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn INSTALL_K3S_EXEC='server --node-ip=10.0.0.24 --node-name=h4 --flannel-backend=none --disable-network-policy --disable=traefik' K3S_URL='https://10.0.0.21:6443' K3S_TOKEN='token' sh -
# 除此之外的INSTALL_K3S_EXEC参数需要和第一个节点相同,否则无法同步
其他agent加入与server相同,但注意不要INSTALL_K3S_EXEC参数控制网络插件
curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn INSTALL_K3S_EXEC='agent --node-ip=10.0.0.14 --node-name=p4' K3S_URL='https://10.0.0.21:6443' K3S_TOKEN='token' sh -
删除
# master
/usr/local/bin/k3s-uninstall.sh
# agent
/usr/local/bin/k3s-agent-uninstall.sh
删除后集群数据并不会完全删除,可能残留有网络插件数据,查阅文档删除即可。
集群网络
CNI cilium
由于自带的是flannel+vxlan,性能比较差,一般希望换成cilium,官方文档:
由于cilium是取代了kube-proxy的,这里面还需要处理一下,安装server的时候:
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC='--flannel-backend=none --disable-network-policy' sh -
# 如果不想使用自带的LB,再加入--disable=traefik
来diable network
然后照官方文档安装cilium就可以了
helm install cilium ./cilium --version 1.17.0 \
--namespace cilium \
--set hubble.relay.enabled=true \
--set operator.replicas=1 \
--set hubble.ui.enabled=true \
--create-namespace
# operator.replicas=1建议只使用1
另外注意的是ip段,cilium默认使用10.0.0.0/8,如果CIDR冲突,需要更改集群IP段,用helm拉下找到CIDR即可,不然cilium修改route后会断网
集群存储
Longhorn
按照官网的安装教程来,使用helm,但是需要做一些初始化工作,每个节点都需要达到要求
# 基础工具nfs-common
sudo apt install -y nfs-common cryptsetup
# dm_crypt 模块
lsmod | grep dm_crypt
sudo modprobe dm_crypt
sudo echo "dm_crypt" | sudo tee -a /etc/modules # 加入启动列表自动加载
# 关闭multipathd
sudo systemctl stop multipathd.socket
sudo systemctl disable multipathd.socket
sudo systemctl stop multipathd.service
sudo systemctl disable multipathd.service
完毕后,安装:
helm install longhorn longhorn/longhorn --namespace longhorn-system --create-namespace --version 1.8.0
longhorn自带一个UI来设置所有的values,所以我们不需要改
集群LB
Ingress Gateway
安装
helm install eg oci://docker.io/envoyproxy/gateway-helm --version v0.0.0-latest -n envoy-gateway-system --create-namespace
# 测试
kubectl wait --timeout=5m -n envoy-gateway-system deployment/envoy-gateway --for=condition=Available
kubectl apply -f https://github.com/envoyproxy/gateway/releases/download/latest/quickstart.yaml -n default
HA Loadbalance
frontend k3s-frontend
bind *:16443 # 这里必须是*,否则没拿到IP的backup节点启动失败
mode tcp
option tcplog
default_backend k3s-backend
backend k3s-backend
mode tcp
option tcp-check
balance roundrobin
default-server inter 10s downinter 5s
server server-1 10.0.0.21:6443 check
server server-2 10.0.0.22:6443 check
server server-3 10.0.0.24:6443 check
global_defs {
enable_script_security
script_user root
}
vrrp_script chk_haproxy {
script 'killall -0 haproxy' # 测试haproxy进程是否存在
interval 2
}
vrrp_instance haproxy-vip {
interface eth1 # 修改通信网卡
state <STATE> # MASTER, BACKUP, BACKUP
priority <PRIORITY> # 200, 150, 100
virtual_router_id 51
virtual_ipaddress {
10.0.0.99/24
}
track_script {
chk_haproxy
}
}
其他
集群调试
实践中关键数据库一般不会暴露到集群外,如 mysql,假设上面我们只有一个 mysql-ci-service 可用,怎么连上mysql 进行调试呢?
- port-forward:使用 kubectl 端口转发:可以转发到 pod 和服务,只转发端口
- proxy:通过 k8s api 访问集群服务,但只能访问 http 服务
- 使用 telepresence:推荐
port-forward
我们已知上面的service 名称为 mysql-ci-service,端口为 30002,则可以输入:
kubectl port-forward service/mysql-ci-service 3306:30002
就把本地端口转发到 service 的 30002,service 再转发到 pod 3306
如果要转发 pod(比如说可能想绕过 service 的负载均衡到达指定 pod),则需要得到 pod 名称,然后输入:
kubectl port-forward pod/mysql-6d57fdf866-f492r 3306:3306
proxy
输入 kubectl proxy 即可使用
telepresence
telepresence 可以直接拦截本地流量发送到 k8s 上,看起来就好像身处集群中。
telepresence connect
如果想要拦截云上服务的流量,telepresence 也能做到,详细参考文档。
其他问题
集群代理问题
k3s一般安装containerd,国内拉镜像需要代理,但TUN模型会严重影响pod的dns,导致大部分服务找不到内网IP,所以需要配置拉取镜像的代理:
sudo mkdir -p /etc/systemd/system/containerd.service.d/
sudo cat > /etc/systemd/system/containerd.service.d/http-proxy.conf <<-EOF
[Service]
Environment="HTTP_PROXY=http://ip:7890"
Environment="HTTPS_PROXY=http://ip:7890"
Environment="NO_PROXY=localhost,::1,127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,169.254.0.0/16"
EOF
sudo systemctl daemon-reload && sudo systemctl restart containerd
docker的配置同理,这里注意要改代理IP和NO_PROXY比较好,防止代理内网
根据一篇文章阐述,k3s必须配置专用的代理,如下,注意server和agent有点不一样:
# /etc/systemd/system/k3s.service.env
# /etc/systemd/system/k3s-agent.service.env
HTTP_PROXY="http://10.0.0.23:7890"
HTTPS_PROXY="http://10.0.0.23:7890"
NO_PROXY="localhost,127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"
sudo systemctl daemon-reload && sudo systemctl restart k3s
sudo systemctl daemon-reload && sudo systemctl restart k3s-agent
查阅官方文档的确是这样,但是上面的配法会影响到kubelet,导致延迟偏高,所以最好只配containerd的:
CONTAINERD_HTTP_PROXY="http://10.0.0.23:7890"
CONTAINERD_HTTPS_PROXY="http://10.0.0.23:7890"
CONTAINERD_NO_PROXY="127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"
而且据文档所述,k3s的ip域自动会添加到NO_PROXY中,所以不需要加
K3s 会自动将集群内部 Pod 和 Service IP 范围以及集群 DNS 域添加到
NO_PROXY
条目列表中。你需要确保 Kubernetes 节点本身使用的 IP 地址范围(即节点的公共和私有 IP)包含在NO_PROXY
列表中,或者可以通过代理访问节点。
本地私有仓库配置
k3s不是在containerd的配置文件中配置本地仓库,而是配置k3s,自动生成containerd的配置文件,假设10.0.0.21:5000上有一个镜像站:
# /etc/rancher/k3s/registries.yaml
sudo mkdir -p /etc/rancher/k3s
# 添加
mirrors:
"10.0.0.21:5000":
endpoint:
- "http://10.0.0.21:5000"
然后重启k3s服务
命名空间无法删除的问题
查看命名空间存在的资源:
kubectl api-resources --verbs=list --namespaced -o name | xargs -n 1 kubectl -n <name-of-namespace> get
然后删除对应的资源