腾讯云轻量服务器折腾 K3s 实录:外网直连与 X509 证书踩坑指南

最近搞了台腾讯云 4核4G 的轻量应用服务器(Debian 12),准备搭个 K3s 跑 ArgoCD 和 Kong 的 GitOps 实验环境。本以为敲个一键安装脚本就能愉快玩耍,结果实际操作下来连续踩了几个不大不小的坑。

这里记录一下完整的排坑过程,特别是外网直连配置证书重签部分,给有同样需求的兄弟们避避雷。

坑一:国内网络卡死与 Traefik 端口冲突

如果你在国内的云主机上直接跑官方的 get.k3s.io 脚本,大概率会遇到卡在拉取 k3s 二进制文件甚至哈希校验超时的问题。乖乖换国内 Rancher 镜像源才是正解。

另外,由于我后续计划部署 Kong 作为 API 网关,K3s 默认捆绑安装的 Traefik 会直接霸占 80 和 443 端口,导致后续 Kong 无法正常监听。所以在安装时必须加上 --disable traefik

直接上干货命令:

# 替换为国内镜像源,剥离 traefik,并提前把公网 IP 加入 TLS SAN(后面会讲为什么)
curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | \
  INSTALL_K3S_MIRROR=cn \
  INSTALL_K3S_EXEC="--disable traefik --tls-san 你的公网IP" \
  sh -

坑二:普通用户 kubectl 权限与环境变量

K3s 装好后,默认只有 root 能用 kubectl。为了平时操作方便,肯定要把配置拷给普通用户。
但拷完 k3s.yaml 后,你会发现依然报错。这是因为 K3s 阉割版的 kubectl 实际上是个指向 k3s 的软连接,这玩意儿有点死心眼,默认非要去读 /etc/rancher/k3s/k3s.yaml

解决办法: 必须在环境变量里显式声明路径。

mkdir -p ~/.kube
sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
sudo chown $(id -u):$(id -g) ~/.kube/config

# 强行指定环境变量
echo 'export KUBECONFIG=~/.kube/config' >> ~/.bashrc
source ~/.bashrc

坑三:本地外网直连超时与腾讯云防火墙

服务端搞定后,我想在自己的笔记本上直接用本地的 kubectl 去连 K3s,把服务端的 config 拷下来并把里面的 127.0.0.1 换成公网 IP 后,一跑命令直接报 TLS handshake timeout

排查了一圈,发现 K3s 的 6443 端口确实监听在 0.0.0.0 上了,问题出在腾讯云的安全组控制策略上。腾讯云轻量服务器默认只开 22/80/443。

你可以去网页控制台手动加,但我比较懒,直接搞了个 Python 的 tccli 脚本一键打通:

# 安装 tccli (带上 --break-system-packages 避开新版 pip 的环境限制)
pip3 install tccli --user --break-system-packages

# 初始化配置 (输入你的 SecretId 和 SecretKey)
tccli configure

# 一键写入防火墙放通 6443 (API Server) 和 30080 (给 ArgoCD 预留)
tccli lighthouse CreateFirewallRules --InstanceId lhins-xxxx \
  --FirewallRules '[{"Protocol":"TCP","Port":"6443","Action":"ACCEPT","CidrBlock":"0.0.0.0/0","FirewallRuleDescription":"K3s"}, {"Protocol":"TCP","Port":"30080","Action":"ACCEPT","CidrBlock":"0.0.0.0/0","FirewallRuleDescription":"ArgoCD"}]'

坑四:终极阻碍 —— x509 证书不包含公网 IP

防火墙打通后,再次从本地连接,这回不超时了,直接糊了我一脸这个报错:

Unable to connect to the server: x509: certificate is valid for 10.1.0.2, 127.0.0.1, not 43.139.x.x

原因分析:
K3s 在初次启动时,会自动生成 TLS 证书。但它很保守,只把机器的内网 IP 和 127.0.0.1 签进去了(SANs),根本不知道你的公网 IP 是多少。如果你在第一步安装时没带 --tls-san 参数,外网连过来必然触发证书校验失败。

补救方法(无需重装,暴力重签):

不用去折腾重装,只要改掉配置,把旧证书删了逼它重生成就行。

# 1. 修改 systemd 启动参数,补上你的公网 IP
sudo sed -i 's/    server \\/    server \\\n    --tls-san 你的公网IP \\/g' /etc/systemd/system/k3s.service

# 2. 停掉服务
sudo systemctl daemon-reload
sudo systemctl stop k3s

# 3. 核心步骤:干掉旧证书
sudo rm -rf /var/lib/rancher/k3s/server/tls/serving-kube-apiserver.crt \
            /var/lib/rancher/k3s/server/tls/serving-kube-apiserver.key \
            /var/lib/rancher/k3s/server/tls/dynamic-cert.json
            
# 4. 重新启动,K3s 发现没证书会自动按照新参数重新签发
sudo systemctl start k3s

最后一步别忘了,服务端的配置发生了变化,你需要重新把服务端的 /etc/rancher/k3s/k3s.yaml 拷贝到本地替换旧配置

再次运行 kubectl get nodes,秒出结果,顺利收工。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐