Skip to content

Kubeadm部署 Kubernetes(v1.27.2)集群

记录并分享最近部署的Kubernetes集群,踩坑记录全部给剔除,并说明不同CRI的方式:docker和containerd 下文不会介绍过多的细节和基础知识,都是生产环境很实用的基本情况,相关命令和解释不会说明。

所谓多节点集群,要求服务器应该有两台或者更多,采用一台是 Control Plane 节点,另两台是 Worker 节点,说明使用 kubeadm 部署 Kubernetes 集群的一些细节和注意点

前期准备(所有节点)

资源规划

主机名IP操作系统
k8s-control-plane-1172.17.40.174CentOS 7.9.2009
k8s-work-1172.17.40.175CentOS 7.9.2009
k8s-work-2172.17.40.176CentOS 7.9.2009

服务器基线配置

设置静态IP

bash
# 修改网卡配置
cat > /etc/sysconfig/network-scripts/ifcfg-eth0 <<EOF
TYPE=Ethernet
BOOTPROTO=static
NAME=eth0
DEVICE=eth0
ONBOOT=yes
IPADDR=172.17.40.174
NETMASK=24
GATEWAY=172.17.40.1
DNS1=114.114.114.114
EOF

# 其他按照如上步骤节点修改IP地址即可

关闭防火墙

bash
sudo systemctl stop firewalld
sudo systemctl disable firewalld
sudo sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
sudo setenforce 0

yum镜像源

bash
sudo yum install -y wget
sudo mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
sudo wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
sudo yum clean all
sudo yum makecache

sudo yum install -y epel-release
sudo yum instanll -y upgrade
sudo yum install -y yum-utils device-mapper-persistent-data lvm2

时间同步

bash
timedatectl set-timezone "Asia/Shanghai"
sudo yum install -y ntpdate
sudo ntpdate -u ntp.aliyun.com

Control Plane 节点需要运行 apiserver、etcd、scheduler、controller-manager 等组件,管理整个集群,所以对配置要求比较高,至少是 2 核 CPU、4GB 的内存。

修改主机名和配置 hosts

bash
# 在172.17.40.174执行
hostnamectl --static set-hostname k8s-control-plane-1 && bash
# 在172.17.40.175执行
hostnamectl --static set-hostname k8s-work-1 && bash
# 在172.17.40.176执行
hostnamectl --static set-hostname k8s-work-2 && bash

# hosts配置
# 转发 IPv4 并让 iptables 看到桥接流量 cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf overlay br_netfilter EOFcat >> /etc/hosts << EOF 
172.17.40.174 k8s-control-plane-1
172.17.40.175 k8s-work-1
172.17.40.176 k8s-work-2
EOF

为了让 Kubernetes 能够检查、转发网络流量,需要修改 iptables 的配置,启用 br_netfilter 模块:

bash
# 转发 IPv4 并让 iptables 看到桥接流量
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF

sudo modprobe overlay
sudo modprobe br_netfilter

# 设置所需的 sysctl 参数,参数在重新启动后保持不变
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables  = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward                 = 1
EOF

# 应用 sysctl 参数而不重新启动
sudo sysctl --system

# 通过运行以下指令确认 br_netfilter 和 overlay 模块被加载:
lsmod | grep br_netfilter
lsmod | grep overlay

# 通过运行以下指令确认 net.bridge.bridge-nf-call-iptables、net.bridge.bridge-nf-call-ip6tables和 net.ipv4.ip_forward系统变量在你的sysctl配置中被设置为 1:
sysctl net.bridge.bridge-nf-call-iptables net.bridge.bridge-nf-call-ip6tables net.ipv4.ip_forward

需要修改 /etc/fstab,关闭 Linux 的 swap 分区,提升 Kubernetes 的性能:

bash
sudo swapoff -a
sudo sed -ri '/\sswap\s/s/^#?/#/' /etc/fstab

容器运行时安装

虽然 Kubernetes 目前支持多种容器运行时,由于从 Kubernetes 1.24.0 以后版本默认使用了 containerd 作为CRI,故把两种部署方式都说明下。

bash
# 卸载docker和containerd
sudo yum remove docker docker-engine docker.io containerd runc

# 重新安装
sudo yum update
sudo yum install ca-certificates curl gnupg lsb-release

sudo mkdir -m 0755 -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo yum update

# 最新稳定版本
sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

使用 docker 作为CRI

bash
cat <<EOF | sudo tee /etc/docker/daemon.json
{
  # "bip": "172.18.97.1/24", 查看内网IP是否和docker默认网段(172.17.0.1/16)有冲突,如有冲突需要单独配置bip替换有冲突的网段,请注意bip是写主机地址而不是网络地址
  "registry-mirrors": ["https://xxxx.mirror.aliyuncs.com"],  # 替换个人阿里云docker镜像源
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2"
}
EOF

sudo systemctl enable docker
sudo systemctl daemon-reload
sudo systemctl restart docker

使用 containerd 作为CRI

bash
# containerd安装如上docker所示
# 配置containerd,修改sandbox_image 镜像源
# 导出默认配置,config.toml这个文件默认是不存在的
containerd config default > /etc/containerd/config.toml

# 修改前检查
grep sandbox_image  /etc/containerd/config.toml

# 修改sandbox_image 镜像源
sed -i "s#registry.k8s.io/pause#registry.aliyuncs.com/google_containers/pause#g" /etc/containerd/config.toml

# 修改后检查
grep sandbox_image  /etc/containerd/config.toml

# 配置containerd cgroup 驱动程序systemd
# 把SystemdCgroup = false修改为:SystemdCgroup = true,
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml

# Containerd配置镜像加速
sudo vim /etc/containerd/config.toml
    [plugins."io.containerd.grpc.v1.cri".registry]
      [plugins."io.containerd.grpc.v1.cri".registry.mirrors]
        [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
          endpoint = ["https://xxxxxxxx.mirror.aliyuncs.com" ,"https://registry-1.docker.io"]

# 重启
systemctl daemon-reload
systemctl enable --now containerd
systemctl restart containerd

确保每个节点上 MAC 地址和 product_uuid 的唯一性 你可以使用命令 ip link 或 ifconfig -a 来获取网络接口的 MAC 地址 可以使用 sudo cat /sys/class/dmi/id/product_uuid 命令对 product_uuid 校验

配置 Kubernetes 软件仓库

bash
sudo yum install -y apt-transport-https ca-certificates curl

sudo curl -fsSLo /etc/apt/keyrings/kubernetes-archive-keyring.gpg https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg

echo "deb [signed-by=/etc/apt/keyrings/kubernetes-archive-keyring.gpg] https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list

sudo yum update

tips

完成之后,最好记得重启一下系统,然后给虚拟机拍个快照做备份,避免后续的操作失误导致重复劳动

Kubernetes 安装

配置软件仓库,就可以用 yum install 获取 kubeadm、kubelet 和 kubectl 这三个安装必备工具了, yum 默认会下载最新版本,但也可以指定版本号,比如指定 1.27.2:

bash
# 安装指定版本
sudo yum install -y kubeadm=1.27.2-00 kubelet=1.27.2-00 kubectl=1.27.2-00

# 安装最新版本
sudo yum install -y kubeadm kubelet kubectl

安装完成之后,你可以用 kubeadm version、kubectl version 来验证版本是否正确:

bash
kubeadm version
kubectl version --client
kubectl version --short

另外按照 Kubernetes 官网的要求,最好再使用命令 apt-mark hold ,锁定这三个软件的版本,避免意外升级导致版本错误:

bash
sudo apt-mark hold kubeadm kubelet kubectl

kubeadm 把 apiserver、etcd、scheduler 等组件都打包成了镜像,以容器的方式启动 Kubernetes,但这些镜像不是放在 Docker Hub 上,而是放在 Google 自己的镜像仓库网站 registry.k8s.io,而它在国内的访问很困难,直接拉取镜像几乎是不可能的。

bash
# 查看 Kubernetes 初始化所需镜像
kubeadm config images list --kubernetes-version v1.27.2
registry.k8s.io/kube-apiserver:v1.27.2
registry.k8s.io/kube-controller-manager:v1.27.2
registry.k8s.io/kube-scheduler:v1.27.2
registry.k8s.io/kube-proxy:v1.27.2
registry.k8s.io/pause:3.9
registry.k8s.io/etcd:3.5.6-0
registry.k8s.io/coredns/coredns:v1.9.3

# 查看国内阿里云镜像
kubeadm config images list --kubernetes-version v1.27.2 --image-repository registry.aliyuncs.com/google_containers
registry.aliyuncs.com/google_containers/kube-apiserver:v1.27.2
registry.aliyuncs.com/google_containers/kube-controller-manager:v1.27.2
registry.aliyuncs.com/google_containers/kube-scheduler:v1.27.2
registry.aliyuncs.com/google_containers/kube-proxy:v1.27.2
registry.aliyuncs.com/google_containers/pause:3.9
registry.aliyuncs.com/google_containers/etcd:3.5.6-0
registry.aliyuncs.com/google_containers/coredns:v1.9.3

Kubernetes 控制平面节点初始化

kubeadm 的用法非常简单,只需要一个命令 kubeadm init 就可以把组件在 Control Plane 节点上运行起来,不过它还有很多参数用来调整集群的配置,你可以用 -h 查看。这里说下几个重点参数:

  • --pod-network-cidr,设置集群里 Pod 的 IP 地址段。
  • --service-cidr,设置集群里 Service 的 IP 地址段。默认:10.96.0.0/12
  • --apiserver-advertise-address,设置 apiserver 的 IP 地址,对于多网卡服务器来说很重要(比如 VirtualBox 虚拟机就用了两块网卡),可以指定 apiserver 在哪个网卡上对外提供服务。
  • --kubernetes-version,指定 Kubernetes 的版本号。

下面的这个安装命令里,我指定了 Pod 的地址段是 10.10.0.0/16,apiserver 的服务地址是 172.17.40.174,Kubernetes 的版本号是 1.26.3:

bash
sudo kubeadm init \
 --apiserver-advertise-address=172.17.40.174 \
 --image-repository registry.aliyuncs.com/google_containers \
 --kubernetes-version v1.27.2 \
 --service-cidr=10.11.0.0/16 \
 --pod-network-cidr=10.10.0.0/16 \
 --v=5

说明

  • --cri-socket=unix:///var/run/cri-dockerd.sock 如果使用 containerd 作为CRI,就不需要加上该参数

  • 如果使用 docker 作为CRI就需要加上 --cri-socket 参数,同时还必须提前安装 cri-dockerd 后,再初始化一个 Kubernetes 控制平面节点

  • --image-repository 加上国内阿里云镜像仓库会快很多,不然默认使用谷歌的,会很慢,一直在init阶段,初始化不成功

安装CRI

使用 docker 作为CRI

bash
# 安装cri-dockerd
wget https://github.com/Mirantis/cri-dockerd/releases/download/v0.3.1/cri-dockerd_0.3.1.3-0.centos-jammy_amd64.rpm

# unix:///var/run/cri-dockerd.sock
# systemd的服务地址 /lib/systemd/system/cri-dockerd.service
sudo rpm -ivh cri-dockerd_0.3.1.3-0.centos-jammy_amd64.rpm

# 修改镜像地址为国内,否则kubelet拉取不了镜像导致启动失败
# 重载沙箱(pause)镜像 可执行命令 kubeadm config images list 查看国内阿里云最新沙箱镜像
sudo vim /lib/systemd/system/cri-docker.service
ExecStart=/usr/bin/cri-dockerd --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.9 --container-runtime-endpoint fd://

sudo systemctl daemon-reload
sudo systemctl enable cri-docker.service
sudo systemctl enable --now cri-docker.socket

使用 containerd 作为CRI

bash
# 安装必要工具
yum install -y yum-utils device-mapper-persistent-data lvm2

# 添加docker仓库
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

# 安装containerd
yum install -y containerd.io

# 生成默认配置
mkdir -p /etc/containerd
containerd config default > /etc/containerd/config.toml

# 修改配置
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml
sed -i 's#registry.k8s.io/pause#registry.aliyuncs.com/google_containers/pause#g' /etc/containerd/config.toml

# 配置镜像加速
sed -i '/\[plugins."io.containerd.grpc.v1.cri".registry.mirrors\]/a\        [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]\n          endpoint = ["https://xxxx.mirror.aliyuncs.com"]' /etc/containerd/config.toml

# 启动服务
systemctl daemon-reload
systemctl enable --now containerd

初始化完成后,终端界面有一个很重要的 kubeadm join 提示,其他 Worker 节点要加入集群必须要用指令里的 token 和 ca 证书,所以这条命令务必拷贝后保存好:

说明:token默认24小时有效期,失效后需要重新生成token

bash
# 获取目前已有的token,如果没用,说明所有的token都失效了
kubeadm token list

# 默认情况下,令牌会在 24 小时后过期。如果要在当前令牌过期后将节点加入集群, 则可以通过在控制平面节点上运行以下命令来创建新令牌:
kubeadm token create --print-join-command

# 可生成永久token,不建议这样做
kubeadm token create --ttl 0 --print-join-command

一般初始化完成后,终端界面有一个很重要的 kubeadm join 提示,搭建集群都会默认使用初始化生成的token,除非是后期扩容,导致token过期,需要生成新的token,加入 Worker 节点。

bash
# Worker节点加入集群
sudo kubeadm join 172.17.40.174:6443 --token vgkyyv.y68eh3sefdw1fkds --discovery-token-ca-cert-hash sha256:0bb49a0d5d0415ed92b8ecd1103832e4874e49737203929fc94049b5eb998641 --cri-socket=unix:///var/run/cri-dockerd.sock

说明

如果使用 docker 作为CRI时,其他节点加入集群需要添加 --cri-socket 参数

如果是高可用控制平面节点集群,也就是指控制节点有多个,比如etcd堆叠模式的3控制节点和5个工作节点

首先需要把apiserver做负载均衡,也就是其他三个控制平面节点的IP或DNS和端口,负载均衡有多种推荐,可使用 nginx + keepliaved,或者keepalived + haproxy。然后有个负载均衡器对外的VIP或者DNS,如:cluster-endpoint。关于负载均衡器选择直接查看:

软件负载平衡选项指南

bash
# 多控制节点初始化必须添加 control-plane-endpoint 参数
# 当 kubeadm init 时,加入--upload-certs,主控制平面的证书被加密并上传到 kubeadm-certs Secret 中,kubeadm-certs Secret 和解密密钥会在两个小时后失效。
sudo kubeadm init \
 --apiserver-advertise-address=172.17.40.174 \
 --image-repository registry.aliyuncs.com/google_containers \
 --control-plane-endpoint=cluster-endpoint \
 --kubernetes-version v1.27.2 \
 --service-cidr=10.11.0.0/16 \
 --pod-network-cidr=10.10.0.0/16 \
 --upload-certs \
 --v=5

说明

  • --control-plane-endpoint=cluster-endpoint

  • cluster-endpoint 是映射到该 IP 的自定义 DNS 名称,如果单节点控制平台,后续计划升级多节点控制平台可提前配置hosts映射:172.17.40.170 cluster-endpoint。这将允许你将-–control-plane-endpoint=cluster-endpoint 传递给 kubeadm init,并将相同的 DNS 名称传递给 kubeadm join。后续你可以修改 cluster-endpoint 以指向高可用性方案中的负载均衡器的地址。

bash
# 控制节点加入集群
sudo kubeadm join 172.17.40.174:6443 --token vgkyyv.y68eh3sefdw1fkds --discovery-token-ca-cert-hash sha256:0bb49a0d5d0415ed92b8ecd1103832e4874e49737203929fc94049b5eb998641 --control-plane --certificate-key f8902e114ef118304e561c3ecd4d0b543adc226b7a07f675f56564185ffe0c07

多控制平面节点初始化集群需要添加,--control-plane-endpoint(必须) 和 --upload-certs(建议),如果没有添加 --upload-certs,可手动复制证书到其他需要添加入集群的控制平台节点。

因为要使用kubectl命令行管理工具,而要使得kubectl可以管理集群,还需要认证文件拷贝到当前用户目录下,kubectl使用kubeconfig认证文件连接K8s集群。

bash
# 配置文件方式 当前用户
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

# 环境变量方式 临时生效(退出当前窗口重连环境变量失效)
export KUBECONFIG=/etc/kubernetes/admin.conf
# 环境变量方式 永久生效(推荐)
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile
source  ~/.bash_profile

安装完成后,你就可以使用 kubectl version、kubectl get node 来检查 Kubernetes 的版本和集群的节点状态了:

bash
kubectl get nodes
kubectl get pods -A
kubectl cluster-info

插件安装

网络插件部署(Calico)

Control Plane 节点的状态是 NotReady,这是由于还缺少网络插件,集群的内部网络还没有正常运作。

bash
# 下载Calico清单文件
curl https://raw.githubusercontent.com/projectcalico/calico/v3.26.4/manifests/calico.yaml -O

# 修改Pod CIDR配置
sed -i 's/192.168.0.0/10.10.0.0/g' calico.yaml

# 部署Calico
kubectl apply -f calico.yaml

# 验证部署
kubectl get pods -n kube-system -l k8s-app=calico-node

CoreDNS 部署

bash
# 下载CoreDNS清单(兼容v1.27)
wget https://github.com/coredns/deployment/blob/master/kubernetes/coredns.yaml.sed -O coredns.yaml

# 修改配置(替换原始镜像)
sed -i 's/k8s.gcr.io\/coredns/registry.aliyuncs.com\/google_containers\/coredns/g' coredns.yaml
sed -i 's/1.10.1/1.9.3/g' coredns.yaml  # 确认使用兼容版本

# 应用配置
kubectl apply -f coredns.yaml

# 验证状态
kubectl get pods -n kube-system -l k8s-app=kube-dns

MetalLB安装(裸机负载均衡)

网络拓扑建议

组件推荐配置注意事项
MetalLB模式Layer2(测试环境)单点故障风险
BGP(生产环境)需要网络设备支持
IP地址池预留专用IP段避免与现有网络冲突
防火墙开放7472/TCP/UDP(BGP)Layer2模式需允许ARP/NDP
bash
# 安装MetalLB v0.13.7(兼容K8s 1.27)
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.7/config/manifests/metallb-native.yaml

# 等待控制器就绪
kubectl wait --namespace metallb-system \
  --for=condition=ready pod \
  --selector=app=metallb \
  --timeout=120s

# 创建IP地址池配置(根据实际网络环境修改)
cat <<EOF | kubectl apply -f -
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: production-public-ips
  namespace: metallb-system
spec:
  addresses:
  - 192.168.1.240-192.168.1.250  # 替换为实际网络环境中的可用IP段
  autoAssign: true
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: l2-advert
  namespace: metallb-system
spec:
  ipAddressPools:
  - production-public-ips
EOF

# 验证安装
kubectl get pods -n metallb-system
kubectl get ipaddresspools.metallb.io -n metallb-system
高级配置(BGP模式示例)
bash
# 创建BGP对等配置(需网络设备支持)
cat <<EOF | kubectl apply -f -
apiVersion: metallb.io/v1beta2
kind: BGPPeer
metadata:
  name: bgp-peer
  namespace: metallb-system
spec:
  myASN: 64500
  peerASN: 64501
  peerAddress: 192.168.1.1
  peerPort: 179
---
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: bgp-pool
  namespace: metallb-system
spec:
  addresses:
  - 192.168.2.0/24
---
apiVersion: metallb.io/v1beta1
kind: BGPAdvertisement
metadata:
  name: bgp-advert
  namespace: metallb-system
spec:
  ipAddressPools:
  - bgp-pool
  communities:
  - 64500:100
EOF

Ingress Nginx 部署

bash
# 下载官方清单(v1.8.1版本)
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/cloud/deploy.yaml -O ingress-nginx.yaml

# 修改配置
sed -i 's/k8s.gcr.io\/ingress-nginx/registry.cn-hangzhou.aliyuncs.com\/google_containers/g' ingress-nginx.yaml
sed -i 's/registry.k8s.io\/ingress-nginx/registry.cn-hangzhou.aliyuncs.com\/google_containers/g' ingress-nginx.yaml

# 调整服务类型
sed -i '/type: LoadBalancer/c\  type: NodePort' ingress-nginx.yaml

# 部署Ingress
kubectl apply -f ingress-nginx.yaml

# 验证安装
kubectl get pods -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx

Metrics Server 部署

bash
# 下载官方清单(v0.6.3版本)
wget https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.6.3/components.yaml -O metrics-server.yaml

# 修改配置
sed -i 's/k8s.gcr.io\/metrics-server/registry.aliyuncs.com\/google_containers/g' metrics-server.yaml
sed -i '/- --metric-resolution=15s/a\        - --kubelet-insecure-tls' metrics-server.yaml

# 部署Metrics Server
kubectl apply -f metrics-server.yaml

# 验证运行(等待2分钟)
kubectl top nodes

集群验证

基本状态检查

bash
kubectl get nodes
kubectl get pods -A
kubectl cluster-info

网络连通性测试

bash
kubectl create deployment nginx --image=nginx
kubectl expose deployment nginx --port=80

kubectl run test --image=busybox --rm -it -- \
  sh -c "wget -qO- http://nginx.default.svc.cluster.local"

CoreDNS功能测试

bash
# 创建测试Pod
kubectl run -it --rm dns-test --image=busybox:1.28 --restart=Never -- sh

# 在Pod内执行
nslookup kubernetes.default
ping coredns.kube-system.svc.cluster.local

MetalLB功能验证

bash
# 创建测试服务
kubectl create deployment nginx-lb --image=nginx
kubectl expose deployment nginx-lb --port=80 --type=LoadBalancer

# 查看分配的外部IP
kubectl get svc nginx-lb -w

# 访问测试(使用分配的EXTERNAL-IP)
curl http://<EXTERNAL-IP>

Ingress功能验证

bash
### Ingress功能验证(使用MetalLB)
```bash
# 创建测试应用
kubectl create deployment demo-app --image=nginx
kubectl expose deployment demo-app --port 80

# 创建Ingress规则
cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: demo-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
  - host: example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: demo-app
            port:
              number: 80
EOF

# 获取LoadBalancer外部IP(等待1-2分钟IP分配)
INGRESS_IP=$(kubectl get svc -n ingress-nginx ingress-nginx-controller -o jsonpath='{.status.loadBalancer.ingress[0].ip}')

# 访问测试(使用MetalLB分配的IP)
curl -v -H "Host: example.com" http://$INGRESS_IP

# 查看Ingress状态
kubectl get ingress
kubectl describe ingress demo-ingress

Metrics Server压力测试

bash
# 创建负载生成器
kubectl run load-generator --image=busybox -- /bin/sh -c "while true; do wget -q -O- http://demo-app; done"

# 监控资源使用
watch -n 2 kubectl top pods

故障排查

CoreDNS排查

bash
# 检查DNS解析
kubectl get svc kube-dns -n kube-system
kubectl logs -n kube-system <coredns-pod> -c coredns

# 验证网络策略
kubectl exec dns-test -- nslookup kubernetes.default

MetalLB排查

bash
# 查看MetalLB分配日志
kubectl logs -n metallb-system -l app=metallb --controller

# 检查IP分配状态
kubectl get svc -n ingress-nginx ingress-nginx-controller -o wide

# 验证网络连通性
curl -v --resolve example.com:80:$INGRESS_IP http://example.com

# 查看Nginx访问日志
kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx --tail=50

# 检查MetalLB事件
kubectl get events -n metallb-system --sort-by=.metadata.creationTimestamp

# 验证IP地址分配
kubectl describe service -n ingress-nginx ingress-nginx-controller

# 检查网络策略
kubectl get networkpolicies -A
kubectl describe networkpolicy -n ingress-nginx <policy-name>

Ingress排查

bash
# 检查控制器日志
kubectl logs -n ingress-nginx <ingress-pod>

# 验证Endpoints
kubectl get ingress
kubectl describe ingress demo-ingress

Metrics Server排查

bash
# 检查证书配置
kubectl logs -n kube-system <metrics-server-pod>

# 验证API访问
kubectl get --raw "/apis/metrics.k8s.io/v1beta1/nodes"

到此就完成一套基于 kubeadm 部署Kubenetes多节点集群

本文作者:许怀安
创作时间:2024.03.01
版权声明:本博客所有文章除特别声明外,均采用BY-NC-SA许可协议。转载请禀明出处!

许怀安 | MIT License