この記事はDocker Advent Calendar 2020の12日目の記事として書かれました。
結論
Portainerはいいぞ。
環境
- Docker CE 19.03.13
- Docker Compose 1.27.4
- Portainer 2.0.0
Portainerとは
DockerコンテナやイメージなどをGUIで管理できるツールです。
小洒落たUIとシンプルな操作性で、入門者から上級者まで幅広い層にオススメできるツールです。
公式のデモ環境があるので、一度触ってみてください。
http://demo.portainer.io/
ID:admin
PW:tryportainer
(参考:公式Githubリポジトリ)
基本的な使い方
まずはPotainerを使ってみましょう。
Portainer自体がDockerイメージとして提供されているため、以下のようにコンテナを起動するだけでOKです。
$ docker run \
--detach \
--publish 9000:9000 \
--publish 8000:8000 \
--name portainer \
--restart always \
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume portainer_data:/data \
portainer/portainer-ce
portainer_data
は登録した情報(ログインユーザの情報など)を永続化するためのボリュームです。
http://<ホスト名>:9000
にアクセスすると、以下のようにパスワードの設定を求められます。適当な値を設定してください。
続いて管理対象の環境を選択します。[Docker] を選び [Connect] を押します。
問題なければHome画面にlocal
なるエンドポイントが表示されます。
local
をクリックすると Containers
や Images
等のリンクが表示されます。一旦 Containers
を確認すると、以下のようにPortainerのコンテナが正常に動作している様子を確認できます。
コンテナを追加すると自動的にPortainerの管理対象に入ります。適当にnginxを立ち上げましょう。
$ docker run -dit -p 8080:80 --name nginx nginx
特にエラーが出なければ、コンテナ一覧にnginxがあることが確認できるでしょう。
各コンテナの画面ではlogsでログ確認、inspectでコンテナの情報確認、statsでリソース使用量等の確認ができます。また、コンテナ起動時に--interactive
, --tty
(-it
)オプションを設定していればconsoleでコンテナ内部に対して操作を行うことができます。試しに先ほど起動したnginxに対してconsoleでアクセスします。
コンテナ一覧から [nginx] -> [Console] とアクセスし、 [Connect] を押すと以下のようにコンテナ内に入れます。とてもお手軽です。
基本的な使い方を確認できたところで、一旦Portainerを削除します。
$ docker stop portainer && docker rm portainer
さて、ここまででPortainerで単一ホストのコンテナを管理する方法が分かりました。ただ、実際にはDockerホストは複数のノードにまたがっていることもあるでしょう。
この記事ではDocker Swarmで作成されたクラスタを単一のPortainerで管理する方法について説明します。
Docker Swarmで構築したクラスタのコンテナを一元管理する
1. Swarmの準備
名称 | 役割 | 説明 |
---|---|---|
ip-172-31-36-96 | MANAGER | Swarmのマネージャノード |
ip-172-31-32-220 | WORKER | Swarmのワーカーノード |
ip-172-31-40-65 | WORKER | Swarmのワーカーノード |
manager1台、worker2台という構成です。
Dockerホストはdocker-machine
で用意するもよし、実際に何らかのインスタンスを立てるもよしです。
今回はmanagerもworkerもAWSで雑にインスタンスを立ててDockerとDocker Composeを入れました。1.27.4の部分は公式ガイドを参考に適宜最新版に置き換えてください。
$ sudo yum -y install docker
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
(注意) クラスタ内の各ノード間で以下のポートにアクセスできるよう設定する必要があります。クラウドサービスでホストを立てたりすると恐らくデフォルトでは閉じているはずなので、各ノードが相互に以下のポートを利用できるよう設定します。
ポート番号 | プロトコル | 用途 |
---|---|---|
2377 | TCP | クラスタ管理通信 |
7946 | TCP | ノード間通信 |
7946 | UDP | ノード間通信 |
4789 | UDP | オーバーレイネットワーク通信 |
ネットワークの設定が完了したら、各ホストをSwarmのメンバーにします。
- Swarmの作成@MANAGER
$ docker swarm init --advertise-addr <自身のIPアドレス>
<自身のIPアドレス>にはSwarmの他ノードから識別可能なIPアドレスを設定します。今回の例では172.31.36.96です。
- Workerを参加させるためのトークンを発行@MANAGER
$ docker swarm join-token worker -q
SWMTKN
から始まるトークンが表示されます。 -q はトークンのみ表示するというオプションで、あってもなくてもいいです。(コピペが楽なので付けています)
- 各WorkerをSwarmに参加させる@WORKER
$ docker swarm join --token <トークン> <managerのIPアドレス>
<トークン>は先ほど作成した`SWMTKN` から始まるものです。はSwarm作成時のmanagerの<自身のIPアドレス>と同じものを指定してください。
- 設定の確認@MANAGER
Swarmを正常に設定できていれば、ノード一覧に3つのホストが表示されます。
$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
v6zghq4r796dbg2ixow620um9 ip-172-31-32-220.ap-northeast-1.compute.internal Ready Active 19.03.13-ce
7gbjabs2eg0rqjhvkkdqwr4dq * ip-172-31-36-96.ap-northeast-1.compute.internal Ready Active Leader 19.03.13-ce
xwl862sqjb5n2hs5z6nxmdz99 ip-172-31-40-65.ap-northeast-1.compute.internal Ready Active 19.03.13-ce
これでクラスタが完成しました。
2.Stackのデプロイ
StackはServiceの集合です。大雑把に捉えるとDocker Swarmはサーバを束ねる技術でDocker Stackはアプリケーションを束ねる技術です。
公式でPortainerのStackを構築するためのymlファイルが提供されているので、curlでダウンロードしてデプロイします。
$ curl -L https://downloads.portainer.io/portainer-agent-stack.yml -o portainer-agent-stack.yml
$ docker stack deploy --compose-file=portainer-agent-stack.yml portainer
デプロイが完了した後Portainerにアクセスすると、以下のように4つのコンテナが表示されます。Hostカラムから、3つの異なるホストにあるコンテナが1つのPortainerで管理できていることが分かります。
Stackとは別に各ノードでnginxを立ちあげてみましょう。
$ docker run -dit -p 8080:80 --name nginx nginx
すべてのnginxがきちんと表示されます。--interactive
, --tty
オプションをつけて起動したので、Consoleを利用できます。当然、Portainerが所属しているノードとは別のノードのnginxのConsoleにもアクセスできます。
これで複数ノードのコンテナを一元管理できるようになったことを確認できました。
今回デプロイしたStackの内容を見てみましょう。
version: '3.2'
services:
agent:
image: portainer/agent
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /var/lib/docker/volumes:/var/lib/docker/volumes
networks:
- agent_network
deploy:
mode: global
placement:
constraints: [node.platform.os == linux]
portainer:
image: portainer/portainer-ce
command: -H tcp://tasks.agent:9001 --tlsskipverify
ports:
- "9000:9000"
- "8000:8000"
volumes:
- portainer_data:/data
networks:
- agent_network
deploy:
mode: replicated
replicas: 1
placement:
constraints: [node.role == manager]
networks:
agent_network:
driver: overlay
attachable: true
volumes:
portainer_data:
2つのサービスportainer
とagent
を確認できます。portainer
はGUIアプリケーションそのものです。agent
は自ノードとPortainerの橋渡し役を担っています。
注目するべきはagent
で定義されているmode: global
でしょう。これはクラスタの各ノードに該当サービスをデプロイするという指定です。各ノードにagentがいるおかげで、クラスタ内の全ノードのコンテナの情報を管理できるようになっています。
networks
は両サービスが利用するネットワークを、volumes
はPortainerのデータを永続化するボリュームを定義しています。どちらもデプロイ時になければ勝手に作成されます。
3. Stackの更新
ここまでで複数ホストのコンテナの一元管理を実現できました。
補足としてnginxをStackに組み込んでデプロイした時の挙動を紹介します。
一旦各ノードのnginxコンテナは削除し、サービスにnginxを突っ込んで再度デプロイします。
version: '3.2'
services:
agent:
image: portainer/agent
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /var/lib/docker/volumes:/var/lib/docker/volumes
networks:
- agent_network
deploy:
mode: global
placement:
constraints: [node.platform.os == linux]
portainer:
image: portainer/portainer-ce
command: -H tcp://tasks.agent:9001 --tlsskipverify
ports:
- "9000:9000"
- "8000:8000"
volumes:
- portainer_data:/data
networks:
- agent_network
deploy:
mode: replicated
replicas: 1
placement:
constraints: [node.role == manager]
web:
image: nginx
tty: true
ports:
- "80:80"
networks:
- agent_network
deploy:
mode: replicated
replicas: 3
networks:
agent_network:
driver: overlay
attachable: true
volumes:
portainer_data:
$ docker stack deploy --compose-file=portainer-agent-stack.yml portainer
Portainerを確認すると、きちんとサービスweb
がStackに組み込まれた状態でデプロイされていることが分かります。
余談
Portainerはシンプルかつ高機能で、色々なことができます。いくつか「おー」と思ったものを紹介します。
おわりに
色々と機能を紹介したものの、正直に言ってローカルホストのコンテナの管理機能だけでも相当にパワフルです。
特にConsole機能は頻繁に使います。CUIで操作していると「あれ、今ホストだっけゲストだっけ?」となることが度々あるので。。。
バージョン2.0からKubernetesに対応したらしいのでそちらも今後触ってみたいですね。
Kubernetes何もわからないので完全に理解したらまた関連記事を書こうと思います。
Portainerはいいぞ。
参考
-
portainer/portainer
Portainerのリポジトリです。 -
Portainer Deployment
本記事は"Inside a Swarm cluster"の内容を大いに参考にしました。 -
Docker Swarm 導入チュートリアル
Docker Swarmによるクラスタ構築の基礎です。