基于Google云原生工程师的kubernetes最佳实践(二)

目录

二、应用部署篇

为deployment打上丰富的label,以便selecting

使用sidecar容器部署agent、proxy等组件

使用init container处理依赖关系,而不要用sidecar

镜像tag使用版本号,不要用latest或空tag

为pod设置readiness和liveness探针

不要给所有服务都使用LoadBalancer,使用ingress

为负载均衡或ingress分配静态IP

用service映射外部依赖服务

使用helm chart管理应用

将所有下游依赖视为不可靠的

微服务划分的粒度不要太细

使用service mesh如istio、linkerd管理微服务

考虑使用Paas平台简化应用管理

不要在生产环境任意使用nodeport

在生产环境给Namespace设置ResourceQuota

不要随便打开容器特权模式

限制emptydir容量

使用emptydir存储临时日志

使用service时尽量配置全域名

 Google云原生工程师最佳实践指南下载


二、应用部署

为deployment打上丰富的label,以便selecting


使用sidecar容器部署agent、proxy等组件

        在Kubernetes中,Sidecar容器用于增强或扩展主应用容器的功能,提供如日志记录、监控、安全性或数据同步等附加服务。Sidecar容器与主应用容器共享同一个Pod,从而能够访问相同的网络和存储资源​​。

        例如,使用Fluentd实现日志记录的Sidecar容器、使用Istio实现服务网格管理的Sidecard容器​


使用init container处理依赖关系,而不要用sidecar

        在需要处理依赖性或预初始化任务时,推荐使用Init容器。这样做的好处是,你可以确保在主应用容器开始运行之前所有必要的准备工作都已经完成。这有助于避免主应用容器因缺少必要的依赖或配置而启动失败


镜像tag使用版本号,不要用latest或空tag

        使用明确的标签能够提供关于镜像的更多信息,而不是仅仅使用latest,这样可以避免潜在的混淆和不可预测的行为。

为pod设置readiness和liveness探针

不要给所有服务都使用LoadBalancer,使用ingress

        虽然LoadBalancer提供了一种简便的方式来暴露服务,但在很多情况下,使用Ingress可能更为合适。Ingress特别适用于需要复杂路由、SSL终止或基于名称的虚拟托管的场景。通过使用Ingress,可以有效地管理流量路由规则,并减少公有云环境中的外部IP使用,从而降低成本

为负载均衡或ingress分配静态IP

        为负载均衡器或Ingress分配静态IP的原因在于确保服务的持续可访问性和稳定性。在默认情况下,当你在Kubernetes中创建LoadBalancer类型的服务时,分配给它的公共IP地址只在该资源的生命周期内有效。如果你删除了Kubernetes服务,关联的负载均衡器和IP地址也会被删除。因此,如果你想为重部署的Kubernetes服务分配特定的IP地址或保留一个IP地址,就需要创建并使用静态公共IP地址

        通过一个具体的例子来理解如何为Ingress-Nginx控制器分配静态IP。在这个例子中,创建一个负载均衡器服务,并配置Ingress控制器使用这个服务分配的静态IP。

第一步:创建负载均衡器服务

首先,你需要创建一个类型为LoadBalancer的服务,该服务将自动为Ingress-Nginx控制器分配一个静态IP。

apiVersion: v1
kind: Service
metadata:name: ingress-nginx-lb
spec:type: LoadBalancerports:- port: 80targetPort: 80protocol: TCP- port: 443targetPort: 443protocol: TCP

这个配置定义了一个名为 ingress-nginx-lb的服务,它将在端口80和443上监听传入的HTTP和HTTPS请求。

第二步:等待服务获取静态IP

一旦服务被创建,你需要等待几分钟,直到服务被分配一个外部IP地址。你可以通过运行以下命令来检查服务状态:

kubectl get svc ingress-nginx-lb

当服务获得一个外部IP地址后,你可以在输出中看到这个IP地址。

第三步:更新Ingress控制器配置

        接下来,你需要更新Ingress控制器的部署,以便它使用上一步中获得的静态IP地址。这通常通过在Ingress控制器的部署配置中添加--publish-service参数来实现,指向刚创建的负载均衡器服务。以下是更新Ingress控制器部署的示例:

apiVersion: apps/v1
kind: Deployment
metadata:name: ingress-nginx-controller
spec:replicas: 1template:spec:containers:- name: nginx-ingress-controllerimage: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.26.1args:- /nginx-ingress-controller- --publish-service=$(POD_NAMESPACE)/ingress-nginx-lb #指向刚创建的负载均衡器服务

在这个配置中,我们通过--publish-service参数指定了Ingress控制器应该使用ingress-nginx-lb服务的IP地址。

第四步:创建Ingress资源

创建Ingress资源,它将使用Ingress控制器和关联的静态IP地址来路由传入的流量。以下是一个基本的Ingress资源的示例YAML配置:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: example-ingress
spec:rules:- host: myapp.example.comhttp:paths:- path: /pathType: Prefixbackend:service:name: my-serviceport:number: 80

        这个Ingress资源配置了一个规则,将所有指向myapp.example.com域的HTTP请求路由到名为my-service`的服务。

        通过这个过程,Ingress-Nginx控制器将使用分配给负载均衡器服务的静态IP地址来处理传入的流量。这样可以确保Ingress的访问地址在服务更新或重部署时保持不变。

 官方参考链接:https://kubernetes.github.io/ingress-nginx/examples/static-ip/

用service映射外部依赖服务

        要在Kubernetes中访问外部的MySQL服务,你可以通过定义一个Endpoints资源和一个Service资源来实现。这样做可以让集群内的Pods通过Kubernetes的内部DNS解析和访问外部服务,就好像这个服务是集群内部的一样。

以下是如何定义这些资源的示例:

1. 定义Endpoints资源:
   这个资源指向外部MySQL服务的具体IP地址和端口。例如,如果外部MySQL服务的地址是192.168.1.100,端口是3306

Endpoints的定义如下所示:

   apiVersion: v1kind: Endpointsmetadata:name: mysql-externalsubsets:- addresses:- ip: 192.168.1.100ports:- port: 3306

2. 定义Service资源:
   这个资源定义了一个逻辑名称(在这个例子中是mysql-external),Pods可以通过这个名称找到对应的Endpoints并通过它访问外部的MySQL服务。

Service的定义如下所示:

   apiVersion: v1kind: Servicemetadata:name: mysql-external  #Service的名称必须和Endpoints的名称匹配spec:ports:- protocol: TCPport: 3306targetPort: 3306

        通过上述配置,集群内的Pods可以通过mysql-external这个名称来访问外部的MySQL服务,就像访问集群内部的服务一样。这种方式简化了外部资源的访问,并允许你在Kubernetes中对这些外部依赖进行抽象。

        请注意,因为这个Service没有选择器(selector),它不会自动与Endpoints关联。在这种情况下,Service的名称必须和Endpoints的名称匹配,这样Service才能正确地将流量转发到定义的外部IP和端口上


使用helm chart管理应用

将所有下游依赖视为不可靠的

        设计应用时,不应假设所有的下游依赖服务是可靠的。要为服务之间的通信建立重试、熔断、降级等保护机制,以降低级联故障的风险。


微服务划分的粒度不要太细

        拆分微服务时需要控制好粒度,过于细化会导致开发、部署和运维的复杂度剧增。应该以业务边界为基准,将密切相关的功能划分到同一个服务中。


使用service mesh如istio、linkerd管理微服务

        在微服务架构中,服务间的通信会变得更加复杂。使用Service Mesh可以提供一整套可靠的通信、监控、安全和流量管理功能。

        Istio和Linkerd是目前主流的Service Mesh方案。它们能自动在服务之间注入智能代理(Sidecar),拦截服务通信,并提供诸如流量控制、熔断、重试、​​金丝雀发布、安全加密等高级功能,而无需修改应用代码。

        使用Service Mesh可以显著降低微服务开发和运维的复杂性,提升整体系统的可观测性、弹性和安全性。


考虑使用Paas平台简化应用管理

        Kubernetes自身作为一个强大而灵活的容器编排平台,它的学习曲线较陡峭,需要一定的运维成本。可以考虑使用基于Kubernetes的PaaS(平台即服务)产品,如OpenShift、Kuboard、Rancher等,这些平台在Kubernetes之上提供了更高级别的抽象,集成了诸多开发者工具,能够显著简化应用的构建、部署、运维等生命周期管理。

不要在生产环境任意使用nodeport

NodePort类型的Service会在每个Node上开放一个端口(默认在30000-32768范围),将该端口映射到集群内的目标Pod。这种方式存在一些限制:

  • 端口范围有限制
  • 每个端口只能映射一个服务
  • 需要防火墙放行对应端口规则
  • 造成端口管理混乱的问题

因此在生产环境中,不建议滥用NodePort。更好的做法是使用Ingress Controller或者LoadBalancer等云负载均衡器,并结合Service的ClusterIP类型来暴露服务。

在生产环境给Namespace设置ResourceQuota

        Kubernetes的Namespace提供了一种对象隔离的机制。在生产环境中,我们往往会为不同的应用、团队或环境创建单独的Namespace。

        为了防止某个Namespace下的资源使用失控,影响整个集群的运行,最佳实践是为每个Namespace配置资源的使用Quota,包括限制Namespace下的CPU、内存、存储等资源总量,以及对单个资源对象的资源限制。

        这样能够实现多租户场景下的资源管控,保证资源的合理分配和隔离,提高集群的稳定性和可靠性。    

ResourceQuota Yaml

apiVersion: v1
kind: ResourceQuota
metadata:name: mem-cpu-demonamespace: quota-mem-cpu-example
spec:hard:requests.cpu: "1"requests.memory: 1Gilimits.cpu: "2"limits.memory: 2Gi

LimitRange和ResourceQuota区别:

1. 作用范围:

   - LimitRange:作用于单个命名空间。

   - ResourceQuota:也作用于单个命名空间,但它是一个更全面的限制。

2. 作用对象:

   - LimitRange:主要针对单个容器或Pod。

   - ResourceQuota:针对整个命名空间里的所有Pod和其他资源。

3. 类型:

   - LimitRange:设置CPU、内存等资源的最小、最大、默认值。

   - ResourceQuota:限制命名空间内可以使用的总资源量。

4. 功能:

   - LimitRange:确保容器使用资源在一定范围内。

   - ResourceQuota:确保命名空间不会超过分配的资源。

5. 例子:

   - LimitRange:Pod里的容器必须有512MB至2GB的内存。

   - ResourceQuota:整个命名空间最多可以有10个Pod,总计不超过10GB内存。

LimitRange是微观的,针对单个容器或Pod。ResourceQuota是宏观的,针对整个命名空间。两者通常一起使用,确保资源使用既高效又安全。

当LimitRange和ResourceQuota发生冲突时,ResourceQuota限制优先

不要随便打开容器特权模式

        在Kubernetes中,避免使用特权模式运行容器是一项重要的安全最佳实践。当容器以特权模式运行时,它拥有宿主机上几乎所有的权限,这与在宿主机上以root用户运行程序类似。这种高权限级别会带来显著的安全风险,因为它提供了足够的权限来执行许多可能危及整个宿主机的操作。

为什么要避免使用特权模式:

  1. 提升攻击面:特权容器具有访问宿主机资源的能力,包括访问硬件设备和操作系统级别的操作。如果攻击者成功利用运行在特权模式下的容器中的漏洞,他们可以获得对整个宿主机的控制。

  2. 违反最小权限原则:按照最小权限原则,应用和服务应仅被授予它们完成工作所必需的权限,而不是更多。特权模式违反了这一原则,因为它为容器提供了超出其实际需求的权限。

  3. 难以审计和追踪:以特权模式运行的容器可能会执行许多非标准的操作,这些操作可能难以通过Kubernetes的日志和监控工具来审计和追踪。

打开特权模式YAML

apiVersion: v1
kind: Pod
metadata:name: privileged-pod
spec:containers:- name: nginximage: nginxsecurityContext:privileged: true    #打开特权模式,极易造成安全逃逸

限制emptydir容量

sizeLimit字段仅作为Pod被驱逐的阈值,而不是硬性限制。这意味着,如果emptyDir使用的空间超过了sizeLimit,指定的大小,Kubernetes会触发Pod的驱逐机制,而不是阻止额外数据的写入

限制emptydir YAML

apiVersion: v1
kind: Pod
metadata:name: pod-with-emptydir
spec:containers:- name: nginximage: nginxvolumeMounts:- mountPath: /cachename: cache-volumevolumes:- name: cache-volumeemptyDir:sizeLimit: "128Mi" # 限制最大容量为128Mi

官网参考链接:

https://kubernetes.io/zh-cn/docs/concepts/storage/volumes/#emptydir-%E9%85%8D%E7%BD%AE%E7%A4%BA%E4%BE%8B

使用emptydir存储临时日志

        在Kubernetes中,使用emptyDir卷存储日志是一种常见的做法,尤其是在处理短暂的或临时的日志数据时。emptyDir是一个临时目录,它与Pod的生命周期相同,这意味着当Pod启动时创建,并在Pod终止时删除。即使Pod运行过程中容器重启多次,之前的应用运行日志仍存在与emptydir中。这种特性使得emptyDir成为存储容器运行期间产生的临时日志文件的理想选择。

使用service时尽量配置全域名

全域名格式:my-service.my-namespace.svc.cluster.local

查看pod的dns解析服务器地址

解释:

  • nameserver: 定义DNS服务器的IP,其实就是kube-dns那个service的IP

  • search:  定义域名的查找后缀规则,查找配置越多,说明域名解析查找匹配次数越多。集群匹配有 default.svc.cluster.local、svc.cluster.local、cluster.local 3个后缀,最多进行8次查询 (IPV4和IPV6查询各四次) 才能得到正确解析结果。不同命名空间,这个参数的值也不同。

  • option: 定义域名解析配置文件选项,支持多个KV值。例如该参数设置成ndots:5,说明如果访问的域名字符串内的点字符数量超过ndots值,则认为是完整域名,并被直接解析;如果不足ndots值,则追加search段后缀再进行查询。

对于Kubernetes集群内的DNS解析,使用更具体、更完整的域名通常会提供更好的性能

        这是因为使用完整域名可以减少DNS解析器需要尝试的搜索后缀(由search参数定义)的数量,从而减少解析时间。具体来说:

1. 完整域名:

        例如,svc-nacos.prod-namespace.svc.cluster.local。这是最具体的域名形式,它直接对应于特定的服务。使用这样的完整域名可以立即定位到目标,无需额外的搜索和尝试,因此这种方式是最高效的。

2. 部分域名:

        例如,svc-nacos.prod-namespace.svc 或 svc-nacos.prod-namespace。这些仍然是相对明确的域名,但它们需要DNS解析器根据 search列表中的后缀来进行一定程度的匹配尝试。虽然这种情况下的性能损失不大,但仍然不如直接使用完整域名。

3. 最短域名:

        例如,仅仅使用 svc-nacos。这种情况下,DNS解析器需要使用search列表中的所有后缀进行尝试,直到找到正确的地址。这会导致最多的DNS查询,因此是这三种情况中性能最低的。

   总结来说,为了获得最佳的性能,建议在Kubernetes集群内部进行通信时使用完整的域名。这样可以减少DNS查询次数,加快解析速度,从而提高整体的网络性能。

 Google云原生工程师最佳实践指南下载

Kubernetes_Best_Practices.pdficon-default.png?t=N7T8https://c74p900o8m.feishu.cn/docx/S84ddjQg2oQRpMxxOykcdP8Snsc

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/768281.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【微服务】以模块化单体架构开发微服务应用

目录 推荐超级课程: Docker快速入门到精通Kubernetes入门到大师通关课AWS云服务快速入门实战我们知道,起初,单体应用有显著的优势:它们更容易开发和部署。从开发人员的角度来看,这种简单性是有益的。一切都是集中的,可以快速更新任何部分的业务逻辑并立即看到结果。这种开…

竞赛 python opencv 深度学习 指纹识别算法实现

1 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 python opencv 深度学习 指纹识别算法实现 🥇学长这里给一个题目综合评分(每项满分5分) 难度系数:3分工作量:4分创新点:4分 该项目较为新颖…

ETL数据倾斜与资源优化

1.数据倾斜实例 数据倾斜在MapReduce编程模型中比较常见,由于key值分布不均,大量的相同key被存储分配到一个分区里,出现只有少量的机器在计算,其他机器等待的情况。主要分为JOIN数据倾斜和GROUP BY数据倾斜。 1.1GROUP BY数据倾…

【短接笔记本或者台式机的CMOS针脚解决电脑开机无法启动BIOS无法进入问题】

为什么要执行短接笔记本或者台式机的CMOS针脚操作? 问题:可以解决如下图所示,技嘉小雕主板开机时按delete键无法进入BIOS主板界面,长时间等待之后依然无法进入BIOS主板界面,则判定为主板问题。此时短接CMOS针脚可清空…

nodejs+vue高校工作室管理系统python-flask-django-php

系统根据现有的管理模块进行开发和扩展,采用面向对象的开发的思想和结构化的开发方法对高校工作室管理的现状进行系统调查。采用结构化的分析设计,该方法要求结合一定的图表,在模块化的基础上进行系统的开发工作。在设计中采用“自下而上”的…

python(django(自动化))之流程接口展示功能前端开发

1、创建模板代码如下&#xff1a; <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><title>测试平台</title> </head> <body role"document"> <nav class "navbar n…

Redis - list 列表

前言 列表类似于 Java 中的数组或者顺序表&#xff0c;在 Redis 中&#xff0c;可以对列表两端插⼊&#xff08;push&#xff09;和弹出&#xff08;pop&#xff09;&#xff0c;还可以获取指定范围的元素列表、 获取指定索引下标的元素等。列表是⼀种⽐较灵活的数据结构&#…

(一)基于IDEA的JAVA基础7

关系运算符 运算符 含义 范例 结果 等于 12 false &#xff01; 不等于 1&#xff01;2 true > 大于 1>2 false < 小于 …

微服务(基础篇-001-介绍、Eureka)

目录 认识微服务&#xff08;1&#xff09; 服务架构演变&#xff08;1.1&#xff09; 单体架构&#xff08;1.1.1&#xff09; 分布式架构&#xff08;1.1.2&#xff09; 微服务&#xff08;1.1.3&#xff09; 微服务结构 微服务技术对比 企业需求 SpringCloud(1.2) …

思科网络中DHCP中继的配置

一、什么是DHCP中继&#xff1f;DHCP中继有什么用? &#xff08;1&#xff09;DHCP中继是指一种网络设备或服务&#xff0c;用于在不同的子网之间传递DHCP&#xff08;动态主机配置协议&#xff09;消息。DHCP中继的作用是帮助客户端设备获取IP地址和其他网络配置信息&#x…

jvm底层

逐步细化 静态链接&#xff1a;静态方法(符号引用)替换为内存指针或者句柄直接引用) 动态链接&#xff1a;程序期间将符号引用替换为直接引用 对象头&#xff1a; 指针压缩&#xff1a; -XX:UseCompressedOops 开启指针压缩 减少内存消耗&#xff1b;大指针在主内存 缓存间移…

6.3 BP神经网络

在多层感知器被引入的同时&#xff0c;也引入了一个新的问题&#xff1a;由于隐藏层的预期输出并没有在训练样例中给出&#xff0c;隐藏层结点的误差无法像单层感知器那样直接计算得到。 为了解决这个问题&#xff0c;反向传播&#xff08;BP&#xff09;算法被引入&#xff0…

centos glibc 升级导致系统崩溃

centos 7.9默认的glibc为2.17&#xff0c;因为要安装一些软件&#xff0c;需要升级到glibc 2.18&#xff0c;而从源码进行编译和安装&#xff0c;安装失败&#xff0c;导致系统崩溃。 系统崩溃首先想到的是利用启动盘进行救援&#xff0c;而利用centos 7.9的启动盘始终无法挂载…

【PHP + 代码审计】数组排序算法

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【Java、PHP】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收…

银行监管报送系统介绍(五):金融统计数据大集中自动化报送系统——PBOC Report

人民银行金融统计数据大集中自动化报送系统&#xff08;简称PBOC Report&#xff09;&#xff0c;是基于现代计算机网络技术应用基础上&#xff0c;由人行总行设置金融统计数据服务器&#xff0c;建立的一个全国统一的金融统计数据库。 人行针对各银行存贷款、中间业务、网点人…

信号处理--基于FBCSP滤波方法的运动想象分类

目录 理论 工具 方法 代码获取 理论 通用空间模式 (CSP) 算法可以用来有效构建最佳空间滤波器区分&#xff0c;然后实现运动想象的数据中的脑电信号的区分。然而&#xff0c;空间滤波器性能的好坏主要取决于其工作频带。如果脑电信号没有经过滤波或者滤波的频带范围不合适…

FPGA使用XADC测量外部模拟输入电压

一、XADC简介 1.1、特性 Xilinx系列的FPGA中都包含了一个内置的XADC&#xff0c;我们可以通过这个XADC进行一些精度不高的外部模拟信号采样以及FPGA片内传感器信号采集。XADC的分辨率为12位&#xff0c;采样率为1MSPS。 1.2、结构框图 两片XADC&#xff0c;ADC A可用于片内…

SpringJPA 做分页条件查询

前言: 相信小伙伴们的项目很多都用到SpringJPA框架的吧,对于单表的增删改查利用jpa是很方便的,但是对于条件查询并且分页 是不是很多小伙伴不经常写到. 今天我整理了一下在这里分享一下. 话不多说直接上代码: Controller: RestController public class ProductInstanceContr…

Apache HTTP服务器(Linux离线编译安装)

Apache HTTP服务器&#xff08;Linux离线编译安装&#xff09; Apache是普通服务器&#xff0c;本身只支持html即普通网页。可以通过插件支持PHP,还可以与Tomcat连通(单向Apache连接Tomcat,就是说通过Apache可以访问Tomcat资源。反之不然)。 Apache和Tomcat都可以做为独立的w…

8个常见的数据可视化错误以及如何避免它们

在当今以数据驱动为主导的世界里&#xff0c;清晰且具有洞察力的数据可视化至关重要。然而&#xff0c;在创建数据可视化时很容易犯错误&#xff0c;这可能导致对数据的错误解读。本文将探讨一些常见的糟糕数据可视化示例&#xff0c;并提供如何避免这些错误的建议。 本文总结了…