Kubernetes v1.24 从入门到实战:核心概念与集群管理详解

Kubernetes v1.24 从入门到实战:核心概念与集群管理详解

📌 前言

Kubernetes(简称 K8s)已经成为容器编排领域的绝对标准。本文将从零开始,系统讲解 K8s 的核心概念、架构原理及实战操作,帮助读者快速上手。内容涵盖:K8s 是什么、核心架构、常用资源(Pod、Deployment、Service、Ingress、存储、配置)的使用方法,以及工作流程与网络模型。所有示例均基于 Kubernetes v1.24 ,容器运行时为 containerd

文中涉及大量 YAML 示例和命令行操作,建议读者一边阅读一边动手实践。


1. K8s 概览

1.1 什么是 Kubernetes?

Kubernetes(源于希腊语,意为"舵手")是一个开源的容器编排平台,用于自动部署、扩缩和管理容器化应用。它源自 Google 15 年的生产环境经验,具备以下核心特性:

  • 服务发现与负载均衡:无需修改应用即可使用内置的服务发现机制。
  • 存储编排:自动挂载所选的存储系统(本地存储、云存储、NFS 等)。
  • 自动上线与回滚:分步骤发布应用变更,出现问题时一键回滚。
  • 自我修复:重启失败的容器,替换不健康的节点上的容器。
  • 水平自动扩缩:根据 CPU 使用率等指标自动调整副本数量。
  • 配置与密钥管理:无需重建镜像即可更新配置和敏感信息。

对比 Docker(单机容器引擎)与 K8s(集群编排引擎):

  • Docker:负责打包应用及其依赖为镜像,提供可执行环境。
  • K8s:负责在集群中调度、运行、伸缩和管理这些容器。

1.2 K8s 核心架构(Master-Worker)

K8s 采用典型的 Master-Worker 架构:
Worker节点2
Worker节点1
Master节点
kube-apiserver
kube-scheduler
kube-controller-manager
etcd
kubelet
kube-proxy
Container Runtime
kubelet
kube-proxy
Container Runtime

组件 作用
kube-apiserver 集群统一入口,所有操作(kubectl、UI、其他组件)均通过它进行认证和授权。
kube-scheduler 负责将新创建的 Pod 分配到合适的 Worker 节点。
kube-controller-manager 运行各种控制器(Node、Deployment、Service 等),维持期望状态。
etcd 分布式键值存储,保存集群所有配置和状态数据。
kubelet Worker 节点上的代理,负责与 Master 通信并管理本节点的 Pod。
kube-proxy 维护节点上的网络规则,实现 Service 的负载均衡和集群内外的网络通信。
Container Runtime 实际运行容器的引擎(containerd、Docker 等)。

2. 快速实战

2.1 kubectl 基本用法

kubectl 是 K8s 的命令行工具,用于与 apiserver 交互。常用命令结构:

bash 复制代码
kubectl [command] [TYPE] [NAME] [flags]
command 说明 示例
get 获取资源 kubectl get pod
describe 查看详情 kubectl describe pod my-pod
create 创建资源 kubectl create -f file.yaml
apply 声明式创建/更新 kubectl apply -f file.yaml
delete 删除资源 kubectl delete pod my-pod
logs 查看容器日志 kubectl logs my-pod
exec 进入容器执行命令 kubectl exec -it my-pod -- bash

💡 提示:使用 kubectl explain <resource> 可查看资源的字段说明,例如 kubectl explain pod.spec.containers

2.2 Namespace(命名空间)

命名空间用于逻辑隔离集群资源(不隔离网络)。K8s 启动后默认有四个命名空间:

命名空间 用途
default 默认创建的资源位置
kube-system K8s 系统组件(如 kube-proxy、coredns)
kube-public 公共可读,通常用于集群级信息
kube-node-lease 存放节点心跳租约,提高节点故障检测效率

命令示例:

bash 复制代码
# 查看所有命名空间
kubectl get namespace

# 创建命名空间
kubectl create namespace tuling

# 查看某命名空间下的 Pod
kubectl get pods -n kube-system

# 删除命名空间(会删除其下所有资源)
kubectl delete namespace tuling

YAML 示例:my-namespace.yaml

yaml 复制代码
apiVersion: v1
kind: Namespace
metadata:
  name: tulingmall

执行:kubectl apply -f my-namespace.yaml

2.3 Pod(最小部署单元)

Pod 是 K8s 中可创建和管理的最小计算单元。一个 Pod 包含一个或多个容器,它们共享网络、存储和 Linux 命名空间。
Pod
Pause容器

(共享网络栈)
业务容器 A
业务容器 B

创建单容器 Pod

命令行:

bash 复制代码
kubectl run mynginx --image=nginx:1.14.2 --port=80
kubectl get pod -o wide
kubectl logs mynginx
kubectl delete pod mynginx

YAML 方式:nginx-pod.yaml

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: mynginx
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.14.2
    ports:
    - containerPort: 80

执行:kubectl apply -f nginx-pod.yaml

🤔 思考:一个 Pod 中能否运行多个容器?

可以! 例如同时运行 nginx 和 tomcat:

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: multi-container-pod
spec:
  containers:
  - name: nginx
    image: nginx:1.14.2
  - name: tomcat
    image: tomcat:9.0.55

多容器场景通常用于辅助容器(如日志收集、代理、调试)与主容器协同工作。

2.4 Deployment(声明式应用管理)

Deployment 为 Pod 提供多副本、自愈、滚动更新、回滚等功能,是生产环境最常用的控制器。
自愈重建
滚动更新
版本异常
创建Deployment
运行ReplicaSet
管理Pod副本
Pod崩溃
更新镜像
滚动更新
回滚

创建 Deployment
bash 复制代码
kubectl create deployment my-tomcat --image=tomcat:9.0.55

# 查看 deployment 和 replicaset
kubectl get deploy,rs

# 扩容到 3 副本
kubectl scale deployment my-tomcat --replicas=3

# 查看 Pod 自动增量
kubectl get pods -w
自愈能力演示

删除一个 Pod,Deployment 会立即重建它:

bash 复制代码
kubectl delete pod my-tomcat-xxxxx   # 删除后立即有新 Pod 出现
滚动更新与回滚
bash 复制代码
# 更新镜像版本到 tomcat:10.1.11
kubectl set image deployment my-tomcat tomcat=tomcat:10.1.11 --record

# 查看更新历史
kubectl rollout history deployment my-tomcat

# 回滚到上一版本
kubectl rollout undo deployment my-tomcat

# 回滚到指定版本
kubectl rollout undo deployment my-tomcat --to-revision=2
YAML 示例(Deployment)
yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-tomcat
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-tomcat
  template:
    metadata:
      labels:
        app: my-tomcat
    spec:
      containers:
      - name: tomcat
        image: tomcat:9.0.55
        ports:
        - containerPort: 8080

2.5 Service(稳定访问入口)

Service 为一组 Pod 提供固定的访问入口(ClusterIP)和负载均衡。Pod 的 IP 会变化,但 Service 的 IP 不变。

Service 类型
Type 说明
ClusterIP 默认类型,仅在集群内部可访问。
NodePort 在每个节点上开放一个静态端口(30000-32767),外部可通过 <NodeIP>:NodePort 访问。
LoadBalancer 云环境专用,自动创建外部负载均衡器。
ExternalName 返回 CNAME 记录,将服务映射到外部域名。
创建 Service 示例(NodePort)

命令行:

bash 复制代码
kubectl expose deployment my-tomcat --name=tomcat-svc --port=8080 --type=NodePort

kubectl get svc
# 输出示例:tomcat-svc   NodePort   10.107.42.139   <none>  8080:30001/TCP

外部访问:http://<任意节点IP>:30001

YAML 方式:tomcat-svc.yaml

yaml 复制代码
apiVersion: v1
kind: Service
metadata:
  name: tomcat-svc
spec:
  type: NodePort
  selector:
    app: my-tomcat          # 匹配 deployment 中的 label
  ports:
    - port: 8080            # Service 的端口
      targetPort: 8080      # Pod 的端口
      nodePort: 30001       # 节点端口(可选,不指定则随机)

2.6 存储(Volume / PV / PVC)

2.6.1 Volume 类型简介
类型 说明
emptyDir 临时目录,Pod 删除时清空,适用于缓存、临时数据。
hostPath 挂载宿主机目录,多 Pod 可共享,但易导致节点耦合,生产慎用。
configMap 注入非敏感配置。
secret 注入敏感信息(密码、证书)。
nfs 挂载 NFS 共享目录,支持多 Pod 读写。
2.6.2 搭建 NFS 共享存储(示例)

Master 节点(NFS Server):

bash 复制代码
yum install -y nfs-utils
echo "/nfs/data *(insecure,rw,sync,no_root_squash)" > /etc/exports
mkdir -p /nfs/data
systemctl enable rpcbind nfs-server
systemctl start rpcbind nfs-server
exportfs -r

Worker 节点(NFS Client):

bash 复制代码
yum install -y nfs-utils
showmount -e <Master_IP>
mkdir -p /nfs/data
mount -t nfs <Master_IP>:/nfs/data /nfs/data
2.6.3 使用 NFS Volume 的 Deployment
yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-nfs
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-nfs
  template:
    metadata:
      labels:
        app: nginx-nfs
    spec:
      containers:
      - name: nginx
        image: nginx
        volumeMounts:
        - name: html
          mountPath: /usr/share/nginx/html
      volumes:
      - name: html
        nfs:
          server: 192.168.11.101   # NFS 服务器 IP
          path: /nfs/data/nginx-pv
2.6.4 PV & PVC(存储资源抽象)
  • PV(PersistentVolume):集群级别的存储资源,由管理员预先创建。
  • PVC(PersistentVolumeClaim):用户对存储的申请(大小、访问模式等)。

创建
创建
绑定
使用
管理员
PV
用户
PVC
Pod

静态供应示例:

  1. 创建 PV(pv.yaml
yaml 复制代码
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-nfs-1gi
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  storageClassName: nfs
  nfs:
    server: 192.168.11.101
    path: /nfs/data/01
  1. 创建 PVC(pvc.yaml
yaml 复制代码
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nginx-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 200Mi
  storageClassName: nfs
  1. Pod 使用 PVC
yaml 复制代码
volumes:
- name: data
  persistentVolumeClaim:
    claimName: nginx-pvc

动态供应 (通过 StorageClass 自动创建 PV)需要部署 nfs-subdir-external-provisioner,较复杂但更灵活,本文暂略。

2.7 配置(ConfigMap & Secret)

2.7.1 ConfigMap(非敏感配置)

创建方式示例:

bash 复制代码
# 从字面量创建
kubectl create cm my-config --from-literal=key1=value1

# 从文件创建
kubectl create cm redis-conf --from-file=redis.conf

# 从 YAML 创建
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  app.properties: |
    spring.profiles.active=prod
    server.port=8080
EOF

Pod 中使用 ConfigMap(作为环境变量或文件):

yaml 复制代码
spec:
  containers:
  - name: app
    env:
    - name: KEY1
      valueFrom:
        configMapKeyRef:
          name: my-config
          key: key1
    volumeMounts:
    - name: config
      mountPath: /etc/config
  volumes:
  - name: config
    configMap:
      name: app-config
2.7.2 Secret(敏感信息)

Secret 默认存储为 base64 编码,并非加密(生产建议开启 etcd 加密)。

创建 Secret 示例:

bash 复制代码
# 从字面量
kubectl create secret generic db-secret --from-literal=username=admin --from-literal=password=123456

# 从文件
echo -n "admin" > ./username
kubectl create secret generic user-secret --from-file=./username

使用私有镜像仓库的 Secret:

bash 复制代码
kubectl create secret docker-registry myregistrykey \
  --docker-server=registry.cn-hangzhou.aliyuncs.com \
  --docker-username=yourname \
  --docker-password=yourpassword

在 Pod 中引用:

yaml 复制代码
spec:
  containers:
  - name: app
    image: registry.cn-hangzhou.aliyuncs.com/fox666/myapp:latest
  imagePullSecrets:
  - name: myregistrykey

2.8 Ingress(七层路由)

Ingress 将集群外部的 HTTP/HTTPS 流量路由到内部 Service,相比 NodePort 更灵活(支持域名、路径、TLS)。
/api
/web
外部客户端
Ingress Controller
Service A
Service B

安装 Ingress Controller(以 nginx-ingress 为例)
bash 复制代码
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.47.0/deploy/static/provider/baremetal/deploy.yaml
# 修改镜像地址为国内可拉取的镜像(如 registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images/ingress-nginx-controller:v0.46.0)
vi deploy.yaml
kubectl apply -f deploy.yaml
创建 Ingress 规则
yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: tomcat-ingress
spec:
  rules:
  - host: tomcat.tuling.com
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: tomcat-svc   # 之前创建的 Service 名称
            port:
              number: 8080

应用并测试:

bash 复制代码
kubectl apply -f ingress.yaml
kubectl get ingress

本地 hosts 添加解析:<任意节点IP> tomcat.tuling.com,浏览器访问 http://tomcat.tuling.com 即可。

Service 与 Ingress 的关系总结

Internet
Ingress
ServiceA
ServiceB
Pod1
Pod2
Pod3

  • Service:集群内部的四层负载均衡,提供稳定的 ClusterIP。
  • Ingress:集群外部的七层路由,依赖 Ingress Controller 实现。

3. K8s 核心原理

3.1 网络模型

K8s 集群中存在三种网络:

  1. 节点网络:主机物理网络,用于 Master 与 Worker 之间的通信。
  2. Pod 网络 :虚拟网络,为每个 Pod 分配独立 IP(如 Flannel 分配的 10.244.0.0/16 网段)。
  3. Service 网络:虚拟 IP 网络(ClusterIP),用于服务发现,不配置在网卡上,而是通过 kube-proxy 转换为 iptables/ipvs 规则。

Service网络
Pod网络
节点网络
Node1

192.168.65.180
Node2

192.168.65.38
Pod A

10.244.1.2
Pod B

10.244.2.3
Service

10.96.0.1

3.2 工作流程(部署 Nginx 为例)

kubelet(Node) scheduler controller-manager etcd kube-apiserver 用户(kubectl) kubelet(Node) scheduler controller-manager etcd kube-apiserver 用户(kubectl) kubectl create deployment nginx 保存 deployment 对象 监听 deployment 变更 创建 replicaset 监听未调度的 Pod 绑定 Pod 到 Node 通知创建 Pod 更新 Pod 状态 返回创建结果

3.3 核心六问

Q1:Master 与 Worker 如何通信?
  • kubelet 定期向 apiserver 注册并汇报节点状态。
  • apiserver 通过 kubelet 的 HTTPS 接口下发指令(创建、删除 Pod)。
  • kube-proxy 从 apiserver 监听到 Service 和 Endpoint 变化后更新本地规则。
Q2:调度器如何选择 Node?
  • 预选(Predicates):过滤不满足资源、端口冲突、节点选择器等的节点。
  • 优选(Priorities):对通过预选的节点打分(资源均衡、亲和性等),选最高分节点。
Q3:集群状态存在哪里?谁维护?
  • 使用 etcd 存储所有状态数据。
  • 只有 apiserver 直接读写 etcd,其他组件均通过 apiserver 间接访问。
Q4:外部用户如何访问 Pod?
  • 可通过 NodePortLoadBalancer 类型的 Service。
  • 推荐使用 Ingress 提供七层路由。
Q5:如何实现 Pod 动态扩缩容?
  • Deployment 控制器维护 replicas 字段。
  • 手动:kubectl scale deployment --replicas=5
  • 自动:配置 HorizontalPodAutoscaler(HPA),根据 CPU/内存使用率自动调整副本数。
Q6:各组件如何协作?
  • kube-controller-manager 运行众多控制器(Deployment、ReplicaSet、Node、Service 等),每个控制器是一个控制循环,通过 apiserver 获取期望状态 ,再调谐实际状态直到一致。

4. 总结与最佳实践

资源类型 作用 生产建议
Namespace 环境隔离(dev/test/prod) 不要使用 default 命名空间跑业务
Pod 最小调度单元 推荐一个 Pod 一个主容器,辅助容器(sidecar)酌情
Deployment 无状态应用管理(多副本、滚动更新、回滚) 默认使用此控制器管理 Pod
Service 为 Pod 提供稳定的访问入口和负载均衡 内部服务用 ClusterIP,对外暴露用 Ingress
Ingress 七层路由(域名、路径、TLS) 生产必备,配合 cert-manager 自动管理证书
ConfigMap 存储非敏感配置 避免存储大文件(1MB 限制)
Secret 存储敏感信息(密码、token、镜像拉取凭据) 建议启用 etcd 加密,或配合外部密钥管理工具
PV / PVC 持久化存储抽象,解耦存储与 Pod 生产使用动态供应(StorageClass)

🚀 学习路径建议

  1. 本地测试:使用 minikube 或 kind 搭建单节点集群。
  2. 核心资源:熟练掌握 Pod、Deployment、Service、Ingress 的 YAML 编写。
  3. 进阶:理解存储(PV/PVC)、配置(ConfigMap/Secret)、RBAC、Helm。
  4. 生态:Prometheus(监控)、Grafana(可视化)、Istio(服务网格)。

参考资料

本文所有操作均基于 Kubernetes v1.24.3 + containerd v1.6.4,CentOS 7.9 环境验证通过。如遇网络拉取镜像慢,可配置镜像加速器或使用阿里云镜像仓库。

下一篇预告: 《K8s 存储进阶:StatefulSet 与动态 PV 实践》

相关推荐
剩下了什么1 小时前
微服务入门介绍
微服务·云原生·架构
wuxinyan1232 小时前
Java面试题52:一文深入了解Kubernetes 核心资源对象
java·kubernetes·面试题
小义_16 小时前
【Kubernetes】(九)Service 2
云原生·容器·kubernetes
Cyber4K18 小时前
【Kubernetes专项】温故而知新,重温技术原理(2)
云原生·容器·kubernetes
雨奔21 小时前
Kubernetes 网络策略(NetworkPolicy)完全指南:声明式 Pod 通信管控
网络·容器·kubernetes
身如柳絮随风扬21 小时前
Kubernetes v1.20.9 集群搭建
云原生·容器·kubernetes
LSL666_21 小时前
微服务架构
微服务·云原生·架构
蛐蛐蛐1 天前
在Windows 11上安装Docker的踩坑记录
运维·docker·容器
AI精钢1 天前
Hermes Agent 整合 OpenCode CLI 的实战经验
人工智能·云原生·aigc