Kubernetes了解与应用

文章目录

Kubernetes(常简称为 K8s )是一个开源的 容器编排平台 ,用于自动部署、扩展和管理容器化应用程序。

核心作用

服务发现与负载均衡 :自动分配 IP,为容器组提供统一访问入口并分发流量。

存储编排 :可挂载多种存储系统(本地、云存储等)。

自动部署与回滚 :支持滚动更新,且能自动回滚到上一版本。

弹性伸缩 :根据 CPU/内存或自定义指标自动扩缩应用实例数。

自我修复 :重启失败容器、替换不响应健康检查的节点、阻止未就绪的容器接收流量。

密钥与配置管理:管理敏感信息(密码、令牌、证书)和应用配置。

  • 启用 Kubernetes 前后的核心区别

    维度 未启用 K8s 已启用 K8s
    容器管理 管理单个容器 管理 Pod(一组容器)
    扩容能力 手动启动多个容器 kubectl scale 一键扩容
    负载均衡 手动配置反向代理 Service 自动负载均衡
    服务发现 手动记录 IP:端口 DNS 自动服务发现
    自愈能力 ❌ 容器挂了需要手动重启 ✅ 自动重启、重建 Pod
    滚动更新 手动逐个替换容器 kubectl rollout 零停机更新
    配置管理 环境变量或挂载文件 ConfigMap + Secret

整体架构

#mermaid-svg-ugkuR3MAbVU6Gdbh{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-ugkuR3MAbVU6Gdbh .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ugkuR3MAbVU6Gdbh .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ugkuR3MAbVU6Gdbh .error-icon{fill:#552222;}#mermaid-svg-ugkuR3MAbVU6Gdbh .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ugkuR3MAbVU6Gdbh .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ugkuR3MAbVU6Gdbh .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ugkuR3MAbVU6Gdbh .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ugkuR3MAbVU6Gdbh .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ugkuR3MAbVU6Gdbh .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ugkuR3MAbVU6Gdbh .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ugkuR3MAbVU6Gdbh .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ugkuR3MAbVU6Gdbh .marker.cross{stroke:#333333;}#mermaid-svg-ugkuR3MAbVU6Gdbh svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ugkuR3MAbVU6Gdbh p{margin:0;}#mermaid-svg-ugkuR3MAbVU6Gdbh .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-ugkuR3MAbVU6Gdbh .cluster-label text{fill:#333;}#mermaid-svg-ugkuR3MAbVU6Gdbh .cluster-label span{color:#333;}#mermaid-svg-ugkuR3MAbVU6Gdbh .cluster-label span p{background-color:transparent;}#mermaid-svg-ugkuR3MAbVU6Gdbh .label text,#mermaid-svg-ugkuR3MAbVU6Gdbh span{fill:#333;color:#333;}#mermaid-svg-ugkuR3MAbVU6Gdbh .node rect,#mermaid-svg-ugkuR3MAbVU6Gdbh .node circle,#mermaid-svg-ugkuR3MAbVU6Gdbh .node ellipse,#mermaid-svg-ugkuR3MAbVU6Gdbh .node polygon,#mermaid-svg-ugkuR3MAbVU6Gdbh .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ugkuR3MAbVU6Gdbh .rough-node .label text,#mermaid-svg-ugkuR3MAbVU6Gdbh .node .label text,#mermaid-svg-ugkuR3MAbVU6Gdbh .image-shape .label,#mermaid-svg-ugkuR3MAbVU6Gdbh .icon-shape .label{text-anchor:middle;}#mermaid-svg-ugkuR3MAbVU6Gdbh .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-ugkuR3MAbVU6Gdbh .rough-node .label,#mermaid-svg-ugkuR3MAbVU6Gdbh .node .label,#mermaid-svg-ugkuR3MAbVU6Gdbh .image-shape .label,#mermaid-svg-ugkuR3MAbVU6Gdbh .icon-shape .label{text-align:center;}#mermaid-svg-ugkuR3MAbVU6Gdbh .node.clickable{cursor:pointer;}#mermaid-svg-ugkuR3MAbVU6Gdbh .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-ugkuR3MAbVU6Gdbh .arrowheadPath{fill:#333333;}#mermaid-svg-ugkuR3MAbVU6Gdbh .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-ugkuR3MAbVU6Gdbh .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ugkuR3MAbVU6Gdbh .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ugkuR3MAbVU6Gdbh .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-ugkuR3MAbVU6Gdbh .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ugkuR3MAbVU6Gdbh .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-ugkuR3MAbVU6Gdbh .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-ugkuR3MAbVU6Gdbh .cluster text{fill:#333;}#mermaid-svg-ugkuR3MAbVU6Gdbh .cluster span{color:#333;}#mermaid-svg-ugkuR3MAbVU6Gdbh div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-ugkuR3MAbVU6Gdbh .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-ugkuR3MAbVU6Gdbh rect.text{fill:none;stroke-width:0;}#mermaid-svg-ugkuR3MAbVU6Gdbh .icon-shape,#mermaid-svg-ugkuR3MAbVU6Gdbh .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ugkuR3MAbVU6Gdbh .icon-shape p,#mermaid-svg-ugkuR3MAbVU6Gdbh .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-ugkuR3MAbVU6Gdbh .icon-shape .label rect,#mermaid-svg-ugkuR3MAbVU6Gdbh .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ugkuR3MAbVU6Gdbh .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-ugkuR3MAbVU6Gdbh .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-ugkuR3MAbVU6Gdbh :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 🌐 外部
🖥️ 工作节点 2
🖥️ 工作节点 1
🎛️ 控制平面 (Control Plane)
kube-apiserver

📡 集群入口
kube-scheduler

📅 调度器
kube-controller-manager

🎮 控制器管理器
etcd

💾 分布式存储
kubelet
kube-proxy
Pod A
Pod B
kubelet
kube-proxy
Pod C
Pod D
👤 用户
kubectl

命令行工具

  • 控制平面(Master):
    • kube-apiserver:所有操作的唯一入口。
    • etcd:键值存储:存储集群所有配置和状态。
    • kube-scheduler:决定 Pod 运行在哪个 Node 上。
    • kube-controller-manager:维持集群的期望状态,运行各种控制器(节点控制器、副本控制器等)。
  • 工作节点(Worker):
    • kubelet:管理节点上的 Pod。
    • kube-proxy:维护网络规则,实现 Service 负载均衡。
    • 容器运行时(如 containerd、CRI‑O、Docker)。

关键概念

概念 说明
Pod K8s最小部署单元,包含一个或多个容器(通常是一个主容器 + 辅助容器)。
Node 工作节点(物理机或虚拟机),上面运行 Pod。
Deployment 管理无状态应用的 Pod 副本、滚动更新、回滚。
Service 为一组 Pod 提供稳定的网络访问入口(ClusterIP、NodePort、LoadBalancer)。
Ingress HTTP/HTTPS 路由规则,将外部请求映射到 Service。
ConfigMap / Secret 分别存储配置信息和敏感数据。
Namespace 虚拟集群,用于隔离资源(如开发、测试、生产环境)。

Kubernetes下载安装

步骤一:在 Docker Desktop 中启用 Kubernetes

  1. 启动并配置 Docker Desktop :打开 Docker Desktop ,点击右上角的 设置 (齿轮图标)进入 Settings
  2. 开启 K8s 开关 :在左侧菜单中找到并点击 Kubernetes,然后勾选 Enable Kubernetes 这个选项,下方会出现Cluster settings (集群设置),本地测试选择单节点的Kubeadm就可以。
  3. 等待并确认 :点击右下角的 Apply按钮。之后 Docker Desktop 会自动重启并开始拉取和启动 Kubernetes 的必要组件。这个过程需要一点时间,请耐心等待。当 Docker Desktop 界面左下角出现 "Kubernetes is running" 的提示时,就说明启动成功了。

    注意 :若出现Failed to start pulling images,这说明 Docker Desktop 在尝试拉取 Kubernetes 所需的镜像时失败了,原因通常是网络问题导致无法访问 registry.k8s.io。通过配置国内镜像加速器解决:
    1. 打开 Docker Desktop → 右上角 Settings(齿轮图标)→ 左侧选择 Docker Engine

    2. 在 JSON 配置中添加 registry-mirrors,内容如下:

      json 复制代码
      "registry-mirrors": [
          "https://docker.1ms.run",
          "https://docker.xuanyuan.me",
          "https://mirrors.aliyun.com/docker-ce/",
          "https://mirror.ccs.tencentyun.com",
          "https://hub-mirror.c.163.com",
          "https://docker.mirrors.ustc.edu.cn"
        ]
    3. 点击右下角 Apply,等待 Docker 重启

    4. 重启后,回到 Settings → Kubernetes,点击 Reset cluster 按钮重置集群

    5. 再次确保选中 Kubeadm,然后点击 Apply,让 Docker 重新拉取镜像

步骤二:验证集群状态

K8s 启用后,可以打开 PowerShell 或命令提示符,用 kubectl 命令来验证一下。

首先,确保 kubectl 正指向 Docker Desktop 的集群:

bash 复制代码
kubectl config use-context docker-desktop

然后,查看集群中的节点状态:

bash 复制代码
kubectl get nodes

果看到 NAMEdocker-desktopSTATUSReady,就说明一切正常。

使用案例

部署一个 Python Web 应用,并通过浏览器访问它。完整项目结构,创建一个新目录,比如 my-k8s-demo,然后创建以下文件:

text 复制代码
my-k8s-demo\          (项目根目录)
├── app.py
├── deployment.yaml
├── Dockerfile        
└── service.yaml

第一步:准备应用代码

创建 my-k8s-demo 文件夹,新建一个 app.py

python 复制代码
from flask import Flask
import socket
import os

app = Flask(__name__)

@app.route('/')
def hello():
    hostname = socket.gethostname()
    return f"Hello from Kubernetes! Pod: {hostname}"

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

创建 Dockerfile

text 复制代码
FROM python:3.9-slim
WORKDIR /app
COPY app.py .
RUN pip install flask
EXPOSE 5000
CMD ["python", "app.py"]

构建镜像:

bash 复制代码
docker build -t my-k8s-demo:latest .

第二步:创建 Deployment(管理 Pod 副本)

创建一个文件 deployment.yaml

yaml 复制代码
# ---------- 第一部分:API 版本和资源类型 ----------
apiVersion: apps/v1          # API 版本号,apps/v1 是 Deployment 的稳定版本
kind: Deployment             # 资源类型,告诉 K8s 这是一个 Deployment

# ---------- 第二部分:元数据(标识信息) ----------
metadata:
  name: my-demo-app          # Deployment 的名称,后续操作会用到

# ---------- 第三部分:规格说明(核心配置) ----------
spec:
  # 3.1 副本管理
  replicas: 3                # 期望保持运行 3 个 Pod 副本,少了会自动补
  
  # 3.2 标签选择器(Deployment 通过它找到自己管理的 Pod)
  selector:
    matchLabels:             # 匹配带有以下标签的 Pod
      app: my-demo-app       # 标签键值对:app=my-demo-app
  
  # 3.3 Pod 模板(定义每个 Pod 的"模样")
  template:
    # Pod 的元数据
    metadata:
      labels:                # Pod 的标签,必须和上面的 selector 一致
        app: my-demo-app     # 这样 Deployment 才能找到并管理这个 Pod
    
    # Pod 的规格(里面运行什么容器)
    spec:
      containers:            # 容器列表(一个 Pod 可以有多个容器)
      - name: app            # 容器名称,在 Pod 内唯一
        image: my-k8s-demo:latest  # 使用的 Docker 镜像及版本
        imagePullPolicy: Never  # 添加这一行,告诉 K8s 不要从远程拉取,只用本地镜像
        ports:               # 容器暴露的端口(仅作文档说明)
        - containerPort: 5000  # 容器内应用监听的端口
        # 可选:资源限制
        # resources:
        #   requests:
        #     memory: "64Mi"
        #     cpu: "250m"
        #   limits:
        #     memory: "128Mi"
        #     cpu: "500m"

应用配置:

bash 复制代码
# 创建 Deployment
kubectl apply -f deployment.yaml

YAML 核心字段速记:

yaml 复制代码
# Deployment 核心
apiVersion: apps/v1    # 版本
kind: Deployment       # 类型
metadata.name: xxx     # 名字
spec.replicas: 3       # 副本数
spec.selector          # 找 Pod 的标签
spec.template          # Pod 模板
  spec.containers      # 容器定义
    imagePullPolicy    # 镜像拉取策略

第三步:创建 Service(暴露内部访问)

创建一个文件 service.yaml

yaml 复制代码
# ---------- 第一部分:API 版本和资源类型 ----------
apiVersion: v1               # Service 使用核心 API v1 版本
kind: Service                # 资源类型,告诉 K8s 这是一个 Service

# ---------- 第二部分:元数据(标识信息) ----------
metadata:
  name: my-demo-service      # Service 的名称,集群内部 DNS 会用到

# ---------- 第三部分:规格说明(核心配置) ----------
spec:
  # 3.1 Service 类型
  type: NodePort              # 服务类型:
                              # - ClusterIP(默认):仅集群内部访问
                              # - NodePort:节点上开放端口,外部可访问
                              # - LoadBalancer:云服务商负载均衡器
  
  # 3.2 标签选择器(Service 把流量转发给哪些 Pod)
  selector:
    app: my-demo-app          # 只转发给带有 app=my-demo-app 标签的 Pod
                              # 必须和 Deployment 中 Pod 的标签一致
  
  # 3.3 端口映射
  ports:
  - port: 5000                  # Service 自己监听的端口(集群内部访问用)
    targetPort: 5000           # 目标 Pod 容器实际监听的端口
    nodePort: 30080          # 节点上开放的端口(仅 NodePort 类型需要)
                              # 范围:30000-32767,外部通过 localhost:30080 访问
    # 可选:指定协议
    # protocol: TCP          # TCP(默认)、UDP

应用配置:

bash 复制代码
kubectl apply -f service.yaml

现在可以通过浏览器访问:http://localhost:30080多刷新几次可以看到PodName会不断变化。

第四步:核心能力体验

首先新建一个终端,持续观察Pod变化:

bash 复制代码
# 终端1:持续观察 Pod 变化
kubectl get pods -w
  • 场景一:自愈能力(Self-Healing)

    验证 Kubernetes 能在 Pod 故障时自动恢复:

    bash 复制代码
    # 手动删除一个 Pod,模拟 Pod 崩溃
    kubectl delete pod <pod-name>  # 替换成实际的 Pod 名称

    会发现,新的 Pod 自动创建了:

    📝 核心理解

    K8s 动作 :自动创建新 Pod 恢复到 3 个

    用户无感:Service 自动将流量转发到新 Pod

  • 场景二:水平伸缩(Horizontal Scaling)

    体验 Kubernetes 根据负载快速调整应用实例数量。

    bash 复制代码
    # 1. 扩容到 5 个副本(应对流量高峰)
    kubectl scale deployment my-demo-app --replicas=5
    
    # 2. 缩容到 2 个副本(流量下降时节省资源)
    kubectl scale deployment my-demo-app --replicas=2

    📝 核心理解

    秒级扩缩容 :几秒钟内就能增加/减少应用实例

    自动负载均衡 :Service 自动将流量分发到所有 Pod

    资源优化:根据实际负载动态调整资源使用

  • 场景三:滚动更新(Rolling Update)

    体验零停机地更新应用版本。

    1. 准备一个新版本镜像

      修改app.py,改变返回信息:

      python 复制代码
      from flask import Flask
      import socket
      import os
      
      app = Flask(__name__)
      
      @app.route('/')
      def hello():
          hostname = socket.gethostname()
          return f"Hello from Kubernetes v2! Pod: {hostname}  (Updated!)"  # 修改这里
      
      if __name__ == '__main__':
          app.run(host='0.0.0.0', port=5000)

      重新构建镜像并打上新标签:

      bash 复制代码
      # 构建新版本镜像
      docker build -t my-k8s-demo:v2 .
      
      # 也可以同时保留 latest 标签
      docker tag my-k8s-demo:v2 my-k8s-demo:latest
    2. 执行滚动更新

      bash 复制代码
      # 方法1:直接设置新镜像(推荐)
      kubectl set image deployment/my-demo-app app=my-k8s-demo:v2
      
      # 方法2:编辑 Deployment 配置
      # kubectl edit deployment my-demo-app
      # 将 image: my-k8s-demo:latest 改为 image: my-k8s-demo:v2
    3. 观察滚动更新过程

      bash 复制代码
      kubectl rollout status deployment/my-demo-app
    4. 模拟更新失败并回滚

      bash 复制代码
      # 故意设置一个不存在的镜像(模拟错误版本)
      kubectl set image deployment/my-demo-app app=my-k8s-demo:not-exist
      
      # 查看更新状态(会卡住)
      kubectl rollout status deployment/my-demo-app
      
      # 立即回滚到上一个稳定版本
      kubectl rollout undo deployment/my-demo-app
      
      # 确认回滚成功
      kubectl rollout status deployment/my-demo-app
      kubectl get pods

    📝 核心理解

    零停机 :新旧 Pod 交替替换,始终有可用的服务

    可控速率 :可以控制每次替换多少个 Pod(maxSurge、maxUnavailable)

    快速回滚 :一键回到上一个版本

    健康检查:新 Pod 不健康时自动停止更新

第五步:清理资源

bash 复制代码
# 删除 Service
kubectl delete service my-demo-service

# 删除 Deployment(会自动删除所有 Pods)
kubectl delete deployment my-demo-app

# 验证清理结果
kubectl get all

常用命令速查表

命令 说明
kubectl get nodes 查看所有节点
kubectl get pods 查看所有 Pods
kubectl get service 查看 Services(简称 svc)
kubectl get deployments 查看所有 Deployments
kubectl get all 查看当前命名空间所有常见资源
kubectl describe pod <pod-name> 查看 Pod 的详细信息和事件
kubectl describe deployment <deployment-name> 查看某个 Deployment 详细信息
kubectl describe svc <service-name> 查看 Service 详细信息
kubectl logs <pod-name> 查看 Pod的日志
ubectl apply -f <file.yaml> 创建或更新资源(声明式)
kubectl create -f <file.yaml> 创建资源(命令式)
kubectl delete -f <file.yaml> 通过 YAML 文件删除资源
kubectl delete pod <pod-name> 删除指定 Pod
kubectl delete deployment <deploy-name> 删除指定 Deployment
kubectl delete svc <service-name> 删除指定 Service
kubectl delete pods --all 删除当前命名空间所有 Pods
kubectl scale deployment <name> --replicas=n 手动扩容/缩容到指定副本数
kubectl set image deployment/<name> <container>=<image> 滚动更新镜像版本
kubectl rollout status deployment/<name> 查看滚动更新状态
kubectl rollout history deployment/<name> 查看更新历史版本
kubectl rollout undo deployment/<name> 回滚到上一个版本
kubectl rollout undo deployment/<name> --to-revision=2 回滚到指定版本
kubectl get pods -w 实时监控 Pod 状态变化
kubectl logs -f <pod-name> 实时跟踪日志
相关推荐
IT策士1 小时前
第28篇 k8s之Service:为 Pod 提供稳定的访问入口
云原生·容器·kubernetes
张忠琳2 小时前
【kubernetes v1.21】(kube-scheduler 4)kube-scheduler 内部缓存、队列与抢占机制
云原生·架构·kubernetes
苏渡苇2 小时前
Seata 番外篇:使用 docker-compose 部署 Seata Server(TC)及 K8S 部署 Seata 高可用
spring boot·docker·微服务·容器·kubernetes·seata·springcloud
JP-Destiny2 小时前
docker报错-无法解析 registry-1.docker.io
运维·docker·容器
IT策士2 小时前
第29篇 k8s之Service 与 Endpoints 深入:服务发现原理
容器·kubernetes·服务发现
Benszen2 小时前
Kubernetes容器编排解决方案【基础篇】
云原生·容器·kubernetes
张忠琳3 小时前
【kubernetes v1.21】(kube-apiserver 4)kube-apiserver Storage/ETCD 与 Watch 机制
云原生·架构·kubernetes
liux35283 小时前
Kubernetes Service 类型详解:从 ClusterIP 到 LoadBalancer
云原生·容器·kubernetes
牟同學3 小时前
Hermes Agent Docker 离线部署完整指南
docker·容器·eureka·hermes