Kubernetes 自动伸缩与高级流量管理
1. Kubernetes Pod 和节点的自动伸缩
为了降低集群的负载,可以减少水平 Pod 自动伸缩器(HPA)中的最大副本数。可以编辑 YAML 文件并应用到系统中,也可以使用
kubectl patch
命令:
$ kubectl patch hpa elastic-hamster-hpa -n ca-demo -p '{"spec": {"maxReplicas": 2}}'
horizontalpodautoscaler.autoscaling/elastic-hamster-hpa patched
此时,Pod 数量将根据更新后的 HPA 进行调整:
$ kubectl get pod -n ca-demo
NAME READY STATUS RESTARTS AGE
elastic-hamster-87d4db7fd-2qghf 1/1 Running 0 20m
elastic-hamster-87d4db7fd-mdvpx 1/1 Running 0 19m
由于容量需求减少,集群自动伸缩器(CA)也会开始缩减节点。但在缩减时,CA 会提供 10 分钟的宽限期,以便将 Pod 从一个节点重新调度到其他节点,然后再强制终止该节点。10 分钟后检查节点,会发现不需要的节点已从集群中移除:
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
gke-k8sdemo-default-pool-1bf4f185-6422 Ready <none> 145m v1.29.7-gke.1008000
gke-k8sdemo-default-pool-1bf4f185-csv0 Ready <none> 145m v1.29.7-gke.1008000
这展示了在 HPA 缩减部署后,CA 能多么有效地应对集群负载的减少。
2. 其他 Kubernetes 自动伸缩工具
与基本的 Kubernetes 自动伸缩器相比,Kubernetes 事件驱动自动伸缩(KEDA)和 Karpenter 等其他自动伸缩器通过基于特定于应用程序的指标和工作负载来管理资源伸缩,提供了更多的灵活性和效率。
-
KEDA
:KEDA(https://keda.sh)旨在通过允许根据自定义指标或外部事件扩展 Pod 副本数量,在 Kubernetes 中实现事件驱动的伸缩。与传统的自动伸缩器依赖 CPU 或内存使用情况不同,KEDA 可以根据来自各种事件源(如消息队列、HTTP 请求速率和自定义应用程序指标)的指标触发伸缩。它与现有的 Kubernetes HPA 无缝集成,可以根据动态工作负载对应用程序进行上下伸缩。KEDA 是由 CNCF 托管的开源项目,通过 GitHub 提供尽力支持。一些不同的供应商将 KEDA 作为其产品和支持的一部分,包括 Azure 容器应用、具有自定义指标的 Red Hat OpenShift 自动伸缩器以及 Azure Kubernetes 服务的 KEDA 插件。
-
Karpenter
:Karpenter(https://karpenter.sh)是一种高级的 Kubernetes 集群自动伸缩器,专注于优化集群内节点的供应和伸缩。它通过根据工作负载需求动态调整节点数量,自动执行计算资源的伸缩过程。Karpenter 旨在快速适应需求变化并优化集群容量,从而提高性能和成本效率。
3. Kubernetes 服务类型回顾
| 服务类型 | 描述 |
|---|---|
| ClusterIP | 使用由每个节点上的 kube-proxy 管理的内部可见虚拟 IP 地址暴露 Pod,只能从集群内部访问。 |
| NodePort | 可以通过任何节点的 IP 地址和指定端口访问。Kube-proxy 在每个节点上暴露一个 30000 - 32767 范围内的端口(默认情况下可配置),并设置转发规则,将对该端口的连接定向到相应的 ClusterIP 服务。 |
| LoadBalancer | 通常用于具有软件定义网络(SDN)的云环境中,可以按需配置负载均衡器将流量重定向到集群。在云控制器管理器中,云负载均衡器的自动配置由特定于供应商的插件驱动。这种类型的服务结合了 NodePort 服务的方法,并在其前面添加了一个额外的外部负载均衡器,将流量路由到 NodePorts。仍然可以通过其 ClusterIP 在内部使用该服务。 |
4. Ingress 对象概述
虽然使用 Kubernetes 服务来启用外部流量到集群听起来很有吸引力,但一直使用它们存在一些缺点。Ingress 对象可以解决这些问题,它可以用于实现和建模第 7 层(L7)负载均衡。Ingress 对象仅用于定义路由和平衡规则,例如将哪个路径路由到哪个 Kubernetes 服务。
以下是一个 Ingress 的 YAML 清单文件示例:
# ingress/portal-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: portal-ingress
namespace: ingress-demo
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: k8sbible.local
http:
paths:
- path: /video
pathType: Prefix
backend:
service:
name: video-service
port:
number: 8080
- path: /shopping
pathType: Prefix
backend:
service:
name: shopping-service
port:
number: 8080
Ingress HTTP 路由规则的构建如下:
-
可选的主机
:在示例中未使用该字段,因此定义的规则适用于所有传入流量。如果提供了字段值,则规则仅适用于以该主机为目标的请求,主机字段支持通配符。
-
路径路由列表
:每个路径都有一个关联的 Ingress 后端,通过提供
serviceName
和
servicePort
来定义。在上述示例中,所有以
/video
为前缀的路径的请求将被路由到
video-service
服务的 Pod,所有以
/shopping
为前缀的路径的请求将被路由到
shopping-service
服务的 Pod。路径字段支持前缀和精确匹配,也可以使用由底层 Ingress 控制器执行的特定于实现的匹配。
5. 使用 nginx 作为 Ingress 控制器
Ingress 控制器是手动部署到集群的 Kubernetes 控制器,通常作为 DaemonSet 或 Deployment 对象运行,负责处理传入流量的负载均衡和智能路由。它负责处理 Ingress 对象,即负责那些指定要使用 Ingress 控制器的对象,并动态配置实际的路由规则。
常用的 Kubernetes Ingress 控制器之一是 nginx(Nginx Ingress Controller)。它作为一个 Deployment 安装在集群中,并带有一组处理 Ingress API 对象的规则。Ingress 控制器作为一个服务暴露,其类型取决于安装环境,在云环境中通常是 LoadBalancer。
ingress-nginx 的安装在不同环境中的说明见官方文档:https://kubernetes.github.io/ingress-nginx/deploy/。虽然使用 Helm 是首选的部署方法,但某些环境可能需要特定的说明。对于云环境,安装 ingress-nginx 通常非常简单,涉及应用单个 YAML 清单文件(或在创建基于云的托管 Kubernetes 集群时启用 ingress-nginx),这将创建多个 Kubernetes 对象。例如,可以使用以下单个命令在 AKS 或 GKE 中部署所需的 Ingress 控制器组件。
与作为 kube-controller-manager 二进制文件一部分运行的其他类型的控制器不同,Ingress 控制器不会随集群自动启动。Kubernetes 项目维护了许多 Ingress 控制器,包括 AWS、GCE 和 nginx Ingress 控制器。对于第三方 Ingress 控制器项目,请参阅文档获取详细列表:https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/#additional-controllers。
在云环境中,经常会遇到专用的 Ingress 控制器,它们利用云提供商提供的特殊功能,允许外部负载均衡器直接与 Pod 通信。在这种情况下,没有额外的 Pod 开销,甚至可能不需要 NodePort 服务。这种路由在软件定义网络(SDN)和容器网络接口(CNI)级别完成,而负载均衡器可以使用 Pod 的私有 IP 地址。
Kubernetes 自动伸缩与高级流量管理
6. 高级流量路由与 Ingress 的优势
Ingress 作为一种反向代理 Kubernetes 资源,在处理外部流量方面具有显著优势。它可以根据 ingress 配置中指定的规则,将来自集群外部的传入请求路由到集群内部的服务。与传统的 Kubernetes 服务类型相比,Ingress 能够实现更复杂的路由和负载均衡。
例如,在处理 HTTP/HTTPS 流量时,传统的 Layer - 4 LoadBalancer 服务存在诸多限制:
-
协议层面
:基于 OSI 层 4 的 TCP/UDP 协议进行流量路由,而大多数 HTTP/HTTPS 应用需要 OSI 层 7 的负载均衡。
-
HTTPS 处理
:无法终止和卸载 HTTPS 流量。
-
虚拟主机
:不能用于跨多个域名的基于名称的虚拟主机。
-
路径路由
:无法配置将如
https://<loadBalancerIp>/service1
这样的请求代理到名为
service1
的 Kubernetes 服务。
-
特殊功能
:像粘性会话或 cookie 亲和性等功能需要 L7 负载均衡器。
而 Ingress 可以解决这些问题,通过定义路由和平衡规则,实现更灵活的流量管理。
7. 应用网关 Ingress 控制器示例(以 AKS 为例)
在云环境中,如 AKS 集群,可以使用专用的应用网关 Ingress 控制器(AGIC)。这种控制器利用云提供商的特殊功能,允许外部负载均衡器直接与 Pod 通信,无需额外的 Pod 开销,甚至可能不需要 NodePort 服务。
以下是这种通信方式的流程:
graph LR
A[外部客户端] --> B[Azure 应用网关]
B --> C[Kubernetes Pods]
style A fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px
style B fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px
style C fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px
外部客户端的请求首先到达 Azure 应用网关,应用网关利用 SDN 和 CNI 技术,直接将流量路由到 Kubernetes Pods,使用 Pod 的私有 IP 地址进行通信。
8. 现代 Kubernetes 项目与技术
除了前面提到的自动伸缩和流量管理技术,还有一些现代的 Kubernetes 项目值得关注:
-
KubeVirt
:用于虚拟化,允许在 Kubernetes 集群中运行虚拟机,为一些需要虚拟机环境的应用提供支持。
-
Knative
:提供服务器less 解决方案,简化了在 Kubernetes 上构建、部署和管理现代无服务器应用的过程。
-
OpenFaaS
:也是一种服务器less 框架,让开发者可以轻松地在 Kubernetes 上创建和运行函数。
9. 临时容器在实时故障排除中的作用
临时容器是一种特殊的容器,用于在运行时对 Pod 进行故障排除。当 Pod 出现问题时,可以动态地将临时容器注入到 Pod 中,进行调试和诊断。
使用临时容器的步骤如下:
1. 确认 Pod 存在问题,需要进行故障排除。
2. 使用
kubectl debug
命令创建临时容器并注入到目标 Pod 中。例如:
kubectl debug -it mypod --image=busybox --target=mypod
- 在临时容器中执行诊断命令,如查看日志、检查文件系统等。
- 完成故障排除后,移除临时容器。
10. Kubernetes 插件的作用
Kubernetes 插件可以扩展 Kubernetes 的功能,满足不同的业务需求。常见的插件包括:
| 插件类型 | 作用 |
| ---- | ---- |
| 网络插件 | 提供网络功能,如 Calico、Flannel 等,实现 Pod 之间的网络通信。 |
| 存储插件 | 管理存储资源,如 Ceph、GlusterFS 等,为 Pod 提供持久化存储。 |
| 安全插件 | 增强集群的安全性,如 OPA Gatekeeper 用于策略管理。 |
11. 多集群管理
随着企业业务的发展,可能会使用多个 Kubernetes 集群。多集群管理变得至关重要,它可以帮助统一管理多个集群的资源、应用和配置。
多集群管理的方法有:
-
使用 Kubernetes 原生工具
:如 kubectl 可以通过配置不同的上下文来管理多个集群。
-
第三方工具
:如 Rancher 提供了可视化的界面,方便管理多个 Kubernetes 集群。
12. Kubernetes 集群的维护与安全
- 维护任务(Day 2 任务) :包括监控集群的健康状态、更新 Kubernetes 版本、管理节点资源等。定期检查集群的日志和指标,及时发现并解决潜在问题。
-
安全最佳实践
:
- 限制对集群的访问权限,使用 RBAC(基于角色的访问控制)进行权限管理。
- 加密敏感数据,如使用 Kubernetes 的 Secret 对象存储密码和密钥。
- 定期进行安全审计,检查集群是否存在安全漏洞。
13. 故障排除 Kubernetes
当 Kubernetes 集群出现问题时,可以按照以下步骤进行故障排除:
1.
查看事件
:使用
kubectl get events
命令查看集群中的事件,了解最近发生的异常情况。
2.
检查 Pod 状态
:使用
kubectl get pods
查看 Pod 的状态,如是否处于
Pending
、
Error
等状态。
3.
查看日志
:使用
kubectl logs
命令查看 Pod 的日志,查找错误信息。
4.
使用临时容器
:如前面所述,注入临时容器进行深入诊断。
通过以上对 Kubernetes 自动伸缩、流量管理、现代项目、维护、安全和故障排除等方面的介绍,我们可以更全面地了解和使用 Kubernetes 技术,构建高效、稳定和安全的应用环境。
超级会员免费看
20

被折叠的 条评论
为什么被折叠?



