深入理解Kubernetes核心概念与架构
从一次线上故障说起
深夜,告警铃声刺破了宁静。监控大屏显示,核心交易服务的响应时间飙升至10秒,用户支付失败率骤增。你迅速登录集群,kubectl get pods 显示一切“Running”,但 kubectl describe pod 揭示了真相:某个Pod反复重启,Last State 显示 Terminated,原因为 OOMKilled。你意识到,这个容器因内存溢出被系统“杀死”了。更棘手的是,由于没有设置就绪探针(Readiness Probe),Kubernetes在容器启动过程中就将其IP加入了Service的负载均衡池,导致部分流量被导入了这个不健康的Pod,引发了雪崩。
这次故障的根源,在于对Kubernetes核心概念理解不深:我们只定义了“要运行什么镜像”,却忽略了定义“容器健康的标准”和“资源使用的边界”。Kubernetes的强大,正源于其对应用生命周期和资源抽象的一套精妙模型。
一、总览 - Kubernetes的设计哲学与核心价值
Kubernetes并非简单的“容器调度器”,它是一个以应用为中心的声明式容器编排平台。其核心设计哲学是:
- 声明式API:你告诉Kubernetes“期望的状态”(Desired State),而非具体操作步骤。它负责驱动当前状态向期望状态收敛。
- 控制器模式:一系列独立的控制循环(Control Loop)持续监听资源状态,并进行调谐(Reconcile)。
- 抽象与封装:将复杂的分布式应用部署、运维细节抽象成一系列易于理解和操作的对象。
它解决了什么问题?
- 自动化运维:自动部署、扩缩容、自愈(重启、替换、重新调度)。
- 资源高效利用:混合部署,提升数据中心资源利用率。
- 环境一致性:从开发到生产,环境高度统一。
- 松耦合的微服务架构:提供服务发现、负载均衡、配置管理,是微服务理念的天然载体。
二、集群架构审视 - 不仅仅是Master和Node

核心交互流程(创建一个Pod):
- 用户通过
kubectl向kube-apiserver提交一个Pod定义(YAML)。 - kube-apiserver 验证请求,并将其持久化存储到 etcd。
- kube-scheduler 监听(Watch)到新建的、未分配节点的Pod,根据资源需求、策略等,选择一个最合适的Node,并通过
kube-apiserver更新Pod的节点绑定信息(写回etcd)。 - 目标Node上的 kubelet 监听(Watch)到属于自己节点的、待创建的Pod,调用 容器运行时(如containerd)拉取镜像并启动容器。
- kubelet 同时将容器状态通过
kube-apiserver报告回etcd。 - kube-controller-manager 中的各种控制器(如Deployment Controller)持续运行,确保实际状态与声明的期望状态一致。
三、Pod:Kubernetes的原子单元
是什么?
Pod是Kubernetes中可以创建和管理的最小、最简单的部署单元。它是一个或多个容器的组合,这些容器共享存储、网络和命名空间。
解决什么问题?
容器本身是轻量隔离的,但有些进程需要紧密协作(如日志收集sidecar与服务容器)。Pod将它们包装成一个“逻辑主机”,使它们能通过localhost通信,共享Volume。
应用场景:
- 主应用容器 + 日志代理Sidecar容器。
- 主应用容器 + 配置文件热加载Sidecar容器。
- 紧密耦合的服务,如Web服务器与内容同步器。
YAML配置深度解析:
# kubernetes-pod-demo.yaml
apiVersion: v1 # Kubernetes API版本,Pod属于核心v1 API
kind: Pod # 资源类型,这里是Pod
metadata: # 元数据,用于标识和描述资源
name: webapp-pod # Pod名称,在命名空间内必须唯一
namespace: default # 命名空间,默认是'default'
labels: # 标签,键值对,用于识别、选择和分组对象
app: webapp # 标签键'app',值'webapp'
tier: frontend # 标签键'tier',值'frontend'
annotations: # 注解,非标识性元数据,可存储较大数据
owner: "dev-team-a" # 注解,说明此Pod的负责人
spec: # 规约,定义Pod的期望状态
containers: # 容器列表,定义Pod中运行的容器
- name: webapp # 容器名称
image: nginx:1.25-alpine # 容器镜像地址与标签
imagePullPolicy: IfNotPresent # 镜像拉取策略:本地有则用,无则拉
ports: # 容器暴露的端口列表(仅声明,不直接映射主机端口)
- name: http # 端口名称
containerPort: 80 # 容器内监听的端口
protocol: TCP # 协议,TCP或UDP
env: # 注入到容器的环境变量列表
- name: LOG_LEVEL # 环境变量名
value: "INFO" # 环境变量值
- name: DB_HOST
valueFrom: # 从其他资源获取值
configMapKeyRef:
name: app-config
key: database.host
resources: # 资源请求与限制,**生产环境必须配置!**
requests: # 调度时保证的最小资源量
memory: "64Mi" # 64 Mebibytes内存
cpu: "250m" # 0.25个CPU核心 (250 millicores)
limits: # 容器运行时允许使用的最大资源量
memory: "128Mi" # 内存限制128Mi,超过会被OOMKill
cpu: "500m" # CPU限制0.5核心,超过会被限流
livenessProbe: # 存活探针,检测容器是否“活着”
httpGet: # 通过HTTP GET请求检查
path: /healthz
port: 80
initialDelaySeconds: 10 # 容器启动后等待10秒开始探测
periodSeconds: 5 # 每5秒探测一次
failureThreshold: 3 # 连续失败3次判定为不健康
readinessProbe: # 就绪探针,检测容器是否“就绪”(可服务流量)
httpGet:
path: /ready
port: 80
initialDelaySeconds: 5
periodSeconds: 5
volumeMounts: # 将卷挂载到容器内的路径
- name: app-config # 卷名称,需与下方volumes列表匹配
mountPath: /etc/app/config
readOnly: true
- name: log-sidecar # 第二个容器:日志收集sidecar
image: busybox:latest
command: ['sh', '-c', 'tail -f /var/log/app.log']
volumeMounts:
- name: app-logs
mountPath: /var/log
volumes: # 定义Pod级别的存储卷
- name: app-config # 卷1:来自ConfigMap
configMap:
name: app-config-map
- name: app-logs # 卷2:emptyDir临时存储
emptyDir: {}
restartPolicy: Always # 容器退出时的重启策略:Always, OnFailure, Never
nodeSelector: # 节点选择器,将Pod调度到有特定标签的节点
disktype: ssd
affinity: # 亲和性规则,更高级的调度约束
podAntiAffinity: # Pod反亲和,避免同类Pod部署在同一节点
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: webapp
topologyKey: kubernetes.io/hostname
运行示例:
# 1. 创建Pod
kubectl apply -f kubernetes-pod-demo.yaml
# 输出:pod/webapp-pod created
# 2. 查看Pod状态
kubectl get pod/webapp-pod -o wide
# 输出:
# NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE
# webapp-pod 2/2 Running 0 30s 10.244.1.5 worker-node-1 <none>
# 注意:READY列显示 2/2,表示Pod内两个容器都就绪了。
# 3. 查看Pod详情(包括事件、配置、状态等)
kubectl describe pod/webapp-pod
# 4. 查看Pod内部容器日志
kubectl logs webapp-pod -c webapp # 查看主容器日志
kubectl logs webapp-pod -c log-sidecar # 查看sidecar容器日志
四、 工作负载控制器:管理Pod的生命周期
直接管理Pod是脆弱的。工作负载控制器(Controller)通过更高级别的抽象来管理Pod副本,实现自愈、扩缩等。
1. Deployment:无状态应用的管家
是什么? 声明式地管理Pod副本集(ReplicaSet),提供滚动更新、回滚等核心功能。
解决什么问题? Pod自身没有自愈能力。Deployment确保指定数量的、完全相同的Pod副本持续运行。
YAML配置深度解析:
# kubernetes-deployment-demo.yaml
apiVersion: apps/v1 # 注意:Deployment API版本是 apps/v1
kind: Deployment
metadata:
name: webapp-deployment
labels:
app: webapp
spec:
replicas: 3 # 期望的Pod副本数,核心参数
selector: # 标签选择器,决定管理哪些Pod
matchLabels:
app: webapp
strategy: # 更新策略
type: RollingUpdate # 滚动更新,默认
rollingUpdate:
maxSurge: 1 # 更新过程中最多可超出 replicas 的Pod数(可百分比或整数)
maxUnavailable: 0 # 更新过程中最多不可用的Pod数,0表示“零停机”
minReadySeconds: 5 # Pod就绪后,等待多少秒才视为可用,用于让流量完全切入
progressDeadlineSeconds: 600 # 部署进度超时时间(秒),超过标记为失败
revisionHistoryLimit: 10 # 保留的历史ReplicaSet数量,用于回滚
template: # Pod模板,与Pod spec定义一致
metadata:
labels:
app: webapp
spec:
containers:
- name: webapp
image: nginx:1.25-alpine
ports: [ { containerPort: 80 } ]
readinessProbe: { ... } # 省略,同Pod示例
resources: { ... } # 省略,同Pod示例
运行示例:
# 1. 创建Deployment
kubectl apply -f kubernetes-deployment-demo.yaml
# 输出:deployment.apps/webapp-deployment created
# 2. 查看Deployment及其管理的ReplicaSet和Pod
kubectl get deployment,replicaset,pod -l app=webapp
# 输出:
# NAME READY UP-TO-DATE AVAILABLE AGE
# deployment.apps/webapp-deployment 3/3 3 3 1m
#
# NAME DESIRED CURRENT READY AGE
# replicaset.apps/webapp-deployment-7d8f9c8b9b 3 3 3 1m
#
# NAME READY STATUS RESTARTS AGE
# pod/webapp-deployment-7d8f9c8b9b-abcx1 1/1 Running 0 1m
# pod/webapp-deployment-7d8f9c8b9b-defx2 1/1 Running 0 1m
# pod/webapp-deployment-7d8f9c8b9b-ghix3 1/1 Running 0 1m
# 3. 模拟容器故障(删除一个Pod)
kubectl delete pod webapp-deployment-7d8f9c8b9b-abcx1
# 输出:pod "webapp-deployment-7d8f9c8b9b-abcx1" deleted
# 4. 再次查看Pod,发现Deployment自动创建了新Pod
kubectl get pod -l app=webapp
# 输出:可以看到一个新名字的Pod在创建/运行,始终保持3个副本。
# 5. 滚动更新镜像版本
kubectl set image deployment/webapp-deployment webapp=nginx:1.26-alpine
# 或通过 kubectl apply -f 更新YAML文件中的镜像
# 查看更新状态
kubectl rollout status deployment/webapp-deployment
# 输出:Waiting for rollout to finish: 1 out of 3 new replicas have been updated...
# deployment "webapp-deployment" successfully rolled out
# 6. 查看更新历史
kubectl rollout history deployment/webapp-deployment
# 7. 回滚到上一个版本
kubectl rollout undo deployment/webapp-deployment
2. StatefulSet:有状态应用的守护者
是什么? 用于管理有状态应用,为Pod提供稳定的标识(有序编号、持久化存储、稳定网络标识)。
解决什么问题? 对于数据库(MySQL集群)、消息队列(Kafka)、注册中心(ZooKeeper)等,Pod需要稳定的网络标识和持久化存储,且启停顺序有要求。
关键特性:
- 稳定的Pod标识:Pod名称形如
<statefulset-name>-0,-1,-2。 - 稳定的持久化存储:通过PVC模板,每个Pod对应独立的PV,即使Pod被重新调度,也会挂载原来的数据。
- 有序部署/扩缩容:按索引顺序创建(0->1->2…),逆序删除(2->1->0)。
- 稳定的网络标识:Headless Service提供DNS记录:
<pod-name>.<svc-name>.<namespace>.svc.cluster.local。
YAML配置核心:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
serviceName: "mysql-headless" # 必须关联一个Headless Service
replicas: 3
selector: { ... }
template: { ... } # Pod模板
volumeClaimTemplates: # PVC模板,每个Pod动态创建一个PVC
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 10Gi
3. DaemonSet:节点守护者
是什么? 确保集群中所有(或部分)节点上都运行一个Pod副本。
解决什么问题? 运行集群级别的守护进程,如日志收集(Fluentd)、监控代理(Node Exporter)、网络插件(Calico)。
特点:当节点加入集群时,Pod会被调度上去;节点移除时,Pod被回收。
4. Job & CronJob:批处理任务
Job:创建一个或多个Pod,并确保指定数量的Pod成功终止。用于一次性任务。
CronJob:基于Cron时间表周期性运行的Job。用于定时任务。
五:Service与Ingress:网络抽象与流量入口
1. Service:服务的稳定访问点
是什么? 定义一组Pod的逻辑集合和访问它们的策略。为Pod提供稳定的IP地址、DNS名称和负载均衡。
解决什么问题? Pod是临时的(IP会变),Service提供了一个稳定的VIP(Cluster IP)和DNS名,将前端与后端Pod解耦。
类型:
- ClusterIP(默认):集群内部IP,只能在集群内部访问。
- NodePort:在每个节点上开放一个静态端口(NodePort),将流量转发到Service。
- LoadBalancer:使用云提供商的负载均衡器,将外部流量导入Service。
- ExternalName:将Service映射到外部DNS名称。
YAML配置深度解析:
# kubernetes-service-demo.yaml
apiVersion: v1
kind: Service
metadata:
name: webapp-service
spec:
selector: # 标签选择器,选择后端Pod
app: webapp
type: ClusterIP # Service类型
clusterIP: 10.96.100.100 # 可指定固定ClusterIP,通常自动分配
ports:
- name: http # 端口名称
port: 80 # Service自身的端口
targetPort: 80 # 后端Pod容器的端口
protocol: TCP
- name: https
port: 443
targetPort: 443
protocol: TCP
sessionAffinity: None # 会话亲和性,ClientIP/None
# externalTrafficPolicy: Local # 外部流量策略,仅对NodePort/LB有意义
运行示例:
# 1. 创建Service
kubectl apply -f kubernetes-service-demo.yaml
# 输出:service/webapp-service created
# 2. 查看Service
kubectl get svc webapp-service
# 输出:
# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
# webapp-service ClusterIP 10.96.100.100 <none> 80/TCP,443/TCP 10s
# 3. 在集群内部访问Service
kubectl run curl-test --image=radial/busyboxplus:curl -i --rm --restart=Never -- curl -I http://webapp-service.default.svc.cluster.local
# 或者使用简化的DNS名(同一命名空间下)
kubectl run curl-test --image=radial/busyboxplus:curl -i --rm --restart=Never -- curl -I http://webapp-service
# 输出:应能看到HTTP 200/OK等响应头。
# 4. 查看Service的Endpoints(实际关联的Pod IP和端口)
kubectl get endpoints webapp-service
# 输出:列出后端Pod的IP:Port
深入原理: Service的实现依赖于 kube-proxy 组件,它通过配置节点上的iptables/IPVS规则,将发往Service ClusterIP的流量负载均衡到后端Pod。
2. Ingress:集群的HTTP/HTTPS流量路由器
是什么? 管理集群外部访问内部服务的HTTP/HTTPS路由规则的API对象。本身不是服务,需要配合Ingress Controller(如Nginx Ingress Controller, Traefik)才能生效。
解决什么问题? Service的LoadBalancer类型每个服务都需要一个外部IP,昂贵且不便管理。Ingress可以提供基于域名和路径的路由、TLS终止等功能。
YAML配置深度解析:
# kubernetes-ingress-demo.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: webapp-ingress
annotations: # 注解,用于配置特定的Ingress Controller
nginx.ingress.kubernetes.io/rewrite-target: /$1
cert-manager.io/cluster-issuer: "letsencrypt-prod" # 使用cert-manager自动签发证书
spec:
ingressClassName: nginx # 指定使用哪个Ingress Controller
tls: # TLS配置
- hosts:
- webapp.example.com
secretName: webapp-tls-secret # 存储证书的Secret
rules: # 路由规则
- host: webapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: webapp-service
port:
number: 80
- host: api.example.com
http:
paths:
- path: /v1(/|$)(.*) # 路径匹配
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8080
六、ConfigMap与Secret:配置与敏感信息管理
核心思想:将应用配置与容器镜像解耦,实现“一次构建,多处运行”。
1. ConfigMap:配置管理中心
是什么? 用于存储非机密的、键值对或配置文件形式的数据。Pod可以将其作为环境变量、命令行参数或配置文件卷挂载。
# kubernetes-configmap-demo.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data: # 数据部分
# 键值对形式
LOG_LEVEL: "DEBUG"
DATABASE_URL: "jdbc:mysql://mysql:3306/appdb"
# 文件形式(多行文本)
application.properties: |
server.port=8080
spring.datasource.url=${DATABASE_URL}
logging.level.root=${LOG_LEVEL}
在Pod中使用:
# 方式1:作为环境变量
env:
- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: app-config
key: LOG_LEVEL
# 方式2:作为卷挂载
volumes:
- name: config-volume
configMap:
name: app-config
items: # 可选,选择特定键
- key: application.properties
path: app.properties
2. Secret:敏感信息保险箱
是什么? 用于存储敏感信息,如密码、OAuth令牌、SSH密钥。数据以Base64编码存储(非加密),确保不直接出现在命令行或环境变量中。
# kubernetes-secret-demo.yaml
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque # 通用类型
stringData: # 方便书写,k8s会将其base64后存入data字段
username: admin
password: Sup3rS3cr3t!
# 或者使用data字段直接写base64编码值
# data:
# username: YWRtaW4=
# password: U3VwM3JTM2NyM3Qh
# 从文件创建Secret更安全
kubectl create secret generic db-secret \
--from-file=./username.txt \
--from-file=./password.txt
七、Volume与PersistentVolume:存储抽象
Volume:Pod中容器可访问的共享目录。生命周期与Pod相同。
PersistentVolume (PV):集群级别的存储资源,由管理员预先创建或动态供应(StorageClass)。
PersistentVolumeClaim (PVC):用户对存储的“请求”,类似于Pod消耗Node资源,PVC消耗PV资源。
工作流程:Pod -> PVC -> PV -> 实际存储(NFS, Ceph, 云盘等)。
YAML配置示例(动态供应):
# 1. StorageClass (集群管理员定义)
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast-ssd
provisioner: disk.csi.azure.com # 指定存储供应者
parameters:
skuName: Premium_LRS
kind: managed
reclaimPolicy: Retain
allowVolumeExpansion: true # 允许卷扩容
# 2. PersistentVolumeClaim (用户/开发者请求)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: app-data-pvc
spec:
accessModes:
- ReadWriteOnce # 访问模式:RWO(单节点读写),RWX(多节点读写),ROX(多节点只读)
storageClassName: fast-ssd
resources:
requests:
storage: 10Gi
# 3. Pod中使用PVC
apiVersion: v1
kind: Pod
metadata:
name: app-with-pvc
spec:
containers:
- name: app
image: nginx
volumeMounts:
- name: data-storage
mountPath: /data
volumes:
- name: data-storage
persistentVolumeClaim:
claimName: app-data-pvc
八、深度原理与机制剖析
1. 控制器原理(Control Loop)
Kubernetes所有自动化能力的核心。以Deployment为例:
- 监听:Deployment Controller 持续监听(通过apiserver)所有Deployment和ReplicaSet对象的变化。
- 比较:将对象的
spec(期望状态)与当前集群中关联的ReplicaSet/Pod的实际状态进行比较。 - 调谐:如果状态不一致(如Pod副本数不足),则执行调谐操作(创建/删除Pod)。对于Deployment,它通过控制ReplicaSet来实现。
- 更新状态:将调谐后的结果更新到对象的
status字段。
这是一种声明式的最终一致性系统。
2. 调度原理(Scheduler)
调度分为两步:过滤(Filtering) 和 评分(Scoring)。
- 过滤:从所有节点中找出可调度的节点。检查节点资源是否充足、节点/Pod亲和性、污点与容忍、节点Selector等。
- 评分:对过滤后的节点打分。考虑因素包括资源平衡、Pod亲和性、数据本地性等。选择分数最高的节点。
- 绑定:将Pod绑定到选定的节点(更新Pod的
nodeName字段)。
3. 网络模型
Kubernetes强制要求所有容器无需NAT就能同其他所有容器通信,所有节点无需NAT就能同所有容器通信。这通常由CNI插件(如Calico, Flannel, Cilium)实现,它们负责配置Pod网络、网络策略等。
九、企业级最佳实践与避坑指南
结合开篇的故障,我们总结以下核心实践:
-
必须配置资源限制(Resources Limits/Requests):
- 原因:防止单个Pod耗尽节点资源,影响其他应用。
requests用于调度,limits用于运行限制。 - 错误示例:不配置或只配置
limits。 - 正确做法:根据应用压测结果,合理设置两者。通常
requests < limits。
- 原因:防止单个Pod耗尽节点资源,影响其他应用。
-
必须配置健康检查(Liveness & Readiness Probes):
- Liveness Probe:告诉K8s何时重启容器。失败会重启Pod。
- Readiness Probe:告诉K8s何时可将流量导入Pod。失败会将Pod从Service端点移除。
- 启动探针(Startup Probe) (K8s 1.16+):用于保护慢启动容器,在启动成功前禁用其他探针。
- 路径必须真实有效,且检查逻辑要轻量。
-
使用有意义的标签(Labels):
- 标签是K8s中进行分组、选择、操作资源的基石。
- 遵循命名规范,如
app,component,version,environment。
-
为容器配置合理的镜像拉取策略:
imagePullPolicy: IfNotPresent(默认非latest标签)或Always(生产环境推荐,确保使用指定版本)。
-
安全性:
- 容器以非root用户运行(
securityContext.runAsUser)。 - 设置文件系统只读(
securityContext.readOnlyRootFilesystem: true)。 - 使用
NetworkPolicy进行网络隔离。
- 容器以非root用户运行(
-
常见错误与排查命令:
- Pod一直Pending:
kubectl describe pod <pod-name>查看事件,通常是资源不足、节点选择器/污点不匹配。 - Pod一直CrashLoopBackOff:
kubectl logs <pod-name> --previous查看前一个容器的日志。 - Service无法访问:
kubectl get endpoints <svc-name>检查后端Pod是否就绪并被正确选中。 - 配置不生效:
kubectl get -f your-config.yaml -o yaml查看K8s中实际的资源定义。
- Pod一直Pending:
十、实战演练 - 部署一个完整的Web应用
让我们将上述概念串联,部署一个具有高可用、配置化、健康检查的Web应用。
步骤1:创建命名空间
kubectl create namespace demo-app
步骤2:创建ConfigMap和Secret
# config-and-secret.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
namespace: demo-app
data:
APP_COLOR: "blue"
LOG_LEVEL: "INFO"
---
apiVersion: v1
kind: Secret
metadata:
name: app-secret
namespace: demo-app
type: Opaque
stringData:
DB_PASSWORD: "demo123!"
kubectl apply -f config-and-secret.yaml
步骤3:创建Deployment
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp
namespace: demo-app
labels:
app: webapp
version: v1
spec:
replicas: 3
selector:
matchLabels:
app: webapp
template:
metadata:
labels:
app: webapp
version: v1
spec:
containers:
- name: webapp
image: nginx:1.25-alpine
ports:
- containerPort: 80
env:
- name: APP_COLOR
valueFrom:
configMapKeyRef:
name: app-config
key: APP_COLOR
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: app-secret
key: DB_PASSWORD
resources:
requests:
memory: "64Mi"
cpu: "100m"
limits:
memory: "128Mi"
cpu: "200m"
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 5
kubectl apply -f deployment.yaml
# 查看部署状态
kubectl -n demo-app get deployment,pod
步骤4:创建Service
# service.yaml
apiVersion: v1
kind: Service
metadata:
name: webapp-service
namespace: demo-app
spec:
selector:
app: webapp
ports:
- port: 80
targetPort: 80
kubectl apply -f service.yaml
# 在集群内测试访问
kubectl -n demo-app run test --image=busybox -it --rm --restart=Never -- wget -qO- http://webapp-service.demo-app.svc.cluster.local
# 应该能看到nginx欢迎页面的HTML代码
步骤5:(可选)创建Ingress
(假设已安装Nginx Ingress Controller)
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: webapp-ingress
namespace: demo-app
spec:
ingressClassName: nginx
rules:
- host: demo.k8s.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: webapp-service
port:
number: 80
kubectl apply -f ingress.yaml
# 配置本地hosts文件,将 demo.k8s.local 指向Ingress Controller的IP
# 然后在浏览器访问 http://demo.k8s.local
至此,一个符合生产级基础要求的应用已在Kubernetes中运行起来。它具备了配置分离、秘密管理、资源限制、健康检查、服务发现和外部访问能力。
结语
理解Kubernetes的核心概念,是掌握这门云原生操作系统的基础。从Pod这个最小调度单元,到管理Pod生命周期的各种Controller,再到定义访问方式的Service和Ingress,以及解耦配置的ConfigMap/Secret和提供持久化的Volume,共同构成了Kubernetes声明式应用编排的基石。
Kubernetes是一个“状态驱动”的系统。我们的角色是声明应用的期望状态,而Kubernetes的职责是不断驱动现实世界向这个状态收敛。掌握这些核心概念,才能更好地设计和部署云原生应用,让K8s真正成为你业务稳定运行的强大引擎。
更多推荐
所有评论(0)