권한이있는 Docker 컨테이너를 사용한 커널 튜닝


10

로드 밸런서의 커널 설정을 조정하기위한 컨테이너를 만들고 있습니다. 단일 권한 컨테이너를 사용하여 이미지의 변경 사항을 호스트에 배포하고 싶습니다. 예를 들면 다음과 같습니다.

docker run --rm --privileged ubuntu:latest sysctl -w net.core.somaxconn=65535

테스트에서 변경 사항은 해당 컨테이너에만 적용됩니다. 전적으로 권한이있는 컨테이너를 / proc로 변경하면 기본 OS가 실제로 변경 될 것이라는 인상을 받았습니다.

$docker run --rm --privileged ubuntu:latest \
    sysctl -w net.core.somaxconn=65535
net.core.somaxconn = 65535

$ docker run --rm --privileged ubuntu:latest \
    /bin/bash -c "sysctl -a | grep somaxconn"
net.core.somaxconn = 128

이것이 특권 컨테이너가 작동하는 방식입니까?

방금 바보 같은 짓을하는거야?

지속적인 변경을 수행하는 가장 좋은 방법은 무엇입니까?

버전 정보 :

Client version: 1.4.1
Client API version: 1.16
Go version (client): go1.3.3
Git commit (client): 5bc2ff8
OS/Arch (client): linux/amd64
Server version: 1.4.1
Server API version: 1.16
Go version (server): go1.3.3
Git commit (server): 5bc2ff8

/ proc가 마운트 된 명령 예 :

$ docker run -v /proc:/proc ubuntu:latest \
    /bin/bash -c "sysctl -a | grep local_port"
net.ipv4.ip_local_port_range = 32768    61000

$ docker run -v /proc:/proc --privileged ubuntu:latest \
    /bin/bash -c "sysctl -p /updates/sysctl.conf"
net.ipv4.ip_local_port_range = 2000 65000

$ docker run -v /proc:/proc ubuntu:latest \
    /bin/bash -c "sysctl -a | grep local_port"
net.ipv4.ip_local_port_range = 32768    61000

$ docker run -v /proc:/proc --privileged ubuntu:latest \
    /bin/bash -c "sysctl -a | grep local_port"
net.ipv4.ip_local_port_range = 32768    61000

볼륨으로 mount / proc와 같은 바보 같은 작업을 수행해야합니까?
allingeek

운이없이 / proc : / proc 마운트를 시도했습니다. sysctl -a에 대한 후속 호출은 원래 값을 반환합니다.
allingeek

외모는 지금처럼은 도커 18.09에서 작동
하이로 안드레스 벨라스코 로메로

답변:


8

이 특정 설정은도 커가 실행되는 네트워크 네임 스페이스의 영향을받습니다.

일반적으로 /proc시스템 전체에 관련된 설정을 변경하지만 기술적으로 말하면 /proc/net네트워크 네임 스페이스별로 결과를 반환하는 설정을 변경 하고 있습니다.

/proc/net사실에 심볼릭 링크 /proc/self/net정말 당신이 일을하고 있다는 네임 스페이스의 설정을 반영처럼.


따라서 / proc 장착 및 --net 호스트가있는 컨테이너에서이 변경을 수행하면 호스트를 변경할 수 있습니다. 그러나 귀하의 답변을 이해하면 후속 컨테이너는 자체 네임 스페이스에서 이전 값 (호스트의 지속 설정에서 부트 스트랩)을 유지합니다. 로드 밸런서의 컨테이너에서 런타임에 동일한 변경을 수행하려면 CAP_NET_ADMIN과 같은 컨테이너를 실행해야합니다. 맞습니까?
allingeek

예, CAP_NET_ADMIN으로 실행하면 네임 스페이스를 인스턴스화 한 경우 문제가 발생하지 않습니다.
Matthew Ife

Matthew_Ife이 경우 컨테이너에 권한이 부여 될 것으로 예상되는 문제는 없습니다. CAP_NET_ADMIN은 docker confination에서 벗어날 수 있습니다 (적어도 컨테이너는 다른 컨테이너를 가장하도록 인터페이스를 재구성 할 수 있음)
Ángel

@Angel 그것은 도커 내부에 어떤 링크 아웃이 설정되어 있는지에 달려 있습니다. 일반적으로 부모 네임 스페이스에 트래픽을 적용해야합니다. CAP_SYS_ADMIN이 필요하므로 네임 스페이스를 다른 곳으로 전환 할 수 없습니다.
Matthew Ife

--net = host를 사용하면 작동합니까?
Jairo Andres Velasco Romero

7

Docker 1.12+는 컨테이너 내부에서 sysctl 값을 조정할 수 있도록 기본 지원됩니다. 다음은 문서 에서 발췌 한 것입니다 .

런타임시 네임 스페이스 커널 매개 변수 (sysctls) 구성

--sysctl은 컨테이너에 네임 스페이스 커널 매개 변수 (sysctls)를 설정합니다. 예를 들어, 컨테이너 네트워크 네임 스페이스에서 IP 전달을 켜려면 다음 명령을 실행하십시오.

docker run --sysctl net.ipv4.ip_forward=1 someimage

귀하의 예를 사용하면 올바른 인상 방법 net.core.somaxconn은 다음과 같습니다.

docker run ... --sysctl net.core.somaxconn=65535 ...

3

권한있는 컨테이너는 여전히 고유 한 프로세스 네임 스페이스를 사용하고 있습니다 /proc. /proc컨테이너 내부에 실제를 마운트하는 것이 가능합니다 .

docker run --rm --privileged -v /proc:/host-proc ubuntu:latest \
  'echo 65535 > /host-proc/sys/net/core/somaxconn'

방금 시도했지만 작동하지 않습니다.
allingeek

작은 것부터 나는 도커에 대해 알고 있습니다. FreeBSD의 감옥처럼 자 급식 인스턴스로되어있어 쉽게 이동하거나 재배치 할 수 있습니다. 도킹 렛을 호스트 OS와 섞어서는 안됩니다.
DutchUncle

2
특권 컨테이너를 사용하는 몇 가지 유효한 경우가 있으며 이는 완벽한 경우처럼 보입니다. 모든 컨테이너는 동일한 기본 커널을 사용합니다. 표준 컨테이너는 / proc를 읽기 전용으로 마운트합니다.
allingeek

@allingeek CAP_NET_ADMIN은 실제로 누락 된 비트 일 수 있습니다.
Ángel

1
NET_ADMIN으로 시도했지만 여전히 작동하지 않습니다-docker run --cap-add NET_ADMIN --net = host -v / proc : / proc_host ubuntu : 14.04 bash -c 'echo 1> / proc_host / sys / net / ipv4 / ip_forward '&& sysctl net.ipv4.ip_forward net.ipv4.ip_forward = 0
tomdee

2

이것은 Docker 1.5.0에서 작동합니다.

docker run --privileged --net=host --rm ubuntu:latest /bin/sh -c \
   'echo 65535 > /proc/sys/net/core/somaxconn'   
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.