Kubernetes 入门教程:从零开始学习 k8s
欢迎来到云原生的世界!如果您正准备踏入容器编排的领域,那么 Kubernetes (常简称为 k8s) 将是您旅途中最重要的一站。Kubernetes 是目前最流行、功能最强大的开源容器编排系统,它能自动化容器化应用的部署、扩缩容和管理。
对于初学者来说,Kubernetes 可能看起来像一个庞然大物,包含众多概念和组件。但请不要畏惧,本教程将从零开始,带您逐步拆解 Kubernetes 的核心思想和基本操作,让您也能驾驭这个强大的工具。
本文的目标是:
1. 理解 Kubernetes 出现的背景和解决的问题。
2. 掌握 Kubernetes 的核心概念和架构。
3. 学会如何在本地搭建一个迷你的 Kubernetes 环境。
4. 实践部署一个简单的应用,了解 Pod, Deployment, Service 等基本资源对象。
5. 为您指明进一步学习的方向。
让我们开始吧!
第一部分:理解 Kubernetes 的前世今生
在深入学习 Kubernetes 之前,我们需要了解它为何如此重要,它解决了哪些问题。
1. 从传统部署到容器化
想象一下传统的应用部署方式:开发者写好代码,构建成一个或多个二进制文件/安装包,然后运维人员需要手动或使用脚本将这些文件部署到服务器上。这个过程面临诸多挑战:
- 环境依赖: 应用依赖特定的操作系统版本、库文件、配置文件等。不同服务器环境的差异可能导致“在我机器上没问题,到生产环境就出问题”的情况。
- 资源隔离: 多个应用部署在同一台服务器上,它们可能会相互影响,争抢资源,甚至因为依赖冲突而无法共存。
- 部署复杂性: 部署新版本、回滚、迁移等操作复杂且容易出错。
- 扩容困难: 面对高并发时,需要手动或编写复杂脚本来增加服务器数量,配置环境,然后部署应用。
- 弹性不足: 应用宕机或服务器故障时,需要人工介入恢复。
2. 容器的出现 (Docker)
容器技术(以 Docker 为代表)彻底改变了应用的打包和部署方式。容器将应用及其所有依赖(代码、运行时、库、环境变量、配置文件等)打包在一个标准的、可移植的单元中。
容器的优点:
- 环境一致性: 容器镜像包含了应用运行所需的所有环境,无论在开发、测试还是生产环境,运行的都是同一个容器,极大地减少了环境差异问题。
- 隔离性: 容器之间相互隔离,拥有自己的文件系统、进程空间、网络接口等,降低了相互影响。
- 轻量与可移植: 容器比虚拟机更轻量,启动更快,可以轻松地在不同的主机、云平台之间迁移。
容器解决了应用打包和单机运行的问题,但当你的应用数量达到几十个、几百个,需要运行在成千上万个容器中,并且需要处理扩容、故障恢复、服务发现等问题时,手动管理这些容器就变得异常困难。
3. 容器编排的需求
这时,我们就需要一个系统来自动化地管理大量的容器,这就是 容器编排。容器编排系统的职责包括:
- 部署和管理: 自动将容器部署到合适的机器上,并持续监控其状态。
- 扩缩容: 根据负载自动或手动增加/减少容器实例数量。
- 服务发现与负载均衡: 容器实例的 IP 可能会变化,服务编排系统需要提供一种机制让应用能够相互发现并进行负载均衡。
- 自我修复: 当容器或所在机器故障时,自动重启或在其他可用机器上重新创建容器。
- 滚动更新与回滚: 安全地更新应用版本,并在需要时回退到旧版本。
- 配置管理和密钥管理: 安全地管理应用的配置和敏感信息。
Kubernetes 正是为解决这些问题而诞生的最优秀的容器编排系统之一。它最初由 Google 设计(基于其内部 Borg 系统),后捐赠给 Cloud Native Computing Foundation (CNCF) 进行维护。
第二部分:Kubernetes 的核心概念与架构
理解 Kubernetes 的架构和核心概念是学习的关键。Kubernetes 采用主从架构,由一组 Master 节点(现在更常称为 控制平面 – Control Plane)和一组 Worker 节点(也称为 Node)组成。
1. 控制平面 (Control Plane)
控制平面是 Kubernetes 集群的大脑,负责管理整个集群。它由以下关键组件组成:
- kube-apiserver (API Server): 这是 Kubernetes 控制平面的前端接口,暴露 Kubernetes API。所有其他组件和用户都通过 API Server 进行通信和操作。它是整个集群的核心枢纽。
- etcd: 一个高可用、分布式的键值存储系统,作为 Kubernetes 集群的唯一数据存储。集群的所有状态信息(如 Pod、Service、Deployment 等的定义和状态)都存储在 etcd 中。
- kube-scheduler (Scheduler): 负责监听新创建的、尚未被分配到 Node 的 Pod。根据预设的调度策略(如资源需求、节点亲和性/反亲和性、硬件/软件/策略约束、Taints/Tolerations 等),为 Pod 选择合适的 Node 进行部署。
- kube-controller-manager (Controller Manager): 运行各种控制器进程。控制器是 Kubernetes 的核心组件之一,它们持续监控集群的当前状态,并努力使其达到期望状态(定义在 etcd 中)。常见的控制器包括:
- 节点控制器 (Node Controller):负责管理节点的状态。
- 副本控制器 (Replication Controller) / Deployment 控制器:负责维护 Pod 的副本数量。
- Service 控制器:负责创建负载均衡器等。
- Endpoint 控制器:填充 Service 和 Pod 之间的关联。
- cloud-controller-manager (云控制器管理器 – 可选): 如果您在云环境中运行 Kubernetes,云控制器管理器负责与云服务商的 API 交互,管理云资源,如创建负载均衡器、公有云存储卷等。
2. 节点 (Node)
Node 是 Kubernetes 集群中的工作机器,可以是虚拟机或物理机。它们负责运行容器化的应用(即 Pods)。每个 Node 上都运行着以下组件:
- kubelet: 运行在每个 Node 上的代理程序。它接收来自 API Server 的 Pod 定义,并与容器运行时(如 Docker、containerd)交互,确保 Pod 中定义的容器正在运行、健康并按期望工作。它还向控制平面报告 Node 的状态、Pod 的状态等信息。
- kube-proxy: 运行在每个 Node 上的网络代理。它维护 Node 上的网络规则,实现 Service 的抽象,负责 Service 和其对应的 Pods 之间的网络通信和负载均衡。
- 容器运行时 (Container Runtime): 负责运行容器的软件,如 Docker, containerd, CRI-O 等。Kubelet 通过 CRI (Container Runtime Interface) 接口与容器运行时交互。
3. 核心资源对象 (Kubernetes Objects)
Kubernetes 通过资源对象来描述您的应用、集群的配置和状态。您通过 Kubernetes API(通常使用 kubectl
命令行工具或 YAML 文件)来创建、修改、删除这些对象,从而管理集群。理解这些对象是使用 Kubernetes 的基础。
- Pod: Kubernetes 中最小的可部署计算单元。一个 Pod 代表集群中运行的一个或一组紧密相关的容器。Pod 中的容器共享网络命名空间(相同的 IP 和端口空间)、存储卷等资源。通常情况下,一个 Pod 包含一个主应用容器和一些辅助容器(如日志收集、服务网格代理等)。
- Deployment: Deployment 是一种更高级别的资源对象,用于管理无状态应用的 Pods。它提供声明式更新能力。您可以指定应用所需的副本数量、更新策略(如滚动更新),Deployment 控制器会确保集群中始终运行着指定数量的 Pods,并在您更新 Pod 模板(如更换镜像版本)时,以受控的方式逐步替换旧 Pods。
- Service: Service 定义了一组 Pods 的逻辑集合以及访问它们的方式。Pod 的 IP 地址会随着 Pod 的创建和销毁而变化,Service 提供了一个稳定的 IP 地址和 DNS 名称来访问这组 Pods。Service 通过
Label Selector
来选择它要代理的 Pods。常见的 Service 类型有:ClusterIP
: 在集群内部暴露 Service,只能从集群内部访问。NodePort
: 在每个 Node 的特定端口上暴露 Service,可以通过任意 Node IP:NodePort 访问。LoadBalancer
: 在云环境中,自动创建一个云服务商的负载均衡器来暴露 Service。
- Namespace: 用于在集群内部划分逻辑隔离的区域。可以将集群资源(如 Pods, Services, Deployments)组织到不同的命名空间中,便于管理、权限控制和资源配额。默认有
default
,kube-system
,kube-public
,kube-node-lease
等命名空间。 - Volume: 用于为 Pod 提供持久化存储。容器的文件系统是短暂的,Pod 重启或迁移后数据会丢失。Volume 可以挂载到 Pod 中的容器上,提供独立于容器生命周期的存储空间。Kubernetes 支持多种类型的 Volume,如 EmptyDir (临时存储), HostPath (宿主机路径), 各种云存储 (AWS EBS, GCE PD, Azure Disk), NFS, iSCSI 等。
- ConfigMap 和 Secret: 用于将应用的配置信息和敏感数据与应用代码分离。
- ConfigMap: 存储非敏感的配置数据,可以作为环境变量、命令行参数或 Volume 中的文件挂载到 Pod 中。
- Secret: 存储敏感数据,如密码、OAuth Tokens、SSH Keys 等。Secret 默认只进行 Base64 编码,并非加密,但在传输和存储上比 ConfigMap 更安全一些。也可以作为环境变量或 Volume 中的文件挂载。
4. kubectl
kubectl
是 Kubernetes 的命令行工具,用于与 Kubernetes 集群的 API Server 交互。它是您操作集群的主要方式。通过 kubectl
,您可以部署应用、检查集群状态、管理资源等。
第三部分:从零开始:搭建本地 Kubernetes 环境
对于初学者来说,在本地搭建一个轻量级的 Kubernetes 环境是最好的学习方式。这里推荐使用 Minikube 或 Docker Desktop 内置的 Kubernetes。
1. 选择并安装工具
- Minikube: 一个在本地快速运行单节点 Kubernetes 集群的工具。它可以在虚拟机(如 VirtualBox, VMware, Hyper-V)、裸机,甚至 Docker 内部运行 Kubernetes。
- 安装 Minikube: 访问 Minikube 官方文档 (https://minikube.sigs.k8s.io/docs/start/),根据您的操作系统(Windows, macOS, Linux)选择对应的安装方法。通常需要先安装一个虚拟机驱动(如 VirtualBox)。
- Docker Desktop (推荐在 Windows 和 macOS): Docker Desktop 自带了单节点 Kubernetes 集群的功能,无需额外安装虚拟机驱动,非常方便。
- 安装 Docker Desktop: 访问 Docker Desktop 官方网站 (https://www.docker.com/products/docker-desktop/) 下载并安装。安装完成后,在设置中找到 “Kubernetes” 选项,勾选 “Enable Kubernetes” 并应用。
无论选择哪种方式,都需要安装 kubectl
命令行工具。
* 安装 kubectl: 访问 Kubernetes 官方文档 (https://kubernetes.io/docs/tasks/tools/install-kubectl/),根据您的操作系统选择对应的安装方法。
2. 启动本地集群
- 使用 Minikube: 打开终端,运行命令
minikube start
。Minikube 会自动下载所需的镜像,启动虚拟机或容器,并在其中部署一个单节点的 Kubernetes 集群。这个过程可能需要一些时间,取决于您的网络环境。 - 使用 Docker Desktop: 安装并启动 Docker Desktop 后,如果已经在设置中启用了 Kubernetes,它应该会自动启动。您可以通过 Docker Desktop 的图标或设置界面检查 Kubernetes 的状态。
3. 验证集群状态
集群启动后,您需要验证 kubectl
是否能正确连接到集群。
打开终端,运行以下命令:
bash
kubectl cluster-info
如果一切正常,您将看到集群的控制平面和附加服务的 URL 信息。
接着,检查集群的节点状态:
bash
kubectl get nodes
您应该会看到一个或多个节点处于 Ready
状态(Minikube 通常只有一个节点,Docker Desktop 也是一个)。
这表明您的本地 Kubernetes 环境已经搭建成功,您可以开始进行实践操作了!
第四部分:实践:部署您的第一个应用
现在,让我们动手部署一个简单的 Nginx Web 服务器应用到您的 Kubernetes 集群中,学习如何使用 Deployment 和 Service。
我们将使用 YAML 文件来声明我们期望的集群状态。这是 Kubernetes 中最常见的资源定义方式。
1. 定义 Deployment
创建一个名为 nginx-deployment.yaml
的文件,内容如下:
yaml
apiVersion: apps/v1 # Deployment 资源的 API 版本
kind: Deployment # 资源类型为 Deployment
metadata:
name: nginx-deployment # Deployment 的名称
labels: # 为这个 Deployment 打上标签,便于识别
app: nginx # 这个 Deployment 管理的应用是 nginx
spec:
replicas: 3 # 期望运行的 Pod 副本数量为 3
selector: # Deployment 通过这个选择器找到它管理的 Pods
matchLabels: # 选择带有特定标签的 Pods
app: nginx # 选择标签 app=nginx 的 Pods
template: # 这是 Pod 模板,Deployment 会根据这个模板创建 Pods
metadata:
labels: # 为 Pod 打上标签
app: nginx # Pod 的标签为 app=nginx (与 selector 匹配)
spec:
containers: # 定义 Pod 中包含的容器列表
- name: nginx # 容器的名称
image: nginx:latest # 使用 nginx 官方最新的镜像
ports:
- containerPort: 80 # 容器暴露的端口是 80
这个 YAML 文件声明了以下内容:
* 我们想要一个 Deployment 资源。
* 它的名字是 nginx-deployment
。
* 它希望运行 3 个 Pod 副本。
* 这些 Pod 的标签是 app: nginx
。
* 每个 Pod 中包含一个名为 nginx
的容器,使用 nginx:latest
镜像,并暴露 80 端口。
2. 创建 Deployment
使用 kubectl apply
命令创建这个 Deployment:
bash
kubectl apply -f nginx-deployment.yaml
您会看到类似如下输出:
deployment.apps/nginx-deployment created
3. 检查 Deployment 和 Pods 状态
检查 Deployment 的创建状态:
bash
kubectl get deployments
您应该会看到 nginx-deployment
,并且 READY
列显示 3/3
(表示 3 个期望副本都已就绪)。
检查由 Deployment 创建的 Pods:
bash
kubectl get pods -l app=nginx # 使用标签选择器过滤 Pods
您应该会看到 3 个名称以 nginx-deployment-
开头的 Pod,它们的状态都是 Running
。
您还可以查看 Pod 的详细信息:
bash
kubectl describe pod <其中一个 Pod 的名称> # 替换为实际的 Pod 名称
或者查看 Deployment 的详细信息:
bash
kubectl describe deployment nginx-deployment
4. 定义 Service
现在我们有 3 个 Nginx Pod 运行着,但是如何访问它们呢?Pod 的 IP 是动态的,并且只能从集群内部访问。我们需要一个 Service 来稳定地暴露这组 Pod。
创建一个名为 nginx-service.yaml
的文件,内容如下:
yaml
apiVersion: v1 # Service 资源的 API 版本
kind: Service # 资源类型为 Service
metadata:
name: nginx-service # Service 的名称
spec:
selector: # Service 通过这个选择器找到它要代理的 Pods
app: nginx # 选择标签 app=nginx 的 Pods
ports:
- protocol: TCP
port: 80 # Service 监听的端口 (Service Port)
targetPort: 80 # Service 将流量转发到 Pod 的哪个端口 (Container Port)
type: NodePort # Service 的类型,NodePort 允许从外部通过 Node IP:NodePort 访问
这个 YAML 文件声明了以下内容:
* 我们想要一个 Service 资源。
* 它的名字是 nginx-service
。
* 它会选择所有标签为 app: nginx
的 Pods。
* 它将在 Service 的 80 端口接收 TCP 流量,并将这些流量转发到它选择的 Pods 的 80 端口。
* Service 的类型是 NodePort
,这意味着 Kubernetes 会在集群的每个 Node 上打开一个静态端口(通常在 30000-32767 范围内),并将该端口映射到 Service 的 80 端口。
5. 创建 Service
使用 kubectl apply
命令创建这个 Service:
bash
kubectl apply -f nginx-service.yaml
您会看到类似如下输出:
service/nginx-service created
6. 检查 Service 状态并访问应用
检查 Service 的创建状态:
bash
kubectl get services
您应该会看到 nginx-service
,其类型为 NodePort
,并且 PORT(S)
列会显示 80:xxxxx/TCP
,其中 xxxxx
就是 Kubernetes 分配的 NodePort 端口号(例如 80:30080/TCP
)。
现在,您可以通过集群中任意一个 Node 的 IP 地址 加上这个 NodePort 端口号来访问 Nginx 服务了。
- 如果您使用 Minikube: 运行
minikube ip
获取 Minikube 虚拟机的 IP 地址,然后用浏览器或curl
访问http://<minikube-ip>:<NodePort>
。或者更简单的办法是,直接运行minikube service nginx-service
,Minikube 会自动打开浏览器访问该 Service。 - 如果您使用 Docker Desktop: Docker Desktop 的单节点集群通常直接运行在您的本机上。您可以使用
localhost
或127.0.0.1
作为 Node IP。用浏览器或curl
访问http://localhost:<NodePort>
。
您应该能看到 Nginx 的欢迎页面,这表明您的应用已成功通过 Kubernetes Service 暴露并访问!
7. 清理资源
完成实验后,清理创建的资源是个好习惯:
bash
kubectl delete -f nginx-service.yaml
kubectl delete -f nginx-deployment.yaml
或者更简单地使用资源类型和名称删除:
bash
kubectl delete service nginx-service
kubectl delete deployment nginx-deployment
您会看到资源被删除的提示,相关的 Pods 也会被终止。
第五部分:更进一步:探索更多 Kubernetes 功能
刚才的例子只是 Kubernetes 功能的冰山一角。一旦掌握了 Pod, Deployment, Service 的基本用法,您可以继续探索更多强大的特性:
- 扩缩容 (Scaling): 学习如何手动调整 Deployment 的副本数量 (
kubectl scale
),或者使用 Horizontal Pod Autoscaler (HPA) 根据 CPU 利用率等指标自动扩缩容。 - 更新与回滚 (Rolling Updates & Rollbacks): 修改 Deployment 的 YAML 文件(例如,更换 Nginx 镜像版本),再次
kubectl apply
,Kubernetes 会执行滚动更新。如果新版本有问题,可以使用kubectl rollout undo
进行回滚。 - 配置管理 (ConfigMaps & Secrets): 学习如何创建 ConfigMap 和 Secret,并将它们挂载到 Pod 中,实现配置和代码的分离。
- 持久化存储 (Volumes & PersistentVolumes): 对于需要存储数据的应用(如数据库),学习如何使用 Volume 和 PersistentVolume 来提供持久化存储。
- Ingress: 学习如何使用 Ingress 资源来管理外部对集群内部 Service 的访问,通常用于提供基于域名的访问、SSL 终端等。
- StatefulSet: 对于有状态应用(如数据库集群),StatefulSet 提供了稳定的网络标识和持久存储。
- Helm: Kubernetes 的包管理工具,可以帮助您更方便地打包、分发和部署应用。
- 集群网络和存储插件 (CNI & CSI): 了解 Kubernetes 如何通过插件机制支持不同的网络和存储解决方案。
- 监控、日志和告警: 学习如何集成 Prometheus, Grafana, EFK/ELK Stack 等工具来监控集群和应用的健康状况。
第六部分:下一步去哪里?
恭喜您已经完成了 Kubernetes 的入门学习!您已经理解了核心概念,并成功部署了一个简单的应用。这只是一个开始,Kubernetes 的世界非常广阔。
接下来的学习路径建议:
- 深入理解核心概念: 回顾并深入理解 Pod 的生命周期、Deployment 的更新策略、Service 的各种类型及其工作原理。
- 查阅官方文档: Kubernetes 官方文档 (https://kubernetes.io/docs/) 是最权威的学习资源。它内容丰富,涵盖了所有概念、任务和 API 参考。
- 多动手实践: 在本地环境或云服务商提供的免费 Kubernetes 集群上多做实验。尝试部署更复杂的应用,练习扩缩容、更新、故障模拟等操作。
- 学习 YAML 语法: 熟练掌握 Kubernetes 资源对象的 YAML 定义方式至关重要。
- 探索高级主题: 根据您的需求,深入学习网络、存储、安全、调度、日志、监控等高级主题。
- 关注云原生生态: Kubernetes 是云原生生态的核心,了解 Prometheus (监控), Grafana (可视化), Fluentd/Logstash (日志), Helm (包管理), Istio/Linkerd (服务网格), Tekton/Argo CD (CI/CD) 等相关工具,它们 अक्सर 与 Kubernetes 一起使用。
- 参与社区或学习课程: 加入 Kubernetes 社区,参与讨论,或选择一些高质量的在线课程系统学习。考虑考取 CNCF 认证 (如 CKA, CKAD) 可以系统性地巩固知识。
结语
Kubernetes 是现代应用部署和管理的基石,掌握它将极大地提升您在云原生时代的竞争力。虽然入门时可能面临不少新概念,但通过循序渐进的学习和持续的实践,您一定能逐步精通它。
从零开始,理解原理,动手实践,不断探索——这就是学习 Kubernetes 的最佳路径。祝您在 Kubernetes 的学习旅程中顺利愉快!