自建三节点 K3s 集群搭建 Drone CI/CD 流水线

自建三节点 K3s 集群搭建 Drone CI/CD 流水线

本文记录如何在家庭网络环境中,使用 Gitee、Drone CI、自建 Docker Registry、GitOps 和 Argo CD,搭建完整的持续集成与持续交付流程。

一、最终架构

text 复制代码
Gitee Push
  -> Gitee WebHook
  -> Drone Server / Runner(node2)
  -> 测试代码
  -> 构建 Docker 镜像
  -> 推送 Registry(node1)
  -> 更新 GitOps 仓库
  -> Argo CD 自动同步
  -> K3s 应用节点滚动更新

三台主机职责:

  • master:K3s control-plane、Argo CD
  • node1:RustFS、外接硬盘、自建 Docker Registry
  • node2:Drone Server、Drone Docker Runner

Ingress、RustFS 和本地磁盘属于基础设施,不应在应用发布流水线中修改。

二、在 node2 启动 Drone

项目配置位于:

text 复制代码
deploy/drone/docker-compose.yaml
deploy/drone/.env.example
deploy/drone/.gitignore

在 node2 执行:

bash 复制代码
cd deploy/drone
cp .env.example .env
vim .env
sudo docker compose up -d
sudo docker compose ps

环境变量包括 Gitee OAuth Client ID、Client Secret、Server 和 Runner 共用的 RPC Secret、Drone 对外地址以及管理员用户名。RPC Secret 可用以下命令生成:

bash 复制代码
openssl rand -hex 32

Server 与 Runner 的 RPC Secret 必须完全一致。

三、配置 Gitee OAuth 和 WebHook

家庭宽带封禁 80 和 443 时,可以使用高位端口,例如公网 18444 转发到 node2 的 18444。

Gitee OAuth 回调地址:

text 复制代码
http://公网域名或IP:18444/login

Gitee WebHook 地址:

text 复制代码
http://公网域名或IP:18444/hook

只选择 Push 事件即可。地址必须能被 Gitee 公网访问,不能使用 localhost 或集群内部地址。

四、在 K3s 中部署自建 Registry

node1 的外接分区已经挂载到:

text 复制代码
/dev/sdb1 -> /data/sdb

不要格式化或卸载 RustFS 正在使用的磁盘。为 Registry 使用独立目录:

bash 复制代码
sudo mkdir -p /data/sdb/registry

项目中的 K3s Registry 清单位于:

text 复制代码
deploy/registry/k3s/
├── namespace.yaml
├── pv.yaml
├── secret.yaml.example
├── deployment.yaml
├── service.yaml
└── kustomization.yaml

Registry Pod 固定在 node1,PV 使用 /data/sdb/registry,Service 使用 NodePort 30500。部署前创建认证 Secret:

bash 复制代码
read -r -p "Registry username: " REGISTRY_USER
read -r -s -p "Registry password: " REGISTRY_PASSWORD
printf '\n'

sudo docker run --rm httpd:2.4-alpine \
  htpasswd -Bbn "$REGISTRY_USER" "$REGISTRY_PASSWORD" \
  > /tmp/registry-htpasswd

kubectl apply -f deploy/registry/k3s/namespace.yaml
kubectl create secret generic movie-registry-auth \
  -n registry \
  --from-file=htpasswd=/tmp/registry-htpasswd \
  --dry-run=client -o yaml | kubectl apply -f -

rm -f /tmp/registry-htpasswd

部署 Registry:

bash 复制代码
kubectl apply -f deploy/registry/k3s/pv.yaml
kubectl apply -f deploy/registry/k3s/deployment.yaml
kubectl apply -f deploy/registry/k3s/service.yaml
kubectl -n registry rollout status deployment/movie-registry

Registry v2 没有网页管理界面,使用 API 测试:

bash 复制代码
curl -i -u '用户名:密码' http://节点1内网IP:30500/v2/

返回 HTTP 200 和空 JSON 对象即表示正常。

五、配置 K3s 和 Drone 访问 Registry

在 node1、node2 创建 K3s 配置文件:

text 复制代码
/etc/rancher/k3s/registries.yaml

内容如下,替换节点 IP、用户名和密码:

yaml 复制代码
mirrors:
  "节点1内网IP:30500":
    endpoint:
      - "http://节点1内网IP:30500"

configs:
  "节点1内网IP:30500":
    auth:
      username: registry-user
      password: registry-password

保存后执行:

bash 复制代码
sudo chmod 600 /etc/rancher/k3s/registries.yaml
sudo systemctl restart k3s-agent

node2 的 Docker daemon 还需要允许 HTTP Registry。编辑 /etc/docker/daemon.json:

json 复制代码
{
  "insecure-registries": ["节点1内网IP:30500"]
}

然后重启并测试:

bash 复制代码
sudo systemctl restart docker
docker login 节点1内网IP:30500

六、配置 Drone Secrets

在 Drone 仓库 Settings -> Secrets 中添加:

text 复制代码
image_repository=节点1内网IP:30500/movie-web
registry_username=Registry用户名
registry_password=Registry密码
gitops_repo=GitOps仓库地址
gitops_username=Gitee用户名
gitops_token=Gitee私人令牌
gitops_branch=main
gitops_file=apps/movie-web/deployment.yaml

不要把密码和 Token 写入 .drone.yml 或提交到 Git。image_repository 不要带 latest,流水线使用提交 SHA 作为不可变 Tag。

七、Drone 到 Argo CD

源码仓库的 .drone.yml 依次执行:测试、构建镜像、推送 Registry、更新 GitOps 仓库。

Drone 不直接执行 kubectl apply。Argo CD 监听 GitOps 仓库提交,并通过自动同步将新版本发布到 K3s。

建议 Application 开启:

yaml 复制代码
syncPolicy:
  automated:
    prune: true
    selfHeal: true

八、常见问题

  • 401 Unauthorized:检查 Registry Secret 中的 htpasswd 和账号密码。
  • HTTP response to HTTPS client:Docker 未配置 insecure-registries,或应改用 HTTPS。
  • ImagePullBackOff:检查 node1、node2 的 registries.yaml 和镜像地址。
  • Registry 浏览器空白:registry:2 没有 Web UI,使用 /v2/ API 验证。
  • Runner 离线:检查 Server 与 Runner 的 RPC Secret 是否一致。

九、安全建议

  • 不要提交 .env、Registry 密码、Gitee Token 和 RPC Secret。
  • 不要将 Docker 2375 端口暴露到公网。
  • HTTP Registry 只用于可信内网,正式环境建议使用 HTTPS。
  • node1 是 Local PV 单点存储,应定期备份 Registry 数据。
相关推荐
虎王物联2 天前
Docker BuildKit多阶段构建:IoT固件交叉编译流水线实战
运维·物联网·ci/cd·docker·容器·物联网嵌入式
LlmCraft|大模型工程实践2 天前
14. CI/CD 流水线中集成 Docker:GitHub Actions 自动构建部署
ci/cd·docker·github
秦渝兴3 天前
GitLab CI/CD 流水线实战
ci/cd·gitlab
gs801403 天前
告别 CI/CD 误伤与红条:Docker 镜像智能清理与优雅防冲突实战
ci/cd·docker·容器
leeyi3 天前
DDD 六条铁律:让 CI 替你骂人——go-arch-lint 门禁实战(第104篇)
ci/cd·agent·领域驱动设计
算法大模型备案干货咪3 天前
《把内容安全做成CI卡点:AIGC合规的工程化落地》
安全·ci/cd·aigc
code 小楊3 天前
生产级 Agent 评测体系实战:从 12 指标框架到 CI/CD 质量门禁全链路落地
大数据·人工智能·ci/cd
Ningcode_cloud4 天前
什么是CICD? GitLab + Jenkins 持续集成实战部署手册
运维·ci/cd·云原生·容器·gitlab·jenkins
成茂峰4 天前
实战:内外网隔离环境下基于 Jenkins + PowerShell 的自动化 CI 构建与邮件通知方案
ci/cd·自动化·jenkins