Kubernetes:容器编排平台
目录
2.1.1 控制平面(Control Plane)- 大脑 / 管理员
2.1.2 工作节点(Worker Nodes)-劳动力 / 工人
一、概念
1.1 概念
Kubernetes(通常简称为 K8s)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。
可以把它想象成一个数据中心的操作系统,或者一个集群的“大脑”。它负责管理成千上万个容器,确保它们按照你的意愿运行:该启动的时候启动,该扩容的时候扩容,出故障的时候能自动恢复。
1.2 解决的核心问题
在容器技术(如 Docker)普及之前,部署应用非常麻烦,环境依赖、资源冲突等问题层出不穷。容器解决了“环境一致性”的问题,但当需要运行成百上千个容器时,新的挑战出现了:
-
如何管理这么多容器的生命周期? (启动、停止、重启)
-
如何实现服务发现和负载均衡? (一个容器挂了,如何让流量转到其他健康的容器?)
-
如何高效利用服务器资源? (如何把容器合理地调度到不同的机器上?)
-
如何实现滚动更新和回滚? (发布新版本时如何做到不中断服务?)
-
如何管理配置信息和敏感数据? (如密码、证书)
-
如何实现应用的弹性伸缩? (根据 CPU 负载自动增加或减少容器数量)
Kubernetes 就是为了解决这些大规模容器管理问题而生的。
1.3 核心概念与对象
-
Pod:
-
最小部署单元:Pod 是 K8s 中最小的、可创建和管理的计算单位。
-
“一个逻辑主机”:一个 Pod 包含一个或多个紧密关联的容器(比如一个主应用容器和一个日志收集的 Sidecar 容器)。这些容器共享网络命名空间(同一个 IP 地址和端口空间)、存储卷和其他资源。
-
同一个节点上的多个Pod有独立IP,并不是因为节点IP被细分了,而是Kubernetes利用Linux的网络命名空间技术,为每个Pod虚拟出了一个独立的网络环境,并从集群级别的IP地址池中为这个虚拟环境分配了一个全新的、全局唯一的IP地址。Pod 内的容器可以通过
localhost互相通信。 -
短暂存在:Pod 是短暂的,它们会被频繁地创建和销毁。每次创建一个新的 Pod,Kubernetes 都会从集群的 CIDR 地址池中动态地为它分配一个 IP 地址。因此,Pod 的 IP 不是固定的,不能直接依赖它来访问服务。
-
当 Deployment 进行版本滚动更新时,会用新 Pod 替换旧 Pod。
-
当 Pod 运行失败时,会被重启或重新调度到其他 Node。
-
当集群缩容时,Pod 会被直接删除。
-
-
一台虚拟机(节点)上可以有多个Pod,同一个节点的多个Pod共享该节点底层的物理资源,但这些Pod本身是相互隔离的。
-
-
Node(节点):
-
集群中的工作机器,可以是物理机或虚拟机。
-
每个 Node 上运行着 Kubelet(负责与主节点通信并管理 Pod)和容器运行时(如 Docker、containerd)。
-
-
Cluster(集群):
-
由一组 Node(工作节点)和一个或多个 Master(控制平面)组成。
-
Master 是集群的“大脑”,包含 API Server、Scheduler、Controller Manager 等核心管理组件。它们负责接收用户指令、调度 Pod、维护集群状态等。
-
-
Service:
-
解决了一个关键问题:Pod 是短暂的,IP 地址会变,如何让前端应用稳定地找到后端应用?
-
Service 定义了一个稳定的访问入口(固定的 IP 地址和 DNS 名称),并将流量负载均衡到一组动态变化的 Pod 上。它是服务的抽象。
-
-
Deployment(控制器):
-
最常用的控制器,定义Pod的期望状态,用于部署无状态应用(绝大多数Java微服务都是无状态的)。它管理ReplicaSet,从而控制Pod的副本数量、滚动更新和回滚。
-
是一个通过
kubectl提交给 API Server 的 API 对象(一种资源定义文件),它存在于 etcd(集群数据库)中。当交给Master后,由Master来控制集群行为。 -
通过它可以轻松实现应用的蓝绿发布、金丝雀发布和版本回滚。
-
应总是使用控制器来管理Pod,例如
Deployment(用于无状态应用)、StatefulSet(用于有状态应用)、DaemonSet、Job等。控制器能确保Pod的副本数始终符合预期,挂了一个会自动创建一个新的。 -
它负责:
-
部署和更新:实现无缝的滚动更新和回滚。
-
扩缩容:轻松地增加或减少 Pod 的副本数量。
-
自愈:如果某个 Pod 挂了,Deployment 会自动创建一个新的来替代它。
-
-
-
Namespace(命名空间):
-
在物理集群内提供的虚拟隔离。可以将集群资源划分为不同的“区域”,用于实现多租户、环境隔离(如 dev, staging, prod)等。它隔离的是 API 对象(如 Pod、Service、Deployment)。
-
不同 Namespace 的 Pod 可能运行在同一个 Node(虚拟机)上。它们共享 同一个 Node 的 CPU 和内存,但它们在 Kubernetes 内部是逻辑隔离的(默认情况下不能互相通过 Service 名访问,资源配额可以按 Namespace 限制等)。
-
开发、测试、生产环境可以部署在同一个K8s集群的不同Namespace下,资源互不干扰。
-
-
ConfigMap 和 Secret:
-
ConfigMap:用于将非机密的配置数据(如配置文件、环境变量)与容器镜像解耦。
-
Secret:类似于 ConfigMap,但专门用于存储敏感信息(如密码、OAuth 令牌、SSH 密钥),会以 base64 编码(注意:不是加密,需配合其他安全措施)。
-
1.4 核心功能
-
服务发现与负载均衡:
-
通过 Service,K8s 可以自动为 Pod 集合提供一个唯一的 DNS 名称和虚拟 IP。流量会自动在健康的 Pod 实例间分发。
-
-
存储编排:
-
可以自动挂载选择的存储系统(本地存储、公有云存储如 AWS EBS、GCP PD、网络文件系统如 NFS等)。
-
-
自动部署与回滚:
-
可以描述应用的期望状态(通过 YAML/JSON 文件),K8s 会以可控的速度(如滚动更新)将实际状态变更至期望状态。如果出现问题,可以一键回滚到之前的版本。
-
-
自动装箱(调度):
-
根据每个 Pod 对 CPU、内存等资源的请求,K8s 调度器会智能地将其放置到合适的 Node 上运行,以最大化资源利用率。
-
-
自我修复(自愈能力):
-
K8s 会不断检查 Pod 的健康状态。如果容器失败、节点宕机或健康检查不通过,它会自动重启容器、替换 Pod 或重新调度到健康节点,确保应用始终可用。
-
-
密钥与配置管理:
-
使用 ConfigMap 和 Secret 管理部署配置和敏感信息,无需重新构建容器镜像,也无需在堆栈配置中暴露密钥。
-
-
水平扩缩容:
-
可以根据 CPU 使用率或其他自定义指标,自动增加或减少 Pod 的副本数量(Horizontal Pod Autoscaler, HPA)。
-
甚至可以基于更复杂的指标进行扩缩容(如 QPS - 每秒查询数)。
-
1.5 功能边界
-
它不是 PaaS(平台即服务):
-
K8s 是一个平台的建设平台,而不是一个具体的应用平台。它提供了构建块(Primitives),而不是具体的解决方案。例如,它不提供数据库、消息队列、CI/CD 管道等“开箱即用”的服务,需要自己部署或集成。
-
-
不限定支持的应用程序类型:
-
K8s 支持各种工作负载,但它不关心运行的是无状态应用、有状态应用还是批处理任务。它只负责按照定义的规则去运行和管理它们。
-
-
不提供中间件(如消息总线、数据库):
-
需要自己部署和管理 MySQL、Redis、Kafka 等中间件,或者使用云服务商提供的托管服务并与 K8s 集成。
-
-
不负责日志、监控和告警:
-
K8s 本身提供了基础的监控指标(通过 Metrics Server),但企业级的日志收集、链路追踪、可视化监控面板(如 Grafana)和告警系统(如 Prometheus Alertmanager)需要自己搭建和集成。
-
-
不提供 CI/CD 管道:
-
可以将 Jenkins、GitLab CI、Argo CD 等 CI/CD 工具与 K8s 集成,实现自动化部署,但 K8s 本身不包含这些功能。
-
-
不解决所有网络安全问题:
-
虽然 K8s 提供了网络策略(Network Policies)来控制 Pod 之间的网络流量,但更复杂的安全策略(如 WAF - Web 应用防火墙)通常需要额外的工作。
-
1.6 应用场景
-
微服务架构:
-
天然契合:微服务架构将应用拆分为多个小型、独立的服务。K8s 的 Service、Deployment、配置管理等功能,完美地解决了微服务的部署、发现、通信和治理问题。
-
-
传统应用现代化(迁移上云):
-
将传统的单体应用进行容器化改造,并部署到 K8s 上,可以立即获得弹性伸缩、高可用和敏捷部署等云原生能力。
-
-
混合云与多云部署:
-
K8s 提供了跨不同云服务商(AWS, Azure, GCP)或混合云(本地数据中心+公有云)的一致性的部署和管理体验,避免被单一云厂商锁定。
-
-
部署复杂的有状态应用:
-
早期 K8s 主要针对无状态应用,但现在通过 StatefulSet、Persistent Volumes 等对象,可以稳定地运行数据库(如 MySQL集群)、缓存系统(如 Redis集群)、大数据框架(如 Spark)等有状态应用。
-
-
批处理任务和机器学习:
-
使用 Job 和 CronJob 控制器,可以方便地运行一次性任务或定时任务,例如数据备份、报表生成、模型训练等。
-
-
高流量、需要快速弹性伸缩的网站/API:
-
例如电商网站在大促期间,可以利用 K8s 的 HPA 功能,根据流量自动扩容,平稳度过高峰,并在高峰过后自动缩容以节省成本。
-
不需要Kubernetes的场景:
-
团队规模小,应用非常简单:如果你的应用只是一个简单的单体应用,且流量稳定,使用 K8s 会引入不必要的复杂性。直接使用虚拟机或简单的 PaaS(如 Heroku)可能更高效。
-
缺乏运维经验和专业知识:K8s 的学习曲线陡峭,管理和维护一个生产级 K8s 集群需要深厚的知识。此时可以考虑使用托管K8s服务(如 GKE, EKS, AKS),将控制平面的管理负担交给云厂商。
-
对资源极其敏感:K8s 集群本身(控制平面和工作节点上的组件)会消耗一定的计算资源。对于资源极其受限的边缘场景,可能更轻量级的方案(如 K3s)更合适。
二、架构与原理
2.1 核心架构
Kubernetes 遵循经典的客户端-服务器架构。一个 Kubernetes 集群由一组机器(物理机或虚拟机)组成,这些机器被分为两种角色:
2.1.1 控制平面(Control Plane)- 大脑 / 管理员
控制平面是集群的“指挥中心”,负责管理集群的所有决策。它通常包含以下核心组件:
-
kube-apiserver:集群的网关和总控台。所有与集群的通信(无论是来自内部组件还是外部用户命令
kubectl)都必须通过 API Server。它是唯一与 etcd 直接交互的组件。负责请求的认证、授权和准入控制。API Server 是无状态的,其状态数据存储在etcd中。为了高可用,可以部署多个 API Server 实例进行负载均衡。 -
etcd:集群的“记忆库”。一个高可用、强一致性的分布式键值数据库,持久化存储了整个集群的所有配置数据和工作状态(例如,有哪些 Pod、运行在哪个节点上等)。它是 Kubernetes 的“唯一信源”。它是 Kubernetes 集群的唯一有状态的核心组件,其数据的安全性和高可用性至关重要。通常需要为其配置备份和高可用方案。
-
kube-scheduler:调度中心。它负责监听 API Server,,发现新建的、还未被分配到任何节点的 Pod(其
nodeName为空),并根据资源需求、策略等因素,选择一个最合适的 Node 来运行它。Scheduler 只做决策,不执行。它通过 API Server 将决策(更新 Pod 的nodeName字段)写入 etcd。 -
kube-controller-manager:控制器管家。它内部运行着多种控制器(Controller),每个控制器都是一个独立的控制循环,负责监控集群的状态并确保其与期望状态一致。
-
节点控制器(Node Controller):负责节点宕机后的通知和响应。
-
副本控制器(Replication Controller):确保 Pod 的副本数量始终与期望值一致(例如,Deployment 的控制器)。
-
端点控制器:为 Service 填充 Endpoint 对象(即 Pod IP:Port)。
-
服务账户和令牌控制器:为新的命名空间创建默认账户和 API 访问令牌。
-
-
cloud-controller-manager:云平台联络员。用于与底层云提供商(如 AWS、GCP、Azure)的 API 交互,管理负载均衡器、存储卷等云资源。
2.1.2 工作节点(Worker Nodes)-劳动力 / 工人
工作节点是真正运行应用程序容器的地方。每个节点上都必须运行以下组件:
-
kubelet:节点代理。它是控制平面在该节点上的“代表”,负责与 API Server 通信,管理本节点上 Pod 的生命周期(如创建、销毁 Pod),并确保容器健康运行。定期向 API Server 汇报节点和 Pod 的状态(如 CPU/内存使用情况)。kubelet 不管理非 Kubernetes 创建的容器。
-
kube-proxy:网络代理。它负责维护节点上的网络规则,实现 Kubernetes Service 的概念,如负载均衡和将流量转发到正确的 Pod。实现方式可以是
iptables(默认)或ipvs(性能更好)。 -
容器运行时(Container Runtime):容器引擎。是真正负责下载容器镜像、启动和停止容器的组件,最常见的是 Docker、containerd、CRI-O 等。Kubernetes 通过 容器运行时接口 支持多种运行时,如
containerd(目前最主流)、CRI-O等。早期直接使用 Docker,但现在通过 CRI 与容器运行时交互,Docker 本身已被containerd取代。

2.2 一个简单的工作流程示例
假设要部署一个包含 3 个副本的 Nginx 应用:
-
定义 YAML 文件:编写一个
deployment.yaml文件,描述期望状态:使用 Nginx 镜像,创建 3 个副本。 -
kubectl提交 YAML:使用kubectl apply -f deployment.yaml命令将文件提交给kube-apiserver。 -
API Server 持久化:
kube-apiserver对请求进行认证和验证,然后将期望状态写入etcd。 -
Deployment 控制器检测到变化:Deployment 控制器通过 Watch 机制发现了新的 Deployment 对象。它意识到需要创建对应的 ReplicaSet。
-
ReplicaSet 控制器开始工作:ReplicaSet 控制器发现新的 ReplicaSet,并意识到当前 Pod 数量(0)与期望数量(3)不符。它通过 API Server 创建 3 个 Pod 定义(此时 Pod 还没有被调度)。
-
调度器发现待调度的 Pod:调度器
kube-scheduler发现这 3 个新的 Pod 的nodeName为空。它开始执行调度流程:-
预选:过滤掉所有不健康的、资源不足的节点。
-
优选:对剩余节点打分,选出最优的 3 个节点(可能分散在不同节点上)。
-
-
调度器绑定:调度器
kube-scheduler将 Pod 与节点绑定的信息(更新 Pod 的nodeName字段)通过kube-apiserver写入 etcd。 -
目标节点上的 kubelet 被唤醒:各个被选中的节点上的 kubelet 通过 Watch 机制发现有一个 Pod 被调度到了自己这里。
-
kubelet 创建 Pod:
-
kubelet 通过容器运行时接口调用本地的容器运行时(如
containerd)。 -
容器运行时从镜像仓库拉取 Nginx 镜像。
-
创建并启动容器。
-
-
kubelet 上报状态:kubelet 持续监控容器状态,并通过 API Server 将 Pod 的状态(如
Running)更新回 etcd。kubelet会持续向控制平面报告 Pod 的状态。如果有一个 Pod 崩溃,Replication Controller(由kube-controller-manager管理)会检测到实际状态与期望状态(3个副本)不符,于是它会创建新的 Pod 来替代。 -
kube-proxy 更新网络规则:在整个过程中,如果创建了 Service,kube-proxy 会监听到 Service 和 Endpoint 的变化,并在本机更新
iptables/ipvs规则,以便将服务流量负载均衡到新创建的 Pod。 -
提供服务:你创建一个
Service,它通过标签找到这 3 个 Nginx Pod,并提供统一的访问入口。
三、使用
3.1 K8S安装
3.1.1 安装前的环境准备
-
服务器:至少准备两台(一台Master,一台Node)Linux机器。虚拟机或物理机均可。
-
操作系统:推荐使用 Ubuntu 16.04/18.04/20.04 或 CentOS 7/8 等稳定版本。
-
硬件配置:每个节点建议至少 2核CPU 和 2GB内存。
-
网络:确保所有节点之间网络互通。
在系统层面,需要完成以下配置:
- 关闭 Swap:Kubernetes 要求必须禁用交换分区(Swap)。
swapoff -a # 临时关闭
sed -i '/swap/s/^/#/' /etc/fstab # 永久关闭,注释掉swap行
-
配置主机名与解析:为每个节点设置唯一的主机名,并确保
/etc/hosts文件包含所有节点的IP和主机名映射。 -
时间同步:确保所有节点时间准确,安装并启用NTP服务。
-
开放防火墙端口:根据你选择的网络插件等,需要在防火墙中放行必要的端口。以下是一些核心端口:
| 组件/协议 | 端口 | 说明 |
|---|---|---|
| API Server | 6443/TCP | 所有组件通信的入口 |
| etcd | 2379-2380/TCP | 数据库客户端API(如果etcd部署在控制平面节点上) |
| Kubelet API | 10250/TCP | 节点上与Kubelet通信的端口 |
| NodePort Services | 30000-32767/TCP | 对外暴露服务的外部端口范围 |
3.1.2 使用 kubeadm 搭建集群
步骤 1: 安装容器运行时(所有节点)
Kubernetes 需要容器运行时来管理容器。以安装 Docker 为例:
# 更新软件包索引
sudo apt-get update
# 安装Docker
sudo apt-get install -y docker.io
# 设置开机自启并启动Docker服务
sudo systemctl enable docker
sudo systemctl start docker
步骤 2: 安装 kubeadm、kubelet、kubectl(所有节点)
添加 Kubernetes 软件源:由于网络原因,在国内环境下建议使用国内镜像源,例如阿里云。
# 更新apt包索引并安装依赖
sudo apt-get update && sudo apt-get install -y apt-transport-https curl
# 添加Kubernetes的GPG密钥
curl -s https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | sudo apt-key add -
# 添加阿里云的Kubernetes软件源
cat <<EOF | sudo tee /etc/apt/sources.list.d/kubernetes.list
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
EOF
sudo apt-get update
安装核心组件:
sudo apt-get install -y kubelet kubeadm kubectl
# 阻止这三个包被自动升级,避免版本不兼容
sudo apt-mark hold kubelet kubeadm kubectl
步骤 3: 初始化控制平面(Master节点)
在主节点上执行初始化命令:
# --pod-network-cidr 需要与你将要安装的网络插件匹配
sudo kubeadm init --pod-network-cidr=10.244.0.0/16
重要! 初始化成功后会输出一行 kubeadm join 命令,请务必复制保存,后续加入工作节点时需要用到。
步骤 4: 配置 kubectl(Master节点)
让当前用户能够使用 kubectl 管理集群。
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
步骤 5: 安装 Pod 网络插件(Master节点)
没有网络插件,Pod 之间无法通信。这里以 Flannel 为例。
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
步骤 6: 加入工作节点(Node节点)
在每个工作节点上,执行步骤3中保存的 kubeadm join 命令。
sudo kubeadm join <Master节点的IP>:6443 --token <token> --discovery-token-ca-cert-hash sha256:<hash>
步骤 7: 验证集群状态(Master节点)
在所有节点加入后,在Master节点执行以下命令检查集群状态。
# 查看所有节点状态,确认状态都是 Ready
kubectl get nodes
3.1.3 部署应用
集群运行起来后,可以快速部署一个测试应用(如Nginx)来验证一切正常。
# 创建一个Deployment来运行Nginx容器
kubectl create deployment nginx --image=nginx:1.18
# 创建一个Service将Nginx暴露到集群外(通过NodePort方式)
kubectl expose deployment nginx --type=NodePort --port=80 --target-port=80 --name=nginx-service
# 查看服务详情,获取外部访问的端口
kubectl get svc nginx-service
之后,就可以通过任意节点的IP地址和分配的端口(如 http://<节点IP>:31000)在浏览器中访问这个Nginx服务了。
3.2 托管 K8S 服务
对于生产环境,强烈推荐使用云厂商的托管服务,它们负责管理控制平面,你只需关心工作节点。
-
Google GKE (Google Kubernetes Engine)
-
Amazon EKS (Elastic Kubernetes Service)
-
Microsoft AKS (Azure Kubernetes Service)
-
阿里云 ACK (Container Service for Kubernetes)
只需在云控制台点击几下,或使用 CLI 工具,即可创建一个高可用的生产级集群。
3.3 YAML文件
Kubernetes (K8S) 的 YAML 文件是定义和配置 Kubernetes 资源的核心。
Kubernetes 的 YAML 文件主要包含以下四个顶层(根级)字段,它们是几乎所有资源的基石:
-
apiVersion: 指定使用的 Kubernetes API 的版本。不同的资源对象存在于不同的 API 组中。-
核心组(如 Pod、Service、Namespace):
v1 -
Apps 组(如 Deployment、StatefulSet):
apps/v1 -
批处理组(如 Job):
batch/v1 -
扩展组(如 Ingress):
networking.k8s.io/v1
-
-
kind: 定义要创建的资源类型。例如:Pod,Service,Deployment,ConfigMap,Secret等。 -
metadata: 存放资源的元数据,用于标识和描述资源。-
name: 资源的名称,在同一个命名空间内必须唯一。 -
namespace: (可选) 资源所属的命名空间。不指定则默认为default。 -
labels: (可选) 键值对标签,用于标识、选择和分组资源。非常灵活和重要。 -
annotations: (可选) 键值对注释,用于存储非识别性的元数据,供工具或库使用(如版本信息、构建信息等)。
-
-
spec: 这是文件的核心,意为“规约”或“期望状态”。你在这里详细描述你希望资源达到什么样的状态。例如,对于 Pod,你会在这里定义它包含哪些容器、使用什么镜像等。每个资源类型的spec结构都完全不同。 -
status: (自动生成) 描述了资源的实际状态。这个字段是由 Kubernetes 系统自动填充和更新的,你永远不需要在创建的 YAML 文件中定义它。它反映了资源当前的健康状况、IP 地址等信息。
常用资源spec字段详解:
Pod (kind: Pod) 的 spec
-
Pod: 最小的可部署计算单元,通常容纳一个或多个容器。
| 字段 | 子字段 | 数据类型 | 是否必填 | 详细解说与示例 |
|---|---|---|---|---|
containers | - | List<Object> | 是 | 定义 Pod 中运行的容器列表。 |
containers[].name | String | 是 | 容器的名称。示例: nginx-container | |
containers[].image | String | 是 | 容器镜像地址。示例: nginx:1.20.1 | |
containers[].ports | List<Object> | 否 | 容器暴露的端口列表(主要是声明性作用,不影响网络)。 | |
containers[].ports[].containerPort | Integer | 否 | 容器内监听的端口号。示例: 80 | |
containers[].env | List<Object> | 否 | 传递给容器的环境变量列表。 | |
containers[].env[].name | String | 是 | 环境变量名称。示例: DB_HOST | |
containers[].env[].value | String | 否 | 环境变量的值。示例: mysql-service | |
containers[].resources | Object | 推荐 | 容器资源请求和限制,对集群稳定性至关重要。 | |
resources.requests | Object | 否 | 容器启动所需的最小资源量(调度依据)。示例: memory: "64Mi", cpu: "250m" | |
resources.limits | Object | 否 | 容器所能使用的最大资源量。示例: memory: "128Mi", cpu: "500m" |
Deployment (kind: Deployment, apiVersion: apps/v1) 的 spec
-
Deployment: 管理 Pod 副本和更新的控制器。
| 字段 | 子字段 | 数据类型 | 是否必填 | 详细解说与示例 |
|---|---|---|---|---|
replicas | - | Integer | 否 | 期望的 Pod 副本数量,默认为 1。示例: 3 |
selector | - | Object | 是 | 标签选择器,Deployment 通过它来识别要管理的 Pod。 |
selector.matchLabels | Map<String, String> | 是 | 必须与下面 template 中定义的 Pod 标签匹配。示例: app: my-app | |
template | - | Object | 是 | 用于创建新 Pod 的模板。其下就是 Pod 的 metadata 和 spec。 |
template.metadata | Object | 是 | Pod 的元数据,必须包含 selector 中指定的标签。 | |
template.spec | Object | 是 | Pod 的规约,与上述 Pod 的 spec 结构完全一致。 |
Service (kind: Service) 的 spec
-
Service: 为一组 Pod 提供稳定的网络访问入口。
| 字段 | 子字段 | 数据类型 | 是否必填 | 详细解说与示例 |
|---|---|---|---|---|
type | - | String | 否 | Service 的类型。可选值: ClusterIP (默认,集群内访问), NodePort (通过节点IP访问), LoadBalancer (云平台负载均衡器) |
selector | - | Map<String, String> | 是 (对于 ClusterIP/NodePort) | 标签选择器,Service 通过它来发现并代理后端的 Pod。示例: app: my-app |
ports | - | List<Object> | 是 | 端口映射规则列表。 |
ports[].port | Integer | 是 | Service 自身暴露的端口。示例: 80 | |
ports[].targetPort | Integer/String | 否 | 后端 Pod 容器的端口(对应 containerPort),默认与 port 相同。示例: 80 或 http | |
ports[].nodePort | Integer | 否 | 当 type=NodePort 时,节点上映射的端口(30000-32767)。 |
3.4 简单的使用
举例:在K8S中部署3台Nginx和2台SpringBoot服务
1、部署SpringBoot服务
SpringBoot Deployment配置
# springboot-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: springboot-app
labels:
app: springboot-app
spec:
replicas: 2
selector:
matchLabels:
app: springboot-app
template:
metadata:
labels:
app: springboot-app
spec:
containers:
- name: springboot-app
image: your-springboot-image:latest # 替换为您的镜像
ports:
- containerPort: 8080
env:
- name: SPRING_PROFILES_ACTIVE
value: "prod"
resources:
requests:
memory: "512Mi"
cpu: "250m"
limits:
memory: "1Gi"
cpu: "500m"
SpringBoot Service配置
# springboot-service.yaml
apiVersion: v1
kind: Service
metadata:
name: springboot-service
spec:
selector:
app: springboot-app
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: ClusterIP
2、部署Nginx服务
Nginx ConfigMap配置(包含反向代理配置)
# nginx-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
data:
nginx.conf: |
events {
worker_connections 1024;
}
http {
upstream springboot_backend {
server springboot-service:80;
}
server {
listen 80;
location / {
proxy_pass http://springboot_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# 健康检查
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
}
}
Nginx Deployment配置
# nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
volumeMounts:
- name: nginx-config
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf
livenessProbe:
httpGet:
path: /health
port: 80
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /health
port: 80
initialDelaySeconds: 5
periodSeconds: 5
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"
volumes:
- name: nginx-config
configMap:
name: nginx-config
items:
- key: nginx.conf
path: nginx.conf
Nginx Service配置(对外暴露)
# nginx-service.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
type: LoadBalancer # 或者使用NodePort根据您的环境选择
部署命令
# 应用所有配置
kubectl apply -f .
# 或者分别部署
kubectl apply -f springboot-deployment.yaml
kubectl apply -f springboot-service.yaml
kubectl apply -f nginx-configmap.yaml
kubectl apply -f nginx-deployment.yaml
kubectl apply -f nginx-service.yaml
验证部署
# 检查Pod状态
kubectl get pods -o wide
# 检查Service
kubectl get services
# 检查Deployment
kubectl get deployments
# 查看Pod日志
kubectl logs -l app=springboot-app --tail=50
kubectl logs -l app=nginx --tail=50
# 测试服务连通性
kubectl exec -it <nginx-pod> -- curl http://springboot-service/health
扩展配置(可选)
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: your-domain.com # 替换为您的域名
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-service
port:
number: 80
3.5 常用命令
3.5.1 全局和集群管理命令
这些命令用于查看集群状态和配置。
| 命令 | 作用 | 示例 |
|---|---|---|
kubectl version | 查看客户端和服务器端的 Kubernetes 版本 | kubectl version --short (简洁显示) |
kubectl cluster-info | 显示集群主节点和核心服务的地址 | kubectl cluster-info |
kubectl config current-context | 显示当前使用的上下文(环境) | kubectl config current-context |
kubectl config get-contexts | 列出所有可用的上下文 | kubectl config get-contexts |
kubectl config use-context <context-name> | 切换到指定的上下文(如从开发切换到生产) | kubectl config use-context prod-cluster |
kubectl get nodes | 查看集群中所有节点的状态 |
3.5.2 核心资源操作命令(增删改查)
这是最常用的一组命令,适用于几乎所有资源类型(Pod, Deployment, Service 等)。其通用语法是 kubectl <动作> <资源类型> [资源名称]。
a) 查询和查看(Get & Describe)
| 命令 | 作用 | 示例和常用参数 |
|---|---|---|
kubectl get | 列出资源。最基本、最常用的命令。 | kubectl get podskubectl get deploymentskubectl get services 或 kubectl get svckubectl get all (列出所有常见资源) |
| 常用参数 | -n <namespace>: 指定命名空间-o wide: 显示更详细信息(如IP,节点)-o yaml 或 -o json: 以YAML/JSON格式输出--watch 或 -w: 实时监听资源变化 | kubectl get pods -n kube-systemkubectl get pod my-pod -o yaml |
kubectl describe | 详细描述某个资源的状态、事件、配置等。用于排障。 | kubectl describe pod <pod-name>kubectl describe deployment/<deployment-name> |
kubectl explain | 查看某个资源的字段说明,写YAML时的好帮手。 | kubectl explain pod.spec.containers |
b) 创建和删除(Create & Delete)
| 命令 | 作用 | 示例 |
|---|---|---|
kubectl create | 命令式创建资源。通常通过 YAML 文件。 | kubectl create -f my-deployment.yaml |
kubectl apply | 声明式创建或更新资源。推荐使用此命令,因为它可以幂等地应用配置。 | kubectl apply -f my-deployment.yaml |
kubectl delete | 删除资源。 | kubectl delete -f my-deployment.yaml (通过文件删除)kubectl delete pod <pod-name> (直接删除指定资源)kubectl delete deployment <deployment-name> --force --grace-period=0 (强制立即删除) |
c) 编辑和更新(Edit & Patch)
| 命令 | 作用 | 示例 |
|---|---|---|
kubectl edit | 直接编辑集群中的现有资源配置。会打开默认编辑器(如vim)。 | kubectl edit deployment/<deployment-name> |
kubectl patch | 对资源进行局部更新,无需编辑整个文件。 | kubectl patch deployment my-deployment -p '{"spec":{"replicas": 3}}' |
kubectl scale | 伸缩 Pod 副本数量。 | kubectl scale deployment/<deployment-name> --replicas=5 |
kubectl set image | 更新 Deployment 的容器镜像,触发滚动更新。 | kubectl set image deployment/<deployment-name> nginx=nginx:1.19 |
3.5.3 Pod 故障排查和交互命令
当 Pod 出现问题时,这些命令至关重要。
| 命令 | 作用 | 示例和常用参数 |
|---|---|---|
kubectl logs | 查看 Pod 中容器的日志。 | kubectl logs <pod-name>kubectl logs -f <pod-name> (实时追踪日志,类似 tail -f)kubectl logs <pod-name> -c <container-name> (Pod内含多个容器时指定) |
kubectl exec | 在 Pod 的容器中执行命令。用于交互式调试。 | kubectl exec -it <pod-name> -- /bin/bash (进入容器的shell)kubectl exec <pod-name> -- ls /app (执行单条命令) |
kubectl port-forward | 将本地端口转发到 Pod 的端口。用于临时访问集群内部服务。 | kubectl port-forward <pod-name> 8080:80 (将本地8080转发到Pod的80端口)kubectl port-forward service/<svc-name> 8080:80 (转发到Service) |
kubectl cp | 在本地和 Pod 容器之间复制文件。 | kubectl cp /local/file <pod-name>:/path/in/podkubectl cp <pod-name>:/path/to/file /local/dest |
3.5.4 特定资源常用命令
| 资源类型 | 常用命令 | 说明 |
|---|---|---|
| Deployment | kubectl rollout status deployment/<name> | 查看滚动更新的状态 |
kubectl rollout history deployment/<name> | 查看更新历史 | |
kubectl rollout undo deployment/<name> | 回滚到上一个版本 | |
kubectl rollout undo deployment/<name> --to-revision=2 | 回滚到指定版本 | |
| ConfigMap/Secret | kubectl get configmap | 查看ConfigMap |
kubectl create secret generic my-secret --from-literal=key=value | 命令式创建Secret |
3.5.6 高级技巧和实用别名
- 使用别名提高效率
将 kubectl 别名设置为 k,并设置一些常用资源的别名。
alias k=kubectl
alias kgp='k get pods'
alias kgd='k get deployments'
alias kdp='k describe pod'
在 ~/.bashrc 或 ~/.zshrc 中配置使其永久生效。
-
动态补全(Auto Completion)
启用
kubectl的自动补全功能,可以大幅提高输入准确性和速度。Bash:
source <(kubectl completion bash)Zsh:
source <(kubectl completion zsh) -
--dry-run=client -o yaml这是一个非常有用的技巧,可以生成一个基础的 YAML 模板,而无需真正创建资源。然后可以基于这个模板进行修改。
kubectl create deployment my-nginx --image=nginx --dry-run=client -o yaml > deployment.yaml
3.6 Pod故障排查流程
假设一个 Pod 无法正常运行,一个典型的排查流程是:
-
查看状态:
kubectl get pods -o wide(看Pod是否Running,在哪个节点) -
查看详情:
kubectl describe pod <problem-pod-name>(查看Events部分,常有错误原因) -
查看日志:
kubectl logs <problem-pod-name>(查看应用本身的错误输出) -
进入Pod:如果日志不清,尝试
kubectl exec -it <problem-pod-name> -- /bin/sh进入容器内部检查。 -
端口转发测试:
kubectl port-forward <problem-pod-name> 8080:80,然后在本地用curl localhost:8080测试服务是否正常。
更多推荐



所有评论(0)