单机 SRE/DevOps 展示项目(Ubuntu 24 / 32G / 200G / 192.168.101.100)
面向面试可展示的“可落地、可复现、可观测”的一体化样例:代码托管与 CI/CD、镜像与 Helm 制品仓库、Kubernetes 部署(区分测试/正式环境)、以及主机性能监控。
1. 目标与价值
- 代码→流水线→镜像→Helm→K8s 部署,全链路自动化。
- 可展示 Dev/Prod 双环境隔离(同集群不同命名空间)。
- 制品沉淀(镜像仓库+Helm 仓库)、可追溯、可回滚。
- 主机性能监控(CPU/内存/磁盘/网络),支持告警扩展。
2. 架构概览
[开发者] ──push──> Gitea (代码托管)
│ 触发
▼
Gitea Actions Runner (CI/CD)
│ 构建/扫描/打包/推送/部署
├──────────> Docker Registry (镜像仓库 :5000)
├──────────> ChartMuseum (Helm 仓库 :8080)
└──────────> k3s (Kubernetes 单机集群)
├─ namespace: dev
└─ namespace: prod
[监控] Prometheus + Grafana + Node Exporter + cAdvisor(主机与容器性能)
3. 组件与端口(默认均运行在 192.168.101.100 上)
- 代码托管:Gitea(:3000 Web / :2222 SSH)
- CI/CD:Gitea Actions Runner(容器)
- 镜像仓库:registry:2(:5000)
- Helm 仓库:ChartMuseum(:8080)
- K8s 集群:k3s(内置 containerd)
- 监控:Prometheus(:9090)、Grafana(:3001)、Node Exporter(:9100)、cAdvisor(:8081)
4. 环境假设
- OS:Ubuntu 24.04,IP:192.168.101.100
- 已安装 Docker 与 docker-compose / compose plugin
- 机器具备出网能力(拉取镜像)
5. 快速开始(30-60 分钟)
5.1 安装 k3s(单机)
curl -sfL https://get.k3s.io | sh -
# 验证
kubectl get node
# 创建双环境命名空间
kubectl create namespace dev || true
kubectl create namespace prod || true
如需让 k3s 能从本地镜像仓库拉取镜像,新增:/etc/rancher/k3s/registries.yaml
mirrors:
"192.168.101.100:5000":
endpoint:
- "http://192.168.101.100:5000"
然后:
sudo systemctl restart k3s
5.2 基础服务一键启动(Gitea/Registry/ChartMuseum/监控)
在目录 infra/
下放置 docker-compose.yml
(建议自建仓库),示例片段:
version: "3.8"
services:
gitea:
image: gitea/gitea:1.21
container_name: gitea
ports: ["3000:3000", "2222:22"]
volumes:
- ./gitea:/data
restart: unless-stopped
runner:
image: gitea/act_runner:latest
depends_on: [gitea]
environment:
- GITEA_INSTANCE_URL=http://192.168.101.100:3000
# 注册后填入 TOKEN
- GITEA_RUNNER_REGISTRATION_TOKEN=${RUNNER_TOKEN}
volumes:
- /var/run/docker.sock:/var/run/docker.sock
restart: unless-stopped
registry:
image: registry:2
ports: ["5000:5000"]
volumes:
- ./registry:/var/lib/registry
restart: unless-stopped
chartmuseum:
image: ghcr.io/helm/chartmuseum:v0.15.0
ports: ["8080:8080"]
environment:
- STORAGE=local
- STORAGE_LOCAL_ROOTDIR=/charts
volumes:
- ./charts:/charts
restart: unless-stopped
prometheus:
image: prom/prometheus
ports: ["9090:9090"]
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
restart: unless-stopped
grafana:
image: grafana/grafana
ports: ["3001:3000"]
volumes:
- ./grafana:/var/lib/grafana
restart: unless-stopped
node_exporter:
image: prom/node-exporter
ports: ["9100:9100"]
restart: unless-stopped
cadvisor:
image: gcr.io/cadvisor/cadvisor:latest
ports: ["8081:8080"]
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
restart: unless-stopped
启动:
cd infra && docker compose up -d
Prometheus 最小配置示例(infra/prometheus/prometheus.yml
):
global:
scrape_interval: 15s
scrape_configs:
- job_name: node
static_configs:
- targets: ["192.168.101.100:9100"]
- job_name: cadvisor
static_configs:
- targets: ["192.168.101.100:8081"]
6. 制品与部署规范
- 镜像命名:
192.168.101.100:5000/<project>/<app>:<gitSha>
- Helm Chart:
ChartMuseum
推送地址http://192.168.101.100:8080
- K8s 命名空间:
dev
(测试)、prod
(正式) - 发布策略:默认滚动升级;支持
helm rollback
一键回滚
7. CI/CD 流水线(Gitea Actions 示例)
仓库中加入:.gitea/workflows/deploy.yml
name: build-and-deploy
on:
push:
branches: ["main", "release/*"]
jobs:
build:
runs-on: docker
steps:
- uses: actions/checkout@v3
- name: Build image
run: |
docker build -t 192.168.101.100:5000/demo/web:${GITEA_SHA} .
docker push 192.168.101.100:5000/demo/web:${GITEA_SHA}
- name: Package Helm
run: |
helm lint helm/demo
helm package helm/demo -d dist
curl -T dist/*.tgz http://192.168.101.100:8080/api/charts
- name: Deploy to dev
if: startsWith(github.ref, 'refs/heads/main')
env:
KUBECONFIG: /kube/config
run: |
helm upgrade --install demo-web helm/demo \
--namespace dev \
--set image.repository=192.168.101.100:5000/demo/web \
--set image.tag=${GITEA_SHA}
- name: Deploy to prod
if: startsWith(github.ref, 'refs/heads/release/')
env:
KUBECONFIG: /kube/config
run: |
helm upgrade --install demo-web helm/demo \
--namespace prod \
--set image.repository=192.168.101.100:5000/demo/web \
--set image.tag=${GITEA_SHA}
Runner 侧需要将 k3s kubeconfig 映射为 /kube/config
(或配置 KUBECONFIG 秘密变量)。
8. 示例应用与目录建议
repo-root/
apps/demo-web/
Dockerfile
src/
helm/demo/
Chart.yaml values.yaml templates/
.gitea/workflows/deploy.yml
k8s/
ingress-dev.yaml ingress-prod.yaml
infra/
docker-compose.yml
prometheus/prometheus.yml
grafana/ (数据目录)
docs/
architecture.md runbook.md dashboards.png
9. 监控与展示要点
- Grafana(http://192.168.101.100:3001):导入 Node Exporter 与 cAdvisor 常用面板,展示 CPU/内存/磁盘/容器资源曲线。
- Prometheus(http://192.168.101.100:9090):查询主机与容器指标。
- 可扩展:接入 Alertmanager(钉钉/飞书/企业微信)实现告警。
10. 演示脚本(面试 5-8 分钟)
- 打开 Gitea 提交 MR → 合并到
main
。 - 展示 Actions 运行:构建镜像→推送 Registry→打包并上传 Helm→部署到
dev
。 - 打开
kubectl get pods -n dev
与应用页面(Ingress)。 - 切换
release/x.y.z
分支 → 同步部署到prod
。 - 人为引入缺陷(返回 500)→
helm rollback
回滚,恢复。 - 展示 Grafana 资源曲线与发布前后对比截图。
11. 安全与合规(最小集合)
- Registry 建议加 BasicAuth + HTTPS(自签证书亦可)
- Gitea 启用管理员与组织权限、保护主干分支
- Runner 使用最小权限 Token;K8s 使用具名 ServiceAccount + RBAC
12. 备份与回收
- 备份目录:
infra/gitea
、infra/registry
、infra/charts
、/etc/rancher/k3s
、应用数据库(如有) - 回收:
docker compose down
;helm uninstall
;kubectl delete ns dev prod
;/usr/local/bin/k3s-uninstall.sh
13. 成本与资源(单机)
- 32G 内存足够跑上述组件与中小型演示;建议日志保留 7-14 天,Grafana/Prometheus 数据卷单独目录
14. 下一步可选增强
- 引入 Trivy 做镜像扫描;引入 Argo Rollouts 做金丝雀;将监控迁移到 kube-prometheus-stack;将制品仓库替换为 Harbor(镜像+Helm 一体)
完成以上步骤后,你将获得一个可复现、可扩展且覆盖 CI/CD、制品管理、Kubernetes 部署与可观测性的端到端展示项目,可直接用于面试演示与简历背书。