10个常见Kubernetes的陷阱
bigegpt 2024-11-20 12:39 4 浏览
Kubernetes 是最流行的容器编排和部署平台。它提供了强大的工具,可以在生产中可靠地运行容器化应用程序。
然而,有灵活性的同时也带来了复杂性,在本文中,我们将探讨许多团队遇到的 10个常见 Kubernetes 陷阱。能够识别并避免这些挑战将提高应用程序的可扩展性、可靠性和安全性,同时让你更好地控制集群及其部署。
1.使用 latest` Tag 部署容器
可以说,Kubernetes 最常被违反的最佳实践之一就是在部署容器时使用latest标签。这将使我们面临无意中接收重大变更的风险,而这些变更可能影响系统稳定性。
每个人使用 latest 标签的方式各不相同,但大多数人都会将 latest 指向其项目的最新版本。例如,今天使用 helm:latest 将提供 Helm v3,但在v4版本发布后,重启就会更新到v4,但是我们可能还认为系统运行的是 v3 版本,从而引发不可预知的风险。
2.不使用Liveness和Readiness 探针
探针可以使我们的应用程序更具弹性。它们会告知 Kubernetes Pod 的健康状况。
当容器出现问题时,比如内存溢出,Liveness探针请求超时,那么Liveness探针会通知 Kubernetes 重启容器。
有时候应用会暂时性地无法为请求提供服务。 例如,应用在启动时可能需要加载大量的数据或配置文件,或是启动后要依赖等待外部服务。 在这种情况下,既不想杀死应用,也不想给它发送请求。 Kubernetes 提供了Readiness探针来发现并缓解这些情况,容器所在 Pod 上报还未就绪的信息,并且不接受通过 Kubernetes Service 的流量。
下面是一个包含有效性和就绪性探针的简单 Pod:
apiVersion: v1
kind: Pod
metadata:
name: probes-demo
spec:
containers:
- name: probes-demo
image: nginx:latest
livenessProbe:
httpGet:
path: /
port: 80
readinessProbe:
httpGet:
path: /
port: 80
3. 缺少节点选择器导致调度效率低下
集群的整体性能取决于 Pod 是否被正确调度到合适的节点上。许多集群包含多种类型的节点,例如用于标准应用程序的小型 2 CPU/4 GB节点和用于密集后端服务的较大8 CPU/16GB节点。
如果Pod无法可靠地调度到我们想要的节点池,那么集群利用率将会很低。例如即使有未充分利用的较小节点,也会强制创建不必要的新的较大节点,从而增加集群的成本。通过在节点上设置标签,然后使用节点选择器将每个 Pod 分配给兼容的节点来避免此问题:
apiVersion: v1
kind: Pod
metadata:
name: pod-node-selector-demo
spec:
containers:
- name: nginx
image: nginx:latest
nodeSelector:
node-class: 2vcpu4gb
此 Pod 只会调度到设置了 标签的节点。node-class: 2vcpu4gb
使用命令在匹配的节点上设置标签:kubectl label
设置适当的调度规则将最大限度地提高节点利用率并保持稳定的集群性能。
4.破坏 Pod 亲和性/反亲和性规则
Pod 亲和性和反亲和性规则允许指示 Kubernetes 哪个节点最适合部署Pod。规则可以以节点级特征(例如标签)或已在节点上运行的其他 Pod 的特征为条件。
亲和性规则将Pod吸引到 Node,使得 Pod 更有可能调度到特定Node上,而反亲和性则具有排斥作用,降低了调度的概率。 Kubernetes 会评估每个可用于调度的可能节点的 Pod 亲和性规则,然后选择最合适的一个。
亲和力系统能够支持复杂的调度行为,但也很容易错误配置亲和力规则,Pod会意外地调度到不正确的节点,或者拒绝调度。
比如一个服务的两个副本,应该调度在两个Node上,这样如果一个 Node 节点发生故障时,可以保证服务的另一个副本可用,如果规则设置不正确都调度到一个Node 上那么会导致服务不可用。
5. 没有监控/记录
当在Kubernetes 中扩容应用程序时,了解集群资源利用率、应用程序错误和实时性能数据至关重要。内存消耗激增、Pod 驱逐和容器崩溃都是我们应该了解的问题,但标准 Kubernetes不具备任何可观测性功能,以便在故障发生时发出告警。
要启用对集群的监控,我们应该部署可观测性平台,例如 Prometheus、夜莺。这会从 Kubernetes 收集指标,同时在Grafana查看相关数据指标。同时也有告警机制。
6. 标签选择器不匹配
部署和服务等对象依赖正确的标签选择器来识别 Pod 及其管理的其他对象。选择器与实际分配给对象的标签之间的不匹配将导致部署失败。
示例
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-deployment
spec:
replicas: 2
selector:
matchLabels:
app: nginx-demo-app
template:
metadata:
labels:
# Label does not match the deployment's selector!
app: nginx-demo-application
spec:
containers:
name: nginx-demo-app
image: nginx:latest
以上文件部署会抛出selector does not match template labelsspec.selector.matchLabelsspec.template.metadata.labels要解决此问题,请调整清单的 和 字段,使它们具有相同的键值对
7. 服务端口不匹配
同样,确保Service将流量路由到Pod上的正确端口也很重要。不正确的端口定义可能会使 Pod 看起来像是发生了故障,而实际上流量根本内有到达该 Pod。
以下清单包含此问题的示例。该Service监听9000端口并将流量转发到其 Pod上的8080端口 ,但容器实际上端口是80,所以流量无法到达。
apiVersion: v1
kind: Pod
metadata:
name: demo-pod
labels:
app: demo-app
spec:
image: nginx:latest
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: demo-service
spec:
ports:
- port: 9000
protocol: TCP
targetPort: 8080
selector:
app: demo-app
8. 意外部署到错误的命名空间
Kubernetes命名空间将一组服务逻辑分组在一起,在集群中提供一定程度的隔离。为每个团队、应用和环境创建命名空间可以防止名称冲突并简化管理体验。
使用命名空间时,请记住为每个服务和Kubectl命令指定目标命名空间。否则,将使用默认命名空间default。如果服务没有部署在合适的命名空间下,会导致相关服务器请求不可达。
以下清单为Istio Ingress转发配置,此文件部署在seg空间下,然后根据/dp-manager请求,转发到seg空间下的dp-manager-backend服务,如果dp-manager-backend不在 seg空间下,那么会导致请求异常。
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: dp-manager-vs
namespace: seg
spec:
gateways:
- dp-manager-gateway
hosts:
- control-dpmanager.test.com
http:
- match:
- uri:
prefix: /dp-manager
route:
- destination:
host: dp-manager-backend
port:
number: 80
9. 没有资源请求和限制的 Pod
正确的资源管理对于保持集群的稳定性至关重要。Pod默认没有任何资源限制,除非我们对其进行配置,因此这可能会导致Node节点CPU 和内存耗尽。
在所有 Pod 上设置适当的资源请求和限制以减少资源争用。 请求Kubernetes为我们的 Pod 预留特定数量的资源,防止其调度到无法提供足够容量的节点上。 Limits设置Pod可以使用的最大资源量;超过 CPU 限制的 Pod 将受到限制,而达到内存限制则会提示内存不足 (OOM) 杀手终止 Pod 中运行的进程。
请求和限制在 Pod 清单的 字段中定义:spec.container.resources,
apiVersion: v1
kind: Pod
metadata:
name: demo-pod
spec:
containers:
- name: demo-container
image: nginx:latest
resources:
requests:
cpu: 100m
memory: 1Gi
limits:
memory: 2Gi
以上Pod 请求100m(1000m等于1核)CPU 时间和 1Gi 内存。它只会调度到可以提供足够资源的节点上。 Pod 还设置了内存限制,最大可以申请2Gi 内存。 最佳实践是将 Pod 的内存限制设置为等于其请求。通常不需要 CPU 限制,因为 Kubernetes 会按比例限制超出其请求的 Pod。
10. 集群自动扩容错误
选择Kubernetes原因之一就是它的弹性扩容。正确配置可以使K8s在需求高峰时自动添加新的 Pod 和节点,从而动态地水平和垂直扩容。但是不幸的是,很多团队它们的自动扩容是不可预测的。
因此定期检查集群的利用率,以检查它是否仍然适合您的工作负载。使用负载测试工具(例如Locust)测试自动扩缩规则,将多余的流量引导至集群。这可以使我们更早地发现问题,确保Pod 在实际流量到达时能够无缝扩容。
相关推荐
- 悠悠万事,吃饭为大(悠悠万事吃饭为大,什么意思)
-
新媒体编辑:杜岷赵蕾初审:程秀娟审核:汤小俊审签:周星...
- 高铁扒门事件升级版!婚宴上‘冲喜’老人团:我们抢的是社会资源
-
凌晨两点改方案时,突然收到婚庆团队发来的视频——胶东某酒店宴会厅,三个穿大红棉袄的中年妇女跟敢死队似的往前冲,眼瞅着就要扑到新娘的高额钻石项链上。要不是门口小伙及时阻拦,这婚礼造型团队熬了三个月的方案...
- 微服务架构实战:商家管理后台与sso设计,SSO客户端设计
-
SSO客户端设计下面通过模块merchant-security对SSO客户端安全认证部分的实现进行封装,以便各个接入SSO的客户端应用进行引用。安全认证的项目管理配置SSO客户端安全认证的项目管理使...
- 还在为 Spring Boot 配置类加载机制困惑?一文为你彻底解惑
-
在当今微服务架构盛行、项目复杂度不断攀升的开发环境下,SpringBoot作为Java后端开发的主流框架,无疑是我们手中的得力武器。然而,当我们在享受其自动配置带来的便捷时,是否曾被配置类加载...
- Seata源码—6.Seata AT模式的数据源代理二
-
大纲1.Seata的Resource资源接口源码2.Seata数据源连接池代理的实现源码3.Client向Server发起注册RM的源码4.Client向Server注册RM时的交互源码5.数据源连接...
- 30分钟了解K8S(30分钟了解微积分)
-
微服务演进方向o面向分布式设计(Distribution):容器、微服务、API驱动的开发;o面向配置设计(Configuration):一个镜像,多个环境配置;o面向韧性设计(Resista...
- SpringBoot条件化配置(@Conditional)全面解析与实战指南
-
一、条件化配置基础概念1.1什么是条件化配置条件化配置是Spring框架提供的一种基于特定条件来决定是否注册Bean或加载配置的机制。在SpringBoot中,这一机制通过@Conditional...
- 一招解决所有依赖冲突(克服依赖)
-
背景介绍最近遇到了这样一个问题,我们有一个jar包common-tool,作为基础工具包,被各个项目在引用。突然某一天发现日志很多报错。一看是NoSuchMethodError,意思是Dis...
- 你读过Mybatis的源码?说说它用到了几种设计模式
-
学习设计模式时,很多人都有类似的困扰——明明概念背得滚瓜烂熟,一到写代码就完全想不起来怎么用。就像学了一堆游泳技巧,却从没下过水实践,很难真正掌握。其实理解一个知识点,就像看立体模型,单角度观察总...
- golang对接阿里云私有Bucket上传图片、授权访问图片
-
1、为什么要设置私有bucket公共读写:互联网上任何用户都可以对该Bucket内的文件进行访问,并且向该Bucket写入数据。这有可能造成您数据的外泄以及费用激增,若被人恶意写入违法信息还可...
- spring中的资源的加载(spring加载原理)
-
最近在网上看到有人问@ContextConfiguration("classpath:/bean.xml")中除了classpath这种还有其他的写法么,看他的意思是想从本地文件...
- Android资源使用(android资源文件)
-
Android资源管理机制在Android的开发中,需要使用到各式各样的资源,这些资源往往是一些静态资源,比如位图,颜色,布局定义,用户界面使用到的字符串,动画等。这些资源统统放在项目的res/独立子...
- 如何深度理解mybatis?(如何深度理解康乐服务质量管理的5个维度)
-
深度自定义mybatis回顾mybatis的操作的核心步骤编写核心类SqlSessionFacotryBuild进行解析配置文件深度分析解析SqlSessionFacotryBuild干的核心工作编写...
- @Autowired与@Resource原理知识点详解
-
springIOCAOP的不多做赘述了,说下IOC:SpringIOC解决的是对象管理和对象依赖的问题,IOC容器可以理解为一个对象工厂,我们都把该对象交给工厂,工厂管理这些对象的创建以及依赖关系...
- java的redis连接工具篇(java redis client)
-
在Java里,有不少用于连接Redis的工具,下面为你介绍一些主流的工具及其特点:JedisJedis是Redis官方推荐的Java连接工具,它提供了全面的Redis命令支持,且...
- 一周热门
- 最近发表
- 标签列表
-
- mybatiscollection (79)
- mqtt服务器 (88)
- keyerror (78)
- c#map (65)
- resize函数 (64)
- xftp6 (83)
- bt搜索 (75)
- c#var (76)
- mybatis大于等于 (64)
- xcode-select (66)
- mysql授权 (74)
- 下载测试 (70)
- linuxlink (65)
- pythonwget (67)
- androidinclude (65)
- logstashinput (65)
- hadoop端口 (65)
- vue阻止冒泡 (67)
- oracle时间戳转换日期 (64)
- jquery跨域 (68)
- php写入文件 (73)
- kafkatools (66)
- mysql导出数据库 (66)
- jquery鼠标移入移出 (71)
- 取小数点后两位的函数 (73)