介绍
在本实验中,你将使用 Minikube 启动一个本地 Kubernetes 集群,部署一个示例 NGINX 应用,并根据需求对其进行扩展。你将观察多个 Pod 之间的负载均衡,监控集群事件,并初步了解 Horizontal Pod Autoscaler (HPA) 以实现未来的自动扩展。本实验旨在通过动手实践,帮助你全面理解 Kubernetes 的扩展和负载均衡机制。
启动 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
这些命令确认了以下内容:
- Minikube 已成功运行。
- 本地 Kubernetes 集群已创建。
- 集群已准备就绪。
- 你拥有一个具备控制平面功能的单节点集群。
部署示例应用
在这一步中,你将学习如何使用 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
关于此部署的关键点:
- 我们创建了一个具有单个副本的 Deployment。
- 该部署使用了最新的 NGINX 镜像。
- 容器暴露了端口 80。
- 该部署具有标签
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
关于扩展的关键点:
- 修改 YAML 文件中的
replicas或使用kubectl scale命令。 - 修改 YAML 文件后,使用
kubectl apply更新部署。 - Kubernetes 确保运行所需的副本数量。
- 你可以扩展(增加副本)或缩减(减少副本)。
通过检查多个 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
关于负载均衡的关键点:
- Service 将流量分配到所有匹配的 Pod。
- 每个请求可能会命中不同的 Pod。
- Kubernetes 默认使用轮询(round-robin)方式。
ClusterIPService 类型提供内部负载均衡。- 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
关于扩展的关键点:
- 使用
kubectl scale进行快速、临时的扩展。 - 更新 YAML 文件以实现持久化配置。
- Kubernetes 确保平滑扩展,最小化中断。
- 你可以根据应用需求使用命令和配置进行扩展或缩减。
监控部署和 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
关于监控的关键点:
kubectl describe提供详细的资源信息。kubectl get events显示集群范围内的事件。- Kubernetes 会自动替换被删除的 Pod。
- 事件有助于排查部署问题。
- 使用
describe获取详细的对象信息,使用events跟踪操作。
简要介绍水平 Pod 自动扩缩器 (HPA) 以便后续学习
在这一步中,你将了解水平 Pod 自动扩缩器 (Horizontal Pod Autoscaler, HPA),它是 Kubernetes 的一项强大功能,可根据资源利用率自动扩展应用程序。HPA 允许你根据 CPU 利用率、内存使用情况甚至自定义指标等指标来定义扩缩规则。
理解 HPA:
HPA 会根据观察到的 CPU 或内存使用情况,或者根据应用程序提供的自定义指标,自动调整 Deployment、ReplicaSet 或 StatefulSet 中运行的 Pod 副本数量。这确保了你的应用程序可以自动扩展以应对不断变化的流量负载,从而提高性能和可用性。
在 Minikube 中启用指标服务器插件:
minikube addons enable metrics-server
示例输出:
* The 'metrics-server' addon is enabled
指标服务器为 Kubernetes 提供有关资源使用情况的数据,这对 HPA 的正常运行至关重要。
创建一个带有资源请求的 Deployment:
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
应用该 Deployment:
kubectl apply -f ~/project/k8s-manifests/hpa-example.yaml
YAML 配置说明:
- 此 YAML 文件定义了一个 PHP 应用程序的 Deployment 以及相应的 Service。
- Deployment 配置与 NGINX 的配置非常相似,不同之处在于:
- **
name: php-apache**:Deployment 和 Pod 容器的名称。 - **
image: k8s.gcr.io/hpa-example**:容器的 Docker 镜像。 - **
resources**:此部分指定了容器的资源要求。- **
limits.cpu: 500m**:容器允许使用的最大 CPU。 - **
requests.cpu: 200m**:分配给容器的保证 CPU 数量。
- **
- **
- 该 Service 是一个标准的 Service 配置,用于在内部暴露 Deployment。
创建一个 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 -w
- 观察随着 HPA 扩容而创建的 Pod:
kubectl get pods -w
- 跟踪与扩缩活动相关的事件:
kubectl get events --sort-by='.lastTimestamp' -w
你可以运行这些命令中的任何一个来观察自动扩缩过程的不同方面。例如,使用 -w 标志观察 Pod 可以让你实时看到系统扩容时创建的 Pod:
kubectl get pods -w 的示例输出:
NAME READY STATUS RESTARTS AGE
php-apache-xxxxxxxxx-xxxxx 1/1 Running 0 2m
load-generator 1/1 Running 0 30s
php-apache-xxxxxxxxx-yyyyy 0/1 Pending 0 0s
php-apache-xxxxxxxxx-yyyyy 0/1 ContainerCreating 0 0s
php-apache-xxxxxxxxx-yyyyy 1/1 Running 0 3s
php-apache-xxxxxxxxx-zzzzz 0/1 Pending 0 0s
php-apache-xxxxxxxxx-zzzzz 0/1 ContainerCreating 0 0s
php-apache-xxxxxxxxx-zzzzz 1/1 Running 0 2s
你将看到 HPA 通过增加 Pod 数量来响应增加的负载。指标更新可能需要一分钟或更长时间才能反映出变化:
kubectl get hpa -w 的示例输出:
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
php-apache Deployment/php-apache 0%/50% 1 10 1 30s
php-apache Deployment/php-apache 68%/50% 1 10 1 90s
php-apache Deployment/php-apache 68%/50% 1 10 2 90s
php-apache Deployment/php-apache 79%/50% 1 10 2 2m
php-apache Deployment/php-apache 79%/50% 1 10 4 2m15s
观察完成后,按 Ctrl+C 停止监控命令,然后回到第一个终端按 Ctrl+C 停止负载生成器。
关于 HPA 的关键点:
- 根据资源利用率自动扩缩 Pod,提高应用程序的弹性。
- 可以根据 CPU、内存或自定义指标进行扩缩。
- 定义最小和最大副本数,确保扩缩平衡且高效。
- HPA 是在不同负载下保持应用程序性能和可用性的关键组件。
- 在
kubectl命令中使用-w(watch)标志可以实时监控集群变化。
总结
在本实验中,你通过动手实践掌握了 Kubernetes 中的扩展和负载均衡技术。你首先使用 Minikube 创建了一个本地 Kubernetes 集群,并部署了一个基础的 NGINX Web 应用。随后,你探索了不同的扩展方法,包括修改部署 YAML 文件和使用 kubectl scale 调整 Pod 副本数量。你还学习了如何通过 Kubernetes Service 和临时测试 Pod 验证负载均衡。
此外,你通过 kubectl describe 和 kubectl get events 命令学习了如何监控部署和 Pod。最后,你初步了解了 Horizontal Pod Autoscaler (HPA),包括它如何基于资源利用率自动扩展你的应用,并通过一个基于 php-apache 镜像的示例进行了实践。本实验全面介绍了 Kubernetes 的扩展、负载均衡、监控和自动扩展技术,为你在 Kubernetes 中管理更复杂的应用奠定了基础。


