今天是第十四天我們可以寫一個K8s銀行提款資料庫管理系統,以下是程式碼
Deployment
、Service
、PersistentVolume
等。這裡是一個簡單的 API 服務,用於處理提款邏輯:
const express = require('express');
const mysql = require('mysql2');
// 建立 Express 應用
const app = express();
app.use(express.json());
// 設定 MySQL 連線
const db = mysql.createConnection({
host: 'db', // K8s 中的資料庫服務名稱
user: 'root',
password: 'password',
database: 'bank'
});
// 提款 API
app.post('/withdraw', (req, res) => {
const { accountNumber, amount } = req.body;
// 查詢帳戶餘額
db.query('SELECT balance FROM accounts WHERE accountNumber = ?', [accountNumber], (err, results) => {
if (err) return res.status(500).json({ message: '資料庫錯誤' });
if (results.length === 0) return res.status(404).json({ message: '帳戶未找到' });
const currentBalance = results[0].balance;
// 檢查餘額是否足夠
if (currentBalance < amount) {
return res.status(400).json({ message: '餘額不足' });
}
// 更新帳戶餘額
const newBalance = currentBalance - amount;
db.query('UPDATE accounts SET balance = ? WHERE accountNumber = ?', [newBalance, accountNumber], (updateErr) => {
if (updateErr) return res.status(500).json({ message: '無法更新餘額' });
// 成功返回
res.json({ message: '提款成功', balance: newBalance });
});
});
});
// 啟動服務
app.listen(3000, () => {
console.log('銀行提款系統已啟動,端口 3000');
});
在 Kubernetes 中,您可以使用一個 MySQL 部署來保存銀行的帳戶數據。
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql
spec:
selector:
matchLabels:
app: mysql
strategy:
type: Recreate
template:
metadata:
labels:
app: mysql
spec:
containers:
- image: mysql:5.7
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: password
- name: MYSQL_DATABASE
value: bank
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: mysql-pv-claim
apiVersion: v1
kind: Service
metadata:
name: db
spec:
ports:
- port: 3306
selector:
app: mysql
apiVersion: v1
kind: PersistentVolume
metadata:
name: mysql-pv
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/mnt/data" # 本地存儲路徑
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pv-claim
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
將 Node.js API 部署到 Kubernetes:
apiVersion: apps/v1
kind: Deployment
metadata:
name: bank-api
spec:
replicas: 2
selector:
matchLabels:
app: bank-api
template:
metadata:
labels:
app: bank-api
spec:
containers:
- name: bank-api
image: node:14
ports:
- containerPort: 3000
volumeMounts:
- name: api-code
mountPath: /usr/src/app
workingDir: /usr/src/app
command: ["npm", "start"]
volumes:
- name: api-code
hostPath:
path: "/path/to/your/api/code" # 本地存儲的 API 代碼路徑
apiVersion: v1
kind: Service
metadata:
name: bank-api
spec:
ports:
- port: 80
targetPort: 3000
selector:
app: bank-api
type: LoadBalancer
您可以選擇任何前端框架來構建用戶界面,並將其部署在 K8s 中。
Deployment
和 Service
資源。kubectl apply -f
部署這些 YAML 文件到您的 K8s 集群。const express = require('express');
const mysql = require('mysql2');
// 建立 Express 應用
const app = express();
app.use(express.json());
express
:這是一個輕量級的 Node.js 網頁應用框架,用來處理 HTTP 請求與回應。mysql2
:這個模組用來連接 MySQL 資料庫並執行查詢操作。app.use(express.json())
:這一行代碼允許應用程式解析 JSON 請求體,因為提款請求的資料會以 JSON 格式發送。const db = mysql.createConnection({
host: 'db', // K8s 中的資料庫服務名稱
user: 'root',
password: 'password',
database: 'bank'
});
mysql.createConnection()
:這是用來連接 MySQL 資料庫的設定。連線資訊包括:
host: 'db'
:這裡的 'db' 是指 Kubernetes 中資料庫的服務名稱,它會解析成對應的 MySQL 服務 IP 地址。user: 'root'
和 password: 'password'
:分別是資料庫的使用者帳號和密碼。database: 'bank'
:這裡指定了要使用的資料庫名稱 "bank"。app.post('/withdraw', (req, res) => {
const { accountNumber, amount } = req.body;
// 查詢帳戶餘額
db.query('SELECT balance FROM accounts WHERE accountNumber = ?', [accountNumber], (err, results) => {
if (err) return res.status(500).json({ message: '資料庫錯誤' });
if (results.length === 0) return res.status(404).json({ message: '帳戶未找到' });
const currentBalance = results[0].balance;
// 檢查餘額是否足夠
if (currentBalance < amount) {
return res.status(400).json({ message: '餘額不足' });
}
// 更新帳戶餘額
const newBalance = currentBalance - amount;
db.query('UPDATE accounts SET balance = ? WHERE accountNumber = ?', [newBalance, accountNumber], (updateErr) => {
if (updateErr) return res.status(500).json({ message: '無法更新餘額' });
// 成功返回
res.json({ message: '提款成功', balance: newBalance });
});
});
});
app.post('/withdraw')
:定義了一個 POST 請求的路由,這個路由處理提款請求。當客戶端向這個路由發送提款請求時,請求資料會包含帳戶號碼 (accountNumber
) 和提款金額 (amount
)。db.query()
:這是執行 SQL 查詢的函數。第一次查詢是檢查該帳戶號碼的餘額。結果儲存在 results
變數中。
UPDATE accounts
:如果餘額足夠,則更新資料庫中的餘額,並返回一個成功的 JSON 響應。app.listen(3000, () => {
console.log('銀行提款系統已啟動,端口 3000');
});
app.listen(3000)
:啟動 Node.js 應用,並將其監聽在 3000 端口上。當服務啟動後,伺服器會顯示 "銀行提款系統已啟動,端口 3000" 的訊息。apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql
spec:
selector:
matchLabels:
app: mysql
strategy:
type: Recreate
template:
metadata:
labels:
app: mysql
spec:
containers:
- image: mysql:5.7
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: password
- name: MYSQL_DATABASE
value: bank
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: mysql-pv-claim
apiVersion
: 指定了這個資源使用的 Kubernetes API 版本。kind: Deployment
: 說明這是一個 Deployment,Kubernetes 用來管理應用程式的副本和更新。spec.template.spec.containers
: 指定容器的映像以及環境變量:
image: mysql:5.7
:使用了 MySQL 5.7 的容器映像。MYSQL_ROOT_PASSWORD
和 MYSQL_DATABASE
:這些環境變數用於配置資料庫的 root 密碼和資料庫名稱。volumeMounts
: 將持久性存儲卷掛載到 /var/lib/mysql
,這裡存放 MySQL 資料。apiVersion: v1
kind: Service
metadata:
name: db
spec:
ports:
- port: 3306
selector:
app: mysql
kind: Service
:Service 用來將 MySQL 容器暴露給其他服務(如 API 服務)使用。port: 3306
是 MySQL 的默認端口。apiVersion: apps/v1
kind: Deployment
metadata:
name: bank-api
spec:
replicas: 2
selector:
matchLabels:
app: bank-api
template:
metadata:
labels:
app: bank-api
spec:
containers:
- name: bank-api
image: node:14
ports:
- containerPort: 3000
volumeMounts:
- name: api-code
mountPath: /usr/src/app
workingDir: /usr/src/app
command: ["npm", "start"]
volumes:
- name: api-code
hostPath:
path: "/path/to/your/api/code"
replicas: 2
:設定兩個 API 服務的副本,這樣可以提供高可用性。image: node:14
:Node.js 14 的容器映像。volumeMounts
和 hostPath
:將本地代碼掛載到容器內的 /usr/src/app
,讓容器能夠執行應用程式。apiVersion: v1
kind: Service
metadata:
name: bank-api
spec:
ports:
- port: 80
targetPort: 3000
selector:
app: bank-api
type: LoadBalancer
kind: Service
:這個服務暴露了 API 應用,port: 80
是暴露給外部的端口,targetPort: 3000
是容器內的端口。type: LoadBalancer
說明這個服務將被外部負載均衡器使用,這樣外部用戶可以通過公共 IP 訪問 API。