Kubernetes (K8s) 快速入门指南:从零开始掌握容器编排
导语
在当今快速发展的云计算和微服务架构时代,如何高效、可靠地部署、管理和扩展大量的容器化应用成为了一个核心挑战。Kubernetes(简称K8s)应运而生,并迅速成为容器编排领域的领导者。它提供了一个强大的平台,自动化容器化应用的部署、扩缩容和管理。
对于初学者来说,Kubernetes庞大的概念体系和命令行工具可能会让人望而生畏。本篇文章旨在提供一个详细且易于理解的K8s快速入门指南,帮助您从零开始,掌握Kubernetes的核心概念,搭建一个本地实验环境,并通过实际操作部署您的第一个容器化应用。
无论您是开发者、运维工程师,还是对容器技术充满好奇的技术爱好者,通过本文的学习,您将能够建立起对Kubernetes的基本认知和操作能力,为进一步深入学习和在实际项目中使用K8s打下坚实的基础。
本文将涵盖以下内容:
- 什么是Kubernetes?为何需要它?
- Kubernetes核心概念详解
- 本地Kubernetes环境搭建(以Minikube为例)
- kubectl命令行工具基础
- 使用YAML文件定义Kubernetes资源
- 部署您的第一个应用(Nginx)
- 暴露您的应用(Service)
- 应用的扩缩容与更新
- 进一步学习方向
准备好了吗?让我们开始Kubernetes之旅!
1. 什么是Kubernetes?为何需要它?
什么是Kubernetes?
Kubernetes是一个开源的容器编排系统,最初由Google设计并捐赠给Cloud Native Computing Foundation (CNCF)。它的主要目标是自动化部署、扩展和管理容器化应用程序。简单来说,如果Docker让你可以轻松地将应用打包成容器,那么Kubernetes则让你可以轻松地管理、运行和调度这些容器,尤其是在大规模集群环境中。
为何需要Kubernetes?
想象一下,你有一个包含几十甚至上百个微服务的应用程序。每个微服务都需要运行在容器中。如果没有一个强大的管理工具,你将面临以下挑战:
- 部署复杂性: 如何在多台服务器上部署所有容器?如何管理它们之间的依赖关系?
- 扩缩容: 当某个服务负载增加时,如何快速增加容器实例?负载降低时如何减少?
- 自我修复: 当某个容器或服务器发生故障时,如何自动重启或迁移容器,保证服务的可用性?
- 服务发现和负载均衡: 容器的IP地址是动态的,服务之间如何相互发现并进行负载均衡?
- 滚动更新和回滚: 如何在不停机的情况下升级应用版本?如果新版本有问题如何快速回退?
- 配置管理和密文管理: 如何安全地管理应用的配置信息和敏感数据(如数据库密码)?
- 资源利用率: 如何更高效地利用服务器资源,避免资源浪费?
Kubernetes正是为了解决这些问题而设计的。它提供了一套机制来声明你的应用应该如何运行(Desired State),然后系统会努力将当前状态(Current State)调整到期望状态。这极大地提高了应用程序的可靠性、可维护性和可伸缩性。
总结来说,选择Kubernetes的主要优势包括:
- 自动化运维: 自动化部署、调度、扩缩容和管理。
- 高可用性: 自动处理故障转移和自我修复。
- 弹性伸缩: 根据负载自动调整应用实例数量。
- 更高效的资源利用: 优化集群资源的分配。
- 敏捷开发: 支持快速迭代和频繁部署。
- 跨云和混合云能力: 可以在各种环境(公有云、私有云、本地数据中心)中运行。
2. Kubernetes核心概念详解
在深入操作之前,理解Kubernetes的一些核心概念至关重要。
2.1 Cluster(集群)
Kubernetes集群是由一组工作机器(节点)组成的集合,这些机器运行容器化的应用程序。集群至少包含一个主节点(Control Plane)和若干个工作节点(Worker Nodes)。
2.2 Control Plane(控制平面 / 主节点)
控制平面是集群的大脑,负责管理集群的状态。它由一系列组件组成:
- kube-apiserver: API服务器,是Kubernetes控制平面的前端。所有其他组件以及外部用户都通过API服务器进行通信。它是无状态的,可以水平扩展。
- etcd: 一个高可用、强一致性的键值存储系统,用于保存集群的所有状态数据(如Pod信息、配置、Secret等)。它是Kubernetes集群的关键组件,必须保证数据安全和高可用。
- kube-scheduler: 调度器,负责监控新创建的、未指定运行在哪一个节点上的Pods,并为其选择一个最佳的节点来运行。调度决策考虑多种因素,如资源需求、硬件/软件/策略约束、亲和性/反亲和性等。
- kube-controller-manager: 控制器管理器,运行多个控制器进程。控制器是K8s中用于实现自动化控制循环的组件。常见的控制器包括:
- Node Controller: 负责节点的状态,处理节点宕机等事件。
- ReplicaSet Controller: 确保特定数量的Pod副本正在运行。
- Deployment Controller: 负责部署的声明式更新,管理ReplicaSets。
- StatefulSet Controller: 管理有状态应用,保证Pod的顺序性和唯一性。
- DaemonSet Controller: 确保所有(或部分)节点上运行一个Pod的副本。
- cloud-controller-manager (可选): 云控制器管理器,与底层云提供商的API交互,管理云资源,如创建负载均衡器、分配云存储卷等。
2.3 Worker Node(工作节点 / 节点)
工作节点是集群中的计算机器,运行实际的应用程序容器。每个工作节点包含以下组件:
- kubelet: 运行在每个工作节点上的代理。它与Control Plane通信,接收Pod的配置信息,并负责在Pod中运行容器。它监控Pod的运行状态并向API服务器报告。
- kube-proxy: 网络代理,运行在每个节点上。它负责为Service提供网络规则,实现服务发现和负载均衡。它维护节点上的网络规则(如iptables或ipvs),允许从集群内部或外部访问Service。
- Container Runtime: 容器运行时环境,负责运行容器。Kubernetes支持多种容器运行时,如Docker、containerd、CRI-O等。
2.4 Pod
Pod是Kubernetes中最小的可部署单元。 一个Pod代表集群中运行的一个或一组容器。在一个Pod中,容器共享网络命名空间、IP地址和端口空间,以及存储卷。
为什么是Pod而不是直接使用容器?
- 协同工作: 某些应用程序设计为紧密协作的多个进程(例如,主应用容器和一个日志收集代理容器)。将它们放在同一个Pod中,它们可以更容易地通过
localhost
互相通信,共享数据卷,并由kubelet作为一个单元进行管理。 - 抽象层: Pod为容器提供了一个更高层次的抽象,使得Kubernetes可以在容器之上提供更丰富的管理功能(如生命周期管理、健康检查等)。
Pod是短暂的,当一个Pod失败或被删除时,Kubernetes不会自动重启它。Pod的生命周期通常由更高级别的控制器(如Deployment)来管理。
2.5 Controller(控制器)
控制器是Kubernetes中实现自动化和声明式管理的幕后英雄。它监控集群的当前状态,并与期望状态进行比较。如果当前状态不符合期望状态,控制器就会采取行动来调整,直到当前状态符合期望状态。
常见的控制器类型包括:
- ReplicaSet: 确保在一个特定时间运行指定数量的Pod副本。通常不单独使用,而是由Deployment管理。
- Deployment: 提供对Pod和ReplicaSet的声明式更新。它是管理无状态应用的推荐方式。您可以定义期望的Pod数量、更新策略(如滚动更新)等。
- StatefulSet: 用于管理有状态应用。它保证Pod的顺序性(启动、终止、更新)和唯一性(每个Pod都有一个稳定的网络标识和持久存储)。
- DaemonSet: 确保在所有(或特定)节点上运行一个Pod的副本,例如日志收集代理或集群存储守护进程。
- Job: 运行一个或多个Pod,执行批处理任务,并在任务成功完成后终止。
- CronJob: 基于时间调度的Job,类似于Linux的crontab。
2.6 Service
Pod是短暂的,它们的IP地址会随着Pod的创建和销毁而改变。这给客户端访问Pod带来了挑战。Service抽象层解决了这个问题。
Service 定义了一组Pod的逻辑集合以及访问它们的策略。Service通过Selector(标签选择器)来选择目标Pod。一旦定义了Service,它会获得一个稳定的IP地址和DNS名称。客户端只需要连接到Service的IP地址或DNS名称,Service会负责将请求负载均衡到后端健康的Pod上。
Service有几种类型:
- ClusterIP (默认): Service在集群内部暴露一个IP地址。只能从集群内部访问。
- NodePort: 在集群中的每个节点上暴露一个静态端口。通过
<NodeIP>:<NodePort>
可以从外部访问Service。NodePort通常在30000-32767范围内。主要用于开发测试或演示环境。 - LoadBalancer: 如果您在支持云提供商的Kubernetes集群(如GKE、EKS、AKS)中运行,这种类型会在云提供商中创建一个外部负载均衡器,并将流量路由到Service。可以通过外部负载均衡器的IP地址访问Service。
- ExternalName: 将Service映射到外部DNS名称,不涉及代理。
2.7 Namespace(命名空间)
Namespace是Kubernetes中用于将集群资源划分为逻辑组的一种方式。它提供了一个范围,用于命名资源,并可以用于访问控制(RBAC)。默认情况下,Kubernetes集群有几个预设的命名空间(如default
、kube-system
、kube-public
)。在大型集群中,使用命名空间可以避免不同团队或应用之间的资源冲突,并方便管理。
2.8 Volume(存储卷)
Pod中的容器是短暂的,容器的文件系统也是短暂的。当容器重启或Pod被删除时,数据将会丢失。Volume提供了一种机制,用于Pod中容器之间共享数据,以及在Pod的生命周期之外持久化数据。
Kubernetes支持多种类型的Volume,如EmptyDir(Pod生命周期内共享的临时存储)、HostPath(将主机文件系统路径挂载到Pod)、各种云提供商的存储(AWS EBS、GCE Persistent Disk、Azure Disk/File)、NFS、PersistentVolumeClaim (PVC) 等。
2.9 YAML
Kubernetes资源(Pod、Deployment、Service等)通常使用YAML文件来定义。YAML是一种易于阅读的数据序列化格式。一个典型的Kubernetes资源定义YAML文件包含:
apiVersion
: 创建该对象所使用的Kubernetes API版本(如v1
,apps/v1
)。kind
: 要创建的资源类型(如Pod
,Deployment
,Service
)。metadata
: 对象的元数据,如name
(名称)、namespace
(命名空间)、labels
(标签)、annotations
(注解)等。spec
: 对象的规格或期望状态。这部分内容根据kind
的不同而变化,描述了对象应该具备的属性和行为。
例如,一个Deployment的spec
会包含副本数、Pod模板、选择器等信息。
3. 本地Kubernetes环境搭建(以Minikube为例)
对于初学者来说,在本地机器上搭建一个轻量级的Kubernetes集群是开始学习的最佳方式。有几种流行的工具可以实现这一目标:
- Minikube: 在单机上运行一个单节点的Kubernetes集群,通常在一个虚拟机或容器中。
- Docker Desktop: 如果你已经安装了Docker Desktop,它内置了Kubernetes支持,可以在其设置中直接启用。
- Kind (Kubernetes in Docker): 使用Docker容器作为“节点”来运行本地Kubernetes集群。适合CI/CD或多节点模拟。
这里我们以Minikube为例进行介绍,因为它功能完善且易于安装和使用。
3.1 前提条件
- 一台运行macOS, Linux 或 Windows 的计算机。
- 支持虚拟化技术(如VT-x/AMD-V)并在BIOS/UEFI中开启。
- 安装一个虚拟机监视器 (Hypervisor),如:
- VirtualBox
- VMware Fusion / Workstation
- Hyper-V (Windows 10 Pro/Enterprise/Education)
- KVM (Linux)
- 或者一个容器运行时,如 Docker 或 Podman(Minikube 也可以直接在 Docker 或 Podman 中运行)。
- 安装
kubectl
命令行工具。
3.2 安装 kubectl
kubectl
是与Kubernetes集群交互的官方命令行工具。安装方法取决于您的操作系统:
- macOS (使用 Homebrew):
bash
brew install kubectl - Windows (使用 Chocolatey):
bash
choco install kubernetes-cli - Linux (使用 apt-get 或 yum): 请参考Kubernetes官方文档获取最准确和最新的安装方法。通常涉及到下载二进制文件或添加到包管理器仓库。
安装后,验证kubectl
是否安装成功:
bash
kubectl version --client
3.3 安装 Minikube
请访问Minikube官方文档 (https://minikube.sigs.k8s.io/docs/start/) 获取适用于您操作系统的最新安装指南。以下是常见方法的示例:
- macOS (使用 Homebrew):
bash
brew install minikube - Windows (使用 Chocolatey):
bash
choco install minikube - Linux (下载二进制文件):
bash
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
安装后,验证Minikube是否安装成功:
bash
minikube version
3.4 启动 Minikube 集群
选择一个Hypervisor或Container Runtime来运行Minikube。默认情况下,Minikube会尝试自动选择一个合适的驱动。您也可以通过--driver
参数指定,例如:
- 使用VirtualBox驱动:
bash
minikube start --driver=virtualbox - 使用Docker驱动(需要在系统上安装Docker):
bash
minikube start --driver=docker
执行启动命令后,Minikube会下载所需的镜像、创建虚拟机或容器、安装Kubernetes组件。这个过程可能需要一些时间,取决于您的网络速度。
bash
minikube start
看到类似 “Done! kubectl is now configured to use \”minikube\”” 的输出时,表示集群启动成功。
3.5 检查集群状态
使用以下命令检查Minikube集群和kubectl的连接状态:
bash
minikube status
kubectl cluster-info
kubectl get nodes
如果一切正常,kubectl get nodes
应该会显示一个名为minikube
的状态为Ready
的节点。
3.6 停止和删除集群
实验完成后,您可以停止Minikube以释放资源:
bash
minikube stop
如果您想彻底移除Minikube集群及其所有数据:
bash
minikube delete
现在,您已经拥有了一个本地的Kubernetes集群环境,可以开始进行实际操作了。
4. kubectl 命令行工具基础
kubectl
是与Kubernetes集群交互的主要命令行工具。以下是一些最常用的基本命令:
-
kubectl get <resource_type>
: 获取指定类型资源的信息。kubectl get pods
:列出所有Pods。kubectl get deployments
:列出所有Deployments。kubectl get services
:列出所有Services。kubectl get nodes
:列出所有工作节点。kubectl get namespaces
:列出所有命名空间。kubectl get all
:列出当前命名空间下的大多数资源类型(Pods, Services, Deployments, ReplicaSets等)。
-
kubectl describe <resource_type>/<name>
: 显示指定资源的详细信息,包括其当前状态、事件、关联的Pods等。kubectl describe pod my-pod-xyz
:描述一个名为my-pod-xyz
的Pod。kubectl describe deployment my-deployment
:描述一个名为my-deployment
的Deployment。
-
kubectl apply -f <yaml_file>
: 根据YAML文件中定义的资源创建或更新资源。这是声明式管理的核心命令。如果资源不存在则创建,如果存在则更新到YAML中定义的状态。kubectl apply -f my-deployment.yaml
:应用my-deployment.yaml
文件。
-
kubectl delete -f <yaml_file>
或kubectl delete <resource_type>/<name>
: 删除指定资源。kubectl delete -f my-deployment.yaml
:删除my-deployment.yaml
中定义的所有资源。kubectl delete pod my-pod-xyz
:删除名为my-pod-xyz
的Pod。kubectl delete deployment my-deployment
:删除名为my-deployment
的Deployment。
-
kubectl logs <pod_name> [-c <container_name>]
: 查看Pod中容器的日志输出。如果Pod中只有一个容器,可以省略-c <container_name>
。kubectl logs my-pod-xyz
:查看Podmy-pod-xyz
的日志。kubectl logs my-pod-xyz -c my-container
:查看Podmy-pod-xyz
中容器my-container
的日志。
-
kubectl exec -it <pod_name> -- <command>
: 在Pod中的一个容器内执行命令。-it
选项用于进入交互式终端。kubectl exec -it my-pod-xyz -- /bin/bash
:在Podmy-pod-xyz
中打开一个Bash终端。
-
kubectl create <resource_type> <name> ...
: 创建指定资源。这个命令更偏向命令式操作,通常用于快速创建少量资源或进行测试,生产环境中更推荐使用kubectl apply -f
。kubectl create deployment nginx --image=nginx
:快速创建一个名为nginx
的Deployment,使用nginx
镜像。
-
kubectl rollout status deployment/<name>
: 检查Deployment的滚动更新状态。 -
kubectl scale deployment/<name> --replicas=<count>
: 手动扩缩容Deployment。
这些是您入门阶段最常用的kubectl
命令。熟练掌握它们是进行Kubernetes操作的基础。您可以使用 kubectl --help
查看更详细的用法,或使用 kubectl <command> --help
查看特定命令的帮助。
5. 使用YAML文件定义Kubernetes资源
Kubernetes推崇声明式配置。这意味着您告诉Kubernetes您想要的最终状态是什么,而不是一步一步告诉它如何达到这个状态。YAML文件是定义这种期望状态的标准方式。
5.1 YAML文件的基本结构
一个Kubernetes资源的YAML文件通常包含以下顶级字段:
yaml
apiVersion: <string> # API版本,取决于资源类型
kind: <string> # 资源类型(Pod, Deployment, Service等)
metadata: # 元数据
name: <string> # 资源名称,在Namespace内必须唯一
namespace: <string> # 资源所属的命名空间 (可选,默认default)
labels: # 标签,用于组织和选择资源 (可选)
<key>: <value>
...
annotations: # 注解,存储非识别性的元数据 (可选)
<key>: <value>
...
spec: # 资源的期望状态或配置
# 内容取决于 kind
...
5.2 示例:一个简单的Pod YAML
虽然实际应用中更多使用Deployment管理Pod,但理解Pod的YAML有助于理解其基本构成:
“`yaml
my-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: my-single-pod
labels:
app: myapp
spec:
containers:
– name: my-container # 容器名称
image: nginx:latest # 容器使用的镜像
ports:
– containerPort: 80 # 容器监听的端口
“`
apiVersion: v1
:Pod是核心API对象,版本是v1
。kind: Pod
:这是一个Pod资源。metadata.name
: Pod的名称。metadata.labels
: 给Pod添加标签,例如app: myapp
,方便后续Service或Selector查找。spec.containers
: 定义Pod中包含的容器列表。这是一个数组,即使只有一个容器也是列表形式。name
:容器的名称。image
:容器使用的镜像。ports.containerPort
:容器内部应用程序监听的端口。
6. 部署您的第一个应用(Nginx)
现在,让我们使用Deployment来部署一个简单的Nginx Web服务器应用。Deployment会自动创建ReplicaSet和Pod,并管理它们的生命周期。
6.1 创建 Deployment YAML 文件
创建一个名为 nginx-deployment.yaml
的文件,内容如下:
“`yaml
nginx-deployment.yaml
apiVersion: apps/v1 # Deployment资源属于 apps/v1 API组
kind: Deployment # 资源类型是 Deployment
metadata:
name: nginx-deployment # Deployment的名称
labels: # Deployment自身的标签
app: nginx-app
spec:
replicas: 3 # 期望运行的Pod副本数量
selector: # 用于查找并管理Pod的标签选择器
matchLabels: # 匹配具有以下标签的Pod
app: nginx-pod # 这个标签要和 Pod 模板中的标签一致
template: # Pod模板:用来创建Pod的模板
metadata:
labels: # Pod的标签
app: nginx-pod # Pod的标签,用于被上面的 selector 选中
spec:
containers:
– name: nginx-container # 容器名称
image: nginx:latest # 使用最新的 Nginx 镜像
ports:
– containerPort: 80 # 容器暴露的端口
“`
解释:
- 我们定义了一个
Deployment
资源,名称为nginx-deployment
。 spec.replicas: 3
表示我们期望有3个Nginx Pod的副本在运行。spec.selector.matchLabels: app: nginx-pod
指定了这个Deployment管理哪些Pod。它会查找所有带有app: nginx-pod
标签的Pod。spec.template
部分是Pod的模板。当Deployment需要创建Pod时(例如,初始化或扩缩容),它会使用这个模板。template.metadata.labels: app: nginx-pod
给通过此模板创建的Pod打上app: nginx-pod
标签,以便被上面的selector
匹配到。template.spec.containers
定义了Pod中包含的容器。这里只有一个容器,名称为nginx-container
,使用nginx:latest
镜像,并暴露容器内部的80端口。
6.2 应用 Deployment
使用 kubectl apply
命令创建Deployment:
bash
kubectl apply -f nginx-deployment.yaml
您应该会看到类似输出:deployment.apps/nginx-deployment created
6.3 检查 Deployment 和 Pods 状态
检查Deployment的状态:
bash
kubectl get deployments
输出应该显示nginx-deployment
,并且READY
列显示期望的副本数量(例如 3/3
)。
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 <some-time>
检查Pod的状态:
bash
kubectl get pods -l app=nginx-pod # 使用标签选择器查找Pod
或者直接:
bash
kubectl get pods
您应该会看到3个名称以nginx-deployment-
开头,后面跟着随机字符串的Pod,并且它们的STATUS
应该是Running
。
NAME READY STATUS RESTARTS AGE
nginx-deployment-abcdefgh-ijklm 1/1 Running 0 <some-time>
nginx-deployment-qrstuvwx-yzabc 1/1 Running 0 <some-time>
nginx-deployment-defghijk-lmnop 1/1 Running 0 <some-time>
恭喜!您已经在Kubernetes集群中成功部署了您的第一个应用。但现在这些Pod只能在集群内部互相访问,外部还无法访问。
7. 暴露您的应用(Service)
要让集群外部能够访问我们部署的Nginx服务,我们需要创建一个Service。Service通过标签选择器找到对应的Pod,并为它们提供一个稳定的网络入口。
7.1 创建 Service YAML 文件
创建一个名为 nginx-service.yaml
的文件,内容如下:
“`yaml
nginx-service.yaml
apiVersion: v1 # Service资源属于 v1 API组
kind: Service # 资源类型是 Service
metadata:
name: nginx-service # Service的名称
spec:
selector:
app: nginx-pod # 使用标签选择器匹配需要暴露的 Pod
ports:
– protocol: TCP # 协议类型
port: 80 # Service 监听的端口(集群内其他 Pod 访问此 Service 时使用的端口)
targetPort: 80 # Pod 中容器监听的端口(流量会被转发到 Pod 的哪个端口)
# NodePort 类型 Service 特有字段
nodePort: 30080 # 可选:指定一个静态的节点端口 (范围通常是 30000-32767)
type: NodePort # Service 类型:NodePort 允许通过任一节点的 IP 和 NodePort 访问
“`
解释:
- 我们定义了一个
Service
资源,名称为nginx-service
。 spec.selector: app: nginx-pod
指定了这个Service会将流量转发到所有带有app: nginx-pod
标签的Pod上。注意,这里的标签选择器要和Deployment的Pod模板中定义的Pod标签一致。spec.ports
定义了端口映射。port: 80
:这是Service自身的端口。集群内部的Pod可以通过nginx-service:80
来访问这个Service。targetPort: 80
:这是流量转发到后端Pod时,Pod中容器监听的端口。这里是Nginx容器的80端口。nodePort: 30080
:这是NodePort
类型的Service特有的端口。Kubernetes会在集群的 每个 节点上打开这个静态端口。您可以通过 任一 节点的IP地址加上这个端口来访问Service。我们指定了30080,如果您不指定,Kubernetes会自动分配一个30000-32767范围内的端口。
spec.type: NodePort
指定了Service的类型是NodePort
,以便从集群外部访问。
7.2 应用 Service
使用 kubectl apply
命令创建Service:
bash
kubectl apply -f nginx-service.yaml
您应该会看到类似输出:service/nginx-service created
7.3 检查 Service 状态
检查Service的状态:
bash
kubectl get services
您应该会看到nginx-service
,其TYPE
为NodePort
,CLUSTER-IP
、EXTERNAL-IP
(NodePort类型通常是<pending>
或<none>
)、PORT(S)
(显示80:30080/TCP
或 80:<assigned_nodeport>/TCP
)。
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP <some-time>
nginx-service NodePort 10.100.x.y <none> 80:30080/TCP <some-time>
7.4 从外部访问应用
现在,您可以通过Minikube节点的IP地址和Service的NodePort来访问Nginx服务了。
-
获取Minikube节点的IP地址:
bash
minikube ip
假设输出是192.168.59.100
。 -
获取Service的NodePort:
从kubectl get services
的输出中找到nginx-service
的PORT(S)
列。如果显示80:30080/TCP
,则NodePort是30080
。如果您没有在YAML中指定nodePort
,则查找冒号后面的端口号。 -
使用浏览器或
curl
访问:
在浏览器中打开http://<minikube-ip>:<nodeport>
,例如http://192.168.59.100:30080
。
或者使用curl
命令:
bash
curl http://<minikube-ip>:<nodeport>
您应该能看到Nginx的欢迎页面!这表明流量成功地通过NodePort、Service,最终到达了后端的Nginx Pod。
Minikube快捷方式:
Minikube提供了一个方便的命令,可以直接在您的默认浏览器中打开Service:
bash
minikube service nginx-service
8. 应用的扩缩容与更新
Kubernetes的一个强大之处在于其内置的自动化能力。我们可以轻松地对应用进行扩缩容和无中断更新。
8.1 扩缩容应用 (Scaling)
修改 nginx-deployment.yaml
文件中的 replicas
字段,例如从 3
修改为 5
:
“`yaml
nginx-deployment.yaml (修改 replicas)
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx-app
spec:
replicas: 5 # 将副本数改为 5
selector:
matchLabels:
app: nginx-pod
template:
metadata:
labels:
app: nginx-pod
spec:
containers:
– name: nginx-container
image: nginx:latest
ports:
– containerPort: 80
“`
然后重新应用这个文件:
bash
kubectl apply -f nginx-deployment.yaml
Kubernetes Deployment Controller会注意到期望状态(5个副本)与当前状态(3个副本)不符,并自动创建两个新的Pod。
检查Pod状态:
bash
kubectl get pods -l app=nginx-pod
您应该会看到5个Nginx Pod在运行。
您也可以使用命令式方法进行扩缩容(但不修改YAML文件):
bash
kubectl scale deployment nginx-deployment --replicas=2 # 缩容到 2 个副本
再次检查Pod状态,应该只有2个Pod在运行。
8.2 更新应用 (Updating)
假设我们要将Nginx的版本从 latest
更新到 1.19.0
。
修改 nginx-deployment.yaml
文件中的 image
字段:
“`yaml
nginx-deployment.yaml (修改 image)
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx-app
spec:
replicas: 2 # 继续使用 2 个副本
selector:
matchLabels:
app: nginx-pod
template:
metadata:
labels:
app: nginx-pod
spec:
containers:
– name: nginx-container
image: nginx:1.19.0 # 将镜像更新为 1.19.0
ports:
– containerPort: 80
“`
然后重新应用这个文件:
bash
kubectl apply -f nginx-deployment.yaml
Deployment Controller会执行一个 滚动更新 (Rolling Update)。它会逐步终止旧版本的Pod,并创建新版本的Pod,而不是一次性停止所有旧Pod再启动新Pod。这保证了在更新过程中服务不会中断。
您可以通过以下命令查看滚动更新的进度:
bash
kubectl rollout status deployment/nginx-deployment
观察Pod的状态:
bash
kubectl get pods -l app=nginx-pod
您会看到旧版本的Pod逐渐被标记为Terminating,同时新版本的Pod被创建并进入Running状态,直到所有Pod都更新到新版本。
“`
滚动更新过程中的可能输出示例
NAME READY STATUS RESTARTS AGE
nginx-deployment-abcdefgh-ijklm 1/1 Running 0 5m # 旧版本 Pod
nginx-deployment-qrstuvwx-yzabc 1/1 Terminating 0 4m # 旧版本 Pod 正在终止
nginx-deployment-newhash-abcde 0/1 ContainerCreating 0 5s # 新版本 Pod 正在创建
nginx-deployment-newhash-fghij 0/1 ContainerCreating 0 2s # 新版本 Pod 正在创建
“`
直到所有Pod都更新为新版本:
NAME READY STATUS RESTARTS AGE
nginx-deployment-newhash-abcde 1/1 Running 0 1m
nginx-deployment-newhash-fghij 1/1 Running 0 50s
通过修改YAML文件并使用kubectl apply
命令,Kubernetes负责了复杂的扩缩容和无中断更新过程,极大地简化了应用的管理。
9. 进一步学习方向
恭喜您!通过本文的学习,您已经成功搭建了本地K8s环境,理解了核心概念,并部署、暴露、扩缩容和更新了一个简单的应用。这只是Kubernetes世界的冰山一角。为了更深入地掌握Kubernetes,您可以继续学习以下主题:
- 更高级别的控制器: StatefulSet (有状态应用)、DaemonSet (节点守护进程)、Job/CronJob (批处理任务)。
- 存储管理: PersistentVolume (PV)、PersistentVolumeClaim (PVC)、StorageClass,理解如何为有状态应用提供持久存储。
- 配置管理和安全: ConfigMap (配置)、Secret (敏感数据)。
- 网络: CNI (容器网络接口)、Ingress (L7负载均衡和路由)。
- 包管理: Helm (Kubernetes应用的包管理器)。
- 监控、日志和追踪: Prometheus、Grafana、EFK/ELK栈、Jaeger/Zipkin。
- 集群安全: RBAC (基于角色的访问控制)、NetworkPolicy (网络策略)。
- 在生产环境中使用Kubernetes: 托管服务(GKE、EKS、AKS)、自建集群工具(Kubeadm、kOps),生产环境的考虑事项(高可用、安全、性能)。
- Operator: 自动化管理复杂有状态应用的模式。
Kubernetes生态系统非常庞大且发展迅速,持续学习和实践是掌握它的关键。
总结
本文为您提供了一个全面的Kubernetes快速入门指南。我们从认识Kubernetes的必要性开始,深入了解了其核心概念(集群、控制平面、节点、Pod、Deployment、Service等),指导您搭建了本地Minikube环境,学习了kubectl
的基本用法,并通过YAML文件定义和部署了一个Nginx应用。您亲自动手体验了应用的部署、暴露、扩缩容和更新过程,感受到了Kubernetes强大的自动化管理能力。
掌握Kubernetes是拥抱云原生时代、构建现代化、可伸缩、高可用应用的重要一步。希望这篇指南能帮助您迈出坚实的第一步。继续探索,不断实践,您将能够充分利用Kubernetes的强大功能,为您的应用程序和团队带来巨大的价值。
祝您在Kubernetes的学习旅程中一切顺利!