Dockerコンテナーのnet.core.somaxcomm(または任意のsysctlプロパティ)を更新する
Dockerコンテナーがnet.core.somaxconn
を変更して、Webアプリケーションのリクエストのキューを大きくできるようにしています。
OSでは、Docker外で、最初にプロパティを正常に変更します。
$ cat /proc/sys/net/core/somaxconn
128
$ Sudo sysctl -w net.core.somaxconn=1024
net.core.somaxconn = 1024
$ cat /proc/sys/net/core/somaxconn
1024
しかし、その変更をdockerに伝播する方法がわかりません。私はもう試した:
- また、
/etc/sysctl.conf
の編集(Dockerがコンテナの起動時にそのファイルを読み取ることを期待して) - コンテナ
Sudo docker stop
およびSudo docker run
を再起動しています Sudo service docker restart
によるdockerサービス全体の再起動
ただし、コンテナ内では、cat /proc/sys/net/core/somaxconn
には常に128
が表示されます。
Docker 1.2(デフォルトではコンテナ内の/proc
属性を変更できない)とElastic Beanstalk(--privileged
モードがないため、/proc
を変更できるようにする)を実行しています。
Sysctlの変更をどのようにdockerに伝播できますか?
これを解決する方法を理解したところです Elastic Beanstalkは特権付きコンテナの実行をサポートしています そして、次のサンプルとして"privileged": "true"
をDockerrun.aws.json
に追加する必要があります( container-1
)を見てください:
{
"AWSEBDockerrunVersion": 2,
"containerDefinitions": [{
"name": "container-0",
"essential": "false",
"image": "ubuntu",
"memory": "512"
}, {
"name": "container-1",
"essential": "false",
"image": "ubuntu",
"memory": "512",
"privileged": "true"
}]
}
注意してください私は この回答を複製 別のスレッドから。
"net/core"サブシステムは ネットワーク名前空間ごとに登録 です。また、somaxconnの初期値は128に設定されています。
ホストシステムでsysctlを実行すると、itsネットワーク名前空間のコアパラメーターが設定されます。これは、initが所有するものです。 (基本的にこれはデフォルトの名前空間です)。これは他のネットワーク名前空間には影響しません。
Dockerコンテナーが起動すると、そのコンテナーの仮想ネットワークインターフェイス(ホストではvethXXXと表示されます) 独自の名前空間に接続されています であり、初期のsomaxconnがまだあります128の値。したがって、技術的には、2つのネットワーク名前空間が値を共有しないため、この値をコンテナに伝播することはできません。
ただし、コンテナーを特権モードで実行する以外に、この値を調整する方法は2つあります。
コンテナの実行時に「--net Host」を使用すると、ホストのネットワークインターフェースが使用されるため、同じネットワーク名前空間を共有できます。
dockerのボリュームマッピングサポートを使用して、procファイルシステムを読み書き可能としてマウントできます。 Dockerは 特に/ proc/sysを非特権コンテナの読み取り専用として再マウントする なので、トリックは「/ proc」ではないボリュームにマッピングすることです。これには、ホストが/ procをrwとしてマウントする必要があります。これは、ほとんどのシステムの場合です。
docker run -it --rm -v /proc:/writable-proc ubuntu:14.04 /bin/bash root@edbee3de0761:/# echo 1024 > /writable-proc/sys/net/core/somaxconn root@edbee3de0761:/# sysctl net.core.somaxconn net.core.somaxconn = 1024
方法2は Dockerrun.aws.json のボリュームマッピングサポートを介してElastic Beanstalkで動作するはずです。また、名前空間ごとの/ procの下の他の調整可能なパラメーターでも機能するはずです。しかし、これはDockerの部分の見落としである可能性が高いため、ボリュームマッピングに追加の検証を追加する可能性があり、その場合、このトリックは機能しません。
docker 1.12は--sysctlでsysctlを設定するためのサポートを追加します。
docker run --name some-redis --sysctl=net.core.somaxconn=511 -d redis
更新:Dockerがdocker run --sysctl
オプションをサポートするようになったため、この回答は廃止されました!
私のOpenVPNコンテナーに使用するソリューションは、nsenter
を使用して完全な機能を備えたコンテナー名前空間に入り、/proc/sys
読み取り/書き込みを一時的に再マウントし、スタッフをセットアップして、読み取り専用で再度マウントすることです。
次の例では、コンテナでIPv6転送を有効にしています。
CONTAINER_NAME=openvpn
# enable ipv6 forwarding via nsenter
container_pid=`docker inspect -f '{{.State.Pid}}' $CONTAINER_NAME`
nsenter --target $container_pid --mount --uts --ipc --net --pid \
/bin/sh -c '/usr/bin/mount /proc/sys -o remount,rw;
/usr/sbin/sysctl -q net.ipv6.conf.all.forwarding=1;
/usr/bin/mount /proc/sys -o remount,ro;
/usr/bin/mount /proc -o remount,rw # restore rw on /proc'
この方法では、コンテナーは特権で実行する必要はありません。
私は解決策を見つけました:
{
"AWSEBDockerrunVersion": "1",
"Command": "run COMMAND",
"Image": {
"Name": "crystalnix/omaha-server",
"Update": "true"
},
"Ports": [
{
"ContainerPort": "80"
}
]
}
詳細はこちら:/opt/elasticbeanstalk/hooks/appdeploy/pre/04run.sh
更新:
ファイルを追加.ebextensions/02-commands.config
container_commands:
00001-docker-privileged:
command: 'sed -i "s/docker run -d/docker run --privileged -d/" /opt/elasticbeanstalk/hooks/appdeploy/pre/04run.sh'
Docker 3.1では、sysctlの指定がサポートされています。に注意してください
sysctls:
-net.core.somaxconn = 1024
私の例のdocker-composeファイル
version: '3.1'
services:
my_redis_master:
image: redis
restart: always
command: redis-server /etc/redis/redis.conf
volumes:
- /data/my_dir/redis:/data
- /data/my_dir/logs/redis:/var/tmp/
- ./redis/redis-master.conf:/etc/redis/redis.conf
sysctls:
- net.core.somaxconn=1024
ports:
- "18379:6379"