今天是第二十七天我們可以寫一個k8s海關資料庫管理系統,以下是我的程式碼
這裡我們將使用 React.js 來構建前端界面,它將與後端 API 進行交互:
npx create-react-app customs-management-system
cd customs-management-system
npm install axios
在 App.js 中:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
function App() {
  const [customsData, setCustomsData] = useState([]);
  const [newEntry, setNewEntry] = useState({});
  useEffect(() => {
    fetchData();
  }, []);
  const fetchData = async () => {
    const result = await axios.get('/api/customs');
    setCustomsData(result.data);
  };
  const handleInputChange = (e) => {
    const { name, value } = e.target;
    setNewEntry({ ...newEntry, [name]: value });
  };
  const handleSubmit = async (e) => {
    e.preventDefault();
    await axios.post('/api/customs', newEntry);
    fetchData();
  };
  return (
    <div>
      <h1>海關資料管理系統</h1>
      <form onSubmit={handleSubmit}>
        <input name="name" placeholder="名稱" onChange={handleInputChange} />
        <input name="description" placeholder="描述" onChange={handleInputChange} />
        <button type="submit">新增資料</button>
      </form>
      <h2>資料列表</h2>
      <ul>
        {customsData.map((entry) => (
          <li key={entry.id}>{entry.name}: {entry.description}</li>
        ))}
      </ul>
    </div>
  );
}
export default App;
建立 Node.js 後端應用來處理業務邏輯,並與資料庫進行交互:
mkdir backend
cd backend
npm init -y
npm install express mongoose
在 index.js 中:
const express = require('express');
const mongoose = require('mongoose');
const app = express();
app.use(express.json());
mongoose.connect('mongodb://mongo:27017/customs', { useNewUrlParser: true, useUnifiedTopology: true });
const customsSchema = new mongoose.Schema({
  name: String,
  description: String,
});
const Customs = mongoose.model('Customs', customsSchema);
app.get('/api/customs', async (req, res) => {
  const customs = await Customs.find();
  res.send(customs);
});
app.post('/api/customs', async (req, res) => {
  const newCustom = new Customs(req.body);
  await newCustom.save();
  res.send(newCustom);
});
app.listen(3001, () => {
  console.log('API 伺服器運行在 3001 端口');
});
Kubernetes 上可以部署 MongoDB。首先,撰寫一個 MongoDB 的 K8s 部署 YAML 檔案:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mongo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mongo
  template:
    metadata:
      labels:
        app: mongo
    spec:
      containers:
        - name: mongo
          image: mongo
          ports:
            - containerPort: 27017
          volumeMounts:
            - name: mongo-storage
              mountPath: /data/db
      volumes:
        - name: mongo-storage
          persistentVolumeClaim:
            claimName: mongo-pvc
---
apiVersion: v1
kind: Service
metadata:
  name: mongo
spec:
  ports:
    - port: 27017
  selector:
    app: mongo
接著,定義 PersistentVolumeClaim (PVC) 來儲存 MongoDB 資料:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mongo-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
我們可以將 React 應用、Node.js API 伺服器以及 MongoDB 部署到 Kubernetes 集群。
撰寫 API 的 Kubernetes 部署檔案:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend-api
spec:
  replicas: 1
  selector:
    matchLabels:
      app: backend-api
  template:
    metadata:
      labels:
        app: backend-api
    spec:
      containers:
        - name: backend-api
          image: your-backend-api-image  # 在 Docker Hub 上推送你的後端 API 圖像
          ports:
            - containerPort: 3001
          env:
            - name: MONGO_URL
              value: "mongodb://mongo:27017/customs"
---
apiVersion: v1
kind: Service
metadata:
  name: backend-api
spec:
  ports:
    - port: 3001
  selector:
    app: backend-api
將前端部署為一個 Kubernetes 服務:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend
spec:
  replicas: 1
  selector:
    matchLabels:
      app: frontend
  template:
    metadata:
      labels:
        app: frontend
    spec:
      containers:
        - name: frontend
          image: your-frontend-image  # 在 Docker Hub 上推送你的前端 React 應用圖像
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: frontend
spec:
  ports:
    - port: 80
  selector:
    app: frontend
  type: LoadBalancer
使用 Helm 來打包你的應用程式可以簡化部署流程。可以將 MongoDB、前端和後端配置為 Helm chart,讓整個應用的部署變得更加自動化和一致性。
這部分的程式碼負責建立一個簡單的前端應用,讓使用者可以輸入、查看和新增海關資料。這裡使用 React.js 框架和 axios 來進行前後端 API 的交互。
useState 和 useEffect:const [customsData, setCustomsData] = useState([]);
const [newEntry, setNewEntry] = useState({});
這裡 useState 用來定義兩個狀態變數:
customsData:儲存從後端 API 獲取的海關資料列表。newEntry:儲存使用者輸入的新資料。useEffect(() => {
  fetchData();
}, []);
useEffect 會在元件渲染後執行一次,用來觸發 fetchData() 函數來獲取資料。
fetchData 函數:const fetchData = async () => {
  const result = await axios.get('/api/customs');
  setCustomsData(result.data);
};
這個函數會向後端 API 發送 GET 請求,從 /api/customs 端點取得海關資料,然後將結果保存到 customsData 中。
handleInputChange 函數:const handleInputChange = (e) => {
  const { name, value } = e.target;
  setNewEntry({ ...newEntry, [name]: value });
};
這個函數會在使用者輸入資料時更新 newEntry,使新資料能夠被即時反映出來。e.target 代表當前的輸入框,name 和 value 代表這個輸入框的名稱和值。
handleSubmit 函數:const handleSubmit = async (e) => {
  e.preventDefault();
  await axios.post('/api/customs', newEntry);
  fetchData();
};
當使用者提交表單時,這個函數會被觸發。它會向後端 API 發送一個 POST 請求,將使用者輸入的 newEntry 資料發送到伺服器,並重新呼叫 fetchData() 以更新顯示的資料。
<ul>
  {customsData.map((entry) => (
    <li key={entry.id}>{entry.name}: {entry.description}</li>
  ))}
</ul>
這段程式碼會渲染一個列表,顯示從後端 API 獲取的所有海關資料。
這部分的程式碼負責處理資料庫邏輯,使用 Express 框架來建立後端伺服器,並且透過 MongoDB 來儲存和讀取海關資料。
mongoose.connect('mongodb://mongo:27017/customs', { useNewUrlParser: true, useUnifiedTopology: true });
這裡使用 mongoose 來連接 MongoDB 資料庫,mongodb://mongo:27017/customs 是資料庫的連接字串,mongo 是在 Kubernetes 中部署的 MongoDB 服務的名稱。
const customsSchema = new mongoose.Schema({
  name: String,
  description: String,
});
mongoose.Schema 定義了一個名為 customsSchema 的模式,表示每筆海關資料都包含 name 和 description 兩個欄位,型別皆為 String。
const Customs = mongoose.model('Customs', customsSchema);
這裡創建了名為 Customs 的模型,這是基於我們定義的 customsSchema,它將用來與 MongoDB 進行操作。
app.get('/api/customs', async (req, res) => {
  const customs = await Customs.find();
  res.send(customs);
});
這段程式碼建立了一個 /api/customs 端點,當前端向這個端點發送 GET 請求時,後端會從資料庫中讀取所有的海關資料並將其返回給前端。
app.post('/api/customs', async (req, res) => {
  const newCustom = new Customs(req.body);
  await newCustom.save();
  res.send(newCustom);
});
這裡建立了一個 POST 端點,當前端向這個端點發送新的海關資料時,後端會將資料保存到資料庫並返回保存後的資料。
app.listen(3001, () => {
  console.log('API 伺服器運行在 3001 端口');
});
這行程式碼會啟動後端伺服器並監聽 3001 端口,當 API 收到請求時,它會進行相應的處理。
這部分程式碼負責將 MongoDB 部署到 Kubernetes,MongoDB 將用來存儲所有的海關資料。
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mongo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mongo
  template:
    metadata:
      labels:
        app: mongo
    spec:
      containers:
        - name: mongo
          image: mongo
          ports:
            - containerPort: 27017
          volumeMounts:
            - name: mongo-storage
              mountPath: /data/db
      volumes:
        - name: mongo-storage
          persistentVolumeClaim:
            claimName: mongo-pvc
這裡定義了 MongoDB 在 Kubernetes 上的部署:
mongo,使用了官方的 MongoDB Docker 映像。volumeMounts 和 volumes 定義了資料卷,確保 MongoDB 的資料是持久化的。apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mongo-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
這段程式碼定義了資料持久化卷 (PVC),確保 MongoDB 的資料存儲在一個 1GiB 的持久性磁碟中。
這部分負責將前端應用和後端 API 部署到 Kubernetes。
apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend-api
spec:
  replicas: 1
  selector:
    matchLabels:
      app: backend-api
  template:
    metadata:
      labels:
        app: backend-api
    spec:
      containers:
        - name: backend-api
          image: your-backend-api-image
          ports:
            - containerPort: 3001
          env:
            - name: MONGO_URL
              value: "mongodb://mongo:27017/customs"
這裡部署了後端 API,使用了名為 your-backend-api-image 的 Docker 映像,並暴露 3001 端口。MONGO_URL 環境變數用來告知後端如何連接 MongoDB。
apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend
spec:
  replicas: 1
  selector:
    matchLabels:
      app: frontend
  template:
    metadata:
      labels:
        app: frontend
    spec:
      containers:
        - name: frontend
          image: your-frontend-image
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: frontend
spec:
  ports:
    - port: 80
  selector:
    app: frontend
  type: LoadBalancer
這裡部署了前端應用,使用名為 your-frontend-image 的 Docker 映像,並暴露 80 端口。Service 將這個應用設定為一個 LoadBalancer,使外部可以訪問。
這樣就完成了整個系統的部署和運行,你可以在 Kubernetes 集群中
運行前端、後端和 MongoDB,並且它們會協同工作來處理海關資料的管理和顯示。