menu

aPaaS 平台完整部署手册

  • date_range 23/01/2023 15:19
    点击量:
    info
    sort
    中台
    label
    aPAAS
    iPAAS
    IaaS
    SaaS

aPaaS 平台完整部署手册

3 Master + 1 Worker | Kubernetes v1.28.2 | CNCF 全栈

从裸机到完整 aPaaS 平台,可直接执行的生产级部署方案

项目
集群规模 4节点(3M+1W)
K8s版本 v1.28.2
Master节点 10.10.10.116 / 117 / 118
Worker节点 10.10.10.119
VIP地址 10.10.10.199
编写日期 XXXX年XX月XX日

一、节点规划

主机名 IP 角色 CPU 内存 磁盘 说明
master-1 10.10.10.116 Master 4核+ 8GB+ 50G+100G etcd + 控制面
master-2 10.10.10.117 Master 4核+ 8GB+ 50G+100G etcd + 控制面
master-3 10.10.10.118 Master 4核+ 8GB+ 50G+100G etcd + 控制面
worker-1 10.10.10.119 Worker 16核 32GB 50G+200G 所有业务Pod
  • VIP: 10.10.10.199(HAProxy + Keepalived 虚拟IP)
  • Pod CIDR: 10.244.0.0/16
  • Service CIDR: 10.96.0.0/12

二、系统初始化(4台全部执行)

⚠️ 以下步骤2.1-2.4需要在4台机器上逐一SSH进去执行,或使用ansible批量执行

2.1 设置主机名

分别在4台机器上执行对应命令:

# --- 10.10.10.116 上执行 ---
sudo hostnamectl set-hostname master-1

# --- 10.10.10.117 上执行 ---
sudo hostnamectl set-hostname master-2

# --- 10.10.10.118 上执行 ---
sudo hostnamectl set-hostname master-3

# --- 10.10.10.119 上执行 ---
sudo hostnamectl set-hostname worker-1

2.2 配置 hosts(4台都加)

cat << EOF | sudo tee -a /etc/hosts
10.10.10.199 k8s-vip
10.10.10.116 master-1
10.10.10.117 master-2
10.10.10.118 master-3
10.10.10.119 worker-1
EOF

2.3 关闭 swap + 内核参数(4台都执行)

# 关闭 swap
sudo swapoff -a
sudo sed -i '/swap/d' /etc/fstab

# 加载内核模块
cat << EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter

# 内核参数
cat << EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables  = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward                 = 1
EOF
sudo sysctl --system

2.4 安装 containerd(4台都执行)

sudo apt-get update
sudo apt-get install -y containerd

sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml

# 启用 SystemdCgroup
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' \
  /etc/containerd/config.toml

# 国内镜像加速(可选)
sudo sed -i 's|registry.k8s.io/pause:3.6|\
  registry.aliyuncs.com/google_containers/pause:3.9|' \
  /etc/containerd/config.toml

sudo systemctl restart containerd
sudo systemctl enable containerd

2.5 安装 kubeadm / kubelet / kubectl v1.28.2(4台都执行)

sudo apt-get install -y apt-transport-https ca-certificates curl gpg

# 添加 K8s v1.28 apt 源
curl -fsSL https://mirrors.aliyun.com/kubernetes-new/core/\
  stable/v1.28/deb/Release.key | \
  sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg

echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] \
  https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.28/deb/ \
  /" | sudo tee /etc/apt/sources.list.d/kubernetes.list

sudo apt-get update
sudo apt-get install -y kubelet=1.28.2-1.1 kubeadm=1.28.2-1.1 \
  kubectl=1.28.2-1.1
sudo apt-mark hold kubelet kubeadm kubectl

# 验证版本
kubeadm version

2.6 配置免密 SSH(master-1 上执行)

方便后续从 master-1 管理其他节点:

ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa
ssh-copy-id master-2
ssh-copy-id master-3
ssh-copy-id worker-1

三、HAProxy + Keepalived(仅 master-1 和 master-2)

⚠️ HAProxy 和 Keepalived 装在 K8s 外面,不是 Pod,所以需要直接 apt 安装

3.1 安装(master-1 和 master-2 都执行)

sudo apt-get install -y haproxy keepalived

3.2 HAProxy 配置(master-1 和 master-2 相同)

cat << 'EOF' | sudo tee /etc/haproxy/haproxy.cfg
global
    log /dev/log local0
    maxconn 4096
    daemon

defaults
    mode tcp
    log global
    option tcplog
    timeout connect 5s
    timeout client  30s
    timeout server  30s

frontend k8s-api
    bind *:8443
    default_backend k8s-masters

backend k8s-masters
    balance roundrobin
    option tcp-check
    server master-1 10.10.10.116:6443 check inter 3s fall 3 rise 2
    server master-2 10.10.10.117:6443 check inter 3s fall 3 rise 2
    server master-3 10.10.10.118:6443 check inter 3s fall 3 rise 2

listen stats
    bind *:9090
    mode http
    stats enable
    stats uri /stats
EOF

sudo systemctl restart haproxy
sudo systemctl enable haproxy

3.3 Keepalived 配置

master-1(MASTER 角色):

cat << 'EOF' | sudo tee /etc/keepalived/keepalived.conf
global_defs {
    router_id LVS_K8S
}

vrrp_script check_haproxy {
    script "/usr/bin/killall -0 haproxy"
    interval 3
    weight -2
    fall 10
    rise 2
}

vrrp_instance VI_1 {
    state MASTER
    interface ens33
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass K8sHA2026
    }
    virtual_ipaddress {
        10.10.10.199/24
    }
    track_script {
        check_haproxy
    }
}
EOF

sudo systemctl restart keepalived
sudo systemctl enable keepalived

⚠️ interface ens33 请改为你实际的网卡名,用 ip addr 查看

master-2(BACKUP 角色),只改两处:

# master-2 上执行,配置与 master-1 相同,仅改以下两行:
    state BACKUP        # MASTER → BACKUP
    priority 90          # 100 → 90

# 其余完全一致,然后启动
sudo systemctl restart keepalived
sudo systemctl enable keepalived

3.4 验证 VIP

# 在 master-1 上执行
ip addr show | grep 10.10.10.199
# 应看到 10.10.10.199/24 绑定在网卡上

# 测试 VIP 可达
ping -c 3 10.10.10.199

四、初始化 Kubernetes v1.28.2 集群

4.1 初始化第一个 Master(仅 master-1 执行)

sudo kubeadm init \
  --kubernetes-version=v1.28.2 \
  --control-plane-endpoint='k8s-vip:8443' \
  --upload-certs \
  --pod-network-cidr=10.244.0.0/16 \
  --service-cidr=10.96.0.0/12 \
  --image-repository=registry.aliyuncs.com/google_containers

# 配置 kubectl
mkdir -p $HOME/.kube
sudo cp /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

⚠️ 务必记录输出中的两条 join 命令:一条带 --control-plane(给Master用),一条不带(给Worker用)

4.2 加入 master-2 和 master-3(分别在两台上执行)

# 在 master-2 (10.10.10.117) 上执行:
sudo kubeadm join k8s-vip:8443 \
  --token <token> \
  --discovery-token-ca-cert-hash sha256:<hash> \
  --control-plane \
  --certificate-key <cert-key>

# 配置 kubectl
mkdir -p $HOME/.kube
sudo cp /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

# master-3 (10.10.10.118) 执行同样的命令

4.3 加入 Worker(仅 worker-1 执行)

# 在 worker-1 (10.10.10.119) 上执行(不带 --control-plane):
sudo kubeadm join k8s-vip:8443 \
  --token <token> \
  --discovery-token-ca-cert-hash sha256:<hash>

⚠️ Worker 不需要配置 kubectl,不需要 --control-plane--certificate-key

4.4 验证集群状态(master-1 上执行)

kubectl get nodes -o wide

# 预期输出:
# master-1   NotReady   control-plane   ...
# master-2   NotReady   control-plane   ...
# master-3   NotReady   control-plane   ...
# worker-1   NotReady   <none>          ...

# NotReady 是正常的,因为还没装 CNI

4.5 安装 Calico CNI(master-1 上执行)

# 安装 Calico v3.26(兼容 K8s v1.28)
kubectl apply -f https://raw.githubusercontent.com/projectcalico/\
  calico/v3.26.4/manifests/calico.yaml

# 等待所有节点 Ready(约2分钟)
watch kubectl get nodes

# 预期:4个节点全部 Ready

# 指定网卡检测方式(避免多网卡环境下选错IP)
kubectl set env daemonset/calico-node -n kube-system \
  IP_AUTODETECTION_METHOD=cidr=10.10.10.0/24

4.6 给 Worker 打标签(master-1 上执行)

# 标记 worker 角色
kubectl label node worker-1 node-role.kubernetes.io/worker=''

# 确认 Master 有 taint(不调度业务 Pod)
kubectl describe node master-1 | grep Taint
# 应输出: node-role.kubernetes.io/control-plane:NoSchedule

4.7 安装 Helm(master-1 上执行)

# 方式1:官方脚本
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash

# 方式2:华为云镜像(国内更快)
curl https://mirrors.huaweicloud.com/helm/v3.13.3/helm-v3.13.3-linux-amd64.tar.gz -o helm.tar.gz
tar -zxvf helm.tar.gz
sudo mv linux-amd64/helm /usr/local/bin/helm

# 验证
helm version

五、存储层:Longhorn

⚠️ 以下所有命令均在 master-1 上通过 kubectl/helm 执行,不用SSH到其他节点

5.1 前置依赖(仅 worker-1 上安装)

# SSH 到 worker-1 安装依赖
ssh worker-1 'sudo apt-get install -y open-iscsi nfs-common'
ssh worker-1 'sudo systemctl enable iscsid && sudo systemctl start iscsid'

5.2 安装 Longhorn

helm repo add longhorn https://charts.longhorn.io
helm repo update

helm install longhorn longhorn/longhorn \
  --namespace longhorn-system --create-namespace \
  --set defaultSettings.defaultReplicaCount=1 \
  --set defaultSettings.defaultDataLocality=best-effort \
  --set longhornManager.tolerations[0].key=\
  node-role.kubernetes.io/control-plane \
  --set longhornManager.tolerations[0].effect=NoSchedule

# 设为默认 StorageClass
kubectl patch storageclass longhorn -p \
  '{"metadata":{"annotations":{\
  "storageclass.kubernetes.io/is-default-class":"true"}}}'

# 等待就绪
kubectl -n longhorn-system get pods -w

如果镜像拉不下来,在 Mac 上下载再传过去:

# Mac 上(有VPN)
docker pull longhornio/longhorn-instance-manager:v1.6.2
docker save longhornio/longhorn-instance-manager:v1.6.2 -o instance-manager.tar
scp instance-manager.tar root@10.10.10.117:~/

# master-2 上导入
sudo ctr -n k8s.io image import ~/instance-manager.tar

# CSI 相关镜像
docker pull longhornio/csi-attacher:v4.5.1
docker pull longhornio/csi-provisioner:v3.6.4
docker pull longhornio/csi-resizer:v1.10.1
docker pull longhornio/csi-snapshotter:v6.3.4
docker pull longhornio/livenessprobe:v2.12.0

docker save \
  longhornio/csi-attacher:v4.5.1 \
  longhornio/csi-provisioner:v3.6.4 \
  longhornio/csi-resizer:v1.10.1 \
  longhornio/csi-snapshotter:v6.3.4 \
  longhornio/livenessprobe:v2.12.0 \
  -o longhorn-csi.tar

scp longhorn-csi.tar root@10.10.10.119:~/

# worker-1 上导入
sudo ctr -n k8s.io image import ~/longhorn-csi.tar

# 回 master-1 重建
kubectl delete pods -n longhorn-system --all --force --grace-period=0
kubectl -n longhorn-system get pods -w

六、创建命名空间

kubectl create namespace apaas
kubectl create namespace monitoring
kubectl label namespace apaas apaas-managed=true

七、MySQL 数据库

7.1 创建密钥

kubectl -n apaas create secret generic mysql-secret \
  --from-literal=MYSQL_ROOT_PASSWORD=Apaas@2026Root \
  --from-literal=MYSQL_DATABASE=nocobase \
  --from-literal=MYSQL_USER=nocobase \
  --from-literal=MYSQL_PASSWORD=Nocobase@2026

7.2 部署 MySQL StatefulSet

cat << 'YAML' | kubectl apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pvc
  namespace: apaas
spec:
  accessModes: [ReadWriteOnce]
  resources:
    requests:
      storage: 50Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql
  namespace: apaas
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
        - name: mysql
          image: mysql:8.0
          ports:
            - containerPort: 3306
          envFrom:
            - secretRef:
                name: mysql-secret
          resources:
            requests: { cpu: '1', memory: 2Gi }
            limits: { cpu: '4', memory: 8Gi }
          volumeMounts:
            - name: data
              mountPath: /var/lib/mysql
          livenessProbe:
            exec:
              command: ['mysqladmin', 'ping', '-u', 'root',
                '-p$(MYSQL_ROOT_PASSWORD)']
            initialDelaySeconds: 30
            periodSeconds: 10
      volumes:
        - name: data
          persistentVolumeClaim:
            claimName: mysql-pvc
---
apiVersion: v1
kind: Service
metadata:
  name: mysql
  namespace: apaas
spec:
  selector:
    app: mysql
  ports:
    - port: 3306
      targetPort: 3306
  clusterIP: None
YAML
# 等待 MySQL 就绪
kubectl -n apaas wait --for=condition=ready pod -l app=mysql \
  --timeout=120s

八、NATS 消息队列(CNCF 毕业)

helm repo add nats https://nats-io.github.io/k8s/helm/charts/
helm repo update

helm install nats nats/nats \
  --namespace apaas \
  --set config.jetstream.enabled=true \
  --set config.jetstream.fileStore.pvc.size=10Gi \
  --set config.cluster.enabled=false

kubectl -n apaas get pods -l app.kubernetes.io/name=nats

如果 Helm chart 下载超时,在 Mac 上先下载 chart:

# Mac 上
helm repo add nats https://nats-io.github.io/k8s/helm/charts/
helm repo update
helm pull nats/nats
scp nats-*.tgz root@10.10.10.116:~/

# master-1 上用本地文件安装
helm install nats ./nats-*.tgz \
  --namespace apaas \
  --set config.jetstream.enabled=true \
  --set config.jetstream.fileStore.pvc.size=10Gi \
  --set config.cluster.enabled=false

九、API 网关:Emissary-Ingress(Envoy, CNCF 毕业)

helm repo add datawire https://app.getambassador.io
helm repo update

helm install emissary datawire/emissary-ingress \
  --namespace emissary --create-namespace \
  --set replicaCount=1 \
  --set service.type=NodePort \
  --set service.nodePorts.http=30080 \
  --set service.nodePorts.https=30443

# 验证
kubectl -n emissary get pods

如果镜像名不对,先在 Mac 上查正确的镜像名:

# Mac 上先下载 chart
helm repo add datawire https://app.getambassador.io
helm repo update
helm pull datawire/emissary-ingress

# 查看 chart 里用的镜像
helm template emissary ./emissary-ingress-*.tgz | grep "image:" | sort -u

# 传到 master-1 用本地文件安装
scp emissary-ingress-*.tgz root@10.10.10.116:~/

helm install emissary ./emissary-ingress-*.tgz \
  --namespace emissary --create-namespace \
  --set replicaCount=1 \
  --set service.type=NodePort \
  --set service.nodePorts.http=30080 \
  --set service.nodePorts.https=30443

kubectl -n emissary get pods -w

配置 NocoBase 路由:

cat << 'YAML' | kubectl apply -f -
apiVersion: getambassador.io/v3alpha1
kind: Listener
metadata:
  name: http-listener
  namespace: emissary
spec:
  port: 8080
  protocol: HTTP
  securityModel: XFP
  hostBinding:
    namespace:
      from: ALL
---
apiVersion: getambassador.io/v3alpha1
kind: Mapping
metadata:
  name: nocobase-mapping
  namespace: apaas
spec:
  hostname: '*'
  prefix: /
  service: nocobase.apaas:13000
YAML

部署完成后通过 http://10.10.10.119:30080 访问 NocoBase


十、NocoBase 低代码引擎(aPaaS 核心)

cat << 'YAML' | kubectl apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nocobase-storage
  namespace: apaas
spec:
  accessModes: [ReadWriteOnce]
  resources:
    requests:
      storage: 20Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nocobase
  namespace: apaas
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nocobase
  template:
    metadata:
      labels:
        app: nocobase
    spec:
      containers:
        - name: nocobase
          image: nocobase/nocobase:latest
          ports:
            - containerPort: 13000
          env:
            - name: DB_DIALECT
              value: mysql
            - name: DB_HOST
              value: mysql.apaas.svc.cluster.local
            - name: DB_PORT
              value: '3306'
            - name: DB_DATABASE
              value: nocobase
            - name: DB_USER
              value: nocobase
            - name: DB_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql-secret
                  key: MYSQL_PASSWORD
            - name: APP_KEY
              value: apaas-nocobase-secret-key-2026
          resources:
            requests: { cpu: 500m, memory: 1Gi }
            limits: { cpu: '4', memory: 4Gi }
          volumeMounts:
            - name: storage
              mountPath: /app/nocobase/storage
          readinessProbe:
            httpGet:
              path: /api/app:getInfo
              port: 13000
            initialDelaySeconds: 60
            periodSeconds: 10
      volumes:
        - name: storage
          persistentVolumeClaim:
            claimName: nocobase-storage
---
apiVersion: v1
kind: Service
metadata:
  name: nocobase
  namespace: apaas
spec:
  selector:
    app: nocobase
  type: NodePort
  ports:
    - port: 13000
      targetPort: 13000
      nodePort: 31300
YAML
# 等待就绪(首次启动较慢,约2-3分钟)
kubectl -n apaas get pods -l app=nocobase -w

直接访问: http://10.10.10.119:31300

默认账号: admin@nocobase.com / admin123


十一、Dapr 微服务运行时(CNCF 孵化)

helm repo add dapr https://dapr.github.io/helm-charts/
helm repo update

helm install dapr dapr/dapr \
  --namespace dapr-system --create-namespace \
  --set global.ha.enabled=false \
  --version 1.14

# 验证
kubectl -n dapr-system get pods

配置 NATS 作为 Pub/Sub + MySQL 状态存储:

cat << 'YAML' | kubectl apply -f -
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: pubsub
  namespace: apaas
spec:
  type: pubsub.nats
  version: v1
  metadata:
    - name: natsURL
      value: nats://nats.apaas.svc:4222
    - name: jetStream
      value: 'true'
---
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: statestore
  namespace: apaas
spec:
  type: state.mysql
  version: v1
  metadata:
    - name: connectionString
      value: 'nocobase:Nocobase@2026@tcp(mysql.apaas.svc:3306)/'
    - name: schemaName
      value: dapr_state
YAML

为 NocoBase 启用 Dapr Sidecar:

kubectl -n apaas patch deployment nocobase -p \
  '{"spec":{"template":{"metadata":{"annotations":{
  "dapr.io/enabled":"true",
  "dapr.io/app-id":"nocobase",
  "dapr.io/app-port":"13000"
  }}}}}'

十二、Argo Workflows 工作流引擎(CNCF 毕业)

kubectl create namespace argo

kubectl apply -n argo -f \
  https://github.com/argoproj/argo-workflows/releases/\
  download/v3.5.5/quick-start-minimal.yaml

# 暴露 Argo UI(NodePort)
kubectl -n argo patch svc argo-server -p \
  '{"spec":{"type":"NodePort","ports":[{\
  "port":2746,"targetPort":2746,"nodePort":32746}]}}'

# 验证
kubectl -n argo get pods

Argo UI: https://10.10.10.119:32746


十三、OPA Gatekeeper 权限引擎(CNCF 毕业)

helm repo add gatekeeper \
  https://open-policy-agent.github.io/gatekeeper/charts
helm repo update

helm install gatekeeper gatekeeper/gatekeeper \
  --namespace gatekeeper-system --create-namespace \
  --set replicas=1

多租户标签约束策略:

cat << 'YAML' | kubectl apply -f -
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
  name: k8srequiredlabels
spec:
  crd:
    spec:
      names:
        kind: K8sRequiredLabels
      validation:
        openAPIV3Schema:
          type: object
          properties:
            labels:
              type: array
              items: { type: string }
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package k8srequiredlabels
        violation[{"msg": msg}] {
          provided := {l | input.review.object.metadata.labels[l]}
          required := {l | l := input.parameters.labels[_]}
          missing := required - provided
          count(missing) > 0
          msg := sprintf("Missing: %v", [missing])
        }
---
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata:
  name: require-tenant-label
spec:
  match:
    kinds:
      - apiGroups: ['']
        kinds: [Namespace]
    namespaceSelector:
      matchLabels:
        apaas-managed: 'true'
  parameters:
    labels: ['tenant-id']
YAML

十四、可观测性:Prometheus + Grafana + Jaeger

14.1 Prometheus + Grafana

helm repo add prometheus-community \
  https://prometheus-community.github.io/helm-charts
helm repo update

helm install monitoring \
  prometheus-community/kube-prometheus-stack \
  --namespace monitoring \
  --set grafana.adminPassword=admin2026 \
  --set grafana.service.type=NodePort \
  --set grafana.service.nodePort=31301 \
  --set prometheus.prometheusSpec.retention=7d \
  --set prometheus.prometheusSpec.storageSpec.\
  volumeClaimTemplate.spec.resources.requests.storage=50Gi \
  --set prometheus.service.type=NodePort \
  --set prometheus.service.nodePort=31090

kubectl -n monitoring get pods

Grafana: http://10.10.10.119:31301 (admin / admin2026)

Prometheus: http://10.10.10.119:31090

14.2 Jaeger 追踪

helm repo add jaegertracing \
  https://jaegertracing.github.io/helm-charts
helm repo update

helm install jaeger jaegertracing/jaeger \
  --namespace monitoring \
  --set provisionDataStore.cassandra=false \
  --set storage.type=memory \
  --set allInOne.enabled=true \
  --set query.service.type=NodePort \
  --set query.service.nodePort=31686

Dapr 集成 Jaeger:

cat << 'YAML' | kubectl apply -f -
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
  name: tracing
  namespace: apaas
spec:
  tracing:
    samplingRate: '1'
    otel:
      endpointAddress: \
        jaeger-collector.monitoring.svc:4317
      isSecure: false
      protocol: grpc
YAML

Jaeger UI: http://10.10.10.119:31686

14.3 Fluentd 日志采集

helm repo add fluent https://fluent.github.io/helm-charts
helm repo update

helm install fluentd fluent/fluentd \
  --namespace monitoring \
  --set kind=DaemonSet

十五、GitOps:Flux(CNCF 毕业)

# 安装 Flux CLI
curl -s https://fluxcd.io/install.sh | sudo bash

# 初始化(连接 GitHub 仓库)
export GITHUB_TOKEN=<your-github-token>

flux bootstrap github \
  --owner=andrewyghub \
  --repository=apaas-gitops \
  --branch=main \
  --path=./clusters/production \
  --personal

# 验证
flux check

十六、完整验证清单

# 检查项 验证命令 预期 访问地址
1 节点状态 kubectl get nodes 4 Ready -
2 VIP ping 10.10.10.199 -
3 HAProxy curl http://10.10.10.199:9090/stats 200 :9090/stats
4 Calico kubectl -n kube-system get pods Running -
5 Longhorn kubectl -n longhorn-system get pods Running -
6 MySQL kubectl -n apaas get pods -l app=mysql Running -
7 NATS kubectl -n apaas get pods -l app.kubernetes.io/name=nats Running -
8 NocoBase curl http://10.10.10.119:31300 200 :31300
9 Emissary kubectl -n emissary get pods Running :30080
10 Dapr kubectl -n dapr-system get pods Running -
11 Argo kubectl -n argo get pods Running :32746
12 OPA kubectl -n gatekeeper-system get pods Running -
13 Grafana curl http://10.10.10.119:31301 200 :31301
14 Prometheus curl http://10.10.10.119:31090 200 :31090
15 Jaeger curl http://10.10.10.119:31686 200 :31686
16 Flux flux check All OK -

十七、访问入口汇总

服务 URL 账号 密码
NocoBase http://10.10.10.119:31300 admin@nocobase.com admin123
Grafana http://10.10.10.119:31301 admin admin2026
Prometheus http://10.10.10.119:31090 - -
Argo Workflows https://10.10.10.119:32746 - -
Jaeger http://10.10.10.119:31686 - -
HAProxy Stats http://10.10.10.199:9090/stats - -
Emissary 网关 http://10.10.10.119:30080 - -

十八、部署顺序与耗时估算

# 步骤 耗时 执行位置 优先级 章节
1 系统初始化 + containerd + kubeadm 30min 4台全部 P0 第二章
2 HAProxy + Keepalived 15min 116/117 P0 第三章
3 kubeadm init + join + Calico 20min master-1 P0 第四章
4 Longhorn 存储 10min master-1 P0 第五章
5 MySQL 数据库 10min master-1 P0 第七章
6 NATS 消息队列 5min master-1 P1 第八章
7 Emissary API 网关 5min master-1 P1 第九章
8 NocoBase 低代码引擎 10min master-1 P0 第十章
9 Dapr 运行时 10min master-1 P1 第十一章
10 Argo Workflows 5min master-1 P1 第十二章
11 OPA Gatekeeper 5min master-1 P1 第十三章
12 Prometheus + Grafana + Jaeger + Fluentd 15min master-1 P2 第十四章
13 Flux GitOps 5min master-1 P2 第十五章
  总计 约 2.5h      
  • P0 = 最小可用(K8s + 存储 + DB + NocoBase),装完就能用
  • P1 = 完整 aPaaS(网关 + 消息 + 运行时 + 工作流 + 权限)
  • P2 = 可观测 + GitOps(监控 + 日志 + 追踪 + 持续交付)


评论:


技术文章推送

手机、电脑实用软件分享

微信搜索公众号: AndrewYG的算法世界
wechat 微信公众号:AndrewYG的算法世界

热门文章