iT邦幫忙

2024 iThome 鐵人賽

DAY 26
0
Kubernetes

K8s 資料庫管理系統系列 第 26

day 26 k8s農業部資料庫管理系統

  • 分享至 

  • xImage
  •  

今天是第二十八天我們可以寫一個k8s農業部資料庫管理系統,以下是我的程式碼

1. 系統需求

  • 資料庫:例如 MySQL,存儲農業相關數據,如作物種類、天氣、土壤信息等。
  • 後端:用 Flask (Python) 或 Node.js 開發 API,處理資料請求。
  • 前端:用 React 或 Angular 構建管理界面。
  • Kubernetes:用來管理應用程式容器、數據持久性、縮放等。

2. Dockerize 各個服務

為了讓應用程式在 Kubernetes 上運行,你需要先為每個服務創建 Docker 映像。

後端 Flask 範例

# app.py
from flask import Flask, jsonify, request
import mysql.connector

app = Flask(__name__)

@app.route('/crops', methods=['GET'])
def get_crops():
    connection = mysql.connector.connect(
        host='mysql-service',  # Kubernetes 內的資料庫服務名稱
        user='root',
        password='password',
        database='agriculture'
    )
    cursor = connection.cursor(dictionary=True)
    cursor.execute("SELECT * FROM crops")
    crops = cursor.fetchall()
    return jsonify(crops)

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

Dockerfile for Flask 後端

dockerfile
# 使用 Python 3.9 基礎映像
FROM python:3.9-slim

# 設置工作目錄
WORKDIR /app

# 安裝依賴
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt

# 複製應用程式代碼
COPY . .

# 暴露端口
EXPOSE 5000

# 啟動應用程式
CMD ["python", "app.py"]

requirements.txt

Flask==2.0.3
mysql-connector-python==8.0.28

3. Kubernetes 資源配置

後端 Deployment 和 Service

# backend-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: backend
  template:
    metadata:
      labels:
        app: backend
    spec:
      containers:
      - name: backend
        image: your-docker-repo/backend:latest
        ports:
        - containerPort: 5000
---
# backend-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: backend-service
spec:
  selector:
    app: backend
  ports:
    - protocol: TCP
      port: 80
      targetPort: 5000
  type: LoadBalancer

MySQL Deployment 和 Service

# mysql-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql-deployment
spec:
  selector:
    matchLabels:
      app: mysql
  replicas: 1
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:8.0
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: "password"
        - name: MYSQL_DATABASE
          value: "agriculture"
        ports:
        - containerPort: 3306
        volumeMounts:
        - name: mysql-storage
          mountPath: /var/lib/mysql
      volumes:
      - name: mysql-storage
        persistentVolumeClaim:
          claimName: mysql-pvc
---
# mysql-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: mysql-service
spec:
  selector:
    app: mysql
  ports:
    - protocol: TCP
      port: 3306
      targetPort: 3306

Persistent Volume Claim (PVC)

# mysql-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi

4. 前端部署

假設前端使用 React:

前端 React Dockerfile

dockerfile
# 使用 node 基礎映像
FROM node:16-alpine

WORKDIR /app

# 複製 package.json 並安裝依賴
COPY package*.json ./
RUN npm install

# 複製應用程式代碼
COPY . .

# 構建應用
RUN npm run build

# 使用 nginx 作為服務器
FROM nginx:1.21-alpine
COPY --from=0 /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

前端 Deployment 和 Service

# frontend-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: frontend
  template:
    metadata:
      labels:
        app: frontend
    spec:
      containers:
      - name: frontend
        image: your-docker-repo/frontend:latest
        ports:
        - containerPort: 80
---
# frontend-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: frontend-service
spec:
  selector:
    app: frontend
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: LoadBalancer

5. 部署到 Kubernetes

部署流程:

  1. 構建 Docker 映像

    docker build -t your-docker-repo/backend:latest -f Dockerfile .
    docker build -t your-docker-repo/frontend:latest -f Dockerfile .
    

    上傳到 DockerHub 或私人容器註冊表:

    docker push your-docker-repo/backend:latest
    docker push your-docker-repo/frontend:latest
    
  2. 部署到 Kubernetes

    kubectl apply -f mysql-deployment.yaml
    kubectl apply -f mysql-service.yaml
    kubectl apply -f backend-deployment.yaml
    kubectl apply -f backend-service.yaml
    kubectl apply -f frontend-deployment.yaml
    kubectl apply -f frontend-service.yaml
    

6. 檢查服務狀態

kubectl get pods
kubectl get services

1. 後端 Flask API (用來處理農業數據)

這個部分的程式碼使用了 Flask 作為後端框架,並通過 MySQL 連接來管理和存取農業部的資料庫。

主要檔案:app.py

from flask import Flask, jsonify, request
import mysql.connector

app = Flask(__name__)  # 創建 Flask 應用實例

@app.route('/crops', methods=['GET'])
def get_crops():
    # 連接 MySQL 資料庫
    connection = mysql.connector.connect(
        host='mysql-service',  # Kubernetes 中 MySQL 服務的名稱
        user='root',
        password='password',
        database='agriculture'  # 資料庫名稱
    )
    cursor = connection.cursor(dictionary=True)
    cursor.execute("SELECT * FROM crops")  # 執行 SQL 查詢,從 crops 表中選擇所有數據
    crops = cursor.fetchall()  # 獲取查詢結果
    return jsonify(crops)  # 返回 JSON 格式的結果

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)  # 啟動 Flask 伺服器

解釋:

  1. Flask 應用:用於創建 API 來處理 HTTP 請求。@app.route('/crops') 定義了當訪問 /crops 路徑時,會返回作物數據的功能。

  2. MySQL 連接mysql.connector.connect() 用來連接 MySQL 資料庫。這裡的 host 是 Kubernetes 內的服務名稱 (mysql-service),user 是 MySQL 用戶名,password 是數據庫的密碼。

  3. SQL 查詢:透過 SQL 語句 SELECT * FROM crops 從資料庫中提取作物數據,然後將結果轉換為 JSON 格式通過 API 返回。


2. Flask Dockerfile (用來將後端應用容器化)

dockerfile
# 使用 Python 3.9 基礎映像
FROM python:3.9-slim

# 設置工作目錄
WORKDIR /app

# 安裝依賴
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt

# 複製應用程式代碼
COPY . .

# 暴露端口
EXPOSE 5000

# 啟動應用程式
CMD ["python", "app.py"]

解釋:

  1. FROM python:3.9-slim:指定基礎映像,這裡選擇的是 Python 3.9 的輕量級版本。
  2. WORKDIR /app:設置工作目錄 /app,之後的所有操作都會在這個目錄下執行。
  3. 安裝依賴COPY requirements.txt 會將本地的 requirements.txt 複製到容器中,並透過 pip install 安裝所需的依賴。
  4. 複製程式碼COPY . . 會將當前目錄的所有檔案複製到容器內。
  5. 暴露端口:告訴 Docker 這個應用會在 5000 端口運行。
  6. 啟動應用:最後一行的 CMD 用來啟動 Flask 應用,這裡是執行 app.py

3. Kubernetes 配置

Kubernetes (K8s) 配置檔案用來管理後端、前端和 MySQL 的容器化應用,並進行自動調度與負載均衡。

3.1 後端 Flask Deployment 和 Service

# backend-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend-deployment
spec:
  replicas: 3  # 副本數,會運行3個 Flask 應用實例
  selector:
    matchLabels:
      app: backend
  template:
    metadata:
      labels:
        app: backend
    spec:
      containers:
      - name: backend
        image: your-docker-repo/backend:latest  # 從 Docker Hub 或私人註冊表中拉取映像
        ports:
        - containerPort: 5000  # 指定容器內部的 Flask 應用埠
---
# backend-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: backend-service
spec:
  selector:
    app: backend  # 服務會將流量轉發給具有這個標籤的 Pod
  ports:
    - protocol: TCP
      port: 80
      targetPort: 5000  # 服務會將端口 80 的流量轉發到 Flask 應用的 5000 埠
  type: LoadBalancer  # 創建一個負載均衡器來分配流量

解釋:

  1. Deployment

    • 定義了後端應用的部署細節。replicas: 3 表示會運行 3 個後端實例來保證高可用性。
    • image: your-docker-repo/backend:latest 是要部署的 Docker 映像。
  2. Service

    • 這裡使用了 LoadBalancer,會將外部請求通過負載均衡器分配到後端的不同 Pod,並將流量從外部的 80 埠轉發到 Flask 應用的 5000 埠。

3.2 MySQL Deployment 和 Service

# mysql-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql-deployment
spec:
  selector:
    matchLabels:
      app: mysql
  replicas: 1  # 只需要一個 MySQL 實例
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:8.0  # 使用 MySQL 8.0 的映像
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: "password"  # 設置 MySQL root 密碼
        - name: MYSQL_DATABASE
          value: "agriculture"  # 創建 agriculture 資料庫
        ports:
        - containerPort: 3306
        volumeMounts:
        - name: mysql-storage
          mountPath: /var/lib/mysql  # 資料持久化存儲
      volumes:
      - name: mysql-storage
        persistentVolumeClaim:
          claimName: mysql-pvc  # 定義持久卷
---
# mysql-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: mysql-service
spec:
  selector:
    app: mysql
  ports:
    - protocol: TCP
      port: 3306  # MySQL 的服務端口
      targetPort: 3306

解釋:

  1. MySQL Deployment:此配置創建了一個 MySQL 容器,並設置了 MySQL 的 root 密碼和要創建的資料庫 (agriculture)。
  2. Volume 和持久卷 (PVC):使用 PersistentVolumeClaim 來確保 MySQL 數據不會隨著容器的銷毀而丟失。
  3. MySQL Service:提供一個 Kubernetes 內部的服務 (mysql-service),用來讓其他應用(如後端)連接 MySQL。

4. 前端部署

假設前端使用 React,配置類似於後端的流程。

# frontend-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend-deployment
spec:
  replicas: 2  # 部署兩個副本
  selector:
    matchLabels:
      app: frontend
  template:
    metadata:
      labels:
        app: frontend
    spec:
      containers:
      - name: frontend
        image: your-docker-repo/frontend:latest  # 前端應用的映像
        ports:
        - containerPort: 80
---
# frontend-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: frontend-service
spec:
  selector:
    app: frontend
  ports:
    - protocol: TCP
      port: 80  # 將外部 80 埠的流量導向前端應用
      targetPort: 80
  type: LoadBalancer  # 使用負載均衡來分配前端流量

解釋:

  • frontend-deployment.yaml 定義了兩個前端實例,確保應用的可用性。
  • frontend-service.yaml 將流量通過 LoadBalancer 分配到前端應用。

總結:

  1. 後端 Flask API 處理作物數據的 API 請求,並與 MySQL 資料庫進行互動。
  2. Docker 和 Kubernetes 則用來容器化應用,並通過 Kubernetes 進行自動調度與負載均衡,使系統更具擴展性和高可用性。

上一篇
day 25 k8s 財政部稅務資料庫管理系統
下一篇
day 27 k8s海關資料庫管理系統
系列文
K8s 資料庫管理系統30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言