複数のコンテナ環境を一元管理できる「Portainer」を試す
GitHubレポジトリ
Portainer
referred from https://github.com/portainer/portainerPortainer Community Edition は、Docker、Swarm、Kubernetes、ACI 環境を管理できる軽量なコンテナアプリケーション向けのサービス提供プラットフォームです。展開も使用も簡単なことを目的としています。本アプリケーションでは、“スマート” な GUI や豊富な API を通じて、オーケストレーターのリソース(コンテナ、イメージ、ボリューム、ネットワークなど)を一元管理できます。
Portainer は単一のコンテナで構成され、あらゆるクラスター上で実行可能です。Linux コンテナとしても Windows ネイティブコンテナとしてもデプロイできます。
Portainer Business Edition はオープンソース版をベースに、RBAC やサポートなどビジネスユーザー向けの高度な機能を追加したエディションです。
- Portainer CE と Portainer BE の比較
- Take3 – Portainer Business を無料で 3 ノード分、好きなだけ利用
- Portainer BE インストールガイド
最新バージョン
Portainer CE は定期的に更新されます。数ヶ月ごとにリリースを目指しています。
はじめよう
機能と特徴
Portainer CE の全機能を確認し、Portainer Business と比較するには、こちら の表をご覧ください。
セキュリティ
Portainer ではセキュリティ問題の responsible disclosure を推奨しています。セキュリティ上の問題を発見された場合は security@portainer.io までご報告ください。
プライバシー
開発リソースの適切な集中のため、最も利用されている機能を把握する必要があります。その情報を取得するために、ドイツでホストされ GDPR 準拠の Matomo Analytics を使用しています。
Portainer 起動時にアナリティクスを無効化するオプションが表示されます。無効化しない場合、プライバシーポリシー に従い匿名の利用情報を収集します。個人を特定できる情報は一切送信・保存せず、改善目的でのみ利用します。
制限
Portainer は「Current - 2 バージョンの Docker」のみサポートします。それ以前のバージョンでも動作する可能性はありますが、サポート対象外です。
ライセンス
Portainer は zlib ライセンスの下で提供されています。詳細は LICENSE をご参照ください。
Portainer には他のオープンソースプロジェクトのコードも含まれています。詳細は ATTRIBUTIONS.md をご覧ください。
オープンソースなCE(Community Edition)と商用のBE(Business Edition)がある。BEについてはこちらが公式。
違いは以下にまとまっている。
Diaにざっくりまとめてもらった。
- PortainerのCE(Community Edition)とBE(Business Edition)の違いは、主に企業向けの機能がBEに追加されてること
- ロールベースのアクセス制御(RBAC): ユーザーごとに権限を細かく設定可能
- 既存の認証システムと連携: Active Directory・LDAP・OAuth等の企業ユースでよく使われる認証システムと連携が可能。自動ユーザー登録やグルーピングなど。
- デプロイ自動化(GitOps対応): GitOpsでアプリの自動アップデートが可能。
- 複数環境&レジストリ管理: Docker・Kubernetesも複数環境まとめて管理可能、コンテナレジストリも一括管理可能。
- 強化されたKubernetesサポート: クラウド(AWS・Azure・GCP等)へのKubernetesクラスタデプロイが可能、既存のkubeconfigファイルで環境追加や、細かなリソース制限・セキュリティ設定も。
- 監査&アクティビティログ: あらゆる操作がログで確認可能。外部へのログエクスポートも可能。
- サポート体制: 9x5や24x7のサポートも利用可能
- CEは個人や小規模向け、BEは企業やエンタープライズ向け
一応公式サイトを見る限りはBEでも3ノードまでは無料で使える様子、あとエンプラ向けの無料トライアルもある様子。価格については、エンタープライズ、IoT/エッジ・学生で異なるようなので以下を参照。
CEのほうはオープンソースでZlibライセンスらしい。あまり知らないけど、
- 商用利用可
- 改変・再配布も可だが、著作権表示とライセンス分の保持・改変時は改変を明記するのが条件
- 無保証
という感じみたい。
とりあえず今回はDockerコンテナの管理を目的としてCEに触れてみる。
インストール(CE)
インストール方法は以下のとおり用意されている
- 新規にPortainer CEをインストール
- Docker単体
- Linux
- Docker on WSL/Docker Desktop
- Docker on Windows Container Service
- Docker Swarm
- Linux
- Docker on WSL/Docker Desktop
- Docker on Windows Container Service
- Podman
- Linux
- Kubernetes
- セルフホストしたKubernetes環境
- WSL/Docker Desktop上のKubernetes環境
- Docker単体
- 既存のPortainer CEで他の環境を追加して管理
- (後述)
今回はUbuntu-22.04上のDocker単体で試してみるので以下
最初にPortainerの構成や注意書き
- Portainer Server と Portainer Agent で構成される。どちらもDockerコンテナとして動作。
- Dockerは最新版を推奨。Ubuntuの場合snapでいれると互換性の問題が出る可能性がある
- Portainer Serverを動かす場合はsudoできること
- デフォルトでは、UIは9443番ポート、Edge機能を使う場合はトンネルサーバが8000番ポートを使用する
- DockerはUnixソケットでアクセスできること(TCPでもOK)
- SELinuxは無効にしておく。有効にする場合は
–privileged
で。 - Dockerはrootで。rootlessはいろいろ制限がある
ではPortainer Serverをインストールする
まず、データベース用のボリュームを作成
docker volume create portainer_data
Portainer Serverのコンテナを起動
docker run \
-d \
-p 8000:8000 \
-p 9443:9443 \
--name portainer \
--restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data:/data \
portainer/portainer-ce:lts
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d6c5e69eba20 portainer/portainer-ce:lts "/portainer" 31 seconds ago Up 30 seconds 0.0.0.0:8000->8000/tcp, [::]:8000->8000/tcp, 0.0.0.0:9443->9443/tcp, [::]:9443->9443/tcp, 9000/tcp portainer
ブラウザで9443番ポートにアクセスする。なお、自己署名証明書が有効になっているので"HTTPS"でアクセス、あとLAN内のリモートサーバの場合はホスト名ではなくIPアドレスでアクセスするほうが良いと思う(サーバの設定によっては次のステップでエラーになって進めないかも)。
初期設定で管理者ユーザを作成する。ユーザ名・パスワードを入力して"Create User"をクリック。作成する。ユーザ名も変更できるらしいが、自分はadmin
のままにした。なお、下のチェックボックスは統計情報の提供を行うかどうかのチェックらしいので、外したければ適宜。
なお、この設定は早めに行わないとタイムアウトしてしまい、再度実行するにはコンテナを再起動する必要があるので注意。
管理者ユーザを登録すると自動的にログインされる。こんな画面が表示される。
設定環境ウイザードが自動的に起動し、このPortainer Serverで別のDocker等の環境を管理する場合は"Add Environments"、そうでない場合=このPortainer Serverが動作しているDocker環境を管理する場合は"Get Started"をクリックすれば良いみたい。今回は"Get Started"をクリック。
どうやらこれがHome画面の様子。ここにローカルのDocker環境が表示され、他のDocker等の環境を追加した場合もここに一覧が表示される様子。今回は新規インストールなので、まだローカル環境しか表示されていない。この環境に接続する。"Live Connect"をクリック。
現在動いているコンテナ、保持しているイメージなどが表示される。例えば"Containers"をクリックしてみる。
動いているコンテナやバインドしているポートなどが表示される。ちなみに以下はDifyのコンテナがいろいろ動いてるのが見える。各コンテナをクリックすると詳細が確認できる。
リモートDocker環境の追加(Portainer Agent)
次に、このPortainer Serverに、別のDocker環境を追加して、一元管理をやってみる。既存のPortainerに他の環境を追加して管理する場合のドキュメントはこちら。
こちらもユースケースにあわせていくつかドキュメントが用意されている。
- Docker単体
- Docker Swarm
- Kubernetes
- Podman
- Azure ACI、など
今回はLAN内にRaspberry Pi 4上にDocker環境を構築したサーバがあるのでそれを追加することにする。Docker単体の場合のドキュメントは以下。
更にやり方は複数ある様子。
- 管理対象のDockerサーバにPortainer Agentをインストールする
- DockerのAPIとかソケットで直接つなぐ
- 管理対象のDockerサーバにEdge Agentをインストールする
- Edge Agentの場合はさらに標準と非同期がある
今回はPortainer Agentを使う方式でやる。
追加する環境側の注意事項は以下
- Portainer Serverインスタンスから9001番ポートでアクセスできること。このポートが空いていない場合はEdge Agentでのインストールを推奨。
- Windowsの場合は、WSLもしくはWCS(Windows Container Services)が必要。新しいシステムの場合はWSL2を推奨
- 追加する環境側では、Portainer AgentからDockerに、Linuxの場合はUnixソケット、WCSの場合は名前付きパイプ(WCS)でアクセスできること。TCP接続はサポートしていない。
- SELinuxは、サーバと同じく、無効・または
–privileged
オプションを使用 - ここはやっていないのでまだわからないけど、Portainer Server側で
AGENT_SECRET
を設定している場合はAgent側でも-e AGENT_SECRET=XXXXX
のような設定が必要。おそらくサーバ・エージェント間の認証的なものなのだろうと思う。
では、管理画面から "Environment-related" → "Environments"をクリックして、"Add Environment"をクリック。
環境ウイザードが開く。今回は、"Docker Standalone" を選択して、"Start Wizard" をクリック。下の方にはBEじゃないと使えない機能もあるっぽいね。
以下のような画面が表示される。"Agent"が選択されていることを確認。追加したい環境で実行すべきDockerコマンドが表示される。
今回の追加対象のRaspberry Pi 4上で実行
docker run -d \
-p 9001:9001 \
--name portainer_agent \
--restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /var/lib/docker/volumes:/var/lib/docker/volumes \
-v /:/host \
portainer/agent:2.27.9
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
21900552b06e portainer/agent:2.27.9 "./agent" 42 seconds ago Up 34 seconds 0.0.0.0:9001->9001/tcp, [::]:9001->9001/tcp portainer_agent
(snip)
Portainer Serverの管理画面に戻って、追加したホストの名前とネットワークアドレス・ポートを入力して"Connect"をクリック。なお、"More settings"でグルーピングしたりタグつけたりってのもできるみたい。
接続が成功したら、右上に新しい環境が表示される。これで追加完了みたい。"Close"でこの画面を閉じる。
環境が追加されている
Homeに戻って、該当のDocker環境に"Live Connect"
コンテナを見てみる。
Raspberry Pi 4上で動いているコンテナもこれで管理できる。
サーバからリモートのDocker等環境をエージェントで管理するのはわかったけど、もう一つあるEdge Agentってのは何なのか?
Diaによるまとめ
- Portainerサーバーから直接アクセスできないリモート環境を管理できる
- 通常のエージェントは、サーバからエージェントに対して通信を行う。これに対し、Edge Agentはエージェン度からサーバに通信を行う
- リモート側でポート開放しなくてよいので、NAT配下などでもアクセスできる
- エージェント・サーバ間はセキュアなTLSトンネルが張られる。
- 代わりに、Portainerサーバー側でポートを開ける必要がある
- UI用: 9443
- トンネル用: 8000等(変更可能みたい)
また、Edge Agentには上記以外に非同期のEdge Agent Asyncもある
こちらもDiaによるまとめ
- StandardモードとAsyncモードの違い 
- Standardモード
- トンネルを張って直接やり取りするため高速。
- リアルタイムでリモート環境を操作可能。
- Asyncモード
- トンネルを張らずに、定期的にリモートのスナップショットがPortainerサーバーに送信される。
- 通信量が削減でき、またネットワーク接続が不安定な状況でも動作可能。
- サーバ側で開放するのはUI用ポート(9443番)のみ
- トンネル用ポート(8000番等)の開放が不要
- ただし、BEでしか使えない
なるほどね。一番ニーズありそうなところは有償になってる。
その他Docker向け管理でどういうことができるのか?をざっと。以下にリストがある。
- テンプレート
- よくあるアプリケーションやサービス等を「テンプレート」として即デプロイ可能
- あらかじめ用意されたビルトインテンプレートを利用可能
- 自分でカスタムテンプレートを作成することも可能
- スタック
- 複数のサービスをまとめて「スタック」として管理してデプロイ等が可能
- 例: WordPress→Webサーバー+DBサーバをまとめてスタックとして管理
- コンテナ
- コンテナの作成・編集・削除
- ログの確認やコンソールへの直接アクセスも可能
- イメージのアップデートなども可能
- イメージ
- コンテナイメージのビルドが可能
- Docker Hubなど外部のレジストリとの連携も可能
- ネットワーク
- Dockerのネットワークを管理可能
- ボリューム
- Dockerのボリュームを管理可能
- イベントログ
- コンテナのイベントログを閲覧可能
- ホスト
- Dockerが動いているホスト側の情報を確認可能
メニューにはDocker Swarm限定のものなど、追加する環境固有のものもあるようなので、管理したい環境に合わせて適宜確認。
イメージのバージョン管理ができて、全環境まとめてアップデート、みたいなことができそう?気になる。
コンポーネント間の構成を見ると、イメージやスタックなどは環境の配下に位置づけられているので、そうういう用途では使えなさそう・・・?
・・・と思ったけど、これかな?
Edge Stacks は、アプリケーションの現在の状態に関係なく、単一のページから複数の環境にアプリケーションをデプロイできる機能です。
リモートDocker環境の追加(Edge Agent)
Edge Agentも試しておく。上に書いた通り、Edge Agentの場合はサーバ側でいくつかポートが空いている必要があるので注意。
今回はProxmoxでUbuntu-24.04のVMを起動して、Dockerをセットアップしておいた。
Portainer Serverで、環境を追加する。
今回は"Edge Agent Standard"を選択して、環境名を入力する。IPアドレスが表示されているけど、これはPortaner ServerのIPアドレスなので、環境側のIPアドレスを設定する必要はなさそう。デフォルトだと5秒間隔でEdge Agentからポーリングされるみたい。"Create"をクリック。
コマンドが出力される。どうやらトークンでサーバへの接続を認証しているみたい。このコマンドを追加するDocker環境側で実行。
docker run -d \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /var/lib/docker/volumes:/var/lib/docker/volumes \
-v /:/host \
-v portainer_agent_data:/data \
--restart always \
-e EDGE=1 \
-e EDGE_ID=1d1aXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX \
-e EDGE_KEY=aHR0cXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX \
-e EDGE_INSECURE_POLL=1 \
--name portainer_edge_agent \
portainer/agent:2.27.9
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fc2abb99777b portainer/agent:2.27.9 "./agent" 5 seconds ago Up 5 seconds portainer_edge_agent
環境が追加された。
Homeに戻って、"Live Connect"
追加した環境のコンテナが確認できる。
見た感じはほとんど変わらないけども、こちらはEdge Agent側から情報がPushされて確認できるということ。
Edge Compute
まだちょっとよくわかってないのだけど、Edge Computeという機能の中にEdge Stacksという機能がある。
Edge Stacks は、アプリケーションの現在の状態に関係なく、単一のページから複数の環境にアプリケーションをデプロイできる機能です。
読んだ感じはエッジ環境にまとめて同じアプリケーションをデプロイできる機能のように見える。実はこういうことがやりたくて、Portainerを調べていたのだった。
一つ上でEdge Agentも試してみたけども、Edge Computeというのは標準では無効になっているようで、どういう位置づけの機能なのかがわからない。
ということでこれを試してみる。
Edge Computeの有効化
Edge Stacksを使うにはまずEdge Computeを有効化する必要がある。
"Settings"→"Edge Compute"に"Edge Compute Settings"があるので、ここの"Enable Edge Compute features"を有効にする。もう一つ下に"Enforce use of Portainer generated Edge ID"というのがあるのだが、ドキュメントには
Portainerが生成したEdge IDの使用を強制する: このオプションを有効にすると、Edge Agentのデプロイで使用されるEdge IDがPortainerのデータベース内に存在すること(言い換えれば、一致するIDを持つ環境がすでに作成されていること)が、接続の条件となります。
とある。うん、読んでもいまいち意味がわからない。とりあえず問題なさそうな気がしたので、こちらも有効にしておく。で保存。
保存すると左のメニューに"Edge compute"のメニューが表示されるようになる。
では各機能を見ていこうと思う。
Edge Compute: Edge Groups
Edge GroupsはEdge Agent環境をグルーピングできる。
Edge Computeメニューの"Edge Groups"で、"Add Edge group"をクリック
Edge Group名を入力して、Edge Groupに追加するEdge Agent環境を選択する。グルーピングは任意のEdge Agent環境を「手動」で追加する"Static"と、タグなどから「自動で動的」に追加する"Dynamic"が選択できる。今回は"Static"で。
で下の左に追加できるEdge Agent環境が表示されているので、これをクリックする。ちなみに、Edge Agent環境は事前に増やしておいた。
左から右に移れば"Associated"ということでグループに入ったことになる。
2つともグループに追加して、"Add edge group"をクリック。
2つのEdge Agent環境が登録されたグループが作成された。
Edge Compute: Edge Stacks
Edge Stackを使うと、アプリケーションの「スタック」を複数の環境に一度にデプロイできる。上でも書いたけど、「スタック」は複数のアプリケーションのデプロイ設定を一つにまとめたもの。イメージとしてはDocker Composeだと思う。
"Edge Stacks"メニューから"Add stacks"をクリック。
こんな画面が開くので、ここでスタックの設定を行う。
まず、スタック名を入力し、スタックを適用するEdge Groupを選択する。つまりEdge Groupに登録されたEdge Agentにスタックが適用されるということになる。
次にデプロイメントタイプ。今回はDocker単体のEdge Groupを指定しているので、自ずとDocker Compose形式となっているが、Kubernetes環境でEdge Groupを構成していればKuberenesのマニフェスト形式となるのだろう。
でそのDocker ComposeのYAMLを指定するのだが、方式としては以下がある。
- Webエディタ: GUI上のエディタでYAMLを直接記載
- アップロード: YAMLファイルをアップロード
- レポジトリ: Gitレポジトリを指定して、レポジトリのdocker-compose.ymlを適用
- テンプレート: Portainerのテンプレート機能を使用。ビルトインとカスタムがある。
今回はお手軽にできるWebエディタを使うが、レポジトリを使えばGitOps的に出来て良さそう。
Webエディタの場合は下のフォームにdocker-compose.yamlをセットする。今回はDocker公式の「Awesome Docker Compose sample」から、WordPress+MySQLを構築するサンプルを使わせもらった。docker-compose.yamlの内容をコピペして"Deploy the stack"をクリック。
スタック一覧画面に戻ると、作成したスタックがデプロイされているのがわかる。
暫く待つと表示が変わってどうやらデプロイが完了した模様。
Edge AgentのDocker側を見てみるとそれぞれでコンテナがデプロイされているのがわかる。
kun432@docker-1:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6611d935d4d5 wordpress:latest "docker-entrypoint.s…" 8 seconds ago Up 7 seconds 0.0.0.0:80->80/tcp, [::]:80->80/tcp edge_sample-stack-wordpress-1
8696b8678885 mariadb:10.6.4-focal "docker-entrypoint.s…" 8 seconds ago Up 7 seconds 3306/tcp, 33060/tcp edge_sample-stack-db-1
fc2abb99777b portainer/agent:2.27.9 "./agent" 40 hours ago Up 40 hours
kun432@docker-2:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
650c8eeb8366 wordpress:latest "docker-entrypoint.s…" 6 seconds ago Up 5 seconds 0.0.0.0:80->80/tcp, [::]:80->80/tcp edge_sample-stack-wordpress-1
e4e77d572a9c mariadb:10.6.4-focal "docker-entrypoint.s…" 6 seconds ago Up 5 seconds 3306/tcp, 33060/tcp edge_sample-stack-db-1
dff542fdd59b portainer/agent:2.27.9 "./agent" 40 hours ago Up 40 hours portainer_edge_agent
これはGUIからも確認できる。該当のEdge Stackをクリックして、"Environments"タブをクリックするとこのように。
スタックをアップデートしてみる。該当のEdge Stackの"Stack"タブでエディタが表示されるので、修正して"Update the stack"をクリックする。MariaDBのバージョンを上げてみる。(実際にはこんなバージョンアップはしないと思うけど、今回はお試しなので)
デプロイされる
デプロイ完了
Edge Agent側でもMariaDBがアップデートされているのがわかる。
kun432@docker-1:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ed5f4540947f mariadb:10.6.22-jammy "docker-entrypoint.s…" 12 seconds ago Up 11 seconds 3306/tcp, 33060/tcp edge_sample-stack-db-1
6611d935d4d5 wordpress:latest "docker-entrypoint.s…" 10 minutes ago Up 10 minutes 0.0.0.0:80->80/tcp, [::]:80->80/tcp edge_sample-stack-wordpress-1
fc2abb99777b portainer/agent:2.27.9 "./agent" 40 hours ago Up 40 hours portainer_edge_agent
kun432@docker-2:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
68a1265cc599 mariadb:10.6.22-jammy "docker-entrypoint.s…" 9 seconds ago Up 8 seconds 3306/tcp, 33060/tcp edge_sample-stack-db-1
650c8eeb8366 wordpress:latest "docker-entrypoint.s…" 10 minutes ago Up 10 minutes 0.0.0.0:80->80/tcp, [::]:80->80/tcp edge_sample-stack-wordpress-1
dff542fdd59b portainer/agent:2.27.9 "./agent" 40 hours ago Up 40 hours portainer_edge_agent
その他
- プライベートレジストリをPortainerで設定できる
- Gitレポジトリを指定した場合(だと思う、エディタだとメニューが見当たらなかった)には以下なども指定できる
- デプロイの再試行の振る舞い
- 自動デプロイの展開の振る舞い(同時並列数とか)
などもできるみたいなので、ドキュメントを参照するのをオススメ。
エディタでやる場合、docker-compose.yml以外のファイルとかをアップロードしたりみたいなことは出来なさそうなので、まあめちゃめちゃシンプルなケースだけかな。上にも書いたけど、おそらくGitレポジトリを指定するのがメインになるのではないかと思う、記録も残るしね。
まとめ
いろいろ機能は豊富なので、かなり使えるのではなかろうか。エッジ向けユースケースが想定されているのも良いと思う。
自分の目的として、自動デプロイみたいなのができるかどうか?ということだったので、基本的な機能含めて雰囲気は理解できたので良かった。ただ、それだけの目的だともっとシンプルなソリューションもあるかもなぁ?という気もしている。
エディタでやる場合、docker-compose.yml以外のファイルとかをアップロードしたりみたいなことは出来なさそうなので、まあめちゃめちゃシンプルなケースだけかな。上にも書いたけど、おそらくGitレポジトリを指定するのがメインになるのではないかと思う、記録も残るしね。
どうやらCEだとダメっぽい?というか、Gitレポジトリを指定してdocker-compose.yaml以外のファイルもクローンはされるが、その場合のパス指定が相対では出来なくて、絶対パスにしようとしてもランダムなパスになるので指定できないってことみたい。BEは修正されていて、CEは修正されていないと。
あぁ、これはなかなか苦しいなぁ・・・試してないから今もそうなのかはわからないけど。