導入のための Docker とシステム化されるのはなぜですか

コンテナ化されたサービスは、予期しない再起動、ハードウェアの故障、またはパッケージの更新を生き残る現代のインフラ要求。 Docker は、再起動ポリシー () を提供しますが、これらのポリシーは、Docker デーモンが実行されている限りのみ機能します。 体系化 - Ubuntu、Debian、Fedora、CentOS、およびほとんどの近代的な Linux ディストリビューションで使用される初期システム - ドーパーデーモン自体のライフサイクルを管理し、Docker ソケットが利用可能な前にコンテナを起動することができます。 以下のようなシステムがあります。

  • 依存ディレクティブ(例えば、ネットワークのターゲットを、Docker.service の後の) による起動順を保証
  • で統一されたロギング、デバッグを簡単フォワード
  • 省資源化の制限(CPU、メモリ、I/O)をシステム単位ディレクティブで適切に管理
  • 設定可能な遅延とバーストの制限で自動再起動
  • ソケットの活発化およびタイム・スタートアップのためのサポート

システム化されたサービスファイルで各Dockerコンテナをラップすることで、作業チームは、起動、停止、監視コンテナの一貫したインターフェイスを獲得し、アドホックスクリプトやマニュアルの介入に依存する。

単一のドッカーコンテナ用のシステムサービスを作成する

標準アプローチは、Dockerコマンドを呼び出してコンテナを実行し、停止するサービスユニットファイルを書くことを含みます。 以下では、プロセスステップをステップバイステップで歩き、基本的な例から始まり、一般的な生産要件をカバーしています。

ステップ1: サービスユニットファイルを書く

[ というファイルを作成します。 開始点として、次のテンプレートを使用します。

[Unit]
Description=My Application Container
After=network-online.target docker.service
Wants=network-online.target
Requires=docker.service

[Service]
Restart=always
RestartSec=10
StartLimitBurst=3
ExecStartPre=-/usr/bin/docker kill myapp
ExecStartPre=-/usr/bin/docker rm myapp
ExecStart=/usr/bin/docker run --rm --name myapp \
 -e DB_HOST=10.0.1.50 \
 -e DB_PORT=5432 \
 -v /data/myapp:/app/data \
 -p 8080:8080 \
 myregistry/myapp:latest
ExecStop=/usr/bin/docker stop -t 10 myapp
ExecStopPost=-/usr/bin/docker rm myapp

[Install]
WantedBy=multi-user.target

:キーディレクティブの解説:[

  • ] - コンテナを起動する前に Docker デーモンが実行されていることを確認します。
  • ] - Dockerが停止した場合、このサービスは停止します。
  • ]] – 前の実行から任意の残りのコンテナをクリーンアップ ()] プレフィックスは、ここで非致命的であることを意味します。
  • ] – コンテナを自動削除するためにを使用します。
  • ] – タイムアウトでコンテナを優雅に停止 (10秒).
  • []] – 出口コードに関係なくコンテナを再起動します。
  • [] – 再起動する前に10秒待ってください。
  • []] - 再起動ループを回避するために、間隔(デフォルト10秒)ごとに3つの試みをリモットする。

ステップ2:サービスを有効にして開始する

sudo systemctl daemon-reload
sudo systemctl enable myapp.service
sudo systemctl start myapp.service

は、サービスファイルを再読み込みするためにシステム化されたことを伝えます。 [] は、サービスが起動時に開始するように、symplinkを作成します。

標準的なシステムコマンドでサービスを管理する

サービスの実行が完了すると、他のシステムサービスと同様に制御できます。

  • ]スタート:
  • ]:] ]
  • ]再起動:
  • スタトス:
  • ログ: ] (ライブログをフォロー)

高度な構成パターン

生産展開は、多くの場合、単純な[以上が必要です。 以下は、システム化されたサービスファイルに追加できる一般的な強化です。

環境変数を渡る

サービスのファイルのハードコーディングの秘密や構成は推奨されません。代わりに、別の環境ファイルを使用します。

[Service]
EnvironmentFile=-/etc/myapp/env.conf
ExecStart=/usr/bin/docker run --rm --name myapp \
 --env-file /etc/myapp/env.conf \
 myregistry/myapp:latest

パスの前に接頭辞は、ファイルが存在しない場合でも、サービスが起動することを意味します(初期設定中に役立ちます)。

ネットワーキングとポートの結合

同じホスト上で互いに通信する必要がある場合は、[ またはユーザー定義のブリッジネットワークの使用を検討してください。例:

ExecStart=/usr/bin/docker run --rm --name web \
 --network=my-net \
 -p 443:443 \
 -v /etc/ssl/certs:/etc/ssl/certs:ro \
 myregistry/web:latest

カスタムネットワークを使用する場合は、サービスが始まる前にネットワークが存在することを確認してください。 [] コマンドを追加して、次のコマンドを実行します。

ExecStartPre=/usr/bin/docker network create my-net

インターコンテーナーの依存関係

開始前に、あるコンテナが別の準備を要求する場合(例えば、データベースを待っているWebアプリ)、システム化は注文を強制することができます。データベースの2番目のサービスファイルを作成し、次に:

[Unit]
Description=Web App Container
After=network-online.target docker.service mydb.service
BindsTo=mydb.service

は、Web アプリのライフサイクルをデータベースコンテナに結びます。データベースが停止した場合、Web アプリも停止します。

健康チェックと準備

Docker 健康チェックは、システム化されたシステムで統合して、早期サービスの利用を防止することができます。 [] は、健康エンドポイントをポーリングするスクリプトで使用します。

ExecStartPost=/usr/local/bin/wait-for-health.sh http://localhost:8080/health 30

コンテナが健康状態のときだけ、スクリプトは 0 を終了します。失敗すると、システムマークはユニットを失敗したままにマークします。

リソース制限は、システム化による

Docker のリソースフラグなしで cgroup レベルでコンテナの CPU とメモリを制約できます。これは、複数のコンテナを 1 つのホストで実行する際に特に便利です。

[Service]
MemoryMax=512M
CPUQuota=50%

これらの設定は、システム化されたシステムが Docker の独立して強制するというハード 制限を作成します。

複数のコンテナの管理: システム対ドッカーコンポース

コンテナ(2-5など)の小さな数では、個々のシステム化されたサービスファイルがシンプルで保守可能です。しかし、プロジェクトが多くの相互接続サービスを伴う場合、Docker Composeはより便利になります。Docker Composeのコンパスを1つのサービスユニットを作成することで、システム化されたことで、Docker Composeのスタック全体を「」と呼ぶようにすることもできます。例:

[Unit]
Description=My Application Stack
After=network-online.target docker.service
Requires=docker.service

[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/opt/myapp
ExecStart=/usr/local/bin/docker-compose up -d
ExecStop=/usr/local/bin/docker-compose down

[Install]
WantedBy=multi-user.target

このアプローチは、システム化されたライフサイクル管理と組み合わせたサービスを定義するためのコンポースのシンプルさを提供します。 がすぐに終了するため、使用されていることに注意してください。 ] は、 が呼び出されるまで、ユニットを "active" 状態に保ちます。

どの方法を選ぶべきか。

  • []個別システムサービス[ - 特定のアプリケーション、厳密な起動順のあるサービス、または、/-containerリソース制限を必要とする場合に最善を尽くします。
  • []Docker Compose は、システム化された[ - 依存関係がコンポースによって内部で処理されるマイクロサービススタックに理想的で、グループ全体を管理するための単一のユニットが必要です。

一般的な問題のトラブルシューティング

慎重に設定しても、問題が発生する可能性があります。 以下は頻繁に下落し、その解決策です。

「Dockerデーモンに接続できません」とサービス障害

通常、Docker ソケットが準備される前にサービスが始まります。 ユニットに と が含まれていることを確認してください。 また、Docker デーモンが有効になっていることを確認します。 ]。

コンテナはループで再起動します

コンテナがすぐに終了したら、システム化されたシステムが[と[に従って再起動します。 でコンテナのログを確認します。 を増加させ、 を強制ループを防ぐために設定します。

サービスを清潔に止めません

誤って設定されたはコンテナの実行を離れる場合があります。 が正しいコンテナ名を使用することを確認してください。 ]を使用して、停止が失敗すると、コンテナを強制的に削除します。

環境変数 負荷無し

を使うと、ファイルが存在することを確認し、root で読みやすくなります。 引用の問題を避けてください。 体系化されたストリップは変数値から引用します。 秘密の注射のために、システム化された認証情報や専用の秘密管理者を使用して検討してください。

セキュリティの考慮事項

システム化された実行中の Docker コンテナは、いくつかのセキュリティポイントを上げます。

  • 可能な限り、システム化されたサービスがrootでないユーザとして実行されます( と ] ディレクティブは、 ユーザが Docker ソケットにアクセスしたり、rootless モードで実行したりするのを確実にします)。
  • 必要ない限り、システム単位での使用を避けてください。
  • コンテナがホストに書き込む必要がない場合、読み込み専用のバインドマウント()を使用します。
  • レバーシステムのと[]をエスケープに対してユニットを硬化させます。
[Service]
ProtectSystem=strict
ReadWritePaths=/var/log/myapp
PrivateTmp=true
User=myappuser

外部リソース

詳しくは、以下の公式の参考文献をご覧ください。

コンテンツ

Dockerコンテナとシステムを統合することで、堅牢で自動化されたスタートアップメカニズムが、Linuxシステムの残りの部分とシームレスに統合されます。 適切に構造化されたサービスユニットファイルを記述することで、スタートアップの注文を管理し、依存関係の管理、リソース制限の設定、および既に知っているツールを使用してログを監視できます。 各コンテナまたはコンパススタックをオーケストするための単一のユニットを選択するかにかかわらず、システム化された生産環境の需要が信頼性と予測性を提供します。

ユニットファイルから始めて、徹底的にテストし、環境ファイル、健康チェック、セキュリティ強化などの高度なオプションをレイヤーします。このアプローチにより、Dockerコンテナは、手動での介入なしに再起動、クラッシュ、構成変更を生き残し、チームを解放してアプリケーションを構築することが可能になります。