6.9. 컨테이너의 sysctl 사용

sysctl 설정은 Kubernetes를 통해 노출되므로 사용자는 런타임에 컨테이너 내의 네임스페이스에 대한 특정 커널 매개변수를 수정할 수 있습니다. 네임스페이스가 지정된 sysctl만 Pod에 독립적으로 설정할 수 있습니다. sysctl이 node-level 이라는 네임스페이스가 지정되지 않은 경우 Node Tuning Operator 와 같은 sysctl을 설정하는 다른 방법을 사용해야 합니다. 또한 기본적으로 안전한 것으로 간주되는 sysctl만 허용 목록에 포함됩니다. 노드의 다른 안전하지 않은 sysctl을 사용자에게 제공하도록 수동으로 활성화할 수 있습니다.

6.9.1. sysctl 정보

Linux에서 sysctl 인터페이스를 사용하면 관리자가 런타임에 커널 매개변수를 수정할 수 있습니다. 매개변수는 /proc/sys/ 가상 프로세스 파일 시스템을 통해 사용할 수 있습니다. 해당 매개변수는 다음과 같이 다양한 하위 시스템에 적용됩니다.

  • 커널(공용 접두사: kernel.)
  • 네트워킹(공용 접두사: net.)
  • 가상 메모리(공용 접두사: vm.)
  • MDADM(공용 접두사: dev.)

커널 설명서에 더 많은 하위 시스템이 설명되어 있습니다. 모든 매개변수 목록을 가져오려면 다음을 실행합니다.

$ sudo sysctl -a

6.9.1.1. 네임스페이스 지정 sysctl 및 노드 수준 sysctl 비교

대다수의 sysctl은 Linux 커널에 네임스페이스가 지정됩니다. 즉 노드의 각 Pod에 개별적으로 설정할 수 있습니다. Kubernetes 내의 Pod 컨텍스트에서 sysctl에 액세스하려면 네임스페이스를 지정해야 합니다.

다음 sysctl은 네임스페이스로 알려져 있습니다.

  • kernel.shm*
  • kernel.msg*
  • kernel.sem
  • fs.mqueue.*

또한 net.* 그룹에 있는 대부분의 sysctl은 네임스페이스로 알려져 있습니다. 해당 네임스페이스 채택은 커널 버전 및 배포자에 따라 다릅니다.

네임스페이스가 지정되지 않은 Sysctl은 노드 수준이라고 하며 노드의 기본 Linux 배포(예: /etc/sysctls.conf 파일 수정)를 통해 또는 권한 있는 컨테이너에 데몬 세트를 사용하여 클러스터 관리자가 수동으로 설정해야 합니다. Node Tuning Operator를 사용하여 노드 수준 sysctl을 설정할 수 있습니다.

참고

특수 sysctl이 있는 노드를 테인트로 표시하는 것이 좋습니다. 이러한 sysctl 설정이 필요한 노드에만 Pod를 예약하십시오. 테인트 및 허용 오차 기능을 사용하여 노드를 표시합니다.

6.9.1.2. 안전한 sysctl 및 안전하지 않은 sysctl 비교

sysctl은 안전한 sysctl 및 안전하지 않은 sysctl로 그룹화됩니다.

sysctl이 안전한 것으로 간주되려면 적절한 네임스페이스를 사용해야 하며 동일한 노드의 Pod 간에 올바르게 격리되어야 합니다. 즉 하나의 Pod에 sysctl을 설정하면 다음과 같은 결과가 발생하지 않아야 합니다.

  • 노드의 다른 Pod에 영향을 미침
  • 노드 상태 손상
  • Pod의 리소스 제한을 벗어나는 CPU 또는 메모리 리소스 확보

OpenShift Container Platform에서는 안전 설정에 있는 다음 sysctl을 지원하거나 허용 목록에 추가합니다.

  • kernel.shm_rmid_forced
  • net.ipv4.ip_local_port_range
  • net.ipv4.tcp_syncookies
  • net.ipv4.ping_group_range

안전한 sysctl은 모두 기본적으로 활성화됩니다. Pod 사양을 수정하여 Pod에서 sysctl을 사용할 수 있습니다.

OpenShift Container Platform에서 허용 목록에 추가하지 않은 sysctl은 OpenShift Container Platform에서 안전하지 않은 것으로 간주합니다. sysctl을 안전한 것으로 간주하기 위해서는 네임스페이스만으로는 충분하지 않습니다.

안전하지 않은 sysctl은 기본적으로 모두 비활성화되어 있으며 클러스터 관리자가 노드별로 수동으로 활성화해야 합니다. 안전하지 않은 sysctl이 비활성화된 Pod는 예약은 되지만 시작되지 않습니다.

$ oc get pod

출력 예

NAME        READY   STATUS            RESTARTS   AGE
hello-pod   0/1     SysctlForbidden   0          14s

6.9.2. Pod의 sysctl 설정

Pod의 securityContext를 사용하여 Pod에 sysctl을 설정할 수 있습니다. securityContext는 동일한 Pod의 모든 컨테이너에 적용됩니다.

안전한 sysctl은 기본적으로 허용됩니다. 안전하지 않은 sysctl이 있는 Pod는 클러스터 관리자가 해당 노드에 대해 안전하지 않은 sysctl을 명시적으로 활성화하지 않는 한 어떠한 노드에서도 시작되지 않습니다. 노드 수준 sysctl과 마찬가지로 노드에 테인트 및 허용 오차 기능을 사용하여 해당 Pod를 올바른 노드에 예약합니다.

다음 예제에서는 Pod securityContext 를 사용하여 안전한 sysctl kernel.shm_rmid_forced 와 안전하지 않은 sysctl인 net.core.somaxconn 및 kernel .msgmax 를 설정합니다. 사양에서는 안전안전하지 않은 sysctl이 구분되지 않습니다.

주의

운영 체제가 불안정해지는 것을 방지하기 위해 sysctl 매개변수 수정이 미치는 영향을 파악한 후에만 수정하십시오.

프로세스

안전한 sysctl 및 안전하지 않은 sysctl을 사용하려면 다음을 수행합니다.

  1. 다음 예제와 같이 Pod를 정의하는 YAML 파일을 수정하고 securityContext 사양을 추가합니다.

    apiVersion: v1
    kind: Pod
    metadata:
      name: sysctl-example
    spec:
      securityContext:
        sysctls:
        - name: kernel.shm_rmid_forced
          value: "0"
        - name: net.core.somaxconn
          value: "1024"
        - name: kernel.msgmax
          value: "65536"
      ...
  2. Pod를 생성합니다.

    $ oc apply -f <file-name>.yaml

    안전하지 않은 sysctl을 노드에 사용할 수 없는 경우 Pod는 예약되지만 배포되지는 않습니다.

    $ oc get pod

    출력 예

    NAME        READY   STATUS            RESTARTS   AGE
    hello-pod   0/1     SysctlForbidden   0          14s

6.9.3. 안전하지 않은 sysctl 활성화

클러스터 관리자는 고성능 또는 실시간 애플리케이션 튜닝과 같이 매우 특별한 상황에 대해 안전하지 않은 특정 sysctl을 허용할 수 있습니다.

안전하지 않은 sysctl을 사용하려면 클러스터 관리자가 특정 유형의 노드에 대해 개별적으로 활성화해야 합니다. sysctl에 네임스페이스가 지정되어 있어야 합니다.

보안 컨텍스트 제약 조건의 allowedUnsafeSysctls 필드에 sysctls 목록 또는 sysctl 패턴 목록을 지정하여 Pod에 설정된 sysctl을 추가로 제어할 수 있습니다.

  • allowedUnsafeSysctls 옵션은 고성능 또는 실시간 애플리케이션 튜닝과 같은 특정 요구 사항을 제어합니다.
주의

안전하지 않은 상태의 특성으로 인해 안전하지 않은 sysctl을 사용하는 경우 사용자가 위험을 감수해야 하고 부적절한 컨테이너 동작, 리소스 부족 또는 노드 중단과 같은 심각한 문제가 발생할 수 있습니다.

프로세스

  1. 안전하지 않은 sysctl이 있는 컨테이너가 실행될 머신 구성 풀에 라벨을 추가합니다.

    $ oc edit machineconfigpool worker
    apiVersion: machineconfiguration.openshift.io/v1
    kind: MachineConfigPool
    metadata:
      creationTimestamp: 2019-02-08T14:52:39Z
      generation: 1
      labels:
        custom-kubelet: sysctl 1
    1
    key: pair 라벨을 추가합니다.
  2. 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을 나열합니다.
  3. 오브젝트를 생성합니다.

    $ oc apply -f set-sysctl-worker.yaml

    99-worker-XXXXXX-XXXXX-XXXX-XXXXX-kubelet 형식으로 이름이 지정된 새 MachineConfig 오브젝트가 생성됩니다.

  4. machineconfigpool 오브젝트 상태 필드를 사용하여 클러스터가 재부팅될 때까지 기다립니다.

    예를 들면 다음과 같습니다.

    status:
      conditions:
        - lastTransitionTime: '2019-08-11T15:32:00Z'
          message: >-
            All nodes are updating to
            rendered-worker-ccbfb5d2838d65013ab36300b7b3dc13
          reason: ''
          status: 'True'
          type: Updating

    클러스터가 준비되면 다음과 유사한 메시지가 표시됩니다.

       - lastTransitionTime: '2019-08-11T16:00:00Z'
          message: >-
            All nodes are updated with
            rendered-worker-ccbfb5d2838d65013ab36300b7b3dc13
          reason: ''
          status: 'True'
          type: Updated
  5. 클러스터가 준비되면 새 MachineConfig 오브젝트에 병합된 KubeletConfig 오브젝트가 있는지 확인합니다.

    $ oc get machineconfig 99-worker-XXXXXX-XXXXX-XXXX-XXXXX-kubelet -o json | grep ownerReference -A7
            "ownerReferences": [
                {
                    "apiVersion": "machineconfiguration.openshift.io/v1",
                    "blockOwnerDeletion": true,
                    "controller": true,
                    "kind": "KubeletConfig",
                    "name": "custom-kubelet",
                    "uid": "3f64a766-bae8-11e9-abe8-0a1a2a4813f2"
                }
            ]

    이제 필요한 경우 Pod에 안전하지 않은 sysctl을 추가할 수 있습니다.