博客 / 詳情

返回

Debian 13基於kubeadm和containerd部署單節點kubernetes

前言

在本地虛擬機環境中使用 kubeadm 搭建 Kubernetes 集羣是學習和實驗的理想選擇。考慮到實際應用場景中可能存在的網絡限制以及鏡像構建需求,本文詳細記錄了在完全離線環境下部署單節點 Kubernetes 集羣的完整過程。通過集成 Harbor 私有鏡像倉庫,所有 Kubernetes 組件鏡像均從本地 Harbor 實例拉取,確保部署過程的可靠性和可重複性。

本指南適用於希望在受限網絡環境中快速搭建 Kubernetes 實驗環境的技術人員,涵蓋了從系統初始化到 Cilium 網絡插件配置的全流程。

環境和版本信息

基礎環境配置

  • 操作系統:Debian 13 (代號 "Trixie")
  • 硬件規格:4 核 CPU / 4GB 內存 / 40GB 存儲空間
  • 網絡拓撲:單節點部署(Control Plane + Worker 合一)

軟件版本清單

組件 版本 説明
Kubernetes v1.33.7 容器編排平台
containerd 2.2.1 容器運行時
runc 1.4.0 OCI 運行時規範實現
CNI Plugins 1.9.0 容器網絡接口插件
Harbor v2.14.2 企業級容器鏡像倉庫
Cilium v1.18.6 eBPF 驅動的網絡和安全解決方案
Helm 3.19.5 Kubernetes 包管理器

網絡規劃

IP 地址 主機名 角色
192.168.0.22 deb13-k8s-node1 Kubernetes 節點
192.168.0.42 deb13-harbor Harbor 鏡像倉庫

注意:本文檔假設兩台主機位於同一內網環境中,且網絡連通性已驗證。

系統初始化

在開始 Kubernetes 組件安裝之前,需要對系統進行必要的初始化配置,以滿足 Kubernetes 的運行要求。

1. 安裝 IPVS 相關工具包

IPVS(IP Virtual Server)是 Linux 內核的負載均衡實現,Kubernetes 在 IPVS 模式下運行 kube-proxy 時需要相關工具支持。

# 僅在 Kubernetes 節點執行
sudo apt update
sudo apt install -y ipvsadm ipset

2. 配置主機名

為便於管理和識別,建議為每台主機設置有意義的主機名。

# Harbor 服務器
hostnamectl set-hostname deb13-harbor

# Kubernetes 節點
hostnamectl set-hostname deb13-k8s-node1

3. 配置本地 DNS 解析

編輯 /etc/hosts 文件,添加主機名與 IP 地址的映射關係:

cat >> /etc/hosts << EOF
192.168.0.22 deb13-k8s-node1
192.168.0.42 deb13-harbor
EOF

4. 加載必要的內核模塊

Kubernetes 依賴特定的內核模塊來支持容器網絡功能。創建模塊加載配置並立即生效:

# 創建模塊加載配置文件
cat << EOF > /etc/modules-load.d/containerd.conf
overlay
br_netfilter
EOF

# 立即加載模塊
sudo modprobe overlay
sudo modprobe br_netfilter

# 驗證模塊加載狀態
lsmod | grep -E "(overlay|br_netfilter)"

5. 配置系統內核參數

調整內核參數以優化容器運行環境:

cat > /etc/sysctl.d/k8s.conf << EOF
net.ipv4.ip_forward=1
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
vm.swappiness = 0
EOF

# 應用配置
sudo sysctl --system

重要提示:如果系統啓用了 swap 分區,必須在 Kubernetes 啓動前將其關閉,否則 kubelet 將無法正常啓動。可通過以下命令臨時關閉:

sudo swapoff -a
# 永久關閉需註釋 /etc/fstab 中的 swap 相關行

Harbor 私有鏡像倉庫部署

Harbor 作為企業級容器鏡像倉庫,為離線環境下的 Kubernetes 部署提供了可靠的鏡像分發能力。

1. 準備 Harbor 安裝包

從 Harbor GitHub Releases 頁面下載離線安裝包(約 600MB)。安裝 Harbor 前需確保 Docker 和 Docker Compose 已正確安裝。

2. 生成自簽名 TLS 證書

由於 Harbor 強制要求 HTTPS 連接,我們需要為 Harbor 服務器生成自簽名證書。創建證書生成腳本:

# 創建證書目錄
mkdir -p ~/apps/harbor/certs
cd ~/apps/harbor/certs

# 創建證書生成腳本
cat > gen-harbor-crt.sh << 'EOF'
#!/bin/bash

# --- 配置參數 ---
DOMAIN="deb13-harbor"       # Harbor 域名
IP="192.168.0.42"           # Harbor 服務器內網 IP
DAYS=3650                   # 有效期 10 年

# 1. 生成私鑰 (無密碼)
openssl genrsa -out harbor.key 2048

# 2. 創建 OpenSSL 配置文件以包含 SAN
cat > harbor.conf << CONF_EOF
[req]
distinguished_name = req_distinguished_name
x509_extensions = v3_req
prompt = no

[req_distinguished_name]
CN = ${DOMAIN}

[v3_req]
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names

[alt_names]
DNS.1 = ${DOMAIN}
IP.1 = ${IP}
CONF_EOF

# 3. 生成自簽名證書
openssl req -x509 -nodes -days ${DAYS} -key harbor.key -out harbor.crt -config harbor.conf -extensions v3_req

# 4. 驗證證書(查看是否有 Subject Alternative Name 字段)
echo "--------------------------------------------------"
echo "證書信息驗證:"
openssl x509 -in harbor.crt -text -noout | grep -A 1 "Subject Alternative Name"

echo "--------------------------------------------------"
echo "生成成功!"
echo "服務端使用: harbor.crt, harbor.key"
echo "客户端 (K8s 節點) 使用: harbor.crt"
EOF

# 執行證書生成
chmod +x gen-harbor-crt.sh
./gen-harbor-crt.sh

3. 配置 Harbor

從模板文件複製並修改 Harbor 配置:

# 複製配置模板
cp harbor.yml.tmpl harbor.yml

# 修改關鍵配置項

主要配置項如下:

# Harbor 訪問地址
hostname: 192.168.0.42

# HTTPS 配置
https:
  port: 443
  certificate: /home/rainux/apps/harbor/certs/harbor.crt
  private_key: /home/rainux/apps/harbor/certs/harbor.key

# 管理員密碼(請設置強密碼)
harbor_admin_password: your-harbor-password

# 數據庫密碼
database:
  password: your-db-password

# 數據存儲路徑
data_volume: /home/rainux/apps/harbor/data

# 日誌配置
log:
  location: /home/rainux/apps/harbor/logs

# 啓用指標監控
metric:
  enabled: true
  port: 9090
  path: /metrics

4. 啓動 Harbor 服務

cd ~/apps/harbor
sudo ./install.sh

5. 初始化 Harbor 項目

通過 Web 界面訪問 Harbor(https://192.168.0.42),使用配置的管理員密碼登錄後,創建以下兩個公開項目:

  • google_containers:用於存儲 Kubernetes 核心組件鏡像
  • cilium:用於存儲 Cilium 網絡插件相關鏡像

配置更新説明:如需修改 Harbor 配置,可執行以下命令使配置生效:

sudo ./prepare
docker-compose down -v
sudo docker-compose up -d

Containerd 容器運行時配置

Containerd 作為輕量級容器運行時,是 Kubernetes 推薦的運行時選項之一。

1. 下載必要組件

從官方 GitHub 倉庫下載以下組件:

  • containerd
  • runc
  • CNI Plugins

2. 安裝 runc

# 注意:原文中的文件名可能存在筆誤,應為 runc.amd64
chmod +x runc.amd64
sudo mv runc.amd64 /usr/local/bin/runc

3. 安裝 CNI 插件

sudo mkdir -p /opt/cni/bin/
sudo tar xf cni-plugins-linux-amd64-v1.9.0.tgz -C /opt/cni/bin/

4. 安裝 containerd

sudo tar xf containerd-2.2.1-linux-amd64.tar.gz
sudo mv bin/* /usr/local/bin/

5. 配置 containerd

生成默認配置並進行必要的修改:

# 創建 Harbor 證書目錄
sudo mkdir -p /etc/containerd/certs.d/192.168.0.42/

# 生成默認配置
sudo containerd config default > /etc/containerd/config.toml

# 複製 Harbor 證書
sudo cp ~/apps/harbor/certs/harbor.crt /etc/containerd/certs.d/192.168.0.42/ca.crt

關鍵配置修改:

# 設置 Pod 沙箱鏡像源
[plugins.'io.containerd.cri.v1.images'.pinned_images]
  sandbox = '192.168.0.42/google_containers/pause:3.10'

# 配置私有鏡像倉庫
[plugins.'io.containerd.cri.v1.images'.registry]
  config_path = '/etc/containerd/certs.d'

# 啓用 systemd cgroup 驅動
[plugins.'io.containerd.cri.v1.runtime'.containerd.runtimes.runc.options]
  SystemdCgroup = true

6. 配置 systemd 服務

從 官方倉庫 獲取 service 文件:

sudo curl -o /usr/lib/systemd/system/containerd.service https://raw.githubusercontent.com/containerd/containerd/main/containerd.service

7. 啓動 containerd 服務

sudo systemctl daemon-reload
sudo systemctl enable --now containerd

Kubernetes 組件部署

1. 安裝 Kubernetes 二進制文件

從 Kubernetes GitHub Releases 下載 kubernetes-server-linux-amd64.tar.gz,提取核心組件:

# 解壓並安裝核心組件
tar xf kubernetes-server-linux-amd64.tar.gz
sudo cp kubernetes/server/bin/{kubeadm,kubelet,kubectl} /usr/local/bin/

# 驗證所需鏡像列表
kubeadm config images list --kubernetes-version v1.33.7

將列出的所有鏡像(包括 pause、coredns、etcd 等)從官方源拉取後重新打標籤並推送到 Harbor 的 google_containers 項目中。

2. 配置 kubelet systemd 服務

創建主服務文件 /usr/lib/systemd/system/kubelet.service

[Unit]
Description=kubelet: The Kubernetes Node Agent
Documentation=https://kubernetes.io/docs/
Wants=network-online.target
After=network-online.target

[Service]
ExecStart=/usr/local/bin/kubelet
Restart=always
StartLimitInterval=0
RestartSec=10

[Install]
WantedBy=multi-user.target

3. 創建 kubeadm 配置目錄

sudo mkdir -p /usr/lib/systemd/system/kubelet.service.d/

4. 配置 kubeadm drop-in 文件

創建 /usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf

# Note: This dropin only works with kubeadm and kubelet v1.11+
[Service]
Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf"
Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml"
# This is a file that "kubeadm init" and "kubeadm join" generates at runtime, populating the KUBELET_KUBEADM_ARGS variable dynamically
EnvironmentFile=-/var/lib/kubelet/kubeadm-flags.env
# This is a file that the user can use for overrides of the kubelet args as a last resort. Preferably, the user should use
# the .NodeRegistration.KubeletExtraArgs object in the configuration files instead. KUBELET_EXTRA_ARGS should be sourced from this file.
EnvironmentFile=-/etc/sysconfig/kubelet
ExecStart=
ExecStart=/usr/local/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS

5. 啓動 kubelet 服務

sudo systemctl daemon-reload
sudo systemctl enable --now kubelet

集羣初始化

1. 創建 kubeadm 配置文件

創建 kubeadm-config.yaml 配置文件:

apiVersion: kubeadm.k8s.io/v1beta4
kind: ClusterConfiguration
kubernetesVersion: v1.33.7
imageRepository: 192.168.0.42/google_containers  # 指向本地 Harbor 倉庫
networking:
  podSubnet: "10.10.0.0/16"   # Cilium 默認 Pod 網段
  serviceSubnet: "10.96.0.0/12"
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cgroupDriver: systemd
imageGCHighThresholdPercent: 70   # 磁盤使用率超過 70% 時開始清理鏡像
imageGCLowThresholdPercent: 60    # 清理至磁盤使用率 60% 時停止
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "ipvs"  # 雖然後續會使用 Cilium 替代 kube-proxy,但初始化階段仍需配置

2. 執行集羣初始化

sudo kubeadm init --config kubeadm-config.yaml --ignore-preflight-errors=ImagePull

3. 清理 kube-proxy(使用 Cilium 替代)

由於我們將使用 Cilium 作為網絡解決方案,可以移除 kube-proxy:

# 刪除 kube-proxy DaemonSet
kubectl delete ds kube-proxy -n kube-system

# 在所有節點清理 iptables 規則殘留
sudo kube-proxy --cleanup

4. 驗證初始化狀態

初始化完成後,配置 kubectl 並檢查集羣狀態:

# 配置 kubectl
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

# 檢查節點狀態(此時應顯示 NotReady,因為 CNI 尚未安裝)
kubectl get nodes
kubectl get namespaces

Cilium 網絡插件部署

Cilium 基於 eBPF 技術提供高性能的網絡、安全和可觀測性功能。

1. 安裝 cilium-cli

從 Cilium CLI Releases 下載並安裝命令行工具。

2. 準備 Cilium 鏡像

將 Cilium 所需的鏡像推送到 Harbor 倉庫:

#!/bin/bash

set -euo pipefail

images=(
    cilium/cilium:v1.18.6
    cilium/hubble-relay:v1.18.6
    cilium/hubble-ui-backend:v0.13.3
    cilium/hubble-ui:v0.13.3
    cilium/cilium-envoy:v1.35.9-1767794330-db497dd19e346b39d81d7b5c0dedf6c812bcc5c9
    cilium/certgen:v0.3.1
    cilium/startup-script:1755531540-60ee83e
)

src_registry="quay.io"
target_registry="192.168.0.42"

for image in "${images[@]}"; do
    echo "Processing image: ${image}"
    docker pull "${src_registry}/${image}"
    docker tag "${src_registry}/${image}" "${target_registry}/${image}"
    docker push "${target_registry}/${image}"
done

3. 獲取 Helm Chart

helm repo add cilium https://helm.cilium.io/
helm pull cilium/cilium --version 1.18.6
tar xf cilium-1.18.6.tgz
mv cilium cilium-chart

4. 配置 Chart Values

首先替換所有鏡像源地址:

sed -i 's#quay.io#192.168.0.42#g' ./cilium-chart/values.yaml

關鍵配置項調整:

# 啓用 kube-proxy 替代模式
kubeProxyReplacement: true

# 指定 Kubernetes API 服務器地址
k8sServiceHost: "192.168.0.22"
k8sServicePort: 6443

# 單節點部署,operator 副本數設為 1
operator:
  replicas: 1

# 啓用 Hubble 可觀測性組件
hubble:
  enabled: true
  relay:
    enabled: true
  ui:
    enabled: true

# 配置 IPAM CIDR 範圍
ipam:
  operator:
    clusterPoolIPv4PodCIDRList:
      - "10.10.0.0/16"

鏡像 Digest 注意事項:通過 docker pull 再 push 的方式可能導致鏡像 digest 發生變化。如遇鏡像拉取失敗,可將 values.yaml 中的 useDigest 設置為 false

5. 安裝 Cilium

# 執行安裝
cilium install --chart-directory ./cilium-chart

# 檢查安裝狀態
cilium status

# 移除 control-plane 污點以允許 Pod 調度
kubectl taint nodes --all node-role.kubernetes.io/control-plane-

6. 驗證集羣狀態

等待所有 Pod 正常運行後,驗證集羣就緒狀態:

# 檢查所有命名空間的 Pod 狀態
kubectl get pods -A

# 驗證節點狀態(應顯示 Ready)
kubectl get nodes

# 檢查 Cilium 組件狀態
cilium status --verbose

添加工作節點(擴展部署)

完成單節點集羣部署後,如需擴展為多節點集羣,可在新節點上執行以下步驟:

在新節點上需要先完成上面的系統初始化、Containerd配置、kube組件配置

1. 生成節點加入令牌

在 Control Plane 節點上生成 24 小時有效的加入令牌:

kubeadm token create --print-join-command

該命令將輸出類似以下格式的加入命令:

kubeadm join 192.168.0.22:6443 --token <token> --discovery-token-ca-cert-hash sha256:<hash>

2. 在新節點執行加入命令

在新節點上執行上述命令,並忽略鏡像預檢錯誤:

sudo kubeadm join 192.168.0.22:6443 \
  --token <token> \
  --discovery-token-ca-cert-hash sha256:<hash> \
  --ignore-preflight-errors=ImagePull

3. 驗證節點加入狀態

# 檢查節點列表
kubectl get nodes

# 驗證 Cilium 狀態
cilium status

# 清理 iptables 規則(如已禁用 kube-proxy)
sudo iptables -F

Cilium 會自動在新節點上部署代理 Pod,確保網絡連通性。

私有鏡像倉庫認證配置

對於 Harbor 中非公開項目的鏡像拉取,需要配置相應的認證機制。

方式一:Pod 級別 imagePullSecrets(推薦)

適用於需要精細化控制鏡像拉取權限的場景。

1. 創建 Docker Registry Secret

kubectl create secret docker-registry harbor-pull-secret \
  --docker-server=192.168.0.42 \
  --docker-username=<your-username> \
  --docker-password=<your-password> \
  --docker-email=<your-email>

2. 在 Pod 定義中引用 Secret

apiVersion: v1
kind: Pod
spec:
  containers:
  - name: my-app
    image: 192.168.0.42/private-project/my-image:v1
  imagePullSecrets:
  - name: harbor-pull-secret

方式二:ServiceAccount 綁定(便捷方案)

適用於命名空間內所有 Pod 都需要訪問私有鏡像倉庫的場景。

# 將 Secret 綁定到 default ServiceAccount
kubectl patch serviceaccount default -p '{"imagePullSecrets": [{"name": "harbor-pull-secret"}]}'

此配置將使該命名空間下所有新建的 Pod 自動繼承鏡像拉取權限。

方式三:Containerd 全局認證(實驗環境適用)

在 Containerd 層面配置全局認證,適用於個人實驗環境。

編輯 /etc/containerd/config.toml

[plugins."io.containerd.grpc.v1.cri".registry.configs."192.168.0.42".auth]
  username = "your-username"
  password = "your-password"
  # 或使用 base64 編碼的憑證:auth = "base64(username:password)"

安全提醒:方式三將憑據明文存儲在配置文件中,不建議在生產環境中使用。

補充

相較於使用二進制方式部署,用kubeadm起碼省去了手動維護證書的操作,後續添加節點也更簡單些。有空整個ansible讓添加節點更方便。

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.