Edit This Page

在 Kubernetes 集群中使用 sysctl

FEATURE STATE: Kubernetes v1.11 feature-state-beta.txt
この機能は、現在 beta版 です。

  • バージョン名には beta がつきます(例:v2beta3)。
  • コードが十分にテストされているため、この機能は安全に有効化できます。デフォルトでも有効化されています。
  • 今後も継続して、この機能は包括的にサポートされる見通しですが、細かい部分が変更になる場合があります。
  • 今後のbeta版または安定版のリリースにおいては、オブジェクトのデータの形式や意味の両方あるいはいずれかについて、互換性のない変更が入る場合があります。その際は、次期バージョンへの移行手順も提供します。その移行にあたっては、APIオブジェクトの削除・改変・再作成が必要になる場合があります。特に改変には、多少の検討が必要になることがあります。また、それを適用する際には、この機能に依存するアプリケーションの一時停止が必要になる場合があります。
  • 今後のリリースにおいて互換性のない変更が入る可能性があります。そのため、業務用途外の検証としてのみ利用が推奨されています。ただし、個別にアップグレード可能な環境が複数ある場合は、この制限事項の限りではありません。
  • beta版の機能の積極的な試用とフィードバックにご協力をお願いします!一度beta版から安定版になると、それ以降は変更を加えることが困難になります。 

本文档介绍如何通过 sysctl 接口在 Kubernetes 集群中配置和使用内核参数。

准备开始

You need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster. If you do not already have a cluster, you can create one by using Minikube, or you can use one of these Kubernetes playgrounds:

To check the version, enter kubectl version.

获取 Sysctl 的参数列表

在 Linux 中,管理员可以通过 sysctl 接口修改内核运行时的参数。在 /proc/sys/ 虚拟文件系统下存放许多内核参数。这些参数涉及了多个内核子系统,如:

若要获取完整的参数列表,请执行以下命令

$ sudo sysctl -a

启用非安全的 Sysctl 参数

sysctl 参数分为 安全 和 _非安全的_。安全 sysctl 参数除了需要设置恰当的命名空间外,在同一 node 上的不同 Pod 之间也必须是 _相互隔离的_。这意味着在 Pod 上设置 安全 sysctl 参数

至今为止,大多数 有命名空间的 sysctl 参数不一定被认为是 安全 的。以下几种 sysctl 参数是 _安全的_:

Note:

注意: 示例中的 net.ipv4.tcp_syncookies 在Linux 内核 4.4 或更低的版本中是无命名空间的。

在未来的 Kubernetes 版本中,若kubelet 支持更好的隔离机制,则上述列表中将会列出更多 安全的 sysctl 参数。

所有 安全的 sysctl 参数都默认启用。

所有 非安全的 sysctl 参数都默认禁用,且必须由集群管理员在每个节点上手动开启。那些设置了不安全 sysctl 参数的 Pod 仍会被调度,但无法正常启动。

参考上述警告,集群管理员只有在一些非常特殊的情况下(如:高可用或实时应用调整),才可以启用特定的 非安全的 sysctl 参数。如需启用 非安全的 sysctl 参数,请您在每个节点上分别设置 kubelet 命令行参数,例如:

$ kubelet --allowed-unsafe-sysctls \
  'kernel.msg*,net.ipv4.route.min_pmtu' ...

如果您使用 minikube,可以通过 extra-config 参数来配置:

$ minikube start --extra-config="kubelet.AllowedUnsafeSysctls=kernel.msg*,net.ipv4.route.min_pmtu"...

只有 有命名空间的 sysctl 参数可以通过该方式启用。

设置 Pod 的 Sysctl 参数

目前,在 Linux 内核中,有许多的 sysctl 参数都是 有命名空间的 。 这就意味着可以为节点上的每个 Pod 分别去设置它们的 sysctl 参数。 在 Kubernetes 中,只有那些有命名空间的 sysctl 参数可以通过 Pod 的 securityContext 对其进行配置。

以下列出有命名空间的 sysctl 参数,在未来的 Linux 内核版本中,此列表可能会发生变化。

没有命名空间的 sysctl 参数称为 节点级别的 sysctl 参数。 如果需要对其进行设置,则必须在每个节点的操作系统上手动地去配置它们,或者通过在 DaemonSet 中运行特权模式容器来配置。

可使用 pod 的 securityContext 来配置有命名空间的 sysctl 参数,securityContext 应用于同一个 pod 中的所有容器。

此示例中,使用 Pod SecurityContext 来对一个安全的 sysctl 参数 kernel.shm_rmid_forced 以及两个非安全的 sysctl 参数 net.ipv4.route.min_pmtukernel.msgmax 进行设置。在 Pod 规格中对 安全的非安全的 sysctl 参数不做区分。

Warning:

为了避免破坏操作系统的稳定性,请您在了解变更后果之后再修改 sysctl 参数。

apiVersion: v1
kind: Pod
metadata:
  name: sysctl-example
spec:
  securityContext:
    sysctls:
    - name: kernel.shm_rmid_forced
      value: "0"
    - name: net.ipv4.route.min_pmtu
      value: "552"
    - name: kernel.msgmax
      value: "65536"
  ...
Warning:

警告:由于 非安全的 sysctl 参数其本身具有不稳定性,在使用 非安全的 sysctl 参数时可能会导致一些严重问题,如容器的错误行为、机器资源不足或节点被完全破坏,用户需自行承担风险。

最佳实践方案是将集群中具有特殊 sysctl 设置的节点视为 _受感染的_,并且只调度需要使用到特殊 sysctl 设置的 Pod 到这些节点上。 建议使用 Kubernetes 的 taints 和 toleration 特性 来实现它。

设置了 非安全的 sysctl 参数的 pod,在禁用了以下两种 非安全的 sysctl 参数配置的节点上启动都会失败。与 节点级别的 sysctl 一样,建议开启 taints 和 toleration 特性taints on nodes 以便将 Pod 调度到正确的节点之上。

PodSecurityPolicy

您可以通过在 PodSecurityPolicy 的 forbiddenSysctls 和/或 allowedUnsafeSysctls 字段中,指定 sysctl 或填写 sysctl 匹配模式来进一步为 Pod 设置 sysctl 参数。sysctl 参数匹配模式以 * 字符结尾,如 kernel.*。 单独的 * 字符匹配所有 sysctl 参数。

所有 安全的 sysctl 参数都默认启用。

forbiddenSysctlsallowedUnsafeSysctls 的值都是字符串列表类型,可以添加 sysctl 参数名称,也可以添加 sysctl 参数匹配模式(以*结尾)。 只填写 * 则匹配所有的 sysctl 参数。

forbiddenSysctls 字段用于禁用特定的 sysctl 参数。 您可以在列表中禁用安全和非安全的 sysctl 参数的组合。 要禁用所有的 sysctl 参数,请设置为 *

如果要在 allowedUnsafeSysctls 字段中指定一个非安全的 sysctl 参数,并且它在forbiddenSysctls 字段中未被禁用,则可以在 Pod 中通过 PodSecurityPolicy 启用该 sysctl 参数。 若要在 PodSecurityPolicy 中开启所有非安全的 sysctl 参数,请设 allowedUnsafeSysctls 字段值为 *

allowedUnsafeSysctlsforbiddenSysctls 两字段的配置不能重叠,否则这就意味着存在某个 sysctl 参数既被启用又被禁用。

Warning:

警告:如果您通过 PodSecurityPolicy 中的 allowedUnsafeSysctls 字段将非安全的 sysctl 参数列入白名单,但该 sysctl 参数未通过 kubelet 命令行参数 --allowed-unsafe-sysctls 在节点上将其列入白名单,则设置了这个 sysctl 参数的 Pod 将会启动失败。

以下示例设置启用了以 kernel.msg 为前缀的非安全的 sysctl 参数,以及禁用了 sysctl 参数 kernel.shm_rmid_forced

apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: sysctl-psp
spec:
  allowedUnsafeSysctls:
  - kernel.msg*
  forbiddenSysctls:
  - kernel.shm_rmid_forced
 ...

反馈