J'essaie de modifier net.core.somaxconn
pour que le conteneur docker puisse avoir une file d'attente plus longue de demandes pour mon application Web.
Sous OS, en dehors du menu fixe, je modifie d'abord la propriété avec succès:
$ 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
Mais alors je ne sais pas comment propager ce changement en docker. J'ai essayé:
/etc/sysctl.conf
(dans l’espoir que le menu fixe lise ce fichier au lancement du conteneur)Sudo docker stop
et Sudo docker run
à nouveauSudo service docker restart
Mais dans le conteneur, cat /proc/sys/net/core/somaxconn
affiche toujours 128
.
J'exécute docker 1.2 (je ne peux donc pas, par défaut, modifier les attributs /proc
dans le conteneur) et dans Elastic Beanstalk (donc sans le mode --privileged
, cela me permettrait de modifier /proc
).
Comment puis-je propager les modifications sysctl au menu fixe?
Je viens juste de comprendre comment résoudre ceci, maintenant Elastic Beanstalk prend en charge l'exécution de conteneurs privilégiés et il vous suffit d'ajouter le "privileged": "true"
à votre Dockerrun.aws.json
comme exemple suivant (consultez le 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"
}]
}
Veuillez noter que je ai dupliqué cette réponse depuis un autre thread.
Le sous-système "net/core" est enregistré par espace de noms réseau . Et la valeur initiale de somaxconn est définie sur 128.
Lorsque vous exécutez sysctl sur le système hôte, il définit les principaux paramètres de l’espace de nommage réseau }, qui appartient à init . (fondamentalement, c'est l'espace de noms par défaut). Cela n'affecte pas les autres espaces de noms réseau.
Lorsqu'un conteneur Docker est démarré, l'interface réseau virtuelle (indiquée par vethXXX sur l'hôte) de ce conteneur est attachée à son propre espace de noms , qui a toujours la valeur initiale somaxconn de 128. Donc techniquement, vous ne pouvez pas propager cette valeur dans le conteneur, car les deux espaces de noms réseau ne la partagent pas.
Vous pouvez toutefois ajuster cette valeur de deux manières, en plus d'exécuter le conteneur en mode privilégié.
utilisez "--net Host" lors de l'exécution du conteneur, il utilise donc l'interface réseau de l'hôte et partage donc le même espace de noms réseau.
vous pouvez monter le système de fichiers proc en lecture-écriture en utilisant le support de mappage de volume de Docker. l'astuce consiste à le mapper sur un volume NON nommé "/ proc", puisque Docker va remount/proc/sys, entre autres, en lecture seule pour les conteneurs non privilégiés . Cela nécessite que l'hôte monte/proc en tant que rw, ce qui est le cas sur la plupart des systèmes.
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
La méthode 2 devrait fonctionner sur Elastic Beanstalk via son support de mappage de volume dans Dockerrun.aws.json . En outre, cela devrait fonctionner pour d'autres paramètres ajustables sous/proc qui sont par espace de noms. Mais il s'agit probablement d'un oubli de la part de Docker, qui peut donc ajouter une validation supplémentaire sur le mappage de volume. Cette astuce ne fonctionnera pas à ce moment-là.
docker 1.12 ajoute le support pour la définition de sysctls avec --sysctl.
docker run --name some-redis --sysctl=net.core.somaxconn=511 -d redis
Mise à jour: Cette réponse est obsolète car Docker prend désormais en charge l'option docker run --sysctl
!
La solution que j'utilise pour mon conteneur OpenVPN consiste à entrer dans l'espace de noms du conteneur avec des fonctionnalités complètes en utilisant nsenter
, en remontant le /proc/sys
en lecture-écriture temporairement, en configurant et en remontant le contenu en lecture seule.
Voici un exemple d'activation du transfert IPv6 dans le conteneur:
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'
De cette façon, le conteneur n'a pas besoin de s'exécuter avec privilège.
J'ai trouvé une solution:
{
"AWSEBDockerrunVersion": "1",
"Command": "run COMMAND",
"Image": {
"Name": "crystalnix/omaha-server",
"Update": "true"
},
"Ports": [
{
"ContainerPort": "80"
}
]
}
plus de détails ici: /opt/elasticbeanstalk/hooks/appdeploy/pre/04run.sh
Mettre à jour:
Ajouter le fichier .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'
Dans docker 3.1, il est possible de spécifier sysctl. Notez le
sysctls:
- net.core.somaxconn = 1024
Mon exemple de fichier 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"