扩展和负载均衡应用

KubernetesKubernetesBeginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

介绍

在本实验中,你将使用 Minikube 启动一个本地 Kubernetes 集群,部署一个示例 NGINX 应用,并根据需求对其进行扩展。你将观察多个 Pod 之间的负载均衡,监控集群事件,并初步了解 Horizontal Pod Autoscaler (HPA) 以实现未来的自动扩展。本实验旨在通过动手实践,帮助你全面理解 Kubernetes 的扩展和负载均衡机制。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL kubernetes(("`Kubernetes`")) -.-> kubernetes/BasicCommandsGroup(["`Basic Commands`"]) kubernetes(("`Kubernetes`")) -.-> kubernetes/AdvancedCommandsGroup(["`Advanced Commands`"]) kubernetes(("`Kubernetes`")) -.-> kubernetes/AdvancedDeploymentGroup(["`Advanced Deployment`"]) kubernetes(("`Kubernetes`")) -.-> kubernetes/TroubleshootingandDebuggingCommandsGroup(["`Troubleshooting and Debugging Commands`"]) kubernetes/BasicCommandsGroup -.-> kubernetes/get("`Get`") kubernetes/BasicCommandsGroup -.-> kubernetes/create("`Create`") kubernetes/AdvancedCommandsGroup -.-> kubernetes/apply("`Apply`") kubernetes/AdvancedDeploymentGroup -.-> kubernetes/scale("`Scale`") kubernetes/TroubleshootingandDebuggingCommandsGroup -.-> kubernetes/describe("`Describe`") kubernetes/TroubleshootingandDebuggingCommandsGroup -.-> kubernetes/exec("`Exec`") subgraph Lab Skills kubernetes/get -.-> lab-434648{{"`扩展和负载均衡应用`"}} kubernetes/create -.-> lab-434648{{"`扩展和负载均衡应用`"}} kubernetes/apply -.-> lab-434648{{"`扩展和负载均衡应用`"}} kubernetes/scale -.-> lab-434648{{"`扩展和负载均衡应用`"}} kubernetes/describe -.-> lab-434648{{"`扩展和负载均衡应用`"}} kubernetes/exec -.-> lab-434648{{"`扩展和负载均衡应用`"}} end

启动 Kubernetes 集群

在这一步中,你将学习如何使用 Minikube 启动并验证一个本地 Kubernetes 集群。这是在 Kubernetes 环境中部署和管理容器化应用的关键第一步。

首先,启动 Minikube 集群:

minikube start

示例输出:

😄  minikube v1.29.0 on Ubuntu 22.04
✨  自动选择 docker 驱动
📌  使用具有 root 权限的 Docker 驱动
🔥  在 Kubernetes 集群中创建 Kubernetes
🔄  重启现有的 Kubernetes 集群
🐳  在 Docker 20.10.23 上准备 Kubernetes v1.26.1 ...
🚀  启动 Kubernetes ...
🌟  启用插件:storage-provisioner, default-storageclass
🏄  完成!kubectl 现已配置为使用 "minikube" 集群和 "default" 命名空间

使用以下命令验证集群状态:

minikube status
kubectl get nodes

minikube status 的示例输出:

minikube
type: Control Plane
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured

kubectl get nodes 的示例输出:

NAME       STATUS   ROLES           AGE   VERSION
minikube   Ready    control-plane   1m    v1.26.1

这些命令确认了以下内容:

  1. Minikube 已成功运行。
  2. 本地 Kubernetes 集群已创建。
  3. 集群已准备就绪。
  4. 你拥有一个具备控制平面功能的单节点集群。

部署示例应用

在这一步中,你将学习如何使用 Kubernetes Deployment 部署一个简单的 Web 应用,并设置单个副本。我们将为 NGINX Web 服务器创建一个 YAML 清单文件,并将其应用到 Minikube 集群中。理解如何部署应用是使用 Kubernetes 的基础。

首先,为你的 Kubernetes 清单文件创建一个目录:

mkdir -p ~/project/k8s-manifests
cd ~/project/k8s-manifests

创建一个新的 YAML 文件用于部署:

nano nginx-deployment.yaml

添加以下部署配置:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:latest
          ports:
            - containerPort: 80

保存文件(按 Ctrl+X,然后按 Y,最后按 Enter)。

YAML 配置说明:

  • apiVersion: apps/v1:指定 Deployment 的 API 版本。
  • kind: Deployment:表示这是一个 Deployment 对象,用于管理复制的应用。
  • metadata:包含 Deployment 的元数据。
    • name: nginx-deployment:Deployment 的名称。
    • labels: app: nginx:用于标识此 Deployment 的标签。
  • spec:包含 Deployment 的规范。
    • replicas: 1:期望的 Pod 实例数量(副本数)。在此初始部署中,我们只有一个副本。
    • selector:定义 Deployment 如何选择要管理的 Pod。
      • matchLabels: app: nginx:带有标签 app: nginx 的 Pod 将由该 Deployment 管理。
    • template:Pod 模板。它指定了 Deployment 创建的 Pod 的配置。
      • metadata.labels: app: nginx:应用于由该 Deployment 管理的 Pod 的标签。
      • spec.containers:定义 Pod 中的容器。
        • name: nginx:容器的名称。
        • image: nginx:latest:容器的 Docker 镜像(使用最新的 NGINX 镜像)。
        • ports: containerPort: 80:在容器中暴露端口 80。

将部署应用到 Kubernetes 集群:

kubectl apply -f nginx-deployment.yaml

示例输出:

deployment.apps/nginx-deployment created

验证部署状态:

kubectl get deployments
kubectl get pods

kubectl get deployments 的示例输出:

NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   1/1     1            1           30s

kubectl get pods 的示例输出:

NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-xxx-yyy            1/1     Running   0          30s

关于此部署的关键点:

  1. 我们创建了一个具有单个副本的 Deployment。
  2. 该部署使用了最新的 NGINX 镜像。
  3. 容器暴露了端口 80。
  4. 该部署具有标签 app: nginx 用于标识。

检查部署的详细信息:

kubectl describe deployment nginx-deployment

示例输出将显示部署配置、事件和当前状态。

扩展部署以应对增加的负载

在这一步中,你将学习如何扩展你的应用以处理更多的流量。在现实场景中,随着你的应用变得越来越受欢迎,单个副本可能不足以应对负载。为了解决这个问题,Kubernetes 允许你通过增加 Pod 实例(副本)的数量轻松扩展你的应用。

在扩展之前,让我们简要讨论为什么需要多个副本。应用的单个副本只能处理一定数量的并发请求。如果流量超过了这个容量,应用可能会变得缓慢或无响应。通过拥有多个副本,负载可以分布到不同的 Pod 实例上,从而确保应用保持响应和可用。这一概念对于创建可扩展的应用至关重要。

你现在将学习如何通过修改 YAML 清单中的 replicas 字段以及使用 kubectl scale 命令来扩展你的 Kubernetes 部署。

打开之前创建的部署清单文件:

nano ~/project/k8s-manifests/nginx-deployment.yaml

replicas 字段从 1 修改为 3:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3 ## 从 1 修改为 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:latest
          ports:
            - containerPort: 80

保存文件(按 Ctrl+X,然后按 Y,最后按 Enter)。

应用更新后的部署:

kubectl apply -f ~/project/k8s-manifests/nginx-deployment.yaml

示例输出:

deployment.apps/nginx-deployment configured

验证扩展后的部署:

kubectl get deployments
kubectl get pods

kubectl get deployments 的示例输出:

NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           5m

kubectl get pods 的示例输出:

NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-xxx-yyy            1/1     Running   0          5m
nginx-deployment-xxx-zzz            1/1     Running   0          30s
nginx-deployment-xxx-www            1/1     Running   0          30s

使用 kubectl scale 的替代扩展方法:

kubectl scale deployment nginx-deployment --replicas=4

示例输出:

deployment.apps/nginx-deployment scaled

验证新的副本数量:

kubectl get deployments
kubectl get pods

关于扩展的关键点:

  1. 修改 YAML 文件中的 replicas 或使用 kubectl scale 命令。
  2. 修改 YAML 文件后,使用 kubectl apply 更新部署。
  3. Kubernetes 确保运行所需的副本数量。
  4. 你可以扩展(增加副本)或缩减(减少副本)。

通过检查多个 Pod 的响应验证负载均衡

在这一步中,你将学习如何通过创建 Service 并检查来自多个 Pod 的响应来验证 Kubernetes 中的负载均衡。负载均衡对于将流量分配到多个副本至关重要,确保没有单个 Pod 过载。Kubernetes Service 会自动处理这一过程。

创建一个 Service 以暴露部署:

nano ~/project/k8s-manifests/nginx-service.yaml

添加以下 Service 配置:

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  type: ClusterIP
  ports:
    - port: 80
      targetPort: 80

保存文件(按 Ctrl+X,然后按 Y,最后按 Enter)。

YAML 配置说明:

  • apiVersion: v1:指定 Service 的 API 版本。
  • kind: Service:表示这是一个 Service 对象。
  • metadata:包含 Service 的元数据。
    • name: nginx-service:Service 的名称。
  • spec:包含 Service 的规范。
    • selector:定义该 Service 将流量路由到哪些 Pod。
      • app: nginx:选择带有标签 app: nginx 的 Pod,这与上一步中创建的 Pod 匹配。
    • type: ClusterIP:创建一个具有集群 IP 地址的内部 Service,用于内部通信。此 Service 类型仅在 Kubernetes 集群内可访问。
    • ports:定义 Service 如何映射流量。
      • port: 80:Service 暴露的端口。
      • targetPort: 80:容器内应用程序监听的端口。

应用 Service:

kubectl apply -f ~/project/k8s-manifests/nginx-service.yaml

示例输出:

service/nginx-service created

验证 Service:

kubectl get services

示例输出:

NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes      ClusterIP   10.96.0.1       <none>        443/TCP   30m
nginx-service   ClusterIP   10.96.xxx.xxx   <none>        80/TCP    30s

现在,为了真正验证负载均衡,你将创建一个临时 Pod 并向 Service 发送多个请求。这使你可以看到请求被分配到不同的 NGINX Pod。

创建一个临时 Pod 以测试负载均衡:

kubectl run curl-test --image=curlimages/curl --rm -it -- sh

此命令执行以下操作:

  • kubectl run curl-test:创建一个名为 curl-test 的新 Pod。
  • --image=curlimages/curl:使用安装了 curl 的 Docker 镜像。
  • --rm:完成后自动删除 Pod。
  • -it:分配一个伪终端并保持标准输入打开。
  • -- sh:在 Pod 中启动一个 shell 会话。

在临时 Pod 中,运行多个请求:

for i in $(seq 1 10); do curl -s nginx-service | grep -q "Welcome to nginx!" && echo "Welcome to nginx - Request $i"; done

此循环将向 nginx-service 发送 10 个请求。每个请求应被路由到可用的 NGINX Pod 之一。输出将为每个成功的请求打印 Welcome to nginx - Request $i

示例输出:

Welcome to nginx - Request 1
Welcome to nginx - Request 2
Welcome to nginx - Request 3
...

退出临时 Pod:

exit

关于负载均衡的关键点:

  1. Service 将流量分配到所有匹配的 Pod。
  2. 每个请求可能会命中不同的 Pod。
  3. Kubernetes 默认使用轮询(round-robin)方式。
  4. ClusterIP Service 类型提供内部负载均衡。
  5. curl 测试显示负载被分配到多个 NGINX 实例。

动态调整部署规模以满足需求

在这一步中,你将练习使用 kubectl scale 命令动态调整 Kubernetes 部署规模,以应对不断变化的应用程序需求。这一步强调了在不直接修改 YAML 文件的情况下调整运行副本数量的实际应用,这对于快速应对流量高峰非常有用。

首先,检查当前的部署状态:

kubectl get deployments

示例输出:

NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   4/4     4            4           45m

使用 kubectl 命令扩展部署:

kubectl scale deployment nginx-deployment --replicas=5

示例输出:

deployment.apps/nginx-deployment scaled

验证新的副本数量:

kubectl get deployments
kubectl get pods

部署的示例输出:

NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   5/5     5            5           46m

Pod 的示例输出:

NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-xxx-yyy            1/1     Running   0          1m
nginx-deployment-xxx-zzz            1/1     Running   0          1m
nginx-deployment-xxx-www            1/1     Running   0          1m
nginx-deployment-xxx-aaa            1/1     Running   0          1m
nginx-deployment-xxx-bbb            1/1     Running   0          1m

现在,更新部署的 YAML 文件以实现持久化扩展:

nano ~/project/k8s-manifests/nginx-deployment.yaml

修改 replicas 字段:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 5 ## 从之前的值更新
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:latest
          ports:
            - containerPort: 80

应用更新后的配置:

kubectl apply -f ~/project/k8s-manifests/nginx-deployment.yaml

示例输出:

deployment.apps/nginx-deployment configured

模拟需求减少时的缩减操作:

kubectl scale deployment nginx-deployment --replicas=2

示例输出:

deployment.apps/nginx-deployment scaled

验证缩减后的副本数量:

kubectl get deployments
kubectl get pods

关于扩展的关键点:

  1. 使用 kubectl scale 进行快速、临时的扩展。
  2. 更新 YAML 文件以实现持久化配置。
  3. Kubernetes 确保平滑扩展,最小化中断。
  4. 你可以根据应用需求使用命令和配置进行扩展或缩减。

监控部署和 Pod 事件以跟踪变化

在这一步中,你将学习如何使用各种 kubectl 命令监控 Kubernetes 部署和 Pod,以跟踪变化、排查问题并了解应用程序的生命周期。可观测性对于确保应用程序的健康和性能至关重要。

描述当前部署以获取详细信息:

kubectl describe deployment nginx-deployment

示例输出:

Name:                   nginx-deployment
Namespace:              default
CreationTimestamp:      [timestamp]
Labels:                 app=nginx
Replicas:               2 desired | 2 updated | 2 total | 2 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  app=nginx
  Containers:
   nginx:
    Image:        nginx:latest
    Port:         80/TCP
    Host Port:    0/TCP
    Environment:  <none>
    Mounts:       <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  <none>
NewReplicaSet:   nginx-deployment-xxx (2/2 replicas created)
Events:          <some deployment events>

获取单个 Pod 的详细信息:

kubectl describe pods -l app=nginx

示例输出将显示每个 Pod 的详细信息,包括:

  • 当前状态
  • 容器信息
  • 事件
  • IP 地址
  • 节点信息

查看集群范围内的事件:

kubectl get events

示例输出:

LAST SEEN   TYPE      REASON              OBJECT                           MESSAGE
5m          Normal    Scheduled           pod/nginx-deployment-xxx-yyy    Successfully assigned default/nginx-deployment-xxx-yyy to minikube
5m          Normal    Pulled              pod/nginx-deployment-xxx-yyy    Container image "nginx:latest" already present on machine
5m          Normal    Created             pod/nginx-deployment-xxx-yyy    Created container nginx
5m          Normal    Started             pod/nginx-deployment-xxx-yyy    Started container nginx

过滤特定资源的事件:

kubectl get events --field-selector involvedObject.kind=Deployment

示例输出将仅显示与部署相关的事件。

通过删除 Pod 模拟事件:

## 获取一个 Pod 的名称
POD_NAME=$(kubectl get pods -l app=nginx -o jsonpath='{.items[0].metadata.name}')

## 删除 Pod
kubectl delete pod $POD_NAME

观察事件和 Pod 的重新创建:

kubectl get events
kubectl get pods

关于监控的关键点:

  1. kubectl describe 提供详细的资源信息。
  2. kubectl get events 显示集群范围内的事件。
  3. Kubernetes 会自动替换被删除的 Pod。
  4. 事件有助于排查部署问题。
  5. 使用 describe 获取详细的对象信息,使用 events 跟踪操作。

简要介绍 Horizontal Pod Autoscaler (HPA) 以便未来学习

在这一步中,你将初步了解 Horizontal Pod Autoscaler (HPA),这是 Kubernetes 的一项强大功能,能够根据资源利用率自动扩展应用程序。HPA 允许你基于 CPU 利用率、内存使用率甚至自定义指标定义扩展规则。

理解 HPA:

HPA 会根据观察到的 CPU 或内存使用情况,或者基于应用程序提供的自定义指标,自动调整 Deployment、ReplicaSet 或 StatefulSet 中运行的 Pod 副本数量。这确保了你的应用程序能够自动扩展以应对变化的流量负载,从而提高性能和可用性。

在 Minikube 中启用 metrics-server 插件:

minikube addons enable metrics-server

示例输出:

* The 'metrics-server' addon is enabled

metrics-server 为 Kubernetes 提供资源使用数据,是 HPA 正常运行的关键。

创建一个带有资源请求的部署:

nano ~/project/k8s-manifests/hpa-example.yaml

添加以下内容:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: php-apache
spec:
  selector:
    matchLabels:
      run: php-apache
  replicas: 1
  template:
    metadata:
      labels:
        run: php-apache
    spec:
      containers:
        - name: php-apache
          image: k8s.gcr.io/hpa-example
          ports:
            - containerPort: 80
          resources:
            limits:
              cpu: 500m
            requests:
              cpu: 200m
---
apiVersion: v1
kind: Service
metadata:
  name: php-apache
  labels:
    run: php-apache
spec:
  ports:
    - port: 80
  selector:
    run: php-apache

应用部署:

kubectl apply -f ~/project/k8s-manifests/hpa-example.yaml

YAML 配置说明:

  • 此 YAML 文件定义了一个 PHP 应用的 Deployment 和相应的 Service。
  • Deployment 配置与 NGINX 的非常相似,除了以下部分:
    • name: php-apache:部署和 Pod 容器的名称。
    • image: k8s.gcr.io/hpa-example:容器的 Docker 镜像。
    • resources:此部分指定了容器的资源需求。
      • limits.cpu: 500m:容器允许使用的最大 CPU。
      • requests.cpu: 200m:分配给容器的保证 CPU 量。
  • Service 是一个标准的服务配置,用于在内部暴露部署。

创建 HPA 配置:

nano ~/project/k8s-manifests/php-apache-hpa.yaml

添加以下 HPA 清单:

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: php-apache
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: php-apache
  minReplicas: 1
  maxReplicas: 10
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 50

应用 HPA 配置:

kubectl apply -f ~/project/k8s-manifests/php-apache-hpa.yaml

YAML 配置说明:

  • apiVersion: autoscaling/v2:指定 HorizontalPodAutoscaler 的 API 版本。
  • kind: HorizontalPodAutoscaler:表示这是一个 HPA 对象。
  • metadata:包含 HPA 的元数据。
    • name: php-apache:HPA 的名称。
  • spec:包含 HPA 的规范。
    • scaleTargetRef:定义将被扩展的目标 Deployment。
      • apiVersion: apps/v1:目标资源的 API 版本。
      • kind: Deployment:目标资源类型,即 Deployment。
      • name: php-apache:将被扩展的目标 Deployment 的名称。
    • minReplicas: 1:保持运行的最小副本数。
    • maxReplicas: 10:扩展到的最大副本数。
    • metrics:定义如何确定扩展指标。
      • type: Resource:基于资源指标进行扩展。
      • resource.name: cpu:基于 CPU 使用率进行扩展。
      • resource.target.type: Utilization:基于 Pod 请求的 CPU 百分比进行扩展。
      • resource.target.averageUtilization: 50:当所有 Pod 的平均 CPU 使用率超过请求的 50% 时进行扩展。

验证 HPA 配置:

kubectl get hpa

示例输出:

NAME         REFERENCE              TARGETS         MINPODS   MAXPODS   REPLICAS   AGE
php-apache   Deployment/php-apache  0%/50%          1         10        1          30s

模拟负载以触发扩展(可选):

kubectl run -i --tty load-generator --rm --image=busybox --restart=Never -- /bin/sh -c "while sleep 0.01; do wget -q -O- http://php-apache; done"

不要关闭负载生成器的终端。打开另一个终端并监控 HPA 行为:

kubectl get hpa

等待几秒钟(可能需要超过一分钟半)以查看 HPA 根据 CPU 利用率扩展部署。

kubectl get hpa
NAME         REFERENCE               TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
php-apache   Deployment/php-apache   68%/50%   1         10        2          72s

Ctrl+C 停止负载生成器。

关于 HPA 的关键点:

  1. 根据资源利用率自动扩展 Pod,从而提高应用程序的弹性。
  2. 可以基于 CPU、内存或自定义指标进行扩展。
  3. 定义最小和最大副本数,确保扩展的平衡和高效。
  4. HPA 是在不同负载下保持应用程序性能和可用性的关键组件。

总结

在本实验中,你通过动手实践掌握了 Kubernetes 中的扩展和负载均衡技术。你首先使用 Minikube 创建了一个本地 Kubernetes 集群,并部署了一个基础的 NGINX Web 应用。随后,你探索了不同的扩展方法,包括修改部署 YAML 文件和使用 kubectl scale 调整 Pod 副本数量。你还学习了如何通过 Kubernetes Service 和临时测试 Pod 验证负载均衡。

此外,你通过 kubectl describekubectl get events 命令学习了如何监控部署和 Pod。最后,你初步了解了 Horizontal Pod Autoscaler (HPA),包括它如何基于资源利用率自动扩展你的应用,并通过一个基于 php-apache 镜像的示例进行了实践。本实验全面介绍了 Kubernetes 的扩展、负载均衡、监控和自动扩展技术,为你在 Kubernetes 中管理更复杂的应用奠定了基础。

您可能感兴趣的其他 Kubernetes 教程