k8s1.35.1二进制部署

k8s1.35.1二进制部署

2026年2月11日,Kubernetes发布了最新v1.35.1版本。截至2月11日,本实验相关软件etcd、docker、cri-dockerd、nginx、kubectl-ai及清单文件calico、coredns、metrics server均采用最新发布版本。集群部署中,发现了个别配置参数过期在本次版本中不能再使用而需要调整,新版k8s体系在部署方面仍维持了高度的稳定性和一到性。本方案结合企业环境部署及运行的经验进行总结,得以整理形成保姆级的部署方案。另外,也得到了多位同学提供的宝贵资源和思路支持,比之前的部署经验及方案更加成熟可靠,可解释性更强,为k8s1.35.x版本部署提供参考。此外,本次也安装了kubectl-ai,引入LLM进行试验。kubectl-ai作为在终端中运行的AI驱动的Kubernetes助手,将自然语言的便捷性与kubectl的强大功能相结合,彻底改变管理和维护 Kubernetes 集群的方式。

(1)主要开源软件及版本

1、主机清单

  • 网络配置
sh 复制代码
vi /etc/NetworkManager/system-connections/ens32.nmconnection
#以下是要修改[ipv4]的内容,IP地址为:192.168.26.49-51
[ipv4]			
method=manual
address1=192.168.26.49/24,192.168.26.2	#192.168.26.2是网关IP,在vmware→编辑→虚拟网络编辑器(N)→NAT设置中查看
dns=8.8.8.8,114.114.114.114
  • 主机名与hosts本地解析
sh 复制代码
## 查看系统版本及内核版本
[root@alma ~]# cat /etc/os-release
NAME="AlmaLinux"
VERSION="10.0 (Purple Lion)"
ID="almalinux"
ID_LIKE="rhel centos fedora"
VERSION_ID="10.0"
PLATFORM_ID="platform:el10"
PRETTY_NAME="AlmaLinux 10.0 (Purple Lion)"
ANSI_COLOR="0;34"
LOGO="fedora-logo-icon"
CPE_NAME="cpe:/o:almalinux:almalinux:10::baseos"
HOME_URL="https://almalinux.org/"
DOCUMENTATION_URL="https://wiki.almalinux.org/"
VENDOR_NAME="AlmaLinux"
VENDOR_URL="https://almalinux.org/"
BUG_REPORT_URL="https://bugs.almalinux.org/"

ALMALINUX_MANTISBT_PROJECT="AlmaLinux-10"
ALMALINUX_MANTISBT_PROJECT_VERSION="10.0"
REDHAT_SUPPORT_PRODUCT="AlmaLinux"
REDHAT_SUPPORT_PRODUCT_VERSION="10.0"
SUPPORT_END=2035-06-01
[root@alma ~]# uname -r
6.12.0-55.9.1.el10_0.x86_64
  • **安装基础软件:**如果不安装,后续会出现一些错误,如docker启动不了。
sh 复制代码
~]# yum install wget tar net-tools telnet tree nmap lrzsz dos2unix bind-utils vim less -y
...
~]# yum install openssl bash-completion ipvsadm ipset sysstat conntrack libseccomp -y
...
~]# yum install yum-utils device-mapper-persistent-data lvm2 ebtables ethtool conntrack-tools -y
...
  • 主机列表
IP 主机名 role 安装软件
192.168.26.49 node49 master/worker docker、cri-dockerd、etcd、apiserver、controllermanager、schedule、kubelet、kube-proxy、nginx、kubectl、kubectl-ai
192.168.26.50 node50 master/worker docker、cri-dockerd、etcd、apiserver、controllermanager、schedule、kubelet、kube-proxy、nginx、kubectl
192.168.26.51 node51 master/worker docker、cri-dockerd、etcd、apiserver、controllermanager、schedule、kubelet、kube-proxy、nginx、kubectl

1.1 安装环境基础设置

sh 复制代码
~]# hostname      ## 修改:# hostnamectl set-hostname master49
~]# hostnamectl set-hostname node49
~]# hostnamectl set-hostname node50
~]# hostnamectl set-hostname node51
~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.26.49 node49 k8s49
192.168.26.50 node50 k8s50
192.168.26.51 node51 k8s51
  • 关闭防火墙
sh 复制代码
 ~]# systemctl disable --now firewalld
 Removed symlink /etc/systemd/system/multi-user.target.wants/firewalld.service.
 Removed symlink /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.
 ~]# firewall-cmd --state
 not running
  • 关闭SELINUX:修改SELinux配置后需要重启操作系统。
sh 复制代码
 ~]# sed -i 's#SELINUX=enforcing#SELINUX=disabled#g' /etc/selinux/config
 ~]# reboot
 ~]# sestatus
 SELinux status:                 disabled
  • 关闭交换分区
sh 复制代码
 ~]# sed -ri 's/.*swap.*/#&/' /etc/fstab
 ~]# swapoff -a && sysctl -w vm.swappiness=0
 ~]# cat /etc/fstab
 #UUID=2ee3ecc4-e9e9-47c5-9afe-7b7b46fd6bab swap                    swap    defaults        0 0
 ~]# free -m
               total        used        free      shared  buff/cache   available
Mem:            3875         360        3590          16         100        3515
Swap:              0           0           0
  • 配置ulimit
sh 复制代码
 ~]# ulimit -SHn 65535
 ~]# cat << EOF >> /etc/security/limits.conf
* soft nofile 655360
* hard nofile 131072
* soft nproc 655350
* hard nproc 655350
* soft memlock unlimited
* hard memlock unlimited
EOF

1.2 ipvs管理工具安装及模块加载

sh 复制代码
~]# cat >> /etc/modules-load.d/ipvs.conf <<EOF
ip_vs
ip_vs_rr
ip_vs_wrr
ip_vs_sh
nf_conntrack
ip_tables
ip_set
xt_set
ipt_set
ipt_rpfilter
ipt_REJECT
ipip
EOF
 
~]# systemctl restart systemd-modules-load.service
 
~]# lsmod | grep -e ip_vs -e nf_conntrack
ip_vs_sh               12288  0
ip_vs_wrr              12288  0
ip_vs_rr               12288  0
ip_vs                 249856  6 ip_vs_rr,ip_vs_sh,ip_vs_wrr
nf_conntrack          204800  1 ip_vs
nf_defrag_ipv6         24576  2 nf_conntrack,ip_vs
nf_defrag_ipv4         12288  1 nf_conntrack

1.3 加载containerd相关内核模块

sh 复制代码
 临时加载模块
 ~]# modprobe overlay
 ~]# modprobe br_netfilter
 
 永久性加载模块
 ~]# cat > /etc/modules-load.d/containerd.conf << EOF
overlay
br_netfilter
EOF
 
 设置为开机启动
 ~]# systemctl restart systemd-modules-load.service ##systemctl enable --now systemd-modules-load.service

1.4 开启内核路由转发及网桥过滤

ini 复制代码
 ~]# cat <<EOF > /etc/sysctl.d/k8s.conf
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
fs.may_detach_mounts = 1
vm.overcommit_memory=1
vm.panic_on_oom=0
fs.inotify.max_user_watches=89100
fs.file-max=52706963
fs.nr_open=52706963
net.netfilter.nf_conntrack_max=2310720
 
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_intvl =15
net.ipv4.tcp_max_tw_buckets = 36000
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_max_orphans = 327680
net.ipv4.tcp_orphan_retries = 3
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.ip_conntrack_max = 131072
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_timestamps = 0
net.core.somaxconn = 16384
EOF
sh 复制代码
 ~]# sysctl --system
 ## 所有节点配置完内核后,重启服务器,保证重启后内核依旧加载
 ~]# reboot -h now
 
 ## 重启后查看ipvs模块加载情况:
 ~]# lsmod | grep --color=auto -e ip_vs -e nf_conntrack
ip_vs_sh               12288  0
ip_vs_wrr              12288  0
ip_vs_rr               12288  0
ip_vs                 249856  6 ip_vs_rr,ip_vs_sh,ip_vs_wrr
nf_conntrack          204800  1 ip_vs
nf_defrag_ipv6         24576  2 nf_conntrack,ip_vs
nf_defrag_ipv4         12288  1 nf_conntrack
 ## 重启后查看containerd相关模块加载情况:
 ~]# lsmod | egrep 'br_netfilter | overlay'
 br_netfilter           36864  0

1.5 检查主机时间是否同步

sh 复制代码
~]# date
Thu Feb 12 16:08:35 CST 2026

2、软件清单

3、资源清单

类型 名称 下载链接 说明
yaml资源 calico.yaml https://github.com/projectcalico/calico/blob/v3.31.3/manifests/calico.yaml kubectl部署
yaml资源 coredns.yaml.base https://github.com/kubernetes/kubernetes/blob/v1.35.1/cluster/addons/dns/coredns/coredns.yaml.base kubectl部署
yaml资源 components.yaml(metrics server) https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.8.1/components.yaml kubectl部署
镜像 calico:v3.31.3 quay.io/calico/cni:v3.31.3 quay.io/calico/node:v3.31.3 quay.io/calico/kube-controllers:v3.31.3 部署calico
镜像 metrics-server:v0.8.1 registry.aliyuncs.com/google_containers/metrics-server:v0.8.1 部署metrics-server
镜像 coredns:v1.13.1 registry.k8s.io/coredns/coredns:v1.13.1 部署coredns
镜像 pause:3.10.1 registry.aliyuncs.com/google_containers/pause:3.10.1 swr.cn-north-4.myhuaweicloud.com/ddn-k8s/registry.k8s.io/pause:3.10.1 部署pause
镜像 busybox:1.28 docker.io/library/busybox:1.28 验证
镜像 nginx:latest、nginx:1.19.6 nginx:latest、nginx:1.19.6 验证

4、部署规划

4.1 创建部署目录

  • /opt/kubernetes/app 存放部署资源文件
  • /opt/kubernetes/cfg 存放配置文件
  • /opt/kubernetes/cert 存放证书
  • /opt/kubernetes/bin 链接/opt/kubernetes/app下的源文件,去除文件名中的版本号,方便升级时只需要更改链接即可。
sh 复制代码
 ]# mkdir -p /opt/kubernetes/{app,cfg,cert,bin}
  • 将下载的软件及资源上传到主机k8s49(192.168.26.49):/opt/kubernetes/app/src

4.2 集群网络规划

网络名称 网段 备注
Node网络 192.168.26.0/24 Node IP,Node节点的IP地址,即物理机(宿主机)的网卡地址。
Service网络 168.26.0.0/16 Cluster IP,也可叫Service IP,Service的IP地址。service-cluster-ip-range定义Service IP地址范围的参数。
Pod网络 10.26.0.0/16 Pod IP,Pod的IP地址,容器(docker0)网桥分配的地址。cluster-cidr定义Pod网络CIDR地址范围的参数。
ini 复制代码
 apiserver:
 --service-cluster-ip-range 168.26.0.0/16    ##Service网络 10.84.0.0/16
 
 controller:
 --cluster-cidr 10.26.0.0/16   ##Pod网络 10.23.0.0/16
 --service-cluster-ip-range 168.26.0.0/16   ##service网络 10.84.0.0/16
 
 kubelet:
 --cluster-dns 168.26.0.2   ## 解析Service,10.84.0.2
 
 proxy:
 --cluster-cidr 10.26.0.0/16   ##Pod网络 10.23.0.0/16

4.3 部署证书生成工具

bash 复制代码
[root@k8s49 src]# mv cfssl-certinfo_1.6.5_linux_amd64 /usr/local/bin/cfssl-certinfo
[root@k8s49 src]# mv cfssl_1.6.5_linux_amd64 /usr/local/bin/cfssl
[root@k8s49 src]# mv cfssljson_1.6.5_linux_amd64 /usr/local/bin/cfssljson
[root@k8s49 src]# chmod +x /usr/local/bin/cfssl*
[root@k8s49 src]# cfssl version
Version: 1.6.5
Runtime: go1.22.0

5、安装docker

5.1 解压、创建软连接

shell 复制代码
~]# cd /opt/kubernetes/app/src
[root@k8s49 src]# tar zxvf docker-29.2.1.tgz
docker/
docker/runc
docker/docker
docker/dockerd
docker/containerd
docker/ctr
docker/containerd-shim-runc-v2
docker/docker-proxy
docker/docker-init
[root@k8s49 src]# ls docker
containerd  containerd-shim-runc-v2  ctr  docker  docker-init  docker-proxy  dockerd  runc
[root@k8s49 src]# mv docker /opt/kubernetes/bin/docker-29.2.1
[root@k8s49 src]# ls /opt/kubernetes/bin/docker-29.2.1
containerd  containerd-shim-runc-v2  ctr  docker  docker-init  docker-proxy  dockerd  runc
shell 复制代码
## 软链接如果存在,则删除
rm -rf /usr/bin/containerd
rm -rf /usr/bin/containerd-shim-runc-v2
rm -rf /usr/bin/ctr
rm -rf /usr/bin/docker
rm -rf /usr/bin/dockerd
rm -rf /usr/bin/docker-init
rm -rf /usr/bin/docker-proxy
rm -rf /usr/bin/runc
## 创建软连接:
ln -s /opt/kubernetes/bin/docker-29.2.1/containerd /usr/bin/containerd
ln -s /opt/kubernetes/bin/docker-29.2.1/containerd-shim-runc-v2 /usr/bin/containerd-shim-runc-v2
ln -s /opt/kubernetes/bin/docker-29.2.1/ctr /usr/bin/ctr
ln -s /opt/kubernetes/bin/docker-29.2.1/docker /usr/bin/docker
ln -s /opt/kubernetes/bin/docker-29.2.1/dockerd /usr/bin/dockerd
ln -s /opt/kubernetes/bin/docker-29.2.1/docker-init /usr/bin/docker-init
ln -s /opt/kubernetes/bin/docker-29.2.1/docker-proxy /usr/bin/docker-proxy
ln -s /opt/kubernetes/bin/docker-29.2.1/runc /usr/bin/runc
app]# docker -v
Docker version 29.2.1, build a5c7197

5.2 创建目录、配置文件

  • 在主机上:
sh 复制代码
]# mkdir -p /data/docker /etc/docker   ## 要创建在数据盘目录下
]# cat /etc/docker/daemon.json
{
  "data-root": "/data/docker",
  "storage-driver": "overlay2",
  "insecure-registries": ["harbor.oss.com:32402"],
  "registry-mirrors": ["https://5gce61mx.mirror.aliyuncs.com"],
  "exec-opts": ["native.cgroupdriver=systemd"],
  "live-restore": true,
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "1g",
    "max-file": "3"
  }
}

5.3 创建启动文件

sh 复制代码
]# cat /usr/lib/systemd/system/docker.service
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service
Wants=network-online.target
[Service]
Type=notify
ExecStart=/usr/bin/dockerd
ExecReload=/bin/kill -s HUP $MAINPID
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
TimeoutStartSec=0
Delegate=yes
KillMode=process
Restart=on-failure
StartLimitBurst=3
StartLimitInterval=60s
[Install]
WantedBy=multi-user.target

5.4 启动、检查

sh 复制代码
]# systemctl daemon-reload
]# systemctl start docker; systemctl enable docker
]# systemctl status docker
ini 复制代码
]# docker info
Client:
 Version:    29.2.1
 Context:    default
 Debug Mode: false

Server:
 Containers: 0
  Running: 0
  Paused: 0
  Stopped: 0
 Images: 0
 Server Version: 29.2.1
 Storage Driver: overlay2
  Backing Filesystem: xfs
  Supports d_type: true
  Using metacopy: false
  Native Overlay Diff: true
  userxattr: false
 Logging Driver: json-file
 Cgroup Driver: systemd
 Cgroup Version: 2
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local splunk syslog
 CDI spec directories:
  /etc/cdi
  /var/run/cdi
 Swarm: inactive
 Runtimes: io.containerd.runc.v2 runc
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: dea7da592f5d1d2b7755e3a161be07f43fad8f75
 runc version: v1.3.4-0-gd6d73eb
 init version: de40ad0
 Security Options:
  seccomp
   Profile: builtin
  cgroupns
 Kernel Version: 6.12.0-55.9.1.el10_0.x86_64
 Operating System: AlmaLinux 10.0 (Purple Lion)
 OSType: linux
 Architecture: x86_64
 CPUs: 4
 Total Memory: 3.785GiB
 Name: k8s49
 ID: c9e02dbe-4e06-4244-99ce-ace8d25c3093
 Docker Root Dir: /data/docker
 Debug Mode: false
 Experimental: false
 Insecure Registries:
  harbor.oss.com:32402
  ::1/128
  127.0.0.0/8
 Registry Mirrors:
  https://5gce61mx.mirror.aliyuncs.com/
 Live Restore Enabled: true
 Product License: Community Engine
 Firewall Backend: iptables

5.5 镜像下载及验证

sh 复制代码
]# docker pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/registry.k8s.io/pause:3.10.1
...
]# docker pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/busybox:1.28
...
]# docker tag swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/busybox:1.28 busybox:1.28
]# docker tag swr.cn-north-4.myhuaweicloud.com/ddn-k8s/registry.k8s.io/pause:3.10.1 registry.k8s.io/pause:3.10.1
]# docker rmi swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/busybox:1.28
]# docker rmi swr.cn-north-4.myhuaweicloud.com/ddn-k8s/registry.k8s.io/pause:3.10.1
]# docker images
IMAGE                          ID             DISK USAGE   CONTENT SIZE   EXTRA
busybox:1.28                   8c811b4aec35       1.15MB             0B
registry.k8s.io/pause:3.10.1   cd073f4c5f6a        736kB             0B
]# docker run -i -t --name box busybox:1.28 /bin/sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop qlen 1000
    link/ipip 0.0.0.0 brd 0.0.0.0
3: eth0@if5: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
    link/ether 8a:db:78:77:76:87 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
/ # exit
image]# docker ps -a
CONTAINER ID   IMAGE          COMMAND     CREATED          STATUS                     PORTS     NAMES
9c1c66a58ea2   busybox:1.28   "/bin/sh"   51 seconds ago   Exited (0) 5 seconds ago             box

5.6 复制到k8s50、K8s51

sh 复制代码
## 复制到k8s50、K8s51
]# scp -r /opt/kubernetes/bin/docker-29.2.1/ root@node50:/opt/kubernetes/bin/.
]# scp -r /opt/kubernetes/bin/docker-29.2.1/ root@node51:/opt/kubernetes/bin/.
## 在k8s50、K8s51创建软连接:同5.1
~]# docker -v
## 在k8s50、K8s51执行5.2、5.3、5.4

6、安装cri-dockerd

6.1 解压、创建软链接

sh 复制代码
src]# tar -zxvf cri-dockerd-0.3.24.amd64.tgz
src]# mv cri-dockerd /opt/kubernetes/bin/cri-dockerd-0.3.24
src]# ll /opt/kubernetes/bin/cri-dockerd-0.3.24
total 49056
-rwxr-xr-x 1 1001 1001 50229432 Feb 11 16:33 cri-dockerd
sh 复制代码
]# ln -s /opt/kubernetes/bin/cri-dockerd-0.3.24/cri-dockerd /usr/local/bin/cri-dockerd
]# cri-dockerd --version
cri-dockerd 0.3.24 (b5aed52)

6.2 修改配置文件、启动

ini 复制代码
]# cat /usr/lib/systemd/system/cri-dockerd.service
[Unit]
Description=CRI Interface for Docker Application Container Engine
Documentation=https://docs.mirantis.com
After=network-online.target firewalld.service docker.service
Wants=network-online.target
# Requires=cri-docker.socket ## 如果启动报错,则注释掉这一行

[Service]
Type=notify
ExecStart=/usr/local/bin/cri-dockerd --network-plugin=cni --pod-infra-container-image=registry.k8s.io/pause:3.10.1
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always

# Note that StartLimit* options were moved from "Service" to "Unit" in systemd 229.
# Both the old, and new location are accepted by systemd 229 and up, so using the old location
# to make them work for either version of systemd.
StartLimitBurst=3

# Note that StartLimitInterval was renamed to StartLimitIntervalSec in systemd 230.
# Both the old, and new name are accepted by systemd 230 and up, so using the old name to make
# this option work for either version of systemd.
StartLimitInterval=60s

# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity

# Comment TasksMax if your systemd version does not support it.
# Only systemd 226 and above support this option.
TasksMax=infinity
Delegate=yes
KillMode=process

[Install]
WantedBy=multi-user.target
sh 复制代码
## 启动前注意拉取好镜像
]# systemctl daemon-reload
]# systemctl enable cri-dockerd && systemctl start cri-dockerd

]# systemctl status cri-dockerd
● cri-dockerd.service - CRI Interface for Docker Application Container Engine
     Loaded: loaded (/usr/lib/systemd/system/cri-dockerd.service; enabled; preset: disabled)
     Active: active (running) since Thu 2026-02-12 16:52:44 CST; 6s ago
 Invocation: 70e3054e2852487e8c55f565c51f231c
       Docs: https://docs.mirantis.com
   Main PID: 2209 (cri-dockerd)
      Tasks: 9
     Memory: 11M (peak: 11.5M)
        CPU: 86ms
     CGroup: /system.slice/cri-dockerd.service
             └─2209 /usr/local/bin/cri-dockerd --network-plugin=cni --pod-infra-container-image=registry.k8s.io/pause:3.10.1
...

6.3 复制到k8s50、K8s51

sh 复制代码
## 复制到k8s50、K8s51
]# scp -r /opt/kubernetes/bin/cri-dockerd-0.3.24 root@node50:/opt/kubernetes/bin/.
]# scp -r /opt/kubernetes/bin/cri-dockerd-0.3.24 root@node51:/opt/kubernetes/bin/.
## 在k8s50、K8s51创建软连接:
]# ln -s /opt/kubernetes/bin/cri-dockerd-0.3.24/cri-dockerd /usr/local/bin/cri-dockerd
]# cri-dockerd --version
## 在k8s50、K8s51执行6.2

7、创建证书

在/opt/kubernetes/cert目录下创建,然后分发。

7.1 创建CA根证书

  • ca-csr.json
json 复制代码
]# cd /opt/kubernetes/cert
cert]# cat > ca-csr.json   << EOF
{
  "CN": "kubernetes",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Beijing",
      "L": "Beijing",
      "O": "Kubernetes",
      "OU": "Kubernetes-manual"
    }
  ],
  "ca": {
    "expiry": "876000h"
  }
}
EOF
sh 复制代码
cert]# cfssl gencert -initca ca-csr.json | cfssljson -bare ca
cert]# ls ca*pem
ca-key.pem  ca.pem
  • ca-config.json
json 复制代码
cat > ca-config.json << EOF
{
  "signing": {
    "default": {
      "expiry": "876000h"
    },
    "profiles": {
      "kubernetes": {
        "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
        ],
        "expiry": "876000h"
      }
    }
  }
}
EOF

7.2 创建etcd证书

  • etcd-ca-csr.json
json 复制代码
cat > etcd-ca-csr.json  << EOF
{
  "CN": "etcd",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Beijing",
      "L": "Beijing",
      "O": "etcd",
      "OU": "Etcd Security"
    }
  ],
  "ca": {
    "expiry": "876000h"
  }
}
EOF
  • etcd-csr.json
json 复制代码
cat > etcd-csr.json << EOF
{
  "CN": "etcd",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Beijing",
      "L": "Beijing",
      "O": "etcd",
      "OU": "Etcd Security"
    }
  ]
}
EOF
sh 复制代码
cert]# cfssl gencert -initca etcd-ca-csr.json | cfssljson -bare etcd-ca
cert]# ls etcd-ca*pem
etcd-ca-key.pem  etcd-ca.pem
 
cert]# cfssl gencert \
   -ca=./etcd-ca.pem \
   -ca-key=./etcd-ca-key.pem \
   -config=./ca-config.json \
   -hostname=127.0.0.1,node49,node50,node51,192.168.26.49,192.168.26.50,192.168.26.51 \
   -profile=kubernetes \
   etcd-csr.json | cfssljson -bare ./etcd
cert]# ls etcd*pem
etcd-ca-key.pem  etcd-ca.pem  etcd-key.pem  etcd.pem

7.3 创建kube-apiserver证书

  • apiserver-csr.json
json 复制代码
cat > apiserver-csr.json << EOF
{
  "CN": "kube-apiserver",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Beijing",
      "L": "Beijing",
      "O": "Kubernetes",
      "OU": "Kubernetes-manual"
    }
  ]
}
EOF
sh 复制代码
cert]# cfssl gencert   \
-ca=./ca.pem   \
-ca-key=./ca-key.pem   \
-config=./ca-config.json   \
-hostname=127.0.0.1,node49,node50,node51,192.168.26.49,192.168.26.50,192.168.26.51,168.26.0.1,kubernetes,kubernetes.default,kubernetes.default.svc,kubernetes.default.svc.cluster,kubernetes.default.svc.cluster.local  \
-profile=kubernetes   apiserver-csr.json | cfssljson -bare ./apiserver
cert]# ls apiserver*pem
apiserver-key.pem  apiserver.pem
  • front-proxy-ca-csr.json
json 复制代码
cat > front-proxy-ca-csr.json  << EOF
{
  "CN": "kubernetes",
  "key": {
     "algo": "rsa",
     "size": 2048
  },
  "ca": {
    "expiry": "876000h"
  }
}
EOF
  • front-proxy-client-csr.json
json 复制代码
cat > front-proxy-client-csr.json  << EOF
{
  "CN": "front-proxy-client",
  "key": {
     "algo": "rsa",
     "size": 2048
  }
}
EOF
sh 复制代码
 ## 生成kube-apiserver聚合证书
cert]# cfssl gencert -initca front-proxy-ca-csr.json | cfssljson -bare ./front-proxy-ca
cert]# ls front-proxy-ca*pem
front-proxy-ca-key.pem  front-proxy-ca.pem

cert]# cfssl gencert  \
-ca=./front-proxy-ca.pem   \
-ca-key=./front-proxy-ca-key.pem   \
-config=./ca-config.json   \
-profile=kubernetes front-proxy-client-csr.json | cfssljson -bare ./front-proxy-client
cert]# ls front-proxy-client*pem
front-proxy-client-key.pem  front-proxy-client.pem

7.4 创建kube-controller-manager的证书

  • manager-csr.json,用于生成配置文件controller-manager.kubeconfig
json 复制代码
cat > manager-csr.json << EOF
{
  "CN": "system:kube-controller-manager",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Beijing",
      "L": "Beijing",
      "O": "system:kube-controller-manager",
      "OU": "Kubernetes-manual"
    }
  ]
}
EOF
sh 复制代码
cert]# cfssl gencert \
   -ca=./ca.pem \
   -ca-key=./ca-key.pem \
   -config=./ca-config.json \
   -profile=kubernetes \
   manager-csr.json | cfssljson -bare ./controller-manager
cert]# ls controller-manager*pem
controller-manager-key.pem  controller-manager.pem
  • admin-csr.json,用于生成配置文件admin.kubeconfig
json 复制代码
cat > admin-csr.json << EOF
{
  "CN": "admin",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Beijing",
      "L": "Beijing",
      "O": "system:masters",
      "OU": "Kubernetes-manual"
    }
  ]
}
EOF
sh 复制代码
cert]# cfssl gencert \
   -ca=./ca.pem \
   -ca-key=./ca-key.pem \
   -config=./ca-config.json \
   -profile=kubernetes \
   admin-csr.json | cfssljson -bare ./admin
cert]# ls admin*pem
admin-key.pem  admin.pem

7.5 创建kube-schedule证书

  • scheduler-csr.json,用于生成配置文件scheduler.kubeconfig
json 复制代码
cat > scheduler-csr.json << EOF
{
  "CN": "system:kube-scheduler",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Beijing",
      "L": "Beijing",
      "O": "system:kube-scheduler",
      "OU": "Kubernetes-manual"
    }
  ]
}
EOF
sh 复制代码
cert]# cfssl gencert \
   -ca=./ca.pem \
   -ca-key=./ca-key.pem \
   -config=./ca-config.json \
   -profile=kubernetes \
   scheduler-csr.json | cfssljson -bare ./scheduler
cert]# ls scheduler*pem
scheduler-key.pem  scheduler.pem

7.6 创建kube-proxy证书

  • kube-proxy-csr.json,用于生成配置文件kube-proxy.kubeconfig
json 复制代码
cat > kube-proxy-csr.json  << EOF
{
  "CN": "system:kube-proxy",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Beijing",
      "L": "Beijing",
      "O": "system:kube-proxy",
      "OU": "Kubernetes-manual"
    }
  ]
}
EOF
sh 复制代码
cert]# cfssl gencert \
   -ca=./ca.pem \
   -ca-key=./ca-key.pem \
   -config=./ca-config.json \
   -profile=kubernetes \
   kube-proxy-csr.json | cfssljson -bare ./kube-proxy
cert]# ls kube-proxy*pem
kube-proxy-key.pem  kube-proxy.pem

7.7 创建ServiceAccount Key - secret

sh 复制代码
cert]# openssl genrsa -out /opt/kubernetes/cert/sa.key 2048
cert]# openssl rsa -in /opt/kubernetes/cert/sa.key -pubout -out /opt/kubernetes/cert/sa.pub
cert]# ls /opt/kubernetes/cert/sa*
/opt/kubernetes/cert/sa.key  /opt/kubernetes/cert/sa.pub

7.8 分发证书到各节点

将证书打包然后复制到各节点。

sh 复制代码
]# scp -r /opt/kubernetes/cert/sa* root@node50:/opt/kubernetes/cert/.
]# scp -r /opt/kubernetes/cert/sa* root@node51:/opt/kubernetes/cert/.
]# scp -r /opt/kubernetes/cert/*.pem root@node50:/opt/kubernetes/cert/.
]# scp -r /opt/kubernetes/cert/*.pem root@node51:/opt/kubernetes/cert/.

8、部署etcd

8.1 准备etcd二进制软件

sh 复制代码
 ## 解压软件包,并将运行软件放到/opt/kubernetes/bin目录
src]# tar -xf etcd-v3.6.7-linux-amd64.tar.gz -C /opt/kubernetes/bin
src]# ls /opt/kubernetes/bin/etcd-v3.6.7-linux-amd64/ -l
total 59208
drwxr-xr-x 6 1000 1000      120 Dec 18 03:41 Documentation
-rw-r--r-- 1 1000 1000    44075 Dec 18 03:41 README-etcdctl.md
-rw-r--r-- 1 1000 1000     8275 Dec 18 03:41 README-etcdutl.md
-rw-r--r-- 1 1000 1000     9839 Dec 18 03:41 README.md
-rw-r--r-- 1 1000 1000     7896 Dec 18 03:41 READMEv2-etcdctl.md
-rwxr-xr-x 1 1000 1000 26087608 Dec 18 03:41 etcd
-rwxr-xr-x 1 1000 1000 17207480 Dec 18 03:41 etcdctl
-rwxr-xr-x 1 1000 1000 17244344 Dec 18 03:41 etcdutl
sh 复制代码
## 创建软链接
ln -s /opt/kubernetes/bin/etcd-v3.6.7-linux-amd64/etcdctl /usr/local/bin/etcdctl
ln -s /opt/kubernetes/bin/etcd-v3.6.7-linux-amd64/etcd /opt/kubernetes/bin/etcd
]# etcdctl version
etcdctl version: 3.6.7
API version: 3.6
sh 复制代码
## 复制到node50、node51,并建立软链接
]# scp -r /opt/kubernetes/bin/etcd-v3.6.7-linux-amd64 root@node50:/opt/kubernetes/bin/.
]# scp -r /opt/kubernetes/bin/etcd-v3.6.7-linux-amd64 root@node51:/opt/kubernetes/bin/.

8.2 启动参数配置文件

  • node49:/opt/kubernetes/cfg/etcd.config.yml
yaml 复制代码
cat > /opt/kubernetes/cfg/etcd.config.yml << EOF
name: 'node49'
data-dir: /opt/kubernetes/etcd
wal-dir: /opt/kubernetes/etcd/wal
snapshot-count: 5000
heartbeat-interval: 100
election-timeout: 1000
quota-backend-bytes: 0
listen-peer-urls: 'https://192.168.26.49:2380'
listen-client-urls: 'https://192.168.26.49:2379,http://127.0.0.1:2379'
max-snapshots: 3
max-wals: 5
cors:
initial-advertise-peer-urls: 'https://192.168.26.49:2380'
advertise-client-urls: 'https://192.168.26.49:2379'
discovery:
discovery-fallback: 'proxy'
discovery-proxy:
discovery-srv:
initial-cluster: 'node49=https://192.168.26.49:2380,node50=https://192.168.26.50:2380,node51=https://192.168.26.51:2380'
initial-cluster-token: 'etcd-k8s-cluster'
initial-cluster-state: 'new'
strict-reconfig-check: false
enable-pprof: true
proxy: 'off'
proxy-failure-wait: 5000
proxy-refresh-interval: 30000
proxy-dial-timeout: 1000
proxy-write-timeout: 5000
proxy-read-timeout: 0
client-cert-auth: true
cert-file: '/opt/kubernetes/cert/etcd.pem'
key-file: '/opt/kubernetes/cert/etcd-key.pem'
trusted-ca-file: '/opt/kubernetes/cert/etcd-ca.pem'
auto-tls: true
client-transport-security:
  cert-file: '/opt/kubernetes/cert/etcd.pem'
  key-file: '/opt/kubernetes/cert/etcd-key.pem'
  client-cert-auth: true
  trusted-ca-file: '/opt/kubernetes/cert/etcd-ca.pem'
  auto-tls: true
peer-transport-security:
  cert-file: '/opt/kubernetes/cert/etcd.pem'
  key-file: '/opt/kubernetes/cert/etcd-key.pem'
  peer-client-cert-auth: true
  trusted-ca-file: '/opt/kubernetes/cert/etcd-ca.pem'
  auto-tls: true
debug: false
log-package-levels:
log-outputs: [default]
force-new-cluster: false
EOF

etcd启动参数配置文件没有enable-v2: true时,etcd默认为v3,命令行中可以不加ETCDCTL_API=3

  • node50:/opt/kubernetes/cfg/etcd.config.yml
yaml 复制代码
cat > /opt/kubernetes/cfg/etcd.config.yml << EOF
name: 'node50'
data-dir: /opt/kubernetes/etcd
wal-dir: /opt/kubernetes/etcd/wal
snapshot-count: 5000
heartbeat-interval: 100
election-timeout: 1000
quota-backend-bytes: 0
listen-peer-urls: 'https://192.168.26.50:2380'
listen-client-urls: 'https://192.168.26.50:2379,http://127.0.0.1:2379'
max-snapshots: 3
max-wals: 5
cors:
initial-advertise-peer-urls: 'https://192.168.26.50:2380'
advertise-client-urls: 'https://192.168.26.50:2379'
discovery:
discovery-fallback: 'proxy'
discovery-proxy:
discovery-srv:
initial-cluster: 'node49=https://192.168.26.49:2380,node50=https://192.168.26.50:2380,node51=https://192.168.26.51:2380'
initial-cluster-token: 'etcd-k8s-cluster'
initial-cluster-state: 'new'
strict-reconfig-check: false
enable-pprof: true
proxy: 'off'
proxy-failure-wait: 5000
proxy-refresh-interval: 30000
proxy-dial-timeout: 1000
proxy-write-timeout: 5000
proxy-read-timeout: 0
client-cert-auth: true
cert-file: '/opt/kubernetes/cert/etcd.pem'
key-file: '/opt/kubernetes/cert/etcd-key.pem'
trusted-ca-file: '/opt/kubernetes/cert/etcd-ca.pem'
auto-tls: true
client-transport-security:
  cert-file: '/opt/kubernetes/cert/etcd.pem'
  key-file: '/opt/kubernetes/cert/etcd-key.pem'
  client-cert-auth: true
  trusted-ca-file: '/opt/kubernetes/cert/etcd-ca.pem'
  auto-tls: true
peer-transport-security:
  cert-file: '/opt/kubernetes/cert/etcd.pem'
  key-file: '/opt/kubernetes/cert/etcd-key.pem'
  peer-client-cert-auth: true
  trusted-ca-file: '/opt/kubernetes/cert/etcd-ca.pem'
  auto-tls: true
debug: false
log-package-levels:
log-outputs: [default]
force-new-cluster: false
EOF
  • node51:/opt/kubernetes/cfg/etcd.config.yml
yaml 复制代码
cat > /opt/kubernetes/cfg/etcd.config.yml << EOF
name: 'node51'
data-dir: /opt/kubernetes/etcd
wal-dir: /opt/kubernetes/etcd/wal
snapshot-count: 5000
heartbeat-interval: 100
election-timeout: 1000
quota-backend-bytes: 0
listen-peer-urls: 'https://192.168.26.51:2380'
listen-client-urls: 'https://192.168.26.51:2379,http://127.0.0.1:2379'
max-snapshots: 3
max-wals: 5
cors:
initial-advertise-peer-urls: 'https://192.168.26.51:2380'
advertise-client-urls: 'https://192.168.26.51:2379'
discovery:
discovery-fallback: 'proxy'
discovery-proxy:
discovery-srv:
initial-cluster: 'node49=https://192.168.26.49:2380,node50=https://192.168.26.50:2380,node51=https://192.168.26.51:2380'
initial-cluster-token: 'etcd-k8s-cluster'
initial-cluster-state: 'new'
strict-reconfig-check: false
enable-pprof: true
proxy: 'off'
proxy-failure-wait: 5000
proxy-refresh-interval: 30000
proxy-dial-timeout: 1000
proxy-write-timeout: 5000
proxy-read-timeout: 0
client-cert-auth: true
cert-file: '/opt/kubernetes/cert/etcd.pem'
key-file: '/opt/kubernetes/cert/etcd-key.pem'
trusted-ca-file: '/opt/kubernetes/cert/etcd-ca.pem'
auto-tls: true
client-transport-security:
  cert-file: '/opt/kubernetes/cert/etcd.pem'
  key-file: '/opt/kubernetes/cert/etcd-key.pem'
  client-cert-auth: true
  trusted-ca-file: '/opt/kubernetes/cert/etcd-ca.pem'
  auto-tls: true
peer-transport-security:
  cert-file: '/opt/kubernetes/cert/etcd.pem'
  key-file: '/opt/kubernetes/cert/etcd-key.pem'
  peer-client-cert-auth: true
  trusted-ca-file: '/opt/kubernetes/cert/etcd-ca.pem'
  auto-tls: true
debug: false
log-package-levels:
log-outputs: [default]
force-new-cluster: false
EOF

8.3 创建service、启动、检查

在edcd节点node49、node50、node51

ini 复制代码
cat > /usr/lib/systemd/system/etcd.service << EOF
[Unit]
Description=Etcd Service
Documentation=https://coreos.com/etcd/docs/latest/
After=network.target

[Service]
Type=notify
ExecStart=/opt/kubernetes/bin/etcd --config-file=/opt/kubernetes/cfg/etcd.config.yml
Restart=on-failure
RestartSec=10
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
Alias=etcd3.service

EOF

启动,检查

sh 复制代码
]# systemctl daemon-reload
]# systemctl enable --now etcd
]# systemctl status etcd
● etcd.service - Etcd Service
     Loaded: loaded (/usr/lib/systemd/system/etcd.service; enabled; preset: disabled)
     Active: active (running) since Fri 2026-02-13 09:31:46 CST; 1min 25s ago
 Invocation: 74153022a69249fc8d8073e083c4c0b3
       Docs: https://coreos.com/etcd/docs/latest/
   Main PID: 2285 (etcd)
      Tasks: 10 (limit: 24588)
     Memory: 26.9M (peak: 27.9M)
        CPU: 1.838s
     CGroup: /system.slice/etcd.service
             └─2285 /opt/kubernetes/bin/etcd --config-file=/opt/kubernetes/cfg/etcd.config.yml
  ...
sh 复制代码
## 默认:ETCDCTL_API=3 
]# etcdctl --endpoints="192.168.26.49:2379,192.168.26.50:2379,192.168.26.51:2379" \
--cacert=/opt/kubernetes/cert/etcd-ca.pem --cert=/opt/kubernetes/cert/etcd.pem --key=/opt/kubernetes/cert/etcd-key.pem  endpoint health --write-out=table
+--------------------+--------+-------------+-------+
|      ENDPOINT      | HEALTH |    TOOK     | ERROR |
+--------------------+--------+-------------+-------+
| 192.168.26.50:2379 |   true | 28.444584ms |       |
| 192.168.26.49:2379 |   true |  28.41198ms |       |
| 192.168.26.51:2379 |   true | 28.312255ms |       |
+--------------------+--------+-------------+-------+
]# etcdctl --endpoints="192.168.26.49:2379,192.168.26.50:2379,192.168.26.51:2379" \
--cacert=/opt/kubernetes/cert/etcd-ca.pem --cert=/opt/kubernetes/cert/etcd.pem --key=/opt/kubernetes/cert/etcd-key.pem  endpoint status --write-out=table
+--------------------+------------------+---------+-----------------+---------+--------+-----------------------+--------+-----------+------------+-----------+------------+--------------------+--------+--------------------------+-------------------+
|      ENDPOINT      |        ID        | VERSION | STORAGE VERSION | DB SIZE | IN USE | PERCENTAGE NOT IN USE | QUOTA  | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS | DOWNGRADE TARGET VERSION | DOWNGRADE ENABLED |
+--------------------+------------------+---------+-----------------+---------+--------+-----------------------+--------+-----------+------------+-----------+------------+--------------------+--------+--------------------------+-------------------+
| 192.168.26.49:2379 |  9422bfd43a40dae |   3.6.7 |           3.6.0 |   20 kB |  16 kB |                   20% | 2.1 GB |     false |      false |         2 |         11 |                 11 |        |                          |             false |
| 192.168.26.50:2379 | 99b87d3d391a718b |   3.6.7 |           3.6.0 |   20 kB |  16 kB |                   20% | 2.1 GB |      true |      false |         2 |         11 |                 11 |        |                          |             false |
| 192.168.26.51:2379 | f0355985a6ae32e9 |   3.6.7 |           3.6.0 |   20 kB |  16 kB |                   20% | 2.1 GB |     false |      false |         2 |         11 |                 11 |        |                          |             false |
+--------------------+------------------+---------+-----------------+---------+--------+-----------------------+--------+-----------+------------+-----------+------------+--------------------+--------+--------------------------+-------------------+
]# etcdctl --endpoints="192.168.26.49:2379,192.168.26.50:2379,192.168.26.51:2379" \
--cacert=/opt/kubernetes/cert/etcd-ca.pem --cert=/opt/kubernetes/cert/etcd.pem --key=/opt/kubernetes/cert/etcd-key.pem member list --write-out=table
+------------------+---------+--------+----------------------------+----------------------------+------------+
|        ID        | STATUS  |  NAME  |         PEER ADDRS         |        CLIENT ADDRS        | IS LEARNER |
+------------------+---------+--------+----------------------------+----------------------------+------------+
|  9422bfd43a40dae | started | node49 | https://192.168.26.49:2380 | https://192.168.26.49:2379 |      false |
| 99b87d3d391a718b | started | node50 | https://192.168.26.50:2380 | https://192.168.26.50:2379 |      false |
| f0355985a6ae32e9 | started | node51 | https://192.168.26.51:2380 | https://192.168.26.51:2379 |      false |
+------------------+---------+--------+----------------------------+----------------------------+------------+

9、k8s核心组件

9.1 准备

bash 复制代码
~]# cd /opt/kubernetes/app/src/
## 解压全部
src]# tar -zxvf kubernetes-server-linux-amd64.tar.gz
src]# mv kubernetes/server/bin /opt/kubernetes/bin/kubernetes-v1.35.1
src]# rm -rf kubernetes
src]# rm -rf /opt/kubernetes/bin/kubernetes-v1.35.1/*.tar
src]# rm -rf /opt/kubernetes/bin/kubernetes-v1.35.1/*_tag
src]# rm -rf /opt/kubernetes/bin/kubernetes-v1.35.1/{apiextensions-apiserver,kube-aggregator,kubectl-convert,kube-log-runner,mounter}
src]# ll /opt/kubernetes/bin/kubernetes-v1.35.1
total 427396
-rwxr-xr-x 1 root root 85778616 Feb 10 21:00 kube-apiserver
-rwxr-xr-x 1 root root 71819448 Feb 10 21:00 kube-controller-manager
-rwxr-xr-x 1 root root 43258040 Feb 10 21:00 kube-proxy
-rwxr-xr-x 1 root root 47689912 Feb 10 21:00 kube-scheduler
-rwxr-xr-x 1 root root 72372408 Feb 10 21:00 kubeadm
-rwxr-xr-x 1 root root 58597560 Feb 10 21:00 kubectl
-rwxr-xr-x 1 root root 58110244 Feb 10 21:00 kubelet
## node节点删除:
src]# rm -rf /opt/kubernetes/bin/kubernetes-v1.33.2/{kube-apiserver,kube-controller-manager,kube-scheduler}
## 创建软链接
ln -s /opt/kubernetes/bin/kubernetes-v1.35.1 /opt/kubernetes/bin/kubernetes
ln -s /opt/kubernetes/bin/kubernetes-v1.35.1/kubectl /usr/local/bin/kubectl
]# /opt/kubernetes/bin/kubernetes/kubelet --version
Kubernetes v1.35.1
sh 复制代码
## 复制到node50、node51,并建立软链接
]# scp -r /opt/kubernetes/bin/kubernetes-v1.35.1 root@node50:/opt/kubernetes/bin/.
]# scp -r /opt/kubernetes/bin/kubernetes-v1.35.1 root@node51:/opt/kubernetes/bin/.

9.2 Nginx高可用方案

使用 nginx方案,kube-apiserver中的配置为: --server=https://127.0.0.1:9443

  • 编译安装nginx
bash 复制代码
## 在一台有开发环境的主机上进行编译安装,然后复制到集群节点
src]# tar xvf nginx-1.28.2.tar.gz
src]# cd nginx-1.28.2
nginx-1.28.2]# ./configure --with-stream --without-http --without-http_uwsgi_module --without-http_scgi_module --without-http_fastcgi_module
......
nginx-1.28.2]# make && make install
......
nginx-1.28.2]# ls -l /usr/local/nginx
total 4
drwxr-xr-x 2 root root 4096 Feb 13 10:44 conf
drwxr-xr-x 2 root root   40 Feb 13 10:44 html
drwxr-xr-x 2 root root    6 Feb 13 10:44 logs
drwxr-xr-x 2 root root   19 Feb 13 10:44 sbin
  • nginx配置文件/usr/local/nginx/conf/kube-nginx.conf
bash 复制代码
 # 写入nginx配置文件
cat > /usr/local/nginx/conf/kube-nginx.conf <<EOF
worker_processes 1;
events {
    worker_connections  1024;
}
stream {
    upstream backend {
        least_conn;
        hash $remote_addr consistent;
        server 192.168.26.49:6443        max_fails=3 fail_timeout=30s;
        server 192.168.26.50:6443        max_fails=3 fail_timeout=30s;
        server 192.168.26.51:6443        max_fails=3 fail_timeout=30s;
    }
    server {
        listen 127.0.0.1:9443;
        proxy_connect_timeout 1s;
        proxy_pass backend;
    }
}
EOF
  • 打包并复制到集群其他节点
sh 复制代码
## 复制到node50、node51
]# scp -r /usr/local/nginx root@node50:/usr/local/.
]# scp -r /usr/local/nginx root@node51:/usr/local/.

## 不能scp时,可采用打包、上传
src]# tar -cvf nginx.tar /usr/local/nginx/
...
## 解压
src]# tar -xvf nginx.tar
src]# mv usr/local/nginx /usr/local/.
src]# ll /usr/local/nginx/
  • 启动配置文件/etc/systemd/system/kube-nginx.service
ini 复制代码
# 写入启动配置文件
cat > /etc/systemd/system/kube-nginx.service <<EOF
[Unit]
Description=kube-apiserver nginx proxy
After=network.target
After=network-online.target
Wants=network-online.target

[Service]
Type=forking
ExecStartPre=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/kube-nginx.conf -p /usr/local/nginx -t
ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/kube-nginx.conf -p /usr/local/nginx
ExecReload=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/kube-nginx.conf -p /usr/local/nginx -s reload
PrivateTmp=true
Restart=always
RestartSec=5
StartLimitInterval=0
LimitNOFILE=65536
 
[Install]
WantedBy=multi-user.target
EOF
  • 设置开机自启并检查启动是否成功
sh 复制代码
 # 设置开机自启
 ]# systemctl enable --now  kube-nginx
 ]# systemctl restart kube-nginx
 ]# systemctl status kube-nginx
● kube-nginx.service - kube-apiserver nginx proxy
     Loaded: loaded (/etc/systemd/system/kube-nginx.service; enabled; preset: disabled)
     Active: active (running) since Fri 2026-02-13 10:51:52 CST; 19s ago
 Invocation: 6aa36a6ac9cd47d1930461107323ead7
    Process: 23601 ExecStartPre=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/kube-nginx.conf -p /usr/local/nginx -t (code=exited, status=0/SUCCESS)
    Process: 23604 ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/kube-nginx.conf -p /usr/local/nginx (code=exited, status=0/SUCCESS)
   Main PID: 23606 (nginx)
      Tasks: 2 (limit: 24588)
     Memory: 1M (peak: 1.2M)
        CPU: 22ms
     CGroup: /system.slice/kube-nginx.service
             ├─23606 "nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/kube-nginx.conf -p /usr/local/nginx"
             └─23607 "nginx: worker process"

9.3 部署kube-apiserver

  • node49:/usr/lib/systemd/system/kube-apiserver.service
ini 复制代码
cat > /usr/lib/systemd/system/kube-apiserver.service << EOF
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes
After=network.target

[Service]
ExecStart=/opt/kubernetes/bin/kubernetes/kube-apiserver \\
      --v=2  \\
      --allow-privileged=true  \\
      --bind-address=0.0.0.0  \\
      --secure-port=6443  \\
      --advertise-address=192.168.26.49 \\
      --service-cluster-ip-range=168.26.0.0/16  \\
      --service-node-port-range=30000-39999  \\
      --etcd-servers=https://192.168.26.49:2379,https://192.168.26.50:2379,https://192.168.26.51:2379 \\
      --etcd-cafile=/opt/kubernetes/cert/etcd-ca.pem  \\
      --etcd-certfile=/opt/kubernetes/cert/etcd.pem  \\
      --etcd-keyfile=/opt/kubernetes/cert/etcd-key.pem  \\
      --client-ca-file=/opt/kubernetes/cert/ca.pem  \\
      --tls-cert-file=/opt/kubernetes/cert/apiserver.pem  \\
      --tls-private-key-file=/opt/kubernetes/cert/apiserver-key.pem  \\
      --kubelet-client-certificate=/opt/kubernetes/cert/apiserver.pem  \\
      --kubelet-client-key=/opt/kubernetes/cert/apiserver-key.pem  \\
      --service-account-key-file=/opt/kubernetes/cert/sa.pub  \\
      --service-account-signing-key-file=/opt/kubernetes/cert/sa.key  \\
      --service-account-issuer=https://kubernetes.default.svc.cluster.local \\
      --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname  \\
      --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,ResourceQuota  \\
      --authorization-mode=Node,RBAC  \\
      --enable-bootstrap-token-auth=true  \\
      --requestheader-client-ca-file=/opt/kubernetes/cert/front-proxy-ca.pem  \\
      --proxy-client-cert-file=/opt/kubernetes/cert/front-proxy-client.pem  \\
      --proxy-client-key-file=/opt/kubernetes/cert/front-proxy-client-key.pem  \\
      --requestheader-allowed-names=aggregator  \\
      --requestheader-group-headers=X-Remote-Group  \\
      --requestheader-extra-headers-prefix=X-Remote-Extra-  \\
      --requestheader-username-headers=X-Remote-User \\
      --enable-aggregator-routing=true
      # --feature-gates=IPv6DualStack=true
      # --token-auth-file=/opt/kubernetes/cert/token.csv

Restart=on-failure
RestartSec=10s
LimitNOFILE=65535

[Install]
WantedBy=multi-user.target

EOF
  • node50:/usr/lib/systemd/system/kube-apiserver.service
ini 复制代码
cat > /usr/lib/systemd/system/kube-apiserver.service << EOF
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes
After=network.target

[Service]
ExecStart=/opt/kubernetes/bin/kubernetes/kube-apiserver \\
      --v=2  \\
      --allow-privileged=true  \\
      --bind-address=0.0.0.0  \\
      --secure-port=6443  \\
      --advertise-address=192.168.26.50 \\
      --service-cluster-ip-range=168.26.0.0/16  \\
      --service-node-port-range=30000-39999  \\
      --etcd-servers=https://192.168.26.49:2379,https://192.168.26.50:2379,https://192.168.26.51:2379 \\
      --etcd-cafile=/opt/kubernetes/cert/etcd-ca.pem  \\
      --etcd-certfile=/opt/kubernetes/cert/etcd.pem  \\
      --etcd-keyfile=/opt/kubernetes/cert/etcd-key.pem  \\
      --client-ca-file=/opt/kubernetes/cert/ca.pem  \\
      --tls-cert-file=/opt/kubernetes/cert/apiserver.pem  \\
      --tls-private-key-file=/opt/kubernetes/cert/apiserver-key.pem  \\
      --kubelet-client-certificate=/opt/kubernetes/cert/apiserver.pem  \\
      --kubelet-client-key=/opt/kubernetes/cert/apiserver-key.pem  \\
      --service-account-key-file=/opt/kubernetes/cert/sa.pub  \\
      --service-account-signing-key-file=/opt/kubernetes/cert/sa.key  \\
      --service-account-issuer=https://kubernetes.default.svc.cluster.local \\
      --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname  \\
      --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,ResourceQuota  \\
      --authorization-mode=Node,RBAC  \\
      --enable-bootstrap-token-auth=true  \\
      --requestheader-client-ca-file=/opt/kubernetes/cert/front-proxy-ca.pem  \\
      --proxy-client-cert-file=/opt/kubernetes/cert/front-proxy-client.pem  \\
      --proxy-client-key-file=/opt/kubernetes/cert/front-proxy-client-key.pem  \\
      --requestheader-allowed-names=aggregator  \\
      --requestheader-group-headers=X-Remote-Group  \\
      --requestheader-extra-headers-prefix=X-Remote-Extra-  \\
      --requestheader-username-headers=X-Remote-User \\
      --enable-aggregator-routing=true
      # --feature-gates=IPv6DualStack=true
      # --token-auth-file=/opt/kubernetes/cert/token.csv

Restart=on-failure
RestartSec=10s
LimitNOFILE=65535

[Install]
WantedBy=multi-user.target

EOF
  • node51:/usr/lib/systemd/system/kube-apiserver.service
ini 复制代码
cat > /usr/lib/systemd/system/kube-apiserver.service << EOF
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes
After=network.target

[Service]
ExecStart=/opt/kubernetes/bin/kubernetes/kube-apiserver \\
      --v=2  \\
      --allow-privileged=true  \\
      --bind-address=0.0.0.0  \\
      --secure-port=6443  \\
      --advertise-address=192.168.26.51 \\
      --service-cluster-ip-range=168.26.0.0/16  \\
      --service-node-port-range=30000-39999  \\
      --etcd-servers=https://192.168.26.49:2379,https://192.168.26.50:2379,https://192.168.26.51:2379 \\
      --etcd-cafile=/opt/kubernetes/cert/etcd-ca.pem  \\
      --etcd-certfile=/opt/kubernetes/cert/etcd.pem  \\
      --etcd-keyfile=/opt/kubernetes/cert/etcd-key.pem  \\
      --client-ca-file=/opt/kubernetes/cert/ca.pem  \\
      --tls-cert-file=/opt/kubernetes/cert/apiserver.pem  \\
      --tls-private-key-file=/opt/kubernetes/cert/apiserver-key.pem  \\
      --kubelet-client-certificate=/opt/kubernetes/cert/apiserver.pem  \\
      --kubelet-client-key=/opt/kubernetes/cert/apiserver-key.pem  \\
      --service-account-key-file=/opt/kubernetes/cert/sa.pub  \\
      --service-account-signing-key-file=/opt/kubernetes/cert/sa.key  \\
      --service-account-issuer=https://kubernetes.default.svc.cluster.local \\
      --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname  \\
      --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,ResourceQuota  \\
      --authorization-mode=Node,RBAC  \\
      --enable-bootstrap-token-auth=true  \\
      --requestheader-client-ca-file=/opt/kubernetes/cert/front-proxy-ca.pem  \\
      --proxy-client-cert-file=/opt/kubernetes/cert/front-proxy-client.pem  \\
      --proxy-client-key-file=/opt/kubernetes/cert/front-proxy-client-key.pem  \\
      --requestheader-allowed-names=aggregator  \\
      --requestheader-group-headers=X-Remote-Group  \\
      --requestheader-extra-headers-prefix=X-Remote-Extra-  \\
      --requestheader-username-headers=X-Remote-User \\
      --enable-aggregator-routing=true
      # --feature-gates=IPv6DualStack=true
      # --token-auth-file=/opt/kubernetes/cert/token.csv

Restart=on-failure
RestartSec=10s
LimitNOFILE=65535

[Install]
WantedBy=multi-user.target

EOF
  • 启动apiserver(所有master节点)
sh 复制代码
]# systemctl daemon-reload && systemctl enable --now kube-apiserver
 
 ## 注意查看状态是否启动正常
]# systemctl status kube-apiserver
● kube-apiserver.service - Kubernetes API Server
     Loaded: loaded (/usr/lib/systemd/system/kube-apiserver.service; enabled; preset: disabled)
     Active: active (running) since Fri 2026-02-13 10:58:26 CST; 15s ago
 Invocation: 63a52c82097d43739676775791d12537
       Docs: https://github.com/kubernetes/kubernetes
   Main PID: 23713 (kube-apiserver)
      Tasks: 10 (limit: 24588)
     Memory: 202.3M (peak: 205.2M)
        CPU: 7.295s
     CGroup: /system.slice/kube-apiserver.service
             └─23713 /opt/kubernetes/bin/kubernetes/kube-apiserver --v=2 --allow-privileged=true --bind-address=0.0.0.0 --secure-port=6443 --advertise-address=192.168.26.49>
......

]# curl -k --cacert /opt/kubernetes/cert/ca.pem \
--cert /opt/kubernetes/cert/apiserver.pem \
--key /opt/kubernetes/cert/apiserver-key.pem \
https://192.168.26.50:6443/healthz
ok

 ]# ip_head='192.168.26';for i in 49 50 51;do \
curl -k --cacert /opt/kubernetes/cert/ca.pem \
--cert /opt/kubernetes/cert/apiserver.pem \
--key /opt/kubernetes/cert/apiserver-key.pem \
https://${ip_head}.${i}:6443/healthz; \
done
okokok

9.4 kubectl配置

  • 创建admin.kubeconfig。使用 nginx方案,-server=https://127.0.0.1:9443在一个节点执行一次即可
sh 复制代码
kubectl config set-cluster kubernetes     \
  --certificate-authority=/opt/kubernetes/cert/ca.pem     \
  --embed-certs=true     \
  --server=https://127.0.0.1:9443     \
  --kubeconfig=/opt/kubernetes/cert/admin.kubeconfig

kubectl config set-credentials kubernetes-admin  \
  --client-certificate=/opt/kubernetes/cert/admin.pem     \
  --client-key=/opt/kubernetes/cert/admin-key.pem     \
  --embed-certs=true     \
  --kubeconfig=/opt/kubernetes/cert/admin.kubeconfig

kubectl config set-context kubernetes-admin@kubernetes    \
  --cluster=kubernetes     \
  --user=kubernetes-admin     \
  --kubeconfig=/opt/kubernetes/cert/admin.kubeconfig

kubectl config use-context kubernetes-admin@kubernetes  --kubeconfig=/opt/kubernetes/cert/admin.kubeconfig

]# mkdir ~/.kube
]# cp /opt/kubernetes/cert/admin.kubeconfig ~/.kube/config
]# scp -r /root/.kube root@node50:/root/.
]# scp -r /root/.kube root@node51:/root/.

注意:远程访问使用--server=https://192.168.26.49:6443

bash 复制代码
~]# kubectl get componentstatuses
Warning: v1 ComponentStatus is deprecated in v1.19+
NAME                 STATUS      MESSAGE                                                                                        ERROR
controller-manager   Unhealthy   Get "https://127.0.0.1:10257/healthz": dial tcp 127.0.0.1:10257: connect: connection refused
scheduler            Unhealthy   Get "https://127.0.0.1:10259/healthz": dial tcp 127.0.0.1:10259: connect: connection refused
etcd-0               Healthy     ok

9.5 部署kube-controller-manager

所有master节点配置,且配置相同。 10.26.0.0/16为pod网段,按需求设置你自己的网段。

  • 创建启动配置:/usr/lib/systemd/system/kube-controller-manager.service
ini 复制代码
cat > /usr/lib/systemd/system/kube-controller-manager.service << EOF

[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/kubernetes/kubernetes
After=network.target

[Service]
ExecStart=/opt/kubernetes/bin/kubernetes/kube-controller-manager \\
      --v=2 \\
      --bind-address=0.0.0.0 \\
      --root-ca-file=/opt/kubernetes/cert/ca.pem \\
      --cluster-signing-cert-file=/opt/kubernetes/cert/ca.pem \\
      --cluster-signing-key-file=/opt/kubernetes/cert/ca-key.pem \\
      --service-account-private-key-file=/opt/kubernetes/cert/sa.key \\
      --kubeconfig=/opt/kubernetes/cert/controller-manager.kubeconfig \\
      --leader-elect=true \\
      --use-service-account-credentials=true \\
      --node-monitor-grace-period=40s \\
      --node-monitor-period=5s \\
      --controllers=*,bootstrapsigner,tokencleaner \\
      --allocate-node-cidrs=true \\
      --service-cluster-ip-range=168.26.0.0/16 \\
      --cluster-cidr=10.26.0.0/16 \\
      --node-cidr-mask-size-ipv4=24 \\
      --requestheader-client-ca-file=/opt/kubernetes/cert/front-proxy-ca.pem 

Restart=always
RestartSec=10s

[Install]
WantedBy=multi-user.target

EOF
  • 创建kube-controller-manager.kubeconfig。使用 nginx方案,-server=https://127.0.0.1:9443。在一个节点执行一次即可。
sh 复制代码
kubectl config set-cluster kubernetes \
     --certificate-authority=/opt/kubernetes/cert/ca.pem \
     --embed-certs=true \
     --server=https://127.0.0.1:9443 \
     --kubeconfig=/opt/kubernetes/cert/controller-manager.kubeconfig
## 设置一个环境项,一个上下文
kubectl config set-context system:kube-controller-manager@kubernetes \
    --cluster=kubernetes \
    --user=system:kube-controller-manager \
    --kubeconfig=/opt/kubernetes/cert/controller-manager.kubeconfig
## 设置一个用户项
kubectl config set-credentials system:kube-controller-manager \
     --client-certificate=/opt/kubernetes/cert/controller-manager.pem \
     --client-key=/opt/kubernetes/cert/controller-manager-key.pem \
     --embed-certs=true \
     --kubeconfig=/opt/kubernetes/cert/controller-manager.kubeconfig
## 设置默认环境
kubectl config use-context system:kube-controller-manager@kubernetes \
     --kubeconfig=/opt/kubernetes/cert/controller-manager.kubeconfig

## 复制/opt/kubernetes/cert/controller-manager.kubeconfig到其它节点
]# scp /opt/kubernetes/cert/controller-manager.kubeconfig root@node50:/opt/kubernetes/cert/.
]# scp /opt/kubernetes/cert/controller-manager.kubeconfig root@node51:/opt/kubernetes/cert/.
  • 启动kube-controller-manager,并查看状态
bash 复制代码
]# systemctl daemon-reload
]# systemctl enable --now kube-controller-manager
]# systemctl status kube-controller-manager
● kube-controller-manager.service - Kubernetes Controller Manager
     Loaded: loaded (/usr/lib/systemd/system/kube-controller-manager.service; enabled; preset: disabled)
     Active: active (running) since Fri 2026-02-13 11:08:26 CST; 16s ago
 Invocation: 5c8e4181591f4a43b6f0831cb8ebd538
       Docs: https://github.com/kubernetes/kubernetes
   Main PID: 23931 (kube-controller)
      Tasks: 7 (limit: 24588)
     Memory: 17.7M (peak: 22.3M)
        CPU: 633ms
     CGroup: /system.slice/kube-controller-manager.service
             └─23931 /opt/kubernetes/bin/kubernetes/kube-controller-manager --v=2 --bind-address=0.0.0.0 --root-ca-file=/opt/kubernetes/cert/ca.pem --cluster-signing-cert-f>
.......
]# kubectl get componentstatuses
Warning: v1 ComponentStatus is deprecated in v1.19+
NAME                 STATUS      MESSAGE                                                                                        ERROR
scheduler            Unhealthy   Get "https://127.0.0.1:10259/healthz": dial tcp 127.0.0.1:10259: connect: connection refused
controller-manager   Healthy     ok
etcd-0               Healthy     ok

9.6 部署kube-schedule

  • 创建启动配置:/usr/lib/systemd/system/kube-scheduler.service
ini 复制代码
cat > /usr/lib/systemd/system/kube-scheduler.service << EOF

[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/kubernetes/kubernetes
After=network.target

[Service]
ExecStart=/opt/kubernetes/bin/kubernetes/kube-scheduler \\
      --v=2 \\
      --bind-address=127.0.0.1 \\
      --leader-elect=true \\
      --kubeconfig=/opt/kubernetes/cert/scheduler.kubeconfig

Restart=always
RestartSec=10s

[Install]
WantedBy=multi-user.target

EOF
  • 创建scheduler.kubeconfig。使用 nginx方案,-server=https://127.0.0.1:9443。在一个节点执行一次即可。
bash 复制代码
kubectl config set-cluster kubernetes \
     --certificate-authority=/opt/kubernetes/cert/ca.pem \
     --embed-certs=true \
     --server=https://127.0.0.1:9443 \
     --kubeconfig=/opt/kubernetes/cert/scheduler.kubeconfig

kubectl config set-credentials system:kube-scheduler \
     --client-certificate=/opt/kubernetes/cert/scheduler.pem \
     --client-key=/opt/kubernetes/cert/scheduler-key.pem \
     --embed-certs=true \
     --kubeconfig=/opt/kubernetes/cert/scheduler.kubeconfig

kubectl config set-context system:kube-scheduler@kubernetes \
     --cluster=kubernetes \
     --user=system:kube-scheduler \
     --kubeconfig=/opt/kubernetes/cert/scheduler.kubeconfig

kubectl config use-context system:kube-scheduler@kubernetes \
     --kubeconfig=/opt/kubernetes/cert/scheduler.kubeconfig

## 复制/opt/kubernetes/cert/scheduler.kubeconfig到其它节点
]# scp /opt/kubernetes/cert/scheduler.kubeconfig root@node50:/opt/kubernetes/cert/.
]# scp /opt/kubernetes/cert/scheduler.kubeconfig root@node51:/opt/kubernetes/cert/.
  • 启动并查看服务状态
bash 复制代码
]# systemctl daemon-reload
]# systemctl enable --now kube-scheduler
]# systemctl status kube-scheduler
● kube-scheduler.service - Kubernetes Scheduler
     Loaded: loaded (/usr/lib/systemd/system/kube-scheduler.service; enabled; preset: disabled)
     Active: active (running) since Fri 2026-02-13 11:11:33 CST; 19s ago
 Invocation: c50f3f3399fc48d3bb832a787ab58520
       Docs: https://github.com/kubernetes/kubernetes
   Main PID: 24069 (kube-scheduler)
      Tasks: 10 (limit: 24588)
     Memory: 15.5M (peak: 18M)
        CPU: 456ms
     CGroup: /system.slice/kube-scheduler.service
             └─24069 /opt/kubernetes/bin/kubernetes/kube-scheduler --v=2 --bind-address=127.0.0.1 --leader-elect=true --kubeconfig=/opt/kubernetes/cert/scheduler.kubeconfig

......
]# kubectl get componentstatuses
Warning: v1 ComponentStatus is deprecated in v1.19+
NAME                 STATUS    MESSAGE   ERROR
controller-manager   Healthy   ok
scheduler            Healthy   ok
etcd-0               Healthy   ok

9.7 配置bootstrapping

  • 创建bootstrap-kubelet.kubeconfig。使用 nginx方案,-server=https://127.0.0.1:9443。在一个节点执行一次即可。
sh 复制代码
kubectl config set-cluster kubernetes     \
--certificate-authority=/opt/kubernetes/cert/ca.pem     \
--embed-certs=true     --server=https://127.0.0.1:9443     \
--kubeconfig=/opt/kubernetes/cert/bootstrap-kubelet.kubeconfig

kubectl config set-credentials tls-bootstrap-token-user     \
--token=c55608.265fd27bb64838ca \
--kubeconfig=/opt/kubernetes/cert/bootstrap-kubelet.kubeconfig

kubectl config set-context tls-bootstrap-token-user@kubernetes     \
--cluster=kubernetes     \
--user=tls-bootstrap-token-user     \
--kubeconfig=/opt/kubernetes/cert/bootstrap-kubelet.kubeconfig

kubectl config use-context tls-bootstrap-token-user@kubernetes     \
--kubeconfig=/opt/kubernetes/cert/bootstrap-kubelet.kubeconfig

## 复制/opt/kubernetes/cert/bootstrap-kubelet.kubeconfig到其它节点
]# scp /opt/kubernetes/cert/bootstrap-kubelet.kubeconfig root@node50:/opt/kubernetes/cert/.
]# scp /opt/kubernetes/cert/bootstrap-kubelet.kubeconfig root@node51:/opt/kubernetes/cert/.

token的位置在bootstrap.secret.yaml(附:yaml文件:bootstrap.secret.yaml),如果修改的话到这个文件修改。

sh 复制代码
## 创建token。(也可以自已定义)
~]# head -c 16 /dev/urandom | od -An -t x | tr -d ' '
c55608265fd27bb64838ca186ee2f3b0
  • bootstrap.secret.yaml
sh 复制代码
## 修改:
apiVersion: v1
kind: Secret
metadata:
  name: bootstrap-token-c55608 ##修改,对应token前6位
  namespace: kube-system
type: bootstrap.kubernetes.io/token
stringData:
  description: "The default bootstrap token generated by 'kubelet '."
  token-id: c55608 ##修改,对应token前6位
  token-secret: 265fd27bb64838ca ##修改,对应token前7-22位共16个字符
  ...
yaml]# kubectl create -f bootstrap.secret.yaml
secret/bootstrap-token-c55608 created
clusterrolebinding.rbac.authorization.k8s.io/kubelet-bootstrap created
clusterrolebinding.rbac.authorization.k8s.io/node-autoapprove-bootstrap created
clusterrolebinding.rbac.authorization.k8s.io/node-autoapprove-certificate-rotation created
clusterrole.rbac.authorization.k8s.io/system:kube-apiserver-to-kubelet created
clusterrolebinding.rbac.authorization.k8s.io/system:kube-apiserver created

9.8 部署kubelet

  • 创建目录
sh 复制代码
~]# mkdir /data/kubernetes/kubelet -p   ## 要创建在数据盘下
  • 启动文件/usr/lib/systemd/system/kubelet.service。默认使用docker作为Runtime。
ini 复制代码
cat > /usr/lib/systemd/system/kubelet.service << EOF
[Unit]
Description=Kubernetes Kubelet
Documentation=https://github.com/kubernetes/kubernetes
After=cri-dockerd.service
Requires=cri-dockerd.service

[Service]
WorkingDirectory=/data/kubernetes/kubelet
ExecStart=/opt/kubernetes/bin/kubernetes/kubelet \\
  --bootstrap-kubeconfig=/opt/kubernetes/cert/bootstrap-kubelet.kubeconfig \\
  --cert-dir=/opt/kubernetes/cert \\
  --kubeconfig=/opt/kubernetes/cert/kubelet.kubeconfig \\
  --config=/opt/kubernetes/cfg/kubelet.json \\
  --container-runtime-endpoint=unix:///var/run/cri-dockerd.sock \\
  --root-dir=/data/kubernetes/kubelet \\
  --v=2
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF

/opt/kubernetes/cert/kubelet.kubeconfig为自动创建的文件,如果已存在就删除

  • 所有k8s节点创建kubelet的配置文件/opt/kubernetes/cfg/kubelet.json
json 复制代码
cat > /opt/kubernetes/cfg/kubelet.json << EOF
{
  "kind": "KubeletConfiguration",
  "apiVersion": "kubelet.config.k8s.io/v1beta1",
  "authentication": {
    "x509": {
      "clientCAFile": "/opt/kubernetes/cert/ca.pem"
    },
    "webhook": {
      "enabled": true,
      "cacheTTL": "2m0s"
    },
    "anonymous": {
      "enabled": false
    }
  },
  "authorization": {
    "mode": "Webhook",
    "webhook": {
      "cacheAuthorizedTTL": "5m0s",
      "cacheUnauthorizedTTL": "30s"
    }
  },
  "address": "192.168.26.49",
  "port": 10250,
  "readOnlyPort": 10255,
  "cgroupDriver": "systemd",                    
  "hairpinMode": "promiscuous-bridge",
  "serializeImagePulls": false,
  "clusterDomain": "cluster.local.",
  "clusterDNS": ["168.26.0.2"],
  "podInfraContainerImage": ["registry.k8s.io/pause:3.10.1"]
}
EOF

注意修改:"address": "192.168.26.49""address": "192.168.26.50""address": "192.168.26.51"

  • 启动
bash 复制代码
~]# systemctl daemon-reload
~]# systemctl enable --now kubelet
~]# systemctl status kubelet
● kubelet.service - Kubernetes Kubelet
     Loaded: loaded (/usr/lib/systemd/system/kubelet.service; enabled; preset: disabled)
     Active: active (running) since Fri 2026-02-13 12:02:16 CST; 15s ago
 Invocation: 3325f05bbfd74862988a4a3e6434baa3
       Docs: https://github.com/kubernetes/kubernetes
   Main PID: 27630 (kubelet)
      Tasks: 13 (limit: 24588)
     Memory: 25.6M (peak: 27.5M)
        CPU: 619ms
     CGroup: /system.slice/kubelet.service
             └─27630 /opt/kubernetes/bin/kubernetes/kubelet --bootstrap-kubeconfig=/opt/kubernetes/cert/bootstrap-kubelet.kubeconfig --cert-dir=/opt/kubernetes/cert --kubec>
......
sh 复制代码
]#  kubectl get nodes -o wide
NAME     STATUS     ROLES    AGE   VERSION   INTERNAL-IP     EXTERNAL-IP   OS-IMAGE                       KERNEL-VERSION                CONTAINER-RUNTIME
node49   NotReady   <none>   75s   v1.35.1   192.168.26.49   <none>        AlmaLinux 10.0 (Purple Lion)   6.12.0-55.9.1.el10_0.x86_64   docker://29.2.1
node50   NotReady   <none>   75s   v1.35.1   192.168.26.50   <none>        AlmaLinux 10.0 (Purple Lion)   6.12.0-55.9.1.el10_0.x86_64   docker://29.2.1
node51   NotReady   <none>   76s   v1.35.1   192.168.26.51   <none>        AlmaLinux 10.0 (Purple Lion)   6.12.0-55.9.1.el10_0.x86_64   docker://29.2.1
sh 复制代码
## 查看kubelet证书请求
~]# kubectl get csr
...kubec					

## 如果处于Pending状态,则批准申请
~]# kubectl certificate approve node-csr-......

如果node仍然是NotReady,则需要部署cni插件

sh 复制代码
~]# kubectl get nodes
NAME     STATUS     ROLES    AGE    VERSION
node49   NotReady   <none>   125m   v1.35.1
node50   NotReady   <none>   125m   v1.35.1
node51   NotReady   <none>   125m   v1.35.1

9.9 部署kube-proxy

  • 创建kube-proxy.kubeconfig。使用 nginx方案,-server=https://127.0.0.1:9443。在一个节点执行一次即可。
sh 复制代码
]# kubectl config set-cluster kubernetes     \
  --certificate-authority=/opt/kubernetes/cert/ca.pem     \
  --embed-certs=true     \
  --server=https://127.0.0.1:9443     \
  --kubeconfig=/opt/kubernetes/cert/kube-proxy.kubeconfig

]# kubectl config set-credentials kube-proxy  \
  --client-certificate=/opt/kubernetes/cert/kube-proxy.pem     \
  --client-key=/opt/kubernetes/cert/kube-proxy-key.pem     \
  --embed-certs=true     \
  --kubeconfig=/opt/kubernetes/cert/kube-proxy.kubeconfig

]# kubectl config set-context kube-proxy@kubernetes    \
  --cluster=kubernetes     \
  --user=kube-proxy     \
  --kubeconfig=/opt/kubernetes/cert/kube-proxy.kubeconfig

]# kubectl config use-context kube-proxy@kubernetes --kubeconfig=/opt/kubernetes/cert/kube-proxy.kubeconfig

## 复制/opt/kubernetes/cert/kube-proxy.kubeconfig到各节点
]# scp /opt/kubernetes/cert/kube-proxy.kubeconfig root@node50:/opt/kubernetes/cert/.
]# scp /opt/kubernetes/cert/kube-proxy.kubeconfig root@node51:/opt/kubernetes/cert/.
  • 所有k8s节点添加kube-proxy的service文件
ini 复制代码
cat >  /usr/lib/systemd/system/kube-proxy.service << EOF
[Unit]
Description=Kubernetes Kube Proxy
Documentation=https://github.com/kubernetes/kubernetes
After=network.target

[Service]
ExecStart=/opt/kubernetes/bin/kubernetes/kube-proxy \\
  --config=/opt/kubernetes/cfg/kube-proxy.yaml \\
  --v=2

Restart=always
RestartSec=10s

[Install]
WantedBy=multi-user.target

EOF
  • 所有k8s节点添加kube-proxy的配置
yaml 复制代码
cat > /opt/kubernetes/cfg/kube-proxy.yaml << EOF
apiVersion: kubeproxy.config.k8s.io/v1alpha1
bindAddress: 0.0.0.0
clientConnection:
  acceptContentTypes: ""
  burst: 10
  contentType: application/vnd.kubernetes.protobuf
  kubeconfig: /opt/kubernetes/cert/kube-proxy.kubeconfig
  qps: 5
clusterCIDR: 10.26.0.0/16
configSyncPeriod: 15m0s
conntrack:
  max: null
  maxPerCore: 32768
  min: 131072
  tcpCloseWaitTimeout: 1h0m0s
  tcpEstablishedTimeout: 24h0m0s
enableProfiling: false
healthzBindAddress: 0.0.0.0:10256
hostnameOverride: ""
iptables:
  masqueradeAll: false
  masqueradeBit: 14
  minSyncPeriod: 0s
  syncPeriod: 30s
ipvs:
  masqueradeAll: true
  minSyncPeriod: 5s
  scheduler: "rr"
  syncPeriod: 30s
kind: KubeProxyConfiguration
metricsBindAddress: 127.0.0.1:10249
mode: "ipvs"
nodePortAddresses: null
oomScoreAdj: -999
portRange: ""
udpIdleTimeout: 250ms

EOF
  • 启动
sh 复制代码
]# systemctl daemon-reload
]# systemctl enable --now kube-proxy
]# systemctl status kube-proxy
● kube-proxy.service - Kubernetes Kube Proxy
     Loaded: loaded (/usr/lib/systemd/system/kube-proxy.service; enabled; preset: disabled)
     Active: active (running) since Fri 2026-02-13 14:12:49 CST; 19s ago
 Invocation: 4c152a893f3a4ffebafb5e419a07fe65
       Docs: https://github.com/kubernetes/kubernetes
   Main PID: 29346 (kube-proxy)
      Tasks: 7 (limit: 24588)
     Memory: 16.1M (peak: 18M)
        CPU: 1.047s
     CGroup: /system.slice/kube-proxy.service
             └─29346 /opt/kubernetes/bin/kubernetes/kube-proxy --config=/opt/kubernetes/cfg/kube-proxy.yaml --v=2
......

10、k8s核心插件

10.1 部署Calico CNI网络插件装

sh 复制代码
- name: CALICO_IPV4POOL_CIDR
  value: "10.26.0.0/16"
  • 拉取镜像
sh 复制代码
app]# grep image calico.yaml
          image: quay.io/calico/cni:v3.31.3
          imagePullPolicy: IfNotPresent
          image: quay.io/calico/cni:v3.31.3
          imagePullPolicy: IfNotPresent
          image: quay.io/calico/node:v3.31.3
          imagePullPolicy: IfNotPresent
          image: quay.io/calico/node:v3.31.3
          imagePullPolicy: IfNotPresent
          image: quay.io/calico/kube-controllers:v3.31.3
          imagePullPolicy: IfNotPresent
## 拉取镜像
]# docker pull quay.io/calico/cni:v3.31.3
]# docker pull quay.io/calico/node:v3.31.3
]# docker pull quay.io/calico/kube-controllers:v3.31.3
  • 创建 calico 组件
sh 复制代码
app]# kubectl apply -f /opt/kubernetes/app/src/calico.yaml
...

在 CNI网络插件成功运行之后,各个pod的状态均会更新为"running":

shell 复制代码
]# kubectl get pod -A
NAMESPACE     NAME                                       READY   STATUS    RESTARTS   AGE
kube-system   calico-kube-controllers-565c89d6df-fwdvp   1/1     Running   0          75s
kube-system   calico-node-4vzrl                          1/1     Running   0          75s
kube-system   calico-node-p5f94                          1/1     Running   0          75s
kube-system   calico-node-zskjs                          1/1     Running   0          75s
  • 查看节点状态
sh 复制代码
~]# kubectl get nodes
NAME     STATUS   ROLES    AGE    VERSION
node49   Ready    <none>   156m   v1.35.1
node50   Ready    <none>   156m   v1.35.1
node51   Ready    <none>   156m   v1.35.1

10.2 部署服务发现插件CoreDNS

sh 复制代码
src]# cp coredns.yaml.base coredns.yaml
 ## 修改以下内容:
 __DNS__DOMAIN__  改为:  cluster.local
 __DNS__MEMORY__LIMIT__ 改为: 170Mi
 __DNS__SERVER__ 改为: 168.26.0.2
 image: registry.k8s.io/coredns/coredns:v1.13.1 
 imagePullPolicy: IfNotPresent
  • 获取取镜像,执行:
sh 复制代码
## 拉取镜像
]# docker pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/registry.k8s.io/coredns/coredns:v1.13.1 
]# docker tag swr.cn-north-4.myhuaweicloud.com/ddn-k8s/registry.k8s.io/coredns/coredns:v1.13.1 registry.k8s.io/coredns/coredns:v1.13.1
]# docker rmi swr.cn-north-4.myhuaweicloud.com/ddn-k8s/registry.k8s.io/coredns/coredns:v1.13.1

src]# kubectl apply -f coredns.yaml
serviceaccount/coredns created
clusterrole.rbac.authorization.k8s.io/system:coredns created
clusterrolebinding.rbac.authorization.k8s.io/system:coredns created
configmap/coredns created
deployment.apps/coredns created
service/kube-dns created

]# kubectl get pod -A -o wide | grep coredns
kube-system   coredns-5c44b89985-fvm4n                   1/1     Running   0          16s   10.26.227.65    node51   <none>           <none>

10.3 部署资源监控插件Metrics-server

Kubernetes中系统资源的采集均使用Metrics-server,通过Metrics采集节点和Pod的内存、磁盘、CPU和网络的使用率。

yaml 复制代码
yaml]# vi components.yaml
# 1
        - --cert-dir=/tmp
        - --secure-port=10250
        - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
        - --kubelet-use-node-status-port
        - --metric-resolution=15s
        - --kubelet-insecure-tls
        - --requestheader-client-ca-file=/opt/kubernetes/cert/front-proxy-ca.pem
        - --requestheader-username-headers=X-Remote-User
        - --requestheader-group-headers=X-Remote-Group
        - --requestheader-extra-headers-prefix=X-Remote-Extra-
# 2
        volumeMounts:
        - mountPath: /tmp
          name: tmp-dir
        - name: ca-ssl
          mountPath: /opt/kubernetes/cert
# 3
      volumes:
      - emptyDir: {}
        name: tmp-dir
      - name: ca-ssl
        hostPath:
          path: /opt/kubernetes/cert
# 4 修改为image镜像
image: registry.aliyuncs.com/google_containers/metrics-server:v0.8.1
  • 拉取镜像、执行、排错、验证
bash 复制代码
]# docker pull registry.aliyuncs.com/google_containers/metrics-server:v0.8.1
src]# kubectl apply -f components.yaml
serviceaccount/metrics-server created
clusterrole.rbac.authorization.k8s.io/system:aggregated-metrics-reader created
clusterrole.rbac.authorization.k8s.io/system:metrics-server created
rolebinding.rbac.authorization.k8s.io/metrics-server-auth-reader created
clusterrolebinding.rbac.authorization.k8s.io/metrics-server:system:auth-delegator created
clusterrolebinding.rbac.authorization.k8s.io/system:metrics-server created
service/metrics-server created
deployment.apps/metrics-server created
apiservice.apiregistration.k8s.io/v1beta1.metrics.k8s.io created

]# kubectl get pod -n kube-system -owide | grep metrics
metrics-server-769555f4b-hskmg             1/1     Running   0          29s   10.26.113.1     node50   <none>           <none>

]# kubectl top node
NAME     CPU(cores)   CPU(%)   MEMORY(bytes)   MEMORY(%)
node49   154m         3%       1001Mi          26%
node50   152m         3%       1128Mi          29%
node51   121m         3%       1073Mi          28%
]# kubectl top pod -A
NAMESPACE     NAME                                       CPU(cores)   MEMORY(bytes)
kube-system   calico-kube-controllers-565c89d6df-fwdvp   5m           44Mi
kube-system   calico-node-4vzrl                          25m          188Mi
kube-system   calico-node-p5f94                          21m          198Mi
kube-system   calico-node-zskjs                          22m          187Mi
kube-system   coredns-5c44b89985-fvm4n                   2m           14Mi
kube-system   metrics-server-769555f4b-hskmg             3m           21Mi
  • 节点标签
sh 复制代码
kubectl label nodes node49  node-role.kubernetes.io/master=
kubectl label nodes node50  node-role.kubernetes.io/master=
kubectl label nodes node51  node-role.kubernetes.io/master=

kubectl label nodes node49  node-role.kubernetes.io/worker=
kubectl label nodes node50  node-role.kubernetes.io/worker=
kubectl label nodes node51  node-role.kubernetes.io/worker=

]# kubectl get nodes
NAME     STATUS   ROLES           AGE    VERSION
node49   Ready    master,worker   3h1m   v1.35.1
node50   Ready    master,worker   3h1m   v1.35.1
node51   Ready    master,worker   3h1m   v1.35.1

11、扩充/新增worker节点

  • 执行01:4.1创建部署目录

  • 执行02:5 安装docker

  • 执行03:6 安装cri-dockerd

  • 执行04:9.1 准备

  • 执行05:9.2 nginx高可用方案

  • 执行06:9.8 部署kubelet

  • 执行07:9.9 部署kube-proxy

12、从v1.35.1升级到v1.35.x

以v1.35.x(x > 1)为例。

sh 复制代码
## 解压、移动到指定位置
src]# tar -zxvf kubernetes-server-linux-arm64-v1.35.x.tar.gz
src]# mv kubernetes/server/bin /opt/kubernetes/bin/kubernetes-v1.35.x
## 删除多余文件
src]# rm -rf kubernetes
src]# rm -rf /opt/kubernetes/bin/kubernetes-v1.35.x/{*.tar,*_tag}
src]# rm -rf /opt/kubernetes/bin/kubernetes-v1.35./{apiextensions-apiserver,kube-aggregator,kubectl-convert,kube-log-runner,mounter}
src]# ll /opt/kubernetes/bin/kubernetes-v1.35.x
## node节点删除:
src]# rm -rf /opt/kubernetes/bin/kubernetes-v1.35.x/{kube-apiserver,kube-controller-manager,kube-scheduler}
## 停止服务,worker节点只需要停止kube-proxy、kubelet
systemctl stop kube-proxy
systemctl stop kubelet

systemctl stop kube-scheduler
systemctl stop kube-controller-manager
systemctl stop kube-apiserver
## 删除链接
rm -rf /opt/kubernetes/bin/kubernetes
rm -rf /usr/local/bin/kubectl
## 链接到新地址
ln -s /opt/kubernetes/bin/kubernetes-v1.35.x /opt/kubernetes/bin/kubernetes
ln -s /opt/kubernetes/bin/kubernetes-v1.35.x/kubectl /usr/local/bin/kubectl
## 检查版本
/opt/kubernetes/bin/kubernetes/kubelet --version
## 启动服务
systemctl start kube-apiserver
systemctl status kube-apiserver

systemctl start kube-controller-manager
systemctl status kube-controller-manager

systemctl start kube-scheduler
systemctl status kube-scheduler
## worker节点只需要启动kube-proxy、kubelet
systemctl start kube-proxy
systemctl status kube-proxy

systemctl start kubelet
systemctl status kubelet
## 查看节点
]# kubectl get nodes -owide

13、集群验证与总结

13.1 部署pod验证

]# vi busybox.yaml

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: busybox
  namespace: default
spec:
  containers:
  - name: busybox
    image: docker.io/library/busybox:1.28
    imagePullPolicy: IfNotPresent
    command:
      - sleep
      - "3600"
    imagePullPolicy: IfNotPresent
  restartPolicy: Always
sh 复制代码
]# kubectl apply -f busybox.yaml
pod/busybox created
]# kubectl  get pod -owide
NNAME      READY   STATUS    RESTARTS   AGE   IP             NODE     NOMINATED NODE   READINESS GATES
busybox   1/1     Running   0          12s   10.26.227.66   node51   <none>           <none>

13.2 部署service验证

yaml 复制代码
cat >  nginx.yaml  << "EOF"
---
apiVersion: v1
kind: ReplicationController
metadata:
  name: nginx-web
spec:
  replicas: 2
  selector:
    name: nginx
  template:
    metadata:
      labels:
        name: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.19.6
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service-nodeport
spec:
  ports:
    - port: 80
      targetPort: 80
      nodePort: 30001
      protocol: TCP
  type: NodePort
  selector:
    name: nginx
EOF
sh 复制代码
]# kubectl apply -f nginx.yaml
]# kubectl get pods -o wide
NAME              READY   STATUS    RESTARTS   AGE   IP             NODE     NOMINATED NODE   READINESS GATES
busybox           1/1     Running   0          57s   10.26.227.66   node51   <none>           <none>
nginx-web-fdh85   1/1     Running   0          7s    10.26.68.2     node49   <none>           <none>
nginx-web-pfrh5   1/1     Running   0          7s    10.26.113.2    node50   <none>           <none>
## 要拉取镜像,需要等一会(提前准备镜像)
]# kubectl get all
NNAME                  READY   STATUS    RESTARTS   AGE
pod/busybox           1/1     Running   0          2m45s
pod/nginx-web-fdh85   1/1     Running   0          115s
pod/nginx-web-pfrh5   1/1     Running   0          115s

NAME                              DESIRED   CURRENT   READY   AGE
replicationcontroller/nginx-web   2         2         2       115s

NAME                             TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
service/kubernetes               ClusterIP   168.26.0.1       <none>        443/TCP        4h36m
service/nginx-service-nodeport   NodePort    168.26.217.116   <none>        80:30001/TCP   115s
]# kubectl get service
NAME                     TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes               ClusterIP   168.26.0.1       <none>        443/TCP        4h37m
nginx-service-nodeport   NodePort    168.26.217.116   <none>        80:30001/TCP   2m26s

访问:http://node50:30001/ 或在浏览器:http://192.168.26.50:30001/

sh 复制代码
]# curl -I http://node50:30001
HTTP/1.1 200 OK
Server: nginx/1.19.6
Date: Fri, 13 Feb 2026 07:36:48 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 15 Dec 2020 13:59:38 GMT
Connection: keep-alive
ETag: "5fd8c14a-264"
Accept-Ranges: bytes

13.3 创建3个副本在不同的节点上

yaml 复制代码
cat > nginx-deployment.yaml << EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80

EOF
sh 复制代码
]# kubectl apply -f nginx-deployment.yaml
deployment.apps/nginx-deployment created
]# kubectl get pod -owide |grep nginx-deployment
nginx-deployment-5bdd6668bd-2l7wf   1/1     Running   0          10s     10.26.113.3    node50   <none>           <none>
nginx-deployment-5bdd6668bd-vr6xn   1/1     Running   0          10s     10.26.227.67   node51   <none>           <none>
nginx-deployment-5bdd6668bd-xwkk6   1/1     Running   0          10s     10.26.68.3     node49   <none>           <none>
]# kubectl delete -f nginx-deployment.yaml

13.4 用pod解析默认命名空间中的kubernetes

bash 复制代码
]# kubectl get svc
NAME                     TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes               ClusterIP   168.26.0.1       <none>        443/TCP        4h40m
nginx-service-nodeport   NodePort    168.26.217.116   <none>        80:30001/TCP   5m54s

]# kubectl exec busybox -n default -- nslookup kubernetes
Server:    168.26.0.2
Address 1: 168.26.0.2 kube-dns.kube-system.svc.cluster.local

Name:      kubernetes
Address 1: 168.26.0.1 kubernetes.default.svc.cluster.local

13.5 测试跨命名空间是否可以解析

bash 复制代码
]# kubectl exec busybox -n default -- nslookup kube-dns.kube-system
Server:    168.26.0.2
Address 1: 168.26.0.2 kube-dns.kube-system.svc.cluster.local

Name:      kube-dns.kube-system
Address 1: 168.26.0.2 kube-dns.kube-system.svc.cluster.local

13.6 每个节点都必须要能访问Kubernetes的kubernetes svc 443和kube-dns的service 53

bash 复制代码
]# kubectl get svc -A
NAMESPACE     NAME                     TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                  AGE
default       kubernetes               ClusterIP   168.26.0.1       <none>        443/TCP                  4h42m
default       nginx-service-nodeport   NodePort    168.26.217.116   <none>        80:30001/TCP             7m19s
kube-system   kube-dns                 ClusterIP   168.26.0.2       <none>        53/UDP,53/TCP,9153/TCP   53m
kube-system   metrics-server           ClusterIP   168.26.191.18    <none>        443/TCP                  43m

~]# telnet 168.26.0.1 443
Trying 168.26.0.1...
Connected to 168.26.0.1.
Escape character is '^]'.

~]# telnet 168.26.0.2 53
Trying 168.26.0.2...
Connected to 168.26.0.2.
Escape character is '^]'.

~]# curl 168.26.0.1:443
Client sent an HTTP request to an HTTPS server.

~]# curl 168.26.0.2:53
curl: (52) Empty reply from server

13.7 Pod和其它主机及Pod之间能通

bash 复制代码
~]# kubectl get po -owide -A
NAMESPACE     NAME                                       READY   STATUS    RESTARTS        AGE    IP              NODE     NOMINATED NODE   READINESS GATES
default       busybox                                    1/1     Running   1 (2m56s ago)   62m    10.26.227.69    node51   <none>           <none>
default       nginx-web-fdh85                            1/1     Running   1 (3m49s ago)   61m    10.26.68.5      node49   <none>           <none>
default       nginx-web-pfrh5                            1/1     Running   1 (3m28s ago)   61m    10.26.113.5     node50   <none>           <none>
kube-system   calico-kube-controllers-565c89d6df-fwdvp   1/1     Running   5 (3m49s ago)   118m   10.26.68.4      node49   <none>           <none>
kube-system   calico-node-4vzrl                          1/1     Running   2 (32m ago)     118m   192.168.26.51   node51   <none>           <none>
kube-system   calico-node-p5f94                          1/1     Running   2 (23m ago)     118m   192.168.26.49   node49   <none>           <none>
kube-system   calico-node-zskjs                          1/1     Running   3 (3m10s ago)   118m   192.168.26.50   node50   <none>           <none>
kube-system   coredns-5c44b89985-fvm4n                   1/1     Running   1 (2m56s ago)   107m   10.26.227.68    node51   <none>           <none>
kube-system   metrics-server-769555f4b-hskmg             1/1     Running   1 (3m28s ago)   97m    10.26.113.4     node50   <none>           <none>

进入pod/busybox ping其他节点上的pod。可以连通证明这个pod是可以跨命名空间和跨主机通信的。

bash 复制代码
## 【POD - 跨主机】主机node51上的pod/busybox ping主机node49、node50
node51 ~]# kubectl exec -ti busybox -- ping 192.168.26.49 -c 2
PING 192.168.26.49 (192.168.26.49): 56 data bytes
64 bytes from 192.168.26.49: seq=0 ttl=63 time=0.423 ms
64 bytes from 192.168.26.49: seq=1 ttl=63 time=0.602 ms

--- 192.168.26.49 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.423/0.512/0.602 ms

node51 ~]# kubectl exec -ti busybox -- ping 192.168.26.50 -c 2
PING 192.168.26.50 (192.168.26.50): 56 data bytes
64 bytes from 192.168.26.50: seq=0 ttl=63 time=0.584 ms
64 bytes from 192.168.26.50: seq=1 ttl=63 time=0.383 ms

--- 192.168.26.50 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.383/0.483/0.584 ms

## 【跨主机、跨命名空间POD - POD】主机node51上的pod/busybox ping主机node49、node51等节点上的pod
node51 ~]# kubectl exec -ti busybox -- ping 10.26.68.5 -c 2
PING 10.26.68.5 (10.26.68.5): 56 data bytes
64 bytes from 10.26.68.5: seq=0 ttl=62 time=0.761 ms
64 bytes from 10.26.68.5: seq=1 ttl=62 time=0.586 ms

--- 10.26.68.5 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.586/0.673/0.761 ms

node51 ~]# kubectl exec -ti busybox -- ping 10.26.113.5 -c 2
PING 10.26.113.5 (10.26.113.5): 56 data bytes
64 bytes from 10.26.113.5: seq=0 ttl=62 time=0.766 ms
64 bytes from 10.26.113.5: seq=1 ttl=62 time=0.417 ms

--- 10.26.113.5 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.417/0.591/0.766 ms

node51 ~]# kubectl exec -ti busybox -- ping 192.168.26.51 -c 2
PING 192.168.26.51 (192.168.26.51): 56 data bytes
64 bytes from 192.168.26.51: seq=0 ttl=64 time=0.129 ms
64 bytes from 192.168.26.51: seq=1 ttl=64 time=0.088 ms

--- 192.168.26.51 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.088/0.108/0.129 ms

至此,成功以二进制方式部署etcd3.6.7 + Kubernetes1.35.1 + docker29.2.1高可用集群。

sh 复制代码
]# kubectl get nodes -owide
NAME     STATUS   ROLES           AGE     VERSION   INTERNAL-IP     EXTERNAL-IP   OS-IMAGE                       KERNEL-VERSION                CONTAINER-RUNTIME
node49   Ready    master,worker   4h40m   v1.35.1   192.168.26.49   <none>        AlmaLinux 10.0 (Purple Lion)   6.12.0-55.9.1.el10_0.x86_64   docker://29.2.1
node50   Ready    master,worker   4h40m   v1.35.1   192.168.26.50   <none>        AlmaLinux 10.0 (Purple Lion)   6.12.0-55.9.1.el10_0.x86_64   docker://29.2.1
node51   Ready    master,worker   4h40m   v1.35.1   192.168.26.51   <none>        AlmaLinux 10.0 (Purple Lion)   6.12.0-55.9.1.el10_0.x86_64   docker://29.2.1

14、kubectl-ai安装及使用

AI驱动的Kubernetes管理:kubectl-ai 简化云原生运维

下载:https://github.com/GoogleCloudPlatform/kubectl-ai/releases/download/v0.0.29/kubectl-ai_Linux_x86_64.tar.gz

sh 复制代码
src]# tar -zxvf kubectl-ai_Linux_x86_64.tar.gz
src]# ll kubectl-ai
-rwxr-xr-x 1 1001 1001 73994424 Jan 22 01:02 kubectl-ai
## chmod a+x kubectl-ai
src]# ./kubectl-ai version
version: 0.0.29
commit: 38382d1add89a0c0825bed997d2257733c08b330
date: 2026-01-21T16:57:34Z
src]# mv kubectl-ai /usr/local/bin/
  • 配置
sh 复制代码
## 使用deepseek,需要先充值(最少10元),然后创建API keys:https://platform.deepseek.com/api_keys
export OPENAI_API_KEY=
export OPENAI_ENDPOINT=https://api.deepseek.com
kubectl-ai --llm-provider=openai --model=deepseek-chat

## 使用阿里云百炼平台进行免费体验
## 创建API Key:https://www.aliyun.com/product/bailian
export OPENAI_API_KEY=sk****8710
export OPENAI_ENDPOINT=https://dashscope.aliyuncs.com/compatible-mode/v1
kubectl-ai --llm-provider=openai --model=deepseek-v3.2  ## 不一定每个模型可用,选一个可用的就行
  • 请帮我查看当前Kubernetes集群的节点状态
ini 复制代码
[root@node49 src]# kubectl-ai --llm-provider=openai --model=deepseek-v3.2

  Hey there, what can I help you with today?

>>> 请帮我查看当前Kubernetes集群的节点状态

  我来帮您查看当前Kubernetes集群的节点状态。让我使用kubectl命令来获取节点信息。


  Running: kubectl get nodes

  现在让我获取更详细的节点信息,包括CPU、内存、Taints等:


  Running: kubectl get nodes -o wide

  让我再查看每个节点的详细资源和调度信息:



  The following commands require your approval to run:

  • kubectl describe nodes | grep -A 10 "Name:|Allocatable:|Capacity:|Taints:"

  Do you want to proceed ?


  1. Yes
  2. Yes, and don't ask me again
  3. No

Enter your choice: 2

  Running: kubectl describe nodes | grep -A 10 "Name:\|Allocatable:\|Capacity:\|Taints:"

  最后,让我查看当前节点的资源使用情况:


  Running: kubectl top nodes

  根据查询结果,以下是当前Kubernetes集群的节点状态汇总:

  ## 📊 集群节点状态

  ### 节点概览

  集群共有 3个节点,全部状态正常(Ready):

   节点名称     │ 状态         │ 角色          │ 运行时间     │ 版本
  ──────────────┼──────────────┼───────────────┼──────────────┼─────────────
   node49       │ ✅ Ready     │ master,worker │ 22h          │ v1.35.1
   node50       │ ✅ Ready     │ master,worker │ 22h          │ v1.35.1
   node51       │ ✅ Ready     │ master,worker │ 22h          │ v1.35.1

  ### 系统信息

  • 操作系统: AlmaLinux 10.0 (Purple Lion)
  • 内核版本: 6.12.0-55.9.1.el10_0.x86_64
  • 容器运行时: docker://29.2.1
  • 网络插件: Calico(Calico is running on this node)

  ### 节点资源配置

  每个节点具有相同配置:

  • CPU: 4核
  • 内存: 约3.8GB(3866-3866Mi可用)
  • 存储: 约46GB临时存储(43.4GB可用)
  • Pods容量: 110个Pod

  ### 资源使用情况(实时)

   节点         │ CPU使用      │ CPU百分比    │ 内存使用     │ 内存百分比
  ──────────────┼──────────────┼──────────────┼──────────────┼──────────────
   node49       │ 181m         │ 4%           │ 1764Mi       │ 46%
   node50       │ 120m         │ 3%           │ 1683Mi       │ 44%
   node51       │ 106m         │ 2%           │ 1624Mi       │ 43%

  ### 关键信息

  1. 集群状态: ✅ 健康 - 所有节点Ready状态
  2. 架构: 高可用架构 - 3个节点都是master+worker角色
  3. 资源: 负载较低,有充足的CPU和内存资源可用
  4. 污点: 无(无Taints),所有节点均可调度Pod
  5. 网络: Calico网络正常运行
  6. 调度: 所有节点均可调度(Unschedulable: false)

  您的Kubernetes集群运行状态非常良好!🎉
  所有节点都正常在线,资源利用率合理,集群健康状况优秀。

>>>
  • 使用已有镜像nginx:latest,请帮我在当前k8s集群中部署nginx应用,使用标准清单文件
ini 复制代码
[root@node49 src]# kubectl-ai --llm-provider=openai --model=deepseek-v3.2

  Hey there, what can I help you with today?

>>> 使用已有镜像nginx:latest,请帮我在当前k8s集群中部署nginx应用,使用标准清单文件

  我来帮您在K8s集群中部署nginx应用。首先,让我检查当前集群的状态和可用的资源。


  Running: kubectl get namespaces

  Running: kubectl get nodes

  Running: kubectl get storageclass

  Running: kubectl get pods --all-namespaces

  我注意到default命名空间中已经有名为 nginx-web
  的pod在运行。我需要先确认一下这些现有nginx部署的详细信息,然后为您创建一个新的部署。让我检查一下现有的nginx资源:


  Running: kubectl get deployments

  Running: kubectl get replicasets

  Running: kubectl get services

  我看到集群中已经有nginx服务和pod运行。现在我需要了解您的具体需求。根据您的要求,我将使用镜像
  nginx:latest 创建一个标准的nginx部署。

  需要向您确认几个重要信息:

  1. 部署到哪个命名空间? 我看到现有的nginx部署在 default 命名空间,您希望:
    • 在 default 命名空间创建新的nginx部署
    • 在全新的命名空间中创建
  2. 部署名称是什么? 由于已有 nginx-web 的pod,我可以使用不同的名称如 nginx-
  deployment
  3. 副本数量是多少? 标准部署通常使用2-3个副本
  4. 服务暴露方式是什么? 您希望:
    • ClusterIP(仅集群内部访问)
    • NodePort(通过节点端口访问)
    • LoadBalancer(如果云提供商支持)
  5. 需要持久化存储吗?
  nginx通常不需要持久化存储,但如果您需要存储配置文件,请告诉我
  6. 需要配置自定义nginx配置文件吗?

  部署方案总结:
  基于已有信息,我计划:

  • 镜像: nginx:latest
  • 命名空间:default(除非您指定其他)
  • 部署名称:nginx-deployment
  • 副本数:2
  • 服务类型:NodePort(端口30080)
  • 不需要持久化存储

  请确认这些配置,或者告诉我您的具体需求!

>>> 就使用这些配置进行部署

  好的!我将按照确认的配置为您部署nginx应用:

  部署配置确认:

  • 镜像: nginx:latest
  • 命名空间:default
  • 部署名称:nginx-deployment
  • 副本数:2
  • 服务类型:NodePort(端口30080)
  • 不需要持久化存储

  现在开始创建标准的Kubernetes清单文件并部署:



  The following commands require your approval to run:

  • cat > nginx-deployment.yaml << 'EOF'
  apiVersion: apps/v1
  kind: Deployment
  metadata:
  name: nginx-deployment
  namespace: default
  labels:
  app: nginx
  spec:
  replicas: 2
  selector:
  matchLabels:
  app: nginx
  template:
  metadata:
  labels:
  app: nginx
  spec:
  containers:
  - name: nginx
  image: nginx:latest
  imagePullPolicy: IfNotPresent
  ports:
  - containerPort: 80
  resources:
  requests:
  memory: "64Mi"
  cpu: "100m"
  limits:
  memory: "128Mi"
  cpu: "200m"

  --------

  apiVersion: v1
  kind: Service
  metadata:
  name: nginx-service-deployment
  namespace: default
  spec:
  type: NodePort
  selector:
  app: nginx
  ports:
  - port: 80
  targetPort: 80
  nodePort: 30080
  EOF

  Do you want to proceed ?


  1. Yes
  2. Yes, and don't ask me again
  3. No

Enter your choice: 2

  Running: cat > nginx-deployment.yaml << 'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  namespace: default
  labels:
    app: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
        resources:
          requests:
            memory: "64Mi"
            cpu: "100m"
          limits:
            memory: "128Mi"
            cpu: "200m"
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service-deployment
  namespace: default
spec:
  type: NodePort
  selector:
    app: nginx
  ports:
    - port: 80
      targetPort: 80
      nodePort: 30080
EOF

  现在使用kubectl apply命令部署nginx应用:


  Running: kubectl apply -f nginx-deployment.yaml

  很好!nginx应用已经成功部署。现在让我验证部署状态:


  Running: kubectl get deployment nginx-deployment

  Running: kubectl get pods -l app=nginx

  Running: kubectl get service nginx-service-deployment

  完美!🎉 nginx应用已经成功部署。让我检查一下pod的详细状态,确保一切正常:


  Running: kubectl describe deployment nginx-deployment

  Running: kubectl describe service nginx-service-deployment

  让我验证nginx服务是否可以正常访问:


  Running: kubectl get nodes -o wide

  现在让我测试nginx服务的访问:

  interactive mode not supported for kubectl, please use non-interactive commands

  让我使用非交互方式测试nginx服务:


  Running: kubectl exec nginx-deployment-77c4bd56fd-6sccw -- curl -s -o /dev/null -w "%{http_code}" http://localhost:80

  nginx容器中没有curl命令,让我使用wget或直接检查pod状态:


  Running: kubectl logs nginx-deployment-77c4bd56fd-6sccw --tail=5

  完美!nginx服务正在正常运行。让我查看完整的部署清单文件内容:


  Running: cat nginx-deployment.yaml

  ## ✅ 部署完成!

  ### 部署总结:

  1. 部署资源已创建:
    • Deployment:  nginx-deployment  (副本数: 2)
    • Service:  nginx-service-deployment  (类型: NodePort)
  2. 部署状态:
    • ✅ 2个Pod全部正常运行: nginx-deployment-77c4bd56fd-6sccw  和  nginx-
    deployment-77c4bd56fd-qpkqc
    • ✅ 服务已暴露:NodePort 30080
  3. 访问方式:
    • 集群内部访问: http://nginx-service-deployment.default.svc.cluster.
    local:80
    • 外部访问(通过任意节点): http://<节点IP>:30080
      • 节点IP: 192.168.26.49, 192.168.26.50, 192.168.26.51
    • 示例: http://192.168.26.49:30080
  4. 资源配置:
    • CPU请求/限制:100m/200m
    • 内存请求/限制:64Mi/128Mi
    • 镜像:nginx:latest
  5. 清单文件: 已保存为  nginx-deployment.yaml

  ### 测试访问:

  您可以通过以下方式验证服务:

  1. 在集群内部: curl http://nginx-service-deployment
  2. 从外部:访问任意节点的30080端口

  ### 管理命令:

    # 查看部署状态
    kubectl get deployment nginx-deployment

    # 查看pod状态
    kubectl get pods -l app=nginx

    # 查看服务
    kubectl get service nginx-service-deployment

    # 查看日志
    kubectl logs -l app=nginx --tail=10

    # 扩展副本数
    kubectl scale deployment nginx-deployment --replicas=3

    # 删除部署
    kubectl delete -f nginx-deployment.yaml

  nginx应用已成功部署并运行!🚀

>>>
sh 复制代码
[root@node50 ~]# kubectl get deployment
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   2/2     2            2           7m7s
[root@node50 ~]# kubectl get pod
NAME                                READY   STATUS    RESTARTS       AGE
busybox                             1/1     Running   3 (42m ago)    19h
nginx-deployment-77c4bd56fd-6sccw   1/1     Running   0              3m24s
nginx-deployment-77c4bd56fd-qpkqc   1/1     Running   0              3m24s
nginx-web-fdh85                     1/1     Running   2 (102m ago)   19h
nginx-web-pfrh5                     1/1     Running   2 (102m ago)   19h
[root@node50 ~]# kubectl get svc
NAME                       TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes                 ClusterIP   168.26.0.1       <none>        443/TCP        24h
nginx-service-deployment   NodePort    168.26.213.219   <none>        80:30080/TCP   3m30s
nginx-service-nodeport     NodePort    168.26.217.116   <none>        80:30001/TCP   19h
[root@node50 ~]# curl -I http://168.26.213.219
HTTP/1.1 200 OK
Server: nginx-n.wtf/1.29.4
Date: Sat, 14 Feb 2026 03:06:56 GMT
Content-Type: text/html
Content-Length: 53609
Last-Modified: Thu, 15 Jan 2026 15:27:26 GMT
Connection: keep-alive
ETag: "6969075e-d169"
Accept-Ranges: bytes
相关推荐
运维螺丝钉2 小时前
Kubernetes之Istio应用
容器·kubernetes·istio
2501_924878732 小时前
中小电商自建直播间成本降47%:AI口播智能体轻量部署(含Docker+OBS链路)
人工智能·docker·容器·排序算法·宽度优先
uNhPiLgvQDpJ2 小时前
基于STM32的实验室环境检测系统:温湿度、烟雾、空气质量检测和报警功能
kubernetes
taiguisheng2 小时前
Windows系统中安装WSL2与Docker-Desktop
windows·docker·容器
西门吹雪分身3 小时前
K8S之Pod生命周期
java·kubernetes·k8s
予枫的编程笔记3 小时前
【Docker进阶篇】Docker Compose实战:Spring Boot与Redis服务名通信全解析
spring boot·redis·docker·docker compose·微服务部署·容器服务发现·容器通信
岳来3 小时前
网络小白对容器参数endpoint 和gateway 对比
网络·docker·容器·gateway·endpoint
小锋学长生活大爆炸3 小时前
【教程】极简部署OpenClaw并接入飞书等各大平台
docker·飞书·openclaw
市安3 小时前
基于Centos构建Nginx镜像(Dokerfile)
linux·运维·nginx·docker·容器·centos·镜像