特権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

ボリュームとして/ procをマウントするような愚かなことをする必要がありますか?
allingeek 2015

/ proc:/ procのマウントを試みたが、運が悪かった。以降のsysctl -aの呼び出しでは、元の値が返されます。
allingeek 2015

Docker 18.09で動作するように見えます
Jairo Andres Velasco Romero

回答:


8

この特定の設定は、Dockerが実行されるネットワーク名前空間の影響を受けます。

一般的なルール/procはシステム全体に関連する設定を変更するため、技術的には/proc/netネットワークの名前空間ごとに結果を返す設定を変更します。

これ/proc/net/proc/self/net、作業を行っている名前空間の設定を実際に反映しているため、実際にはへのシンボリックリンクであることに注意してください。


したがって、/ procがマウントされ、-netホストが含まれるコンテナでこの変更を行うと、ホストに変更を加えることができます。しかし、私があなたの答えを理解した場合、後続のコンテナは、独自の名前空間で古い値(ホストの永続的な設定からブートストラップされたもの)を維持します。ロードバランサーのコンテナーで実行時に同じ変更を行うには、CAP_NET_ADMINなどを使用してそのコンテナーを実行する必要があります。いいでしょう?
allingeek 2015

はい、CAP_NET_ADMINで実行しても、名前空間をインスタンス化した問題は発生しません。
マシューイフェ2015

Matthew_Ifeこの場合、コンテナに特権が必要であることが予想されるという問題はありません。CAP_NET_ADMINがドッキングウィンドウのconfination(少なくともコンテナが別のコンテナを偽装するために、そのインターフェイスを再設定できる)から脱出する可能性がありますように私には思える
アンヘル・

@Angelそれは、Docker内で設定されているリンクによって異なります。ただし、一般に、親ネームスペースにトラフィックを適用する必要があります。CAP_SYS_ADMINが必要なため、名前空間を別の場所に切り替えることはできません。
Matthew Ife、2015

--net = hostを使用して動作しますか?
Jairo Andres Velasco Romero

7

Docker 1.12+には、コンテナー内のsysctl値を調整するためのネイティブサポートがあります。これはドキュメントからの抜粋です:

実行時に名前空間付きカーネルパラメータ(sysctl)を構成する

--sysctlは、コンテナー内の名前空間付きカーネルパラメーター(sysctl)を設定します。たとえば、コンテナネットワークの名前空間で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 2015

私がドッカーについて知っている小さなことから; FreeBSDの刑務所のような自己完結型のインスタンスであることが想定されているため、簡単に移動したり、再デプロイしたりできます。ホストOSとドックレットを混同しないでください。
DutchUncle 2015

2
--privilegedコンテナの使用にはいくつかの有効なケースがあり、これは完璧なケースのようです。すべてのコンテナーは、同じ基本カーネルを使用します。標準コンテナーは/ procを読み取り専用としてマウントします。
allingeek 2015

@allingeek CAP_NET_ADMINは実際に欠落しているビットである可能性があります。
アンヘル

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.