10个Kubernetes最佳实践,以实现更好的容器编排
让我们谈谈在使用Kubernetes时应该遵循的一些最佳实践。
Kubernetes是一个开源的容器编排平台,它自动化了容器部署、持续扩展和缩减、容器负载均衡等等。
由于容器化在许多具有数千个容器的生产服务器上使用,因此很重要对其进行良好的管理,这就是Kubernetes的作用。
如果您正在使用Kubernetes,您必须采用最佳实践来实现更好的容器编排。
以下是您必须遵循的一些Kubernetes最佳实践的列表。
#1. 设置资源请求和限制
当您在具有有限资源的生产集群上部署一个大型应用程序时,如果节点的内存或CPU用完,应用程序将停止工作。应用程序的停机时间可能对业务产生巨大影响。但是您可以通过设置资源请求和限制来解决此问题。
在Kubernetes中,资源的请求和限制是控制内存和CPU等资源使用的机制。如果一个pod使用了全部的CPU和内存,其他pod将无法获得资源并无法运行应用程序。因此,您需要在Pod上设置资源请求和限制以提高可靠性。
只是提供一些信息,限制将始终高于请求。如果请求大于定义的限制,容器将无法运行。您可以为Pod中的每个容器设置请求和限制。CPU使用以毫核心为单位,内存使用以字节(兆字节/兆字节)为单位。
下面是设置限制为500毫核心CPU和128兆字节,以及设置请求配额为300毫核心CPU和64兆字节的示例。
containers:
- name: prodcontainer1
image: ubuntu
resources:
requests:
memory: “64Mi”
cpu: “300m”
limits:
memory: “128Mi”
cpu: “500m”
#2. 使用livenessProbe和readinessProbe
在Kubernetes中,健康检查非常重要。
它提供了两种类型的健康检查 – 就绪性探测和活跃性探测。
就绪性探测用于检查应用程序是否准备好开始提供流量。在Kubernetes中,在将流量发送到运行应用程序的容器内的pod之前,必须通过此探测来检查就绪性。如果就绪性健康检查失败,Kubernetes将停止向pod发送流量。
活跃性探测用于检查应用程序是否仍在运行(活动)或已停止(停止)。如果应用程序正常运行,Kubernetes不会采取任何操作。如果应用程序不可用,Kubernetes将启动一个新的pod并在其中运行应用程序。
如果这些检查没有正确执行,pod可能会被终止,或者甚至在准备就绪之前就开始接收用户请求。
可以使用三种类型的探测进行活跃性和就绪性检查 – HTTP、Command和TCP。
让我展示一个最常见的HTTP探测的示例。
在这里,您的应用程序将在其中运行一个HTTP服务器。当Kubernetes对HTTP服务器发出路径请求并获得HTTP响应时,它将标记应用程序为健康或不健康。
apiVersion: v1 kind: Pod metadata: name: container10 spec: containers: - image: ubuntu name: container10 livenessProbe: httpGet: path: /prodhealth port: 8080
#3. 构建小型容器镜像
优先使用较小的容器映像,因为它所需的存储空间较少,您将能够更快地拉取和构建映像。由于映像的大小较小,安全攻击的几率也较小。
减小容器大小的两种方法是使用较小的基本映像和构建者模式。目前,最新的NodeJS基本映像为345 MB,而NodeJS Alpine映像仅为28 MB,是大小的十倍以上。因此,始终使用较小的映像,并添加运行应用程序所需的依赖项。
为了使容器映像更小,可以使用构建者模式。代码在第一个容器中构建,然后将编译代码打包到最终容器中,而不需要制作编译代码所需的所有编译器和工具,从而使容器映像更小。
#4. 授予适当的访问权限(RBAC)
拥有安全的Kubernetes集群非常重要。
对集群的访问权限应该进行良好的配置。您必须定义每个用户每秒/分钟/小时的请求数量,允许每个IP地址的并发会话数,请求大小以及路径和主机名的限制。这将有助于使集群免受DDoS attacks的安全威胁。
在Kubernetes集群上工作的开发人员和DevOps工程师应具有明确定义的访问级别。Kubernetes的基于角色的访问控制(RBAC)功能在这里非常有用。您可以使用角色和集群角色来定义访问配置文件。为了简化配置RBAC,您可以使用开源的rbac-managers来帮助您简化语法,或者使用Rancher,它提供了默认的RBAC。
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cluster-role
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]
Kubernetes Secrets存储机密信息,例如身份验证令牌、密码和SSH密钥。您不应该在IaC代码库上检查Kubernetes Secrets,否则它将暴露给那些可以访问您的git代码库的人。
DevSecOps现在是一个关于DevOps和安全性的流行词。组织正在采纳这一趋势,因为他们理解其重要性。
#5. 保持最新
建议始终在集群上安装最新版本的Kubernetes。
最新版本的Kubernetes包括新功能、先前功能的更新、安全更新、错误修复等。如果您正在使用与云提供商一起的Kubernetes,则更新变得非常容易。
#6. 使用命名空间
Kubernetes提供了三个不同的命名空间 – default,kube-system和kube-public。
这些命名空间在Kubernetes集群中对于团队之间的组织和安全性起着非常重要的作用。
如果您是一个只有5-10个微服务的小团队,那么使用默认命名空间是有意义的。但是,一个快速增长的团队或一个大型组织将有几个团队在测试或生产环境中工作,因此每个团队都需要一个单独的命名空间以便更容易管理。
如果他们不这样做,他们可能会无意中覆盖或干扰另一个团队的应用程序/功能,而甚至没有意识到。建议创建多个命名空间并使用它们将服务分成可管理的块。
以下是在命名空间中创建资源的示例:
apiVersion: v1
kind: Pod
metadata:
name: pod01
namespace: prod
labels:
image: pod01
spec:
containers:
- name: prod01
image: ubuntu
#7. 使用标签
随着您的Kubernetes部署规模的扩大,它们必然会包含多个服务、Pod和其他资源。跟踪这些资源可能会变得繁琐。更具挑战性的是描述Kubernetes如何使这些不同资源相互交互,以及如何复制、扩展和提供服务。Kubernetes中的标签在解决这些问题上非常有帮助。
标签是用于组织Kubernetes界面中的项目的键值对。
例如,app: kube-app,phase: test,role: front-end。它们用于描述Kubernetes中群集中的各种对象和资源如何协同工作。
apiVersion: v1
kind: Pod
metadata:
name: test-pod
labels:
environment: testing
team: test01
spec:
containers:
- name: test01
image: "Ubuntu"
resources:
limits:
cpu: 1
因此,您可以通过始终为资源和对象打上标签来减少Kubernetes生产的痛苦。
#8. 审计日志
为了识别Kubernetes群集中的威胁,审计日志非常重要。审计有助于回答诸如发生了什么、为什么发生、谁造成的等问题。
与kube-apiserver发出的请求相关的所有数据都存储在名为audit.log
的日志文件中。此日志文件以JSON格式结构化。
在Kubernetes中,默认情况下,审计日志存储在/var/log/audit.log
中,审计策略位于/etc/kubernetes/audit-policy.yaml
中。
要启用审计日志记录,请使用以下参数启动kube-apiserver:
--audit-policy-file=/etc/kubernetes/audit-policy.yaml --audit-log-path=/var/log/audit.log
下面是一个配置用于记录Pod中的更改的示例audit.log
文件:
apiVersion: audit.k8s.io/v1
kind: Policy
omitStages:
- "RequestReceived"
rules:
- level: RequestResponse
resources:
- group: ""
resources: ["pods"]
- level: Metadata
resources:
- group: ""
resources: ["pods/log", "pods/status"]
在Kubernetes群集中出现任何问题时,您可以随时查看审计日志,它将帮助您恢复群集的正确状态。
#9. 应用亲和规则(节点/Pod)
Kubernetes中有两种将Pod与节点关联的机制- Pod亲和性和节点亲和性。建议使用这些机制以获得更好的性能。
使用节点亲和性,您可以根据定义的条件在节点上安排Pod。根据Pod的要求,选择匹配的节点并将其分配给Kubernetes群集中的Pod。
apiVersion: v1
kind: Pod
metadata:
name: ubuntu
spec:
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 2
preference:
matchExpressions:
- key: disktype
operator: In
values:
- ssd
containers:
- name: ubuntu
image: ubuntu
imagePullPolicy: IfNotPresent
使用Pod亲和性,您可以将多个Pod安排在同一个节点上(以提高延迟)或决定将Pod保留在不同节点上(以提高高可用性)以增加性能。
apiVersion: v1
kind: Pod
metadata:
name: ubuntu-pod
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: security
operator: In
values:
- S1
topologyKey: failure-domain.beta.kubernetes.io/zone
containers:
- name: ubuntu-pod
image: ubuntu
在分析群集的工作负载后,您需要决定使用哪种亲和性策略。
#10. Kubernetes终止
Kubernetes在不再需要时终止pod。您可以通过命令或API调用来启动它,所选的pod进入终止状态,不会将流量发送到这些pod。然后,向这些pod发送SIGTERM消息,随后这些pod关闭。
pod以优雅的方式终止,默认的优雅期为30秒。如果pod仍在运行,Kubernetes会发送SIGKILL消息,强制关闭pod。最后,Kubernetes会从主机上的API服务器中删除这些pod。
如果您的pod始终需要超过30秒,可以将此优雅期增加到45或60秒。
apiVersion: v1
kind: Pod
metadata:
name: container10
spec:
containers:
- image: ubuntu
name: container10
terminationGracePeriodSeconds: 60
结论
希望这些最佳实践能帮助您更好地使用Kubernetes。请尝试在您的Kubernetes集群中实施这些实践以获得更好的结果。
接下来,请探索DevOps成功的最佳实践。