Kubernetes 系统资源预留

前言 Kubernetes 的 pod 可以按照节点的资源进行调度,默认情况下 pod 能够使用节点的全部资源,这样往往会出现因为节点自身运行的一些驱动及 Kubernetes 系统守护进程,导致资源不足的问题。 例如有一个应用在运行中使用了大量的系统资源,导致 kubelet 和 apiserver 的心跳出现故障,导致节点处于 Not Ready 的状态,节点出现 Not Ready 的状况后,过一会儿会将 pod 调度到其它 node 节点上运行,往往会导致节点雪崩,一个接一个的出现 Not Ready 状况. 那么如何解决这个问题呢? 这时可以通过 为 Kubernetes 集群配置资源预留,kubelet 暴露了一个名为 Node Allocatable 的特性,有助于为系统守护进程预留计算资源,Kubernetes 也是推荐集群管理员按照每个节点上的工作负载来配置 Node Allocatable。 Node Allocatable Kubernetes 节点上的 Allocatable 被定义为 Pod 可用计算资源量。 调度器不会超额申请 Allocatable。 目前支持 CPU、内存 和 存储 这几个参数。可以通过 kubectl describe node 命令查看节点可分配资源的数据: 可以看到有 Capacity 和 Allocatable 两个内容,Allocatable 这个就是节点可分配资源,由于没有设置,所以默认 Capacity 和 Allocatable 是一致的。 Capacity 是节点所有的系统资源,kube-reserved 是给 kube 组件预留的资源,system-reserved 是给系统进程预留的资源,eviction-hard 是Kubelet 的驱逐阈值。 ...

三月 9, 2024 · overstarry

Kubernetes ExternalName

前言 我们知道 kubernetes 内部服务之间是通过 service 进行相互访问的, 那么如果现在有一个非 kubernetes 部署的服务,我们可以也通过 service 进行内部交互使用吗?答案是可以,我们可以使用 service 的 ExternalName 类型将service 映射到外部服务上。 最近需要将一个外部服务映射到 kubernetes service 上,通过查找资料学习,本文记录如何将 kubernetes service 映射到外部服务的流程步骤。 外部域名映射内部 service 先讲解如何将外部服务通过域名的方式映射到内部 service 上,通过配置 externalName 字段来配置映射关系.例如,以下 Service 定义将 test 命名空间中的 my-service 服务映射到 my.overstarry.vip: apiVersion: v1 kind: Service metadata: name: my-service namespace: test spec: type: ExternalName externalName: my.overstarry.vip 虽然 externalName 也支持填写 ip 地址,但不会被 kubernetes 解析,如果需要使用 ip 地址,可以使用无头服务 Headless ,下文会进行介绍。 外部服务ip映射service 接下来介绍没有域名的外部服务和service如何进行映射。上文讲过虽然 externalName 也支持填写 ip 地址,但不会被 kubernetes 解析,如果需要,则应该使用 Headless Service 进行映射。 apiVersion: v1 kind: Service metadata: name: test spec: clusterIP: None type: ClusterIP --- apiVersion: v1 kind: Endpoints metadata: name: test subsets: - addresses: - ip: 10.0.1.10 创建service 不指定 selector,手动维护创建 endpoint,创建之后就可以通过 test 访问 10.0.1.10 这个外部服务。 ...

二月 24, 2024 · overstarry

Kubernetes externaltrafficpolicy 简介

前言 最近在使用 Kubernetes 查看 pod 日志时,发现 pod 日志显示的 ip 不是真实的请求者 ip, 而是 Node 节点的 ip。通过查阅资料发现可以通过设置 externalTrafficPolicy 来显示真实的 IP。 本文对 externaltrafficpolicy 进行一个简单的介绍。 简介 ExternalTrafficPolicy 是 Kubernetes Service 对象的一个属性,它决定了流量如何从集群外部访问 Service。有两个可选值:Cluster 和 Local。 Cluster 模式: 在 Cluster 模式下,流量将通过负载均衡器分发到 Service 的所有 Pod 上。这是传统的负载均衡方式,适用于需要水平扩展和容错的场景。负载均衡器会将流量平均分配给所有可用的 Pod,从而实现负载均衡。 Local 模式: 在 Local 模式下,流量将直接访问与请求最近的节点上运行的 Pod。这种方式避免了负载均衡器的介入,直接将流量定向到本地的 Pod 上。这样可以减少延迟,并且在负载均衡器发生故障时仍然保持可用性。 区别 两种模式有什么区别呢? Cluster 模式 Cluster 模式是默认的模式,Kube-proxy 不管容器在哪个节点上,会公平的转发到某一个节点上,在转发时会替换掉源ip,变成转发的上一个节点的ip.原因是Kube-proxy在做转发的时候,会做一次SNAT (source network address translation),所以源ip变成了上一个节点的ip地址。 这个模式的优点是负载均衡比较好,缺点是由于转发,可能会有性能损耗。 Local 模式 Local 模式下,请求只转发给本机的容器,不会转发给其它节点的容器,保留了源ip。 这个模式的优缺点跟 Cluster 模式恰恰相反:性能好,负载均衡不好。所以如果想要负载均衡就需要一层 LB 来进行控制。 参考 https://github.com/apache/apisix-ingress-controller/issues/1166 https://medium.com/pablo-perez/k8s-externaltrafficpolicy-local-or-cluster-40b259a19404 https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/

十二月 3, 2023 · overstarry

Nginx Ingress http 请求413状态码问题及解决方法

问题 最近在调用一个上传文件的接口时,发现接口调用响应状态码为413,并且控制台显示跨域错误信息。查找了相关信息,得知 413 状态码表示请求的包体过大导致的。 出现这种情况,我想到了2种解决方案: 1) 调整上传文件的方式 2) 调整网关的参数。 综合目前的现况,采取了第二种方式调整网关客户端请求体最大值的参数。 解决 通过查阅 nginx ingress 的文档, 得知可以添加 nginx.ingress.kubernetes.io/proxy-body-size 注解来设置请求体的最大值, 设置 nginx.ingress.kubernetes.io/proxy-body-size 值为合适的值后,再请求接口发现接口顺利响应。 小结 本文介绍了客户端请求接口时,由于 nginx 默认 proxy-body-size 参数太小, 导致请求413 的问题及相应的解决方案。 参考 https://opendocs.alipay.com/support/01rb44 https://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/nginx-configuration/annotations.md#custom-max-body-size

九月 16, 2023 · overstarry

Kubernetes Health check

本文我来讲解 Kubernetes 中的一个重要概念: 容器的健康检查。 介绍 在 Kubernetes 中,你可以为 Pod 里的容器定义一个健康检查“探针”(Probe)。 这样,kubelet 就会根据这个 Probe 的返回值决定这个容器的状态,而不是直接以容器镜像是否运行(来自 Docker 返回的信息)作为依据。 这种机制,是生产环境中保证应用健康存活的重要手段。 k8s 主要有三种健康检查的探针: 1) LivenessProbe 存活探针 2) ReadinessProbe 就绪探针 3) StartupProbe 启动探针 kubelet 使用存活探针来确定什么时候要重启容器。 例如,存活探针可以探测到应用死锁(应用程序在运行,但是无法继续执行后面的步骤)情况。 重启这种状态下的容器有助于提高应用的可用性,即使其中存在缺陷。 存活探针的常见模式是为就绪探针使用相同的低成本 HTTP 端点,但具有更高的 failureThreshold。 这样可以确保在硬性终止 Pod 之前,将观察到 Pod 在一段时间内处于非就绪状态。 kubelet 使用就绪探针可以知道容器何时准备好接受请求流量,当一个 Pod 内的所有容器都就绪时,才能认为该 Pod 就绪。 这种信号的一个用途就是控制哪个 Pod 作为 Service 的后端。 若 Pod 尚未就绪,会被从 Service 的负载均衡器中剔除。 kubelet 使用启动探针来了解应用容器何时启动。 如果配置了这类探针,你就可以控制容器在启动成功后再进行存活性和就绪态检查, 确保这些存活、就绪探针不会影响应用的启动。 启动探针可以用于对慢启动容器进行存活性检测,避免它们在启动运行之前就被杀掉。 probe 介绍 接下来我来讲解用的较多的2个探针: 1) LivenessProbe 存活探针 2) ReadinessProbe 就绪探针 ...

六月 23, 2023 · overstarry