Kubernetes 介绍

(网络插件 | Kubernetes官方讲解k8s)

应用部署发展过程

  • 传统部署时代:企业在物理服务器上运行应用程序。无法为物理服务器中的应用程序定义资源边界,这会导致资源分配问题。例如,如果在物理服务器上运行多个应用程序,则可能会出现一个应用程序占用大部分资源的情况,结果可能导致其他应用程序的性能下降。一种解决方案是在不同的物理服务器上运行每个应用程序,但是由于资源利用不足而无法扩展,并且组织维护许多物理服务器的成本很高。

    物理机-16991922695144

  • 虚拟化部署时代:作为解决方案,引入了虚拟化功能,它允许您在单个物理服务器的CPU上运行多个虚拟机(VM)。虚拟化功能允许应用程序在VM之间隔离,并提供安全级别,因为一个应用程序的信息不能被另一应用程序自由地访问。因为虚拟化可以轻松地添加或更新应用程序、降低硬件成本等等,所以虚拟化可以更好地利用物理服务器中的资源,并可以实现更好的可伸缩性。每个VM是一台完整的计算机,在虚拟化硬件之上运行所有组件,包括其自己的操作系统。

    虚拟机-16991922695155

  • 容器部署时代:容器类似于VM,但是它们具有轻量级的隔离属性,可以在应用程序之间共享操作系统(OS)。因此,容器被认为是轻量级的。容器与VM类似,具有自己的文件系统、CPU、内存、进程空间等。由于它们与基础架构分离,因此可以跨云和OS分发进行移植。

    容器-16991922695156

    容器因具有许多优势而变得流行起来。下面列出了容器的一些好处:

    • 敏捷应用程序的创建和部署:与使用VM镜像相比,提高了容器镜像创建的简便性和效率。

    • 持续开发、集成和部署:通过快速简单的回滚(由于镜像不可变性),提供可靠且频繁的容器镜像构建和部署。

    • 关注开发与运维的分离:在构建/发布时而不是在部署时创建应用程序容器镜像,从而将应用程序与基础架构分离。

    • 跨开发、测试和生产的环境一致性:在便携式计算机上与在云中相同地运行。

    • 云和操作系统分发的可移植性:可在Ubuntu、RHEL、CoreOS、本地、Google Kubernetes Engine和其他任何地方运行。

    • 以应用程序为中心的管理:提高抽象级别,从在虚拟硬件上运行OS到使用逻辑资源在OS上运行应用程序。

    • 松散耦合、分布式、弹性、解放的微服务:应用程序被分解成较小的独立部分,并且可以动态部署和管理-而不是在一台大型单机上整体运行。

    • 资源隔离:可预测的应用程序性能。

    • 资源利用:高效率和高密度。

Kubernetes 前世今生

Kubernetes 的名字来自希腊语,意思是“舵手” 或 “领航员”。K8s是将8个字母“ubernete”替换为“8”的缩写。

据说Google的数据中心里运行着20多亿个容器,而且Google十年前就开始使用容器技术。最初,Google开发了一个叫Borg的系统(现在命名为Omega)来调度如此庞大数量的容器和工作负载。在积累了这么多年的经验后,Google决定重写这个容器管理系统,并将其贡献到开源社区,让全世界都能受益。这个项目就是Kubernetes(K8s)。简单地讲,Kubernetes是Google Omega的开源版本。

2014 年 6 月,谷歌云计算专家埃里克·布鲁尔(Eric Brewer)在旧金山的发布会为这款新的开源工具揭牌。

2015 年 5 月,Kubernetes 在 Google 上的的搜索热度就已经超过了 Mesos 和 Docker Swarm,从那儿之后更是一路飙升,将对手甩开了十几条街。

2015 年 7 月 22 日K8S迭代到 v 1.0并正式对外公布。

2017 年 9 月,Mesosphere 宣布 支持 Kubernetes;10 月,Docker 宣布将在新版本中加入对 Kubernetes 的原生支持。至此,容器编排引擎领域的三足鼎立时代结束,Kubernetes 赢得全面胜利。

目前,AWS、Azure、Google、阿里云、腾讯云等主流公有云提供的是基于 Kubernetes 的容器服务;Rancher、CoreOS、IBM、Mirantis、Oracle、Red Hat、VMWare 等无数厂商也在大力研发和推广基于 Kubernetes 的容器 CaaS 或 PaaS 产品。可以说,Kubernetes 是当前容器行业最炙手可热的明星。

Kubernetes 是什么

官方介绍

Kubernetes 也称为 K8s,是用于自动部署、扩缩和管理容器化应用程序的开源系统。

它将组成应用程序的容器组合成逻辑单元,以便于管理和服务发现。

Kubernetes 特性

1. 自动化上线、出错自动回滚

更新应用时不会一次性停掉所有程序实例,分批替换新版本,同时监控程序运行状态。 一旦新版本崩了、异常,自动退回上一个稳定版本,不用人工手动恢复。

2. 内置服务发现 + 负载均衡

每个最小应用单元 Pod 都有独立 IP,同一套程序统一分配固定 DNS 域名。 不用改代码、不用额外搭建负载工具,集群内部自带流量分发,自动把请求分给各个 Pod。

3. 灵活挂载各类存储

容器需要硬盘存储数据时,可以自动挂上多种存储: 服务器本地硬盘、云厂商云盘、NFS、iSCSI 等网络存储,切换存储不用改容器。

4. 配置、密码单独管理(Secret/ConfigMap)

数据库账号、密钥、系统配置分开存放,不用写死打包到镜像里。 改配置、更新密码不用重新打包、重启镜像,敏感密码不会明文暴露。

5. 自动调度装箱,提高服务器利用率

根据每个程序 CPU、内存需求,智能分配到节点服务器。 重要业务和临时任务混跑在同一台机器,不互相抢占资源,最大化利用服务器硬件,省钱。

6. 支持批处理、离线任务

不只是 7×24 小时运行的网站服务,也能管理一次性任务、定时批量任务、CI 流水线任务。任务失败会自动重启容器。

7. 集群自我修复,不用人工运维

  • 容器崩溃自动重启

  • 节点故障,自动把 Pod 迁移到正常机器

  • 存储断开自动重新挂载 配合节点扩缩容,机器坏了集群自动兜底恢复业务

8. 一键 / 自动水平扩缩容

访问量暴涨时,一条命令、页面点击,或者根据 CPU 占用自动新增程序实例; 流量低谷自动减少实例,节省资源。

9. 同时支持 IPv4、IPv6 双栈

容器 Pod 和后台服务 Service 可以同时分配 IPv4、IPv6 两套地址,适配新旧网络环境。

10. 高可扩展,自定义扩展能力

不用修改 K8s 底层源码,通过插件、控制器、CRD 等方式拓展集群功能,按需增加自定义能力。

Kubernetes 不是什么?

一、K8s 不是传统 PaaS 平台

传统 PaaS(平台即服务) 会把开发框架、数据库、消息队列全都打包内置,强制开发者按它的规则写代码、部署程序,限制很多。 K8s 只是容器编排工具,不属于这类封闭平台。

二、不限制你的应用、语言、架构

  1. 不限编程语言:Java、Python、Go、PHP、Ruby 全都能跑;

  2. 不强制十二要素应用,有状态(数据库)、无状态(网站接口)、大数据批处理任务全部兼容;

  3. 不分普通应用 / 后台服务,只要能打包成容器,就能丢到 K8s 运行,没有框架束缚。

三、不自带中间件、数据库、存储组件

消息队列、Spark、MySQL、Ceph 这类软件,K8s 不会预装、不作为集群自带功能。 你需要自己部署,但 K8s 能完美调度、管理它们。

四、不负责编译代码、上传源码

K8s 只管运行容器,不管打包、编译项目:

  • 不会读取你的源代码;

  • 不会帮你构建镜像; CI/CD 流水线(代码自动打包发布)由你自己选工具搭建,K8s 只预留对接能力,不规定流程。

五、不强制日志、监控、告警工具

日志收集、性能监控、报警通知系统完全自由选择,ELK、Prometheus、自建监控都可以,没有绑定自带组件。

六、不自带专属配置语法

不会强制你用某种特殊配置语言管理应用,只用标准 YAML,第三方配置工具由使用者自选。

七、不管理底层服务器(节点机器)

只管容器和 Pod,服务器重装、系统补丁、机器故障运维、底层节点自愈不归 K8s 管,需要额外工具(如 Ansible、云厂商服务器运维能力)处理。

补充:通俗解释 PaaS

PaaS = 平台即服务,给你一套完整、封闭的开发平台: 内置数据库、缓存、运行框架,开发者不用管服务器,但必须遵守平台规范写代码;平台自带扩容、多租户能力,大幅减少代码量,但灵活性很低。 K8s 只做容器调度,自由度远高于传统 PaaS。

一句话总结区别

传统 PaaS:给你一套固定完整开发平台,限制多; Kubernetes:只是容器调度底座,只负责调度容器,其余软件、工具、流程全部让用户自由搭配。

Kubernetes并不是传统的PaaS(平台即服务)系统。

Kubernetes 架构

一个 Kubernetes 集群由一组被称作node的计算机组成。这些节点上运行 Kubernetes 所管理的容器化应用。集群至少具有一个master节点和一个worker节点。

Chart_02_Kubernetes-Architecture-16991922695157

1.控制平面的组件

控制平面的组件(Control Plane Components)对集群做出全局决策(比如调度),以及检测和响应集群事件(例如,当不满足部署的 replicas 字段时,启动新的 pod )。

控制平面组件可以在集群中的任何节点上运行。为了简单起见,设置脚本通常会在同一个计算机上启动所有控制平面组件,并且不会在此计算机上运行用户容器。

  • kube-apiserver,部署在master节点,负责提供 Kubernetes API服务,是Kubernetes 控制面的前端。各种客户端工具(CLI或UI) 以及Kubernetes其他组件可以通过它管理Cluster的各种资源。

  • kube-scheduler,部署在master节点,按照预定的调度策略将Pod调度到相应的机器上。

  • kube-controller-manager,部署在master节点,负责维护集群的状态,比如故障检测、自动扩展、滚动更新等。

  • etcd,兼具一致性和高可用性的键值数据库,保存 Kubernetes 所有集群数据的后台数据库。

 Master 四大组件 通俗人话版
 1. kube-apiserver(集群唯一大门)
 跑在主节点,提供 K8s 统一 API 接口,是控制平面的入口。kubectl 命令、可视化页面、集群内部其他组件,所有增删改查资源的操作都必须走它,相当于整个集群的统一接待窗口。
 2. kube-scheduler(Pod 调度员)
 跑在主节点。当要新建 Pod 时,它根据资源、规则筛选合适的服务器,把 Pod 安排到对应节点运行。
 3. kube-controller-manager(集群运维管家)
 跑在主节点,一直盯着集群真实状态。一旦实际运行情况和你配置的目标状态不一样,自动修复:节点故障处理、应用扩容缩容、滚动更新等都由它负责。
 4. etcd(集群数据库)
 高可靠、数据统一的键值库,集群所有数据(节点、Pod、配置、密钥等)全都存在这里,是 K8s 的底层存储。
 ​
 ​
 ​
 API 接口 通俗解释:
 1. 大白话理解
 API 就是程序和程序之间沟通的标准通道,约定好一套统一的说话规则,两个软件不用读懂对方内部代码,就能互相传数据、发指令。
 举个生活例子:
 自动售货机 = 一套 API
 你(客户端)投币、按按钮发请求
 售货机(服务端)接收指令,给你出货、找零
 按钮、投币口、出货口,就是它对外暴露的API 接口。
 2. 放到 kube-apiserver 里理解
 kube-apiserver 对外提供一堆 API 接口,相当于集群的 “售货机操作面板”:
 你敲 kubectl create pod、网页可视化工具,都是在调用 API;
 scheduler、controller-manager 这些内部组件,想查 / 改 Pod、节点数据,也只能调用这套 API;
 所有操作都遵循统一格式(HTTP+JSON/YAML),有固定请求方式。
 3. 核心作用
 统一标准,所有客户端、内部组件只需要对接这一套入口,不用分别对接数据库 etcd,方便权限校验、日志记录、安全管控。

 #集群配置完成会出现的情况:
 [root@master30 ~ 10:21:17]# kubectl  get pods  -A
 NAMESPACE     NAME                                        READY   STATUS    RESTARTS      AGE
 kube-system   calico-kube-controllers-585df69d45-vb7rb    1/1     Running   0             27m
 kube-system   calico-node-hmhp5                           1/1     Running   0             103s
 kube-system   calico-node-mqrws                           1/1     Running   0             27m
 kube-system   calico-node-x27nl                           1/1     Running   0             119s
 kube-system   coredns-7db6d8ff4d-clc6p                    1/1     Running   0             17h
 kube-system   coredns-7db6d8ff4d-px2fg                    1/1     Running   0             17h
 kube-system   etcd-master30.zy.cloud                      1/1     Running   1 (77m ago)   17h
 kube-system   kube-apiserver-master30.zy.cloud            1/1     Running   1 (77m ago)   17h
 kube-system   kube-controller-manager-master30.zy.cloud   1/1     Running   1 (77m ago)   17h
 kube-system   kube-proxy-bj5j8                            1/1     Running   0             103s
 kube-system   kube-proxy-lrrx7                            1/1     Running   1 (77m ago)   17h
 kube-system   kube-proxy-mb7vn                            1/1     Running   0             119s
 kube-system   kube-scheduler-master30.zy.cloud            1/1     Running   1 (77m ago)   17h
 ​
 ​
 ​
 逐类拆分说明
 一. K8s 控制平面组件(master30 静态 Pod,集群核心)
 etcd-master30.zy.cloud
 kube-apiserver-master30.zy.cloud
 kube-controller-manager-master30.zy.cloud
 kube-scheduler-master30.zy.cloud
 ​
 etcd:集群数据库,存所有资源数据
 kube-apiserver:集群唯一入口,kubectl / 节点都和它通信(地址 10.1.8.30:6443)
 controller-manager:控制器,维持资源期望状态
 kube-scheduler:调度器,把 Pod 分配到节点
 信息:17h 运行时长,各重启 1 次(77 分钟前),属于正常偶发重启,无持续崩溃
 ​
 二. CoreDNS 集群内部域名解析
 coredns-7db6d8ff4d-clc6p
 coredns-7db6d8ff4d-px2fg
 ​
 2 副本 DNS 服务,Pod 之间通过服务名互相访问全靠它,运行 17 小时稳定。
 ​
 三. Calico 网络插件(集群 Pod 网络互通)
 plaintext
 calico-kube-controllers-585df69d45-vb7rb
 calico-node-hmhp5
 calico-node-mqrws
 calico-node-x27nl
 ​
 calico-kube-controllers:Calico 控制器,管理网络策略、IP 池
 calico-node:每个节点都会部署 1 个 DaemonSet Pod
 calico-node-mqrws:master30 主节点(27m)
 calico-node-hmhp5 /calico-node-x27nl:两台新加入 worker 节点(103s、119s,刚通过 kubeadm join 加入不久)
 作用:实现 Pod 跨节点通信、网络 NetworkPolicy 隔离。
 ​
 四. kube-proxy 节点代理(Service 负载均衡)
 kube-proxy-bj5j8
 kube-proxy-lrrx7
 kube-proxy-mb7vn
 ​
 DaemonSet,每个节点 1 个:
 kube-proxy-lrrx7:master 节点(17h)
 bj5j8 /mb7vn:两台新 worker 节点(刚加入不久)
 作用:维护节点 iptables/ipvs 规则,实现 Service 访问转发。
 ​
 五.节点数量判断
 calico-node、kube-proxy 各 3 个 Pod → 集群一共 3 台节点:
 master30 控制节点
 worker 节点 A(hmhp5 /bj5j8)
 worker 节点 B(x27nl /mb7vn)
 ​
 六.关键字段含义
 READY 1/1:容器就绪,服务正常提供能力
 Running:Pod 正在运行,无崩溃、无镜像拉取失败
 RESTARTS:重启次数,少量重启不影响;持续频繁重启才代表异常
 AGE:Pod 启动时长,两个 worker 节点是刚执行完 kubeadm join 加入集群的

14791969222306-16991922695158

2.Worker组件

Worker组件在每个节点上运行(包括master节点),维护运行的 Pod 并提供 Kubernetes 运行环境。

  • kubelet,集群中每个节点上都需要运行的代理,负责维护容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理。kubelet 接收一组通过各类机制提供给它的 PodSpecs,确保这些 PodSpecs 中描述的容器处于运行状态且健康。

  • kube-proxy,集群中每个节点上运行的网络代理,负责为Service提供cluster内部的服务发现和负载均衡。kube-proxy 维护节点上的网络规则。这些网络规则允许从集群内部或外部的网络会话与 Pod 进行网络通信。

  • 容器运行环境(Container Runtime),容器运行环境,负责镜像管理以及Pod和容器的真正运行(CRI)。Kubernetes 支持多个容器运行环境: Dkubectlker、 containerd、cri-o、 rktlet 以及任何实现 Kubernetes CRI (容器运行环境接口)。

14791969311297-16991922695159

3.插件(Addons)

插件(Addons)使用 Kubernetes 资源 (DaemonSet , Deployment 等) 实现集群功能,插件资源属于 kube-system 命名空间。包涵如下插件:

  • kubedns,一个 DNS 服务器,为 Kubernetes 服务提供 DNS 记录。

  • 用户界面(Dashboard),为Kubernetes 集群提供Web UI。它使用户可以管理集群中运行的应用程序以及集群本身并进行故障排除。

  • 容器资源监控,将关于容器的一些常见的时间序列度量值保存到一个集中的数据库中,并提供用于浏览这些数据的界面。例如Heapster。

  • 集群层面日志,负责将容器的日志数据保存到一个集中的日志存储中,该存储能够提供搜索和浏览接口。例如,Fluentd-elasticsearch。

  • 网络插件 ,是实现容器网络接口(CNI)规范的软件组件。它们负责为 Pod 分配 IP 地址,并使这些 Pod 能在集群内部相互通信。

为什么master上也有kubelet和kube-proxy呢?

因为Master同时也是一个worker。

Master上也可以运行应用,几乎所有的Kubernetes组件本身都运行在Pod里 。例如etcd,kube-apiserver,kube-controller-manager等。

kubelet是唯一没有以容器形式运行的Kubernetes组件。

Kubernetes 安装

生产环境说明

安装方式

安装方式核心特点难度适用场景优点缺点推荐指数
kubeadm官方标准、无魔改中等生产自建、CKA/CKAD考试、标准集群兼容性强、易升级、生态完善、文档全步骤较多,需手动配置运行时/网络⭐⭐⭐⭐⭐
二进制手工部署全手动、底层可控极高原理研究、深度定制、教学演示掌控所有组件、无任何封装极易出错、升级繁琐、维护成本高⭐⭐
Sealos / KubeKey一键部署、高可用快速搭建生产/测试环境命令简单、自动装依赖、自带插件轻度封装,不如 kubeadm 透明⭐⭐⭐⭐
k3s / k0s轻量、单二进制边缘节点、低配机器、开发测试占用小、启动快、自带 containerd/ingress裁剪版,部分高级特性有差异⭐⭐⭐⭐
minikube / kind / k3d单机实验环境极低本地开发、快速验证、学习调试一键启动、环境干净不能模拟真实多节点生产集群⭐⭐⭐
云厂商托管(ACK/EKS等)Master 托管、免运维云上生产业务高可用、自动升级、无需维护控制面成本高、受厂商限制⭐⭐⭐⭐
RKE / OpenShift企业发行版中高大型企业、有商业化支持需求生态成熟、技术支持完善重、学习成本高、商用成本高⭐⭐⭐

选择建议:

  • 学习 + 未来上生产:优先 kubeadm

  • 快速搭建、不想折腾:Sealos

  • 本地测试/开发:k3s 或 minikube

  • 边缘/低配机器:k3s

环境说明

软件清单

  • vmware workstation 17

  • ubuntu-24.04-live-server-amd64

  • kubeadm 1.30.2

  • kubernetes 1.30.2

  • containerd.io=1.7.20-1

  • nerdctl-1.7.7-linux-amd64

  • cni-plugins-linux-amd64-v1.6.0

虚拟机硬件配置

  • 2 cpu

  • 4G memory

  • 1个NAT 网卡

  • 1个100G 硬盘

节点规划

节点IP角色
master30.laoma.cloud10.1.8.30master
worker31.laoma.cloud10.1.8.31work
worker32.laoma.cloud10.1.8.32work

准备模板(使用ubuntu虚拟机先克隆一个虚拟机当模板修改k8s节点都需要配置的部分,然后直接根据这个修改后的模板再克隆修改就行)

系统准备

安装系统

Ubuntu 2404 系统最小化安装,不需要swap分区,按以下要求分区。

  • /boot 2G

  • / 90G

配置仓库源

操作系统仓库换成华为云的仓库,速度更快。

 [root@ubuntu2404 ~]# cat > /etc/apt/sources.list.d/ubuntu.sources <<'EOF'
 Types: deb
 URIs: http://mirrors.huaweicloud.com/ubuntu/
 Suites: noble noble-updates noble-backports
 Components: main restricted universe multiverse
 Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
 EOF

containerd 仓库

 # 导入 containerd 仓库 key
 [root@ubuntu2404 ~]# curl -fsSL https://mirrors.huaweicloud.com/docker-ce/linux/ubuntu/gpg | gpg --dearmour -o /etc/apt/trusted.gpg.d/containerd.gpg
 ​
 # 添加 containerd 仓库
 [root@ubuntu2404 ~]# cat << 'EOF' > /etc/apt/sources.list.d/docker-ce.list
 deb [arch=amd64] https://mirrors.huaweicloud.com/docker-ce/linux/ubuntu noble stable
 EOF

Kubernetes 官方变更了仓库的存储路径以及使用方式,使用 1.28 及以上版本,需按照新版配置方法进行配置。

该文档示例为配置 1.30 版本,如需其他版本请在对应位置字符串替换即可。比如需要安装 1.29 版本,则需要将如下配置中的 v1.30 替换成 v1.29。

目前该源支持 v1.24 - v1.35 版本,后续版本会持续更新。

 # 添加 kubernetes 仓库 key
 [root@ubuntu2404 ~]# curl -fsSL https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.30/deb/Release.key | gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
 ​
 # 添加 kubernetes 仓库
 [root@ubuntu2404 ~]# echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.30/deb/ /" > /etc/apt/sources.list.d/kubernetes.list
安装基础软件包
 [root@ubuntu2404 ~]# apt update && apt install -y vim lrzsz bash-completion open-vm-tools apt-transport-https sshpass
 ​
 # vim:强大的终端文本编辑器,用于编辑配置文件、代码等。
 # lrzsz:便于xshell快速上传和下载文件
 # bash-completion:命令行自动补全工具,按 Tab 可补全命令、参数、文件名。
 # open-vm-tools:VMware 虚拟机工具,实现时间同步、文件拖拽、分辨率适配等。
 # apt-transport-https:让 apt 支持通过 HTTPS 下载软件包,用于访问安全源。
 # sshpass:非交互式 SSH 登录工具,可在命令行直接带密码登录,多用于脚本自动化。

设置 IP
 [root@ubuntu2404 ~]# mkdir /etc/netplan/origin
 [root@ubuntu2404 ~]# mv /etc/netplan/*yaml /etc/netplan/origin
 [root@ubuntu2404 ~]# cat > /etc/netplan/00-static.yaml <<EOF
 network:
   ethernets:
     ens32:        # 网卡名称,你的服务器网卡是ens32
       dhcp4: no    # 关闭DHCP自动获取IP,改用静态手动设置
       addresses:
         - 10.1.8.30/24   # 本机静态IP + 子网掩码(/24=255.255.255.0)
       routes:
         - to: default
           via: 10.1.8.2  # 默认网关,所有访问外网的流量走10.1.8.2
       nameservers:
         addresses:
           - 223.5.5.5    # DNS服务器(阿里公共DNS,负责域名解析)
   version: 2   # netplan配置格式版本,固定写2
 EOF
 ​
 #600 权限代表:只有 root 用户能读写,其他用户完全无权限查看 / 修改,安全加固,防止普通用户篡改网络。
 #r读:4   w写:2    x执行:1
 #755:文件 rwxr-xr-x
 #644:普通文件 rw-r--r--
 #600:私密配置文件(如网络、密钥)
 #777:全部开放,生产环境禁止使用
 ​
 #chmod 600:仅 root 读写,防止普通用户篡改网络,安全加固
 [root@ubuntu2404 ~]# chmod 600 /etc/netplan/00-static.yaml
 [root@ubuntu2404 ~]# netplan apply
设置 /etc/hosts
 [root@ubuntu2404 ~]# cat << 'EOF' >> /etc/hosts
 ​
 ###### kubernetes #####
 10.1.8.30 master30.laoma.cloud master30
 10.1.8.31 worker31.laoma.cloud worker31
 10.1.8.32 worker32.laoma.cloud worker32
 EOF
彻底关闭 swap(K8s 硬性要求)

如果有 swap 分区,需要关闭。kubernetes不需要swap分区。

 [root@ubuntu2404 ~]# swapoff -a && sed -i '/^.*swap/d' /etc/fstab
 [root@ubuntu2404 ~]# rm -f /swap.img
配置对时

集群所有节点时间必须完全一致,否则证书校验、日志、调度、监控全部异常 chrony 比 ntp 更轻量化,适配云服务器 / 虚拟机,自动同步公网时间

 [root@ubuntu2404 ~]# apt-get install -y chrony
 ​
 # 以下步骤可以省略
 [root@ubuntu2404 ~]# systemctl enable chrony --now
设置 ssh
 # 避免ssh服务器对客户端IP进行反向解析为域名,客户端可以快速与服务器建立连接
 [root@ubuntu2404 ~]# echo 'UseDNS no' >> /etc/ssh/sshd_config
 ​
 # 避免ssh客户端校验服务器公钥,否则首次连接需要交互输入yes
 [root@ubuntu2404 ~]# echo 'StrictHostKeyChecking no' >> /etc/ssh/ssh_config
 ​
 # 生成秘钥
 [root@ubuntu2404 ~]# ssh-keygen -N '' -f ~/.ssh/id_rsa -t rsa
 ​
 # 配置免密登录自己:替换password为实际密码
 [root@ubuntu2404 ~]# sshpass -p password ssh-copy-id root@localhost
配置 IPVS
 # 1. 安装 ipvs 依赖包
 [root@ubuntu2404 ~]# apt install -y iptables ipvsadm ipset conntrack
 ​
 # 2-1. 加载基础网络模块:临时加载(立即生效)
 [root@ubuntu2404 ~]# modprobe overlay 
 [root@ubuntu2404 ~]# modprobe br_netfilter
 # 模块功能说明:
 # overlay:Overlay 文件系统模块,容器运行时(containerd/docker)分层镜像必备。
 # br_netfilter:允许桥接设备(Linux 网桥)通过 iptables 过滤,是 Kubernetes 网络通信必需。
 ​
 # 2-2. 加载 ipvs 内核模块:临时加载(立即生效)
 [root@ubuntu2404 ~]# modprobe ip_vs
 [root@ubuntu2404 ~]# modprobe ip_vs_rr
 [root@ubuntu2404 ~]# modprobe ip_vs_wrr
 [root@ubuntu2404 ~]# modprobe ip_vs_lc
 [root@ubuntu2404 ~]# modprobe ip_vs_sh
 [root@ubuntu2404 ~]# modprobe nf_conntrack
 # 模块功能说明:
 # ip_vs:IPVS 核心模块,实现四层负载均衡,是 kube-proxy ipvs 模式的基础。
 # ip_vs_rr:IPVS 轮询调度算法,按顺序依次分发请求。
 # ip_vs_wrr:加权轮询,按后端节点权重分配流量。
 # ip_vs_lc:最少连接调度,优先发给连接数最少的节点。
 # ip_vs_sh:源地址哈希,保证同一客户端 IP 始终访问同一后端。
 # nf_conntrack:连接跟踪,记录网络连接状态,保证数据包正确转发。
 ​
 ​
 # 3 永久加载模块(重启生效),写入 systemd 模块加载配置,服务器重启自动加载,不用重复执行 modprobe
 # systemd-modules-load.service 会自动加载改配置文件
 [root@ubuntu2404 ~]# cat > /etc/modules-load.d/k8s-net.conf << EOF
 # K8s 基础网络
 br_netfilter
 overlay
 # IPVS 必需
 ip_vs
 ip_vs_rr
 ip_vs_wrr
 ip_vs_lc
 ip_vs_sh
 nf_conntrack
 EOF
配置其他内核参数
 # 配置内核参数,将桥接的IPv4流量传递到iptables的链
 [root@ubuntu2404 ~]# cat > /etc/sysctl.d/k8s.conf << 'EOF'
 net.bridge.bridge-nf-call-iptables=1  
 net.bridge.bridge-nf-call-ip6tables=1
 net.ipv4.ip_forward=1
 vm.swappiness=0
 EOF
 ​
 # 内核参数说明:
 # net.bridge.bridge-nf-call-iptables=1,启用iptables网络包过滤功能
 # net.bridge.bridge-nf-call-ip6tables=1,启用ip6tables的网络包过滤功能
 # net.ipv4.ip_forward=1,开启路由转发,转发IPv4的数据包
 # vm.swappiness=0,禁止使用交换分区
 ​
 # 内核参数立刻生效
 [root@ubuntu2404 ~]# sysctl -p /etc/sysctl.d/k8s.conf

k8s 准备

配置 containerd
 [root@ubuntu2404 ~]# apt-get install -y containerd.io=1.7.20-1 cri-tools
 ​
 # 设置crictl的runtime-endpoint
 root@ubuntu2204:~# crictl config runtime-endpoint unix:///var/run/containerd/containerd.sock
 ​
 [root@ubuntu2404 ~]# containerd config default > /etc/containerd/config.toml
 ​
 # 修改 SystemdCgroup 和 sandbox_image
 [root@ubuntu2404 ~]# sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
 [root@ubuntu2404 ~]# sed -i 's|sandbox_image = ".*"|sandbox_image = "registry.k8s.io/pause:3.9"|' /etc/containerd/config.toml
 ​
 # 配置镜像仓库加速
 [root@ubuntu2404 ~]# vim /etc/containerd/config.toml
 # 查找 mirrors行
       [plugins."io.containerd.grpc.v1.cri".registry.mirrors]
         # 添加如下四行记录,注意缩进
         [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
           endpoint = ["https://docker.m.daocloud.io","https://docker.1ms.run","https://docker.xuanyuan.me"]
         [plugins."io.containerd.grpc.v1.cri".registry.mirrors."registry.k8s.io"]
           endpoint = ["https://k8s.m.daocloud.io","https://registry.cn-hangzhou.aliyuncs.com/google_containers"]
 # 重启服务
 [root@ubuntu2404 ~]# systemctl restart containerd.service
 # containerd 服务,默认已经设置开机启动,并启动

crictl 走的是 containerd CRI 接口,会读取 /etc/containerd/config.toml 里的 registry.mirrors 配置。

下载测试:

 [root@ubuntu2404 ~]# crictl pull busybox
 Image is up to date for sha256:925ff61909aebae4bcc9bc04bb96a8bd15cd2271f13159fe95ce4338824531dd
安装 nerdctl 和 cni plugin

nerdctl 项目地址:https://github.com/containerd/nerdctl/releases

cni 插件项目地址:https://github.com/containernetworking/plugins/releases

 # 下载并安装
 [root@ubuntu2404 ~]# wget http://192.168.42.200/course-materials/softwares/stage03/nerdctl-1.7.7-linux-amd64.tar.gz
 [root@ubuntu2404 ~]# tar -xf nerdctl-1.7.7-linux-amd64.tar.gz -C /usr/bin/
 ​
 # 下载 nerdctl 所需要的 cni 插件
 [root@ubuntu2404 ~]# wget http://192.168.42.200/course-materials/softwares/stage03/cni-plugins-linux-amd64-v1.6.0.tgz
 [root@ubuntu2404 ~]# mkdir -p /opt/cni/bin
 [root@ubuntu2404 ~]# tar -xf cni-plugins-linux-amd64-v1.6.0.tgz -C /opt/cni/bin

nerdctl 走的是 containerd 原生 API不会读取 CRI 专属的 registry 配置,而是用自己独立的镜像源配置。

nerdctl 有自己的配置文件,需要单独配置 Docker Hub 加速。

 # 配置 docker.io 镜像加速
 mkdir -p /etc/containerd/certs.d/docker.io
 cat > /etc/containerd/certs.d/docker.io/hosts.toml << EOF
 server = "https://registry-1.docker.io"
 [host."https://09def58152000fc00ff0c00057bad7e0.mirror.swr.myhuaweicloud.com"]
   capabilities = ["pull", "resolve"]
 EOF
 ​
 # 配置 registry.k8s.io 镜像加速
 mkdir -p /etc/containerd/certs.d/registry.k8s.io
 cat > /etc/containerd/certs.d/registry.k8s.io/hosts.toml << EOF
 server = "https://registry.k8s.io"
 ​
 # 首选 DaoCloud
 [host."https://k8s.m.daocloud.io"]
   capabilities = ["pull", "resolve"]
 ​
 # 次选 Mirrorify
 [host."https://k8s.mirrorify.net"]
   capabilities = ["pull", "resolve"]
 ​
 # 兜底阿里云(如有账号)
 [host."https://registry.cn-hangzhou.aliyuncs.com/google_containers"]
   capabilities = ["pull", "resolve"]
   override_path = true
 EOF

下载测试:

 [root@ubuntu2404 ~]# nerdctl pull docker.io/library/busybox
 [root@ubuntu2404 ~]# nerdctl pull registry.k8s.io/pause:3.9
安装 kubernetes 软件包
 # 查看版本
 [root@ubuntu2404 ~]# apt list kubeadm -a|head
 ​
 WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
 ​
 Listing...
 kubeadm/unknown 1.30.2-1.1 amd64
 kubeadm/unknown 1.30.1-1.1 amd64
 kubeadm/unknown 1.30.0-1.1 amd64
 ​
 kubeadm/unknown 1.30.2-1.1 arm64
 kubeadm/unknown 1.30.1-1.1 arm64
 kubeadm/unknown 1.30.0-1.1 arm64
 ​
 kubeadm/unknown 1.30.2-1.1 ppc64el
 ​
 #安装 K8s 三件套 kubeadm/kubelet/kubectl
 [root@ubuntu2404 ~]# apt install -y kubeadm=1.30.2-1.1 kubelet=1.30.2-1.1 kubectl=1.30.2-1.1
 ​
 1. kubectl:集群客户端(你操作集群的命令工具)
 作用:你在任意节点(master/worker)执行的所有集群操作,全靠它。相当于 K8s 的 “遥控器”。它只会发请求给 kube-apiserver,不管理本机容器。
 ​
 2. kubelet:每个服务器上的代理(核心服务,必须每个节点都装)
 地位
 K8s 最核心的节点组件,所有节点必装,后台常驻 systemd 服务。
 作用
 和 apiserver 保持通信,接收调度指令;
 调用 containerd(CRI)创建、启停、销毁 Pod 容器;
 采集节点、容器状态上报给控制平面;
 管理静态 Pod(master 上的 etcd、kube-apiserver 都是它创建)。
 没有 kubelet = 这台机器无法加入集群,不能跑业务容器。
 ​
 3. kubeadm:集群搭建工具,仅初始化时使用
 作用
 专门用来快速搭建、扩容、修复集群,自动化做一堆复杂操作:
 kubeadm init:初始化 master 控制平面,生成证书、etcd、apiserver、调度器、控制器;
 kubeadm join:worker 节点加入集群;
 自动配置 kubelet 连接 apiserver;
 证书更新、集群升级、重置集群。
 特点
 平时运维几乎不用,只在搭集群、加节点、升级时执行一次。
 worker 节点虽然装上,但基本不会主动调用。
 ​
 4.三者分工一句话总结
 kubectl:人用来操作集群的命令行工具;
 kubelet:跑在每台机器上,负责本机容器生命周期;
 kubeadm:一键搭建 / 扩容整个集群的初始化工具。
 ​
 5.对应集群流程举例
 你敲 kubectl create deployment nginx(kubectl 发送请求)
 apiserver 记录资源,调度器把 Pod 分配到某台节点
 该节点上的 kubelet 监听到变化,调用 containerd 拉镜像、启动容器
 ​
 6.补充面试考点
 master 三件套全部安装;
 worker 同样三件套都安装,kubelet 是刚需,kubectl 方便排查,kubeadm 备用扩容;
 集群真正运行时,只有 kubelet 持续运行;kubectl、kubeadm 只是临时执行工具。
 ​
 ​
 # 设置 kubelet 服务
 [root@ubuntu2404 ~]# systemctl enable kubelet --now

此时kubelet服务处于activating,等 kubernetes 安装完成后状态变更为active。

配置相关命令补全
 # 配置 crictl 命令自动补全
 [root@ubuntu2404 ~]# mkdir /etc/bash_completion.d
 [root@ubuntu2404 ~]# crictl completion bash > /etc/bash_completion.d/crictl
 [root@ubuntu2404 ~]# source /etc/bash_completion.d/crictl
 ​
 # 配置 nerdctl 命令自动补全
 [root@ubuntu2404 ~]# nerdctl completion bash > /etc/bash_completion.d/nerdctl
 [root@ubuntu2404 ~]# echo 'export CONTAINERD_NAMESPACE=k8s.io' >> /etc/bash_completion.d/nerdctl
 [root@ubuntu2404 ~]# source /etc/bash_completion.d/nerdctl

注意:此处必须设置变量 CONTAINERD_NAMESPACE,否则 nerdctl 默认将镜像导入到 default 命名空间,导致 k8s 无法使用镜像。k8s 默认使用 k8s.io 命名空间中镜像。

 # 配置 kubectl 命令补全
 [root@ubuntu2404 ~]# kubectl completion bash > /etc/bash_completion.d/kubectl
 [root@ubuntu2404 ~]# source /etc/bash_completion.d/kubectl
 ​
 # 配置 kubeadm 命令补全
 [root@ubuntu2404 ~]# kubeadm completion bash > /etc/bash_completion.d/kubeadm
 [root@ubuntu2404 ~]# source /etc/bash_completion.d/kubeadm
关闭虚拟机
 [root@ubuntu2404 ~]# init 0

准备节点

 ### 隆虚拟机
 # 采用完全克隆方法克隆出其他3台虚拟机。
 # 3台虚拟机重新设置自己的的主机名和网络。
 ​
 # master30 节点
 [root@master30 ~]# hostnamectl set-hostname master30.zy.cloud
 [root@master30 ~]# cat > /etc/netplan/00-static.yaml <<EOF
 network:
   ethernets:
     ens32:
       dhcp4: no
       addresses:
         - 10.1.8.30/24
       routes:
         - to: default
       nameservers:
         addresses:
           - 223.5.5.5
   version: 2
 EOF
 ​
 [root@master30 ~]# netplan apply
 ​
 # worker31 节点
 [root@worker31 ~]# hostnamectl set-hostname worker31.laoma.cloud
 [root@worker31 ~]# cat > /etc/netplan/00-static.yaml <<EOF
 network:
   ethernets:
     ens32:
       dhcp4: no
       addresses:
         - 10.1.8.31/24
       routes:
         - to: default
           via: 10.1.8.2
       nameservers:
         addresses:
           - 223.5.5.5
   version: 2
 EOF
 [root@worker31 ~]# netplan apply
 ​
 # worker32 节点
 [root@worker32 ~]# hostnamectl set-hostname worker32.laoma.cloud
 [root@worker32 ~]# cat > /etc/netplan/00-static.yaml <<EOF
 network:
   ethernets:
     ens32:
       dhcp4: no
       addresses:
         - 10.1.8.32/24
       routes:
         - to: default
           via: 10.1.8.2
       nameservers:
         addresses:
           - 223.5.5.5
   version: 2
 EOF
 [root@worker32 ~]# netplan apply

创建集群

下载镜像

在master节点初始化集群过程中,需要下载镜像,这里我们提前下载。

 [root@master30 ~]# kubeadm config images pull --kubernetes-version=v1.30.2
 [config/images] Pulled registry.k8s.io/kube-apiserver:v1.30.2
 [config/images] Pulled registry.k8s.io/kube-controller-manager:v1.30.2
 [config/images] Pulled registry.k8s.io/kube-scheduler:v1.30.2
 [config/images] Pulled registry.k8s.io/kube-proxy:v1.30.2
 [config/images] Pulled registry.k8s.io/coredns/coredns:v1.11.1
 [config/images] Pulled registry.k8s.io/pause:3.9
 [config/images] Pulled registry.k8s.io/etcd:3.5.12-0

备选方案-使用阿里云仓库镜像:

 [root@master30 ~]# kubeadm config images pull --kubernetes-version=v1.30.2 --image-repository registry.aliyuncs.com/google_containers
 [config/images] Pulled registry.k8s.io/kube-apiserver:v1.30.2
 [config/images] Pulled registry.k8s.io/kube-controller-manager:v1.30.2
 [config/images] Pulled registry.k8s.io/kube-scheduler:v1.30.2
 [config/images] Pulled registry.k8s.io/kube-proxy:v1.30.2
 [config/images] Pulled registry.k8s.io/coredns/coredns:v1.11.1
 [config/images] Pulled registry.k8s.io/pause:3.9
 [config/images] Pulled registry.k8s.io/etcd:3.5.12-0

worker 节点需要kube-proxy和pause镜像:

 [root@worker31 ~]# nerdctl pull registry.k8s.io/kube-proxy:v1.30.2
 [root@worker31 ~]# nerdctl pull registry.k8s.io/pause:3.9
 ​
 [root@worker32 ~]# nerdctl pull registry.k8s.io/kube-proxy:v1.30.2
 [root@worker32 ~]# nerdctl pull registry.k8s.io/pause:3.9

初始化集群

 #这条命令是搭建 K8s 集群的第一步:在当前 master30 机器上,创建整套集群控制平面(Master 主控节点)
 #自动部署 apiserver、etcd、调度器、控制器管理器 四大核心组件,同时生成:1.集群根 CA 证书、管理员凭证(就是你之前一直在用的 /root/.kube/config 文件来源)  2.工作节点加入集群的 kubeadm join 加入指令  3.Pod 网络通信网段定义
 [root@master30 ~]# kubeadm init --kubernetes-version=v1.30.2 --pod-network-cidr=10.224.0.0/16

备选方案-使用阿里云仓库镜像初始化集群:

 [root@master30 ~]# kubeadm init --kubernetes-version=v1.30.2 --pod-network-cidr=10.224.0.0/16  --image-repository registry.aliyuncs.com/google_containers(多加了--image-repository这个参数)

初始化过程如下:

 [init] Using Kubernetes version: v1.30.2
 [preflight] Running pre-flight checks
 [preflight] Pulling images required for setting up a Kubernetes cluster
 [preflight] This might take a minute or two, depending on the speed of your internet connection
 [preflight] You can also perform this action in beforehand using 'kubeadm config images pull'
 [certs] Using certificateDir folder "/etc/kubernetes/pki"
 [certs] Generating "ca" certificate and key
 [certs] Generating "apiserver" certificate and key
 [certs] apiserver serving cert is signed for DNS names [kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local master30.laoma.cloud] and IPs [10.96.0.1 10.1.8.30]
 [certs] Generating "apiserver-kubelet-client" certificate and key
 [certs] Generating "front-proxy-ca" certificate and key
 [certs] Generating "front-proxy-client" certificate and key
 [certs] Generating "etcd/ca" certificate and key
 [certs] Generating "etcd/server" certificate and key
 [certs] etcd/server serving cert is signed for DNS names [localhost master30.laoma.cloud] and IPs [10.1.8.30 127.0.0.1 ::1]
 [certs] Generating "etcd/peer" certificate and key
 [certs] etcd/peer serving cert is signed for DNS names [localhost master30.laoma.cloud] and IPs [10.1.8.30 127.0.0.1 ::1]
 [certs] Generating "etcd/healthcheck-client" certificate and key
 [certs] Generating "apiserver-etcd-client" certificate and key
 [certs] Generating "sa" key and public key
 [kubeconfig] Using kubeconfig folder "/etc/kubernetes"
 [kubeconfig] Writing "admin.conf" kubeconfig file
 [kubeconfig] Writing "super-admin.conf" kubeconfig file
 [kubeconfig] Writing "kubelet.conf" kubeconfig file
 [kubeconfig] Writing "controller-manager.conf" kubeconfig file
 [kubeconfig] Writing "scheduler.conf" kubeconfig file
 [etcd] Creating static Pod manifest for local etcd in "/etc/kubernetes/manifests"
 [control-plane] Using manifest folder "/etc/kubernetes/manifests"
 [control-plane] Creating static Pod manifest for "kube-apiserver"
 [control-plane] Creating static Pod manifest for "kube-controller-manager"
 [control-plane] Creating static Pod manifest for "kube-scheduler"
 [kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
 [kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
 [kubelet-start] Starting the kubelet
 [wait-control-plane] Waiting for the kubelet to boot up the control plane as static Pods from directory "/etc/kubernetes/manifests"
 [kubelet-check] Waiting for a healthy kubelet. This can take up to 4m0s
 [kubelet-check] The kubelet is healthy after 502.398615ms
 [api-check] Waiting for a healthy API server. This can take up to 4m0s
 [api-check] The API server is healthy after 7.50265248s
 [upload-config] Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
 [kubelet] Creating a ConfigMap "kubelet-config" in namespace kube-system with the configuration for the kubelets in the cluster
 [upload-certs] Skipping phase. Please see --upload-certs
 [mark-control-plane] Marking the node master30.laoma.cloud as control-plane by adding the labels: [node-role.kubernetes.io/control-plane node.kubernetes.io/exclude-from-external-load-balancers]
 [mark-control-plane] Marking the node master30.laoma.cloud as control-plane by adding the taints [node-role.kubernetes.io/control-plane:NoSchedule]
 [bootstrap-token] Using token: ybenal.6mszwb1nf8nck72g
 [bootstrap-token] Configuring bootstrap tokens, cluster-info ConfigMap, RBAC Roles
 [bootstrap-token] Configured RBAC rules to allow Node Bootstrap tokens to get nodes
 [bootstrap-token] Configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials
 [bootstrap-token] Configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token
 [bootstrap-token] Configured RBAC rules to allow certificate rotation for all node client certificates in the cluster
 [bootstrap-token] Creating the "cluster-info" ConfigMap in the "kube-public" namespace
 [kubelet-finalize] Updating "/etc/kubernetes/kubelet.conf" to point to a rotatable kubelet client certificate and key
 [addons] Applied essential addon: CoreDNS
 [addons] Applied essential addon: kube-proxy
 ​
 Your Kubernetes control-plane has initialized successfully!
 ​
 To start using your cluster, you need to run the following as a regular user:
 ​
   mkdir -p $HOME/.kube
   sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
   sudo chown $(id -u):$(id -g) $HOME/.kube/config
 ​
 Alternatively, if you are the root user, you can run:
 ​
   export KUBECONFIG=/etc/kubernetes/admin.conf
 ​
 You should now deploy a pod network to the cluster.
 Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
   https://kubernetes.io/docs/concepts/cluster-administration/addons/
 ​
 Then you can join any number of worker nodes by running the following on each as root:
 ​
 kubeadm join 10.1.8.30:6443 --token mi0yt8.1tzza4q64dr8y3pc \
     --discovery-token-ca-cert-hash sha256:5606e09618330aee8859abe3ea4cd8734f9b540630048a6e1c3aaf6c54d486fd

选项说明:

--image-repository registry.aliyuncs.com/google_containers,指定镜像下载位置

--kubernetes-version=v1.30.2,指定版本

--pod-network-cidr=10.224.0.0/16,指定Pod网络的范围。 Kubernetes支持多种网络 方案, 而且不同网络方案对--pod-network-cidr有自己的要求。

--apiserver-advertise-address指明用哪个interface与Cluster的其他节点通信。 如果master有多个interface, 建议明确指定, 如果不指定, kubeadm会自动选择有默认网关的interface。

最后面生成的命令:kubeadm join 10.1.8.30:6443 --token mi0yt8.1tzza4q64dr8y3pc --discovery-token-ca-cert-hash sha256:5606e09618330aee8859abe3ea4cd8734f9b540630048a6e1c3aaf6c54d486fd是后面节点加入k8s集群的命令,直接复制就行

初始化过程说明:

  1. kubeadm执行初始化前的检查。

  2. 下载组件的Docker镜像。 这一步可能会花一些时间, 主要取决于网络质量。

  3. 生成token和证书。

  4. 生成KubeConfig文件, kubelet需要用这个文件与master通信。

  5. 安装master组件。

  6. 安装附加组件kube-proxy和CoreDNS。

  7. Kubernetes master初始化成功。

  8. 提示如何配置kubectl。

  9. 提示如何安装Pod网络。

  10. 提示如何注册其他节点到Cluster。

配置集群

配置凭据

  1. kubectl默认使用~/.kube/config文件中凭据信息管理kubernetes。

 #$HOME:当前用户家目录,root 用户等价 /root
 #作用:创建 kubectl 默认存放凭证的隐藏目录 .kube
 [root@master30 ~ 09:49:09]# mkdir -p $HOME/.kube
 ​
 ​
 #/etc/kubernetes/admin.conf:kubeadm 初始化集群后自动生成的管理员完整凭证文件(集群 master 自带)
 #$HOME/.kube/config:复制到 kubectl 默认读取位置
 #效果:直接执行 kubectl 无需额外指定凭证,即可操作集群()
 [root@master30 ~ 09:50:10]# cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  1. 如果环境变量KUBECONFIG存在,则优先使用境变量KUBECONFIG设置的值。

 [root@master30 ~ 09:45:37]# mv .kube/config  .
 [root@master30 ~ 09:50:10]# ls
 calico.yaml  config  kubeadm.yaml  kubectx-master  kubectx.zip  ns-zy.yaml
 ​
 #KUBECONFIG:kubectl 专属环境变量,优先级高于默认~/.kube/config
 #赋值 /root/config:告诉 kubectl 去这个路径读取凭证
 [root@master30 ~ 09:55:42]# export KUBECONFIG=/root/config
 ​
 #NotReady:节点未就绪,通常是CNI 网络插件未部署,部署网络组件后状态变为 Ready
 [root@master30 ~ 09:58:11]# kubectl get nodes
 NAME                 STATUS     ROLES                  AGE    VERSION
 master30..cloud   NotReady   control-plane,master   5m2s   v1.28.2
 ​
 # 等网络配置完成后,STATUS状态由NotReady变更为Ready
  1. 还可以通过选项--kubeconfig=''明确指定凭据文件位置。

 [root@master30 ~ 09:58:17]# kubectl  get nodes  --kubeconfig  /root/config 
 NAME                STATUS   ROLES           AGE   VERSION
 master30.zy.cloud   Ready    control-plane   12h   v1.30.2
 worker31.zy.cloud   Ready    <none>          12h   v1.30.2
 worker32.zy.cloud   Ready    <none>          12h   v1.30.2
 ​
 [root@master30 ~]# mv config kube.conf#kubernetes对凭据文件名没有要求。
 #比如把config重命名为kube.conf
 [root@master30 ~ 10:00:40]# mv config  kube.conf  
 [root@master30 ~ 10:01:57]# kubectl  get  nodes --kubeconfig  /root/kube.conf 
 NAME                STATUS   ROLES           AGE   VERSION
 master30.zy.cloud   Ready    control-plane   12h   v1.30.2
 worker31.zy.cloud   Ready    <none>          12h   v1.30.2
 worker32.zy.cloud   Ready    <none>          12h   v1.30.2
 ​
  1. 恢复使用默认位置~/.kube/config

 [root@master30 ~ 10:02:03]# unset  KUBECONFIG
 [root@master30 ~ 10:02:44]# mv kube.conf    .kube/config
 ​

凭证文件优先级总结(从高到低) 1.--kubeconfig 命令行显式指定文件 2.环境变量 KUBECONFIG 指定路径 3.默认路径 ~/.kube/config

 # 配置普通用户 kubectl 访问权限置凭据:意思是把集群管理员的身份证书复制到当前用户专属目录,并修改权限,让当前用户拥有集群管理员权限,无需 sudo 即可操作集群。
 [root@master30 ~ 21:03:24]# mkdir  -p $HOME/.kube
 [root@master30 ~ 21:05:41]# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
 [root@master30 ~ 21:06:07]# sudo chown  $(id -u):$(id -g) $HOME/.kube/config 
 ​
 ​
 /etc/kubernetes/admin.conf:集群最高管理员证书,只有 root 可读;
 复制到当前用户家目录 .kube/config,普通用户不用 sudo 就能执行 kubectl;
 chown 修改文件归属为当前登录用户,否则会权限不足。
 ​
 ​
 #一、为什么要 配置普通用户 kubectl 访问权限置凭据
 kubectl 是操作 K8s 集群的命令工具,它访问集群 kube-apiserver 需要身份证书,证明你是管理员。
 集群初始化后,管理员证书文件放在这里:
 /etc/kubernetes/admin.conf
 这是集群最高权限凭证,只有 root 用户能读取。
 下面三条命令,就是把这份管理员证书复制到普通用户目录,让你不用 sudo 就能直接敲 kubectl:
 mkdir -p $HOME/.kube
 sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
 sudo chown $(id -u):$(id -g) $HOME/.kube/config
 生成的文件:~/.kube/config,行业内统称 kubeconfig 管理员凭证文件。
 ​
 #二、为什么必须配置
 1. 不配置的后果
 直接执行 kubectl get nodes 会报错:
 要么提示找不到 .kube/config;
 要么权限不足,必须加 sudo kubectl get nodes。
 每次操作都加 sudo 很麻烦,而且脚本、自动化工具不方便使用。
 2. 文件权限限制
 /etc/kubernetes/admin.conf 归属 root,普通用户读取不了,直接用会鉴权失败。
 把它复制到自己家目录,再修改文件属主为当前登录用户,普通用户就能正常读取证书。
 3. 作用原理
 kubectl 默认会自动读取 ~/.kube/config,里面包含:
 apiserver 集群地址
 CA 根证书
 管理员客户端证书、私钥
 每次执行 kubectl 命令,都会带着这份证书去和 apiserver 做 TLS 加密身份校验,集群识别你是管理员,才允许增删改查所有资源。
 4. 一句话总结含义
 把集群管理员的身份证书复制到当前用户专属目录,并修改权限,让当前用户拥有集群管理员权限,无需 sudo 即可操作集群。
 #比如我做实验验证:
 [root@master30 ~ 21:19:47]# cd .kube/
 [root@master30 .kube 21:19:59]# ls
 cache  config
 [root@master30 .kube 21:19:59]# cd
 #把.kube/config移走到当前目录下
 [root@master30 ~ 21:20:10]# mv  .kube/config   .
 [root@master30 ~ 21:20:25]# ls
 calico.yaml  config  kubeadm.yaml
 #验证kubectl命令是否可以使用,发现不行
 [root@master30 ~ 21:20:26]# kubectl  get  nodes
 E0705 21:20:36.901546  366922 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp 127.0.0.1:8080: connect: connection refused
 E0705 21:20:36.901874  366922 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp 127.0.0.1:8080: connect: connection refused
 E0705 21:20:36.907567  366922 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp 127.0.0.1:8080: connect: connection refused
 E0705 21:20:36.907748  366922 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp 127.0.0.1:8080: connect: connection refused
 E0705 21:20:36.909579  366922 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp 127.0.0.1:8080: connect: connection refused
 The connection to the server localhost:8080 was refused - did you specify the right host or port?
 [root@master30 ~ 21:20:36]# kubectl  get  pods
 E0705 21:20:43.463915  367020 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp 127.0.0.1:8080: connect: connection refused
 E0705 21:20:43.464846  367020 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp 127.0.0.1:8080: connect: connection refused
 E0705 21:20:43.466617  367020 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp 127.0.0.1:8080: connect: connection refused
 E0705 21:20:43.466831  367020 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp 127.0.0.1:8080: connect: connection refused
 E0705 21:20:43.468341  367020 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp 127.0.0.1:8080: connect: connection refused
 The connection to the server localhost:8080 was refused - did you specify the right host or port?
 #把config文件再移回到.kube/config
 [root@master30 ~ 21:20:43]# mv config  .kube/
 #发现kubectl命令可以执行
 [root@master30 ~ 21:20:55]# kubectl  get  pods
 No resources found in default namespace.
 [root@master30 ~ 21:20:59]# kubectl  get  nodes
 NAME                STATUS   ROLES           AGE   VERSION
 master30.zy.cloud   Ready    control-plane   17m   v1.30.2
 worker31.zy.cloud   Ready    <none>          11m   v1.30.2
 worker32.zy.cloud   Ready    <none>          10m   v1.30.2

部署网络

这里采用 calico 网络。

官方地址:http://projectcalico.org 或者 Project Calico | Tigera – Creator of Calico

产品文档:https://projectcalico.docs.tigera.io/about/about-calico

项目地址:https://github.com/projectcalico/calico(提供镜像)

下载 calico 配置
 [root@master30 ~]# wget --no-check-certificate https://raw.githubusercontent.com/projectcalico/calico/v3.30.7/manifests/calico.yaml
 ​
 1.wget:文件下载工具
 2.--no-check-certificate:不校验 SSL 证书,国内服务器访问 github raw 常证书报错,加此参数跳过验证
 3.链接:官方提供的 Calico 完整资源清单,包含 DaemonSet、Deployment、ConfigMap、RBAC 等所有网络组件定义
 4.作用:本地得到calico.yaml,后续修改网段并部署到集群
修改 pod 网络
 # 查看集群 pod 网络范围
 [root@master30 ~ 21:18:52]# kubectl get cm -n kube-system kubeadm-config -o yaml|grep podSubnet
       podSubnet: 10.224.0.0/16
       
       
 #kubectl get cm:查询 ConfigMap 配置资源
 #-n kube-system:指定命名空间,kubeadm 初始化配置存于 kube-system
 #kubeadm-config:kubeadm 记录集群初始化参数的配置文件
 #-o yaml:以 yaml 格式完整输出配置内容
 #|grep podSubnet:管道过滤,只输出 Pod 网段配置行
 #输出podSubnet: 10.224.0.0/16:集群所有 Pod 分配的 IP 段,Calico 必须和这个网段保持一致,否则 Pod 网络不通
 ​
 # 更改 calico.yml,确保 CALICO_IPV4POOL_CIDR 与集群初始化的pod网络一致。
 [root@master30 ~ 22:11:52]# sed -i "s|# - name: CALICO_IPV4POOL_CIDR|- name: CALICO_IPV4POOL_CIDR|g" calico.yaml
 ​
 #sed -i:直接编辑文件,无需输出到控制台
 #s|匹配内容|替换内容|g:全局替换语法,用|分隔避免和 IP 斜杠冲突
 #匹配# - name: CALICO_IPV4POOL_CIDR:原文这一行是注释状态(带 #)
 #替换为- name: CALICO_IPV4POOL_CIDR:去掉注释,启用网段配置项
 ​
 [root@master30 ~ 23:8:52]# sed -i "s|#   value: \"192.*|  value: \"10.224.0.0/16\"|g" calico.yaml
 ​
 ​
 # value: "192.*":正则匹配原注释里默认 192 网段的配置
 #替换为value: "10.224.0.0/16":写入当前集群真实 Pod 网段,和 kubeadm 配置保持统一
 #两条命令合起来:开启 Calico IPv4 地址池并指定集群 Pod 网段
下载镜像
 [root@master30 ~ 21:19:06]# grep  image: calico.yaml 
           image: docker.io/calico/cni:v3.30.7
           image: docker.io/calico/node:v3.30.7
           image: docker.io/calico/kube-controllers:v3.30.7
 ​
 # 所有节点下载以上镜像
 [root@all-node ~]# nerdctl pull docker.io/calico/cni:v3.30.7
 [root@all-node ~]# nerdctl pull docker.io/calico/node:v3.30.7
 [root@all-node ~]# nerdctl pull docker.io/calico/kube-controllers:v3.30.7
部署 calico 网络
 #执行后:集群会在 kube-system 命名空间创建 calico-node(每个节点运行 1 个)、calico-kube-controllers 控制器
 [root@master30 ~]# kubectl apply -f calico.yaml
验证部署
 [root@master30 ~ 21:20:09]# kubectl  get pods --all-namespaces 
 NAMESPACE     NAME                                         READY   STATUS    RESTARTS   AGE
 kube-system   calico-kube-controllers-56fcbf9d6b-v6qsn     1/1     Running   0          28m
 kube-system   calico-node-vc9v6                            1/1     Running   0          28m
 kube-system   coredns-6d8c4cb4d-9qdxg                      1/1     Running   0          43m
 kube-system   coredns-6d8c4cb4d-wwfmx                      1/1     Running   0          43m
 kube-system   etcd-master30.laoma.cloud                    1/1     Running   0          43m
 kube-system   kube-apiserver-master30.laoma.cloud          1/1     Running   0          43m
 kube-system   kube-controller-manager-master30.laoma.cloud 1/1     Running   0          43m
 kube-system   kube-proxy-8b7tn                             1/1     Running   0          43m
 kube-system   kube-scheduler-master30.laoma.cloud          1/1     Running   0          43m

节点加入集群

 # 节点 worker31 加入集群
 [root@worker31 ~]# kubeadm join 10.1.8.30:6443 --token mi0yt8.1tzza4q64dr8y3pc \
     --discovery-token-ca-cert-hash sha256:5606e09618330aee8859abe3ea4cd8734f9b540630048a6e1c3aaf6c54d486fd
 [preflight] Running pre-flight checks
     [WARNING SystemVerification]: missing optional cgroups: blkio
 [preflight] Reading configuration from the cluster...
 [preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
 [kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
 [kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
 [kubelet-start] Starting the kubelet
 [kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...
 ​
 This node has joined the cluster:
 * Certificate signing request was sent to apiserver and a response was received.
 * The Kubelet was informed of the new secure connection details.
 ​
 Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
 ​
 # 节点 worker32 加入集群
 [root@worker32 ~]# kubeadm join 10.1.8.30:6443 --token mi0yt8.1tzza4q64dr8y3pc \
     --discovery-token-ca-cert-hash sha256:5606e09618330aee8859abe3ea4cd8734f9b540630048a6e1c3aaf6c54d486fd

如果没有保存初始化界面中加入集群命令,可以通过以下命令获取加入集群命令:

 [root@master30 ~]# kubeadm token create --print-join-command
 kubeadm join 10.1.8.30:6443 --token dzpuca.8lqxqqydwskroabx --discovery-token-ca-cert-hash sha256:5606e09618330aee8859abe3ea4cd8734f9b540630048a6e1c3aaf6c54d486fd

验证部署

 # 查看集群信息
 [root@master30 ~ 21:21:08]# kubectl  cluster-info 
 Kubernetes control plane is running at https://10.1.8.30:6443
 CoreDNS is running at https://10.1.8.30:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
 ​
 To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
 ​
 ​
 # 查看版本,正常要求:客户端和服务端大版本保持一致
 [root@master30 ~ 21:26:52]# kubectl version 
 Client Version: v1.30.2
 Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
 Server Version: v1.30.2
 ​
 #Client Version:本机 kubectl 工具版本
 #Server Version:集群 apiserver 真实版本
 ​
 ​
 # 查看节点状态
 [root@master30 ~ 21:27:10]# kubectl  get nodes
 NAME                STATUS   ROLES           AGE   VERSION
 master30.zy.cloud   Ready    control-plane   11d   v1.30.2
 worker31.zy.cloud   Ready    <none>          11d   v1.30.2
 worker32.zy.cloud   Ready    <none>          11d   v1.30.2
 ​
 ​
 输出字段说明:
 NAME:节点主机名
 STATUS:节点状态
    *Ready:满足四大条件(Calico 网络就绪、kubelet 正常运行、swap 关闭、selinux 关闭)
    *NotReady:网络插件异常 /kubelet 挂了
 ROLES:角色,master 带 control-plane,worker 无角色
 AGE:节点加入集群时长
 VERSION:节点 kubelet 版本

节点的状态为 Ready,必须满足以下条件:

  • 网络配置完成

  • 节点启动 kubelet 服务

  • swap 关闭

  • SELinux 关闭

 # 查看 pod 状态
 #-A 等价 --all-namespaces,相当于kubectl get pods --all-namespace
 [root@master30 ~ 21:28:47]# kubectl  get pods -A
 NAMESPACE     NAME                                          READY   STATUS    RESTARTS   AGE
 kube-system   calico-kube-controllers-7cb4fd5784-jx2xl      1/1     Running   0          11m
 kube-system   calico-node-4b6s8                             1/1     Running   0          11m
 kube-system   calico-node-bsr7v                             1/1     Running   0          11m
 kube-system   calico-node-v8jdn                             1/1     Running   0          11m
 kube-system   coredns-66f779496c-4j88h                      1/1     Running   0          13m
 kube-system   coredns-66f779496c-fnb8m                      1/1     Running   0          13m
 kube-system   etcd-master30.laoma.cloud                     1/1     Running   0          13m
 kube-system   kube-apiserver-master30.laoma.cloud           1/1     Running   0          13m
 kube-system   kube-controller-manager-master30.laoma.cloud  1/1     Running   0          13m
 kube-system   kube-proxy-27vl2                              1/1     Running   0          11m
 kube-system   kube-proxy-npv9h                              1/1     Running   0          11m
 kube-system   kube-proxy-q2qrs                              1/1     Running   0          11m
 kube-system   kube-scheduler-master30.laoma.cloud           1/1     Running   0          13m
 ​
 ​
 ​
 逐类拆分说明
 一. K8s 控制平面组件(master30 静态 Pod,集群核心)
 etcd-master30.zy.cloud
 kube-apiserver-master30.zy.cloud
 kube-controller-manager-master30.zy.cloud
 kube-scheduler-master30.zy.cloud
 ​
 etcd:集群数据库,存所有资源数据
 kube-apiserver:集群唯一入口,kubectl / 节点都和它通信(地址 10.1.8.30:6443)
 controller-manager:控制器,维持资源期望状态
 kube-scheduler:调度器,把 Pod 分配到节点
 信息:17h 运行时长,各重启 1 次(77 分钟前),属于正常偶发重启,无持续崩溃
 ​
 二. CoreDNS 集群内部域名解析
 coredns-7db6d8ff4d-clc6p
 coredns-7db6d8ff4d-px2fg
 ​
 2 副本 DNS 服务,Pod 之间通过服务名互相访问全靠它,运行 17 小时稳定。
 ​
 三. Calico 网络插件(集群 Pod 网络互通)
 calico-kube-controllers-585df69d45-vb7rb
 calico-node-hmhp5
 calico-node-mqrws
 calico-node-x27nl
 ​
 calico-kube-controllers:Calico 控制器,管理网络策略、IP 池
 calico-node:每个节点都会部署 1 个 DaemonSet Pod
 calico-node-mqrws:master30 主节点(27m)
 calico-node-hmhp5 /calico-node-x27nl:两台新加入 worker 节点(103s、119s,刚通过 kubeadm join 加入不久)
 作用:实现 Pod 跨节点通信、网络 NetworkPolicy 隔离。
 ​
 四. kube-proxy 节点代理(Service 负载均衡)
 kube-proxy-bj5j8
 kube-proxy-lrrx7
 kube-proxy-mb7vn
 ​
 DaemonSet,每个节点 1 个:
 kube-proxy-lrrx7:master 节点(17h)
 bj5j8 /mb7vn:两台新 worker 节点(刚加入不久)
 作用:维护节点 iptables/ipvs 规则,实现 Service 访问转发。
 ​
 五.节点数量判断
 calico-node、kube-proxy 各 3 个 Pod → 集群一共 3 台节点:
 master30 控制节点
 worker 节点 A(hmhp5 /bj5j8)
 worker 节点 B(x27nl /mb7vn)
 ​
 六.关键字段含义
 READY 1/1:容器就绪,服务正常提供能力
 Running:Pod 正在运行,无崩溃、无镜像拉取失败
 RESTARTS:重启次数,少量重启不影响;持续频繁重启才代表异常
 AGE:Pod 启动时长,两个 worker 节点是刚执行完 kubeadm join 加入集群的

更多推荐