在雲端原生時代,Kubernetes 已成為容器協調的標準選擇。然而,許多開發者和組織在考慮是否該建立自主管理的 Kubernetes 叢集時常感到猶豫。玄貓在多年管理大規模容器化環境的經驗中,深刻體會到掌握自建叢集的技術細節對於理解整個系統架構的重要性。

為何需要自建 Kubernetes 叢集?

在進入技術細節之前,我們先來討論為什麼要考慮建立自主管理的 Kubernetes 叢集:

  • 深入學習和實驗:透過親手建置,能夠深入理解 Kubernetes 的運作機制
  • 成本控制:對於特定規模的專案,自主管理可能比使用雲端服務更具成本效益
  • 客製化需求:完全掌控基礎設施,能夠根據特定需求進行最佳化
  • 技術自主:減少對特定雲端供應商的依賴

系統架構概述

在這個專案中,我們將建立一個包含以下元件的本地 Kubernetes 環境:

  • 4台 QEMU 虛擬機器
  • 私有網路設定(/24 網段)
  • 3個 Kubernetes 節點
  • 1台執行 HAProxy 的負載平衡器
  • 虛擬網路橋接器(br0)
  • 每個節點的 TAP 裝置

這樣的架構設計能夠模擬真實的生產環境,同時保持足夠的靈活性供實驗和學習使用。

重要考量事項

在開始建置之前,有幾點重要的注意事項:

  1. 環境定位:這個設定主要適合用於開發和測試環境,不建議直接用於生產環境。

  2. 技術能力要求:建立自主管理的叢集需要對 Linux 系統管理、網路設定和容器技術有深入瞭解。

  3. 維護責任:相較於管理型服務,自主管理需要投入更多時間在維護和更新上。

玄貓建議,在決定採用自主管理的 Kubernetes 之前,應該先評估團隊的技術能力和專案需求。如果專案規模較小,使用 Docker Compose 可能是更合適的選擇;如果缺乏 Kubernetes 專業知識,選擇管理型服務可能更為明智。

接下來,我們將逐步探討完整的建置流程,從虛擬機器的設定、網路設定,到 Kubernetes 叢集的佈署,以及負載平衡器的架設。每個步驟我都會分享在實際佈署過程中的經驗和注意事項。

在建置私有雲或測試環境時,虛擬化技術扮演著關鍵角色。玄貓在多年的技術實踐中,發現QEMU搭配Cloud-init是一個非常靈活與強大的組合。今天就來分享如何建立一個完整的虛擬化環境。

網路環境架構設計

在這個虛擬環境中,我們採用dnsmasq作為DHCP伺服器,負責根據MAC位址分配IP位址給各個節點。這種設計有幾個重要優勢:

  1. 確保IP位址分配的可預測性
  2. 簡化網路管理
  3. 提供DNS服務功能

玄貓建議在選擇虛擬化方案時,可以考慮以下幾種選項:

  • QEMU:輕量與靈活
  • VirtualBox:使用者介面友善
  • VMware:企業級功能完整
  • Libvirt:提供統一的抽象層

虛擬私有網路設定

我們的環境模擬了一個VPC(Virtual Private Cloud)架構,透過iptables規則允許虛擬機器存取外部網路。這種設計特別適合:

  • 開發環境隔離
  • 測試環境佈署
  • 安全性驗證

Debian虛擬機器佈署流程

基礎映像檔準備

首先,我們需要下載Debian 12的雲端映像檔:

wget -O debian12.qcow2 https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-genericcloud-amd64.qcow2

Cloud-init設定

建立cloud-init設定檔案 cloud_init.yaml

#cloud-config
users:
  - name: root
    ssh-authorized-keys:
      - <SSH_PUBLIC_KEY>

產生Seed ISO

使用cloud-localds工具產生啟動用的ISO檔:

cloud-localds -v seed.iso cloud_init.yaml

虛擬機器映像檔準備

複製基礎映像檔作為新虛擬機器使用:

cp ./debian12.qcow2 ./test.qcow2

啟動虛擬機器

使用以下QEMU指令啟動虛擬機器:

sudo qemu-system-x86_64 \
-m 2G \
-smp 2 \
-device virtio-net-pci,netdev=net0 \
-netdev user,id=net0,hostfwd=tcp::2222-:22 \
-drive file=./test.qcow2,if=virtio,cache=writeback,discard=ignore,format=qcow2 \
-drive file=./seed.iso,if=virtio,media=cdrom

啟動引數說明

  • -m 2G:設定2GB記憶體
  • -smp 2:使用2個CPU核心
  • -device virtio-net-pci:設定網路裝置
  • -netdev user:設定使用者模式網路
  • -drive:設定儲存裝置

在實際佈署過程中,玄貓發現這樣的設定特別適合開發測試環境,因為它提供了足夠的靈活性,同時保持了環境的一致性。不過要注意,在生產環境中可能需要根據實際負載調整這些引數。

使用Cloud-init進行自動化設定不僅提高了佈署效率,也確保了環境的一致性。這個方法特別適合需要快速佈署多個測試環境的場景。在實務上,我建議將這些步驟整合到自動化指令碼中,進一步提升工作效率。

最後,這種虛擬化環境的建置方式特別適合用於微服務架構的開發和測試。透過靈活的網路設定和自動化的佈署流程,開發團隊可以快速建立所需的測試環境,大幅提升開發效率。

在建置虛擬化環境時,QEMU是一個功能強大與靈活的工具。讓玄貓帶領大家深入理解QEMU的指令引數與網路設定的精髓。

QEMU指令引數詳解

讓我們先來分析一個典型的QEMU啟動指令:

qemu-system-x86_64 -m 2G -smp 2 \
-device virtio-net-pci,netdev=net0 \
-netdev user,id=net0,hostfwd=tcp::2222-:22 \
-drive file=./test.qcow2,format=qcow2 \
-drive file=./seed.iso,media=cdrom \
-boot d \
-serial stdio \
-machine type=pc,accel=kvm

關鍵引數說明

  1. 系統架構與資源設定
  • qemu-system-x86_64: 指定虛擬機器的CPU架構為x86_64
  • -m 2G: 設定2GB記憶體
  • -smp 2: 設定2個虛擬CPU核心
  1. 網路裝置設定
  • -device virtio-net-pci,netdev=net0: 建立虛擬網路卡裝置
  • -netdev user,id=net0,hostfwd=tcp::2222-:22: 設定網路後端並進行連線埠轉送
  1. 儲存裝置設定
  • -drive file=./test.qcow2: 指定系統磁碟映像檔
  • -drive file=./seed.iso: 掛載ISO映像檔作為CD-ROM
  1. 其他重要設定
  • -boot d: 設定從CD-ROM開機
  • -serial stdio: 將序列埠輸出導向終端機
  • -machine type=pc,accel=kvm: 啟用KVM加速

虛擬網路架構設計

在建置多節點虛擬環境時,網路架構的設計至關重要。玄貓建議採用橋接模式(Bridge Mode)來建立虛擬網路,這樣可以讓所有虛擬機器都在同一個網段中進行通訊。

主要網路元件包含:

  1. 虛擬橋接器(Bridge)
  • 作為虛擬交換器使用
  • 連線所有虛擬機器的網路介面
  • 提供類別似實體交換器的功能
  1. TAP裝置
  • 每個虛擬機器都需要一個專屬的TAP裝置
  • TAP裝置連線到虛擬橋接器
  • 負責虛擬機器與外部網路的資料傳輸
  1. 虛擬網路卡
  • 在虛擬機器內部可見的網路介面
  • 透過virtio-net驅動程式提供高效能網路存取
  • 與TAP裝置配對工作
  1. 網路後端
  • 處理實際的網路資料傳輸
  • 可選擇user networking或bridge networking模式
  • 決定虛擬機器如何與外部網路互連

在實務上,玄貓建議避免使用預設的user networking模式,因為它雖然容易設定,但效能較差與無法支援虛擬機器之間的直接通訊。相反地,採用bridge networking可以:

  • 提供更好的網路效能
  • 支援虛擬機器之間的直接通訊
  • 更接近實體網路的運作方式
  • 便於管理與監控

建立虛擬網路時,需要注意幾個關鍵點:

  1. 確保bridge裝置正確設定
  2. 設定適當的網路遮罩與IP位址範圍
  3. 規劃好各個虛擬機器的網路介面
  4. 考慮網路安全性設定
# 建立虛擬橋接器
ip link add br0 type bridge
ip link set br0 up

# 建立TAP裝置並連線到橋接器
ip tuntap add tap0 mode tap
ip link set tap0 master br0
ip link set tap0 up

透過這樣的設定,我們就能建立一個功能完整的虛擬網路環境,讓多個虛擬機器能夠順暢地進行通訊。在實際佈署時,還需要根據具體需求調整網路引數,確保整個虛擬化環境的穩定運作。

在多年的虛擬化環境建置經驗中,玄貓發現良好的網路規劃是確保虛擬化專案成功的關鍵。合理的網路架構不僅能提供更好的效能,還能大幅降低後續維護的複雜度。

虛擬化技術的發展日新月異,但基本原理始終不變。掌握了QEMU的核心概念和網路設定要點,就能靈活運用這些知識來建立各種規模的虛擬化環境。透過實踐和持續學習,相信大家都能熟練運用這些技術來解決實際問題。

在多年的網路架構設計經驗中,玄貓發現網路橋接與DNS服務的正確設定對於建立穩定的網路環境至關重要。本文將分享如何在Linux系統上建立網路橋接並設定dnsmasq服務,開發一個完整的網路管理解決方案。

建立網路橋接裝置

首先,讓我們使用ip指令建立虛擬網路橋接裝置。這個橋接器將作為我們網路環境的核心元件:

# 建立橋接裝置
sudo ip link add br0 type bridge

# 設定網路介面位址
sudo ip addr add 10.0.0.0/24 dev br0

# 啟動橋接裝置
sudo ip link set up dev br0

在這段程式碼中:

  • 第一行建立名為br0的橋接裝置
  • 第二行為橋接器設定IP位址,使用10.0.0.0/24網段
  • 第三行啟動該橋接裝置

使用以下指令確認橋接裝置是否正確建立:

ip -d link show br0

建立TAP網路介面

接下來,我們需要為每個節點建立TAP裝置。TAP裝置是虛擬網路裝置,能夠在使用者空間程式與核心網路堆積積疊之間傳輸資料:

for NODE_NAME in node0 node1 node2 node3; do
    echo "${NODE_NAME}tap"
    # 建立TAP裝置
    sudo ip tuntap add "${NODE_NAME}tap" mode tap
    # 啟動裝置
    sudo ip link set "${NODE_NAME}tap" up
    # 連線至橋接器
    sudo ip link set "${NODE_NAME}tap" master br0
done

這段程式碼執行:

  • 建立四個TAP裝置,分別對應到四個節點
  • 啟動每個TAP裝置
  • 將TAP裝置連線到先前建立的br0橋接器

設定dnsmasq服務

dnsmasq是一個輕量級的DNS快取與DHCP伺服器,我們將其設定為網路環境的核心服務:

# dnsmasq設定檔案內容
interface=br0
bind-interfaces
no-resolv
no-hosts
domain-needed
bogus-priv
server=8.8.8.8
server=8.8.4.4
dhcp-range=10.0.0.0,10.0.0.255
dhcp-host=86:e2:e3:21:13:b4,10.0.0.10,node0
dhcp-host=7c:92:6e:84:1f:50,10.0.0.11,node1
dhcp-host=b0:aa:4c:4c:7b:1a,10.0.0.12,node2
dhcp-host=a6:fc:4a:66:8f:c9,10.0.0.13,node3

設定檔案重點說明:

  • 繫結到br0橋接介面
  • 停用系統的resolv.conf與hosts檔案
  • 使用Google的DNS伺服器(8.8.8.8與8.8.4.4)
  • 設定DHCP位址範圍
  • 為特定MAC位址的裝置指派固定IP

啟動dnsmasq服務

最後,使用以下指令在背景執行dnsmasq服務:

sudo dnsmasq \
    --no-daemon --conf-file=./dnsmasq.conf \
    > dnsmasq.log 2>&1 &
echo $! > dnsmasq.pid

這個指令會:

  • 以非守護程式模式執行dnsmasq
  • 使用指定的設定檔案
  • 將輸出導向log檔案
  • 儲存程式ID以便後續管理

在實際佈署中,這套設定能夠為網路環境提供穩定的DNS快取與DHCP服務。透過適當的網路橋接設定,我們成功建立了一個可靠的網路管理環境,不僅支援多個節點的網路連線,還提供了DNS查詢與IP位址管理的功能。

這套設定特別適合需要建立虛擬網路環境的場景,如開發測試環境或虛擬機器叢集。在實務應用中,這種設定方式已被證實能有效提升網路管理效率並降低維護成本。

設定 iptables 與建置節點

在建置 Kubernetes 叢集的過程中,我們需要確保節點之間能正常通訊,以及能夠連線外部網路。以下是關鍵的設定步驟:

設定 iptables NAT 轉發規則

首先,我們需要設定 iptables 規則,讓節點能夠存取網際網路:

# 新增 NAT 轉發規則
sudo iptables -t nat -A POSTROUTING ! -o br0 --source 10.0.0.0/24 -j MASQUERADE

# 若要移除該規則,可使用以下指令
sudo iptables -t nat -D POSTROUTING ! -o br0 --source 10.0.0.0/24 -j MASQUERADE

** **

  • -t nat:指定要操作 NAT 表
  • -A POSTROUTING:在 POSTROUTING 鏈中新增規則
  • ! -o br0:不經由 br0 介面輸出的流量
  • --source 10.0.0.0/24:來源為 10.0.0.0/24 網段的流量
  • -j MASQUERADE:執行 MASQUERADE 動作,也就是源 NAT 轉換

這個規則讓節點不只能與主機通訊(如 SSH 連線),還能夠存取區域網路與網際網路。

建立虛擬機器節點

在設定好網路環境後,接著我們要建立虛擬機器節點。首先複製基礎映像檔並調整容量:

# 為每個節點複製並調整映像檔大小
for NODE_NAME in node0 node1 node2 node3; do
    # 複製基礎映像檔
    cp ./debian12.qcow2 "./${NODE_NAME}.qcow2"
    
    # 調整容量至 10GB
    qemu-img resize "./${NODE_NAME}.qcow2" 10G
done

玄貓提醒,雖然我們設定了 10GB 的容量,但由於使用 qcow2 格式,實際檔案大小會根據實際使用量動態成長,這讓我們能更有效率地使用儲存空間。

啟動第一個節點

接下來使用 QEMU 啟動第一個節點:

NODE_NAME="node0"
NODE_MAC="86:e2:e3:21:13:b4"
NODE_DISK="./${NODE_NAME}.qcow2"

sudo qemu-system-x86_64 \
    -name "$NODE_NAME" \
    -m 2G \
    -smp 2 \
    -device "virtio-net-pci,netdev=${NODE_NAME}tap,mac=${NODE_MAC}" \
    -netdev "tap,id=${NODE_NAME}tap,ifname=${NODE_NAME}tap,script=no" \
    -drive "file=./${NODE_DISK},if=virtio,cache=writeback,discard=ignore,format=qcow2" \
    -drive "file=./seed.iso,media=cdrom" \
    -boot d \
    -machine type=pc,accel=kvm &

** **

  • -name:設定虛擬機器名稱
  • -m 2G:分配 2GB 記憶體
  • -smp 2:設定 2 個 CPU 核心
  • -device-netdev:設定網路裝置,包含 MAC 位址與 TAP 裝置設定
  • -drive:設定儲存裝置,包含系統磁碟與 cloud-init 設定檔
  • -machine:設定機器類別並啟用 KVM 加速

當虛擬機器啟動後,dnsmasq 會自動分配 IP 位址。我們可以透過觀察 dnsmasq 的日誌來確認 IP 位址是否正確分配:

watch -n0.1 cat ./dnsmasq.log

從日誌中可以看到 DHCP 分配過程:

  1. 節點發出 DHCP 探索請求
  2. dnsmasq 提供 IP 位址
  3. 節點請求使用該 IP
  4. dnsmasq 確認並完成 IP 分配

這樣我們就完成了第一個節點的基本設定,接下來就可以依此方式建立其他節點,為建置 Kubernetes 叢集做好準備。

在容器化應用程式逐漸成為主流的今日,建置一個可靠的 Kubernetes 叢集變得越來越重要。本文將介紹如何使用 k0s 這個輕量級的 Kubernetes 發行版,建立一個功能完整的叢集系統。

節點初始連線設定

完成節點的基礎設定後,我們可以透過 SSH 連線到已設定 IP 位址的節點:

ssh root@10.0.0.10

k0s:精簡高效的 Kubernetes 發行版

在眾多 Kubernetes 發行版中,k0s 以其獨特的優勢脫穎而出:

  • 單一執行檔設計,便於佈署和維護
  • 以 systemd 服務形式運作
  • 專注於核心功能,減少不必要的套件
  • 保持與上游 Kubernetes 的高度一致性

k0s 與另一個知名的輕量級發行版 K3s 相比,各有特色。K3s 著重於易用性並預裝了許多常用工具,適合資源受限的環境;而 k0s 則追求極簡設計,讓使用者能夠根據需求自由擴充功能。

使用 k0sctl 佈署叢集

k0sctl 是 k0s 專案提供的官方佈署工具。以下是一個基本的叢集設定範例:

apiVersion: k0sctl.k0sproject.io/v1beta1
kind: Cluster
metadata:
  name: local-cluster
spec:
  hosts:
  - role: controller
    installFlags:
    - --debug
    ssh:
      address: 10.0.0.10
      user: root
      port: 22
      keyPath: ~/.ssh/id_ed25519
  - role: worker
    installFlags:
    - --debug
    ssh:
      address: 10.0.0.11
      user: root
      port: 22
      keyPath: ~/.ssh/id_ed25519
  - role: worker
    installFlags:
    - --debug
    ssh:
      address: 10.0.0.12
      user: root
      port: 22
      keyPath: ~/.ssh/id_ed25519
  k0s:
    version: 1.27.5+k0s.0
    dynamicConfig: true

設定檔案解析

此設定建立了一個包含三個節點的叢集:

  • 一個控制平面節點(Controller):負責管理叢集核心元件
  • 兩個工作節點(Worker):用於執行實際的工作負載

在正式環境中,建議採用 2k + 1 的控制平面節點設定(k 代表叢集可承受的節點故障數),並將控制平面節點分散在不同的失敗網域中,以提高系統可用性。

佈署叢集

使用以下指令開始佈署叢集:

k0sctl --debug apply \
  --config ./k0sctl.yaml \
  --kubeconfig-out kubeconfig
  • --debug:啟用詳細的除錯輸出,有助於排查佈署問題
  • --config:指定叢集設定檔案路徑
  • --kubeconfig-out:指定產生的 kubeconfig 檔案存放位置

若遇到 k0s 執行檔下載速度過慢的情況,玄貓建議直接從 GitHub 發布頁面下載對應版本的執行檔,並將其手動放置於節點的 /usr/local/bin/k0s 目錄下。這樣不僅可以加快佈署速度,還能確保安裝檔案的完整性。

在多年的叢集佈署經驗中,玄貓發現採用這種精簡的 k0s 方案特別適閤中小規模的生產環境。它不僅降低了維護複雜度,還為後續的功能擴充提供了充分的彈性。相較於其他預裝眾多元件的發行版,k0s 讓我們能夠更好地掌控叢集的每個導向,從而開發出真正符合需求的容器化環境。

設定 Ingress 控制器與負載平衡

在我們建立完 Kubernetes 叢集後,接下來要設定 Ingress 控制器和外部負載平衡器,讓流量能夠順利到達 Pod。這個步驟對於建立生產環境級別的 Kubernetes 叢集來說是相當重要的。

首先,讓我們驗證叢集運作狀態:

KUBECONFIG=./kubeconfig kubectl get pods -A

檢查結果應該會顯示所有系統 Pod 都在正常執行中,包括 CoreDNS、Konnectivity Agent、Kube Proxy 等重要元件。

在探討 Ingress 設定之前,我們需要理解幾個關鍵概念:

Ingress 控制器的角色是管理 HTTP 流量路由至應用程式服務。然而,它本身並不負責處理外部流量如何進入叢集。這部分工作是由負載平衡器來完成的。

在公有雲環境中(如 GKE 或 EKS),當我們將 Ingress 控制器的服務類別設定為 LoadBalancer 時,雲端平台會自動設定一個外部負載平衡器。這個負載平衡器會分配一個外部 IP 位址,所有進入該 IP 的流量都會被導向 Ingress 控制器。

但在我們的自建環境中,需要手動設定這個架構。以下是詳細的設定步驟:

  1. 安裝 ingress-nginx 控制器:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.2/deploy/static/provider/baremetal/deploy.yaml
  1. 設定 NodePort 服務:
kubectl -n ingress-nginx patch svc ingress-nginx-controller -p '{"spec": {"type": "NodePort"}}'

在自建環境中,我們採用 NodePort 方式暴露服務,這與雲端環境中使用 LoadBalancer 的方式有所不同。這是因為在沒有雲端提供商的情況下,我們需要自行管理流量的進入點。

值得注意的是,Kubernetes 中的服務類別有四種:

  • ClusterIP(叢集內部存取)
  • NodePort(透過節點連線埠存取)
  • LoadBalancer(需要外部負載平衡器)
  • ExternalName(外部服務對映)

在我們的架構中,第四個節點將扮演負載平衡器的角色,這讓我們能夠在不依賴雲端服務的情況下,依然保持高用性和負載平衡的特性。

接下來,我們將繼續設定負載平衡器,確保外部流量能夠正確地路由到我們的應用程式。這個設定過程需要特別注意安全性和效能的考量,以確保生產環境的穩定運作。 讓我將這段內容改寫為一篇探討 HAProxy 與 Kubernetes Ingress 整合的技術文章。

在設計企業級 Kubernetes 叢集時,建立可靠的入口流量管理機制至關重要。本文將詳細說明如何整合 HAProxy 與 Kubernetes Ingress Controller,開發一個強大的反向代理架構。

系統架構概觀

在這個架構中,我們將 HAProxy 佈署於獨立的節點(node3),用於處理所有進入叢集的 HTTP 和 HTTPS 流量。這些流量會被反向代理到 Ingress Controller 的 NodePort 服務。

流量路由機制

整體的網路流量路徑如下:

  1. 外部請求首先到達 HAProxy
  2. HAProxy 將流量轉發至 Ingress Controller 的 NodePort 服務
  3. Ingress Controller 根據路由規則將請求導向對應的後端服務

這種設計能夠確保流量得到有效管理與分配,同時提供更好的安全性與可控性。

佈署 Ingress Controller

首先需要在 Kubernetes 叢集中佈署 ingress-nginx controller。玄貓建議在正式環境中使用 Helm 進行佈署,這樣能夠更好地管理版本與設定:

# 使用官方提供的 baremetal 設定檔佈署
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.2/deploy/static/provider/baremetal/deploy.yaml

驗證佈署狀態

佈署完成後,執行以下指令確認 Pod 狀態:

kubectl get pods -n ingress-nginx

應該能看到類別似這樣的輸出:

NAME                                        READY   STATUS      RESTARTS   AGE
ingress-nginx-controller-79bc9f5df8-vpmrw   1/1     Running     0          60s
ingress-nginx-admission-create-dv4p7        0/1     Completed   0          60s
ingress-nginx-admission-patch-7htxb         0/1     Completed   2          60s

檢查服務設定

接著檢視 Ingress Controller 服務的設定:

kubectl get -n ingress-nginx svc

這會顯示 NodePort 服務的詳細資訊:

NAME                                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx-controller             NodePort    10.106.85.180   <none>        80:30299/TCP,443:30448/TCP   85s
ingress-nginx-controller-admission   ClusterIP   10.105.197.7    <none>        443/TCP                      85s

在這個輸出中,要特別注意 NodePort 的對應連線埠:

  • HTTP 流量使用 30299 連線埠
  • HTTPS 流量使用 30448 連線埠

這些連線埠號碼是系統自動分配的,在不同環境中可能會有所不同,但一旦分配後就會保持穩定。

佈署 HAProxy

接下來在負載平衡節點上安裝 HAProxy:

ssh "root@10.0.0.13" "apt-get update -y && apt-get install -y haproxy=2.6.*"

確認 HAProxy 運作狀態

安裝完成後,檢查 HAProxy 服務狀態:

ssh root@10.0.0.13 systemctl status haproxy

如果看到類別似以下的輸出,表示 HAProxy 已經正常運作:

● haproxy.service - HAProxy Load Balancer
     Loaded: loaded (/lib/systemd/system/haproxy.service; enabled; preset: enabled)
     Active: active (running) since Wed 2023-09-27 18:03:55 UTC; 21s ago
     Docs: man:haproxy(1)

這個基礎架構的建立為後續的進階設定打下了良好的基礎。在實際應用中,我們還需要根據具體需求進行更細緻的設定,例如 SSL 終止、工作階段永續性、健康檢查等功能。這些進階設定不僅能提升系統的可靠性,還能為應用提供更好的效能與安全性保障。

在建置這類別架構時,玄貓建議在正式佈署前,先在測試環境中進行完整的功能驗證,確保所有元件都能正常協同工作。同時,也要建立完善的監控機制,以便及時發現和解決可能出現的問題。

在建構大規模系統架構時,負載平衡器扮演著關鍵角色。今天玄貓要深入分享如何設定與最佳化 HAProxy,這套強大的負載平衡解決方案。在多年的系統架構經驗中,玄貓發現適當的 HAProxy 設定不僅能提升系統效能,更能確保服務的高用性。

HAProxy 基礎架構概述

HAProxy 的核心架構主要由前端(Frontend)和後端(Backend)兩大部分組成:

  • 前端負責接收外部連線請求
  • 後端則處理將請求導向實際的服務節點

HAProxy 設定檔案解析

讓我們來看一個完整的 HAProxy 設定範例:

global
    log /dev/log local0
    log /dev/log local1 notice
    chroot /var/lib/haproxy
    stats socket /run/haproxy/admin.sock mode 660 level admin
    stats timeout 30s
    user haproxy
    group haproxy
    daemon

defaults
    log global
    mode http
    option httplog
    option dontlognull
    timeout connect 5000
    timeout client 50000
    timeout server 50000
    timeout http-request 10000

這段設定了 HAProxy 的基礎運作引數,讓我為各位解析重要設定:

  1. global 區段:定義全域性的系統層級設定

    • log 指定日誌記錄位置
    • chroot 確保安全性隔離
    • stats socket 提供管理介面
  2. defaults 區段:設定預設的連線引數

    • mode http 指定預設的處理模式
    • 各種 timeout 設定確保連線的穩定性

HTTP 和 HTTPS 流量處理設定

接下來看前端和後端的具體設定:

frontend http-frontend
    bind *:80
    default_backend http-backend

backend http-backend
    server node1 10.0.0.11:30299
    server node2 10.0.0.12:30299

frontend https-frontend
    mode tcp
    option tcplog
    bind *:443
    default_backend https-backend

backend https-backend
    mode tcp
    server node1 10.0.0.11:30448
    server node2 10.0.0.12:30448

這個設定建立了兩組前端和後端配對:

  1. HTTP 處理

    • 前端繫結 80 埠
    • 後端指向兩個服務節點
  2. HTTPS 處理

    • 採用 TCP 模式處理加密流量
    • 實作 TLS Passthrough 機制

TLS Passthrough 機制深入解析

在 HTTPS 流量處理中,玄貓採用了 TLS Passthrough 機制。這種方式有以下優點:

  1. 降低 HAProxy 的運算負擔
  2. 簡化憑證管理流程
  3. 維持端對端加密的完整性

在這個設定中,HAProxy 不需要解密 HTTPS 流量,而是直接將加密的 TCP 封包轉發到後端伺服器。這種方式特別適合與 Kubernetes 整合,因為憑證管理可以統一在 Kubernetes 層面處理。

效能最佳化與錯誤處理

系統還包含了完整的錯誤頁面處理機制:

errorfile 400 /etc/haproxy/errors/400.http
errorfile 403 /etc/haproxy/errors/403.http
errorfile 408 /etc/haproxy/errors/408.http
errorfile 500 /etc/haproxy/errors/500.http
errorfile 502 /etc/haproxy/errors/502.http
errorfile 503 /etc/haproxy/errors/503.http
errorfile 504 /etc/haproxy/errors/504.http

這些錯誤頁面設定確保了在發生問題時,使用者能收到清晰的錯誤訊息,有助於問題診斷和使用者經驗最佳化。

根據多年的佈署經驗,玄貓建議在實際執行環境中,應該特別注意以下幾點:

  1. 根據實際需求調整 timeout 設定
  2. 開啟適當的日誌記錄級別
  3. 定期檢查系統效能指標
  4. 建立完善的監控機制

透過以上的設定與最佳化,我們就能建立一個穩定、高效的負載平衡系統。正確的 HAProxy 設定不僅能提供可靠的負載平衡功能,還能確保系統的安全性和可維護性。在實際佈署時,別忘了根據具體環境和需求調整這些引數。

透過這樣的設定,系統就能夠有效處理各種網路流量,並在需要時進行適當的負載分配。記住,好的負載平衡器設定是構建高用性系統的關鍵基礎。

在進行了一連串的基礎建設後,我們終於要進入 Kubernetes 叢集的應用程式佈署階段。過去在協助企業建置容器平台時,我發現許多團隊往往在這個階段遇到挫折。今天就讓玄貓帶領大家完成這個重要里程碑,並分享多年實戰經驗。

Ingress 路由驗證與問題排除

當我們收到 404 錯誤而非連線錯誤時,這其實是個好訊息。這表示請求已經成功透過負載平衡器並抵達 Ingress 控制器,只是尚未正確路由到後端服務。讓我們來佈署一個測試應用程式來驗證整個流程。

佈署測試應用程式

我們將使用 whoami 容器來建立一個簡單的測試環境。這個輕量級應用程式能夠回傳請求的詳細資訊,非常適合用來除錯與驗證設定。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: whoami-test
  labels:
    app.kubernetes.io/name: whoami
spec:
  replicas: 3
  selector:
    matchLabels:
      app.kubernetes.io/name: whoami
  template:
    metadata:
      labels:
        app.kubernetes.io/name: whoami
    spec:
      containers:
      - name: whoami
        image: traefik/whoami:v1.10
        ports:
        - containerPort: 80
  • 這個 Deployment 設定檔建立了三個 whoami 容器副本
  • 使用 app.kubernetes.io/name: whoami 標籤來識別與選擇 Pod
  • 容器使用官方的 traefik/whoami 映像檔,並開放 80 埠

接著建立對應的 Service 與 Ingress 資源:

apiVersion: v1
kind: Service
metadata:
  name: nginx-test
spec:
  selector:
    app.kubernetes.io/name: nginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-test
spec:
  ingressClassName: nginx
  rules:
  - host: example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-test
            port:
              number: 80
  • Service 設定建立一個叫做 nginx-test 的服務,選擇帶有特定標籤的 Pod
  • Ingress 資源指定使用 nginx 作為 Ingress 控制器
  • 設定 example.com 作為虛擬主機,所有請求都會導向到 nginx-test 服務

驗證佈署結果

使用 curl 工具來測試我們的設定:

curl -ik -H 'Host: example.com' http://10.0.0.13

如果一切正常,你會看到類別似這樣的回應:

HTTP/1.1 200 OK
date: Wed, 27 Sep 2023 18:45:20 GMT
content-type: text/plain; charset=utf-8
content-length: 429
...

這個回應包含了大量有用的資訊,包括:

  • 請求是如何被路由的
  • 經過了哪些代理伺服器
  • 使用了什麼協定
  • 客戶端的來源 IP 位址

環境最佳化與擴充套件建議

在建立基礎叢集之後,玄貓建議可以考慮以下幾個重要的擴充套件方向:

  1. 佈署 Helm 套件管理工具,簡化應用程式的安裝與更新流程

  2. 實作 Local Persistence Volume Static Provisioner,為需要持久化儲存的服務提供支援

  3. 建置私有的 Harbor 容器映像檔倉函式庫保映像檔管理的安全性與效能

  4. 整合 cert-manager,實作 TLS 憑證的自動化管理

  5. 使用 keepalived 來強化 Kubernetes API 伺服器的高用性

在實際營運過程中,這些元件對於建構一個穩定與可擴充套件的生產環境至關重要。透過這些年在不同規模企業的佈署經驗,玄貓深刻體會到,一個良好的基礎建設能為後續的應用程式佈署與維運帶來莫大助益。

建立一個生產級的 Kubernetes 叢集需要審慎的規劃與紮實的基礎建設。透過本文的步驟,我們不僅完成了基礎叢集的建置,更為未來的擴充套件奠定了良好的基礎。記住,在雲端架構中,擴充套件性與維護性同樣重要,適當的規劃能讓系統在未來面對更大的挑戰時依然保持彈性與穩定。 總結來說,建立一個穩固與可靠的自我管理 Kubernetes 叢集需要仔細的規劃和設定。透過使用 HAProxy 作為負載平衡器、Keepalived 提供高用性以及適當的網路設定,我們可以開發出一個具備企業級可用性的生產環境叢集。

在實作過程中,玄貓特別強調幾個關鍵要點:首先是確保控制平面的高用性,這對於生產環境來說是不可或缺的;其次是網路設定的重要性,包括正確設定虛擬 IP 和負載平衡;最後是監控和維護機制的建立,以確保叢集的長期穩定運作。

透過這些最佳實踐和技術組合,我們不僅能建立起一個穩定可靠的 Kubernetes 環境,更能為未來的擴充套件和維護奠定良好基礎。這些知識和經驗對於想要自建和管理 Kubernetes 叢集的團隊來說都是非常寶貴的參考。