Jenkins 与 K8s 发布
这套发布方式适合你现在描述的网络结构:
- Jenkins 构建
globi-website镜像并推送到 Harbor。 - Jenkins 通过 SSH 登录 K3s Master,执行
kubectl apply和滚动更新。 - K8s 通过 NodePort 对 VPN 内网暴露网站端口。
- 公网 VPS 与 K8s 在同一个 VPN 内,通过 Nginx 反向代理 NodePort,对外提供域名和 HTTPS。
推荐架构
Internet
|
v
Public Domain -> VPS Nginx (80/443)
|
| VPN
v
K3s Node VPN IP:30081 -> Service(NodePort) -> Deployment -> Nginx Container -> Docusaurus Static Files
这套方案的核心点是:
- 公网流量只落在 VPS 上。
- K3s 集群只需要在 VPN 内暴露 NodePort。
- TLS 证书、域名和访问日志统一收敛在 VPS 上处理。
仓库内文件
Dockerfile: 多阶段构建 Docusaurus,并用 Nginx 托管静态文件。nginx.conf: 容器内 Nginx 配置,负责静态站点服务和健康检查。k8s/globi-website.yaml: K8s Deployment 与 NodePort Service。Jenkinsfile: Jenkins 自动构建、推送和部署流水线。
Jenkins 准备
复用你现在 globi-server 的发布思路即可,至少需要这些 Jenkins 凭据:
harbor-robot-creds: Harbor 用户名密码。homelab-chius: SSH 私钥,用于登录 K3s Master。
流水线里还提供了两个构建参数:
SITE_URL: 网站正式访问地址,例如https://www.globi.lan.tamochi.cnBASE_URL: 部署前缀,根路径部署就保持/
如果网站挂在二级路径,比如 https://www.globi.lan.tamochi.cn/globi/,则:
SITE_URL=https://www.globi.lan.tamochi.cnBASE_URL=/globi/
K8s 发布方式
网站通过 NodePort 暴露在 30081/TCP。
手工发布时可以直接执行:
kubectl apply -f k8s/globi-website.yaml
kubectl set image deployment/globi-website-deployment \
globi-website=10.0.0.134/main/globi-website:<tag> \
-n default
kubectl rollout status deployment/globi-website-deployment -n default
如果你已经启用了 Jenkins,则正常情况不需要手工执行这些命令。
VPS 反向代理
VPS 上建议使用 Nginx 对外暴露域名,再通过 VPN 转发到 K3s 节点的 NodePort。
示例配置:
upstream globi_website_k8s {
server 10.0.0.190:30081;
keepalive 16;
}
server {
listen 80;
server_name www.globi.lan.tamochi.cn;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl http2;
server_name www.globi.lan.tamochi.cn;
ssl_certificate /etc/letsencrypt/live/www.globi.lan.tamochi.cn/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.globi.lan.tamochi.cn/privkey.pem;
location / {
proxy_http_version 1.1;
proxy_pass http://globi_website_k8s;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_connect_timeout 5s;
proxy_read_timeout 60s;
}
}
如果你的 K3s 有多个可访问节点,可以把多个 VPN IP 都加进 upstream,让 VPS 侧做简单故障切换。
防火墙与网络要求
- VPS 需要对公网开放
80/443。 - K3s 节点需要允许来自 VPS VPN 地址的
30081/TCP。 - 最好不要把 NodePort 直接暴露到公网,只对 VPN 网段放行。
验证链路
可以按这个顺序检查:
kubectl get pods -n default -l app=globi-websitekubectl get svc globi-website-service -n default- 在 VPS 上执行
curl http://10.0.0.190:30081/healthz - 在公网执行
curl -I https://www.globi.lan.tamochi.cn
如果第 3 步不通,先查 VPN 与 K3s 节点防火墙。 如果第 3 步通而第 4 步不通,重点查 VPS Nginx、证书和公网安全组。
为什么这里选 NodePort
因为你的公网入口已经确定放在 VPS,而不是直接放在 K8s Ingress 上。
在这个前提下,NodePort 的优点是:
- 实现最直接,和你现有
globi-server的发布方式一致。 - VPS 不需要加入 K8s 集群,只要能通过 VPN 打到节点端口即可。
- Jenkins 侧只需要更新镜像和 K8s 清单,不需要额外接入外部 LB。
后面如果你想把入口完全迁到集群内部,再考虑 Ingress Controller 或 LoadBalancer 会更合适。