主要目标是在上一篇中搭建的集群中进行基础设施建设NFS,PostgreSQL,Redis,MinIO,JuiceF--- 搭建步骤概览 Phase 1准备虚拟机1-2天 1. VMware 创建3台 Ubuntu 虚拟机 2. 配置静态 IP同一网段互通 3. 每台机器安装 Docker/containerd 4. 每台机器安装 kubeadm、kubelet、kubectl Phase 2初始化集群半天 1. master-1 上执行 kubeadm init 2. worker节点执行 kubeadm join 加入集群 3. 安装 CNI 网络插件Calico 或 Flannel Phase 3基础设施3-5天 按依赖顺序部署 1. PostgreSQL用 Helm 或手动部署 2. Redis 3. MinIO对象存储 4. JuiceFS CSI 每个组件部署后验证能否正常使用。 Phase 4监控栈2-3天 1. Prometheus 2. Grafana Loki 3. Grafana Alloy 4. Grafana Dashboard Phase 5业务部署1-2天 1. brokerDeployment 2. Service Ingress 3. 连接测试 第一步搭建 K8s 集群 第二步部署存储层依赖最底层 先部署这些因为 JuiceFS 和业务都依赖 顺序 1. PostgreSQL / MySQL数据库 2. Redis缓存 3. 对象存储MinIO模拟 S3 ← JuiceFS 需要 4. JuiceFS依赖对象存储 PostgreSQL/Redis 作元数据 第三步部署监控栈 ACK 用的是 Grafana生态部署顺序 1. Prometheus指标采集 2. Grafana Loki日志存储 3. Grafana Mimir指标存储 4. Grafana Alloy采集器 5. Grafana Dashboard可视化 第四步部署业务broker 1. 部署 broker Deployment Service 2. 配置 Ingress/NodePort 暴露服务 3. 配置连接数据库、Redis、JuiceFS 第五步验证 1. 检查 Pod 状态 2. 测试 API 接口 3. 检查日志、监控数据 建议的学习路线 第1周K8s 基础 ├── Kind/Minikube 搭集群 ├──kubectl 基础命令 ├── Pod、Deployment、Service 概念 第2周存储基础 ├── PostgreSQL/MySQL 部署StatefulSet ├── Redis 部署 ├── PVC/PV 概念 ├── 测试数据库读写 第3周分布式存储 ├── MinIO 部署对象存储 ├── JuiceFS CSI 部署 ├── 创建 JuiceFS PV ├── 测试文件写入 第4周监控栈 ├── Prometheus 部署 ├── Grafana Loki 部署 ├── Grafana Alloy 部署 ├── 配置日志采集 第5周业务部署 ├── broker 部署 ├── 配置依赖连接 ├── Ingress暴露服务 ├── 端到端测试 111111111111111111111111111111111111111111111111111111111111111111111111111111111 ✅ Phase 1 2K8s 集群已完成 创建3台 Ubuntu 虚拟机 配置静态 IP 安装 containerd 安装 kubeadm、kubelet、kubectl kubeadm init 初始化集群 worker 节点 join 集群 安装 Calico CNI Phase 2.5存储基础设施前置 生产环境用 NFS 作为共享存储后端比 local-path 更接近真实环境 部署 NFS Server在 master 或单独节点上 安装 nfs-kernel-server 配置导出目录 /data/nfs 所有节点安装 nfs-common 客户端 部署 NFS Provisioner自动创建 PV helm install nfs-provisioner 设置为默认 StorageClass 验证创建一个测试 PVC确认自动绑定 Phase 3基础设施 PostgreSQL Helm 安装 PostgreSQLStatefulSet 验证 PVC 绑定、Pod Running 测试数据库连接读写 Redis Helm 安装 Redis单机或主从 验证 Pod Running 测试 redis-cli ping MinIO Helm 安装 MinIO 创建 Bucket供 JuiceFS 使用 验证 Web UI 可访问NodePort 测试文件上传/下载 JuiceFS CSI 安装 JuiceFS CSI Driver 创建 JuiceFS Secret连接 MinIO Redis/PostgreSQL 创建 StorageClass 创建测试 PVC验证文件挂载读写 Phase 4监控栈 安装 Prometheuskube-prometheus-stack 安装 Grafana Loki 安装 Grafana Mimir 安装 Grafana Alloy日志/指标采集器 配置 Grafana Dashboard 验证能看到节点指标 Pod 日志 Phase 5业务部署broker 编写 broker Deployment YAML 配置 ConfigMap / Secret数据库、Redis、JuiceFS 连接信息 配置 ServiceClusterIP 安装 Ingress Controllernginx-ingress 配置 Ingress 暴露 API 端到端连接测试 Phase 6验证 所有 Pod 状态 Running API 接口测试 日志在 Loki 中可查询 指标在 Grafana 中可视化 存储基础设施前置生产环境用 NFS 作为共享存储后端 选择合适的存储类型 简单来说单点读写的数据库就用云盘RWO需要多 Pod 共享读写就上 NASRWX海量静态文件就存到 OSS对象存储 #直接部署 NFS用 NFS 统一作为所有组件的存储后端包括数据库。 Step 1Master 节点安装 NFS Server sudo apt install -y nfs-kernel-server sudo mkdir -p /data/nfs sudo chmod 777 /data/nfs echo /data/nfs *(rw,sync,no_subtree_check,no_root_squash) | sudo tee -a /etc/exports sudo exportfs -ra sudo systemctl enable --now nfs-kernel-server sudo systemctl status nfs-kernel-server Step 2所有 Worker 节点安装 NFS 客户端 在 node01 和 node02 都执行 sudo apt install -y nfs-common 验证能看到 master 的共享目录 showmount -e 192.168.74.128 Step 3安装 NFS Provisioner自动创建 PV 回到 master 执行 # 试试这个源不行就换 helm repo add nfs-provisioner https://charts.kubesphere.io/main helm repo update helm search repo nfs 安装 helm install nfs-provisioner nfs-provisioner/nfs-client-provisioner \ --namespace kube-system \ --set nfs.server192.168.74.128 \ --set nfs.path/data/nfs \ --set storageClass.defaultClasstrue \ --set storageClass.namenfs-client 验证 kubectl get pods -n kube-system | grep nfs 开始部署 PostgreSQL。推荐用 Helm 部署简单可靠。 第一步安装 Helm 在 master 节点执行 curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash helm version 第二步添加 Bitnami Helm 仓库 # helm repo add bitnami https://charts.bitnami.com/bitnami helm repo add bitnami https://helm-charts.itboon.top/bitnami helm repo update 第三步创建命名空间 kubectl create namespace database 第四步部署 PostgreSQL helm install postgresql bitnami/postgresql \ --namespace database \ --set auth.postgresPasswordyourpassword \ --set auth.databasemydb \ --set primary.persistence.size5Gi 检查状态 hsqk8s-master01:~$ kubectl get pods -n database NAME READY STATUS RESTARTS AGE postgresql-0 0/1 ImagePullBackOff 0 114m hsqk8s-master01:~$ 如果没办法拉到镜像3个节点手动拉换官方 PostgreSQL 镜像 sudo ctr -n k8s.io image pull docker.m.daocloud.io/library/postgres:17.6 手动拉取以后手动写yaml kubectl apply -f - EOF apiVersion: v1 kind: PersistentVolumeClaim metadata: name: postgres-pvc namespace: database spec: accessModes: [ReadWriteOnce] resources: requests: storage: 5Gi --- apiVersion: apps/v1 kind: StatefulSet metadata: name: postgresql namespace: database spec: serviceName: postgresql replicas: 1 selector: matchLabels: app: postgresql template: metadata: labels: app: postgresql spec: containers: - name: postgresql image: docker.m.daocloud.io/library/postgres:17.6 env: - name: POSTGRES_PASSWORD value: yourpassword - name: POSTGRES_DB value: mydb ports: - containerPort: 5432 volumeMounts: - name: data mountPath: /var/lib/postgresql/data volumes: - name: data persistentVolumeClaim: claimName: postgres-pvc --- apiVersion: v1 kind: Service metadata: name: postgresql namespace: database spec: selector: app: postgresql ports: - port: 5432 targetPort: 5432 EOF 测试一下数据库连接 不进入容器内 kubectl run pg-client # 创建一个临时 Pod名字叫 pg-client --rm # Pod 退出后自动删除不留垃圾 -it # 交互式终端-i 标准输入-t 分配 TTY --restartNever # 不重启运行完就结束否则默认会重启变成 Deployment --namespacedatabase # 在 database 命名空间里运行 --imagedocker.m.daocloud.io/library/postgres:17.6 # 用 postgres 镜像里面有 psql 客户端工具 -- # 分隔符后面是容器内执行的命令 psql # PostgreSQL 客户端命令 -h postgresql # 连接到 Service 名 postgresqlK8s DNS 自动解析 -U postgres # 用户名 postgres -d mydb # 连接到数据库 mydb -c \l # 执行 SQL 命令列出所有数据库 或者进入容器内 # 1. 进入容器 kubectl exec -it -n database postgresql-0 -- bash # 2. 连接数据库 psql -U postgres -d mydb # 3. 创建表如果还没有 CREATE TABLE storage_test (id int, msg text); # 4. 正确插入数据 INSERT INTO storage_test VALUES (1, hello persistence); # 5. 确认插入成功 SELECT * FROM storage_test; # 6. 退出 psql 和容器 \q exit # 7. 删除 Pod模拟重启 kubectl delete pod postgresql-0 -n database # 8. 等待 Pod 重新 Running kubectl get pods -n database -w # 9. 再次进入容器查询数据 kubectl exec -it -n database postgresql-0 -- bash psql -U postgres -d mydb -c SELECT * FROM storage_test; 开始部署 radis。 模式 适用场景 复杂度 单机 学习/开发环境 简单 1主1从 接近生产有读写分离 中等 Sentinel 生产自动故障转移 较复杂 # Helm 部署bitnami/redis 支持主从 helm install redis bitnami/redis \ --namespace database \ --set auth.passwordyourpassword \ --set architecturereplication \ --set replica.replicaCount1 \ --set image.registrydocker.m.daocloud.io \ --set image.repositorybitnami/redis \ --set master.persistence.size2Gi \ --set replica.persistence.size2Gi \ --set global.security.allowInsecureImagestrue # 如果拉不到手搓一个yaml kubectl apply -f - EOF apiVersion: v1 kind: ConfigMap metadata: name: redis-config namespace: database data: master.conf: | requirepass yourpassword masterauth yourpassword replica.conf: | requirepass yourpassword masterauth yourpassword replicaof redis-master 6379 --- apiVersion: apps/v1 kind: StatefulSet metadata: name: redis-master namespace: database spec: serviceName: redis-master replicas: 1 selector: matchLabels: app: redis role: master template: metadata: labels: app: redis role: master spec: affinity: nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 preference: matchExpressions: - key: kubernetes.io/hostname operator: In values: [k8s-node01] containers: - name: redis image: docker.m.daocloud.io/library/redis:7.4 command: [redis-server, /etc/redis/master.conf] ports: - containerPort: 6379 volumeMounts: - name: config mountPath: /etc/redis - name: data mountPath: /data volumes: - name: config configMap: name: redis-config items: - key: master.conf path: master.conf volumeClaimTemplates: - metadata: name: data spec: accessModes: [ReadWriteOnce] resources: requests: storage: 2Gi --- apiVersion: v1 kind: Service metadata: name: redis-master namespace: database spec: selector: app: redis role: master ports: - port: 6379 targetPort: 6379 --- apiVersion: apps/v1 kind: StatefulSet metadata: name: redis-replica namespace: database spec: serviceName: redis-replica replicas: 1 selector: matchLabels: app: redis role: replica template: metadata: labels: app: redis role: replica spec: affinity: nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 preference: matchExpressions: - key: kubernetes.io/hostname operator: In values: [k8s-node02] containers: - name: redis image: docker.m.daocloud.io/library/redis:7.4 command: [redis-server, /etc/redis/replica.conf] ports: - containerPort: 6379 volumeMounts: - name: config mountPath: /etc/redis - name: data mountPath: /data volumes: - name: config configMap: name: redis-config items: - key: replica.conf path: replica.conf volumeClaimTemplates: - metadata: name: data spec: accessModes: [ReadWriteOnce] resources: requests: storage: 2Gi --- apiVersion: v1 kind: Service metadata: name: redis-replica namespace: database spec: selector: app: redis role: replica ports: - port: 6379 targetPort: 6379 EOF 删除方法 # 删除 StatefulSet 和 Service kubectl delete statefulset redis-master redis-replica -n database kubectl delete service redis-master redis-replica -n database kubectl delete configmap redis-config -n database # 删除 PVC数据也一起删 kubectl delete pvc -n database>接下来 MinIO 创建一个 BucketJuiceFS 会用到 可以在 Web UI 操作 登录后点击左侧 Buckets 点击 Create Bucket Bucket 名称填 juicefs 点击 Create Bucket 继续部署 JuiceFS CSI Driver。 Step 1所有节点拉取 JuiceFS 镜像 sudo ctr -n k8s.io image pull docker.m.daocloud.io/juicedata/juicefs-csi-driver:v0.24.0 Step 2安装 JuiceFS CSI Driver curl -o juicefs-csi.yaml https://raw.githubusercontent.com/juicedata/juicefs-csi-driver/master/deploy/k8s.yaml 需要拉取4个镜像在所有节点执行 # juicefs 自己的镜像 sudo ctr -n k8s.io image pull docker.m.daocloud.io/juicedata/juicefs-csi-driver:v0.31.3 sudo ctr -n k8s.io image pull docker.m.daocloud.io/juicedata/csi-dashboard:v0.31.3 # k8s sig-storage 镜像 sudo ctr -n k8s.io image pull registry.aliyuncs.com/google_containers/csi-provisioner:v3.6.0 sudo ctr -n k8s.io image pull registry.aliyuncs.com/google_containers/csi-resizer:v1.9.0 sudo ctr -n k8s.io image pull registry.aliyuncs.com/google_containers/livenessprobe:v2.11.0 sudo ctr -n k8s.io image pull registry.aliyuncs.com/google_containers/csi-node-driver-registrar:v2.9.0 kubectl apply -f juicefs-csi.yaml 拉完后需要打 tag因为 YAML 里用的是 registry.k8s.io 地址 sudo ctr -n k8s.io image tag docker.m.daocloud.io/juicedata/juicefs-csi-driver:v0.31.3 docker.io/juicedata/juicefs-csi-driver:v0.31.3 sudo ctr -n k8s.io image tag docker.m.daocloud.io/juicedata/csi-dashboard:v0.31.3 docker.io/juicedata/csi-dashboard:v0.31.3 sudo ctr -n k8s.io image tag registry.aliyuncs.com/google_containers/csi-provisioner:v3.6.0 registry.k8s.io/sig-storage/csi-provisioner:v3.6.0 sudo ctr -n k8s.io image tag registry.aliyuncs.com/google_containers/csi-resizer:v1.9.0 registry.k8s.io/sig-storage/csi-resizer:v1.9.0 sudo ctr -n k8s.io image tag registry.aliyuncs.com/google_containers/livenessprobe:v2.11.0 registry.k8s.io/sig-storage/livenessprobe:v2.11.0 sudo ctr -n k8s.io image tag registry.aliyuncs.com/google_containers/csi-node-driver-registrar:v2.9.0 registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.9.0 验证 kubectl get pods -n kube-system | grep juicefs 续 Step 3 和 4创建 Secret 和 StorageClass Secret 文件定义了“连接到哪个 Redis 和 S3”而 StorageClass 文件则定义了“如何使用这些信息来动态创建存储卷” kubectl apply -f - EOF apiVersion: v1 kind: Secret metadata: name: juicefs-secret namespace: kube-system type: Opaque stringData: name: juicefs storage: s3 bucket: http://minio.minio.svc.cluster.local:9000/juicefs access-key: admin secret-key: yourpassword metaurl: redis://:1redis-master.database.svc.cluster.local:6379/1 --- apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: juicefs provisioner: csi.juicefs.com parameters: csi.storage.k8s.io/provisioner-secret-name: juicefs-secret csi.storage.k8s.io/provisioner-secret-namespace: kube-system csi.storage.k8s.io/node-publish-secret-name: juicefs-secret csi.storage.k8s.io/node-publish-secret-namespace: kube-system EOF 创建测试 PVC 验证 JuiceFS 是否正常工作 kubectl apply -f - EOF apiVersion: v1 kind: PersistentVolumeClaim metadata: name: juicefs-test-pvc namespace: default spec: accessModes: [ReadWriteMany] storageClassName: juicefs resources: requests: storage: 1Gi EOF kubectl get pvc juicefs-test-pvc ✅ Phase 3 全部完成 PostgreSQL 部署完成 Redis 1主1从部署完成 MinIO 部署完成 JuiceFS CSI 部署完成