iT邦幫忙

2024 iThome 鐵人賽

DAY 4
1
Kubernetes

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

day 4 K8s 資料庫模仿google存取資料系統

  • 分享至 

  • xImage
  •  

今天是第四天我們可以寫一個Kubernetes模仿google存取資料系統,因為google是目前大家用量最大的伺服器,因此google是怎麼去存取大量資料的我是相當好奇,因此我想寫一個k8s來模仿,以下是程式碼
要在 Kubernetes (K8s) 上模仿 Google 的資料存取系統,主要涉及設計一個分散式資料庫,類似 Google 的 Bigtable、Spanner 或是 Google 的分散式檔案系統 (GFS)。這些系統強調高可用性、分區容錯、線性擴展能力,並提供一致性和可用性保證。

1. 架構概覽

Kubernetes 是一個容器管理平台,透過其提供的服務來實現一個分散式、擴展的系統架構。假設我們要模仿一個簡單的分散式 NoSQL 資料庫系統,可以分成以下幾個組件:

  • Master Node:控制並管理系統,包括分區和節點間的通訊。
  • Worker Nodes:運行分散式資料存儲服務的節點。
  • Persistent Storage:使用 PersistentVolume (PV) 和 PersistentVolumeClaim (PVC) 來保存資料。

2. 準備環境

首先,確認你有一個 Kubernetes 集群運行。可以使用 Minikube 或 GKE 等 Kubernetes 平台。為了建立這個系統,我們會使用 StatefulSets 來管理資料庫的狀態,以及 PersistentVolume (PV) 和 PersistentVolumeClaim (PVC) 來持久化資料。

3. 編寫 StatefulSet

StatefulSet 用來管理有狀態的應用,比如資料庫節點。這裡我們使用 etcd 作為示例,它是一個分散式資料庫,模仿 Google 的 GFS 系統。

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: etcd-cluster
spec:
  serviceName: "etcd"
  replicas: 3
  selector:
    matchLabels:
      app: etcd
  template:
    metadata:
      labels:
        app: etcd
    spec:
      containers:
      - name: etcd
        image: quay.io/coreos/etcd:v3.4.13
        ports:
        - containerPort: 2379
          name: client
        - containerPort: 2380
          name: peer
        volumeMounts:
        - name: etcd-data
          mountPath: /var/lib/etcd
        env:
        - name: ETCD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: ETCD_INITIAL_ADVERTISE_PEER_URLS
          value: http://$(ETCD_NAME).etcd:2380
        - name: ETCD_ADVERTISE_CLIENT_URLS
          value: http://$(ETCD_NAME).etcd:2379
        - name: ETCD_INITIAL_CLUSTER
          value: etcd-0=http://etcd-0.etcd:2380,etcd-1=http://etcd-1.etcd:2380,etcd-2=http://etcd-2.etcd:2380
        - name: ETCD_INITIAL_CLUSTER_TOKEN
          value: etcd-cluster-1
        - name: ETCD_INITIAL_CLUSTER_STATE
          value: "new"
  volumeClaimTemplates:
  - metadata:
      name: etcd-data
    spec:
      accessModes: ["ReadWriteOnce"]
      resources:
        requests:
          storage: 1Gi

這個 YAML 檔案定義了一個 3 節點的 etcd 叢集,每個節點有一個 PersistentVolumeClaim 來保存資料。該集群會使用 Kubernetes 的 DNS 來讓節點間互相發現彼此。

4. 服務 (Service) 定義

還需要定義一個 Service,用來公開 etcd 叢集內部的對等通訊,以及客戶端的資料存取:

apiVersion: v1
kind: Service
metadata:
  name: etcd
spec:
  clusterIP: None
  ports:
  - port: 2379
    name: client
  - port: 2380
    name: peer
  selector:
    app: etcd

這個 Service 會為 etcd 提供穩定的網路端點。

5. 資料持久化 (PersistentVolume 和 PersistentVolumeClaim)

每個 etcd 節點需要一個 PersistentVolume 來確保資料不會因為 Pod 重啟而丟失。定義一個動態配置 PersistentVolume 的 StorageClass 和 PersistentVolumeClaim:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast
provisioner: kubernetes.io/aws-ebs  # 可以根據你的平台選擇不同的 provisioner
parameters:
  type: gp2

6. 啟動集群

使用 kubectl 部署上面的資源:

kubectl apply -f etcd-statefulset.yaml
kubectl apply -f etcd-service.yaml
kubectl apply -f storageclass.yaml

這樣你會得到一個運行在 Kubernetes 上的分散式 etcd 叢集。你可以把這個系統作為分散式資料存取的基礎,模仿 Google 的 GFS 系統進行讀寫操作。

7. 測試資料存取

可以使用 etcdctl 工具來測試叢集的資料寫入和讀取:

etcdctl --endpoints=http://<etcd-cluster-endpoint>:2379 put foo "Hello, World!"
etcdctl --endpoints=http://<etcd-cluster-endpoint>:2379 get foo

1. StatefulSet 解釋

StatefulSet 是 Kubernetes 中專門用來管理有狀態應用的資源。它確保每個 Pod 都有一個固定的身份(名稱),並且持久化資料即使 Pod 重啟或重新安排,資料依然能夠保留。這裡的 StatefulSet 用來創建和管理一個 3 節點的 etcd 叢集。

YAML 檔案的結構:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: etcd-cluster
  • apiVersion:指定此資源使用的 Kubernetes API 版本,apps/v1 是用於管理應用的版本。
  • kind:表示這是一個 StatefulSet,用於管理有狀態的應用。
  • metadata:包含此資源的名稱,即 etcd-cluster,這個名稱會用來標識這個 StatefulSet

StatefulSet 的規範部分 (spec):

spec:
  serviceName: "etcd"
  replicas: 3
  selector:
    matchLabels:
      app: etcd
  • serviceName:這裡定義了這個 StatefulSet 所屬的服務名稱。這個服務會讓 Pod 之間可以互相通訊。
  • replicas:表示應該有 3 個 etcd 節點,也就是 3 個 Pod。
  • selector:用來選擇標籤為 app=etcd 的 Pod,這些 Pod 屬於這個 StatefulSet。

Pod 的模板 (template):

template:
  metadata:
    labels:
      app: etcd
  spec:
    containers:
    - name: etcd
      image: quay.io/coreos/etcd:v3.4.13
      ports:
      - containerPort: 2379
        name: client
      - containerPort: 2380
        name: peer
      volumeMounts:
      - name: etcd-data
        mountPath: /var/lib/etcd
  • template.metadata.labels:這裡為每個 Pod 設置標籤 app=etcd,這樣 Kubernetes 知道哪些 Pod 屬於這個 StatefulSet。
  • containers:定義了運行在 Pod 中的容器。這裡有一個名為 etcd 的容器,使用 etcd 版本 v3.4.13 的 Docker 映像。
  • ports:兩個端口用於不同用途:
    • 2379:用於客戶端連接(讀取和寫入資料)。
    • 2380:用於節點之間的對等通訊。
  • volumeMounts:將命名為 etcd-data 的持久化卷掛載到容器的 /var/lib/etcd 目錄,這是 etcd 存儲數據的地方。

環境變量 (env):

env:
- name: ETCD_NAME
  valueFrom:
    fieldRef:
      fieldPath: metadata.name
- name: ETCD_INITIAL_ADVERTISE_PEER_URLS
  value: http://$(ETCD_NAME).etcd:2380
- name: ETCD_ADVERTISE_CLIENT_URLS
  value: http://$(ETCD_NAME).etcd:2379
- name: ETCD_INITIAL_CLUSTER
  value: etcd-0=http://etcd-0.etcd:2380,etcd-1=http://etcd-1.etcd:2380,etcd-2=http://etcd-2.etcd:2380
- name: ETCD_INITIAL_CLUSTER_TOKEN
  value: etcd-cluster-1
- name: ETCD_INITIAL_CLUSTER_STATE
  value: "new"

這些環境變量告訴每個 etcd 節點如何進行初始化和彼此之間的連接。

  • ETCD_NAME:動態生成每個 Pod 的名稱,來自於 Kubernetes 的 metadata.name
  • ETCD_INITIAL_ADVERTISE_PEER_URLSETCD_ADVERTISE_CLIENT_URLS:分別指定節點間互相廣告的對等 URL 和客戶端連接 URL。
  • ETCD_INITIAL_CLUSTER:列出叢集中的所有節點,用來讓它們進行節點間的同步。
  • ETCD_INITIAL_CLUSTER_STATE:指定叢集的初始狀態,new 表示這是一個新建立的叢集。

持久化卷 (volumeClaimTemplates):

volumeClaimTemplates:
- metadata:
    name: etcd-data
  spec:
    accessModes: ["ReadWriteOnce"]
    resources:
      requests:
        storage: 1Gi
  • volumeClaimTemplates:這裡定義了每個 etcd 節點所使用的持久化存儲。每個 Pod 都會獲得 1GB 的存儲,來保存其資料。
  • accessModesReadWriteOnce 表示該卷只能被一個節點同時掛載並進行讀寫。

2. Service 解釋

這個服務的定義用來允許外部客戶端訪問 etcd 叢集,並且確保叢集內部節點間的對等通訊。

apiVersion: v1
kind: Service
metadata:
  name: etcd
spec:
  clusterIP: None
  ports:
  - port: 2379
    name: client
  - port: 2380
    name: peer
  selector:
    app: etcd
  • kind:定義這個資源是 Service
  • clusterIP: None:指定這個服務是 "Headless Service",不分配 ClusterIP,只用來讓 Pod 之間進行發現。
  • ports:定義服務公開的端口:
    • 2379:客戶端用來存取資料。
    • 2380:節點間的對等通訊端口。
  • selector:選擇 app=etcd 標籤的 Pod,也就是與該 StatefulSet 關聯的 Pod。

3. PersistentVolumePersistentVolumeClaim 解釋

這部分負責為每個 etcd 節點提供持久化存儲,確保即使 Pod 重啟,數據依然存在。

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast
provisioner: kubernetes.io/aws-ebs
parameters:
  type: gp2
  • StorageClass:定義一個存儲類別,這裡用 kubernetes.io/aws-ebs 作為 provisioner(如果你在 AWS 平台上運行 Kubernetes)。這個類別會自動動態地創建 PersistentVolume,並使用 gp2 類型的 AWS EBS 卷來提供存儲。

總結

這段程式碼定義了一個 3 節點的 etcd 叢集,每個節點都有自己的持久化存儲卷,並且使用 StatefulSet 來確保每個節點都有穩定的網路身份和持久化的數據存儲。Service 提供了叢集內節點間的通訊,以及外部客戶端的存取點。


上一篇
day3 K8s豬隻管理系統
下一篇
day 5 k8s 資料庫管理大賣場系統
系列文
K8s 資料庫管理系統30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言