一文读懂 K8s:Kubernetes 快速入门 – wiki基地


一文读懂 K8s:Kubernetes 快速入门

引言:从集装箱到管弦乐团的蜕变

在云计算和微服务盛行的今天,容器技术,尤其是Docker,已经成为应用程序打包和部署的标准。它解决了“在我的机器上能运行”的问题,让开发和运维的界限变得模糊。然而,当容器的数量从几个增长到几十个、几百个甚至上千个时,管理这些容器的复杂性指数级上升:它们如何协同工作?如何自动扩缩容?一个容器挂掉后如何自动恢复?如何在不停机的情况下更新应用程序?

这些问题,单靠Docker本身是无法解决的。这就好比你有了无数个标准化生产的集装箱(容器),但你还需要一个强大的港口管理系统、一个调度中心、一个物流网络,来确保这些集装箱能够高效、可靠地运行和运输。

Kubernetes(简称K8s,因为K和s之间有8个字母)正是这个“港口管理系统”和“物流网络”——一个开源的容器编排平台。它源自Google内部的Borg系统,于2014年开源,如今已成为云原生时代的基石。它不仅仅是一个工具,更是一种管理现代复杂分布式系统的哲学。

本文将带领你深入浅出地理解K8s的核心概念、架构原理、常见组件及其工作方式,助你快速入门,从容应对容器时代的挑战。

第一部分:K8s的诞生背景与核心价值

1.1 容器化带来的挑战

Docker的出现极大地简化了应用程序的打包、分发和运行。每个容器都是一个独立的、轻量级的运行环境,包含了应用及其所有依赖。然而,在生产环境中,我们面临以下问题:

  • 部署与调度: 如何将容器部署到合适的服务器上?如何确保每个服务器的资源得到充分利用?
  • 服务发现与负载均衡: 容器的IP地址是动态变化的,应用程序之间如何找到对方?如何将请求均匀地分发到多个容器实例上?
  • 健康检查与自愈: 容器出现故障怎么办?如何自动重启或替换故障容器?
  • 扩缩容: 面对流量高峰和低谷,如何动态增加或减少容器实例?
  • 配置管理: 如何统一管理容器的配置信息和敏感数据?
  • 滚动更新与回滚: 如何在不中断服务的情况下更新应用程序?更新失败后如何快速回滚到旧版本?

手动处理这些问题,不仅效率低下,而且极易出错,成为运维团队的巨大负担。

1.2 Kubernetes的解决方案

K8s应运而生,旨在自动化和简化容器化应用程序的部署、扩展和管理。它的核心价值体现在:

  • 自动化操作: K8s能够自动化容器的部署、扩缩容、更新和维护。
  • 自愈能力: 当容器、节点甚至集群的一部分出现故障时,K8s能自动检测并尝试恢复服务,保证高可用性。
  • 声明式配置: 你只需告诉K8s你想要达到的状态(例如,我需要运行3个Nginx容器),K8s就会尽力去实现并维持这个状态,而不是告诉它一步一步如何操作。
  • 服务发现与负载均衡: K8s提供了内置的服务发现机制和负载均衡功能,让应用程序之间能够轻松通信。
  • 资源管理: K8s能根据资源需求(CPU、内存)智能地调度容器到合适的节点。
  • 可移植性: K8s可以在各种环境中运行,无论是本地开发机、私有数据中心还是公有云。

简单来说,K8s就像一个高明的管弦乐团指挥,你只需给出乐谱(应用程序的声明式配置),它就能协调所有乐手(容器和节点),自动演奏出美妙的乐章(高可用、可扩展的应用服务)。

第二部分:K8s的核心架构与组件

K8s集群由一组主节点(Master Node / Control Plane)工作节点(Worker Node) 组成。主节点负责管理和控制整个集群,工作节点则负责运行实际的应用程序容器。

2.1 主节点(Master Node / Control Plane)—— K8s的大脑

主节点是K8s集群的“大脑”,负责维护集群的期望状态。它包含以下核心组件:

  1. kube-apiserver (API Server):

    • 作用: 它是K8s集群的“前门”,所有外部请求(如kubectl命令行工具、其他管理工具)和内部组件(如kubelet、scheduler)与K8s集群通信的唯一入口。
    • 特点: 提供RESTful API接口,负责身份认证、授权、数据校验和审计。它是整个集群的数据中心枢纽,确保所有操作都经过它的校验。
  2. etcd:

    • 作用: K8s集群的“大脑记忆库”,是一个高可用、分布式、一致性的键值存储系统。
    • 特点: 存储集群的所有配置数据、状态信息、元数据(如Pod、Service、Deployment等对象的定义和状态),以及集群的期望状态。它是集群的唯一真实来源。
  3. kube-scheduler (Scheduler):

    • 作用: K8s集群的“任务调度器”,负责监测新创建的、未指定运行节点(Node)的Pod。
    • 特点: 根据预设的调度策略(如资源需求、亲和性/反亲和性、节点选择器、Taints和Tolerations等),为Pod选择一个最适合运行的工作节点,并将调度结果更新到API Server。
  4. kube-controller-manager (Controller Manager):

    • 作用: K8s集群的“自愈引擎”和“状态控制器”,包含多个控制器(如Deployment Controller、ReplicaSet Controller、Node Controller、Service Account Controller等)。
    • 特点: 每个控制器都负责维护一种特定的资源类型,确保集群的当前状态与etcd中存储的期望状态一致。例如,ReplicaSet Controller会确保运行的Pod数量始终与期望的副本数一致;Node Controller会检测并处理节点故障。

2.2 工作节点(Worker Node)—— K8s的肌肉

工作节点是K8s集群的“肌肉”,是应用程序真正运行的地方。每个工作节点都包含以下核心组件:

  1. kubelet:

    • 作用: 运行在每个工作节点上的“节点代理”,它是K8s与容器运行时(如Docker)的桥梁。
    • 特点: 接收API Server发送的指令,负责管理节点上的Pod生命周期(创建、启动、停止、删除容器),并向API Server报告节点和Pod的状态。
  2. kube-proxy:

    • 作用: K8s集群的“网络代理”,运行在每个工作节点上。
    • 特点: 负责为Service提供网络代理和负载均衡功能。它会根据Service和Pod的变化,动态更新节点的网络规则(如iptables或ipvs),将对Service的请求转发到正确的Pod。
  3. Container Runtime (容器运行时):

    • 作用: 负责运行容器的软件,例如Docker、Containerd或CRI-O。
    • 特点: kubelet通过CRI(Container Runtime Interface)与容器运行时交互,拉取镜像、运行容器、停止容器等。

第三部分:K8s的核心概念与资源对象

理解K8s的关键在于理解其核心概念和资源对象。K8s中的所有操作都围绕着这些对象进行,它们是K8s世界的“积木”。

  1. Pod (豆荚/基本调度单元):

    • 定义: K8s中最小的、可部署的计算单元。一个Pod可以包含一个或多个紧密耦合的容器,以及这些容器共享的存储、网络和运行时的配置。
    • 特点:
      • 原子性: Pod内的容器总是共同调度、共同停止,共享网络命名空间(即它们共享同一个IP地址和端口范围)。
      • 共享资源: Pod内的容器可以共享存储卷(Volumes)和网络(IP地址)。
      • 一次性: Pod是短暂的,被创建后,如果Pod内的容器挂掉,K8s不会在原地重启它们,而是创建一个全新的Pod来替代。
    • 类比: 就像一个独立的小公寓,里面住着一户人家(紧密相关的容器),共享厨房、卫生间(共享网络和存储)。
  2. Deployment (部署):

    • 定义: K8s中最常用的一种工作负载控制器,用于管理Pod和ReplicaSet。它描述了你希望运行的应用程序的期望状态。
    • 特点:
      • 声明式更新: 允许你声明应用程序的期望状态(例如,运行多少个Nginx Pod),Deployment会负责创建和更新ReplicaSet,进而管理Pod。
      • 滚动更新和回滚: 支持平滑地更新应用程序(逐个替换Pod),并在更新失败时能够快速回滚到旧版本。
      • 自动伸缩: 可以与Horizontal Pod Autoscaler (HPA) 配合,根据CPU利用率或自定义指标自动扩缩容Pod数量。
    • 类比: 应用程序的“发布经理”,负责版本管理、平滑升级和回滚。
  3. Service (服务):

    • 定义: 一种抽象,定义了一组Pod的逻辑集合以及访问它们的策略。它为Pod提供了一个稳定的、不变的入口IP地址和DNS名称。
    • 特点:
      • 服务发现: 即使Pod的IP地址因为重启或扩缩容而变化,Service的IP地址和DNS名称保持不变,方便其他应用程序发现和访问。
      • 负载均衡: Service会根据请求自动将流量分发到其关联的Pod上。
      • 服务类型:
        • ClusterIP (默认): 只能在集群内部访问,为Service提供一个稳定的内部IP。
        • NodePort: 在每个工作节点上暴露一个静态端口,可以通过节点IP:NodePort从集群外部访问Service。
        • LoadBalancer: 在支持的云提供商上,会自动创建一个外部负载均衡器,将流量转发到Service。
        • ExternalName: 将Service映射到外部的DNS名称。
    • 类比: 应用程序的“总机号码”或“公司前台”,无论内部员工(Pod)如何变动,外界(其他应用或用户)只需拨打这个固定号码就能找到服务。
  4. Namespace (命名空间):

    • 定义: K8s集群内部的逻辑隔离机制,用于将集群资源划分为不同的“虚拟集群”。
    • 特点:
      • 资源隔离: 不同的Namespace可以拥有相同的资源名称(例如,每个Namespace都可以有一个名为nginx-deployment的Deployment)。
      • 权限管理: 可以为不同的Namespace设置不同的访问权限,实现多租户环境。
      • 默认Namespace: K8s集群启动时会有一个defaultkube-systemkube-public等命名空间。
    • 类比: 一个大型公司的不同“部门”,每个部门有自己的预算和人员,但都在同一个公司框架下。
  5. ReplicaSet (副本集):

    • 定义: 确保在任何给定时间运行指定数量的Pod副本。
    • 特点: 通常由Deployment管理,用户很少直接操作ReplicaSet。当Deployment更新应用程序时,它会创建一个新的ReplicaSet来管理新版本的Pod,并逐渐淘汰旧的ReplicaSet。
    • 类比: 负责“保镖数量”的管理员,确保始终有指定数量的保镖(Pod)在岗。
  6. ConfigMap (配置映射) & Secret (秘密):

    • 定义:
      • ConfigMap: 用于存储非敏感的配置信息,如环境变量、命令行参数或配置文件。
      • Secret: 专门用于存储敏感数据,如密码、API密钥、令牌等。
    • 特点:
      • 解耦配置: 将应用程序的配置与代码解耦,方便管理和更新。
      • 挂载方式: 可以作为环境变量注入到Pod中,或作为文件挂载到容器的卷中。
      • 安全性: Secret的数据经过Base64编码(但并非加密),在K8s集群内部进行管理和分发时会受到更好的保护。
    • 类比: ConfigMap是应用的“操作手册”,Secret是应用的“保险箱密码”。
  7. Volume (卷):

    • 定义: Pod中容器可以访问的目录,提供数据持久化或共享能力。
    • 特点: 解决容器重启后数据丢失的问题,也方便Pod内多个容器共享数据。K8s支持多种类型的卷,如emptyDir、hostPath、NFS、云提供商存储(AWS EBS、GCE Persistent Disk等)。
    • 类比: 容器的“硬盘”或“共享文件夹”。
  8. PersistentVolume (PV) & PersistentVolumeClaim (PVC):

    • 定义:
      • PV: 集群中由管理员预先配置或动态提供的持久化存储资源。
      • PVC: 用户对存储资源的请求,声明了存储的大小、访问模式等。
    • 特点:
      • 存储抽象: PV/PVC将存储的物理实现与用户需求解耦,用户无需关心底层存储的具体细节。
      • 动态供给: K8s可以根据PVC的请求,动态地从存储后端创建PV。
    • 类比: PV是“公司的存储仓库”,PVC是“员工提交的存储申请单”。
  9. Ingress (入口):

    • 定义: K8s集群的“七层负载均衡器”,提供HTTP和HTTPS路由,将外部流量路由到集群内部的Service。
    • 特点:
      • 统一入口: 允许你使用一个IP地址和多个域名来提供多个Service。
      • 高级路由规则: 可以根据请求的URL路径或主机名将流量路由到不同的Service。
      • TLS/SSL终止: 可以配置Ingress来处理HTTPS流量。
    • 类比: 城市入口的“交通枢纽”,根据车辆(请求)的目的地(URL/域名)将其引导到不同的区域(Service)。

第四部分:K8s的实际操作与快速入门

掌握了理论知识后,最好的学习方式就是动手实践。

4.1 kubectl命令行工具

kubectl是K8s的官方命令行工具,用于与K8s API Server进行交互。它是你管理K8s集群的主要方式。

常用命令示例:

  • 查看集群状态:
    bash
    kubectl cluster-info
    kubectl get nodes
  • 查看资源:
    bash
    kubectl get pods
    kubectl get deployments
    kubectl get services
    kubectl get all -n default # 查看default命名空间下的所有资源
  • 创建/更新/删除资源:
    bash
    kubectl apply -f my-app.yaml # 创建或更新资源
    kubectl delete -f my-app.yaml # 删除资源
    kubectl create deployment nginx --image=nginx # 命令行创建Deployment
  • 日志与进入容器:
    bash
    kubectl logs <pod-name> -f # 查看Pod日志
    kubectl exec -it <pod-name> -- bash # 进入Pod内的容器
  • 扩缩容:
    bash
    kubectl scale deployment <deployment-name> --replicas=5 # 将副本数扩容到5

4.2 K8s的声明式配置 (YAML)

K8s资源通常通过YAML文件进行定义。这种声明式的方式使得配置版本化、可审计、易于共享。

示例:一个简单的Nginx Deployment

创建一个名为nginx-deployment.yaml的文件:

yaml
apiVersion: apps/v1 # API版本,指定Deployment资源属于apps/v1组
kind: Deployment # 资源类型,这里是Deployment
metadata:
name: nginx-deployment # Deployment的名称
labels:
app: nginx # 为Deployment打上标签
spec:
replicas: 3 # 期望的Pod副本数量
selector: # 选择器,用于关联Pod
matchLabels:
app: nginx # 选择所有带有app=nginx标签的Pod
template: # Pod模板,用于创建Pod
metadata:
labels:
app: nginx # Pod的标签,与Deployment的selector匹配
spec:
containers: # 容器列表
- name: nginx # 容器名称
image: nginx:latest # 使用的Docker镜像
ports:
- containerPort: 80 # 容器暴露的端口
resources: # 资源限制和请求
limits:
cpu: "500m" # 最大CPU使用量0.5核
memory: "256Mi" # 最大内存使用量256MB
requests:
cpu: "200m" # 启动时请求0.2核CPU
memory: "128Mi" # 启动时请求128MB内存

示例:为Nginx Deployment创建Service

创建一个名为nginx-service.yaml的文件:

yaml
apiVersion: v1 # API版本,指定Service资源属于v1组
kind: Service # 资源类型,这里是Service
metadata:
name: nginx-service # Service的名称
spec:
selector:
app: nginx # 选择所有带有app=nginx标签的Pod作为后端
ports:
- protocol: TCP
port: 80 # Service监听的端口
targetPort: 80 # 流量转发到Pod的哪个端口
nodePort: 30080 # 当使用NodePort类型时,节点上暴露的端口(范围30000-32767)
type: NodePort # Service的类型,这里选择NodePort,以便从集群外部访问

4.3 部署并访问你的第一个应用

前提: 你需要一个K8s集群。
* 本地学习: 推荐使用MinikubeDocker Desktop(内置Kubernetes)。
* 云端: 各大云厂商(AWS EKS, GCP GKE, Azure AKS)都提供托管K8s服务。

步骤:

  1. 保存YAML文件: 将上述nginx-deployment.yamlnginx-service.yaml文件保存到本地。
  2. 部署Deployment:
    bash
    kubectl apply -f nginx-deployment.yaml

    K8s会根据YAML文件创建Deployment,Deployment会进一步创建ReplicaSet,ReplicaSet再创建3个Nginx Pod。
  3. 检查Pod状态:
    bash
    kubectl get pods -l app=nginx
    # 应该看到3个Status为Running的Pod
  4. 部署Service:
    bash
    kubectl apply -f nginx-service.yaml
  5. 检查Service状态:
    bash
    kubectl get services nginx-service
    # 应该看到Service的ClusterIP、外部IP(如果类型是LoadBalancer),以及NodePort(如果类型是NodePort)
  6. 访问Nginx:
    • 如果使用Minikube,可以通过minikube service nginx-service命令直接在浏览器中打开。
    • 如果使用NodePort,找到集群中任意一个工作节点的IP地址,然后通过http://<节点IP>:<NodePort>访问(例如http://192.168.49.2:30080)。
    • 如果使用LoadBalancer,找到其分配的外部IP地址访问。

4.4 体验K8s的自愈和扩缩容

  1. 模拟Pod故障:
    bash
    kubectl delete pod <其中一个nginx-deployment的pod名称>

    你会发现K8s很快会自动创建一个新的Pod来替换被删除的Pod,维持3个副本的期望状态。

  2. 扩缩容:
    bash
    kubectl scale deployment nginx-deployment --replicas=5
    # 再次查看Pod,会发现变成了5个
    kubectl get pods -l app=nginx

    将副本数改回3:
    bash
    kubectl scale deployment nginx-deployment --replicas=3
    # 再次查看Pod,会发现自动缩减到了3个
    kubectl get pods -l app=nginx

第五部分:K8s的优势、挑战与未来展望

5.1 K8s的显著优势

  • 提高开发效率: 开发者可以专注于业务逻辑,无需关心底层基础设施。
  • 提升运维效率: 自动化部署、扩缩容、自愈等功能,大大减轻运维负担。
  • 高可用性: 自动故障转移和自我修复能力,确保服务持续在线。
  • 可伸缩性: 应对流量波动,动态调整资源。
  • 环境一致性: 容器化和K8s确保了开发、测试、生产环境的一致性。
  • 云厂商锁定解除: K8s作为开源标准,可以在任何支持的云平台或本地数据中心运行,避免特定云厂商的绑定。

5.2 学习K8s面临的挑战

  • 学习曲线陡峭: 概念众多,组件复杂,初学者往往感到不知所措。
  • 资源消耗: K8s本身也需要一定的计算资源才能运行。
  • 网络和存储的复杂性: K8s的网络模型和存储选项相对复杂。
  • 安全性: K8s集群的安全性配置需要专业知识和严格实践。

5.3 未来展望

K8s已经成为云原生生态的核心,未来将继续深化发展:

  • Operator模式: 允许扩展K8s的能力,管理复杂有状态应用。
  • Serverless与K8s集成: 将K8s作为Serverless函数运行的底层平台。
  • 边缘计算: K8s正在向边缘设备和物联网领域拓展,管理分布式微型集群。
  • 更智能的调度和资源管理: 利用AI/ML技术优化资源调度和成本。

结语

“一文读懂 K8s” 并非意味着你可以读完这3000字就成为K8s专家。相反,这只是一个起点,为你描绘了K8s的宏伟蓝图和核心脉络。K8s是一个庞大且仍在快速发展的生态系统,深入学习需要持续的实践和探索。

从集装箱(容器)到港口(Docker)再到整个智能物流网络(Kubernetes),我们见证了软件交付方式的巨大变革。K8s以其强大的自动化、自愈和调度能力,正在重新定义现代应用程序的部署和管理方式。

勇敢地迈出第一步,在Minikube或Docker Desktop上搭建你的第一个K8s集群,部署一个简单的应用,感受K8s的魔力。你将发现,掌握K8s不仅仅是掌握一项技术,更是获得了驾驭未来云原生世界的强大能力。祝你在K8s的学习旅程中一帆风顺!


发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部