56
61

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

DockerAdvent Calendar 2020

Day 12

Portainerで複数ホストのコンテナを一元管理してPortainerはいいぞと言う

Last updated at Posted at 2020-12-11

この記事はDocker Advent Calendar 2020の12日目の記事として書かれました。

結論

Portainerはいいぞ。

環境

  • Docker CE 19.03.13
  • Docker Compose 1.27.4
  • Portainer 2.0.0

Portainerとは

DockerコンテナやイメージなどをGUIで管理できるツールです。
小洒落たUIとシンプルな操作性で、入門者から上級者まで幅広い層にオススメできるツールです。
portainer00.png
公式のデモ環境があるので、一度触ってみてください。
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 にアクセスすると、以下のようにパスワードの設定を求められます。適当な値を設定してください。
startup01.png
続いて管理対象の環境を選択します。[Docker] を選び [Connect] を押します。
問題なければHome画面にlocalなるエンドポイントが表示されます。

local をクリックすると ContainersImages 等のリンクが表示されます。一旦 Containers を確認すると、以下のようにPortainerのコンテナが正常に動作している様子を確認できます。
startup04.png
コンテナを追加すると自動的にPortainerの管理対象に入ります。適当にnginxを立ち上げましょう。

$ docker run -dit -p 8080:80 --name nginx nginx

特にエラーが出なければ、コンテナ一覧にnginxがあることが確認できるでしょう。

各コンテナの画面ではlogsでログ確認、inspectでコンテナの情報確認、statsでリソース使用量等の確認ができます。また、コンテナ起動時に--interactive, --tty (-it)オプションを設定していればconsoleでコンテナ内部に対して操作を行うことができます。試しに先ほど起動したnginxに対してconsoleでアクセスします。

コンテナ一覧から [nginx] -> [Console] とアクセスし、 [Connect] を押すと以下のようにコンテナ内に入れます。とてもお手軽です。
nginx02.png
基本的な使い方を確認できたところで、一旦Portainerを削除します。

$ docker stop portainer && docker rm portainer

さて、ここまででPortainerで単一ホストのコンテナを管理する方法が分かりました。ただ、実際にはDockerホストは複数のノードにまたがっていることもあるでしょう。

この記事ではDocker Swarmで作成されたクラスタを単一のPortainerで管理する方法について説明します。

Docker Swarmで構築したクラスタのコンテナを一元管理する

1. Swarmの準備

今回は図のようなクラスタを構築しました。
cluster.png

名称 役割 説明
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で管理できていることが分かります。

portainer01.png
Stackとは別に各ノードでnginxを立ちあげてみましょう。

$ docker run -dit -p 8080:80 --name nginx nginx

portainer02.png
すべてのnginxがきちんと表示されます。--interactive, --ttyオプションをつけて起動したので、Consoleを利用できます。当然、Portainerが所属しているノードとは別のノードのnginxのConsoleにもアクセスできます。
これで複数ノードのコンテナを一元管理できるようになったことを確認できました。

今回デプロイしたStackの内容を見てみましょう。

portainer-agent-stack.yml
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つのサービスportaineragentを確認できます。portainerはGUIアプリケーションそのものです。agentは自ノードとPortainerの橋渡し役を担っています。
注目するべきはagentで定義されているmode: globalでしょう。これはクラスタの各ノードに該当サービスをデプロイするという指定です。各ノードにagentがいるおかげで、クラスタ内の全ノードのコンテナの情報を管理できるようになっています。

networksは両サービスが利用するネットワークを、volumesはPortainerのデータを永続化するボリュームを定義しています。どちらもデプロイ時になければ勝手に作成されます。

3. Stackの更新

ここまでで複数ホストのコンテナの一元管理を実現できました。
補足としてnginxをStackに組み込んでデプロイした時の挙動を紹介します。
一旦各ノードのnginxコンテナは削除し、サービスにnginxを突っ込んで再度デプロイします。

 portainer-agent-stack.yml
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に組み込まれた状態でデプロイされていることが分かります。
portainer03.png

余談

Portainerはシンプルかつ高機能で、色々なことができます。いくつか「おー」と思ったものを紹介します。

  • テンプレートからアプリケーションの立上げ
    portainer04.png
    WordPressとかGitlabみたいなちょっと面倒なやつらもボタンポチポチで起動できます。

  • Stackのデプロイ
    portainer05.png
    ymlファイルをベタ書きするもよし、ymlファイルをアップロードするもよしです。

  • LDAP / OAuth認証
    portainer06.png
    既存の認証情報を利用することができます。

おわりに

色々と機能を紹介したものの、正直に言ってローカルホストのコンテナの管理機能だけでも相当にパワフルです。
特にConsole機能は頻繁に使います。CUIで操作していると「あれ、今ホストだっけゲストだっけ?」となることが度々あるので。。。

バージョン2.0からKubernetesに対応したらしいのでそちらも今後触ってみたいですね。
Kubernetes何もわからないので完全に理解したらまた関連記事を書こうと思います。

Portainerはいいぞ。

参考

56
61
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
56
61

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?