作者:ikubernetes 2022-09-01 08:50:22
云计算
云原生 本文仅提供在kubernetes上部署安全、可扩展和弹性服务的可行性最佳实践。仅供参考。
本文仅提供在kubernetes上部署安全、可扩展和弹性服务的可行性最佳实践。仅供参考。
精选的最佳实践清单,旨在帮助您发布到生产环境。
就绪探测不包括对服务的依赖,例如:
参考链接:https://blog.colinbreck.com/kubernetes-liveness-and-readiness-probes-how-to-avoid-shooting-yourself-in-the-foot/#shootingyourselfinthefootwithreadinessprobes。
当应用程序启动时,它不应该因为数据库等依赖项尚未准备好而崩溃。
相反,应用程序应该不断重试连接到数据库,直到成功。
Kubernetes 期望应用程序组件可以以任何顺序启动。
当您确保您的应用程序可以重新连接到依赖项(例如数据库)时,您就知道您可以提供更强大和更有弹性的服务。
pod即使在收到终止信号后,可能也需要继续接受连接,直到所有的kube-proxy完成对iptables规则或ipvs规则的更新。
可能ingress-controller以及Loadblance也会将连接转发到POD。
为确保所有客户端都不会遇到断开连接,您必须等到所有客户端都以某种方式通知您他们将不再将连接转发到 pod。
但是显然,这是不可能的,因为所有这些组件都分布在许多不同的计算机上。如果有一个没有写响应,都会导致应用无法关闭。
一般情况下我们会配置一个预停止的hook:
lifecycle:
preStop:
exec:
command:
- sh
- c
- "sleep 5"
当pod即将终止时,可以通过在应用程序中捕获SIGTERM信号。可以使用tini。tini项目地址:https://github.com/krallin/tini。
如果调用应用程序没有关闭TCP连接;当pod被删除时;理想情况下,请求应该发送到另一个 Pod;但是,调用应用程序与即将终止的 Pod 建立了长期连接,并将继续使用它;不应该突然终止长期连接;您应该在关闭应用程序之前终止它们。
永远不要单独运行单个 Pod。
而是考虑将 Pod 部署为 Deployment、DaemonSet、ReplicaSet 或 StatefulSet 的一部分。
运行多个 Pod 实例可确保删除单个 Pod 不会导致停机。
考虑以下场景:单个集群节点上有 11 个副本。
如果节点不可用,则 11 个副本将丢失,并且您有停机时间。
您应该将反关联规则应用于您的部署,以便 Pod 分布在集群的所有节点中。
pod间亲和性和反亲和性文档描述了如何将 Pod 更改为位于(或不在)同一节点中。
设置 Pod 中断预算。
翻译过来就是配置POD干扰预算;通过设置应用 Pod 处于正常状态的最低个数或最低百分比,这样可以保证在主动销毁 Pod 的时候,不会销毁太多的 Pod 导致业务异常中断,从而提高业务的可用性。
参考链接:https://zhuanlan.zhihu.com/p/367827614。
官方文档是了解Pod Disruption Budgetshttps://kubernetes.io/docs/concepts/workloads/pods/disruptions/。
资源限制用于限制您的容器可以使用多少 CPU 和内存,并使用containerSpec 字段进行配置。
调度程序使用这些作为指标之一来决定哪个节点最适合当前 Pod。
没有做资源限制的容器调度优先级为0.即当发生OOM时,会先停掉此类容器。
由于 CPU 是一种可压缩资源,因此如果您的容器超出限制,则进程会受到限制。
请注意,如果您不确定正确的CPU 或内存限制应该是多少,您可以在 Kubernetes 中使用Vertical Pod Autoscaler并打开推荐模式。自动缩放器会分析您的应用并为其推荐限制。
除非您有计算密集型作业,否则建议将请求设置为 1 CPU 或以下。
如果您不确定应用程序的最佳设置是什么,最好不要设置 CPU 限制。
如果您想了解更多信息,本文将深入探讨 CPU 请求和限制。https://medium.com/@
betz.mark/understanding-resource-limits-in-kubernetes-cpu-time-9eff74d3161b。
如果您认为您可能忘记设置内存和 CPU 限制,您应该考虑使用 LimitRange 对象来定义部署在当前命名空间中的容器的标准大小。
LimitRange 的官方文档https://kubernetes.io/docs/concepts/policy/limit-range/。
当一个节点资源使用率过高时,kubernetes会尝试驱驱逐该节点中的一些pod。
kubernetes会根据定义的优先级以及Qos对pod进行排名和驱逐。
关于如何配置Qos可参考官方文档 :https://kubernetes.io/docs/tasks/configure-pod-container/quality-service-pod/。
下面是官方推荐的相关技术的标签:
官方文档:https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/。
示例:
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment
labels:
app.kubernetes.io/name: user-api
app.kubernetes.io/instance: user-api-5fa65d2
app.kubernetes.io/version: "42"
app.kubernetes.io/component: api
app.kubernetes.io/part-of: payment-gateway
app.kubernetes.io/managed-by: kubectl
spec:
replicas: 3
selector:
matchLabels:
application: my-app
template:
metadata:
labels:
app.kubernetes.io/name: user-api
app.kubernetes.io/instance: user-api-5fa65d2
app.kubernetes.io/version: "42"
app.kubernetes.io/component: api
app.kubernetes.io/part-of: payment-gateway
spec:
containers:
- name: app
image: myapp
您可以使用以下标签标记您的 Pod:
示例:
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment
labels:
owner: payment-team
project: fraud-detection
business-unit: "80432"
spec:
replicas: 3
selector:
matchLabels:
application: my-app
template:
metadata:
labels:
owner: payment-team
project: fraud-detection
business-unit: "80432"
spec:
containers:
- name: app
image: myapp
您可以使用以下标签标记您的 Pod:
示例:
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment
labels:
confidentiality: official
compliance: pci
spec:
replicas: 3
selector:
matchLabels:
application: my-app
template:
metadata:
labels:
confidentiality: official
compliance: pci
spec:
containers:
- name: app
image: myapp
有两种日志记录策略:passive(被动) 和 active(主动)。
使用被动策略的应用程序将日志消息记录到标准输出。
此最佳实践是十二因素应用程序的一部分。
在主动日志记录中,应用程序与中间聚合器建立网络连接,将数据发送到第三方日志记录服务,或直接写入数据库或索引。
主动日志记录被认为是一种反模式,应该避免。
如果您希望将日志转换应用于具有非标准日志事件模型的应用程序,您可能需要使用边车容器。
使用 sidecar 容器,您可以在将日志条目发送到其他地方之前对其进行规范化。
例如,您可能希望在将 Apache 日志传送到日志基础设施之前将其转换为 Logstash JSON 格式。
但是,如果您可以控制应用程序,则可以首先输出正确的格式。
您可以节省为集群中的每个 Pod 运行一个额外的容器。
容器有一个本地文件系统,你可能会想用它来持久化数据。
但是,将持久数据存储在容器的本地文件系统中会阻止包含的 Pod 水平扩展(即,通过添加或删除 Pod 的副本)。
这是因为,通过使用本地文件系统,每个容器都维护自己的“状态”,这意味着 Pod 副本的状态可能会随着时间的推移而发散。这会导致从用户的角度来看不一致的行为(例如,当请求命中一个 Pod 时,一条特定的用户信息可用,但当请求命中另一个 Pod 时则不可用)。
相反,任何持久性信息都应该保存在 Pod 之外的中心位置。例如,在集群中的一个 PersistentVolume 中,甚至在集群外的一些存储服务中更好。
Horizontal Pod Autoscaler (HPA)是一个内置的 Kubernetes 功能,可以监控您的应用程序并根据当前使用情况自动添加或删除 Pod 副本。
配置 HPA 可让您的应用在任何流量条件下(包括意外高峰)保持可用和响应。
要将 HPA 配置为自动缩放您的应用程序,您必须创建一个HorizontalPodAutoscaler资源,该资源定义了要为您的应用程序监控的指标。
HPA 可以监控内置资源指标(Pod 的 CPU 和内存使用情况)或自定义指标。在自定义指标的情况下,您还负责收集和公开这些指标,例如,您可以使用Prometheus和Prometheus Adapter来做到这一点。
与Horizontal Pod Autoscaler (HPA)类似, Vertical Pod Autoscaler (VPA)也存在。
VPA 可以自动适应你 Pod 的资源请求和限制,这样当一个 Pod 需要更多资源时,它可以得到它们(增加/减少单个 Pod 的资源称为垂直扩展,而不是水平扩展,这意味着增加/减少 Pod 的副本数)。
这对于扩展无法水平扩展的应用程序很有用。
然而,VPA 目前处于 beta 阶段,它有一些已知的限制(例如,通过改变 Pod 的资源需求来扩展 Pod,需要杀死并重新启动 Pod)。
鉴于这些限制,以及 Kubernetes 上的大多数应用程序无论如何都可以水平扩展的事实,建议不要在生产中使用 VPA(至少在有稳定版本之前)。
Cluster Autoscaler是另一种类型的“autoscaler”(除了Horizo ntal Pod Autoscaler和Vertical Pod Autoscaler)。
Cluster Autoscaler 可以通过添加或删除工作节点来自动扩展集群的大小。
当 Pod 由于现有工作节点上的资源不足而无法调度时,就会发生扩展操作。在这种情况下,Cluster Autoscaler 会创建一个新的工作节点,以便 Pod 可以被调度。同样,当现有工作节点的利用率较低时,集群自动缩放器可以通过从一个工作节点中逐出所有工作负载并将其移除来缩减规模。
使用 Cluster Autoscaler 对于高度可变的工作负载是有意义的,例如,当 Pod 的数量可能在短时间内增加,然后又回到之前的值时。在这种情况下,Cluster Autoscaler 允许您通过过度配置工作节点来满足需求高峰,而不会浪费资源。
但是,如果您的工作负载变化不大,则可能不值得设置 Cluster Autoscaler,因为它可能永远不会被触发。如果您的工作负载增长缓慢且单调,那么监控现有工作节点的利用率并在达到临界值时手动添加一个额外的工作节点可能就足够了。
配置应在应用程序代码之外维护。
这有几个好处。首先,更改配置不需要重新编译应用程序。其次,可以在应用程序运行时更新配置。第三,相同的代码可以在不同的环境中使用。
在 Kubernetes 中,可以将配置保存在 ConfigMaps 中,然后可以将其挂载到容器中,因为卷作为环境变量传入。
在 ConfigMaps 中仅保存非敏感配置。对于敏感信息(例如凭证),请使用 Secret 资源。
Secret 资源的内容应该作为卷挂载到容器中,而不是作为环境变量传入。
这是为了防止秘密值出现在用于启动容器的命令中,这可能会被不应访问秘密值的个人查看到。
没有限制的容器可能会导致与其他容器的资源争用和计算资源的未优化消耗。
Kubernetes 有两个限制资源使用的特性:ResourceQuota 和 LimitRange。
使用 LimitRange 对象,您可以定义资源请求的默认值和命名空间内单个容器的限制。
在该命名空间内创建的任何容器,没有明确指定请求和限制值,都会被分配默认值。
资源配额,您应该查看官方文档。https://kubernetes.io/docs/concepts/policy/resource-quotas/。
使用 ResourceQuotas,您可以限制命名空间内所有容器的总资源消耗。
为命名空间定义资源配额会限制属于该命名空间的所有容器可以使用的 CPU、内存或存储资源的总量。
您还可以为其他 Kubernetes 对象设置配额,例如当前命名空间中的 Pod 数量。
如果您认为有人可以利用您的集群并创建 20000 个 ConfigMap,那么使用 LimitRange 可以防止这种情况发生。
可以使用 Kubernetes Pod 安全策略来限制:
参考Kubernetes Pod安全策略最佳实战https://www.mend.io/resources/blog/kubernetes-pod-security-policy/。
在 Pod 中,容器可以在“特权”模式下运行,并且几乎可以不受限制地访问主机系统上的资源。
虽然在某些特定用例中需要此级别的访问权限,但总的来说,让您的容器执行此操作会带来安全风险。
特权 Pod 的有效用例包括使用节点上的硬件,例如 GPU。
您可以从本文中了解有关安全上下文和权限容器的更多信息 :https://kubernetes.io/docs/tasks/configure-pod-container/security-context/。
在容器中运行只读文件系统会强制容器不可变。
这不仅可以减轻一些旧的(和有风险的)做法,例如热补丁,还可以帮助您防止恶意进程在容器内存储或操作数据的风险。
使用只读文件系统运行容器可能听起来很简单,但它可能会带来一些复杂性。
如果您需要在临时文件夹中写入日志或存储文件怎么办?
您可以在本文中了解有关在生产环境中安全运行容器的权衡取舍: https://medium.com/@
axbaretto/running-docker-containers-securely-in-production-98b8104ef68。
在容器中运行的进程与主机上的任何其他进程没有什么不同,只是它有一小段元数据声明它在容器中。
因此,容器中的 root 与主机上的 root (uid 0) 相同。
如果用户设法突破在容器中以 root 身份运行的应用程序,他们可能能够获得对具有相同 root 用户的主机的访问权限。
将容器配置为使用非特权用户,是防止提权攻击的最佳方法。
如果您想了解更多信息,以下文章提供了一些详细说明示例,说明当您以 root 身份运行容器时会发生什么 :ttps://medium.com/@
mccode/processes-in-containers-should-not-run-as-root-2feae3f0df3b。
Linux 功能使进程能够执行默认情况下只有 root 用户才能执行的许多特权操作。
例如,CAP_CHOWN允许进程“对文件 UID 和 GID 进行任意更改”。
即使您的进程不以 身份运行root,进程也有可能通过提升权限来使用这些类似 root 的功能。
换句话说,如果您不想受到损害,您应该只启用您需要的功能。
但是应该启用哪些功能,为什么?
以下两篇文章深入探讨了有关 Linux 内核功能的理论和实践最佳实践:
您应该在关闭权限提升的情况下运行容器,以防止使用setuid或setgid二进制文件提升权限。
集群中的恶意用户要获得对集群的访问权限——他们可以向整个集群发出请求。
为了解决这个问题,您可以使用网络策略定义如何允许 Pod 在当前命名空间和跨命名空间中进行通信。
Kubernetes 网络策略指定 Pod 组的访问权限,就像云中的安全组用于控制对 VM 实例的访问一样。
换句话说,它在 Kubernetes 集群上运行的 Pod 之间创建了防火墙。
Kubernetes 集群网络 :https://ahmet.im/blog/kubernetes-network-policy/。
如果想深入了解如何丢弃/限制运行在 Kubernetes 上的应用程序的流量,请查看此文档。https://github.com/ahmetb/kubernetes-network-policy-recipes。
请注意,默认的 ServiceAccount 会自动挂载到所有 Pod 的文件系统中。
您可能希望禁用它并提供更精细的策略。
很难找到关于如何设置 RBAC 规则的好建议。在Kubernetes RBAC 的 3 种实际方法中,您可以找到三个实际场景和有关如何开始的实用建议。
实际场景参考文档:https://thenewstack.io/three-realistic-approaches-to-kubernetes-rbac/。
有一个简明的策略来定义角色和 ServiceAccounts。
首先,他们描述了他们的要求:
这四个要求转化为五个单独的角色:
您可以在此链接中了解他们的定义:https://kubernetes-on-aws.readthedocs.io/en/latest/dev-guide/arch/access-control/adr-004-roles-and-service-accounts.html。
互联网安全中心为保护您的代码的最佳实践提供了一些指南和基准测试。
他们还维护了kubernetes的基准;官网地址:https://www.cisecurity.org/benchmark/kubernetes。
虽然您可以阅读冗长的指南并手动检查您的集群是否合规,但更简单的方法是下载并执行kube-bench.
下载地址:https://github.com/aquasecurity/kube-bench。
kube-bench是一种工具,旨在自动化 CIS Kubernetes 基准测试并报告集群中的错误配置。
示例输出:
[INFO] 1 Master Node Security Configuration
[INFO] 1.1 API Server
[WARN] 1.1.1 Ensure that the --anonymous-auth argument is set to false (Not Scored)
[PASS] 1.1.2 Ensure that the --basic-auth-file argument is not set (Scored)
[PASS] 1.1.3 Ensure that the --insecure-allow-any-token argument is not set (Not Scored)
[PASS] 1.1.4 Ensure that the --kubelet-https argument is set to true (Scored)
[PASS] 1.1.5 Ensure that the --insecure-bind-address argument is not set (Scored)
[PASS] 1.1.6 Ensure that the --insecure-port argument is set to 0 (Scored)
[PASS] 1.1.7 Ensure that the --secure-port argument is not set to 0 (Scored)
[FAIL] 1.1.8 Ensure that the --profiling argument is set to false (Scored)
当master由云厂商托管的话,可能无法使用kube-bench。
Alpha 和 beta Kubernetes 功能正在积极开发中,可能存在导致安全漏洞的限制或错误。
始终评估 Alpha 或 Beta 功能可能提供的价值,以应对您的安全状况可能面临的风险。
Kubernetes 支持各种身份验证方法,包括 OpenID Connect (OIDC)。
OpenID Connect 允许单点登录 (SSO)(例如您的 Google 身份)连接到 Kubernetes 集群和其他开发工具。
您无需单独记住或管理凭据。
您可以将多个集群连接到同一个 OpenID 提供程序。
有关 Kubernetes 中的 OpenID 连接的更多信息。 可以访问:https://thenewstack.io/kubernetes-single-sign-one-less-identity/
服务帐户令牌不应用于尝试与 Kubernetes 集群交互的最终用户,但它们是在 Kubernetes 上运行的应用程序和工作负载的首选身份验证策略。
您应该保留 30-45 天的历史日志。
从哪些方面收集日志:
你应该收集什么:
应用程序应该记录到标准输出而不是文件。
每个节点上的守护进程可以从容器运行时收集日志(如果记录到文件,可能需要每个 pod 的 sidecar 容器)。
参考地址:https://rclayton.silvrback.com/container-services-logging-with-docker#effective-logging-infrastructure。
使用日志聚合工具,例如 EFK stack(Elasticsearch、Fluentd、Kibana)、DataDog、Sumo Logic、Sysdig、GCP Stackdriver、Azure Monitor、AWS CloudWatch。
网站标题:kubernetes生产环境优秀实践
地址分享:http://www.shufengxianlan.com/qtweb/news29/327079.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联