找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

3075

积分

1

好友

415

主题
发表于 11 小时前 | 查看: 2| 回复: 0

对于希望在隔离网络或受限环境中快速搭建 Kubernetes 测试、开发平台的工程师来说,使用 kubeadm 是一个可靠且标准的选择。本文将手把手带你完成在 Debian 13 (Trixie) 系统上,基于 containerd 运行时,并集成私有 Harbor 镜像仓库的单节点 Kubernetes (v1.33.7) 集群部署。整个过程完全离线,确保在无外网访问的环境下也能顺利构建你的容器编排实验田。

环境和版本信息

基础环境配置

  • 操作系统: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 组件之前,我们必须先为系统打好基础,满足其运行的最低要求。

1. 安装 IPVS 相关工具包

IPVS (IP Virtual Server) 是 Linux 内核内置的负载均衡器,Kubernetes 的 kube-proxy 组件在 IPVS 模式下运行时需要它。

# 仅在 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 地址的映射,确保在无 DNS 服务器时也能正常解析。

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 作为企业级的开源解决方案,能完美胜任这个角色。

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

从下载的压缩包中找到模板文件,复制并修改为我们的配置。

# 复制配置模板
cp harbor.yml.tmpl harbor.yml

# 修改关键配置项

主要配置项如下(以 YAML 格式展示):

# 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 容器运行时配置

作为 Kubernetes 推荐的轻量级运行时,containerd 的配置是部署过程中的关键一步。

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

关键配置修改(在 /etc/containerd/config.toml 中定位并修改):

# 设置 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 组件部署

现在,我们可以安装 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

集群初始化

万事俱备,现在可以初始化我们的 Kubernetes 控制平面了。

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 网络插件部署

接下来,我们将部署基于 eBPF 的现代云原生网络插件——Cilium。它不仅提供网络连通性,还集成了安全策略和可观测性能力。

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 来部署 Cilium,这是一种更灵活、更易于管理的方式。

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

首先,将 Chart 中所有的默认镜像仓库地址替换为我们的 Harbor 地址:

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

然后,修改 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 pullpush 的方式可能导致镜像 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

添加工作节点(扩展部署)

完成单节点集群部署后,如果你想扩展为多节点集群,可以在新的节点上执行以下步骤。这对于理解 kubeadm join 的流程很有帮助。

在新节点上需要先完成前面的系统初始化、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 中设置为非公开(Private)项目的镜像,Kubernetes 在拉取时需要提供认证信息。这里介绍几种配置方式。

方式一: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 全局认证(实验环境适用)

在容器运行时层面配置全局认证,省去了在 Kubernetes 中管理 Secret 的步骤,但安全性较低。

编辑 /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)”

安全提醒:方式三将凭据明文存储在配置文件中,不建议在生产环境中使用。

总结

相较于手动使用二进制文件部署 Kubernetes,kubeadm 极大地简化了流程,特别是证书管理和节点加入环节。本文详细演示了在 Debian 13 离线环境下,从零开始构建一个基于 containerdCilium 的单节点 Kubernetes 集群的全过程,并集成了 Harbor 私有仓库以满足镜像分发需求。

这套方案非常适合用于搭建个人实验环境、企业内部演示或CI/CD测试平台。如果你希望进一步自动化,可以考虑使用如 Ansible 这样的配置管理工具来封装上述步骤,让节点扩容变得更加轻松。关于 Helm 等包管理工具的更多高级用法,你可以在 云栈社区 的云原生板块找到丰富的讨论和资源。




上一篇:AI编程如何构建技术人杠杆系统:从执行到赋能的转型路径
下一篇:红日靶场1内网渗透实战:从phpMyAdmin到域控黄金票据全流程(Win7+DC+Kali)
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-2-3 18:22 , Processed in 0.356554 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表