web-dev-qa-db-ja.com

実行時にコンテナーをKubernetesポッドに追加する方法

私は ジョブ をk8sで実行しています。

これらのジョブは、一部のファイルをコピーし、ユーザー(信頼できる)が提供するコンテナーを実行するための環境をセットアップするカスタムエージェントを実行します。このエージェントは、ユーザーコンテナーの側面で実行され、ログをキャプチャし、コンテナーが終了して生成された結果を処理するのを待ちます。

これを実現するには、Dockerのソケット/var/run/docker.sockをマウントして特権コンテナとして実行し、エージェント内から docker-py を使用してユーザーコンテナと対話します(セットアップ、実行、キャプチャ)ログ、終了)。

これはほぼ問題なく動作しますが、ハックだと思います。ユーザーコンテナーはノードで直接dockerを呼び出して作成されたため、k8sはその存在を認識しません。監視ツールがK8とやり取りし、これらのスタンドアロンユーザーコンテナーを表示できないため、これにより問題が発生しています。また、ユーザーコンテナーの制限(cpu /メモリ)がポッドのリクエストとして考慮されないため、ポッドのスケジュール管理が難しくなります。

私は init Containers を知っていますが、エージェントを実行し続け、完了するまでユーザーコンテナーを監視する必要があるため、これらはこのユースケースに完全には適合しません。

ポッドで実行されているコンテナが、エージェントが実行している同じポッドに追加のコンテナを追加するようにKubernetesに要求することは可能ですか?その場合、エージェントはKubernetesにユーザーコンテナを自由に削除するように要求することもできますか(たとえば、特定のカスタム条件が満たされた場合)?

7
Xocoatzin

このGitHubの問題 から、ポッド仕様のコンテナリストは不変であるため、ポッドへのコンテナの追加または削除は不可能であるように思われます。

2
Xocoatzin

共有ボリューム を使用して、ポッド内の複数のコンテナー間でデータを共有できます。これにより、エージェントコンテナーはユーザーコンテナーに書き込まれたログファイルから読み取り、構成ファイルをセットアップ用の共有ボリュームにドロップできます。

このようにして、ユーザーコンテナーとエージェントコンテナーを、ポッド内の両方のコンテナーでジョブとして実行できます。両方のコンテナが終了すると、ジョブが完了します。

上記で、ユーザーコンテナーを手動で終了していることを示しているようです。共有ボリューム上のファイルが存在する場合にユーザーに実行を強制的に終了させるようなことを行わない限り、共有ボリュームを介したサポートは行われません。

ポッドで実行されているコンテナが、エージェントが実行している同じポッドに追加のコンテナを追加するようにKubernetesに要求することは可能ですか?その場合、エージェントはKubernetesにユーザーコンテナを自由に削除するよう要求することもできますか(たとえば、特定のカスタム条件が満たされた場合)?

既存のジョブポッド定義にコンテナーを追加する方法を知りません。ジョブにはレプリカオプションがないため、Deploymentの場合と同様に、レプリカを0-> 1から変更してハックすることはできません。

kubectlを使用してポッド全体ではなくコンテナを削除する方法を知りません。 kubectl delete を参照してください。

ユーザーコンテナーを強制終了するのではなく強制終了する場合は、ホストにアクセスして、ユーザーコンテナーでdocker kill <sha>を使用する必要があります。ユーザーコンテナに.spec.template.spec.restartPolicy = "Never"を設定してください。そうしないと、k8sによって再起動されます。

私はお勧めします:

  • ログをエージェントに転送して、エージェントがユーザーコンテナをセットアップできるようにする共有ボリュームを用意する
  • ユーザーコンテナーが独自に終了し、共有ボリュームから構成を読み取ることを期待させる

あなたがどのようなワークロードを行っているのか、またはユーザーがどのようにコンテナーを作成しているのかはわかりません。ユーザーがコンテナを構築する方法を指示できない場合、上記は機能しない可能性があります。

別のオプションは、ユーザーコンテナでコマンドAPIとして機能するバイナリを提供することです。このバイナリは、RPCを介して「セットアップ」、「実行」、「終了」、「転送ログ」などのコマンドを受け入れることができ、Dockerコンテナのメインプロセスになります。

次に、ユーザーのビルドプロセスを次のようにします。

  • Your-container-with-binary:latestから
  • このコンテナに何でも入れて、ENV JOB_PATH =/path/to/executable/codeを設定します(またはコードを特定の場所に配置します)

どちらの方法で実現するにせよ、多くの可動部分があります。

0
Dave Koston

コンテナをポッドに動的に挿入するには、次のようにします。 https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/

アドミッションコントローラは、オブジェクトの永続化の前であるが、リクエストが認証および承認された後で、Kubernetes APIサーバーへのリクエストをインターセプトするコードです。コントローラーは以下のリストで構成され、kube-apiserverバイナリにコンパイルされ、クラスター管理者のみが構成できます。そのリストには、MutatingAdmissionWebhookとValidatingAdmissionWebhookの2つの特別なコントローラーがあります。これらは、APIで構成された変更と検証(それぞれ)のアドミッションコントロールWebhookを実行します。

アドミッションコントローラは、「検証」、「変更」、またはその両方の場合があります。コントローラーを変更すると、許可するオブジェクトが変更される場合があります。コントローラーの検証は行われない場合があります。

そして、追加のランタイム要件をポッドに注入できます: https://kubernetes.io/docs/concepts/workloads/pods/podpreset/

ポッドプリセットは、追加のランタイム要件を作成時にポッドに注入するためのAPIリソースです。ラベルセレクターを使用して、特定のポッドプリセットを適用するポッドを指定します。

0
Emre Savcı

私はあなたがそのように実行中のポッドを変更することはできないと思いますが、あなたは確かにあなた自身のポッドを定義し、APIを使用してプログラムでそれを実行することができます

つまり、ユーザーコンテナーと他のコンテナーを使用してポッドを定義し、ユニットとして実行する必要があります。ユーザーコンテナーが終了した後に後処理を完了するには、活性チェックをいじる必要がある可能性があります

0
Lev Kuznetsov