Forum général.général Docker, traefik et multi port

Posté par  (site web personnel) . Licence CC By‑SA.
Étiquettes :
1
12
nov.
2018

Bonjour,

Je migre petit à petit plusieurs services vers Docker. Pour me simplifier la vie j'utilise traefik pour le reverse mais je suis confronté à un "problème". Pour un service je souhaite que le http et mysql soit accessible depuis l'extérieur du container.

Je pensais que multiplier les labels traefik.port avec autant de port à mapper allait suffir mais en fait non. Du coups je ne vois pas du tout comment exposer x ports en passant par le reverse traefik.

Vous avez une idée ?

  • # un début de réponse

    Posté par  (site web personnel) . Évalué à 1. Dernière modification le 12 novembre 2018 à 18:02.

    Bon en fait la doc est assez clair https://docs.traefik.io/v1.5/configuration/backends/docker/#on-service , il fallait juste trouver la bonne page.

    Du coups c'est simple :

        traefik.service_name.port

    avec autant de service_name que de ports à exposer.

    Pour mon exemple :

        --traefik.http.port=80 --traefik.mysql.port=3306

    pour le 80 pas de problème mais pour mysql j'ai le message

        ERROR 2002 (HY000): Can't connect to MySQL server on 'sql-xxxx-sql.doc.yyyy' (115)

    Le message est assez clair, il ne trouve pas le serveur à cette adresse. Dans le doute et comme je suis sur un container en test j'ai mappé le port directement via docker 3345:3306. Je tente une connexion

        mysql -u monuser -p -P 3345 monserveur

    magie ça connecte donc le problème est bien au niveau du reverse.

    Born to Kill EndUser !

    • [^] # Re: un début de réponse

      Posté par  . Évalué à 2.

      Le message est assez clair, il ne trouve pas le serveur à cette adresse. Dans le doute et comme je suis sur un container en test j'ai mappé le port directement via docker 3345:3306. Je tente une connexion

      et ton nom de domaine sql-xxxx-sql.doc.yyyy
      resoud bien vers l'IP de ton docker ?

      • [^] # Re: un début de réponse

        Posté par  (site web personnel) . Évalué à 1.

        Yep ça ping

        Born to Kill EndUser !

        • [^] # Re: un début de réponse

          Posté par  . Évalué à 3.

          au hasard, ta config mysql n'ecoute que sur localhost:3306

          du coup ca marche quand tu te connectes sur 3345 qui mappe le 3306 du localhost du docker
          mais pas quand tu arrives de l'exterieur

          de memoire y a une ligne à decommenter pour autoriser les connexions distantes à mysql

          • [^] # Re: un début de réponse

            Posté par  (site web personnel) . Évalué à 1. Dernière modification le 13 novembre 2018 à 10:26.

            J'y ai bien pensé du coups dans le my.cnf j'ai mis

            bind-address = 0.0.0.0

            Et relancer le service mais même punition.

            Born to Kill EndUser !

            • [^] # Re: un début de réponse

              Posté par  (site web personnel) . Évalué à 1.

              As-tu vérifié (netstat, ss, etc.) la bonne prise en compte de ce paramètre ?

              Debian Consultant @ DEBAMAX

              • [^] # Re: un début de réponse

                Posté par  (site web personnel) . Évalué à 1.

                Non pas encore mais voici le résultat

                # netstat -tln
                Active Internet connections (only servers)
                Proto Recv-Q Send-Q Local Address           Foreign Address         State      
                tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN     
                tcp        0      0 0.0.0.0:3306            0.0.0.0:*               LISTEN     
                tcp6       0      0 :::80                   :::*                    LISTEN     
                tcp6       0      0 :::22                   :::*                    LISTEN 
                
                
                # netstat -a
                Active Internet connections (servers and established)
                Proto Recv-Q Send-Q Local Address           Foreign Address         State      
                tcp        0      0 0.0.0.0:ssh             0.0.0.0:*               LISTEN     
                tcp        0      0 0.0.0.0:mysql           0.0.0.0:*               LISTEN     
                tcp6       0      0 [::]:http               [::]:*                  LISTEN     
                tcp6       0      0 [::]:ssh                [::]:*                  LISTEN     
                Active UNIX domain sockets (servers and established)
                Proto RefCnt Flags       Type       State         I-Node   Path
                unix  2      [ ACC ]     STREAM     LISTENING     178616126 /var/run/mysqld/mysqld.sock
                

                Il y a bien mysql en écoute

                # ss -l    
                Netid State      Recv-Q Send-Q                                                        Local Address:Port                                                                         Peer Address:Port                
                nl    UNCONN     0      0                                                                      rtnl:kernel                                                                                   *                     
                nl    UNCONN     0      0                                                                      rtnl:12933                                                                                    *                     
                nl    UNCONN     4352   0                                                                   tcpdiag:ss/2763                                                                                  *                     
                nl    UNCONN     768    0                                                                   tcpdiag:kernel                                                                                   *                     
                nl    UNCONN     0      0                                                                      xfrm:kernel                                                                                   *                     
                nl    UNCONN     0      0                                                                 fiblookup:kernel                                                                                   *                     
                nl    UNCONN     0      0                                                                    uevent:kernel                                                                                   *                     
                nl    UNCONN     0      0                                                                      genl:kernel                                                                                   *                     
                u_str LISTEN     0      80                                              /var/run/mysqld/mysqld.sock 178616126                                                                               * 0                    
                tcp   LISTEN     0      128                                                                       *:ssh                                                                                     *:*                    
                tcp   LISTEN     0      80                                                                        *:mysql                                                                                   *:*                    
                tcp   LISTEN     0      128                                                                      :::http                                                                                   :::*                    
                tcp   LISTEN     0      128                                                                      :::ssh                                                                                    :::*  
                

                Born to Kill EndUser !

                • [^] # Re: un début de réponse

                  Posté par  (site web personnel) . Évalué à 1. Dernière modification le 19 novembre 2018 à 09:35.

                  Bon d'après le support de traefik il n'est pas possible d'utiliser le reverse pour mysql parce-que :

                  traefik cant proxy mysq, as this is plain TCP

                  Reste à trouver un équivalent à traefik.

                  Born to Kill EndUser !

                  • [^] # Re: un début de réponse

                    Posté par  . Évalué à 2.

                    Reste à trouver un équivalent à traefik.

                    haproxy sait faire du proxy http et TCP
                    du coup le mieux ca reste de tout faire en TCP,

                    comme ca tu geres le certificat SSL dans le docker pour le https aussi

                    et il peut faire du SNI meme en TCP,
                    il regarde le SNI puis envoie sur le serveur final en TCP et laisse le serveur final chiffrer la connexion

                    • [^] # Re: un début de réponse

                      Posté par  (site web personnel) . Évalué à 1.

                      J'y ai pensé mais est-ce que haproxy est capable de créer le reverse tout seul à chaque ajout de container ou bien est-ce qu'il faut le faire à la main ?

                      Born to Kill EndUser !

                      • [^] # Re: un début de réponse

                        Posté par  . Évalué à 2.

                        il ne peut pas le faire tout seul,

                        traefik non plus d'ailleurs, si ? il devine tout seul les ports ouverts sur ton docker et le port sur lequel tu veux le joindre sur l'exterieur ?

                        dans les deux cas il doit y avoir un fichier à configurer ou un script à lancer

                        • [^] # Re: un début de réponse

                          Posté par  (site web personnel) . Évalué à 1.

                          Pour traefik lorsque tu créé le conteneur tu annonce via les labels différents paramètres dont les ports à utiliser, le nom auquel il va répondre… Ensuite treafik accède directement à docker, il détecte tout ça et hop le reverse se fait.

                          C'est franchement très très simple à utiliser au quotidien.

                          Born to Kill EndUser !

                          • [^] # Re: un début de réponse

                            Posté par  . Évalué à 2.

                            donc traefik va lire les fichiers de docker pour savoir quoi faire
                            ca te simplifie le boulot,

                            mais ce n'est pas insurmontable non plus de faire un fichier haproxy

                            listen nom-du-service-que-tu-veux
                                    bind IP:PORT # ou haproxy va ecouter
                                    server nomverslequeltupointes IP_DOCKER:PORT_DOCKER
                            • [^] # Re: un début de réponse

                              Posté par  (site web personnel) . Évalué à 1.

                              Oui certes c'est pas compliqué mais pour autant ça ajoute une étape :

                              Avec traefik lancé en container lui aussi
                              - création du/des containers avec les labels qui vont bien
                              - traefik récupère tout seul les infos des containers via /var/run/docker.sock

                              Avec haproxy lancé en container
                              - création du/des containers
                              - creation du fichier dans le container haproxy
                              - bien pensé à commiter le container haproxy ou alors l'avoir créé avec un volume mappé sur le serveur.

                              C'est une analyse rapide car je n'ai jamais utilisé haproxy. En parallèle je test https://github.com/jwilder/nginx-proxy qui reproduit le même comportement que traefik mais en étant pas limité à http… Enfin c'est ce que j'ai compris.

                              Born to Kill EndUser !

                              • [^] # Re: un début de réponse

                                Posté par  (site web personnel) . Évalué à 1.

                                Contrairement à ce qui a été annoncé pas moyen, de faire du reverse proxy pour mysql avec nginx-proxy :(

                                Born to Kill EndUser !

                                • [^] # Re: un début de réponse

                                  Posté par  . Évalué à 2.

                                  voici un exemple qui devrait fonctionner avec haproxy

                                  on ecoute sur TONPORT de la machine principale, en mode TCP
                                  on regarde si c'est du SSL et si le domaine est www.domaine1.tld ou www.domain2.tld
                                  si c'est le cas on envoie vers le bon docker/port
                                  sinon on envoie sur le fourretout

                                  evidemment il faut que l'application sache faire du SNI (envoyer le domaine dans la requete)

                                  frontend tonservice-SSL
                                    bind *:TONPORT                 #alctl: listener https configuration.
                                    mode tcp                                                  #alctl: load balancing algorythm
                                    log global                                                 #alctl: log activation
                                    #option tcplog                                             #alctl: log format
                                    timeout client 25s                                         #alctl: client inactivity timeout
                                    maxconn 1000                                               #alctl: connections maximum
                                  
                                           # attente d'un client hello et rejet si pas de SNI
                                          tcp-request inspect-delay 5s
                                          tcp-request content reject if ! { req.ssl_sni -m found }
                                  
                                          use_backend premier_service-ssl if { req.ssl_sni -i www.domain1.tld }
                                          use_backend deuxieme_service-ssl if { req.ssl_sni -i www.domain2.tld }
                                          default_backend fourre-tout
                                  
                                  backend fourre-tout
                                    mode tcp
                                    option tcplog
                                    server local localhost:port_fourretout check
                                  
                                  backend premier_service-ssl
                                      mode tcp
                                    option tcplog                                              #alctl: log format
                                    #default-server inter 3s rise 2 fall 3                      #alctl: default check parameters
                                      server docker1 ip_docker1:portD1 check
                                  
                                  
                                  backend deuxieme_service-ssl
                                      mode tcp
                                    option tcplog                                              #alctl: log format
                                    #default-server inter 3s rise 2 fall 3                      #alctl: default check parameters
                                    server docker2 ip_docker2:portD2 check

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.