Skip to content

Vận hành

CI/CD Pipeline

BANA dùng GitLab CI/CD để build, test và deploy các service. Registry image có thể là GitLab Container Registry hoặc registry self-hosted (cấu hình qua biến env NX_REGISTRY).

  • Registry: bcr.bana.com.vn (cấu hình qua biến env NX_REGISTRY)
  • Staging: Triển khai thủ công qua deploy.sh / deploy-full.sh
  • Production: GitOps auto-deploy khi merge vào main

Kiến trúc Pipeline

Ví dụ .gitlab-ci.yml

### .gitlab-ci.yml Example
yaml
stages:
  - build
  - test
  - push
  - deploy

variables:
  REGISTRY: bcr.bana.com.vn
  # Services to build — set dynamically or list all
  SERVICES: "identity commerce sale finance inventory ledger pricing payment signal"

# --- Build Stage ---
build:
  stage: build
  image: oven/bun:1
  script:
    - bun install --frozen-lockfile
    - bun run rebuild
  artifacts:
    paths:
      - packages/*/dist/
    expire_in: 1 hour
  rules:
    - if: $CI_MERGE_REQUEST_IID
    - if: $CI_COMMIT_BRANCH == "main"
    - if: $CI_COMMIT_BRANCH == "develop"

# --- Test Stage ---
test:
  stage: test
  image: oven/bun:1
  needs: [build]
  script:
    - bun run test
  rules:
    - if: $CI_MERGE_REQUEST_IID
    - if: $CI_COMMIT_BRANCH == "main"
    - if: $CI_COMMIT_BRANCH == "develop"

# --- Push Stage (per service) ---
.push-template: &push-template
  stage: push
  image: docker:27
  services:
    - docker:27-dind
  needs: [test]
  before_script:
    - echo "$CI_REGISTRY_PASSWORD" | docker login $CI_REGISTRY -u $CI_REGISTRY_USER --password-stdin
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
    - if: $CI_COMMIT_BRANCH == "develop"

push-identity:
  <<: *push-template
  script:
    - docker build -t $REGISTRY/nx-identity:$CI_COMMIT_SHORT_SHA -t $REGISTRY/nx-identity:latest -f packages/identity/Dockerfile .
    - docker push $REGISTRY/nx-identity --all-tags

push-commerce:
  <<: *push-template
  script:
    - docker build -t $REGISTRY/nx-commerce:$CI_COMMIT_SHORT_SHA -t $REGISTRY/nx-commerce:latest -f packages/commerce/Dockerfile .
    - docker push $REGISTRY/nx-commerce --all-tags

push-sale:
  <<: *push-template
  script:
    - docker build -t $REGISTRY/nx-sale:$CI_COMMIT_SHORT_SHA -t $REGISTRY/nx-sale:latest -f packages/sale/Dockerfile .
    - docker push $REGISTRY/nx-sale --all-tags

push-payment:
  <<: *push-template
  script:
    - docker build -t $REGISTRY/nx-payment:$CI_COMMIT_SHORT_SHA -t $REGISTRY/nx-payment:latest -f packages/payment/Dockerfile .
    - docker push $REGISTRY/nx-payment --all-tags

push-signal:
  <<: *push-template
  script:
    - docker build -t $REGISTRY/nx-signal:$CI_COMMIT_SHORT_SHA -t $REGISTRY/nx-signal:latest -f packages/signal/Dockerfile .
    - docker push $REGISTRY/nx-signal --all-tags

# Frontend apps
push-client:
  <<: *push-template
  script:
    - docker build -t $REGISTRY/nx-client:$CI_COMMIT_SHORT_SHA -t $REGISTRY/nx-client:latest -f apps/client/Dockerfile .
    - docker push $REGISTRY/nx-client --all-tags

push-bo:
  <<: *push-template
  script:
    - docker build -t $REGISTRY/nx-bo:$CI_COMMIT_SHORT_SHA -t $REGISTRY/nx-bo:latest -f apps/bo/Dockerfile .
    - docker push $REGISTRY/nx-bo --all-tags

# --- Deploy Stage ---
deploy-staging:
  stage: deploy
  image: bitnami/kubectl:latest
  needs: [push-identity, push-commerce, push-sale, push-payment, push-signal, push-client, push-bo]
  environment:
    name: staging
  when: manual
  script:
    - bash infrastructure/deployments/staging/deploy-full.sh --from 6
  rules:
    - if: $CI_COMMIT_BRANCH == "develop"

deploy-production:
  stage: deploy
  image: bitnami/kubectl:latest
  needs: [push-identity, push-commerce, push-sale, push-payment, push-signal, push-client, push-bo]
  environment:
    name: production
  script:
    - kubectl apply -k k8s/overlays/production/
    - kubectl rollout status deployment -n nx-backend --timeout=300s
  rules:
    - if: $CI_COMMIT_BRANCH == "main"

Chiến lược Gắn Tag Image

BranchTagSử dụng
develop\<commit-sha\>, latestTriển khai staging
main\<commit-sha\>, latest, v\<semver\>Triển khai production
Feature branch\<commit-sha\>Chỉ build/test, không push

Build Image

Dùng script build tại infrastructure/registry/build.sh:

bash
# Build a single service (tag defaults to git short SHA)
bash infrastructure/registry/build.sh identity

# Build with a specific tag
bash infrastructure/registry/build.sh identity v1.0.0

# Build and push to registry
bash infrastructure/registry/build.sh identity --push
bash infrastructure/registry/build.sh identity v1.0.0 --push

# Build all services
bash infrastructure/registry/build.sh all --push

Registry được cấu hình qua biến env NX_REGISTRY. Nếu chưa set, nó mặc định về giá trị trong script.

Pattern Dockerfile

Tất cả Dockerfile backend service đều dùng multi-stage build với user bun:

dockerfile
FROM docker.io/oven/bun:1.3.10-alpine AS base

RUN mkdir -p /home/bun/app && chown -R bun:bun /home/bun/app
WORKDIR /home/bun/app

USER bun

# ... deps, builder, production stages ...

Điểm chính:

  • Base image: docker.io/oven/bun:1.3.10-alpine
  • Chạy dưới user bun (không phải root, không phải nx-operator)
  • Working directory: /home/bun/app
  • Tất cả lệnh COPY dùng --chown=bun

Xác thực Registry

Pod cần imagePullSecrets để pull từ container registry:

bash
# Create the registry secret (Bana Container Registry)
./kc create secret docker-registry bcr-registry \
  --docker-server=bcr.bana.com.vn \
  --docker-username=<deploy-token-user> \
  --docker-password=<deploy-token-password> \
  -n nx-backend

# Repeat for other namespaces
for ns in nx-app nx-internal; do
  ./kc create secret docker-registry bcr-registry \
    -n $ns \
    --docker-server=bcr.bana.com.vn \
    --docker-username=<deploy-token-user> \
    --docker-password=<deploy-token-password>
done

Thứ tự Khởi động

Identity phải chạy trước khi bất kỳ backend service nào khác khởi động. Điều này được enforce qua init container.

Chuỗi Dependency

Tất cả service ngoài identity đều có init container này:

All services except identity have this init container:
yaml
initContainers:
  - name: wait-for-identity
    image: busybox:1.36
    command:
      - sh
      - -c
      - |
        echo "Waiting for identity service..."
        until wget -qO- http://nx-identity.nx-backend.svc.cluster.local:3000/v1/api/identity/health 2>/dev/null; do
          echo "Identity not ready, retrying in 2s..."
          sleep 2
        done
        echo "Identity is ready!"

Migration Jobs

Database migration chạy dưới dạng Kubernetes Job trước khi Deployment của service khởi động. Mỗi service có migration Job riêng.

Template Migration Job

Job: nx-{service}-migrate-
yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: nx-<service>-migrate-<version>
  namespace: nx-backend
  labels:
    app.kubernetes.io/name: <service>
    app.kubernetes.io/component: migration
spec:
  backoffLimit: 3
  activeDeadlineSeconds: 300
  template:
    spec:
      restartPolicy: OnFailure
      nodeSelector:
        node.kubernetes.io/pool: default  # staging: default, production: app
      imagePullSecrets:
        - name: bcr-registry
      initContainers:
        - name: wait-for-identity
          image: busybox:1.36
          command: ['sh', '-c', 'until wget -qO- http://nx-identity.nx-backend.svc.cluster.local:3000/v1/api/identity/health; do sleep 2; done']
        - name: wait-for-db
          image: postgres:16-alpine
          command: ['sh', '-c', 'until pg_isready -h nx-postgresql-primary.nx-persistent.svc.cluster.local -p 5432; do sleep 2; done']
      containers:
        - name: migrate
          image: <registry>/<service>:<tag>
          command: ['bun', 'run', 'migrate']
          envFrom:
            - configMapRef:
                name: nx-shared-config
            - configMapRef:
                name: nx-<service>-config
            - secretRef:
                name: nx-shared-secret
            - secretRef:
                name: nx-<service>-secret
          resources:
            requests:
              cpu: 100m
              memory: 128Mi
            limits:
              cpu: 500m
              memory: 256Mi

Thứ tự Migration

Migration phải chạy theo thứ tự dependency:

  1. identity -- Tạo bảng auth, seed roles/users
  2. commerce -- Bảng product, category, variant
  3. sale -- Bảng sale order, checkout
  4. finance -- Bảng ledger, account
  5. inventory -- Bảng stock, warehouse
  6. pricing -- Bảng fare, promotion, tax
  7. payment -- Bảng transaction, webhook
  8. Các service khác theo nhu cầu

Trình tự Triển khai

Staging: Triển khai Thủ công

Staging dùng shell script với wrapper kubectl ./kc. Có hai chế độ triển khai:

Cập nhật Single Service (phổ biến nhất)

bash
# Deploy a single service (tag defaults to current git short SHA)
bash infrastructure/deployments/staging/deploy.sh <service> [tag]

# Examples:
bash infrastructure/deployments/staging/deploy.sh identity
bash infrastructure/deployments/staging/deploy.sh sale abc1234
bash infrastructure/deployments/staging/deploy.sh payment-api v1.0.0

Các service khả dụng:

  • Backend: identity, commerce, sale, finance, inventory, ledger, pricing, payment-api, payment-worker, signal

  • Frontend: client, bo, wiki, sale-renderer

Script ánh xạ tên service tới đúng deployment, namespace, container và image, sau đó chạy kubectl set image + rollout status.

Triển khai Full Stack (setup ban đầu hoặc rebuild)

bash
# Preview without applying
bash infrastructure/deployments/staging/deploy-full.sh --dry-run

# Full deployment (all steps)
bash infrastructure/deployments/staging/deploy-full.sh

# Run only a specific step
bash infrastructure/deployments/staging/deploy-full.sh --step 6

# Resume from a specific step
bash infrastructure/deployments/staging/deploy-full.sh --from 3

Các bước:

BướcThực hiện
0Setup cluster (namespaces, quotas, limits, priority classes)
1Network policies
2Secrets (hỏi tương tác, chạy create-secrets.sh)
3Tầng dữ liệu (CNPG operator, PostgreSQL, Redis Cluster, Kafka, Typesense)
4Ingress controller (nginx)
5API gateway (Traefik)
6Application services (backend + frontend)
7Rule ingress (routing domain)
8Xác thực sau triển khai (pod status, health check)

Tạo Secrets

Secrets không được lưu trong git. Tạo qua helper script hoặc thủ công:

bash
# Option 1: Helper script
bash infrastructure/deployments/staging/manifests/02-secrets/create-secrets.sh

# Option 2: Manual creation (see infrastructure/deployments/staging/manifests/02-secrets/README.md)

Wrapper kubectl

Script ./kc tại infrastructure/deployments/staging/kc tự động nạp staging kubeconfig:

bash
# From the staging directory
./kc get nodes
./kc get pods -n nx-backend
./kc logs -f deploy/nx-identity -n nx-backend

# From project root
infrastructure/deployments/staging/kc get pods -n nx-backend

File kubeconfig được gitignore. Đặt nó tại:

infrastructure/deployments/staging/kubeconfig.yaml

Develop: Triển khai Docker Compose

Phát triển local dùng Docker Compose qua wrapper dc và Makefile targets.

Wrapper Docker Compose

bash
# From infrastructure/deployments/develop/ directory
./dc ps
./dc up -d
./dc up -d identity commerce sale
./dc down
./dc logs -f dev-nx-sale

# Optional stacks
./dc --with-cdc up -d           # Include CDC infrastructure
./dc --with-monitoring up -d    # Include Prometheus + Grafana
./dc --with-cdc --with-monitoring up -d

Makefile Targets

bash
# Deploy dependencies (PostgreSQL, Redis, etc.)
make deploy-dev-deps

# Deploy individual services
make deploy-dev-identity
make deploy-dev-commerce
make deploy-dev-sale
make deploy-dev-payment
# ... etc.

# Deploy all backend services at once
make deploy-dev-backend-services

Các script nằm tại infrastructure/deployments/develop/scripts/.

Production: GitOps Auto-Deploy

Production tự động triển khai khi code được merge vào main. Pipeline GitLab CI/CD xử lý toàn bộ trình tự.

Triển khai production bao gồm các bước bổ sung:

bash
#!/bin/bash
# deploy-production.sh — Called by GitLab CI/CD

set -euo pipefail
TAG=$CI_COMMIT_SHORT_SHA

echo "=== Run Migrations ==="
# Identity migration first
kubectl apply -f k8s/overlays/production/backend/identity/migration.yaml
kubectl wait --namespace nx-backend --for=condition=complete job/nx-identity-migrate-$TAG --timeout=120s

# Other migrations in parallel
for svc in commerce sale finance inventory pricing payment; do
  kubectl apply -f k8s/overlays/production/backend/$svc/migration.yaml
done
kubectl wait --namespace nx-backend --for=condition=complete job --selector=app.kubernetes.io/component=migration --timeout=300s

echo "=== Deploy via Kustomize ==="
kubectl apply -k k8s/overlays/production/

echo "=== Wait for Rollout ==="
for deploy in $(kubectl get deploy -n nx-backend -o name); do
  kubectl rollout status $deploy -n nx-backend --timeout=300s
done

echo "=== Verify Health ==="
for svc in identity commerce sale finance inventory ledger pricing payment-api signal; do
  STATUS=$(kubectl exec deploy/nx-$svc -n nx-backend -- wget -qO- http://localhost:3000/v1/api/${svc/payment-api/payment}/health 2>/dev/null || echo "FAIL")
  echo "$svc: $STATUS"
done

Rolling Updates

Tất cả Deployment dùng strategy RollingUpdate mặc định:

All Deployments use the default RollingUpdate strategy:
yaml
spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 0     # No downtime for HA services
      maxSurge: 1           # One extra pod during rollout

Đối với service single-replica:

For single-replica services:
yaml
spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1     # Brief downtime acceptable
      maxSurge: 1

Rollback

bash
# Rollback a single service deployment
./kc rollout undo deployment/nx-<service> -n nx-backend

# Rollback to a specific revision
./kc rollout undo deployment/nx-<service> -n nx-backend --to-revision=<revision>

# Check rollout history
./kc rollout history deployment/nx-<service> -n nx-backend

Thao tác Bảo trì

Scaling

bash
# Scale identity for high traffic (staging — manual)
./kc scale deployment nx-identity --replicas=3 -n nx-backend

# Scale down after traffic subsides
./kc scale deployment nx-identity --replicas=2 -n nx-backend

INFO

Trong production, các HA service (identity, sale, payment-api, signal) dùng HPA cho auto-scaling. Override thủ công là tạm thời và sẽ bị HPA reconcile lại.

Logs

bash
# View logs for a specific service
./kc logs -l app.kubernetes.io/name=identity -n nx-backend --tail=100 -f

# View logs across all services
./kc logs -l app.kubernetes.io/component=backend -n nx-backend --tail=50

# View migration job logs
./kc logs job/nx-identity-migrate -n nx-backend

# Query logs via Loki/Grafana for historical data
# Grafana > Explore > Loki > {namespace="nx-backend", service="identity"}

Debug

bash
# Exec into a running pod
./kc exec -it deploy/nx-identity -n nx-backend -- sh

# Check pod events
./kc describe pod -l app.kubernetes.io/name=identity -n nx-backend

# Check resource usage
./kc top pods -n nx-backend
./kc top nodes

# Check HPA status (production)
./kc get hpa -n nx-backend

# Check PDB status (production)
./kc get pdb -n nx-backend

Thao tác Database

bash
# Port-forward PostgreSQL for local access (e.g. with DBeaver, psql)
./kc port-forward svc/nx-postgresql-primary 5432:5432 -n nx-persistent

# Then connect locally:
# psql -h localhost -U nx_seller_operator -d nx_seller_core

# Exec into PostgreSQL pod directly
./kc exec -it sts/nx-postgresql -n nx-persistent -- psql -U postgres nx_seller_core

# Connect to Redis
./kc exec -it nx-redis-0 -n nx-broker -- redis-cli -a $REDIS_PASSWORD

# Kafka topic listing
./kc exec -it nx-kafka-0 -n nx-broker -- /opt/kafka/bin/kafka-topics.sh \
  --bootstrap-server localhost:29092 --list

Tham khảo nhanh Namespace

NamespaceChứaThao tác phổ biến
nx-internalnginx-ingress, Traefik, cert-manager, API PortalGia hạn TLS cert, log ingress/gateway
nx-backendBackend servicesDeployments, scaling, logs
nx-appFrontend appsTriển khai frontend
nx-persistentPostgreSQL, PgBouncerTruy cập DB, sao lưu
nx-brokerRedis Cluster, Kafka KRaftTruy cập cache, quản lý topic
nx-searchTypesense, DebeziumQuản lý search index, CDC
nx-watcher(chưa triển khai)--

Công cụ Quản lý Cluster

Thay vì chạy lệnh kubectl thô cho từng thao tác, dùng công cụ quản lý chuyên dụng cho thao tác cluster nhanh hơn, an toàn hơn.

K9s (TUI) -- Thao tác Hàng ngày

K9s là UI terminal cho Kubernetes. Nó cung cấp giám sát cluster real-time, log tailing, quản lý pod và kiểm tra tài nguyên -- tất cả từ terminal với phím tắt.

Cài đặt

bash
# macOS
brew install derailed/k9s/k9s

# Linux (via webi)
curl -sS https://webinstall.dev/k9s | bash

# Linux (binary)
curl -LO https://github.com/derailed/k9s/releases/latest/download/k9s_Linux_amd64.tar.gz
tar xf k9s_Linux_amd64.tar.gz && sudo mv k9s /usr/local/bin/

Sử dụng

bash
# Launch with the staging kubeconfig
KUBECONFIG=infrastructure/deployments/staging/kubeconfig.yaml k9s

# Launch directly into a namespace
KUBECONFIG=infrastructure/deployments/staging/kubeconfig.yaml k9s -n nx-backend
KUBECONFIG=infrastructure/deployments/staging/kubeconfig.yaml k9s -n nx-broker

Phím tắt Quan trọng

Phím tắtHành động
:Chế độ lệnh (gõ tên resource: deploy, pod, svc, ns, hpa, pdb)
/Lọc resource theo tên
lXem log của pod đã chọn
sShell vào pod đã chọn
dDescribe resource đã chọn
eChỉnh sửa YAML resource
ctrl-kKill/xóa resource đã chọn
ctrl-dXóa resource đã chọn
:xray deployX-ray view -- hiển thị deployment cùng tất cả child resource
:pulsePulse view -- tóm tắt sức khỏe cluster real-time
:ctxChuyển context cluster
:nsChuyển namespace

Workflow Khuyến nghị

bash
# Morning check — cluster health
KUBECONFIG=infrastructure/deployments/staging/kubeconfig.yaml k9s
# Type :pulse to see overall health
# Type :events to see recent events

# Debugging a service
# :deploy -> select nx-identity -> l (logs) -> / error (filter)

# Scaling
# :deploy -> select nx-sale -> s (scale) -> enter new replica count

# Quick namespace hop
# :ns -> select nx-broker -> enter -> see Redis/Kafka pods

Portainer (GUI) -- Dashboard cho Team

Portainer cung cấp GUI trên web cho quản lý Kubernetes. Triển khai nó trên production để cả team (PM, QA, dev) có thể xem trạng thái cluster mà không cần truy cập CLI.

Tại sao dùng Portainer

  • Không cần chuyên môn K8s -- thành viên team có thể xem trạng thái pod, log và deployment qua trình duyệt
  • Đa cluster -- một dashboard duy nhất cho cả staging và production
  • RBAC tích hợp -- tạo user read-only cho QA/PM, admin cho DevOps
  • Quản lý Helm chart -- triển khai và nâng cấp chart từ UI
  • Nhẹ -- chạy dưới dạng một pod agent duy nhất mỗi cluster

Triển khai

bash
# Add Portainer Helm repo
helm repo add portainer https://portainer.github.io/k8s/
helm repo update

# Install Portainer server (on production cluster)
helm install portainer portainer/portainer \
  --namespace portainer \
  --create-namespace \
  --set service.type=ClusterIP \
  --set tls.force=true

# Install Portainer agent (on staging cluster, connects back to production Portainer)
helm install portainer-agent portainer/portainer-agent \
  --namespace portainer \
  --create-namespace \
  --set agent.serverAddr=portainer.production.internal

Expose qua nginx-ingress

Ingress: portainer-ingress
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: portainer-ingress
  namespace: portainer
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - portainer.bana.com.vn
      secretName: portainer-tls
  rules:
    - host: portainer.bana.com.vn
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: portainer
                port:
                  number: 9443

Truy cập

URLMục đích
portainer.bana.com.vnDashboard Portainer production
UsernameĐặt trong lần đăng nhập đầu tiên

Vai trò User Khuyến nghị

Vai tròUsersQuyền
AdminDevOps, LeadTruy cập đầy đủ -- triển khai, scale, xóa, secrets
OperatorBackend devTriển khai, scale, xem log, khởi động lại pod
Read-onlyPM, QAChỉ xem trạng thái pod, log, event

Sao lưu & Khôi phục sau Thảm họa (Velero)

Velero cung cấp backup cấp cluster của tất cả Kubernetes resources và persistent volume. Nó bổ sung cho backup cấp database (CloudNativePG cho PostgreSQL) bằng snapshot trạng thái cluster đầy đủ.

Tại sao dùng Velero

  • Trạng thái cluster đầy đủ -- sao lưu tất cả K8s resources (Deployments, Services, ConfigMaps, Secrets, CRDs), không chỉ dữ liệu
  • Snapshot PVC -- snapshot persistent volume qua CSI hoặc restic
  • Backup lên lịch -- backup tự động hàng ngày/hàng giờ với policy retention
  • Restore phạm vi namespace -- restore một namespace mà không ảnh hưởng đến phần còn lại của cluster
  • Khôi phục sau thảm họa -- restore toàn bộ cluster từ đầu

Cài đặt

bash
# Install Velero CLI
curl -LO https://github.com/vmware-tanzu/velero/releases/latest/download/velero-linux-amd64.tar.gz
tar xf velero-linux-amd64.tar.gz && sudo mv velero /usr/local/bin/

# Install Velero server in cluster with S3 backend
velero install \
  --provider aws \
  --plugins velero/velero-plugin-for-aws:v1.10.0 \
  --bucket bana-backups \
  --secret-file ./credentials-velero \
  --backup-location-config region=ap-southeast-1,s3ForcePathStyle=true,s3Url=https://s3.vnpaycloud.vn \
  --snapshot-location-config region=ap-southeast-1 \
  --use-node-agent \
  --namespace nx-internal

Backup Lên lịch

Daily full backup — retain 30 days
yaml
# Daily full backup — retain 30 days
apiVersion: velero.io/v1
kind: Schedule
metadata:
  name: nx-daily-full
  namespace: nx-internal
spec:
  schedule: "0 2 * * *"  # 2 AM daily
  template:
    ttl: 720h  # 30 days retention
    includedNamespaces:
      - nx-backend
      - nx-app
      - nx-persistent
      - nx-broker
      - nx-search
      - nx-internal
    snapshotVolumes: true
    defaultVolumesToFsBackup: true
---
# Hourly config-only backup — retain 7 days (no PVCs, fast)
apiVersion: velero.io/v1
kind: Schedule
metadata:
  name: nx-hourly-config
  namespace: nx-internal
spec:
  schedule: "0 * * * *"  # Every hour
  template:
    ttl: 168h  # 7 days retention
    includedNamespaces:
      - nx-backend
      - nx-app
      - nx-internal
    snapshotVolumes: false
    includedResources:
      - deployments
      - services
      - configmaps
      - secrets
      - ingresses
      - ingressroutes

Quy trình Restore

bash
# List available backups
velero backup get

# Restore a specific namespace from latest backup
velero restore create --from-backup nx-daily-full-20260317020000 \
  --include-namespaces nx-backend \
  --restore-volumes

# Restore entire cluster (disaster recovery)
velero restore create --from-backup nx-daily-full-20260317020000 \
  --restore-volumes

# Check restore status
velero restore get
velero restore describe <restore-name>

Runbook Khôi phục sau Thảm họa

  1. Đánh giá -- Xác định phạm vi sự cố (một namespace hay toàn cluster)
  2. Provision -- Nếu mất toàn cluster, provision cluster mới với spec node pool giống nhau
  3. Cài Velero -- Cài Velero trỏ đến cùng S3 bucket
  4. Restore -- Chạy velero restore create từ backup mới nhất
  5. Xác thực -- Kiểm tra tất cả pod đang chạy, health endpoint phản hồi
  6. DNS -- Cập nhật bản ghi DNS nếu IP cluster thay đổi
  7. Kiểm tra -- Chạy script health check đầy đủ (xem mục Trình tự Triển khai ở trên)

WARNING

Velero sao lưu Kubernetes resource nhưng không dữ liệu database bên trong PostgreSQL. Luôn kết hợp Velero với archiving liên tục của CloudNativePG (WAL) cho point-in-time database recovery. Xem Data Layer để biết chi tiết backup database.

Trivy trong CI Pipeline

Scan lỗ hổng bằng Trivy được tích hợp vào GitLab CI/CD pipeline. Mỗi image được scan sau khi build và trước khi push. Xem Security & Hardening để biết policy admission controller.

Tích hợp Pipeline

Thêm stage scan giữa testpush trong .gitlab-ci.yml:

Add a scan stage between test and push in `.gitlab-ci....
yaml
stages:
  - build
  - test
  - scan     # NEW — Trivy vulnerability scanning
  - push
  - deploy

# --- Scan Stage ---
.scan-template: &scan-template
  stage: scan
  image:
    name: aquasec/trivy:latest
    entrypoint: [""]
  needs: [test]
  before_script:
    - echo "$CI_REGISTRY_PASSWORD" | docker login $CI_REGISTRY -u $CI_REGISTRY_USER --password-stdin
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
    - if: $CI_COMMIT_BRANCH == "develop"
    - if: $CI_MERGE_REQUEST_IID

scan-identity:
  <<: *scan-template
  script:
    - docker build -t $REGISTRY/identity:scan -f packages/identity/Dockerfile .
    - trivy image --exit-code 1 --severity CRITICAL,HIGH --no-progress $REGISTRY/identity:scan

scan-sale:
  <<: *scan-template
  script:
    - docker build -t $REGISTRY/sale:scan -f packages/sale/Dockerfile .
    - trivy image --exit-code 1 --severity CRITICAL,HIGH --no-progress $REGISTRY/sale:scan

scan-payment:
  <<: *scan-template
  script:
    - docker build -t $REGISTRY/payment:scan -f packages/payment/Dockerfile .
    - trivy image --exit-code 1 --severity CRITICAL,HIGH --no-progress $REGISTRY/payment:scan

Policy Mức độ Nghiêm trọng Scan

Môi trườngFail khiHành động
Tất cả branchCRITICALPipeline fail, chặn merge
main, developCRITICAL, HIGHPipeline fail, chặn merge
Feature branchCRITICALPipeline fail; HIGH chỉ là cảnh báo

Công cụ nào khi nào

Tình huốngCông cụ
Debug on-call, xem log nhanhK9s
Scale một deploymentK9s hoặc Portainer
QA kiểm tra trạng thái deploymentPortainer
PM xem sức khỏe servicePortainer
Chỉnh sửa ConfigMap trực tiếpK9s
Xem lại các event toàn clusterK9s (:events)
Triển khai Helm chartPortainer
Tổng quan đa clusterPortainer

Proprietary and Confidential. Unauthorized copying, distribution, or use of this software is strictly prohibited.