xuanyuanaosheng / xuanyuanaosheng.github.io

个人网站:灵梦缘
https://xuanyuanaosheng.github.io/
0 stars 0 forks source link

K8S集群管理员基础知识 #18

Open xuanyuanaosheng opened 4 days ago

xuanyuanaosheng commented 4 days ago

1. Kubernetes 基础知识

Q1: 什么是Kubernetes?Kubernetes主要解决了哪些问题?

回答要点

Q2: 描述一下Kubernetes中的主要组件及其作用?

回答要点

Q3: 什么是Pod?为什么Pod是Kubernetes的基础单位?

回答要点

Q4: 什么是ReplicaSet,Deployment与StatefulSet之间的区别?

回答要点

Q5: ConfigMap和Secret有什么区别?

回答要点


2. 集群管理

Q6: 描述一下Kubernetes的调度策略。

回答要点

Q7: 什么是Taints和Tolerations?

回答要点

Q8: 如何在Kubernetes中进行滚动更新和回滚?

回答要点

Q9: Kubernetes中的Service有哪几种类型?分别有什么作用?

回答要点

Q10: 如何对K8S集群进行自动伸缩(Horizontal Pod Autoscaling, HPA)?

回答要点


3. 高级主题

Q11: 在Kubernetes中,如何管理存储?PersistentVolume和PersistentVolumeClaim有什么作用?

回答要点

Q12: 如何在Kubernetes中实现安全性?如何进行网络隔离?

回答要点

Q13: 什么是Kubernetes的Ingress?如何配置HTTPS的Ingress?

回答要点

Q14: Helm是什么?它是如何工作的?

回答要点

Q15: 如何备份和恢复Kubernetes集群中的etcd数据?

回答要点


4. Kubernetes故障排查与优化

Q16: 当Pod状态为CrashLoopBackOff时,如何进行故障排查?

回答要点

Q17: 如何监控Kubernetes集群的运行状况?

回答要点

Q18: 如何管理多个Kubernetes集群?

回答要点

Q19: 你如何优化Kubernetes集群的性能?

回答要点

Q20: 如何在Kubernetes中进行日志收集和集中管理?

回答要点

xuanyuanaosheng commented 4 days ago

怎样在命令行下管理多个K8S集群

在命令行下管理多个 Kubernetes 集群,通常使用 kubectl 工具结合 Kubernetes 的 kubeconfig 文件。以下是管理多个 Kubernetes 集群的基本步骤和技巧:

1. 配置 kubeconfig

Kubernetes 使用 kubeconfig 文件来存储集群的配置信息。您可以在一个 kubeconfig 文件中配置多个集群和用户。

创建/更新 kubeconfig 文件

  1. 合并多个 kubeconfig 文件:

    如果您已经有多个集群的 kubeconfig 文件,可以使用以下命令合并它们:

    KUBECONFIG=~/.kube/config:~/.kube/other-config kubectl config view --merge --flatten > ~/.kube/merged-config

    然后,您可以使用合并后的配置文件:

    export KUBECONFIG=~/.kube/merged-config
  2. 手动添加集群配置:

    您可以通过以下命令手动添加集群和上下文配置:

    kubectl config set-cluster CLUSTER_NAME --server=https://your-cluster-api-server --certificate-authority=/path/to/ca.crt
    kubectl config set-credentials USER_NAME --token=YOUR_TOKEN
    kubectl config set-context CONTEXT_NAME --cluster=CLUSTER_NAME --user=USER_NAME
  3. 选择上下文:

    kubeconfig 文件中,您可以定义多个上下文(contexts),每个上下文代表一个集群、用户和命名空间的组合。您可以使用以下命令查看当前上下文和所有上下文:

    kubectl config current-context
    kubectl config get-contexts

    切换到另一个上下文:

    kubectl config use-context CONTEXT_NAME

2. 使用命令行管理集群

一旦配置好 kubeconfig 文件,您就可以使用 kubectl 命令管理不同的集群。以下是一些常见的命令示例:

3. 使用环境变量管理 KUBECONFIG

如果您经常需要在多个集群之间切换,可以通过设置 KUBECONFIG 环境变量来简化流程。例如:

export KUBECONFIG=~/.kube/config:~/.kube/other-config

这允许您一次性访问多个集群的配置。

4. 使用工具

还有一些工具可以帮助管理多个 Kubernetes 集群:

5. 结论

通过配置 kubeconfig 文件和使用 kubectl 命令,您可以方便地在命令行中管理多个 Kubernetes 集群。结合使用工具如 kubectx 可以进一步简化管理流程。

xuanyuanaosheng commented 4 days ago

在K8S中怎样使用RBAC来控制一个用户能的操作的权限?

在 Kubernetes (K8S) 中,RBAC(Role-Based Access Control,基于角色的访问控制)允许你通过角色和绑定来精确地控制用户和服务账户在集群中的权限。你可以通过定义不同的 RoleClusterRole 来控制用户能够执行的操作,以及通过 RoleBindingClusterRoleBinding 来将这些角色分配给用户。

基本概念

RBAC 控制权限的基本步骤

1. 创建 RoleClusterRole

Role 适用于某个 Namespace 内的资源控制,而 ClusterRole 则适用于集群范围内的控制。我们先来看如何创建一个 Role

示例:创建一个 Role,只允许用户在 dev-namespace 中管理 Pods
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: dev-namespace
  name: pod-manager
rules:
- apiGroups: [""]  # "" 代表核心 API 组,用于控制像 Pod 这样的基本资源
  resources: ["pods"]
  verbs: ["create", "delete", "get", "list", "watch", "update"]
创建 Role:
kubectl apply -f pod-manager-role.yaml

2. 创建 RoleBindingClusterRoleBinding

你需要创建一个 RoleBindingClusterRoleBinding,将刚刚创建的 Role 绑定到一个用户或组上。

示例:将 pod-manager Role 绑定到一个用户 user1
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: pod-manager-binding
  namespace: dev-namespace
subjects:
- kind: User  # 这里可以是 User, Group, 或 ServiceAccount
  name: user1  # 绑定的用户名称
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role  # 绑定的角色是 Role
  name: pod-manager  # Role 的名称
  apiGroup: rbac.authorization.k8s.io
创建 RoleBinding:
kubectl apply -f pod-manager-binding.yaml

3. 使用 ClusterRoleClusterRoleBinding 进行集群范围的权限控制

如果你希望在集群范围内进行权限控制,可以使用 ClusterRoleClusterRoleBindingClusterRole 还可以用来控制某些特定非命名空间资源(如节点、命名空间、持久卷等)。

示例:创建一个 ClusterRole,允许用户查看所有命名空间中的 Pods
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: view-pods
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]
创建 ClusterRole:
kubectl apply -f view-pods-clusterrole.yaml
将 ClusterRole 绑定到一个用户 user2
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: view-pods-binding
subjects:
- kind: User
  name: user2
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: view-pods
  apiGroup: rbac.authorization.k8s.io
创建 ClusterRoleBinding:
kubectl apply -f view-pods-binding.yaml

4. 验证用户权限

在绑定角色后,用户应该只能执行他们所被允许的操作。你可以使用 kubectl auth can-i 命令来验证某个用户是否有执行某些操作的权限。

kubectl auth can-i create pods --as=user1 --namespace=dev-namespace
kubectl auth can-i get pods --as=user2 --namespace=default

总结

通过 RBAC,你可以灵活控制用户或组对 Kubernetes 资源的访问权限。以下是配置 RBAC 的主要步骤:

  1. 定义 Role 或 ClusterRole: 通过 RoleClusterRole 来定义某个命名空间或集群范围内的访问权限。
  2. RoleBinding 或 ClusterRoleBinding: 使用 RoleBindingClusterRoleBinding 将用户或组与相应的 RoleClusterRole 绑定。
  3. 验证用户权限: 使用 kubectl auth can-i 验证用户的权限。

通过这种方式,你可以为不同角色和用户设置不同的权限,从而确保 Kubernetes 集群的安全性。


在 Kubernetes 中,您可以通过 kubectl auth can-i 命令查看某个账户在集群中的资源权限。该命令用于检查某个用户是否有权执行特定的操作。下面是一些具体的使用方式:

1. 查看当前用户的权限

kubectl auth can-i <verb> <resource> --namespace=<namespace>

示例:

# 查看当前用户是否可以获取 pods 资源
kubectl auth can-i get pods

# 查看当前用户是否可以删除 services 资源
kubectl auth can-i delete services --namespace=my-namespace

2. 查看某个用户的权限

通过指定 --as 选项,您可以模拟某个用户来查看他们的权限。

kubectl auth can-i <verb> <resource> --namespace=<namespace> --as=<username>

示例:

# 查看名为 "user123" 的用户是否可以创建 deployments 资源
kubectl auth can-i create deployments --as=user123

# 查看 "user123" 是否可以在 "prod" 命名空间中删除 pods
kubectl auth can-i delete pods --namespace=prod --as=user123

3. 查看所有资源权限

如果您想查看用户在命名空间中的所有资源权限,可以使用以下命令列出用户可以进行的所有操作:

kubectl auth can-i --list --namespace=<namespace> --as=<username>

示例:

# 查看当前用户在 "default" 命名空间的所有权限
kubectl auth can-i --list

# 查看名为 "user123" 的用户在 "dev" 命名空间的所有权限
kubectl auth can-i --list --namespace=dev --as=user123

4. 通过 RoleBinding 和 ClusterRoleBinding 查看权限

如果您想了解某个用户或者服务账户绑定了哪些角色,您可以查看相关的 RoleBindingClusterRoleBinding

查看 ClusterRoleBindings:

kubectl get clusterrolebindings --field-selector subjects.kind=User,subjects.name=<username> -o yaml

查看 RoleBindings:

kubectl get rolebindings --namespace=<namespace> --field-selector subjects.kind=User,subjects.name=<username> -o yaml

示例:

# 查看 user123 绑定的 ClusterRoleBinding
kubectl get clusterrolebindings --field-selector subjects.kind=User,subjects.name=user123 -o yaml

# 查看 user123 在 "dev" 命名空间中绑定的 RoleBinding
kubectl get rolebindings --namespace=dev --field-selector subjects.kind=User,subjects.name=user123 -o yaml

5. 查看某个 ServiceAccount 的权限

对于 ServiceAccount,您可以通过以下命令查看权限:

kubectl auth can-i --as=system:serviceaccount:<namespace>:<serviceaccount> <verb> <resource>

示例:

# 查看 default 命名空间中的 my-serviceaccount 是否可以创建 pods
kubectl auth can-i create pods --as=system:serviceaccount:default:my-serviceaccount

总结

xuanyuanaosheng commented 4 days ago

在K8S中怎样调度GPU资源?

在 Kubernetes (K8S) 中,调度和使用 GPU 资源需要做一些配置,涉及 GPU 驱动、设备插件以及指定资源请求等。以下是调度 GPU 资源的具体步骤:

1. 准备 GPU 节点

要调度 GPU 资源,首先需要确保在 Kubernetes 集群中的节点具备 GPU,并安装了相应的驱动程序。

1.1 安装 NVIDIA 驱动程序

如果使用 NVIDIA GPU,首先需要在节点上安装 NVIDIA GPU 驱动程序。

在大多数情况下,你可以按照以下步骤安装 NVIDIA 驱动:

# 1. 添加 NVIDIA repository
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list

# 2. 安装 NVIDIA 驱动
sudo apt-get update
sudo apt-get install -y nvidia-driver-470

根据你的系统类型(例如 Ubuntu 或 CentOS),可能需要调整安装过程。如果在云平台(如 AWS、GCP 等)使用 GPU 节点,通常系统会预装必要的驱动。

1.2 安装 NVIDIA Docker 和设备插件

接下来,你需要为 Docker 安装 nvidia-docker 来管理 GPU 资源。

# 安装 nvidia-container-toolkit
sudo apt-get install -y nvidia-container-toolkit
sudo systemctl restart docker

Kubernetes GPU 调度依赖于 NVIDIA 的 NVIDIA Kubernetes Device Plugin,用于暴露 GPU 设备给 Kubernetes。接下来我们来安装这个插件。

2. 部署 NVIDIA Device Plugin

NVIDIA 提供了一个设备插件(device plugin)用于管理 GPU。通过这个插件,Kubernetes 可以自动发现并调度 GPU 资源。

2.1 部署设备插件

使用 kubectl apply 来部署 NVIDIA 设备插件:

kubectl apply -f https://github.com/NVIDIA/k8s-device-plugin/raw/main/nvidia-device-plugin.yml

这个插件会在每个拥有 GPU 的节点上运行,并将 GPU 资源报告给 Kubernetes。部署完成后,你可以通过以下命令来验证设备插件是否正常运行:

kubectl get ds -n kube-system

查看 nvidia-device-plugin 的状态,确保设备插件已经正常部署到所有 GPU 节点上。

3. 检查 GPU 资源

部署 NVIDIA 设备插件后,Kubernetes 将自动检测节点上的 GPU 并将其作为资源。你可以通过以下命令检查 GPU 资源是否可用:

kubectl describe nodes | grep -A 5 "Capacity"

在输出中,你应该能看到类似如下的 GPU 资源:

nvidia.com/gpu:  1

这表示该节点上有 1 个 NVIDIA GPU 可供调度。

4. 使用 GPU 资源的 Pod 配置

在创建需要使用 GPU 的 Pod 时,可以在 spec 中指定 GPU 资源请求。下面是一个示例,演示如何请求使用 1 个 GPU 的 Pod:

apiVersion: v1
kind: Pod
metadata:
  name: gpu-pod
spec:
  containers:
  - name: gpu-container
    image: nvidia/cuda:10.0-base
    resources:
      limits:
        nvidia.com/gpu: 1 # 请求 1 个 GPU
    command: ["nvidia-smi"]

在这个 Pod 配置中,nvidia.com/gpu: 1 表示请求 1 个 GPU 资源。可以根据实际需要调整请求的 GPU 数量。

5. 部署 GPU 作业

使用 kubectl apply 命令部署 Pod:

kubectl apply -f gpu-pod.yaml

你可以通过 kubectl logs 命令查看容器日志,确认 GPU 是否正常工作:

kubectl logs gpu-pod

例如,使用 nvidia/cuda 镜像并执行 nvidia-smi 命令可以查看 GPU 的工作状态。

6. 为工作负载调度 GPU 资源

在 K8S 集群中,GPU 是作为一种 可限制的资源 来管理的,类似于 CPU 和内存。当你定义工作负载(如 Pod、Deployment 等)时,可以在 resources 字段下设置对 GPU 资源的请求和限制。

resources:
  limits:
    nvidia.com/gpu: 1  # 限制容器最多使用 1 个 GPU

Kubernetes 通过设备插件自动发现并分配 GPU 资源,调度器根据这些资源请求为 Pod 安排 GPU 节点。如果节点上没有可用的 GPU,Pod 将处于 Pending 状态,直到有 GPU 可用。

7. 验证 GPU 调度

你可以通过以下命令查看 Pod 是否成功调度到 GPU 节点上:

kubectl get pods -o wide

查看 Pod 所在节点,并确认该节点上是否有 GPU。

总结

调度 GPU 资源的关键步骤包括:

  1. 安装 GPU 驱动程序:在拥有 GPU 的节点上安装 GPU 驱动。
  2. 部署 NVIDIA 设备插件:通过 nvidia/k8s-device-plugin 来将 GPU 资源暴露给 Kubernetes。
  3. 为 Pod 分配 GPU 资源:在工作负载配置中请求 GPU 资源。
  4. 验证 GPU 调度:确认 Pod 被调度到具有 GPU 的节点上,并使用 GPU 资源。

通过以上步骤,您可以在 Kubernetes 集群中高效地调度和管理 GPU 资源,支持需要 GPU 加速的计算任务(如深度学习、图像处理等)。

xuanyuanaosheng commented 3 days ago

K8S网络插件

Kubernetes(K8S)的网络插件用于管理和配置集群中的网络通信,确保Pod之间以及Pod与外部服务之间的连接。Kubernetes本身提供了基本的网络模型,但具体的网络实现是通过插件来完成的。网络插件一般遵循CNI(Container Network Interface)标准,并为集群提供了不同的功能和特性,如网络隔离、服务发现、负载均衡等。


总结

Kubernetes中的网络插件非常多样,选择合适的插件取决于具体的需求,如性能、易用性、安全性、网络策略支持等。以下是常见场景下的推荐插件:

选择适合的网络插件可以帮助提高集群的性能、灵活性和安全性。

以下是常见的Kubernetes网络插件及其介绍:


1. Flannel

Flannel 是最简单、最常见的Kubernetes网络插件之一,专注于为Kubernetes集群中的每个节点提供IP地址空间。

适用场景:适用于对网络要求不高的场景,尤其是开发或测试环境。


2. Calico

Calico 是一个功能强大的网络插件,提供IP数据包路由和网络策略控制,支持大规模Kubernetes集群。

适用场景:适用于对网络安全、性能和可扩展性要求较高的场景,尤其是生产环境。


3. Weave Net

Weave Net 是一个简单易用的Kubernetes网络插件,支持网络隔离和加密功能。

适用场景:适用于中小规模集群,尤其是对安全性和易用性有要求的环境。


4. Cilium

Cilium 是一个基于eBPF(Extended Berkeley Packet Filter)的网络插件,专注于提供安全性和可观察性,尤其适用于微服务架构。

适用场景:适用于微服务架构、云原生应用以及对网络安全和监控有较高要求的场景。


5. Canal

Canal 是Calico和Flannel的结合体,兼具两者的优点,提供了网络策略支持和简化的配置。

适用场景:适合需要网络策略但又想要保持简单配置的场景。


6. Kube-Router

Kube-Router 是一个Kubernetes网络插件,专注于提供高效的网络转发、网络策略和负载均衡功能。

适用场景:适合对网络性能要求较高的场景,尤其是需要复杂路由和负载均衡的场景。


7. Multus

Multus 是一个多网络插件,允许在Kubernetes中为Pod分配多个网络接口。

适用场景:适合需要多网络接口或多CNI插件的复杂网络环境。


8. Open vSwitch (OVS) + OVN (Open Virtual Network)

OVS + OVN 是一个强大的网络解决方案,基于Open vSwitch的虚拟交换技术。

适用场景:适合需要复杂虚拟网络架构的场景,如企业数据中心或云计算环境。

xuanyuanaosheng commented 3 days ago

K8S 调度器的工作原理

Kubernetes 调度器(Scheduler)是 Kubernetes 中负责将新创建的未指定节点的 Pod 分配到合适的节点上的组件。调度器是 Kubernetes 系统中非常关键的一部分,因为它决定了工作负载如何在集群内的节点上分布,从而影响资源利用率、应用程序的性能和集群的健壮性。

K8S 调度器的工作原理

当一个新的 Pod 被创建时,它处于一个未调度(Pending)的状态,并且没有分配到任何节点上。此时,Kubernetes 调度器会负责以下操作:

  1. 过滤阶段(Filtering Phase):调度器首先会根据 Pod 的要求和节点的条件,对所有的节点进行筛选,过滤掉不符合要求的节点。这些条件可能包括:

    • 节点的可用资源(CPU、内存等)
    • Pod 与节点的污点和容忍度
    • 节点的亲和性和反亲和性
    • 节点的健康状况(如是否准备就绪)
  2. 优选阶段(Scoring Phase):在过滤完所有不适合的节点之后,调度器会对剩余的候选节点进行评分。评分的依据可以是多种因素,例如:

    • 节点的剩余资源
    • 节点和 Pod 之间的亲和性(如区域、拓扑、标签)
    • 节点的负载均衡情况(如优先分配到负载较低的节点)
  3. 绑定阶段(Binding Phase):最后,调度器会将 Pod 绑定到得分最高的节点上。这个步骤完成后,Kubelet(节点上的代理)会开始在该节点上运行这个 Pod。

调度器的核心功能

调度器的关键组件

  1. Predicate 算法:在过滤阶段,调度器会使用多个 Predicate 函数来确定某个节点是否能够运行特定的 Pod。这些函数包括检查节点的可用性、资源、污点、Pod 的请求等。

  2. Priority 算法:在优选阶段,调度器使用 Priority 函数对候选节点进行评分。这些评分由多个因素决定,例如节点的剩余资源、负载均衡情况、亲和性等。

  3. 调度周期:调度器定期执行调度循环,在这个过程中会检查所有的 Pending Pod,尝试将它们调度到合适的节点。

常见的调度策略

调度器的可扩展性

Kubernetes 调度器是可扩展的,允许你根据集群的需求自定义调度逻辑:

  1. 自定义调度器:如果默认调度器不满足你的需求,你可以编写自定义调度器,并将其部署到 Kubernetes 中。自定义调度器可以使用不同的调度算法和策略来调度 Pod。

  2. 调度器扩展点:Kubernetes 还提供了调度器扩展点(Scheduler Extender),允许你在现有调度器的基础上添加额外的调度逻辑,比如增加过滤条件或对节点进行额外评分。

  3. 多调度器支持:Kubernetes 允许你运行多个调度器,不同的 Pod 可以通过 schedulerName 字段来指定使用哪个调度器。

调度器的优化

为了提高集群效率,调度器需要经过调优,以下是一些常见的调优策略:

  1. 资源分配策略:合理配置 Pod 的 CPU、内存请求和限制,避免资源超分配或不足。
  2. 节点负载均衡:确保工作负载在多个节点间合理分布,防止单个节点过载。
  3. 分布式应用调度:结合拓扑感知调度,确保分布式应用(如微服务、数据库等)可以高效运行并具备容灾能力。
  4. 优先级和抢占:为关键工作负载设置更高的优先级,并允许其抢占低优先级的 Pod。

调度器的日志和监控

调度器的日志非常重要,它可以帮助你理解调度决策并排查问题。常见的调度器日志包括:

另外,你可以使用 Prometheus 等监控工具来监控调度器的行为,捕获调度延迟、调度成功率等关键指标。


Kubernetes 调度器在确保集群资源的高效利用、Pod 的可靠调度和应用程序的可用性方面起到了至关重要的作用。你可以通过调优、监控和扩展来更好地满足不同业务需求。如果你有更多的具体问题或场景,可以进一步讨论!

xuanyuanaosheng commented 3 days ago

K8S的HPA

Kubernetes 的 HPA(Horizontal Pod Autoscaler,水平 Pod 自动伸缩)是 Kubernetes 中的一项核心功能,它允许基于集群的实时负载自动调整工作负载的副本数量,以保证应用的高可用性和弹性。HPA 能根据资源使用情况或自定义指标的变化,自动增加或减少 Pod 数量,从而优化资源利用和应用性能。

HPA 的工作原理

HPA 的核心功能是监控某个工作负载(如 Deployment、ReplicaSet 或 StatefulSet)的资源使用情况(例如 CPU、内存)或其他自定义指标,当负载达到某个预定义的阈值时,它会动态调整副本的数量,确保应用具有足够的资源来处理负载变化。

HPA 的主要工作流程如下:

  1. 监控指标:HPA 定期(默认 15 秒)通过 Kubernetes 的资源度量 API(Metrics API)或自定义指标 API 收集 Pod 的资源使用情况或自定义指标。

  2. 计算副本数:根据预定义的目标值和当前的资源使用情况,HPA 计算出应该增加或减少多少个 Pod。例如,如果 CPU 使用率超过目标值,它会增加 Pod 数量,反之则减少。

  3. 更新副本数:HPA 将新计算的副本数量更新到控制器(如 Deployment),以调整 Pod 副本的数量。

配置 HPA

使用 HPA 需要定义一个 HPA 资源对象,这个对象指定了:

基于 CPU 使用率的 HPA 配置示例

以下是一个简单的 HPA 配置示例,基于 CPU 使用率自动伸缩:

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: myapp-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: myapp-deployment  # 需要伸缩的对象
  minReplicas: 2  # 最小副本数
  maxReplicas: 10  # 最大副本数
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 50  # 目标 CPU 使用率

在上面的配置中:

基于自定义指标的 HPA 配置示例

你也可以基于自定义指标(如应用程序请求数、队列长度等)来定义 HPA。这需要借助外部监控工具如 Prometheus 和自定义指标 API。

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: myapp-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: myapp-deployment
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Pods
    pods:
      metric:
        name: custom_requests_per_second  # 自定义指标名称
      target:
        type: AverageValue
        averageValue: 100  # 每秒请求数的目标值

在这个示例中,HPA 会基于 custom_requests_per_second 指标来调整副本数。

HPA 的主要组件

  1. Metrics Server:HPA 默认通过 Metrics Server 来获取资源使用数据,特别是 CPU 和内存使用率。Metrics Server 是 Kubernetes 内置的资源监控工具,它定期从节点和 Pod 中收集指标。

  2. Custom Metrics API:如果你想要基于自定义指标进行伸缩(例如业务指标、Prometheus 指标等),则需要配置 Custom Metrics API,并与外部的监控系统(如 Prometheus)集成。

  3. Control Loop:HPA 是一个控制回路(control loop)组件,它会定期评估当前的资源使用情况,并与目标值对比,然后做出决策。如果发现当前使用率超过或低于目标值,HPA 就会相应地增减 Pod 的数量。

HPA 的伸缩算法

HPA 的伸缩逻辑是基于资源使用率的目标值。伸缩算法可以总结为以下公式:

desiredReplicas = ceil(currentReplicas * (currentMetricValue / desiredMetricValue))

例如,如果当前有 5 个 Pod,每个 Pod 的 CPU 使用率为 80%,而目标 CPU 使用率是 50%,则 HPA 将计算出新的副本数量:

desiredReplicas = ceil(5 * (80 / 50)) = ceil(5 * 1.6) = 8

HPA 会将副本数从 5 个增加到 8 个。

HPA 的高级配置和策略

Kubernetes 的 HPA 提供了多个高级选项,帮助你更好地管理自动伸缩行为:

  1. 冷却时间(Stabilization Window):你可以设置一个冷却时间,避免 HPA 频繁地扩展或缩减副本数。默认情况下,HPA 会在缩减 Pod 数时采用 5 分钟的冷却时间。

    behavior:
     scaleDown:
       stabilizationWindowSeconds: 300  # 5 分钟冷却时间
  2. 伸缩速率:你可以限制每次伸缩操作的最大增长或减少幅度,避免过度伸缩导致系统不稳定。

    behavior:
     scaleUp:
       policies:
       - type: Percent
         value: 50  # 每次最多扩展 50%
         periodSeconds: 60
     scaleDown:
       policies:
       - type: Pods
         value: 4  # 每次最多缩减 4 个 Pod
         periodSeconds: 60
  3. 最小副本数与最大副本数:你可以设置最小和最大副本数,防止自动伸缩时 Pod 数过低影响可用性,或过高造成资源浪费。

  4. 自定义指标:通过 Custom Metrics API,你可以使用 Prometheus 等外部系统作为自定义指标数据源。例如,基于请求率或队列长度来调整副本数。

HPA 的监控和故障排查

  1. 查看 HPA 状态:可以使用以下命令查看 HPA 的当前状态,包括当前副本数、目标值和实际的资源使用情况:

    kubectl get hpa
    kubectl describe hpa <hpa-name>
  2. 监控 HPA:可以使用 Prometheus 和 Grafana 来监控 HPA 的伸缩行为和 Pod 的资源使用情况。

  3. 调试问题:如果 HPA 没有按预期工作,常见的故障排查步骤包括:

    • 确保 Metrics Server 正常工作并返回正确的数据。
    • 检查 HPA 目标的 Deployment 或 ReplicaSet 是否工作正常。
    • 查看 HPA 事件日志,分析调度器是否存在错误或资源不足。

HPA 的应用场景

  1. 自动伸缩 Web 服务:对于处理用户请求的 Web 应用,HPA 可以根据 CPU 使用率或请求率自动扩展或缩减副本,确保在高负载时有足够的资源应对流量。

  2. 批处理任务:HPA 可以根据任务队列长度或工作负载的数量自动增加 Pod 数量,以加快处理速度。当任务完成后,它会自动缩减副本数。

  3. 微服务架构:在微服务架构中,不同服务的负载可能差异较大,HPA 能够为每个服务动态调整副本数,从而优化资源利用率并提高服务的稳定性。

总结

Kubernetes 的 HPA 是实现应用程序自动伸缩的强大工具,通过动态调整 Pod 数量来应对负载波动。它可以基于多种指标(如 CPU、内存、请求数等)来执行自动伸缩操作,帮助你更好地管理资源,提高系统的弹性和可用性。

xuanyuanaosheng commented 6 hours ago

关于K8S的一些待解决的问题

  1. 线上核心业务比方说数据库,redis这些有状态服务有部署在K8S里面么?
  2. K8S的备份只用备份Etcd就可以么?是否需要备sc对于的存储。
  3. 通过helm部署应用修改配置出现劈叉问题即怎么找到某个应用的部署源头(可能不是helm部署的)或者说怎么查询一个服务有部署源头,从而实现快速拍错更改配置
  4. 一个通过 Deployment和StatefulSet部署的有状态服务例如Mysql有什么区别?