学习K8s第一步: Kubernetes入门指南
在当今云原生和微服务盛行的时代,Kubernetes(常简称为K8s)已经成为容器编排和管理的行业标准。无论是大型互联网公司还是初创企业,掌握Kubernetes都意味着拥抱更高效、更弹性、更可靠的应用部署与运维方式。然而,对于初学者来说,K8s庞大而复杂的概念体系可能会让人望而生畏。
本篇文章旨在为你揭开Kubernetes的神秘面纱,作为你学习旅程的第一步。我们将从最基础的概念讲起,介绍K8s是什么、为什么需要它,以及如何迈出实践的第一步。请准备好,我们即将踏上这场激动人心的云原生之旅!
第一章:K8s是什么?为什么我们需要它?
1.1 什么是Kubernetes (K8s)?
Kubernetes,源自希腊语,意为“舵手”或“引航员”。它是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。简单来说,如果Docker等容器技术解决了“如何在任何地方运行我的应用”的问题,那么Kubernetes就是解决“如何大规模、可靠地运行和管理成千上万个这样的应用实例”的问题。
你可以把Kubernetes集群想象成一个庞大的、分布式的“云操作系统”。在这个操作系统上,你不需要关心底层的物理机或虚拟机,只需要提交你的应用程序(打包成容器镜像),告诉K8s你想要运行多少个实例,它们之间如何互相访问,以及如何对外提供服务。Kubernetes会负责:
- 自动化部署与回滚: 轻松地将你的应用程序部署到集群中,并在需要时回滚到之前的版本。
- 自动扩缩容: 根据流量负载或其他指标,自动增加或减少应用程序的实例数量。
- 自我修复: 当容器或节点发生故障时,自动重启失败的容器,或在新的节点上重新调度容器。
- 服务发现与负载均衡: 为你的应用程序提供一个稳定的网络地址,并自动将流量分发到健康的实例上。
- 存储编排: 自动挂载指定的存储系统(如本地存储、云存储等)到容器中。
- 配置管理与密文管理: 安全地管理应用程序的配置信息和敏感数据(如密码、密钥)。
Kubernetes最初由Google设计并捐赠给云原生计算基金会(CNCF),现在已经拥有一个庞大而活跃的社区。
1.2 为什么我们需要Kubernetes?
在没有容器编排工具的时代,部署和管理应用程序,特别是微服务架构下的应用,面临着诸多挑战:
- 手动部署与更新效率低下: 当你有几十个甚至几百个服务,每个服务有多个实例时,手动SSH到服务器进行部署、更新、重启几乎是不可能的。
- 资源利用率不高: 不同的应用可能部署在不同的服务器上,难以实现资源的统一管理和优化。
- 高可用性难以保证: 如果某个服务器宕机,上面的应用实例就会中断服务,需要人工介入恢复。
- 弹性伸缩困难: 应对突发的流量高峰需要手动增加服务器和应用实例,响应速度慢。
- 服务之间的通信复杂: 如何让不同的服务找到并互相通信是一个棘手的问题,特别是当服务实例的IP地址经常变化时。
- 配置管理混乱: 不同的环境(开发、测试、生产)有不同的配置,手动管理容易出错。
Kubernetes正是为了解决这些问题而诞生的。它提供了一个声明式的API,你只需要描述你期望的应用状态(例如:我想要运行3个Nginx实例,它们可以通过80端口访问),K8s就会尽力将当前状态调整到期望状态。这极大地提高了运维效率,降低了出错率,并提供了强大的自愈和弹性能力。
简单来说,使用Kubernetes意味着:
- 提高了开发和运维效率: 自动化一切重复性工作。
- 增强了应用的可靠性和可用性: 自动处理故障,保证服务不中断。
- 实现了资源的更优利用: 在集群范围内统一调度和管理资源。
- 简化了微服务管理: 提供了内置的服务发现和负载均衡。
- 增强了应用的可移植性: 基于容器,可以在任何支持K8s的环境中运行。
因此,学习和掌握Kubernetes,对于希望构建和管理现代、可伸缩、高可用应用的人来说,已经是必不可少的技能。
第二章:入门前的准备:你需要了解的基础知识
在深入Kubernetes之前,了解一些基础概念会非常有帮助,这能让你更快地理解K8s的工作原理和术语。
2.1 容器基础(推荐Docker)
Kubernetes是围绕容器构建的。最流行的容器技术是Docker。在学习K8s之前,建议你至少了解:
- 什么是容器: 容器是一种轻量级、可移植、自给自足的软件包,包含应用程序运行所需的一切(代码、运行时、系统工具、系统库等)。
- 什么是镜像(Image): 镜像是容器的只读模板,包含运行应用程序所需的文件系统和元数据。
- 什么是容器实例(Container): 镜像是容器的运行实例。
- 如何构建镜像: 理解
Dockerfile
的基本语法。 - 如何运行容器: 了解
docker run
等基本命令。
提示: 如果你对Docker还不熟悉,可以先花一些时间学习Docker的基础知识。这是学习K8s的坚实基础。
2.2 Linux基础
Kubernetes集群通常运行在Linux操作系统上。熟悉基本的Linux命令(如ls
, cd
, pwd
, cp
, mv
, rm
, ssh
, systemctl
, journalctl
, top/htop
)和概念(如文件系统、进程、网络配置)会非常有帮助,特别是在排查问题时。
2.3 YAML基础
Kubernetes使用YAML(YAML Ain’t Markup Language)文件来定义其各种资源对象(如 Pod、Deployment、Service等)。YAML是一种人类可读的数据序列化格式,常用于配置文件。你需要了解YAML的基本语法,包括:
- 缩进: YAML使用缩进来表示结构层次,务必注意不能使用Tab键,只能使用空格。
- 键值对:
key: value
- 列表/数组: 使用
-
开头表示列表项。 - 字典/对象: 使用缩进表示嵌套的键值对。
例如,一个简单的YAML结构:
yaml
person:
name: Alice
age: 30
cities:
- New York
- London
isStudent: false
你不需要成为YAML专家,但能够阅读和编写基本的K8s资源定义文件是必需的。
第三章:迈出第一步:搭建本地K8s环境
学习任何新技术,动手实践都是最有效的方式。在学习Kubernetes的第一步,搭建一个本地的单节点K8s集群是最好的选择。这样你可以在自己的电脑上安全地实验,而无需复杂的云环境设置或担心费用。
有几种流行的本地Kubernetes解决方案可供选择:
- Minikube: 一个轻量级的工具,可以在虚拟机中快速启动一个单节点的Kubernetes集群。它支持多种虚拟化驱动(VirtualBox, VMware, KVM, HyperV等)。
- Kind (Kubernetes in Docker): 使用Docker容器作为节点来运行本地Kubernetes集群。它特别适合用于测试K8s本身或自动化CI/CD流程。
- Docker Desktop (内置Kubernetes): 如果你已经在使用Docker Desktop(适用于Windows和macOS),它通常内置了启动一个单节点K8s集群的选项,非常方便。
推荐:对于初学者,如果你的系统支持且已经安装了Docker Desktop,直接启用内置的Kubernetes是最快捷的方式。否则,Minikube是一个非常成熟和广泛使用的选项。
下面我们以Minikube为例,简述搭建步骤(具体步骤请参考官方文档,因为安装细节可能随版本变化):
- 安装虚拟机软件: 例如 VirtualBox 或 VMware Fusion。
- 安装kubectl: Kubectl是Kubernetes的命令行工具,用于与集群进行交互。你需要根据你的操作系统下载并安装它。访问 https://kubernetes.io/docs/tasks/tools/install-kubectl/ 获取详细指南。
- 安装Minikube: 访问 https://minikube.sigs.k8s.io/docs/start/ 根据你的操作系统下载并安装Minikube。
- 启动Minikube集群: 打开终端,运行命令:
bash
minikube start
Minikube会自动下载必要的镜像和组件,并在虚拟机中启动一个单节点的K8s集群。这个过程可能需要一些时间,取决于你的网络状况。 - 验证集群状态: 集群启动完成后,可以使用kubectl命令检查集群信息:
bash
kubectl cluster-info
kubectl get nodes
kubectl cluster-info
会显示Kubernetes控制平面(Master)和各个服务(如 CoreDNS, Dashboard)的地址。kubectl get nodes
会显示集群中的节点列表,你应该看到一个节点,状态是Ready
。
恭喜你!你现在已经拥有了一个可供实验的本地Kubernetes环境。
第四章:Kubernetes核心概念初探
在开始动手实践之前,让我们简单了解几个最最核心的Kubernetes概念。这将帮助你理解后续操作的意义。
4.1 Node(节点)
Node是Kubernetes集群中的工作机器,可以是虚拟机或物理机。每个Node都运行着必要的服务来管理容器,包括:
- kubelet: 负责与Kubernetes控制平面通信,管理运行在Node上的Pod。
- Container Runtime: 运行容器的软件,如Docker、containerd、CRI-O。
- kube-proxy: 负责Pod之间的网络通信和服务发现。
Node由Master(控制平面)管理。当一个Node发生故障时,Master会将运行在该Node上的工作负载调度到其他健康的Node上。
4.2 Pod
Pod是Kubernetes中最小的可部署计算单元。 它代表集群中运行的一个或一组紧密相关的容器。
一个Pod中的容器:
- 共享网络命名空间: 它们共享同一个IP地址和端口空间,可以通过
localhost
互相通信。 - 共享存储卷(Volume): 如果配置了卷,它们可以访问共享的数据。
- 总是被一起调度: 它们会被调度到同一个Node上运行。
通常情况下,一个Pod只包含一个容器。但在某些场景下,可以将紧密耦合的多个容器打包到同一个Pod中(例如,一个主应用容器和一个Sidecar日志收集容器)。
Pod是短暂的。当一个Pod死亡(因为Node故障或Pod被删除),它不会自己恢复。我们通常不直接创建单个的Pod,而是使用更上层的控制器来管理Pod的生命周期。
4.3 Deployment(部署)
Deployment是一个更高层次的控制器,用于管理无状态的Pod。它提供了一种声明式的方式来更新Pod和ReplicaSets。
Deployment的主要功能:
- 管理ReplicaSet: Deployment会创建一个或多个ReplicaSet。
- 管理Pod副本数: 通过ReplicaSet确保指定数量的Pod副本正在运行。
- 滚动更新: 以一种受控的方式逐步用新版本的Pod替换旧版本的Pod,避免服务中断。
- 回滚: 如果新版本出现问题,可以轻松回滚到之前的稳定版本。
对于大多数无状态的应用(如Web服务器、API服务),Deployment是推荐的部署方式。你只需要告诉Deployment你想要运行多少个Pod副本,使用哪个容器镜像,Deployment就会负责创建和维护这些Pod。
4.4 Service(服务)
Pod是短暂的,它们的IP地址可能会随着Pod的创建、删除或调度而改变。这给服务之间的通信带来了问题:客户端如何找到并访问正确的Pod实例?
Service解决了这个问题。它是一个抽象层,为一组Pod提供了一个稳定的网络端点(一个固定的IP地址和端口)。客户端只需要连接Service的IP地址和端口,Service会自动将请求负载均衡到其背后健康运行的Pod实例上。
Service有几种类型,最常见的有:
- ClusterIP: Service获得一个集群内部IP地址,只能在集群内部访问。这是默认类型。
- NodePort: Service通过集群中 每个 Node的特定端口暴露服务。可以通过
NodeIP:NodePort
从集群外部访问。 - LoadBalancer: 在云环境中,Kubernetes会请求云提供商创建一个外部负载均衡器,将流量导向Service。
- ExternalName: 将服务映射到外部DNS名称。
对于你的第一个应用程序,我们通常会使用 Deployment 来管理 Pod,然后使用 Service(可能是 NodePort 类型,方便本地访问)来暴露应用程序。
第五章:你的第一个K8s实践:部署一个Web应用
现在,是时候将理论付诸实践了!我们将使用 kubectl
命令,通过声明式配置(YAML) 来部署一个简单的Nginx Web服务器应用。虽然前面提到了简单的命令式方式 (kubectl create deployment
), 但学会使用YAML是管理K8s资源的更标准和推荐的方法,所以我们直接从YAML开始。
5.1 定义你的应用 (YAML 文件)
首先,创建一个名为 nginx-app.yaml
的文件,并在其中定义一个Deployment和一个Service:
“`yaml
定义一个 Deployment
apiVersion: apps/v1 # Deployment 资源所属的 API 版本
kind: Deployment # 资源的类型是 Deployment
metadata:
name: nginx-deployment # Deployment 的名称
spec:
replicas: 3 # 希望运行的 Pod 副本数量
selector:
matchLabels: # 用于选择哪些 Pod 属于这个 Deployment
app: nginx # Pod 必须带有 label “app: nginx”
template: # 定义 Pod 的模板
metadata:
labels: # Pod 的标签
app: nginx
spec:
containers: # Pod 中包含的容器列表
– name: nginx # 容器的名称
image: nginx:latest # 容器使用的镜像
ports:
– containerPort: 80 # 容器内部应用监听的端口
— # — 是 YAML 分隔符,表示定义下一个 K8s 资源
定义一个 Service
apiVersion: v1 # Service 资源所属的 API 版本
kind: Service # 资源的类型是 Service
metadata:
name: nginx-service # Service 的名称
spec:
selector:
app: nginx # Service 将流量转发到带有 label “app: nginx” 的 Pod
ports:
– protocol: TCP # 协议类型
port: 80 # Service 监听的端口 (Service 的 ClusterIP:port)
targetPort: 80 # 流量转发到 Pod 的哪个端口 (Pod 的 containerPort)
nodePort: 30000 # (可选,如果 Service type 是 NodePort) Node 上暴露的端口,范围通常在 30000-32767
type: NodePort # Service 的类型,这里使用 NodePort 方便从外部访问本地集群
“`
解释这个文件:
- 我们定义了两个K8s资源:一个Deployment (
nginx-deployment
) 和一个Service (nginx-service
)。 - Deployment 指定我们想要运行 3 个带有
app: nginx
标签的 Pod 副本,这些 Pod 使用nginx:latest
镜像,容器暴露 80 端口。 - Service 使用
selector: app: nginx
来找到由nginx-deployment
创建的 Pod。 - Service 定义了端口映射:将 Service 的 80 端口流量转发到 Pod 的 80 端口。
- Service 的类型是
NodePort
,这意味着Kubernetes会在集群中的每个Node上(对于Minikube就是那个唯一的Node)打开一个随机的高位端口(或指定nodePort: 30000
),并将该端口的流量转发到Service的80端口,进而转发到Pod。这样我们就可以通过访问NodeIP:NodePort
来访问Nginx。
5.2 应用配置到集群
保存上述内容为 nginx-app.yaml
文件后,打开终端,确保你的kubectl已经配置为指向你的本地Minikube集群(minikube start
已经为你做好了这件事)。然后执行以下命令来应用这个配置文件:
bash
kubectl apply -f nginx-app.yaml
kubectl apply -f <filename>
是一个非常常用的命令,它会根据YAML文件中定义的期望状态来创建或更新K8s资源。
如果一切顺利,你会看到类似这样的输出:
deployment.apps/nginx-deployment created
service/nginx-service created
这表示Deployment和Service资源已经在集群中创建成功。
5.3 检查资源状态
现在,让我们看看Kubernetes集群中发生了什么。使用 kubectl get
命令来查看你创建的资源:
查看 Deployment:
bash
kubectl get deployments
输出可能类似:
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 <some-time>
READY
列显示的是 3/3
,表示期望的3个Pod副本都已准备就绪并运行。
查看 Pods:
bash
kubectl get pods
输出可能类似:
NAME READY STATUS RESTARTS AGE
nginx-deployment-abcdefg-12345 1/1 Running 0 <some-time>
nginx-deployment-abcdefg-67890 1/1 Running 0 <some-time>
nginx-deployment-abcdefg-vwxyz 1/1 Running 0 <some-time>
你会看到3个Pod,它们的名称以nginx-deployment
开头,后面跟着ReplicaSet的哈希值和Pod的随机ID。STATUS
列显示 Running
,表示Pod正在正常运行。
查看 Services:
bash
kubectl get services
输出可能类似:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP <some-time> # 这是 K8s 内置的服务
nginx-service NodePort 10.100.xxx.xxx <none> 80:30000/TCP <some-time> # 你创建的服务
找到 nginx-service
,可以看到它的类型是 NodePort
,并且端口映射显示 80:30000/TCP
(如果指定了 nodePort: 30000
)。这表示 Service 在内部监听 80 端口,并通过 Node 的 30000 端口暴露出去。
5.4 访问你的应用
你的Nginx应用现在已经在Kubernetes集群中运行了,并且通过NodePort Service暴露出来。要访问它,你需要知道Minikube虚拟机的IP地址和Service的NodePort端口。
- 获取Minikube IP:
bash
minikube ip
输出会是Minikube虚拟机的IP地址,例如192.168.49.2
。 - 获取Service的NodePort端口: 你已经通过
kubectl get services
知道了是 30000。 - 在浏览器中访问: 打开你的浏览器,访问
http://<minikube-ip>:<nodeport>
,例如http://192.168.49.2:30000
。
你应该能看到Nginx的欢迎页面!
另一种使用Minikube访问Service的方式:
Minikube提供了一个方便的命令来直接打开浏览器访问NodePort Service:
bash
minikube service nginx-service
这个命令会自动获取Minikube IP和Service的NodePort,并在默认浏览器中打开访问地址。
5.5 体验K8s的弹性能力 (扩缩容)
还记得我们在Deployment中设置了 replicas: 3
吗?这意味着我们希望运行3个Nginx Pod。现在,让我们体验一下K8s的扩缩容能力,将Pod数量扩展到5个:
bash
kubectl scale deployment nginx-deployment --replicas=5
执行命令后,立即查看Pod状态:
bash
kubectl get pods
你会看到Kubernetes正在创建新的Pod,直到总共有5个Pod运行。这个过程是自动化的,无需你手动启动新的容器。
5.6 清理你的实验环境
当你完成了实验,为了释放资源,你需要删除你创建的Kubernetes资源:
bash
kubectl delete -f nginx-app.yaml
这个命令会读取 nginx-app.yaml
文件,并删除其中定义的所有资源(Deployment和Service)。删除Deployment会自动删除它管理的Pod和ReplicaSet。
你可以再次使用 kubectl get deployments
, kubectl get pods
, kubectl get services
来确认资源已经被删除。
最后,如果你想停止Minikube虚拟机:
bash
minikube stop
如果你想彻底删除Minikube虚拟机和相关文件:
bash
minikube delete
第六章:下一步去哪里?
恭喜你!你已经成功迈出了学习Kubernetes的第一步,了解了其核心概念,并在本地环境中亲手部署和访问了一个应用程序。这只是冰山一角,但你已经掌握了入门的关键。
接下来,你可以继续深入学习以下主题:
- 更深入地理解YAML: 学习更多K8s资源的定义方式,如 StatefulSet (管理有状态应用), DaemonSet (在每个Node上运行一个Pod), Job/CronJob (运行一次性或定时任务)。
- 了解更多的
kubectl
命令: 学习如何查看资源详情 (kubectl describe
), 查看Pod日志 (kubectl logs
), 在Pod中执行命令 (kubectl exec
), 复制文件 (kubectl cp
) 等,这些对于调试非常重要。 - Service 类型和 Ingress: 深入理解ClusterIP, NodePort, LoadBalancer 的区别,以及如何使用Ingress来提供更灵活、强大的外部访问方式。
- 存储 (Volumes): 学习如何为Pod提供持久化存储,以及各种存储插件的使用。
- 配置管理 (ConfigMap) 和 密文管理 (Secrets): 学习如何将应用的配置和敏感数据与Pod解耦。
- 网络: 了解Kubernetes的网络模型和各种网络插件 (CNI)。
- 命名空间 (Namespaces): 学习如何使用命名空间来隔离不同的环境或项目。
- Helm: 学习使用Helm这个包管理器来简化K8s应用的部署和管理。
- 更高级的部署策略: 了解蓝绿部署、金丝雀发布等。
- 监控与日志: 了解如何集成Prometheus进行监控和EFK/Loki进行日志管理。
推荐的学习资源:
- Kubernetes官方文档 (kubernetes.io): 最权威、最全面的资料来源。特别是“概念”(Concepts)和“任务”(Tasks)部分。
- Kubernetes By Example (k8s.io/examples): 提供大量可以直接运行的示例。
- 在线课程: Coursera, Udemy, edX 等平台有许多优质的Kubernetes入门及进阶课程。
- 书籍: 许多关于Kubernetes的优秀书籍可以提供系统化的学习路径。
- 社区: 加入Kubernetes相关的Slack频道、论坛、Meetup等,与其他学习者和专家交流。
总结
学习Kubernetes是一个循序渐进的过程。不要试图一次性掌握所有概念。从核心组件(Node, Pod, Deployment, Service)开始,结合实际动手操作,逐步深入。理解为什么需要K8s,以及它是如何解决传统应用部署和管理中的痛点,将帮助你更好地把握学习方向。
本指南为你提供了一个起点。你已经成功搭建了本地环境,部署了你的第一个应用,并了解了K8s的核心思想和基础操作。记住,持续的实践和探索是掌握这项强大技术的关键。
祝你在Kubernetes的学习旅程中一切顺利!云原生的世界正在向你敞开大门。