{"id":887,"date":"2020-05-04T17:54:05","date_gmt":"2020-05-04T15:54:05","guid":{"rendered":"https:\/\/blog.tiraquelibras.com\/?p=887"},"modified":"2020-05-04T17:54:08","modified_gmt":"2020-05-04T15:54:08","slug":"docker-contenedores-en-redes-independientes-y-como-conectarlos","status":"publish","type":"post","link":"https:\/\/blog.tiraquelibras.com\/?p=887","title":{"rendered":"Docker: Contenedores en redes independientes y como conectarlos"},"content":{"rendered":"\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_76 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Tabla de contenidos<\/p>\n<label for=\"ez-toc-cssicon-toggle-item-69f0d73db5adc\" class=\"ez-toc-cssicon-toggle-label\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/label><input type=\"checkbox\"  id=\"ez-toc-cssicon-toggle-item-69f0d73db5adc\"  aria-label=\"Alternar\" \/><nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=887\/#Introduccion\"  rel=\"nofollow\" target=\"_blank\">Introducci\u00f3n<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=887\/#Supuesto\"  rel=\"nofollow\" target=\"_blank\">Supuesto<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=887\/#Redes\"  rel=\"nofollow\" target=\"_blank\">Redes<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-4 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=887\/#Crear_nuevas_redes\"  rel=\"nofollow\" target=\"_blank\">Crear nuevas redes<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-5 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=887\/#Contenedores\"  rel=\"nofollow\" target=\"_blank\">Contenedores<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-6 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=887\/#Crear_nuevos_Contenedores\"  rel=\"nofollow\" target=\"_blank\">Crear nuevos Contenedores<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-7 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=887\/#Redes_asignadas_en_los_Contenedores\"  rel=\"nofollow\" target=\"_blank\">Redes asignadas en los Contenedores<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-8 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=887\/#Conectividad_entre_Contenedores\"  rel=\"nofollow\" target=\"_blank\">Conectividad entre Contenedores<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-9 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=887\/#Permitir_conectividad_entre_Contenedores\"  rel=\"nofollow\" target=\"_blank\">Permitir conectividad entre Contenedores<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-10 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=887\/#Asignar_el_Contenedor_a_la_red_destino\"  rel=\"nofollow\" target=\"_blank\">Asignar el Contenedor a la red destino<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-11 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=887\/#FW_IPTABLES_en_Docker_Host\"  rel=\"nofollow\" target=\"_blank\">FW (IPTABLES) en Docker Host<\/a><\/li><\/ul><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-12 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=887\/#Conclusion\"  rel=\"nofollow\" target=\"_blank\">Conclusi\u00f3n<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-13 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=887\/#Enlaces_de_interes\"  rel=\"nofollow\" target=\"_blank\">Enlaces de inter\u00e9s<\/a><\/li><\/ul><\/nav><\/div>\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Introduccion\"><\/span>Introducci\u00f3n<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>En <strong>Docker<\/strong> existen distintos tipos de redes, las cuales se interconectan usando lo se denominan <strong>Drivers<\/strong>. Existen distintos tipos de <strong>Drivers<\/strong> que podemos utilizar para proveer de funcionalidades de red a nuestros Contenedores:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>Bridge<\/strong>: es el driver por defecto si no se especifica ninguno a la hora de crear el Contenedor. Est\u00e1 destinado a aplicaciones que corren en Contenedores independientes que precisan comunicarse entre ellas. Cada Contenedor tendr\u00e1 su propia IP, pudiendo segmentar el direccionamiento en subredes distintas, permitiendo controlar las comunicaciones entre dispositivos y servicios dentro del mismo Docker Host.<\/li><\/ul>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"651\" height=\"401\" src=\"https:\/\/blog.tiraquelibras.com\/wp-content\/uploads\/2020\/05\/Docker-net-bridge.png\" alt=\"\" class=\"wp-image-888\"\/><figcaption>Docker Bridge<\/figcaption><\/figure><\/div>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>Host<\/strong>: para Contenedores independientes, eliminando el aislamiento de red entre el Contenedor y el Docker Host, usando el mismo direccionamiento en ambos equipos. Es decir, ambos comparten la misma IP.<\/li><\/ul>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"651\" height=\"402\" src=\"https:\/\/blog.tiraquelibras.com\/wp-content\/uploads\/2020\/05\/Docker-net-host.png\" alt=\"\" class=\"wp-image-889\"\/><figcaption>Docker Host<\/figcaption><\/figure><\/div>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>Overlay<\/strong>: conecta m\u00faltiples demonios de Docker entre s\u00ed y habilita los servicios de <strong>Swarm<\/strong> para comunicarse unos entre otros. Es el mejor cuando necesitamos conectar Contenedores ubicados en distintos Docker Hosts, o cuando m\u00faltiples aplicaciones trabajan juntas usando servicios <strong>Swarm<\/strong>.<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"651\" height=\"401\" src=\"https:\/\/blog.tiraquelibras.com\/wp-content\/uploads\/2020\/05\/Docker-net-overlay.png\" alt=\"\" class=\"wp-image-890\"\/><figcaption>Docker Overlay<\/figcaption><\/figure>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>Macvlan<\/strong>: permite asignar una direcci\u00f3n MAC a un Contendor, simulando ser un host f\u00edsico en la red. Destinado para aplicaciones legacy que precisan estar conectadas f\u00edsicamente a la red en lugar de a un Docker Host.<\/li><li><strong>None<\/strong>: cuando un Contenedor tiene deshabilitadas todas las redes. No disponible para servicios <strong>Swarm<\/strong>.<\/li><li><strong>Plugin de terceros<\/strong>: para integrar Docker con redes especializadas de terceros.<\/li><\/ul>\n\n\n\n<p>En esta entrada nos vamos a centrar en c\u00f3mo crear Contenedores ubicados en redes independientes y aisladas entre s\u00ed, y en c\u00f3mo permitir la comunicaci\u00f3n entre ellos, usando redes con Drivers de tipo <strong>Bridge<\/strong>.<\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Supuesto\"><\/span>Supuesto<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Supongamos que ofrecemos microservicios con la tecnolog\u00eda <strong>Docker<\/strong> desde un mismo <strong>Docker Host<\/strong> y precisamos independizar la comunicaci\u00f3n entre estos y permitirla entre nodos concretos si fuera preciso. Tambi\u00e9n podemos imaginarnos un entorno en el que ofrecemos servidores Web como microservicios y con una base de datos MySQL unificada para todos ellos y en una red segura sin ning\u00fan puerto expuesto hac\u00eda Internet. O simplemente disponer de un entorno de preproducci\u00f3n y otro de producci\u00f3n independientes. Existen muchos supuestos posibles para abordar este tema.<\/p>\n\n\n\n<p>El entorno en el que nos vamos a centrar cuenta con:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Dos subredes independientes.<\/li><li>Dos Contenedores creados a partir de la imagen oficial <strong>ubuntu:latest<\/strong> modificada \u00fanicamente con el servicio <strong>ping<\/strong> instalado.<\/li><li>Docker Host corriendo en Debian 9.<\/li><\/ul>\n\n\n\n<p class=\"has-text-color has-vivid-red-color\"><strong>Vamos al l\u00edo!!!<\/strong><\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Redes\"><\/span>Redes<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Por defecto disponemos de las siguienets redes en una instalaci\u00f3n limpia de <strong>Docker<\/strong>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\"># docker network ls\nNETWORK ID          NAME                DRIVER              SCOPE\n00195108f37e        bridge              bridge              local\nd41425e0dad0        host                host                local\n515fa5624551        none                null                local<\/code><\/pre>\n\n\n\n<div style=\"height:25px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Crear_nuevas_redes\"><\/span>Crear nuevas redes<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Vamos a crear dos subredes indpenedientes, bajo el direccionamiento <strong><em>192.169.0.0\/16<\/em><\/strong> y de tipo <strong>Bridge<\/strong>, que llamaremos <strong>net_A<\/strong> (192.169.5.0\/24) y <strong>net_B<\/strong> (192.169.6.0\/24):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\"># docker network create --driver bridge --subnet=192.169.5.0\/24 --ip-range=192.169.5.0\/24 net_A\ne3ea14fdce1f4b59690e753eed767e69fe0206ec855cdc175983d3dc29dfb3cb\n\n# docker network create --driver bridge --subnet=192.169.6.0\/24 --ip-range=192.169.6.0\/24 net_B\n4bc6f7e9bccc7f639ce43bf4ba838dfce6f143e083955cd682f94af1eebb8559<\/code><\/pre>\n\n\n\n<p>En estos momentos el lisado de redes ser\u00eda el siguiente:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\"># docker network ls\nNETWORK ID          NAME                DRIVER              SCOPE\n00195108f37e        bridge              bridge              local\nd41425e0dad0        host                host                local\ne3ea14fdce1f        net_A               bridge              local\n4bc6f7e9bccc        net_B               bridge              local\n515fa5624551        none                null                local<\/code><\/pre>\n\n\n\n<p>Cada una con su direccionamiento propio, pero a\u00fan sin Contenedores asignados:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\"># docker network inspect net_A\n[\n    {\n        \"Name\": \"net_A\",\n        \"Id\": \"e3ea14fdce1f4b59690e753eed767e69fe0206ec855cdc175983d3dc29dfb3cb\",\n        \"Created\": \"2020-04-29T11:40:34.083305502+02:00\",\n        \"Scope\": \"local\",\n        \"Driver\": \"bridge\",\n        \"EnableIPv6\": false,\n        \"IPAM\": {\n            \"Driver\": \"default\",\n            \"Options\": {},\n            \"Config\": [\n                {\n                    \"Subnet\": \"192.169.5.0\/24\",\n                    \"IPRange\": \"192.169.5.0\/24\"\n                }\n            ]\n        },\n        \"Internal\": false,\n        \"Attachable\": false,\n        \"Ingress\": false,\n        \"ConfigFrom\": {\n            \"Network\": \"\"\n        },\n        \"ConfigOnly\": false,\n        \"Containers\": {}\n        },\n        \"Options\": {},\n        \"Labels\": {}\n    }\n]\n\n# docker network inspect net_B\n[\n    {\n        \"Name\": \"net_B\",\n        \"Id\": \"4bc6f7e9bccc7f639ce43bf4ba838dfce6f143e083955cd682f94af1eebb8559\",\n        \"Created\": \"2020-04-29T11:40:50.303744508+02:00\",\n        \"Scope\": \"local\",\n        \"Driver\": \"bridge\",\n        \"EnableIPv6\": false,\n        \"IPAM\": {\n            \"Driver\": \"default\",\n            \"Options\": {},\n            \"Config\": [\n                {\n                    \"Subnet\": \"192.169.6.0\/24\",\n                    \"IPRange\": \"192.169.6.0\/24\"\n                }\n            ]\n        },\n        \"Internal\": false,\n        \"Attachable\": false,\n        \"Ingress\": false,\n        \"ConfigFrom\": {\n            \"Network\": \"\"\n        },\n        \"ConfigOnly\": false,\n        \"Containers\": {}\n        },\n        \"Options\": {},\n        \"Labels\": {}\n    }\n]<\/code><\/pre>\n\n\n\n<p>Incidar que la primera IP de cada rango est\u00e1 destinado al <strong>Gateway<\/strong> de cada red, como veremos m\u00e1s adelante cuando creemos los Contenedores.<\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Contenedores\"><\/span>Contenedores<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Creamos dos contenedores a partir de la imagen <strong>ubuntu:latest<\/strong> a la que le hemso instalado el servicio <strong>Ping<\/strong>, la cual llamamos <strong>ubuntu_ping:latest<\/strong>, aunque podemos instalar este en el Contenedor cuando lo creemos. Esta entrada no se basa en explicar como crear im\u00e1genes personalizadas, por lo que dejamos a elecci\u00f3n del lector investigar para saber c\u00f3mo se hace o bien instalar el servicio en cada Contenedor una vez arrancado.<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Crear_nuevos_Contenedores\"><\/span>Crear nuevos Contenedores<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>En el comando de creaci\u00f3n indicaremos el nombre del Contenedor, <strong>ubuntu_A<\/strong> y <strong>ubuntu_B<\/strong>, e indicaremos para cada uno una red distinta de las creadas en el apartado anterior, <strong>net_A<\/strong> y <strong>net_B<\/strong> respectivamente. Estos ser\u00e1n creados en modo interactivo (<strong>-it<\/strong>) y en segundo plano (<strong>-d<\/strong>):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\"># docker container run -itd --name ubuntu_A --network net_A  ubuntu_ping\nf531122b80e35f1d9f8202c2d7b7df686520788836101026ddb26a20ae87fe3b\n\n# docker container run -itd --name ubuntu_B --network net_B  ubuntu_ping\n718c3cf82a4e5bbe956bd2cefa452d95b0dc13eb6a9b1a25efab660b35441941<\/code><\/pre>\n\n\n\n<p>Estar\u00edan ambos arrancados si no se mostr\u00f3 error alguno durante su creaci\u00f3n:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\"># docker ps\nCONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES\n718c3cf82a4e        ubuntu_ping         \"bash\"                   8 seconds ago       Up 2 seconds                                 ubuntu_B\nf531122b80e3        ubuntu_ping         \"bash\"                   16 seconds ago      Up 14 seconds                                ubuntu_A<\/code><\/pre>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Redes_asignadas_en_los_Contenedores\"><\/span>Redes asignadas en los Contenedores<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Si inspeccionamos ambos Contenedores podemos ver que cada uno est\u00e1 asignado a una red distinta, con su direccionamiento y el de su Gateway correspondiente:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\"># docker container inspect f531122b80e3\n...\n            \"Networks\": {\n                \"net_A\": {\n                    \"IPAMConfig\": null,\n                    \"Links\": null,\n                    \"Aliases\": [\n                        \"f531122b80e3\"\n                    ],\n                    \"NetworkID\": \"e3ea14fdce1f4b59690e753eed767e69fe0206ec855cdc175983d3dc29dfb3cb\",\n                    \"EndpointID\": \"732b715c1beff252db77d3e90c38a84ea86e494903eac199b41a486f5e14afa5\",\n                    \"Gateway\": \"192.169.5.1\",\n                    \"IPAddress\": \"192.169.5.2\",\n                    \"IPPrefixLen\": 24,\n                    \"IPv6Gateway\": \"\",\n                    \"GlobalIPv6Address\": \"\",\n                    \"GlobalIPv6PrefixLen\": 0,\n                    \"MacAddress\": \"02:42:c0:a9:05:02\",\n                    \"DriverOpts\": null\n                }\n            }\n\n# docker container inspect 718c3cf82a4e\n...\n            \"Networks\": {\n                \"net_B\": {\n                    \"IPAMConfig\": null,\n                    \"Links\": null,\n                    \"Aliases\": [\n                        \"718c3cf82a4e\"\n                    ],\n                    \"NetworkID\": \"4bc6f7e9bccc7f639ce43bf4ba838dfce6f143e083955cd682f94af1eebb8559\",\n                    \"EndpointID\": \"f522fb6265f2a4bcc360f89b17f5907dcf2d0a5017f31b3b117ef47f688e2ffc\",\n                    \"Gateway\": \"192.169.6.1\",\n                    \"IPAddress\": \"192.169.6.2\",\n                    \"IPPrefixLen\": 24,\n                    \"IPv6Gateway\": \"\",\n                    \"GlobalIPv6Address\": \"\",\n                    \"GlobalIPv6PrefixLen\": 0,\n                    \"MacAddress\": \"02:42:c0:a9:06:02\",\n                    \"DriverOpts\": null\n                }\n            }<\/code><\/pre>\n\n\n\n<p>Tal y como se indic\u00f3 antes, la primera IP de cada rango est\u00e1 destinada al <strong>Gateway<\/strong> de cada red, siendo las IPs sucesivas las que Docker va destinando a los Contenedores que se van agregando a la red. En este caso Docker asignar\u00e1 la siguiente primera IP libre dentro de cada rango, siendo en este caso las IPs 192.169.5.2 y 192.169.6.2 respectivamente.<\/p>\n\n\n\n<p>Si inspeccionamos de nuevo las redes podemos ver como ya tienen Contenedores asignados, en donde se muestra informaci\u00f3n de cada uno, como la IP asignada:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\"># docker network inspect net_A\n...\n        \"Containers\": {\n            \"f531122b80e35f1d9f8202c2d7b7df686520788836101026ddb26a20ae87fe3b\": {\n                \"Name\": \"ubuntu_A\",\n                \"EndpointID\": \"732b715c1beff252db77d3e90c38a84ea86e494903eac199b41a486f5e14afa5\",\n                \"MacAddress\": \"02:42:c0:a9:05:02\",\n                \"IPv4Address\": \"192.169.5.2\/24\",\n                \"IPv6Address\": \"\"\n            }\n        },\n...\n\n# docker network inspect net_B\n...\n        \"Containers\": {\n            \"718c3cf82a4e5bbe956bd2cefa452d95b0dc13eb6a9b1a25efab660b35441941\": {\n                \"Name\": \"ubuntu_B\",\n                \"EndpointID\": \"f522fb6265f2a4bcc360f89b17f5907dcf2d0a5017f31b3b117ef47f688e2ffc\",\n                \"MacAddress\": \"02:42:c0:a9:06:02\",\n                \"IPv4Address\": \"192.169.6.2\/24\",\n                \"IPv6Address\": \"\"\n            }\n        },\n...<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Conectividad_entre_Contenedores\"><\/span>Conectividad entre Contenedores<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Si accedemos a cada Contenedor podemos comprobar la conectividad entre el resto de Contenedor y los Gateways de cada subred.<\/p>\n\n\n\n<p>En ete caso s\u00ed podemos hacer ping al Gateway de todas las subredes, pero no a la IP de los Contenedores en redes distintas. Por ejemplo:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Accedemos a la consola del Contenedor <strong>ubuntu_A<\/strong>:<\/li><\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\"># docker exec -it f531122b80e3 bash<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\"><li>Hacemos ping hacia ambos Gateways creados (192.169.5.1 y 192.169.6.1), el cual funciona en todos los casos:<\/li><\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\"># ping 192.169.5.1\nPING 192.169.5.1 (192.169.5.1) 56(84) bytes of data.\n64 bytes from 192.169.5.1: icmp_seq=1 ttl=64 time=0.425 ms\n64 bytes from 192.169.5.1: icmp_seq=2 ttl=64 time=0.264 ms\n64 bytes from 192.169.5.1: icmp_seq=3 ttl=64 time=0.259 ms\n^C\n--- 192.169.5.1 ping statistics ---\n3 packets transmitted, 3 received, 0% packet loss, time 2079ms\nrtt min\/avg\/max\/mdev = 0.259\/0.316\/0.425\/0.077 ms\n#\n# ping 192.169.6.1\nPING 192.169.6.1 (192.169.6.1) 56(84) bytes of data.\n64 bytes from 192.169.6.1: icmp_seq=1 ttl=64 time=0.332 ms\n64 bytes from 192.169.6.1: icmp_seq=2 ttl=64 time=0.259 ms\n^C\n--- 192.169.6.1 ping statistics ---\n2 packets transmitted, 2 received, 0% packet loss, time 1012ms\nrtt min\/avg\/max\/mdev = 0.259\/0.295\/0.332\/0.040 ms<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\"><li>Hacemos ping a la IP del Contenedor de la subred distinta (192.169.6.2), el cual falla:<\/li><\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">root@f531122b80e3:\/# ping 192.169.6.2\nPING 192.169.6.2 (192.169.6.2) 56(84) bytes of data.\n^C\n--- 192.169.6.2 ping statistics ---\n8 packets transmitted, 0 received, 100% packet loss, time 7262ms<\/code><\/pre>\n\n\n\n<p>Confirmamos que los Contenedores de ambas subredes no son accesibles entre ellos. A continuaci\u00f3n veremos como solucionar este punto, llegado al caso de necesitar conectividad entre ambos Contenedores.<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Permitir_conectividad_entre_Contenedores\"><\/span>Permitir conectividad entre Contenedores<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Para permitir la conectividad entre ambos Contenedores tenemos dos m\u00e9todos distintos:<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Asignar_el_Contenedor_a_la_red_destino\"><\/span>Asignar el Contenedor a la red destino<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p>El m\u00e9todo recomendado por <strong>Docker<\/strong> es asignar el Contenedor a la otra red, de tal forma que este tendr\u00eda una nueva interfaz de red con una IP en el otro segmento de red, permitiendo conectarse con el resto de Contenedores de esta. Esto genera dos inconveneintes:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Conectividad con el resto de Contenedores de la red agregada.<\/li><li>Conectividad con todos los puertos de los Contenedores de la red agregada.<\/li><li>Disponer de una IP libre en la red que vamos a agregar.<\/li><\/ul>\n\n\n\n<p>De todas formas, si ninguno de los inconvenientes anterioers fueran un problema podemos proceder a establecer la comunicaci\u00f3n usando este m\u00e9todo.<\/p>\n\n\n\n<p>Agregamos la nueva red a cada Contenedor:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\"># docker network connect net_A ubuntu_B<\/code><\/pre>\n\n\n\n<p>Si inspeccionamos el Contenedor <strong>ubuntu_A<\/strong> vemos la nueva red agregada:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\"># docker container inspect ubuntu_A\n...\n            \"Networks\": {\n                \"net_A\": {\n                    \"IPAMConfig\": null,\n                    \"Links\": null,\n                    \"Aliases\": [\n                        \"f531122b80e3\"\n                    ],\n                    \"NetworkID\": \"e3ea14fdce1f4b59690e753eed767e69fe0206ec855cdc175983d3dc29dfb3cb\",\n                    \"EndpointID\": \"732b715c1beff252db77d3e90c38a84ea86e494903eac199b41a486f5e14afa5\",\n                    \"Gateway\": \"192.169.5.1\",\n                    \"IPAddress\": \"192.169.5.2\",\n                    \"IPPrefixLen\": 24,\n                    \"IPv6Gateway\": \"\",\n                    \"GlobalIPv6Address\": \"\",\n                    \"GlobalIPv6PrefixLen\": 0,\n                    \"MacAddress\": \"02:42:c0:a9:05:02\",\n                    \"DriverOpts\": null\n                },\n                \"net_B\": {\n                    \"IPAMConfig\": {},\n                    \"Links\": null,\n                    \"Aliases\": [\n                        \"f531122b80e3\"\n                    ],\n                    \"NetworkID\": \"4bc6f7e9bccc7f639ce43bf4ba838dfce6f143e083955cd682f94af1eebb8559\",\n                    \"EndpointID\": \"80b793958c42e81789f3308c0cfdf904377bcbb080e2e522b427770837a22225\",\n                    \"Gateway\": \"192.169.6.1\",\n                    \"IPAddress\": \"192.169.6.3\",\n                    \"IPPrefixLen\": 24,\n                    \"IPv6Gateway\": \"\",\n                    \"GlobalIPv6Address\": \"\",\n                    \"GlobalIPv6PrefixLen\": 0,\n                    \"MacAddress\": \"02:42:c0:a9:06:03\",\n                    \"DriverOpts\": {}\n                }\n            }\n...<\/code><\/pre>\n\n\n\n<p>Si nos conectamos a un Contenedor vemos la nueva interfaz de red agregada (192.169.6.3):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\"># docker exec -it f531122b80e3 bash\n\nroot@f531122b80e3:\/# ifconfig\neth0: flags=4163&lt;UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500\n        inet 192.169.5.2  netmask 255.255.255.0  broadcast 192.169.5.255\n        ether 02:42:c0:a9:05:02  txqueuelen 0  (Ethernet)\n        RX packets 4600  bytes 1840120 (1.8 MB)\n        RX errors 0  dropped 0  overruns 0  frame 0\n        TX packets 329  bytes 28019 (28.0 KB)\n        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0\n\neth2: flags=4163&lt;UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500\n        inet 192.169.6.3  netmask 255.255.255.0  broadcast 192.169.6.255\n        ether 02:42:c0:a9:06:03  txqueuelen 0  (Ethernet)\n        RX packets 30  bytes 4348 (4.3 KB)\n        RX errors 0  dropped 2  overruns 0  frame 0\n        TX packets 2  bytes 493 (493.0 B)\n        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0\n\nlo: flags=73&lt;UP,LOOPBACK,RUNNING>  mtu 65536\n        inet 127.0.0.1  netmask 255.0.0.0\n        loop  txqueuelen 1000  (Local Loopback)\n        RX packets 6  bytes 476 (476.0 B)\n        RX errors 0  dropped 0  overruns 0  frame 0\n        TX packets 6  bytes 476 (476.0 B)\n        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0<\/code><\/pre>\n\n\n\n<p>Ya funcionar\u00eda el PING entre equipos hacia las mismas redes, por ejemplo desde <strong>ubuntu_A<\/strong> hacia <strong>ubuntu_B<\/strong>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\"># ping 192.169.6.2\nPING 192.169.6.2 (192.169.6.2) 56(84) bytes of data.\n64 bytes from 192.169.6.2: icmp_seq=1 ttl=64 time=0.762 ms\n64 bytes from 192.169.6.2: icmp_seq=2 ttl=64 time=0.350 ms\n64 bytes from 192.169.6.2: icmp_seq=3 ttl=64 time=0.357 ms\n^C\n--- 192.169.6.2 ping statistics ---\n3 packets transmitted, 3 received, 0% packet loss, time 2052ms\nrtt min\/avg\/max\/mdev = 0.350\/0.489\/0.762\/0.194 ms<\/code><\/pre>\n\n\n\n<p>Desconectamos la red para explicar el siguiente apartado:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">root@f531122b80e3:\/# exit\nexit\n# docker network disconnect net_B ubuntu_A<\/code><\/pre>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"FW_IPTABLES_en_Docker_Host\"><\/span>FW (IPTABLES) en Docker Host<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p>Por defecto <strong>Docker<\/strong> usa <strong>IPTABLES<\/strong> para comunicar los elementos de su tecnolog\u00eda en el Docker Host que lo contiene. Entre las reglas creadas podemos encontrar dos reglas personalizadas:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>DOCKER<\/strong>: es donde <strong>Docker<\/strong> agrega todas sus cadenas de reglas, la cual se recomienda no manipular manualmente.<\/li><li><strong>DOCKER-USER<\/strong>: es donde cada usuario puede agregar, borrar o modificar sus reglas personalizadas, las cuales son aplicadas antes que las creadas autom\u00e1ticamente por <strong>Docker<\/strong>.<\/li><li><strong>FORWARD<\/strong>: pueden ser creadas manualmente o por otro firewall basado en IPTABLES, y ser\u00e1n evaluadas despu\u00e9s que las anteriores. Esto significa que si exponemos un puerto a trav\u00e9s de <strong>Docker<\/strong> este qeuda expuesto sin importar las reglas que el Firewall haya configurado, debiendo ser agregadas estas reglas a la cadena <strong>DOCKER-USER<\/strong>.<\/li><\/ul>\n\n\n\n<p>En nuestro caso vamos a agregar una regla en la cadena <strong>DOCKER-USER<\/strong> que permita el <strong>ICMP<\/strong> o <strong>Ping<\/strong> entre ambos Contenedores:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\"># iptables -I DOCKER-USER -s 192.169.5.2 -d 192.169.6.2 -p icmp -j ACCEPT\n# iptables -I DOCKER-USER -s 192.169.6.2 -d 192.169.5.2 -p icmp -j ACCEPT<\/code><\/pre>\n\n\n\n<p>La regla en el Firewall quedar\u00eda de la sigiuente forma:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\"># iptables -L -n -v\n...\nChain DOCKER-USER (1 references)\n pkts bytes target     prot opt in     out     source               destination\n    2   168 ACCEPT     icmp --  *      *       192.169.6.2          192.169.5.2\n   11   924 ACCEPT     icmp --  *      *       192.169.5.2          192.169.6.2\n 4669 4016K RETURN     all  --  *      *       0.0.0.0\/0            0.0.0.0\/0\n# Warning: iptables-legacy tables present, use iptables-legacy to see them<\/code><\/pre>\n\n\n\n<p>Ahora comprobamos si funciona la conectividad conect\u00e1ndonos de nuevo al Contenedor <strong>ubuntu_A<\/strong> y lanzando un <strong>Ping<\/strong> hacia el Contenedor <strong>ubuntu_B<\/strong>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\"># docker exec -it f531122b80e3 bash\nroot@f531122b80e3:\/# ping 192.169.6.2\nPING 192.169.6.2 (192.169.6.2) 56(84) bytes of data.\n64 bytes from 192.169.6.2: icmp_seq=1 ttl=63 time=0.490 ms\n64 bytes from 192.169.6.2: icmp_seq=2 ttl=63 time=0.365 ms\n^C\n--- 192.169.6.2 ping statistics ---\n2 packets transmitted, 2 received, 0% packet loss, time 1080ms\nrtt min\/avg\/max\/mdev = 0.365\/0.427\/0.490\/0.065 ms<\/code><\/pre>\n\n\n\n<p>Borramos las regla en el FW si no las necesitamos:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\"># iptables -D DOCKER-USER 2\n# iptables -D DOCKER-USER 1<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Conclusion\"><\/span>Conclusi\u00f3n<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Trabajar con Contenedores de <strong>Docker<\/strong> en redes distintas dentro de un mismo <strong>Docker Host<\/strong> es posible gracias al tipo de redes <strong>Bridge<\/strong> que esta tecnolog\u00eda nos ofrece y la segmentaci\u00f3n de redes privadas dentro del mismo host. Esto nos permite controlar la conectividad entre estos de varias formas, como se ha explciado en esta entrada, ofreciendo una gran flexibilidad tanto a empresas que ofrezcan este tipo de microservicios como para usuarios individuales que usen esta tecnolog\u00eda, asegurando las comunicaciones y manteniendo nuestro entorno siempre seguro ante, por ejemplo, movimientos laterales dentro de nuestro ecosistema <strong>Docker<\/strong>.<\/p>\n\n\n\n<hr class=\"wp-block-separator is-style-default\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Enlaces_de_interes\"><\/span>Enlaces de inter\u00e9s<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Docker oficial sobre redes https:\/\/docs.docker.com\/network\/<\/p>\n\n\n\n<p>Docker oficial sobre IPTABLES https:\/\/docs.docker.com\/network\/iptables\/<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introducci\u00f3n En Docker existen distintos tipos de redes, las cuales se interconectan usando lo se denominan Drivers. Existen distintos tipos de Drivers que podemos utilizar<span class=\"read-more-link\"><a class=\"read-more\" href=\"https:\/\/blog.tiraquelibras.com\/?p=887\">Read More<\/a><\/span><\/p>\n","protected":false},"author":1,"featured_media":897,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,10,22],"tags":[101,56,107],"class_list":["post-887","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ciberseguridad","category-sistemas","category-ti","tag-docker","tag-firewall","tag-redes"],"post_mailing_queue_ids":[],"_links":{"self":[{"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=\/wp\/v2\/posts\/887","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=887"}],"version-history":[{"count":0,"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=\/wp\/v2\/posts\/887\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=\/wp\/v2\/media\/897"}],"wp:attachment":[{"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=887"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=887"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=887"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}