Swarmkitの紹介
Swarmkitは、Dockerによって起動されたDockerクラスター管理およびコンテナーオーケストレーションツールです。Docker1.12以降、Docker-engineに統合され、リリースされました。SwarmkitはSwarmプロジェクトから開発されました。Docker独自のオーケストレーションシステムとして、サービスオーケストレーション、クラスター管理、およびスケジューリング機能を提供できます。
Swarmkitのノードは2つのカテゴリに分けられます
- ワーカーノードは、エグゼキューターを介してタスクを実行する責任があります。SwarmkitのデフォルトのエグゼキュータはDockerContainerExecutorです。
- 管理ノードは、ユーザー要求の受信と応答、およびクラスター状態の最終状態への調整を担当します。
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保持を実現するために変更するコードの場所と機能について説明します。
-
libnetwork
のステートメントをコメントアウトして、指定したIPアドレスの有効性を確認します。libnetworkコードのステートメントをコメントアウトして、指定したIPを持つコンテナーのIPアドレスの有効性を確認します。このステートメントは、指定したIPアドレスがに割り当てられているかどうかを確認します。コンテナが利用可能です。その理由は、コンテナが停止した後、そのIPアドレスがリサイクルされますが、このリサイクルはリアルタイムではないためです。新しく作成されたコンテナのIPアドレスが作成時に再利用されていない場合、リソースの競合が原因でコンテナの作成は失敗します。実際、IPアドレスを持つ古いコンテナーは停止しているため、停止してもサービスの正確性には影響しません。変更はgetAddress関数にあります。
マッピング関係を保存するデータ構造を増やします。マッピング関係を
維持するために、networkAllocatorでは、ネットワーク情報の一部がnetworkという名前のローカル構造に格納されます。マッピング関係を保存するために、マップが構造に追加されます。そのキーは、タスクを一意に識別できる前述のタスクIDであり、その値は、タスクに対応するIPアドレスです。 -
IP割り当て機能の追加タスクにIPアドレスを割り当てる場合は、まずネットワーク名に応じて対応するネットワーク情報を保存するデータ構造を見つけ、その構造に新しく追加されたマップで検索します。ヒットした場合は、タスクに以前にIPアドレスが割り当てられていることを意味します。今回は、タスクを再起動または移行できます。このとき、割り当てられたIPアドレスがタスクに直接割り当てられます。ヒットがない場合は、タスクが初めて実行され、libnetworkのインターフェースを直接呼び出して、未使用のIPアドレスを割り当てていることを意味します。この関数は、AllocateTask関数を変更し、allocateTaskIP関数を追加することで実現されます。 -
割り当てられたIP機能を記録する機能を追加する
タスクにIPアドレスを割り当てた後、新しく追加されたマップのデータを更新する必要があります。つまり、タスクIDをキーとして、割り当てられたIPアドレスを値としてマッピングがマップに保存されます。将来、タスクを再開または移行する必要がある場合は、割り当て機能を使用してIP保持を実現できます。この関数は、AllocateTask関数を変更し、recordTaskIP関数を追加することで実現されます。 -
IP
を再利用する機能の変更IPを保持するには、割り当てられたIPアドレスが再利用されないように、再利用タスクのIPアドレス部分のコードを変更する必要もあります。IPアドレスが再利用されると、新しいタスクに割り当てられる可能性があるためです。これにより、IP保持を実現できなくなります。この関数は、元のreleaseEndpoints関数を変更します。
マッピングを追加 -
リレーションシップ初期化関数
この関数は、リーダーが変更された後のマッピングデータの再構築を担当します。ノードがリーダーとして選択された後、ノードはクラスターのその後の管理を担当します。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が正常に起動しない場合があります。
効果テスト
- 新しくコンパイルされた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#
- コピー数を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 ~]#
- 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 ~]#
- ノードを使用不可にすると、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 ~]#
- その中で、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 ~]#
- 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 ~]#
- 今すぐVMをリセットして使用可能にし、リーダーを再起動します
[root@vm-1473648611529 ~]# docker node update --availability active cm1k85xgzxivrazge4qqteotv
cm1k85xgzxivrazge4qqteotv
[root@vm-1473648611529 ~]#
[root@vm-1473648642890 ~]# reboot
- 他の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 ~]#
- この時点で、元のリーダーノードのタスクは、再び使用可能になるノードに移行されています。
[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 ~]#
- 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 ~]#