切換語言為:簡體
如何將 Docker 單節點部署應用改成叢集部署?

如何將 Docker 單節點部署應用改成叢集部署?

  • 爱糖宝
  • 2024-09-22
  • 2047
  • 0
  • 0

在專案開發中,Docker Compose 是一種常見的工具,能夠幫助開發者在本地輕鬆啟動多容器應用。然而,當應用擴充套件到生產環境,單節點的 Docker Compose 可能無法滿足高可用性、容錯和擴充套件需求。這時候,我們可以考慮將 Docker Compose 部署遷移到 Kubernetes 這樣的叢集環境中,實現應用的叢集化管理。

本文將以我之前開發的一個 Node.js 應用(一個線上流程圖系統)為例,使用 PostgreSQLAdminer 管理資料庫,介紹如何將單節點的 Docker Compose 部署轉化為 Kubernetes 叢集部署。

如何將 Docker 單節點部署應用改成叢集部署?

Docker Compose 配置

這是一個典型的 docker-compose.yml 檔案,它定義了一個使用 PostgreSQL 作為資料庫,Adminer 作為資料庫管理介面,Node.js 應用作為服務的環境。

version: "3.8"

services:
  db:
    image: postgres
    volumes:
      - pg_data:/var/lib/postgresql/data
    restart: always
    ports:
      - 5432:5432
    environment:
      POSTGRES_DB: pro
      POSTGRES_USER: admin
      POSTGRES_PASSWORD: example

  adminer:
    image: adminer
    restart: always
    ports:
      - 8080:8080

  app:
    image: maqi1520/cloneprocesson
    ports:
      - "3000:3000"
    environment:
      DATABASE_URL: "postgresql://admin:example@db:5432/pro?schema=public"
      JWT_SECRET: "xxxx"
      GITHUB_CLIENT_ID: "xxxx"
      GITHUB_CLIENT_SECRET: "xxxx"
      DOMAIN: "http://localhost:3000"
      EMAIL_USER: "xxxx@163.com"
      EMAIL_USER_NAME: "xxxxx"
      EMAIL_HOST: "smtp.163.com"
      EMAIL_PASS: "xxxx"
    depends_on:
      - db

volumes:
  pg_data:

此配置可以在本地使用 docker-compose up -d 命令啟動,但如果要將其部署在生產環境中並確保高可用性,則需要遷移到 Kubernetes。接下來,我們將介紹如何完成這一轉化。

Kubernetes 叢集化部署概述

在 Kubernetes 中,使用多個資源來管理應用的不同元件。與 Docker Compose 的單一檔案不同,Kubernetes 使用 DeploymentStatefulSetServiceConfigMapSecret 等多個配置檔案來描述和管理容器化應用。

爲了將上述 Docker Compose 配置轉移到 Kubernetes,我們需要以下幾種關鍵元件:

  1. PostgreSQL StatefulSet:用於管理資料庫容器,保證資料永續性。

  2. Deployment:用於部署 Node.js 應用和 Adminer,確保應用的可擴充套件性。

  3. Service:為應用提供叢集內外的訪問介面。

  4. Secret:用於儲存敏感資訊(如資料庫憑證、API 金鑰等)。

Step 1: 將 PostgreSQL 部署為 StatefulSet

在 Kubernetes 中,StatefulSet 用於管理有狀態應用(例如資料庫),它確保資料庫例項的永續性和穩定性。我們首先需要建立一個用於儲存資料庫憑證的 Secret,然後再建立 StatefulSet

PostgreSQL Secret

apiVersion: v1
kind: Secret
metadata:
  name: postgres-secret
type: Opaque
data:
  DATABASE_URL: cG9zdGdyZXNxbDovL2FkbWluOmV4YW1wbGVAcG9zdGdyZXM6NTQzMi9wcm8/c2NoZW1hPXB1YmxpYw== # base64編碼的 "postgresql://admin:example@postgres:5432/pro?schema=public"
  POSTGRES_DB: "cHJv"        # "pro" encoded in base64
  POSTGRES_USER: "YWRtaW4="   # "admin" encoded in base64
  POSTGRES_PASSWORD: "ZXhhbXBsZQ=="  # "example" encoded in base64

在 Kubernetes 中,Secret 中的資料可以使用 base64 編碼是一種常見的做法,但不是必須的。

在 Linux 和 macOS 系統中,可以使用 base64 命令。例如,要對字串 “postgresql://admin:example@postgres:5432/pro?schema=public” 進行編碼,可以在終端中執行以下命令:

echo -n "postgresql://admin:example@postgres:5432/pro?schema=public" | base64

在 Windows 系統中,可以使用 PowerShell 中的[Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("postgresql://admin:example@postgres:5432/pro?schema=public"))命令。

Kubernetes 的 Secret 物件可以儲存任意資料,但爲了確保資料的安全性和可讀性,通常會進行某種形式的編碼或加密。

PostgreSQL StatefulSet

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: postgres
spec:
  serviceName: "postgres"
  replicas: 1
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
        - name: postgres
          image: postgres:latest
          ports:
            - containerPort: 5432
          env:
            - name: POSTGRES_DB
              valueFrom:
                secretKeyRef:
                  name: postgres-secret
                  key: POSTGRES_DB
            - name: POSTGRES_USER
              valueFrom:
                secretKeyRef:
                  name: postgres-secret
                  key: POSTGRES_USER
            - name: POSTGRES_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: postgres-secret
                  key: POSTGRES_PASSWORD
          volumeMounts:
            - name: pg-data
              mountPath: /var/lib/postgresql/data
  volumeClaimTemplates:
    - metadata:
        name: pg-data
      spec:
        accessModes: ["ReadWriteOnce"]
        resources:
          requests:
            storage: 1Gi

透過 StatefulSet,我們確保了資料庫資料的持久化儲存和穩定的網路標識。每個副本都可以訪問持久儲存卷。

PostgreSQL Service

apiVersion: v1
kind: Service
metadata:
  name: postgres
spec:
  ports:
    - port: 5432
  selector:
    app: postgres

Service 用於暴露 PostgreSQL 服務,使得應用可以透過叢集內部的 DNS 名稱 postgres 訪問資料庫。

Step 2: Node 應用程式的 Deployment 和 Secret

接下來,我們為 Node.js 應用建立一個 Deployment,並透過 Secret 管理敏感資料,例如資料庫 URL、JWT 金鑰和 GitHub API 憑證。

應用程式的 Secret

apiVersion: v1
kind: Secret
metadata:
  name: app-secret
type: Opaque
data:
  jwt-secret: "YOUR_ENCODED_JWT_SECRET"
  github-client-id: "YOUR_ENCODED_GITHUB_CLIENT_ID"
  github-client-secret: "YOUR_ENCODED_GITHUB_CLIENT_SECRET"

應用程式 Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: app
  template:
    metadata:
      labels:
        app: app
    spec:
      containers:
        - name: app
          image: maqi1520/cloneprocesson:latest
          ports:
            - containerPort: 3000
          env:
             - name: DATABASE_URL
              valueFrom:
                secretKeyRef:
                  name: app-secret
                  key: DATABASE_URL
            - name: JWT_SECRET
              valueFrom:
                secretKeyRef:
                  name: app-secret
                  key: jwt-secret
            - name: GITHUB_CLIENT_ID
              valueFrom:
                secretKeyRef:
                  name: app-secret
                  key: github-client-id
            - name: GITHUB_CLIENT_SECRET
              valueFrom:
                secretKeyRef:
                  name: app-secret
                  key: github-client-secret

應用程式 Service

apiVersion: v1
kind: Service
metadata:
  name: app
spec:
  type: LoadBalancer
  ports:
    - port: 3000
  selector:
    app: app

Step 3: Adminer Deployment 和 Service

最後,Adminer 作為資料庫管理介面,也需要用 DeploymentService 部署。

如何將 Docker 單節點部署應用改成叢集部署?

Adminer Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: adminer
spec:
  replicas: 1
  selector:
    matchLabels:
      app: adminer
  template:
    metadata:
      labels:
        app: adminer
    spec:
      containers:
        - name: adminer
          image: adminer:latest
          ports:
            - containerPort: 8080

Adminer Service

apiVersion: v1
kind: Service
metadata:
  name: adminer
spec:
  type: LoadBalancer
  ports:
    - port: 8080
  selector:
    app: adminer

Step 4: 部署步驟

  1. SecretDeployment 等資源應用到 Kubernetes 叢集:

    kubectl apply -f postgres-secret.yml
    kubectl apply -f postgres-statefulset.yml
    kubectl apply -f postgres-service.yml
    kubectl apply -f app-secret.yml
    kubectl apply -f app-deployment.yml
    kubectl apply -f app-service.yml
    kubectl apply -f adminer-deployment.yml
    kubectl apply -f adminer-service.yml

    這將會啟動 PostgreSQL 資料庫例項,併爲資料庫提供持久儲存,應用程式將透過 Secret 獲取敏感資訊,並連線到 PostgreSQL 資料庫。Service 將會為外部客戶端提供訪問 Node.js 應用的入口。 Adminer 將作為資料庫管理介面透過叢集的 LoadBalancer 公開出來,允許你直接管理 PostgreSQL 資料。

Step 5: 驗證和監控

完成部署後,你可以透過以下方式驗證叢集的執行情況:

  1. 檢視所有資源是否成功建立:

    kubectl get pods
    kubectl get services
    kubectl get statefulsets

  2. 驗證 PostgreSQL 連線:

    可以透過訪問 Adminer 服務,驗證 PostgreSQL 資料庫是否正常工作。你可以使用瀏覽器訪問 http://<LoadBalancer_IP>:8080,然後使用 Secret 中的資料庫憑證登入。

  3. 驗證應用程式連線:

    訪問 Node.js 應用的 Service 地址,檢視應用是否能正常連線 PostgreSQL 資料庫,併成功啟動。

如果使用本地部署可以使用minikube service app看到應用地址,他會自動開啟部署 url 埠。

Kubernetes 部署的優勢

相比於 Docker Compose 單節點部署,Kubernetes 的叢集化部署具備以下幾個顯著優勢:

  1. 高可用性和容錯:Kubernetes 提供了原生的自動重啟、容器健康檢查、橫向擴充套件等機制,使得應用能夠在出現問題時自動恢復。

  2. 自動擴充套件:你可以根據負載的變化,透過 Kubernetes 自動或手動擴充套件應用的副本數,保證應用能夠處理更多請求。

  3. 滾動更新:透過 Kubernetes,你可以實現應用的滾動更新,逐步替換舊版本的容器,而不會導致服務中斷。

  4. 資源分配和最佳化:Kubernetes 允許更精細地控制資源的使用,如 CPU 和記憶體,確保叢集資源的合理利用。

  5. Secret 和 ConfigMap:透過 Secret 和 ConfigMap,Kubernetes 提供了更安全和動態的方式來管理應用的配置和敏感資訊,避免將敏感資料硬編碼在映象或程式碼中。

總結

將 Docker Compose 的單節點部署遷移到 Kubernetes,不僅能夠使應用從本地開發階段順利過渡到生產環境,還可以透過 Kubernetes 提供的叢集管理能力來提高系統的高可用性、彈性擴充套件和安全性。

在本文中,我們透過將 Docker Compose 配置中的 PostgreSQL、Adminer 和自定義 Node.js 應用遷移到 Kubernetes,學習瞭如何利用 StatefulSetDeploymentSecretService 等 Kubernetes 資源來管理和部署複雜的叢集化應用。這種方式可以幫助你在生產環境中實現更加靈活、安全和可擴充套件的容器管理。

0則評論

您的電子郵件等資訊不會被公開,以下所有項目均必填

OK! You can skip this field.