Un método para realizar la retención de IP en el clúster Swarm

Reimpreso de: http://dockone.io/article/1861

Introducción a Swarmkit

Swarmkit es una herramienta de orquestación de contenedores y administración de clústeres de Docker lanzada por Docker. Desde Docker 1.12, se ha integrado en Docker-engine y se ha lanzado. Swarmkit se desarrolla a partir del proyecto Swarm. Como sistema de orquestación propio de Docker, puede proporcionar funciones de orquestación de servicios, administración de clústeres y programación.

Los nodos en Swarmkit se dividen en dos categorías

  1. El nodo trabajador es responsable de ejecutar tareas a través del ejecutor. El ejecutor predeterminado de Swarmkit es Docker Container Executor;
  2. El nodo de gestión es responsable de recibir y responder a las solicitudes de los usuarios y de ajustar el estado del clúster al estado final.
    Diagrama de estructura del clúster Swarm La
    Inserte la descripción de la imagen aquí
    figura anterior muestra la organización del clúster Swarm en Docker. El clúster puede contener varios nodos de administrador, y estos administradores eligen un nodo como nodo líder. El nodo líder es responsable de la gestión de todo el clúster. Si el nodo líder falla, los nodos administradores restantes serán reelegidos y el nuevo nodo líder asumirá la administración del clúster. El nodo líder original puede volver a unirse al clúster después de la recuperación. En este momento, la identidad es normal. nodo administrador.

Swarmkit puede lograr la coherencia del estado del servicio en la orquestación del servicio y actualizar y reiniciar los servicios de acuerdo con estrategias específicas. En pocas palabras, después de que se crea el servicio, Swarmkit determina la cantidad de tareas de acuerdo con el tipo de servicio y genera las tareas correspondientes, verifica regularmente para asegurarse de que la cantidad de tareas sea estable y envía estas tareas a cada nodo trabajador de acuerdo con la programación. estrategia. Si un nodo no está disponible, el nodo líder migrará las tareas en ese nodo a otros nodos disponibles para continuar ejecutándose, y también puede aumentar o disminuir la cantidad de tareas según los comandos del usuario. Consulte la documentación oficial para conocer los métodos de uso específicos. La siguiente figura muestra la estructura interna de Swarmkit. Swarmkit realiza la gestión de los recursos de la red a través de libnetwork.
Diagrama esquemático de la estructura interna de Swarmkit.
Inserte la descripción de la imagen aquí

Preguntas planteadas

Desde la perspectiva de la operación y el mantenimiento, con el fin de mejorar la eficiencia de la operación y el mantenimiento, se espera que la dirección IP del contenedor no cambie después de reiniciar o migrar el contenedor. De esta manera, el personal de operación y mantenimiento puede realizar operaciones como mantenimiento y actualizaciones en el contenedor a través de una dirección IP estática específica.

La situación real ahora es que en las versiones posteriores a Docker.10, al crear un contenedor, puede especificar su dirección IP usando la opción -ip en la línea de comando. Sin embargo, en la implementación actual de Swarmkit, al asignar una IP a una tarea de un servicio, no admite especificar una dirección IP, sino que utiliza un método de asignación aleatoria. Cuando es necesario reiniciar o migrar una tarea, no hay garantía de que las direcciones IP de los contenedores correspondientes de las dos tareas sean las mismas. Para mejorar la eficiencia de operación y mantenimiento de los clústeres de enjambre, se necesita un método para mantener las tareas correspondientes a la dirección IP del contenedor.

Ideas de realización

Después de leer la documentación y el código de Docker, se encuentra que al crear un contenedor para cada tarea, el nombre del contenedor consta de tres partes. Para obtener detalles, consulte el código a continuación (daemon / cluster / ejecutor / container / container.go name () ).
return strings.Join ([] string { c.task.ServiceAnnotations.Name , fmt.Sprint (c.task.Slot), c.task.ID }, “.”)

Se determinan el nombre del servicio y el valor de la ranura, y el sistema genera automáticamente el ID de la tarea y cambia cada vez que se reinicia o se migra. La tarea realizada por el contenedor se puede identificar de forma única por las dos primeras partes del nombre del contenedor, que se denomina aquí identificador de la tarea (el identificador de la tarea en la implementación específica de Swarmkit es similar a esto, pero se utiliza el ServiceID) .

La idea principal de la solución es asociar la dirección IP del contenedor con el ID de la tarea y guardar la relación de mapeo entre el ID de la tarea y la dirección IP asignada por Swarmkit para la tarea en el sistema. Cuando la tarea se reinicia o se migra, al contenedor recién generado se le asigna la dirección IP previamente guardada en la relación de mapeo, de modo que la dirección IP correspondiente a una tarea se pueda mantener sin cambios.

Otro tema que debe tenerse en cuenta es cómo restaurar la relación de mapeo previamente guardada en el nuevo nodo líder después de que el nodo líder no esté disponible. Una solución es escribir la relación correspondiente en el almacenamiento de estado en la Figura 1, y la otra solución es reconstruir la relación correspondiente de la lista de tareas cuando se inicializa el líder. La última solución se elige aquí, porque la primera solución también necesita aprender el uso de protobuffer y el código de implementación de almacenamiento distribuido de Swarmkit, que es más complicado de implementar.

La realización concreta de la preservación de la propiedad intelectual

Aquí se habla principalmente de la ubicación y función del código a modificar para realizar la retención de IP.

  1. Comente
    la declaración en libnetwork para verificar la validez de la dirección IP especificada . Comente la declaración en el código libnetwork para verificar la validez de la dirección IP para el contenedor con la IP especificada. Esta declaración verifica si la dirección IP especificada se asignó a el contenedor está disponible. La razón es que después de detener el contenedor, se reciclará su dirección IP, pero este reciclaje no es en tiempo real. Si la dirección IP del contenedor recién creado no se reclamó cuando se creó, la creación del contenedor fallará debido a conflictos de recursos. De hecho, el contenedor antiguo con la dirección IP se ha detenido, por lo que hacerlo no afectará la corrección del servicio. La modificación está en la función getAddress.
    Incrementar la estructura de datos que guarda la relación de mapeo Para
    mantener la relación de mapeo, en networkAllocator, parte de la información de la red se almacena en una estructura local llamada red. Para guardar la relación de mapeo, se agrega un mapa a la estructura, cuya clave es el identificador de tarea mencionado anteriormente que puede identificar de manera única una tarea, y su valor es la dirección IP correspondiente a la tarea.

  2. Agregar la función
    de asignación de IP Al asignar una dirección IP a una tarea, primero busque la estructura de datos que guarda la información de red correspondiente según el nombre de la red y búsquela en el mapa recién agregado en la estructura. Si acierta, significa que a la tarea se le ha asignado una dirección IP anteriormente. Esta vez la tarea se puede reiniciar o migrar. En este momento, la dirección IP asignada se asigna directamente a la tarea. Si no hay ningún resultado, significa que la tarea se ejecuta por primera vez y luego llama directamente a la interfaz de libnetwork para asignarle una dirección IP no utilizada. Esta función se realiza modificando la función AllocateTask y agregando la función allocateTaskIP.

  3. Agregar una función para registrar la función IP asignada
    Después de asignar una dirección IP a una tarea, los datos en el mapa recién agregado deben actualizarse. Es decir, el mapeo con el ID de tarea como clave y la dirección IP asignada como valor se guarda en el mapa. Si la tarea debe reiniciarse o migrarse en el futuro, la retención de IP se puede lograr a través de la función de asignación. Esta función se realiza modificando la función AllocateTask y agregando la función recordTaskIP.

  4. Modificación de la función
    de recuperación de IP Para lograr la retención de IP, también es necesario modificar el código de la parte de la dirección IP de la tarea de recuperación para evitar la recuperación de la dirección IP asignada. Porque una vez que se recupera la dirección IP, se puede asignar a una nueva tarea. Esto hace que sea imposible lograr la retención de la propiedad intelectual. Esta función modifica la función releaseEndpoints original.
    Agregar mapeo

  5. Función de inicialización de relación
    Esta función es responsable de la reconstrucción de los datos de mapeo después de que cambia el Líder. Una vez seleccionado el nodo como líder, será responsable de la gestión posterior del clúster. Para lograr la retención de IP, la relación de mapeo debe reconstruirse en la inicialización del líder. Este trabajo se logra modificando la función doNetworkInit y agregando la función IpmapsInit. Esta función atraviesa todas las tareas almacenadas en el almacenamiento consistente. Para cada tarea, lee la dirección IP asignada de la información de red almacenada y compara estas IP con la relación de mapeo de la identificación de la tarea se guarda en el mapa recién agregado en la red, de modo que se realiza la reconstrucción de la relación de mapeo.

Método de compilación e instalación (tome Docker 1.12.1 como ejemplo)

(1) Clone el proyecto Docker desde github y cambie a la versión 1.12.1, o descargue el código fuente de Docker 1.12.1 directamente.

(2) Modificación completa del código.

(3) Ingrese al directorio del proyecto, ingrese make shell, se instalará el entorno de desarrollo correspondiente a la versión 1.12.1, e ingrese al contenedor donde se encuentra el entorno de desarrollo.

(4) Al ingresar hack / make.sh binary, se compilará y generará un archivo ejecutable binario. En el directorio bundle / latest.

(5) Método de instalación, después de compilar y generar el archivo binario, copie el archivo al directorio / usr / bin o / usr / local / bin del sistema. El sistema host es mejor si acaba de instalar la misma versión de Docker o no está instalado Docker, de lo contrario, es posible que Docker no se inicie correctamente.

Prueba de efecto

  1. Instale el programa Docker recién compilado en tres VM. Los tres nodos son administradores. Aquí se omite el proceso de creación de clústeres y servicios.
root@vm-1476374349871:/home/ubuntu# docker service ls
ID            NAME        REPLICAS  IMAGE   COMMAND
7huiwv4vgrs7  helloworld  10/10     alpine  ping www.docker.com
root@vm-1476374349871:/home/ubuntu# docker node ls
ID                           HOSTNAME                                        STATUS  AVAILABILITY  MANAGER STATUS
bn68rlizdmnchk14fd1ft9izx    vm-1473648642890.vm-14736486428901473648642890  Ready   Active        Reachable
bu5cc1nx0aj29q984kkngeftd *  vm-1476374349871                                Ready   Active        Leader
cm1k85xgzxivrazge4qqteotv    vm-1473648611529.vm-14736486115291473648611529  Ready   Active        Reachable
root@vm-1476374349871:/home/ubuntu#

  1. Aumente el número de copias a 10, y la tarea en una de las máquinas virtuales es la siguiente
[root@vm-1473648611529 ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                 CREATED             STATUS              PORTS               NAMES
971b6cca77c4        alpine:latest       "ping www.docker.com"   2 minutes ago       Up 2 minutes                            helloworld.2.8hnyq37xrkkvoc1ddzoxxacv5
8773911a47fc        alpine:latest       "ping www.docker.com"   2 minutes ago       Up 2 minutes                            helloworld.3.9egflo60nvh1i96l1y110ejg7
1315a7fb46d1        alpine:latest       "ping www.docker.com"   2 minutes ago       Up 2 minutes                            helloworld.5.e25s0snjn960zu6xlmt3a8cqq
[root@vm-1473648611529 ~]#
  1. La IP de eth0 de helloworld.3 es 10.0.0.3
[root@vm-1473648611529 ~]# docker exec -ti 8773911a47fc sh
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:0A:00:00:03  
      inet addr:10.0.0.3  Bcast:0.0.0.0  Mask:255.255.255.0
      inet6 addr: fe80::42:aff:fe00:3%32520/64 Scope:Link
      UP BROADCAST RUNNING MULTICAST  MTU:1450  Metric:1
      RX packets:29 errors:0 dropped:0 overruns:0 frame:0
      TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
      collisions:0 txqueuelen:0 
      RX bytes:2334 (2.2 KiB)  TX bytes:648 (648.0 B)

eth1      Link encap:Ethernet  HWaddr 02:42:AC:12:00:03  
      inet addr:172.18.0.3  Bcast:0.0.0.0  Mask:255.255.0.0
      inet6 addr: fe80::42:acff:fe12:3%32520/64 Scope:Link
      UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
      RX packets:214 errors:0 dropped:0 overruns:0 frame:0
      TX packets:235 errors:0 dropped:0 overruns:0 carrier:0
      collisions:0 txqueuelen:0 
      RX bytes:19918 (19.4 KiB)  TX bytes:22174 (21.6 KiB)

lo        Link encap:Local Loopback  
      inet addr:127.0.0.1  Mask:255.0.0.0
      inet6 addr: ::1%32520/128 Scope:Host
      UP LOOPBACK RUNNING  MTU:65536  Metric:1
      RX packets:4 errors:0 dropped:0 overruns:0 frame:0
      TX packets:4 errors:0 dropped:0 overruns:0 carrier:0
      collisions:0 txqueuelen:1 
      RX bytes:334 (334.0 B)  TX bytes:334 (334.0 B)

/ # exit
[root@vm-1473648611529 ~]#
  1. Haga que el nodo no esté disponible y las tareas en la máquina virtual se reasignarán a las otras dos máquinas
[root@vm-1473648611529 ~]# docker node ls
ID                           HOSTNAME                                        STATUS  AVAILABILITY  MANAGER STATUS
bn68rlizdmnchk14fd1ft9izx    vm-1473648642890.vm-14736486428901473648642890  Ready   Active        Reachable
bu5cc1nx0aj29q984kkngeftd    vm-1476374349871                                Ready   Active        Leader
cm1k85xgzxivrazge4qqteotv *  vm-1473648611529.vm-14736486115291473648611529  Ready   Active        Reachable
[root@vm-1473648611529 ~]# docker node update --availability drain cm1k85xgzxivrazge4qqteotv
cm1k85xgzxivrazge4qqteotv
[root@vm-1473648611529 ~]# docker node ls
ID                           HOSTNAME                                        STATUS  AVAILABILITY  MANAGER STATUS
bn68rlizdmnchk14fd1ft9izx    vm-1473648642890.vm-14736486428901473648642890  Ready   Active        Leader 
bu5cc1nx0aj29q984kkngeftd    vm-1476374349871                                Ready   Active        Reachable
cm1k85xgzxivrazge4qqteotv *  vm-1473648611529.vm-14736486115291473648611529  Ready   Drain         Reachable
[root@vm-1473648611529 ~]# docker service ls
ID            NAME        REPLICAS  IMAGE   COMMAND
7huiwv4vgrs7  helloworld  10/10     alpine  ping www.docker.com
[root@vm-1473648611529 ~]#
  1. Entre ellos, helloworld.3 se asigna al nodo líder (el ID de tarea después de helloworld.3. Es diferente)
[root@vm-1473648642890 ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                 CREATED              STATUS              PORTS               NAMES
7308b277a77d        alpine:latest       "ping www.docker.com"   About a minute ago   Up About a minute                       helloworld.3.95dodap792m1l2d9of2tg6lt0
8b78496370c3        alpine:latest       "ping www.docker.com"   6 minutes ago        Up 6 minutes                            helloworld.6.auphkstyrt0yrrqpile2wjatz
243d15b67aaa        alpine:latest       "ping www.docker.com"   6 minutes ago        Up 6 minutes                            helloworld.8.e9v6zdshztpvik79zt9tooei9
4d84734f60f9        alpine:latest       "ping www.docker.com"   6 minutes ago        Up 6 minutes                            helloworld.10.4rbworz9sa4mvmby6aj2ys8m6
c1a833410e3a        alpine:latest       "ping www.docker.com"   6 minutes ago        Up 6 minutes                            helloworld.7.5y4urb3mnn9395hzzkxp1ffgs
[root@vm-1473648642890 ~]#
  1. Verifique la IP de su eth0, todavía es 10.0.0.3
[root@vm-1473648642890 ~]# docker exec -ti 7308b277a77d sh
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:0A:00:00:03  
      inet addr:10.0.0.3  Bcast:0.0.0.0  Mask:255.255.255.0
      inet6 addr: fe80::42:aff:fe00:3%32684/64 Scope:Link
      UP BROADCAST RUNNING MULTICAST  MTU:1450  Metric:1
      RX packets:8 errors:0 dropped:0 overruns:0 frame:0
      TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
      collisions:0 txqueuelen:0 
      RX bytes:648 (648.0 B)  TX bytes:648 (648.0 B)

eth1      Link encap:Ethernet  HWaddr 02:42:AC:12:00:06  
      inet addr:172.18.0.6  Bcast:0.0.0.0  Mask:255.255.0.0
      inet6 addr: fe80::42:acff:fe12:6%32684/64 Scope:Link
      UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
      RX packets:101 errors:0 dropped:0 overruns:0 frame:0
      TX packets:125 errors:0 dropped:0 overruns:0 carrier:0
      collisions:0 txqueuelen:0 
      RX bytes:9416 (9.1 KiB)  TX bytes:11674 (11.4 KiB)

lo        Link encap:Local Loopback  
      inet addr:127.0.0.1  Mask:255.0.0.0
      inet6 addr: ::1%32684/128 Scope:Host
      UP LOOPBACK RUNNING  MTU:65536  Metric:1
      RX packets:4 errors:0 dropped:0 overruns:0 frame:0
      TX packets:4 errors:0 dropped:0 overruns:0 carrier:0
      collisions:0 txqueuelen:1 
      RX bytes:334 (334.0 B)  TX bytes:334 (334.0 B)

/ # exit
[root@vm-1473648642890 ~]#
  1. Vuelva a configurar la máquina virtual ahora para que esté disponible y reinicie el líder
[root@vm-1473648611529 ~]# docker node update --availability active cm1k85xgzxivrazge4qqteotv
cm1k85xgzxivrazge4qqteotv
[root@vm-1473648611529 ~]#
[root@vm-1473648642890 ~]# reboot
  1. Verifique otras VM, aproximadamente medio minuto después, se eligió un nuevo líder y se restableció el número de tareas a 10
[root@vm-1473648611529 ~]# docker node ls
ID                           HOSTNAME                                        STATUS  AVAILABILITY  MANAGER STATUS
bn68rlizdmnchk14fd1ft9izx    vm-1473648642890.vm-14736486428901473648642890  Down    Active        Unreachable
bu5cc1nx0aj29q984kkngeftd    vm-1476374349871                                Ready   Active        Leader
cm1k85xgzxivrazge4qqteotv *  vm-1473648611529.vm-14736486115291473648611529  Ready   Active        Reachable
[root@vm-1473648611529 ~]# docker service ls
ID            NAME        REPLICAS  IMAGE   COMMAND
7huiwv4vgrs7  helloworld  10/10     alpine  ping www.docker.com
[root@vm-1473648611529 ~]#
  1. En este momento, las tareas del nodo líder original se han migrado al nodo que vuelve a estar disponible.
[root@vm-1473648611529 ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                 CREATED             STATUS              PORTS               NAMES
1d3a252664d8        alpine:latest       "ping www.docker.com"   23 seconds ago      Up 22 seconds                           helloworld.3.25sfbbqwqggvpdwbst8dgqmza
8ca053e810c1        alpine:latest       "ping www.docker.com"   23 seconds ago      Up 22 seconds                           helloworld.6.3z3dy1w216eu2833sdpxjz7mr
a1744b36a51d        alpine:latest       "ping www.docker.com"   24 seconds ago      Up 23 seconds                           helloworld.10.28ikt9ajopam1lf11c6vm0b91
981ba2a3ffec        alpine:latest       "ping www.docker.com"   24 seconds ago      Up 23 seconds                           helloworld.7.7ce9f4ia66op0pi08h897vsw8
7af8cbd1e07c        alpine:latest       "ping www.docker.com"   30 seconds ago      Up 27 seconds                           helloworld.8.339nbcym1ttyvnytm6ls65zuu
[root@vm-1473648611529 ~]#
  1. Mira la IP de eth0 de helloworld.3, sigue siendo 10.0.0.3
[root@vm-1473648611529 ~]# docker exec -ti 1d3a252664d8 sh
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:0A:00:00:03  
      inet addr:10.0.0.3  Bcast:0.0.0.0  Mask:255.255.255.0
      inet6 addr: fe80::42:aff:fe00:3%32585/64 Scope:Link
      UP BROADCAST RUNNING MULTICAST  MTU:1450  Metric:1
      RX packets:26 errors:0 dropped:0 overruns:0 frame:0
      TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
      collisions:0 txqueuelen:0 
      RX bytes:2036 (1.9 KiB)  TX bytes:648 (648.0 B)

eth1      Link encap:Ethernet  HWaddr 02:42:AC:12:00:06  
      inet addr:172.18.0.6  Bcast:0.0.0.0  Mask:255.255.0.0
      inet6 addr: fe80::42:acff:fe12:6%32585/64 Scope:Link
      UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
      RX packets:218 errors:0 dropped:0 overruns:0 frame:0
      TX packets:224 errors:0 dropped:0 overruns:0 carrier:0
      collisions:0 txqueuelen:0 
      RX bytes:20106 (19.6 KiB)  TX bytes:20984 (20.4 KiB)

lo        Link encap:Local Loopback  
      inet addr:127.0.0.1  Mask:255.0.0.0
      inet6 addr: ::1%32585/128 Scope:Host
      UP LOOPBACK RUNNING  MTU:65536  Metric:1
      RX packets:4 errors:0 dropped:0 overruns:0 frame:0
      TX packets:4 errors:0 dropped:0 overruns:0 carrier:0
      collisions:0 txqueuelen:1 
      RX bytes:334 (334.0 B)  TX bytes:334 (334.0 B)

/ # exit
[root@vm-1473648611529 ~]#

Supongo que te gusta

Origin blog.csdn.net/zimu312500/article/details/88556522
Recomendado
Clasificación