iT邦幫忙

2024 iThome 鐵人賽

DAY 12
0
Kubernetes

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

day 12 K8s住戶個人資料庫管理系統

  • 分享至 

  • xImage
  •  

今天是第十二天我們可以寫一個k8s住戶個人資料庫管理系統,以下是我的程式碼

方案概述

  1. 後端:使用 Python 的 Flask 框架,負責管理 RESTful API,允許 CRUD 操作(創建、讀取、更新和刪除住戶個人資料)。
  2. 資料庫:使用 MySQL 作為後端資料庫,存儲住戶資料。
  3. Kubernetes:使用 Kubernetes 來部署 Flask 應用和 MySQL 資料庫。透過 Kubernetes 部署、服務和 Persistent Volume Claim(PVC)來管理應用。

步驟 1:準備 Flask 應用程式

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

app = Flask(__name__)

# 設定資料庫連接
def get_db_connection():
    conn = mysql.connector.connect(
        host='mysql-service',  # K8s 內部的 MySQL 服務
        user='root',
        password='password',
        database='residents_db'
    )
    return conn

@app.route('/residents', methods=['GET'])
def get_residents():
    conn = get_db_connection()
    cursor = conn.cursor(dictionary=True)
    cursor.execute('SELECT * FROM residents')
    residents = cursor.fetchall()
    cursor.close()
    conn.close()
    return jsonify(residents)

@app.route('/resident', methods=['POST'])
def add_resident():
    new_resident = request.get_json()
    conn = get_db_connection()
    cursor = conn.cursor()
    cursor.execute('INSERT INTO residents (name, address, phone) VALUES (%s, %s, %s)',
                   (new_resident['name'], new_resident['address'], new_resident['phone']))
    conn.commit()
    cursor.close()
    conn.close()
    return jsonify({'message': 'Resident added successfully'}), 201

@app.route('/resident/<int:id>', methods=['PUT'])
def update_resident(id):
    update_data = request.get_json()
    conn = get_db_connection()
    cursor = conn.cursor()
    cursor.execute('UPDATE residents SET name = %s, address = %s, phone = %s WHERE id = %s',
                   (update_data['name'], update_data['address'], update_data['phone'], id))
    conn.commit()
    cursor.close()
    conn.close()
    return jsonify({'message': 'Resident updated successfully'})

@app.route('/resident/<int:id>', methods=['DELETE'])
def delete_resident(id):
    conn = get_db_connection()
    cursor = conn.cursor()
    cursor.execute('DELETE FROM residents WHERE id = %s', (id,))
    conn.commit()
    cursor.close()
    conn.close()
    return jsonify({'message': 'Resident deleted successfully'})

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

步驟 2:準備 MySQL 資料庫

你需要在 MySQL 中創建一個資料庫和一個表格,這些操作可以透過 MySQL 的 init.sql 文件完成:

-- init.sql
CREATE DATABASE IF NOT EXISTS residents_db;
USE residents_db;

CREATE TABLE IF NOT EXISTS residents (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100),
    address VARCHAR(255),
    phone VARCHAR(20)
);

步驟 3:建立 Dockerfile

我們需要將 Flask 應用程式打包為 Docker 映像:

dockerfile
# Dockerfile
FROM python:3.9-slim

WORKDIR /app

COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt

COPY . .

CMD ["python", "app.py"]

步驟 4:Kubernetes 部署檔案

接下來,我們將建立 Kubernetes 的 YAML 檔案來定義 Flask 應用和 MySQL 的部署與服務。

Flask 應用的 Deployment 和 Service

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

MySQL 的 Deployment 和 Service

# mysql-deployment.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
---
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:5.7
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: "password"
        - name: MYSQL_DATABASE
          value: "residents_db"
        ports:
        - containerPort: 3306
        volumeMounts:
        - name: mysql-storage
          mountPath: /var/lib/mysql
      volumes:
      - name: mysql-storage
        persistentVolumeClaim:
          claimName: mysql-pvc
---
apiVersion: v1
kind: Service
metadata:
  name: mysql-service
spec:
  selector:
    app: mysql
  ports:
    - protocol: TCP
      port: 3306
      targetPort: 3306
  clusterIP: None

步驟 5:部署到 Kubernetes

  1. 構建並推送 Docker 映像

    docker build -t your-docker-hub-username/flask-app:latest .
    docker push your-docker-hub-username/flask-app:latest
    
  2. 在 Kubernetes 上部署

    kubectl apply -f mysql-deployment.yaml
    kubectl apply -f flask-deployment.yaml
    

這樣,你的 Flask 應用和 MySQL 資料庫就會運行在 Kubernetes 集群中,並且可以透過 LoadBalancer 服務來進行訪問。

步驟 6:測試應用

當部署完成後,你可以使用 kubectl get svc 獲取外部 IP,然後用 Postman 或 curl 測試 API,例如:

curl http://<external-ip>:5000/residents

這樣即可完成住戶個人資料庫管理系統的 Kubernetes 部署。


步驟 1:Flask 應用程式

這部分程式碼是使用 Python 的 Flask 框架撰寫的一個簡單 REST API,負責管理住戶的個人資料(增刪查改)。

1. 基本設置

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

app = Flask(__name__)
  • Flask:這是 Flask 框架的核心,負責處理 HTTP 請求與回應。
  • mysql.connector:用來連接 MySQL 資料庫。
  • app = Flask(__name__):初始化 Flask 應用程式。

2. 連接資料庫的函數

def get_db_connection():
    conn = mysql.connector.connect(
        host='mysql-service',  # K8s 內部的 MySQL 服務名稱
        user='root',
        password='password',
        database='residents_db'
    )
    return conn
  • mysql-service 是 Kubernetes 中 MySQL 服務的名稱,使用此名稱可以讓 Flask 應用連接到 Kubernetes 集群中的 MySQL 資料庫。
  • mysql.connector.connect:連接到 MySQL 資料庫,並指定使用者、密碼和資料庫名稱。
  • 此函數每次需要操作資料庫時被調用,確保資料庫連接成功。

3. 取得住戶資料的 API

@app.route('/residents', methods=['GET'])
def get_residents():
    conn = get_db_connection()
    cursor = conn.cursor(dictionary=True)
    cursor.execute('SELECT * FROM residents')
    residents = cursor.fetchall()
    cursor.close()
    conn.close()
    return jsonify(residents)
  • @app.route('/residents', methods=['GET']):定義一個 HTTP GET 請求的路由,它將返回所有住戶資料。
  • cursor.execute('SELECT * FROM residents'):執行 SQL 查詢,從 residents 表格中獲取所有資料。
  • cursor.fetchall():返回查詢結果的所有記錄。
  • jsonify(residents):將查詢結果轉換為 JSON 格式,並返回給用戶端。

4. 新增住戶資料的 API

@app.route('/resident', methods=['POST'])
def add_resident():
    new_resident = request.get_json()
    conn = get_db_connection()
    cursor = conn.cursor()
    cursor.execute('INSERT INTO residents (name, address, phone) VALUES (%s, %s, %s)',
                   (new_resident['name'], new_resident['address'], new_resident['phone']))
    conn.commit()
    cursor.close()
    conn.close()
    return jsonify({'message': 'Resident added successfully'}), 201
  • @app.route('/resident', methods=['POST']):這個路由定義了一個 POST 請求,用於新增一位住戶資料。
  • request.get_json():獲取請求體中的 JSON 資料,解析成 Python 字典格式。
  • INSERT INTO residents:將新住戶的 nameaddressphone 插入 residents 表格中。
  • conn.commit():提交資料庫變更。
  • 回應訊息:{'message': 'Resident added successfully'},並返回 HTTP 狀態碼 201(已創建)。

5. 更新住戶資料的 API

@app.route('/resident/<int:id>', methods=['PUT'])
def update_resident(id):
    update_data = request.get_json()
    conn = get_db_connection()
    cursor = conn.cursor()
    cursor.execute('UPDATE residents SET name = %s, address = %s, phone = %s WHERE id = %s',
                   (update_data['name'], update_data['address'], update_data['phone'], id))
    conn.commit()
    cursor.close()
    conn.close()
    return jsonify({'message': 'Resident updated successfully'})
  • @app.route('/resident/<int:id>', methods=['PUT']):定義一個 PUT 請求,用來更新指定 ID 的住戶資料。
  • request.get_json():取得需要更新的資料。
  • UPDATE residents SET... WHERE id = %s:根據住戶的 id,更新住戶的 nameaddressphone
  • 更新完成後返回成功訊息。

6. 刪除住戶資料的 API

@app.route('/resident/<int:id>', methods=['DELETE'])
def delete_resident(id):
    conn = get_db_connection()
    cursor = conn.cursor()
    cursor.execute('DELETE FROM residents WHERE id = %s', (id,))
    conn.commit()
    cursor.close()
    conn.close()
    return jsonify({'message': 'Resident deleted successfully'})
  • @app.route('/resident/<int:id>', methods=['DELETE']):定義 DELETE 請求,根據 ID 刪除住戶資料。
  • DELETE FROM residents WHERE id = %s:執行刪除 SQL 查詢,從資料庫中刪除住戶記錄。
  • 刪除完成後返回成功訊息。

7. 啟動 Flask 應用

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)
  • app.run():啟動 Flask 應用,並使其在 0.0.0.0(允許所有 IP 連接)和 5000 端口上運行。

步驟 2:MySQL 資料庫設定

這部分是 MySQL 的資料庫初始化 SQL 腳本,會在 MySQL 容器啟動時執行。

CREATE DATABASE IF NOT EXISTS residents_db;
USE residents_db;

CREATE TABLE IF NOT EXISTS residents (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100),
    address VARCHAR(255),
    phone VARCHAR(20)
);
  • CREATE DATABASE IF NOT EXISTS residents_db:創建一個名為 residents_db 的資料庫,如果它不存在。
  • CREATE TABLE IF NOT EXISTS residents:在資料庫中創建一個 residents 表格,儲存每個住戶的 ID、姓名、地址和電話號碼。

步驟 3:Dockerfile

這部分定義如何將 Flask 應用程式打包成 Docker 映像。

FROM python:3.9-slim

WORKDIR /app

COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt

COPY . .

CMD ["python", "app.py"]
  • FROM python:3.9-slim:使用 Python 3.9 的精簡版本作為基底映像。
  • WORKDIR /app:設定容器內的工作目錄。
  • COPY requirements.txt:將應用程式的依賴檔案複製到容器中。
  • RUN pip install -r requirements.txt:安裝應用程式的依賴項。
  • COPY . .:將所有應用程式檔案複製到容器中。
  • CMD ["python", "app.py"]:執行 Flask 應用程式。

步驟 4:Kubernetes 部署檔案

這部分說明如何使用 Kubernetes 部署 Flask 應用和 MySQL。

Flask Deployment 和 Service

apiVersion: apps/v1
kind: Deployment
metadata:
  name: flask-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: flask-app
  template:
    metadata:
      labels:
        app: flask-app
    spec:
      containers:
      - name: flask-app
        image: your-docker-hub-username/flask-app:latest
        ports:
        - containerPort: 5000
---
apiVersion: v1
kind: Service
metadata:
  name: flask-service
spec:
  selector:
    app: flask-app
  ports:
    - protocol: TCP
      port: 5000
      targetPort: 5000
  type: LoadBalancer
  • Deployment:定義 Flask 應用的 Kubernetes 部署。這裡設置了 2 個副本(replicas),用於負載均衡和高可用性。
  • Service:創建一個 Kubernetes 服務,將流量轉發到 Flask 應用,使用 LoadBalancer 使其可以被外部訪問。

MySQL Deployment 和 Service

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql-deployment
spec:
 

 replicas: 1
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:5.7
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: password
        ports:
        - containerPort: 3306
        volumeMounts:
        - name: mysql-storage
          mountPath: /var/lib/mysql
      volumes:
      - name: mysql-storage
        persistentVolumeClaim:
          claimName: mysql-pvc
---
apiVersion: v1
kind: Service
metadata:
  name: mysql-service
spec:
  selector:
    app: mysql
  ports:
    - protocol: TCP
      port: 3306
      targetPort: 3306
  • PersistentVolumeClaim (PVC):用來定義持久化存儲卷,確保 MySQL 資料在重啟時不會丟失。
  • Deployment:部署 MySQL 應用,並設置環境變數 MYSQL_ROOT_PASSWORD 作為資料庫的根密碼。
  • Service:創建 MySQL 服務,使 Flask 應用能夠連接到資料庫。

這是整個系統的邏輯與步驟。總結來說,我使用 Flask API 管理住戶資料,並透過 Docker 容器和 Kubernetes 進行部署,MySQL 作為後端資料庫儲存資料。


上一篇
day 11 k8s 學校ESG資料庫管理系統
下一篇
day 12 K8s 科學園區廠區氣體資料庫管理系統
系列文
K8s 資料庫管理系統15
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言