web-dev-qa-db-fra.com

Actualiser net.core.somaxcomm (ou toute propriété sysctl) pour les conteneurs de menu fixe

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é:

  • Édite également /etc/sysctl.conf (dans l’espoir que le menu fixe lise ce fichier au lancement du conteneur)
  • Redémarrage des conteneurs Sudo docker stop et Sudo docker run à nouveau
  • Redémarrage de l'ensemble du service de menu fixe par Sudo 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?

16
Tuukka Mustonen

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.

2
sirboderafael

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é.

  1. 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.

  2. 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à.

28
zliuva

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

docs: https://docs.docker.com/engine/reference/commandline/run/#/configure-namespaced-kernel-parameters-sysctls-at-runtime

7
eshizhan

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.

3
neingeist

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'
3
Egor Yurtaev

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"                                   
0
nizam.sp