学习 Kubernetes:给初学者的完整介绍
在现代软件开发和运维(DevOps)领域,容器化技术已经成为部署和管理应用程序的标准方式。Docker 等工具使得将应用程序及其依赖打包成轻量级、可移植的容器变得轻而易举。然而,当应用程序规模扩大,容器数量从几个增长到成百上千甚至数万个时,手动管理这些容器的部署、扩展、网络和生命周期就变成了一项极其复杂且容易出错的任务。这时,容器编排(Container Orchestration)工具应运而生,而 Kubernetes(通常简称为 K8s)正是这个领域的王者。
对于初学者来说,Kubernetes 可能看起来像一个庞大而令人生畏的系统。它拥有自己的一套术语、概念和架构。但这篇完整的介绍旨在为您揭开 Kubernetes 的神秘面纱,从基础概念讲起,逐步深入,为您打下坚实的学习基础,并指明前进的方向。
一、 什么是 Kubernetes?
Kubernetes 是一个开源的容器编排平台,最初由 Google 设计并贡献给云原生计算基金会(Cloud Native Computing Foundation, CNCF)。它的核心目标是自动化容器化应用程序的部署、扩展和管理。
您可以将 Kubernetes 想象成一个集群的“操作系统”。就像操作系统管理计算机的硬件资源(CPU、内存、存储)并为应用程序提供运行环境一样,Kubernetes 管理着组成集群的计算节点(物理机或虚拟机),并为容器化应用程序提供部署、运行和维护所需的基础设施和服务。
核心功能:
- 服务发现与负载均衡 (Service Discovery and Load Balancing): Kubernetes 可以使用 DNS 名称或自己的 IP 地址公开容器。如果到容器的流量很大,Kubernetes 能够负载均衡并分发网络流量,从而保证部署的稳定性。
- 存储编排 (Storage Orchestration): Kubernetes 允许您自动挂载您选择的存储系统,例如本地存储、公有云提供商(如 AWS、GCP)的存储或其他网络存储(如 NFS、iSCSI)。
- 自动部署和回滚 (Automated Rollouts and Rollbacks): 您可以使用 Kubernetes 描述已部署容器的期望状态,它可以以受控的速率将实际状态更改为期望状态。例如,您可以自动化 Kubernetes 来为您的部署创建新容器,删除现有容器并将它们的所有资源用于新容器。如果出现问题,Kubernetes 会为您回滚更改。
- 自动装箱 (Automatic Bin Packing): 您为 Kubernetes 提供一个节点集群,它可以用来运行容器化任务。您告诉 Kubernetes 每个容器需要多少 CPU 和内存 (RAM)。Kubernetes 可以将容器装配到您的节点上,以最好地利用您的资源。
- 自我修复 (Self-Healing): Kubernetes 会重新启动失败的容器、替换容器、杀死不响应用户定义的运行状况检查的容器,并且在它们准备好服务之前不将它们公布给客户端。
- 密钥和配置管理 (Secret and Configuration Management): Kubernetes 允许您存储和管理敏感信息,例如密码、OAuth 令牌和 SSH 密钥。您可以部署和更新密钥和应用程序配置,而无需重新构建容器镜像,也无需在堆栈配置中暴露密钥。
二、 为什么我们需要 Kubernetes?(它解决了什么问题?)
在 Kubernetes 出现之前,管理大规模容器化应用面临诸多挑战:
- 手动部署复杂: 在多台机器上手动启动、停止、更新容器非常耗时且容易出错。
- 难以扩展: 当流量增加时,如何快速、自动地增加应用程序实例(容器)的数量?当流量减少时,如何缩减实例以节省资源?
- 服务发现困难: 当容器动态启动和停止时,它们的 IP 地址会改变。其他服务如何可靠地找到并连接到它们?
- 负载均衡不易: 如何将进入的流量均匀地分配给多个运行相同应用程序的容器实例?
- 缺乏故障恢复: 如果一个容器或运行它的节点发生故障,如何自动检测并重新启动一个新的实例来替代它?
- 更新和回滚风险高: 如何在不中断服务的情况下更新应用程序?如果新版本有问题,如何快速回滚到旧版本?
- 资源利用率低: 如何有效地将容器调度到可用的机器上,以最大限度地利用硬件资源?
Kubernetes 通过提供一个统一的平台和一组强大的抽象,系统性地解决了上述所有问题。它将底层的物理或虚拟基础设施抽象为一个巨大的资源池,开发人员和运维人员只需关注应用程序的“期望状态”(例如,“我需要运行 3 个 Web 服务器实例,并对外暴露 80 端口”),Kubernetes 会负责实现并维护这个状态。
三、 Kubernetes 核心架构
理解 Kubernetes 的工作原理,首先需要了解其核心架构。一个 Kubernetes 集群通常由两类节点组成:控制平面(Control Plane)节点和工作节点(Worker Nodes)。
1. 控制平面 (Control Plane)
控制平面是 Kubernetes 集群的大脑,负责做出全局决策(例如调度),以及检测和响应集群事件(例如,当部署的 replicas
字段不满足时启动新的 Pod)。控制平面组件可以在集群中的任何机器上运行,但为了简单起见,启动脚本通常在同一台机器上启动所有控制平面组件,并且不会在该机器上运行用户容器。
主要组件包括:
kube-apiserver
(API 服务器): 这是 Kubernetes 控制平面的前端,是所有内部和外部通信的中心枢纽。它公开了 Kubernetes API,处理 REST 请求,验证它们,并更新etcd
中的相应对象状态。kubectl
命令行工具就是通过 API 服务器与集群交互的。etcd
: 一个一致性、高可用的键值存储,用作 Kubernetes 所有集群数据的后台数据库。集群的所有状态信息,如节点信息、Pod 信息、配置、密钥等,都存储在etcd
中。它是集群的“单一事实来源”。kube-scheduler
(调度器): 负责监视新创建的、未指定运行节点的 Pod,并根据资源需求、策略约束、亲和性和反亲和性规范等因素,选择一个最佳的 Worker Node 来运行该 Pod。kube-controller-manager
(控制器管理器): 运行多个控制器进程。每个控制器负责集群中的特定任务,以确保集群的当前状态与etcd
中存储的期望状态一致。常见的控制器包括:- Node Controller: 负责节点故障检测和响应。
- Replication Controller/ReplicaSet Controller: 维护指定数量的 Pod 副本。
- Deployment Controller: 管理 Deployment 对象,处理滚动更新等。
- Service Controller: 创建、更新和删除云提供商的负载均衡器、IP 地址等。
cloud-controller-manager
(云控制器管理器,可选): 如果您的集群运行在特定的云提供商(如 AWS, Azure, GCP)环境中,该组件会运行与该云提供商交互的控制器。它将 Kubernetes 与云平台的 API(如存储卷、负载均衡器)连接起来。
2. 工作节点 (Worker Nodes)
工作节点是集群中实际运行容器化应用程序的地方。每个工作节点都由控制平面管理,并运行以下关键组件:
kubelet
: 在集群中每个节点上运行的主要“节点代理”。它确保 Pod 中的容器都按照 PodSpec(Pod 规范)运行。kubelet
不管理不是由 Kubernetes 创建的容器。它接收来自 API 服务器的 Pod 定义,并与容器运行时交互以启动、停止和监视容器。它还会定期向 API 服务器报告节点和 Pod 的状态。kube-proxy
: 在集群中的每个节点上运行的网络代理,实现了 Kubernetes Service 概念的一部分。它维护节点上的网络规则,允许从集群内部或外部的网络会话与 Pod 进行网络通信。它可以通过操作系统的数据包过滤层(如 iptables)或自身转发流量。- 容器运行时 (Container Runtime): 负责运行容器的软件。Kubernetes 支持多种容器运行时,最常见的是 Docker,但其他如
containerd
和CRI-O
也被广泛使用,它们都实现了 Kubernetes 容器运行时接口 (CRI)。
四、 Kubernetes 关键对象(核心抽象)
Kubernetes 使用一系列称为“对象 (Objects)”的抽象来表示集群的状态。用户通过创建、更新或删除这些对象来管理应用程序和基础设施。以下是一些最基本和最重要的 Kubernetes 对象:
Pod
: Kubernetes 中可以创建和管理的最小、最基本的可部署计算单元。一个 Pod 代表集群中运行的一个进程实例。Pod 包含一个或多个紧密耦合的容器(例如,一个主应用程序容器和一个辅助“sidecar”容器用于日志收集或代理),这些容器共享存储、网络(同一个 IP 地址和端口空间)以及运行规范。可以将 Pod 想象成一个逻辑主机,里面的容器就像运行在这个主机上的进程。Service
: 定义了一组逻辑 Pod 的抽象,并为它们提供了一个单一、稳定的访问点(IP 地址和 DNS 名称)以及访问策略(通常是负载均衡)。当 Pod 被创建或销毁时,它们的 IP 地址会变化,但 Service 的 IP 地址和 DNS 名称保持不变。这使得其他应用程序或用户可以可靠地连接到运行在 Pod 组中的服务,而无需关心后端 Pod 的具体细节。可以将 Service 想象成应用程序的“前端”或“入口”。Deployment
: 提供了一种声明式的方式来管理 Pod 和ReplicaSet
(见下文)的更新。您在 Deployment 中描述应用程序的期望状态(例如,运行 N 个副本的特定容器镜像),Deployment 控制器会以受控的速率将实际状态逐步改变为期望状态。Deployment 支持滚动更新(逐步替换旧 Pod)、回滚到先前版本、暂停和恢复部署等功能。它是部署无状态应用(如 Web 服务器)最常用的方式。ReplicaSet
: 确保在任何给定时间运行指定数量的 Pod 副本(replicas)。它的主要目的是保证 Pod 的可用性和可伸缩性。通常,您不会直接创建 ReplicaSet,而是通过 Deployment 来创建和管理它们。Deployment 会创建 ReplicaSet 来实际管理 Pod 的数量。Namespace
: 提供了一种在同一个物理集群中划分虚拟集群的方法。它用于将集群资源(如 Pods, Services, Deployments)组织成逻辑上隔离的组。这对于多租户环境、区分开发/测试/生产环境或按团队/项目隔离资源非常有用。默认情况下,Kubernetes 会有几个预设的 Namespace,如default
、kube-system
(用于 Kubernetes 系统组件)、kube-public
。Volume
: Kubernetes 中的 Volume 解决了容器内文件生命周期短暂以及 Pod 内多容器间共享文件的问题。Volume 的生命周期与 Pod 相同,Pod 内的所有容器都可以访问它。Kubernetes 支持多种类型的 Volume,包括本地存储(如emptyDir
,生命周期同 Pod)、持久化存储(如PersistentVolumeClaim
,用于连接网络存储或云存储,生命周期独立于 Pod)以及配置数据卷(如ConfigMap
、Secret
)。ConfigMap
和Secret
: 用于将配置数据和敏感信息(如密码、API 密钥)与应用程序代码解耦。ConfigMap
用于存储非机密的键值对配置数据,而Secret
用于存储敏感信息(数据会被 base64 编码,但并非加密,需要配合 RBAC 等机制保证安全)。这些对象可以作为环境变量、命令行参数或卷挂载到 Pod 中供应用程序使用。Ingress
: 管理对集群内部 Service 的外部访问(主要是 HTTP 和 HTTPS 流量)。它可以提供负载均衡、SSL/TLS 终止和基于名称的虚拟主机路由。Ingress 将外部请求路由到集群内部的不同 Service,通常需要一个 Ingress Controller(如 Nginx Ingress Controller, Traefik)来实际处理这些规则。可以将其视为集群流量的“路由器”或“网关”。StatefulSet
: 用于管理有状态应用程序(如数据库、需要稳定网络标识符和持久存储的应用)。与 Deployment 不同,StatefulSet 为其管理的每个 Pod 提供唯一的、稳定的网络标识符(如web-0
,web-1
)和稳定的持久存储。Pod 的创建、更新和删除是有序且受控的。DaemonSet
: 确保集群中的全部(或部分)节点都运行一个指定的 Pod 副本。常用于运行集群范围的守护进程,例如日志收集器(如 Fluentd)、节点监控代理(如 Prometheus Node Exporter)或存储插件。
五、 与 Kubernetes 交互:kubectl
kubectl
是 Kubernetes 的主要命令行工具,允许您与 Kubernetes 集群进行交互。通过 kubectl
,您可以:
- 部署应用程序 (例如
kubectl apply -f my-app.yaml
) - 检查和管理集群资源 (例如
kubectl get pods
,kubectl describe deployment my-deployment
) - 查看日志 (例如
kubectl logs my-pod
) - 在容器内执行命令 (例如
kubectl exec -it my-pod -- /bin/bash
) - 获取集群信息 (例如
kubectl cluster-info
,kubectl get nodes
)
kubectl
通过向 Kubernetes API 服务器发送请求来工作。它通常读取 YAML 或 JSON 格式的配置文件(称为 Manifest 文件),这些文件描述了您想要创建或更新的 Kubernetes 对象的状态。这种使用配置文件声明期望状态的方式被称为 声明式配置 (Declarative Configuration),是 Kubernetes 推荐的管理方式,因为它更易于版本控制、审计和自动化。当然,kubectl
也支持 命令式命令 (Imperative Commands)(例如 kubectl run my-nginx --image=nginx
),这对于快速测试或一次性任务很方便,但不推荐用于生产环境的管理。
六、 初学者的学习路径
学习 Kubernetes 是一个循序渐进的过程。以下是一个建议的学习路径:
-
掌握先决条件:
- Linux 基础和命令行: Kubernetes 的许多操作都在命令行完成,并且其节点通常运行 Linux。
- 容器基础 (Docker): 深刻理解容器是什么、如何构建 Docker 镜像、运行容器、管理容器生命周期至关重要。
- 网络基础: 了解 IP 地址、端口、DNS、负载均衡、代理等基本概念。
- YAML 语法: Kubernetes 的配置文件主要使用 YAML 格式。
-
搭建本地学习环境:
- Minikube: 在本地机器上运行一个单节点的 Kubernetes 集群,非常适合学习和实验。
- kind (Kubernetes in Docker): 使用 Docker 容器作为“节点”来运行本地 Kubernetes 集群。
- k3s: 一个轻量级的 Kubernetes 发行版,易于安装和运行。
- Docker Desktop: 内置了 Kubernetes 功能,可以在 Windows 和 macOS 上方便地启动本地集群。
- 在线 Playground: 如 Katacoda、Play with Kubernetes 等提供了临时的在线 Kubernetes 环境。
-
理解核心概念和对象:
- 从
Pod
开始,理解它是运行容器的基本单元。 - 学习
Service
如何暴露 Pod 并提供稳定的访问点。 - 掌握
Deployment
如何管理应用程序的部署、更新和扩展。 - 理解
Namespace
如何隔离资源。
- 从
-
实践
kubectl
命令:- 练习常用的
get
,describe
,apply
,delete
,logs
,exec
命令。 - 尝试创建简单的 Pod、Service 和 Deployment 的 YAML 文件,并使用
kubectl apply
部署它们。
- 练习常用的
-
部署一个简单的应用程序:
- 选择一个简单的 Web 应用(如 Nginx 或一个简单的 Node.js/Python 应用),将其打包成 Docker 镜像。
- 编写 Deployment YAML 文件来部署它。
- 编写 Service YAML 文件(如
ClusterIP
或NodePort
类型)来暴露它。 - 尝试访问您的应用程序。
-
深入学习网络:
- 理解不同类型的 Service (
ClusterIP
,NodePort
,LoadBalancer
) 的区别和用途。 - 学习
Ingress
如何处理外部 HTTP/S 流量路由。尝试部署一个 Ingress Controller 和 Ingress 规则。
- 理解不同类型的 Service (
-
探索存储:
- 了解
Volume
的概念。 - 使用
emptyDir
进行 Pod 内数据共享。 - 学习
PersistentVolume
(PV) 和PersistentVolumeClaim
(PVC) 如何为 Pod 提供持久化存储(这在本地环境可能需要额外配置或使用特定存储插件)。
- 了解
-
管理配置和密钥:
- 学习如何使用
ConfigMap
注入配置数据。 - 学习如何使用
Secret
安全地管理敏感信息。
- 学习如何使用
-
了解健康检查和资源管理:
- 学习如何为 Pod 配置 Liveness Probe 和 Readiness Probe,以实现自愈和可靠的服务发布。
- 了解如何为容器设置资源请求(requests)和限制(limits),以帮助 Kubernetes 调度和管理资源。
-
进阶主题 (了解即可):
StatefulSet
(用于有状态应用)DaemonSet
(用于节点守护进程)- Helm (Kubernetes 包管理器)
- Operators (自动化复杂应用管理)
- 监控 (Prometheus, Grafana) 与日志 (EFK/Loki Stack)
- RBAC (基于角色的访问控制) 与网络策略 (Network Policies)
七、 Kubernetes 的优势
- 自动化: 大大减少了手动运维工作。
- 高可用性: 通过副本和自愈能力确保应用持续运行。
- 可伸缩性: 可以根据负载自动或手动调整应用实例数量。
- 基础设施解耦: 应用更具可移植性,可以在不同云平台或本地数据中心运行。
- 提高资源利用率: 通过智能调度优化硬件资源使用。
- 加速开发和部署: 提供标准化的部署和管理流程。
- 庞大的生态系统和社区: 拥有丰富的工具、插件和活跃的社区支持。
八、 Kubernetes 的挑战
- 复杂性: 学习曲线相对陡峭,涉及的概念和组件较多。
- 运维成本: 管理 Kubernetes 集群本身也需要专业知识和资源投入。
- 资源消耗: 控制平面和节点组件本身会消耗一定的计算资源。
- 网络复杂性: 集群网络配置和故障排查可能比较复杂。
- 安全性: 需要仔细配置 RBAC、网络策略、密钥管理等来确保集群安全。
九、 结论与下一步
Kubernetes 已经成为云原生时代部署和管理应用程序的事实标准。虽然初看起来它可能很复杂,但其提供的自动化、可伸缩性和弹性能力对于现代应用架构至关重要。
对于初学者来说,关键在于循序渐进,从核心概念入手,动手实践。不要试图一次性掌握所有内容。搭建一个本地环境,部署简单的应用,逐步探索不同的对象和功能。利用官方文档、在线教程、社区论坛和互动式学习平台。
学习 Kubernetes 的旅程可能充满挑战,但掌握这项技能将为您在 DevOps、云计算和软件工程领域打开新的大门。它不仅仅是一个工具,更是一种构建、部署和运行可伸缩、高可用应用的思维方式。现在就开始您的 Kubernetes 学习之旅吧!利用本文提供的路线图,一步一个脚印,您将逐渐揭开这个强大平台的奥秘,并最终能够自信地驾驭它。