$ sudo sysctl -a
Sysctl 设置通过 Kubernetes 公开,允许用户在运行时修改某些内核参数。只有命名空间的 sysctls 才能在 Pod 上独立设置。如果 sysctl 不是命名空间的,称为节点级,则必须使用其他方法设置 sysctl,例如使用节点调优操作符。
网络 sysctls 是 sysctl 的一个特殊类别。网络 sysctls 包括:
系统范围的 sysctls,例如net.ipv4.ip_local_port_range
,对所有网络有效。您可以为节点上的每个 Pod 独立设置这些 sysctls。
接口特定的 sysctls,例如net.ipv4.conf.IFNAME.accept_local
,仅适用于给定 Pod 的特定附加网络接口。您可以为每个附加网络配置独立设置这些 sysctls。您可以使用tuning-cni
中的配置在创建网络接口后设置这些 sysctls。
此外,默认情况下,只有那些被认为是安全的 sysctls 才是白名单;您可以手动启用节点上其他不安全的 sysctls 以供用户使用。
如果您正在设置 sysctl 且它不是节点级的,您可以在使用节点调优操作符部分中找到此过程的信息。
在 Linux 中,sysctl 接口允许管理员在运行时修改内核参数。参数可从/proc/sys/
虚拟进程文件系统获得。这些参数涵盖各种子系统,例如:
内核(通用前缀:kernel.
)
网络(通用前缀:net.
)
虚拟内存(通用前缀:vm.
)
MDADM(通用前缀:dev.
)
更多子系统在内核文档中有所描述。要获取所有参数的列表,请运行:
$ sudo sysctl -a
许多 sysctls 在 Linux 内核中是命名空间的。这意味着您可以为节点上的每个 Pod 独立设置它们。命名空间是 sysctls 在 Kubernetes 中的 Pod 上下文中可访问的必要条件。
已知以下 sysctls 是命名空间的:
kernel.shm*
kernel.msg*
kernel.sem
fs.mqueue.*
此外,net.*
组中的大多数 sysctls 已知是命名空间的。它们的命名空间采用情况因内核版本和发行版而异。
不是命名空间的 sysctls 称为节点级,必须由集群管理员手动设置,可以通过节点的基础 Linux 发行版来设置,例如通过修改/etc/sysctls.conf
文件,或使用具有特权容器的守护进程集。您可以使用节点调优操作符来设置节点级 sysctls。
考虑将具有特殊 sysctls 的节点标记为受损。仅将需要这些 sysctl 设置的 Pod 调度到这些节点上。使用污点和容忍功能来标记节点。 |
Sysctls 分为安全和不安全的 sysctls。
对于系统范围的 sysctls 来说,要被认为是安全的,它们必须是命名空间的。命名空间 sysctl 确保命名空间和 Pod 之间存在隔离。如果您为一个 Pod 设置 sysctl,它不能添加以下任何内容:
影响节点上的任何其他 Pod
损害节点健康
获取超出 Pod 资源限制的 CPU 或内存资源
仅命名空间不足以使 sysctl 被认为是安全的。 |
任何未添加到 OpenShift Container Platform 允许列表中的 sysctl 对于 OpenShift Container Platform 而言都被认为是不安全的。
默认情况下不允许使用不安全的 sysctls。对于系统范围的 sysctls,集群管理员必须在每个节点的基础上手动启用它们。具有禁用的不安全 sysctls 的 Pod 将被调度但不会启动。
您无法手动启用接口特定的不安全 sysctls。 |
OpenShift Container Platform 将以下系统范围和接口特定的安全 sysctls 添加到允许的安全列表中:
sysctl | 描述 |
---|---|
|
设置为 |
|
定义TCP和UDP用于选择本地端口的本地端口范围。第一个数字是第一个端口号,第二个数字是最后一个本地端口号。如果可能,最好这两个数字奇偶性不同(一个偶数,一个奇数)。它们必须大于或等于 |
|
当设置 |
|
这将 |
|
这定义了网络命名空间中的第一个非特权端口。要禁用所有特权端口,请将其设置为 |
|
指定要为应用程序或服务保留的逗号分隔的本地端口范围。 |
|
指定连接空闲后应发送第一个 |
|
指定连接在 |
|
指定 |
|
指定要发送的 |
sysctl | 描述 |
---|---|
|
接受IPv4 ICMP重定向消息。 |
|
接受具有严格源路由(SRR)选项的IPv4数据包。 |
|
定义对于ARP表中尚不存在IPv4地址的 gratuitous ARP 帧的行为
|
|
定义IPv4地址和设备更改通知的模式。 |
|
禁用此IPv4接口的IPSEC策略(SPD)。 |
|
仅接受发送到接口当前网关列表中列出的网关的ICMP重定向消息。 |
|
仅当节点充当路由器时才启用发送重定向。也就是说,主机不应发送ICMP重定向消息。路由器使用它来通知主机特定目的地的更好的路由路径。 |
|
接受IPv6路由器通告;使用它们自动配置。它还确定是否传输路由器请求。只有当功能设置是接受路由器通告时,才会传输路由器请求。 |
|
接受IPv6 ICMP重定向消息。 |
|
接受具有SRR选项的IPv6数据包。 |
|
定义对于ARP表中尚不存在IPv6地址的 gratuitous ARP 帧的行为
|
|
定义IPv6地址和设备更改通知的模式。 |
|
此参数控制IPv6邻居表中硬件地址到IP映射的生存期。 |
|
设置邻居发现消息的重传计时器。 |
使用 |
OpenShift Container Platform包含一个预定义的安全接口特定sysctls
列表。您可以通过更新openshift-multus
命名空间中的cni-sysctl-allowlist
来修改此列表。
更新接口特定安全sysctls列表的支持仅为技术预览功能。技术预览功能不受Red Hat生产服务级别协议(SLA)的支持,并且可能功能不完整。Red Hat不建议在生产环境中使用它们。这些功能可提前访问即将推出的产品功能,使客户能够在开发过程中测试功能并提供反馈。 有关Red Hat技术预览功能支持范围的更多信息,请参见 技术预览功能支持范围。 |
请按照此步骤修改预定义的安全sysctls
列表。此步骤描述如何扩展默认允许列表。
运行以下命令查看现有的预定义列表
$ oc get cm -n openshift-multus cni-sysctl-allowlist -oyaml
apiVersion: v1
data:
allowlist.conf: |-
^net.ipv4.conf.IFNAME.accept_redirects$
^net.ipv4.conf.IFNAME.accept_source_route$
^net.ipv4.conf.IFNAME.arp_accept$
^net.ipv4.conf.IFNAME.arp_notify$
^net.ipv4.conf.IFNAME.disable_policy$
^net.ipv4.conf.IFNAME.secure_redirects$
^net.ipv4.conf.IFNAME.send_redirects$
^net.ipv6.conf.IFNAME.accept_ra$
^net.ipv6.conf.IFNAME.accept_redirects$
^net.ipv6.conf.IFNAME.accept_source_route$
^net.ipv6.conf.IFNAME.arp_accept$
^net.ipv6.conf.IFNAME.arp_notify$
^net.ipv6.neigh.IFNAME.base_reachable_time_ms$
^net.ipv6.neigh.IFNAME.retrans_time_ms$
kind: ConfigMap
metadata:
annotations:
kubernetes.io/description: |
Sysctl allowlist for nodes.
release.openshift.io/version: 4.17.0-0.nightly-2022-11-16-003434
creationTimestamp: "2022-11-17T14:09:27Z"
name: cni-sysctl-allowlist
namespace: openshift-multus
resourceVersion: "2422"
uid: 96d138a3-160e-4943-90ff-6108fa7c50c3
使用以下命令编辑列表
$ oc edit cm -n openshift-multus cni-sysctl-allowlist -oyaml
例如,要允许您实现更严格的反向路径转发,您需要将^net.ipv4.conf.IFNAME.rp_filter$
和^net.ipv6.conf.IFNAME.rp_filter$
添加到列表中,如下所示
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
data:
allowlist.conf: |-
^net.ipv4.conf.IFNAME.accept_redirects$
^net.ipv4.conf.IFNAME.accept_source_route$
^net.ipv4.conf.IFNAME.arp_accept$
^net.ipv4.conf.IFNAME.arp_notify$
^net.ipv4.conf.IFNAME.disable_policy$
^net.ipv4.conf.IFNAME.secure_redirects$
^net.ipv4.conf.IFNAME.send_redirects$
^net.ipv4.conf.IFNAME.rp_filter$
^net.ipv6.conf.IFNAME.accept_ra$
^net.ipv6.conf.IFNAME.accept_redirects$
^net.ipv6.conf.IFNAME.accept_source_route$
^net.ipv6.conf.IFNAME.arp_accept$
^net.ipv6.conf.IFNAME.arp_notify$
^net.ipv6.neigh.IFNAME.base_reachable_time_ms$
^net.ipv6.neigh.IFNAME.retrans_time_ms$
^net.ipv6.conf.IFNAME.rp_filter$
保存对文件的更改并退出。
也支持删除 |
请按照此步骤为IPv4强制执行更严格的反向路径转发。有关反向路径转发的更多信息,请参见 反向路径转发。
创建一个网络附件定义,例如reverse-path-fwd-example.yaml
,内容如下
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
name: tuningnad
namespace: default
spec:
config: '{
"cniVersion": "0.4.0",
"name": "tuningnad",
"plugins": [{
"type": "bridge"
},
{
"type": "tuning",
"sysctl": {
"net.ipv4.conf.IFNAME.rp_filter": "1"
}
}
]
}'
运行以下命令应用yaml
$ oc apply -f reverse-path-fwd-example.yaml
networkattachmentdefinition.k8.cni.cncf.io/tuningnad created
使用以下YAML创建一个pod,例如examplepod.yaml
apiVersion: v1
kind: Pod
metadata:
name: example
labels:
app: httpd
namespace: default
annotations:
k8s.v1.cni.cncf.io/networks: tuningnad (1)
spec:
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
containers:
- name: httpd
image: 'image-registry.openshift-image-registry.svc:5000/openshift/httpd:latest'
ports:
- containerPort: 8080
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
1 | 指定已配置的NetworkAttachmentDefinition 的名称。 |
运行以下命令应用yaml
$ oc apply -f examplepod.yaml
运行以下命令验证pod是否已创建
$ oc get pod
NAME READY STATUS RESTARTS AGE
example 1/1 Running 0 47s
运行以下命令登录到pod
$ oc rsh example
验证已配置的sysctl标志的值。例如,运行以下命令查找值net.ipv4.conf.net1.rp_filter
sh-4.4# sysctl net.ipv4.conf.net1.rp_filter
net.ipv4.conf.net1.rp_filter = 1
您可以使用Pod的securityContext
在Pod上设置sysctl。securityContext
适用于同一Pod中的所有容器。
默认情况下允许使用安全sysctl。
此示例使用Pod securityContext
设置以下安全sysctl
kernel.shm_rmid_forced
net.ipv4.ip_local_port_range
net.ipv4.tcp_syncookies
net.ipv4.ping_group_range
为避免使您的操作系统不稳定,请仅在了解其影响后修改sysctl参数。 |
使用此过程启动具有已配置sysctl设置的Pod。
在大多数情况下,您需要修改现有的Pod定义并添加 |
创建一个YAML文件sysctl_pod.yaml
,定义一个示例Pod并添加securityContext
规范,如下例所示
apiVersion: v1
kind: Pod
metadata:
name: sysctl-example
namespace: default
spec:
containers:
- name: podexample
image: centos
command: ["bin/bash", "-c", "sleep INF"]
securityContext:
runAsUser: 2000 (1)
runAsGroup: 3000 (2)
allowPrivilegeEscalation: false (3)
capabilities: (4)
drop: ["ALL"]
securityContext:
runAsNonRoot: true (5)
seccompProfile: (6)
type: RuntimeDefault
sysctls:
- name: kernel.shm_rmid_forced
value: "1"
- name: net.ipv4.ip_local_port_range
value: "32770 60666"
- name: net.ipv4.tcp_syncookies
value: "0"
- name: net.ipv4.ping_group_range
value: "0 200000000"
1 | runAsUser 控制使用哪个用户ID运行容器。 |
2 | runAsGroup 控制使用哪个主组ID运行容器。 |
3 | allowPrivilegeEscalation 确定Pod是否可以请求允许权限提升。如果未指定,则默认为true。此布尔值直接控制容器进程上是否设置no_new_privs 标志。 |
4 | capabilities 允许特权操作,而无需完全访问root权限。此策略确保从Pod中删除所有功能。 |
5 | runAsNonRoot: true 要求容器将使用任何UID(非0)的用户运行。 |
6 | RuntimeDefault 为Pod或容器工作负载启用默认seccomp配置文件。 |
运行以下命令创建Pod
$ oc apply -f sysctl_pod.yaml
运行以下命令验证pod是否已创建
$ oc get pod
NAME READY STATUS RESTARTS AGE
sysctl-example 1/1 Running 0 14s
运行以下命令登录到pod
$ oc rsh sysctl-example
验证已配置sysctl标志的值。例如,通过运行以下命令查找值kernel.shm_rmid_forced
sh-4.4# sysctl kernel.shm_rmid_forced
kernel.shm_rmid_forced = 1
除非集群管理员显式为该节点启用不安全sysctl,否则使用不安全sysctl的Pod将无法在任何节点上启动。与节点级sysctl一样,使用节点上的污点和容忍功能或标签将这些Pod调度到正确的节点上。
以下示例使用Pod securityContext
设置安全sysctl kernel.shm_rmid_forced
和两个不安全sysctl,net.core.somaxconn
和kernel.msgmax
。规范中没有安全和不安全sysctl的区别。
为避免使您的操作系统不稳定,请仅在了解其影响后修改sysctl参数。 |
以下示例说明将安全和不安全sysctl添加到Pod规范时会发生的情况
创建一个YAML文件sysctl-example-unsafe.yaml
,定义一个示例Pod并添加securityContext
规范,如下例所示
apiVersion: v1
kind: Pod
metadata:
name: sysctl-example-unsafe
spec:
containers:
- name: podexample
image: centos
command: ["bin/bash", "-c", "sleep INF"]
securityContext:
runAsUser: 2000
runAsGroup: 3000
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
sysctls:
- name: kernel.shm_rmid_forced
value: "0"
- name: net.core.somaxconn
value: "1024"
- name: kernel.msgmax
value: "65536"
使用以下命令创建Pod
$ oc apply -f sysctl-example-unsafe.yaml
使用以下命令验证Pod是否已调度但未部署,因为节点不允许使用不安全sysctl
$ oc get pod
NAME READY STATUS RESTARTS AGE
sysctl-example-unsafe 0/1 SysctlForbidden 0 14s
集群管理员可以允许某些不安全sysctl用于非常特殊的情况,例如高性能或实时应用程序调整。
如果要使用不安全sysctl,集群管理员必须为特定类型的节点单独启用它们。sysctl必须是命名空间的。
您可以通过在安全上下文约束的allowedUnsafeSysctls
字段中指定sysctl或sysctl模式列表来进一步控制在Pod中设置哪些sysctl。
allowedUnsafeSysctls
选项控制特定需求,例如高性能或实时应用程序调整。
由于其不安全的性质,使用不安全sysctl的风险自负,并可能导致严重问题,例如容器行为不当、资源短缺或节点中断。 |
列出OpenShift Container Platform集群的现有MachineConfig对象,以决定如何标记您的机器配置,请运行以下命令
$ oc get machineconfigpool
NAME CONFIG UPDATED UPDATING DEGRADED MACHINECOUNT READYMACHINECOUNT UPDATEDMACHINECOUNT DEGRADEDMACHINECOUNT AGE
master rendered-master-bfb92f0cd1684e54d8e234ab7423cc96 True False False 3 3 3 0 42m
worker rendered-worker-21b6cb9a0f8919c88caf39db80ac1fce True False False 3 3 3 0 42m
使用以下命令向将运行具有不安全sysctl的容器的机器配置池添加标签
$ oc label machineconfigpool worker custom-kubelet=sysctl
创建一个YAML文件set-sysctl-worker.yaml
,定义一个KubeletConfig
自定义资源(CR)
apiVersion: machineconfiguration.openshift.io/v1
kind: KubeletConfig
metadata:
name: custom-kubelet
spec:
machineConfigPoolSelector:
matchLabels:
custom-kubelet: sysctl (1)
kubeletConfig:
allowedUnsafeSysctls: (2)
- "kernel.msg*"
- "net.core.somaxconn"
1 | 指定机器配置池中的标签。 |
2 | 列出您要允许的不安全sysctl。 |
运行以下命令创建对象
$ oc apply -f set-sysctl-worker.yaml
等待Machine Config Operator生成新的渲染配置并将其应用于机器,请运行以下命令
$ oc get machineconfigpool worker -w
几分钟后,UPDATING
状态将从True变为False
NAME CONFIG UPDATED UPDATING DEGRADED MACHINECOUNT READYMACHINECOUNT UPDATEDMACHINECOUNT DEGRADEDMACHINECOUNT AGE
worker rendered-worker-f1704a00fc6f30d3a7de9a15fd68a800 False True False 3 2 2 0 71m
worker rendered-worker-f1704a00fc6f30d3a7de9a15fd68a800 False True False 3 2 3 0 72m
worker rendered-worker-0188658afe1f3a183ec8c4f14186f4d5 True False False 3 3 3 0 72m
创建一个YAML文件sysctl-example-safe-unsafe.yaml
,定义一个示例Pod并添加securityContext
规范,如下例所示
apiVersion: v1
kind: Pod
metadata:
name: sysctl-example-safe-unsafe
spec:
containers:
- name: podexample
image: centos
command: ["bin/bash", "-c", "sleep INF"]
securityContext:
runAsUser: 2000
runAsGroup: 3000
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
sysctls:
- name: kernel.shm_rmid_forced
value: "0"
- name: net.core.somaxconn
value: "1024"
- name: kernel.msgmax
value: "65536"
运行以下命令创建Pod
$ oc apply -f sysctl-example-safe-unsafe.yaml
Warning: would violate PodSecurity "restricted:latest": forbidden sysctls (net.core.somaxconn, kernel.msgmax)
pod/sysctl-example-safe-unsafe created
运行以下命令验证pod是否已创建
$ oc get pod
NAME READY STATUS RESTARTS AGE
sysctl-example-safe-unsafe 1/1 Running 0 19s
运行以下命令登录到pod
$ oc rsh sysctl-example-safe-unsafe
验证已配置sysctl标志的值。例如,通过运行以下命令查找值net.core.somaxconn
sh-4.4# sysctl net.core.somaxconn
net.core.somaxconn = 1024
现在允许使用不安全sysctl,并且其值设置为更新后的Pod规范的securityContext
规范中定义的值。