SwarmクラスターでIP保持を実現する方法

転載元:http//dockone.io/article/1861

Swarmkitの紹介

Swarmkitは、Dockerによって起動されたDockerクラスター管理およびコンテナーオーケストレーションツールです。Docker1.12以降、Docker-engineに統合され、リリースされました。SwarmkitはSwarmプロジェクトから開発されました。Docker独自のオーケストレーションシステムとして、サービスオーケストレーション、クラスター管理、およびスケジューリング機能を提供できます。

Swarmkitのノードは2つのカテゴリに分けられます

  1. ワーカーノードは、エグゼキューターを介してタスクを実行する責任があります。SwarmkitのデフォルトのエグゼキュータはDockerContainerExecutorです。
  2. 管理ノードは、ユーザー要求の受信と応答、およびクラスター状態の最終状態への調整を担当します。
    Swarmクラスターの構造図上の
    ここに画像の説明を挿入
    、DockerでのSwarmクラスターの構成を示しています。クラスターには複数のマネージャーノードを含めることができ、これらのマネージャーは1つのノードをリーダーノードとして選択します。リーダーノードは、クラスター全体の管理を担当します。リーダーノードに障害が発生した場合、残りのマネージャーノードが再選出され、新しいリーダーノードがクラスターの管理を引き継ぎます。元のリーダーノードは回復後にクラスターに再参加できます。この時点では、IDは正常です。マネージャーノード。

Swarmkitは、サービスオーケストレーションでサービスステータスの一貫性を実現し、指定された戦略に従ってサービスをアップグレードおよび再起動できます。簡単に言うと、サービスの作成後、Swarmkitはサービスの種類に応じてタスクの数を決定し、対応するタスクを生成し、タスクの数が安定していることを定期的にチェックして、スケジュールに従ってこれらのタスクを各ワーカーノードにディスパッチします。戦略。ノードが使用できない場合、リーダーノードはそのノード上のタスクを他の使用可能なノードに移行して実行を継続します。また、ユーザーコマンドに応じてタスクの数を増減できます。具体的な使用方法については、公式ドキュメントを参照してください。次の図は、Swarmkitの内部構造を示しています。Swarmkitは、libnetworkを介してネットワークリソースの管理を実現します。
Swarmkitの内部構造の概略図
ここに画像の説明を挿入

提起された質問

運用・保守の観点から、運用・保守の効率化を図るため、コンテナの再起動や移行後もコンテナのIPアドレスを変更しないことが望まれる。このようにして、運用および保守担当者は、特定の静的IPアドレスを介して、コンテナーの保守やアップグレードなどの操作を実行できます。

現在の実際の状況では、Docker.10以降のバージョンでは、コンテナーを作成するときに、コマンドラインで-ipオプションを使用してそのIPアドレスを指定できます。ただし、Swarmkitの現在の実装では、サービスのタスクにIPを割り当てる場合、IPアドレスの指定はサポートされていませんが、ランダムな割り当て方法が使用されます。タスクを再起動または移行する必要がある場合、2つのタスクの対応するコンテナのIPアドレスが同じになる保証はありません。スウォームクラスターの運用と保守の効率を向上させるには、コンテナーのIPアドレスに対応するタスクを保持する方法が必要です。

実現のアイデア

Dockerのドキュメントとコードを読んだ後、各タスクのコンテナーを作成するとき、コンテナー名は3つの部分で構成されていることがわかりました。詳細については、以下のコードを参照してください(daemon / cluster / executer / container / container.go name() )。
strings.Join([] string { c.task.ServiceAnnotations.Name、fmt.Sprint(c.task.Slot)、c.task.ID }、“。”)を返します。

サービス名とスロットの値が決定され、タスクIDはシステムによって自動的に生成され、再起動または移行されるたびに変更されます。コンテナーによって実行されるタスクは、コンテナー名の最初の2つの部分によって一意に識別できます。これは、ここではタスクIDと呼ばれます(Swarmkitの特定の実装のタスクIDはこれに似ていますが、ServiceIDが使用されます) 。

このソリューションの主なアイデアは、コンテナーのIPアドレスをタスクIDに関連付け、タスクIDとSwarmkitによってシステム内のタスクに割り当てられたIPアドレスとの間のマッピング関係を保存することです。タスクを再起動または移行すると、新しく生成されたコンテナには、マッピング関係で以前に保存されたIPアドレスが割り当てられるため、タスクに対応するIPアドレスは変更されません。

考慮する必要があるもう1つの問題は、リーダーノードが使用できなくなった後、以前に保存したマッピング関係を新しいリーダーノードに復元する方法です。1つの解決策は、対応する関係を図1の状態ストレージに書き込むことであり、もう1つの解決策は、リーダーが初期化されたときにタスクリストから対応する関係を再構築することです。ここでは後者のソリューションを選択します。最初のソリューションでは、プロトバッファーの使用と、実装がより複雑なSwarmkitの分散ストレージ実装コードも学習する必要があるためです。

IP保全の具体的な実現

ここでは主に、IP保持を実現するために変更するコードの場所と機能について説明します。

  1. libnetwork
    ステートメントコメントアウトして、指定したIPアドレスの有効性を確認します。libnetworkコードのステートメントをコメントアウトして、指定したIPを持つコンテナーのIPアドレスの有効性を確認します。このステートメントは、指定したIPアドレスがに割り当てられているかどうかを確認します。コンテナが利用可能です。その理由は、コンテナが停止した後、そのIPアドレスがリサイクルされますが、このリサイクルはリアルタイムではないためです。新しく作成されたコンテナのIPアドレスが作成時に再利用されていない場合、リソースの競合が原因でコンテナの作成は失敗します。実際、IPアドレスを持つ古いコンテナーは停止しているため、停止してもサービスの正確性には影響しません。変更はgetAddress関数にあります。
    マッピング関係を保存するデータ構造を増やします。マッピング関係を
    維持するために、networkAllocatorでは、ネットワーク情報の一部がnetworkという名前のローカル構造に格納されます。マッピング関係を保存するために、マップが構造に追加されます。そのキーは、タスクを一意に識別できる前述のタスクIDであり、その値は、タスクに対応するIPアドレスです。


  2. IP割り当て機能追加タスクにIPアドレスを割り当てる場合は、まずネットワーク名に応じて対応するネットワーク情報を保存するデータ構造を見つけ、その構造に新しく追加されたマップで検索します。ヒットした場合は、タスクに以前にIPアドレスが割り当てられていることを意味します。今回は、タスクを再起動または移行できます。このとき、割り当てられたIPアドレスがタスクに直接割り当てられます。ヒットがない場合は、タスクが初めて実行され、libnetworkのインターフェースを直接呼び出して、未使用のIPアドレスを割り当てていることを意味します。この関数は、AllocateTask関数を変更し、allocateTaskIP関数を追加することで実現されます。

  3. 割り当てられたIP機能を記録する機能を追加する
    タスクにIPアドレスを割り当てた後、新しく追加されたマップのデータを更新する必要があります。つまり、タスクIDをキーとして、割り当てられたIPアドレスを値としてマッピングがマップに保存されます。将来、タスクを再開または移行する必要がある場合は、割り当て機能を使用してIP保持を実現できます。この関数は、AllocateTask関数を変更し、recordTaskIP関数を追加することで実現されます。

  4. IP
    再利用する機能変更IPを保持するには、割り当てられたIPアドレスが再利用されないように、再利用タスクのIPアドレス部分のコードを変更する必要もあります。IPアドレスが再利用されると、新しいタスクに割り当てられる可能性があるためです。これにより、IP保持を実現できなくなります。この関数は、元のreleaseEndpoints関数を変更します。
    マッピングを追加

  5. リレーションシップ初期化関数
    この関数は、リーダーが変更された後のマッピングデータの再構築を担当します。ノードがリーダーとして選択された後、ノードはクラスターのその後の管理を担当します。IP保持を実現するには、リーダーの初期化でマッピング関係を再構築する必要があります。この作業は、doNetworkInit関数を変更し、IpmapsInit関数を追加することで実現されます。この関数は、一貫性のあるストレージに保存されているすべてのタスクをトラバースします。タスクごとに、保存されているネットワーク情報から割り当てられたIPアドレスを読み取り、これらのIPをのマッピング関係と比較します。タスクIDは、ネットワークに新しく追加されたマップに保存されるため、マッピング関係の再構築が実現されます。

メソッドのコンパイルとインストール(例としてDocker 1.12.1を取り上げます)

(1)Dockerプロジェクトをgithubから複製してバージョン1.12.1に切り替えるか、Docker1.12.1のソースコードを直接ダウンロードします。

(2)完全なコード変更。

(3)プロジェクトディレクトリを入力し、make shellと入力すると、バージョン1.12.1に対応する開発環境がインストールされ、開発環境が配置されているコンテナが入力されます。

(4)hack / make.shバイナリを入力すると、バイナリ実行可能ファイルがコンパイルおよび生成されます。bundle / latestディレクトリ内。

(5)インストール方法バイナリファイルをコンパイルして生成した後、システムの/ usr / binまたは/ usr / local / binディレクトリにファイルをコピーします。ホストシステムは、同じバージョンのDockerをインストールしたばかりか、Dockerをインストールしていない場合に最適です。そうしないと、Dockerが正常に起動しない場合があります。

効果テスト

  1. 新しくコンパイルされたDockerプログラムを3つのVMにインストールします。3つのノードはすべてマネージャーです。クラスターとサービスを作成するプロセスはここでは省略されています。
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. コピー数を10に増やすと、いずれかのVMでのタスクは次のようになります。
[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. helloworld.3のeth0のIPは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. ノードを使用不可にすると、VM上のタスクが他の2台のマシンに再割り当てされます
[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. その中で、helloworld.3はリーダーノードに割り当てられます(helloworld.3。の後のタスクIDは異なります)
[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. eth0のIPを確認してください。まだ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. 今すぐVMをリセットして使用可能にし、リーダーを再起動します
[root@vm-1473648611529 ~]# docker node update --availability active cm1k85xgzxivrazge4qqteotv
cm1k85xgzxivrazge4qqteotv
[root@vm-1473648611529 ~]#
[root@vm-1473648642890 ~]# reboot
  1. 他のVMを確認します。約30分後、新しいリーダーが選出され、タスクの数が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. この時点で、元のリーダーノードのタスクは、再び使用可能になるノードに移行されています。
[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. helloworld.3のeth0のIPを見てください、それはまだ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 ~]#

おすすめ

転載: blog.csdn.net/zimu312500/article/details/88556522