Cert-manager を使用した Admission Webhooks 証明書の管理

Cert-manager を使用した Admission Webhooks 証明書の管理

Kubernetes は、組み込み機能を拡張する方法を提供します。最も一般的に使用されるのは、おそらくカスタム リソース タイプとカスタム コントローラーです。さらに、Kubernetes には、API を拡張し、特定の Kubernetes リソースの基本的な動作を変更するために使用できる、アドミッション Webhook などの非常に興味深い機能がいくつかあります。

アドミッション コントローラーは、オブジェクトが永続化される前に Kubernetes API サーバーへのリクエストをインターセプトし、認証と承認後にリクエストを通過させるコード スニペットです。アドミッション コントローラは、検証、変更、またはその両方を行うことができます。変更コントローラーは処理するリソース オブジェクトを変更できますが、検証コントローラーは変更できません。どのフェーズでもいずれかのコントローラーがリクエストを拒否した場合、リクエスト全体が直ちに拒否され、エンド ユーザーにエラーが返されます。

つまり、Kubernetes API リクエストをインターセプトし、カスタム ロジックに基づいてリクエストを変更または拒否できる特別なコントローラーが存在するということです。 Kubernetes には、実装するコントローラーのリストがあります: https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#what-does-each-admission-controller-do。もちろん、独自のコントローラーを作成することもできます。これらのコントローラーはより強力に聞こえますが、kube-apiserver にコンパイルする必要があり、apiserver が起動したときにのみ起動できます。

kube-apiserver 起動パラメータを直接使用して、サポートされている組み込みコントローラーを表示することもできます。

 kube - apiserver --ヘルプ| grep有効化-入場-プラグイン

上記のコントローラーの制限により、API サーバーと結合する代わりに動的な概念を使用する必要があります。 Admission Webhook は、動的な構成方法を通じてこの制限を解決します。

アドミッションウェブフックとは何ですか?

Kubernetes apiserver には、MutatingAdmissionWebhook と ValidatingAdmissionWebhook という 2 つの特別なアドミッション コントローラーが含まれています。これら 2 つのコントローラは、外部 HTTP コールバック サービスにアドミッション要求を送信し、アドミッション応答を受信します。両方のアドミッション コントローラーが有効になっている場合、Kubernetes 管理者はクラスター内にアドミッション Webhook を作成して構成できます。

全体的な手順は次のとおりです。

  • クラスターでアドミッション Webhook コントローラーが有効になっているかどうかを確認し、必要に応じて構成します。
  • アドミッション要求を処理する HTTP コールバックを記述します。コールバックは、クラスターにデプロイされた単純な HTTP サービス、またはサーバーレス関数にすることもできます。
  • MutatingWebhookConfiguration および ValidatingWebhookConfiguration リソースを使用して、アドミッション Webhook を構成します。

これら 2 種類のアドミッション Webhook の違いは非常に明確です。検証 Webhook はリクエストを拒否できますが、アドミッション リクエストで取得されたオブジェクトを変更することはできません。一方、変更 Webhook は、アドミッション レスポンスを返す前にパッチを作成することでオブジェクトを変更できます。 Webhook がリクエストを拒否した場合、エンドユーザーにエラーが返されます。

人気のサービス メッシュ アプリケーション istio​ は、変更可能な Webhook を通じて Envoy サイドカー コンテナーを Pod に自動的に挿入します: https://istio.io/latest/docs/setup/additional-setup/sidecar-injection/。

入場Webhookの作成と設定

以上、Admission Webhookの理論的な知識を紹介しました。次に、実際の Kubernetes クラスターでテストします。 Webhook Web サーバーを作成し、クラスターにデプロイしてから、Webhook 構成を作成して動作するかどうかを確認します。

まず、API サーバーで MutatingAdmissionWebhook および ValidatingAdmissionWebhook コントローラーが有効になっていることを確認します。 --enable-admission-plugins パラメータを使用して設定します。現在の v1.25+ バージョンには、デフォルトの有効化が組み込まれています。有効になっていない場合は、これら 2 つのパラメータを追加して、apiserver を再起動します。

次に、次のコマンドを実行して、クラスターでアドミッション登録 API が有効になっているかどうかを確認します。

   kubectl api -バージョン| grep入場
admissionregistration.k8s.io/v1

これらの前提条件を満たしたら、Admission Webhook サーバーを作成できます。これは、実際には、サービス内の APIServer によって送信された AdmissionReview リクエストを処理する Web サーバーを開発することです。形式は次のとおりです。

 {
「apiバージョン」 : 「admission.k8s.io/v1」
"種類" : "入学レビュー" ,
...
"リクエスト" : {
#このアドミッションコール一意に識別するランダムなuid
「uid」 : 「d595e125-9489-4d1c-877d-0a05984355c8」
# object許可される新しいオブジェクトです
「オブジェクト」 : { 「apiVersion」 : 「v1」 , 「種類」 : 「Pod」 , ...},
...
}
}

次に、AdmissionReview オブジェクトを構築して返します。

 {
「apiバージョン」 : 「admission.k8s.io/v1」
"種類" : "入学レビュー" ,
"応答" : {
"uid" : "<request.uid からの値>" ,
「許可」 : true
}
}
// または
{
「apiバージョン」 : 「admission.k8s.io/v1」
"種類" : "入学レビュー" ,
"応答" : {
"uid" : "<request.uid からの値>" ,
「許可」 : false
"状態" : {
「コード」 : 402
「ステータス」「失敗」
「メッセージ」 : 「xxx」
「理由」「xxxx」
}
}
}

応答を決定するフィールドは .response.uid と .response.allowed です。前者はリクエストを一意に識別し、後者はリクエストが通過したかどうかを示します。ステータス フィールドは主にエラー プロンプトに使用されます。

Kubernetes e2e テスト https://github.com/kubernetes/kubernetes/blob/release-1.25/test/images/agnhost/webhook/main.go のサンプル実装コードを直接参照できます。

Webhookの作成

これまでの前提条件が整ったので、2 つの異なる HTTP エンドポイント (validate と mutate) をリッスンして、検証および変更 Webhook 検証を実行する Webhook の例を実装してみましょう。

この Webhook の完全なコードは Github で入手できます: https://github.com/cnych/admission-webhook-example (train4 ブランチ)。この Webhook は、Deployment を使用してクラスターにデプロイされた、TLS 認証を備えたシンプルな HTTP サービスです。

コードの主なロジックは、main.go と webhook.go の 2 つのファイルにあります。 main.go ファイルには HTTP サービスを作成するコードが含まれており、webhook.go には 2 つの webhook、検証、および変更のロジックが含まれています。コードの大部分は比較的単純です。まず、main.go ファイルを見て、標準の golang パッケージを使用して HTTP サービスを開始する方法と、コマンドライン フラグから TLS 構成証明書を読み取る方法を確認します。

フラグStringVar ( &パラメータ. certFile , "tlsCertFile" , "/etc/webhook/certs/cert.pem" , "HTTPS の x509 証明書を含むファイル。" )
フラグStringVar ( &パラメータ. keyFile , "tlsKeyFile" , "/etc/webhook/certs/key.pem" , "--tlsCertFile への x509 秘密キーを含むファイル。" )

次に重要なのは、mutate 関数と validating 関数に渡された HTTP リクエストを処理するために使用される serve 関数です。この関数は、リクエストから AdmissionReview オブジェクトを逆シリアル化し、いくつかの基本的なコンテンツ検証を実行し、URL パスに基づいて適切な mutate 関数と validate 関数を呼び出して、AdmissionReview オブジェクトをシリアル化します。

 // Webhook サーバーの Serve メソッド
func ( whsvr * WebhookServer ) serve ( w http.ResponseWriter , r * http.Request ) {
var body []バイト
rの場合本文!= nil {
データの場合err : = ioutilReadAll ( r.Body );エラー==ゼロ{
本文=データ
}
}
len (本体) == 0 の場合{
グログエラー( 「本文が空です」 )
http://www.youtube.com/watch?v=vUyQyYyxcエラー( w「空の本文」http . StatusBadRequest )
戻る
}

// コンテンツタイプが正しいことを確認する
コンテンツタイプ: = rヘッダー取得( "Content-Type" )
contentType != "application/json"の場合{
グログエラー( "Content-Type=%s、application/json が必要です"contentType )
http://www.youtube.com/watch?v=vUyQyYyxcエラー( w「無効なコンテンツ タイプ、`application/json` が必要です」httpStatusUnsupportedMediaType )
戻る
}

varadmissionResponse * admissionv1 入学申込書
ar : =入場v1入学審査{}
if _ , _ , err : =デシリアライザーデコード( bodynil& ar );エラー!=ゼロ{
グログErrorf ( "本文をデコードできません: %v"err )
admissionResponse = & admissionv1入学応答{
結果: & metav1状態{
メッセージ:エラーエラー()、
},
}
}それ以外{
fmtPrintln ( r . URL .パス)
rの場合.URL .パス== "/mutate" {
入場応答= whsvr変異( & ar )
}そうでなけれr.URL .パス== "/validate" {
入場応答= whsvr検証( & ar )
}
}

入場レビュー: =入場v1入学審査{}
入場レビュータイプメタ= metav1タイプメタ{
種類: 「AdmissionReview」
APIバージョン: "admission.k8s.io/v1"
}
入場応答nil場合{
入場レビューレスポンス= admissionResponse
ar の場合リクエスト!= nil {
入場レビュー応答UID = arリクエストユーザID
}
}

resperr : = jsonマーシャル入場審査
err != nil の場合{
グログErrorf ( "応答をエンコードできません: %v"err )
http://www.youtube.com/watch?v=vUyQyYyxcエラー( wfmt . Sprintf ( "応答をエンコードできませんでした: %v"err )、 http . StatusInternalServerError )
}
グログInfof ( "応答を書き込む準備ができました..." )
_の場合err : = w書く( resp );エラー!=ゼロ{
グログErrorf ( "応答を書き込めません: %v"err )
http://www.youtube.com/watch?v=vUyQyYyxcエラー( wfmt . Sprintf ( "応答を書き込めませんでした: %v"err )、 http . StatusInternalServerError )
}
}

主な承認ロジックは、検証関数と変更関数です。検証関数は、リソース オブジェクトを検証する必要があるかどうかを確認します。kube-system 名前空間内のリソースは検証されません。リソースが検証されていないことを明示的に宣言する場合は、リソース オブジェクトに admission-webhook-example.qikqiak.com/validate=false アノテーションを追加して宣言できます。検証が必要な場合、サービスまたはデプロイメント リソースは、リソース タイプの種類とタグを対応する項目と比較した上で、リクエストから逆シリアル化されます。一部のラベル タグが欠落している場合、応答の Allowed は false に設定されます。検証が失敗した場合、失敗の理由が応答に書き込まれ、エンドユーザーがリソースを作成しようとしたときに失敗メッセージが表示されます。検証関数は次のように実装されます。

 // デプロイメントとサービスを検証する
func ( whsvr * WebhookServer )検証( ar * admissionv1 . AdmissionReview ) * admissionv1 .入学応答{
要求: = arリクエスト
var (
availableLabelsマップ[文字列]文字列
オブジェクトメタ* metav1オブジェクトメタ
resourceNamespaceresourceName文字列


グログInfof ( "AdmissionReview、Kind=%v、Namespace=%v、Name=%v (%v)、UID=%v、patchOperatinotallow=%v、UserInfo=%v"
必要種類要件名前空間必須名前リソース名要件UID必須操作要件ユーザー情報)

スイッチが必要です親切親切{
ケース「デプロイメント」 :
varデプロイメントappsv1 .Deployment
err : = json の場合アンマーシャル( req . Object . Raw&デプロイメント);エラー!=ゼロ{
グログErrorf ( "raw オブジェクトをアンマーシャリングできませんでした: %v"err )
帰国入場v1入学応答{
結果: & metav1状態{
メッセージ:エラーエラー()、
},
}
}
resourceNameresourceNamespaceobjectMeta =デプロイメント名前展開名前空間およびデプロイメントオブジェクトメタ
availableLabels =デプロイメントラベル
ケース「サービス」 :
varサービスcorev1サービス
err : = json の場合アンマーシャル( req . Object . Raw& service );エラー!=ゼロ{
グログErrorf ( "raw オブジェクトをアンマーシャリングできませんでした: %v"err )
帰国入場v1入学応答{
結果: & metav1状態{
メッセージ:エラーエラー()、
},
}
}
resourceNameresourceNamespaceobjectMeta =サービス名前サービス名前空間&サービスオブジェクトメタ
availableLabels =サービスラベル
}

もし検証が必要(無視される名前空間オブジェクトメタ) {
グログInfof ( "ポリシー チェックのため %s/%s の検証をスキップしています"resourceNamespaceresourceName )
帰国入場v1入学応答{
許可: true
}
}

許可: = true
var結果* metav1状態
グログ情報( "利用可能なラベル:"availableLabels )
グログ情報( 「必須ラベル」requiredLabels )
_の場合rl : =範囲必須ラベル{
_の場合ok : = availableLabels [ rl ]; わかりました{
許可=
結果= & metav1状態{
理由: 「必要なラベルが設定されていません」
}
壊す
}
}

帰国入場v1入学応答{
許可:許可
結果:結果
}
}

検証が必要かどうかを判断する方法は次のとおりです。名前空間を通じて無視することも、注釈設定を通じて構成することもできます。

関数validationRequired ( ignoredList []文字列メタデータ* metav1.ObjectMeta ) bool {
必須: = admissionRequired ( ignoreListadmissionWebhookAnnotationValidateKeyメタデータ)
グログInfof ( "%v/%v の検証ポリシー: 必須:%v"メタデータ名前空間メタデータ名前必須)
返品が必要
}

func admissionRequired ( ignoreList []文字列admissionAnnotationKey文字列メタデータ* metav1 . ObjectMeta ) bool {
// 特別な Kubernetes システム名前空間をスキップします
_の場合名前空間: =範囲ignoreList {
メタデータの場合名前空間==名前空間{
グログInfof ( "%v は特別な名前空間内にあるため、検証をスキップします:%v"メタデータ.名前メタデータ.名前空間)
を返す
}
}

注釈: =メタデータ注釈を取得します()
アノテーション== nil の場合{
注釈=マップ[文字列]文字列{}
}

var必須bool
スイッチ文字列ToLower (アノテーション[ admissionAnnotationKey ]) {
デフォルト
必須= true
ケース"n""no""false""off" :
必須=
}
返品が必要
}

mutate 関数のコードは非常に似ていますが、タグを比較して応答に Allowed を設定するのではなく、不足しているタグをリソースに追加し、not_available をタグの値に設定するパッチが作成されます。

 // メインの変異プロセス
func ( whsvr * WebhookServer ) mutate ( ar * admissionv1 . AdmissionReview ) * admissionv1 .入学応答{
要求: = arリクエスト
var (
availableLabelsavailableAnnotationsマップ[文字列]文字列
オブジェクトメタ* metav1オブジェクトメタ
resourceNamespaceresourceName文字列


グログInfof ( "AdmissionReview、Kind=%v、Namespace=%v、Name=%v (%v)、UID=%v、patchOperatinotallow=%v、UserInfo=%v"
必要種類要件名前空間必須名前リソース名要件UID必須操作要件ユーザー情報)

スイッチが必要です親切親切{
ケース「デプロイメント」 :
varデプロイメントappsv1 .Deployment
err : = json の場合アンマーシャル( req . Object . Raw&デプロイメント);エラー!=ゼロ{
グログErrorf ( "raw オブジェクトをアンマーシャリングできませんでした: %v"err )
帰国入場v1入学応答{
結果: & metav1状態{
メッセージ:エラーエラー()、
},
}
}
resourceNameresourceNamespaceobjectMeta =デプロイメント名前展開名前空間デプロイメントオブジェクトメタ
availableLabels =デプロイメントラベル
ケース「サービス」 :
varサービスcorev1サービス
err : = json の場合アンマーシャル( req . Object . Raw& service );エラー!=ゼロ{
グログErrorf ( "raw オブジェクトをアンマーシャリングできませんでした: %v"err )
帰国入場v1入学応答{
結果: & metav1状態{
メッセージ:エラーエラー()、
},
}
}
resourceNameresourceNamespaceobjectMeta =サービス名前サービス名前空間&サービスオブジェクトメタ
availableLabels =サービスラベル
}

もし変異が必要(無視される名前空間オブジェクトメタ) {
グログInfof ( "ポリシー チェックのため %s/%s の検証をスキップしています"resourceNamespaceresourceName )
帰国入場v1入学応答{
許可: true
}
}

アノテーション: = map [文字列]文字列{ admissionWebhookAnnotationStatusKey : "mutated" }
patchByteserr : = createPatch (利用可能なアノテーションアノテーション利用可能なラベル追加ラベル)
err != nil の場合{
帰国入場v1入学応答{
結果: & metav1状態{
メッセージ:エラーエラー()、
},
}
}

グログInfof ( "AdmissionResponse: patch=%v\n"文字列( patchBytes ))
帰国入場v1入学応答{
許可: true
パッチ: patchBytes
パッチタイプ: func () * admissionv1パッチタイプ{
pt : = admissionv1 .PatchTypeJSONPatch
戻り& pt
}(),
}
}

建てる

実際、コードを Docker イメージにパッケージ化しているので、直接使用できます。イメージ リポジトリのアドレスは cnych/admission-webhook-example:v4 です。もちろん、コードの一部を変更する場合は、プロジェクトを再構築する必要があります。このプロジェクトは go 言語で開発されており、パッケージ管理ツールが go mod に変更されているため、事前にビルド環境に go 環境がインストールされていることを確認する必要があります。もちろん、docker イメージにパッケージ化する必要があるため、docker も不可欠です。

プロジェクトを入手:

   mkdir admission - webhook && cd admission - webhook
gitクローンhttps://github.com/cnych/admission-webhook-example.git
git checkout train4 # train4 ブランチ

コードのルート ディレクトリの下にビルド スクリプトがあることがわかります。独自の Docker イメージのユーザー名を指定して、直接ビルドするだけです。

   DOCKER_USER = cnychをエクスポートします
./ビルド

展開する

apiserver に Admission Webhook を登録します。 apiserver はどのようにしてサービスの存在を認識し、インターフェースを呼び出すのでしょうか?これには、ValidatingWebhookConfiguration オブジェクトと MutatingWebhookConfiguration オブジェクトの使用が必要です。このリソース オブジェクトを作成することにより、apiserver は ValidatingAdmissionWebhook コントローラー モジュールに webhook を登録します。このオブジェクトを作成するときに注意すべき点がいくつかあります。

  • apiserver は HTTPS Webhook のみをサポートしているため、TLS 証明書を準備する必要があります。これは通常、KubernetesCertificateSigningRequest または cert-manager を使用して取得できます。
  • clientConfig.caBundle は、TLS 証明書を発行するための CA 証明書を指定するために使用されます。 Kubernetes CertificateSigningRequest を使用して証明書を発行する場合は、kube-public 名前空間 clusterinfo からクラスター CA を取得し、base64 でフォーマットしてから、clientConfig.caBundle に書き込むことができます。 cert-manager を使用して証明書を発行する場合、コンポーネントは自動的に証明書を挿入します。
  • 自分自身が傍受されるのを防ぐには、objectSelector を使用して自分自身を除外することができます。
  • クラスタにデプロイする場合は、サービスリファレンスを使用してサービスを指定します。
  • クラスターの外部にデプロイする場合は、URLを使用してHTTPSインターフェースを指定します。

ここでは、以下に示すように ValidatingWebhookConfiguration オブジェクトを作成します。

 apiバージョン: admissionregistrationk8sio / v1
種類: ValidatingWebhookConfiguration
メタデータ:
名前:検証- Webhook -- cfg
ラベル:
アプリ:入場- Webhook -
注釈:
証明マネージャーio / inject - ca - from : default / admission - example - tls - secret # $ ( CERTIFICATE_NAMESPACE ) / $ ( CERTIFICATE_NAME )
ウェブフック:
-名前:必須-ラベルキキキアックcom
入場レビューバージョン:
- v1
クライアント構成:
caBundle : "" # "<Kubernetes CA> または <cert-manager CA>"
サービス
名前:入場- Webhook -- SVC
名前空間:デフォルト
ポート: 443
パス: /検証
ルール:
-操作: [ "CREATE" ]
apiGroups : [ "アプリ" , "" ]
apiバージョン: [ "v1" ]
リソース: [ "デプロイメント""サービス" ]
名前空間セレクタ:
マッチラベル:
入場- Webhook -:有効
失敗ポリシー:失敗
一致ポリシー:正確
副作用:なし

このオブジェクトでは、検証 Webhook を登録し、clientConfig.service を通じて Webhook のアドレスを指定します。通常は、caBundle のコンテンツも指定する必要がありますが、cert-manager を使用して CA コンテンツを自動的に挿入できるように、ここで cert-manager.io/inject-ca-from: default/admission-example-tls-secret アノテーションを設定します。さらに、namespaceSelector も構成して、admission-webhook-example: enabled ラベルを持つ名前空間にのみ Webhook が適用されるように指定します。

したがって、ここでも cert-manager をデプロイする必要があります。

   kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.10.1/cert-manager.yaml

インストールが完了すると、次の Pod が cert-manager 名前空間で実行されます。

   kubectl get pods - n cert - manager
名前準備完了ステータス再起動年齢
cert - manager - 74 d949c895 - 4 v8kj 1 / 1実行中0 71
cert - manager - cainjector - d9bc5979d - 2 tt4v 1 / 1実行中0 71
cert - manager - webhook - 84 b7ddd796 - 7 wdgk 1 / 1実行中0 71

cert-manager には、CA バンドルを Mutating に挿入する CA インジェクターと呼ばれるコンポーネントがあります。 WebhookConfigurationを検証しています。 Mutating | でキー certmanager.k8s.io/inject-ca-from を持つアノテーションを使用する必要があります。 ValidatingWebhookConfiguration オブジェクト。アノテーションの値は、<certificate-namespace>/<certificate-name> の形式で既存の証明書 CR インスタンスを指す必要があります。

ここでは、以下に示すように、自己署名発行者のみを必要とする証明書オブジェクトを作成します。

 apiバージョン: cert-manager.io/v1
種類:発行者
メタデータ:
名前:入場--発行者
名前空間:デフォルト
仕様:
自己署名: {}
---
apiバージョン: cert-manager.io/v1
種類:証明書
メタデータ:
名前:入場-- tls -秘密
仕様:
所要時間: 8760時間
更新前: 8000時間
主題
組織:
-キキキアックcom
commonName :入場- webhook - example - svcデフォルト
isCA :
秘密鍵:
アルゴリズム: RSA
エンコーディング: PKCS1
サイズ: 2048
使用法:
-デジタル署名
-キー暗号
-サーバー認証
dns名:
-入場- Webhook -- SVC
-入場- Webhook -- SVCデフォルト
-入場- Webhook -- SVCデフォルトサービス
発行者参照:
種類:発行者
名前:入場--発行者
secretName :入場- webhook --証明書

ここでの Certificate オブジェクトの名前は上記の注釈に対応する必要があり、その後、発行された最終証明書を admission-webhook-example-certs という名前の Secret オブジェクトに書き込むことに注意してください。

次に、Webhook サーバーをデプロイします。展開は非常に簡単で、サービスの TLS 構成を構成するだけで済みます。コード ルート ディレクトリの下のデプロイメント フォルダーの下にある deploy.yaml ファイルで証明書に関する構成宣言を確認すると、コマンド ライン パラメーターから読み取られた証明書と秘密キー ファイルがシークレット オブジェクトを介してマウントされていることがわかります。

引数:
- - tlsCertFile = /etc/webhook/certs/tls.crt
- - tlsKeyFile = /etc/webhook/certs/tls.key
[...]
ボリュームマウント:
-名前: webhook -証明書
マウントパス: / etc / webhook / certs
読み取り専用: true
巻数:
-名前: webhook -証明書
秘密
secretName :入場- webhook --証明書

admission-webhook-example-certs オブジェクトは、上記の Cert-manager によって作成された Certificate オブジェクトによって自動的に生成されます。シークレット オブジェクトが正常に作成されると、デプロイメント オブジェクトとサービス オブジェクトを直接作成できます。

   kubectl apply -fデプロイメント/ rbac .yaml
kubectl apply -fデプロイメント/デプロイメント.yaml
展開アプリ「admission-webhook-example-deployment」が作成されました
kubectl apply -fデプロイメント/サービス.yaml
サービス「admission-webhook-example-svc」が作成されました

次に、デフォルトの名前空間に次のタグを追加します。

   kubectlラベル名前空間デフォルトアドミッション- webhook -=有効
名前空間「デフォルト」ラベル

最後に、上記の validatingwebhookconfigurations オブジェクトを作成できます。正常に作成されると、リクエストをインターセプトして webhook サービスを呼び出します。

   kubectl でWebhook構成を検証する
名前ウェブフック年齢
検証- Webhook -- cfg 1 9 分52 秒

テスト

それでは、デプロイメント リソースを作成して、それが効果的かどうかを確認しましょう。コード リポジトリには sleep.yaml リソース マニフェスト ファイルがあります。直接作成することもできます:

   kubectl apply -fデプロイメント/スリープ.yaml
サーバーからのエラー(必須ラベル設定されていません) : 「deployment/sleep.yaml」の作成中にエラーが発生しました:アドミッションWebhook 「required-labels.qikqiak.com」リクエスト拒否しました:必須ラベル設定されていません

通常、必要なラベルが何も作成されていないため、作成時に上記のエラー メッセージが表示されます。その後、sleep-with-labels.yaml の別のリソース リストをデプロイします。

   kubectl apply -fデプロイメント/ sleep -with - labels .yaml
展開アプリ「スリープ」作成

展開が正常であることがわかります。次に、上記のデプロイメントを削除し、別の sleep-no-validation.yaml リソース マニフェストをデプロイします。このマニフェストには必要なラベルが存在しませんが、admission-webhook-example.qikqiak.com/validate=false アノテーションが設定されているため、正常に作成できます。

   kubectlデプロイメントスリープを削除する
kubectl apply -fデプロイメント/スリープ-no -検証.yaml
展開アプリ「スリープ」作成

ミューテーティングWebhookをデプロイする

同じ方法で、MutatingWebhookConfiguration オブジェクトを作成できます。まず、変更の干渉を防ぐために上記の検証 Webhook を削除し、新しい構成をデプロイします。 mutating webhook の構成は、validating webhook と基本的に同じですが、webook サーバーのパスは /mutate です。

 apiバージョン: admissionregistrationk8sio / v1
種類: MutatingWebhookConfiguration
メタデータ:
名前: mutating - webhook -- cfg
ラベル:
アプリ:入場- Webhook -
注釈:
証明マネージャーio / inject - ca - from : default / admission - example - tls - secret
ウェブフック:
-名前:変化-キキキアックcom
入場レビューバージョン:
- v1
クライアント構成:
caBundle : "" # "<Kubernetes CA> または <cert-manager CA>"
サービス
名前:入場- Webhook -- SVC
名前空間:デフォルト
ポート: 443
パス: / mutate
ルール:
-操作: [ "CREATE" ]
apiGroups : [ "アプリ" , "" ]
apiバージョン: [ "v1" ]
リソース: [ "デプロイメント""サービス" ]
名前空間セレクタ:
マッチラベル:
入場- Webhook -:有効
失敗ポリシー:失敗
一致ポリシー:正確
副作用:なし

これで、スリープ アプリケーションを再度デプロイし、ラベルが正しく追加されたかどうかを確認できます。

   kubectlmutatingwebhook 設定を取得します
名前ウェブフック年齢
変化- Webhook -- cfg 1 42
kubectl apply -fデプロイメント/スリープ.yaml
展開アプリ「スリープ」作成
kubectl get deploy sleep - o yaml
apiバージョン:アプリ/ v1
種類:デプロイメント
メタデータ:
注釈:
入場- Webhook -キキキアックcom /ステータス:変異
展開Kubernetesio /リビジョン: "1"
作成タイムスタンプ: "2023-01-05T08:43:59Z"
世代: 1
ラベル:
アプリKubernetesio /コンポーネント:利用できません
アプリKubernetesio /インスタンス:利用できません
アプリKubernetesio /管理-提供元: not_available
アプリKubernetesio /名前:利用できません
アプリKubernetesio /一部:利用不可
アプリKubernetesio /バージョン:利用できません
名前:スリープ
名前空間:デフォルト
# ......

最後に、検証 Webhook を再作成して一緒にテストしてみましょう。ここで、もう一度睡眠アプリを作成してみます。通常は正常に作成できます。

アドミッション制御は 2 つのフェーズで実行されます。最初のフェーズでは、変更アドミッション コントローラが実行され、2 番目のフェーズでは、検証アドミッション コントローラが実行されます。

したがって、変更 Webhook は最初のフェーズで不足しているラベルを追加し、ラベルがすでに存在し、その値が not_available で設定されているため、検証 Webhook は 2 番目のフェーズでデプロイメントを拒否しません。

   kubectl apply -fデプロイメント/ validatingwebhook .yaml
Webhook 構成を検証しています入学登録k8sio 「validation-webhook-example-cfg」が作成されました
kubectl delete -fデプロイメント/スリープ.yaml
展開アプリ「スリープ」が削除されました
kubectl apply -fデプロイメント/スリープ.yaml
デプロイメント.apps / sleepが作成されました

しかし、このような関連要件がある場合、アドミッション コントローラー用の Webhook を個別に開発するのは非常に面倒で柔軟性に欠けます。この問題を解決するには、Kyverno、Gatekeeper など、Kubernetes が提供するポリシー管理エンジンを使用して、コードを記述せずに要件を満たすことができます。公式の Kubernetes v1.26 バージョンでは、ポリシー管理のサポートも追加されました。

<<:  クラウドコンピューティングが企業を変革し、モバイル化する方法

>>:  オラクル、2023年のクラウドコンピューティングに関する5つの予測を発表

推薦する

COVID-19により銀行はクラウドコンピューティングの導入を迫られているが、まずは戦略を立てる必要がある

COVID-19 パンデミックは、銀行業界が長年にわたって議論されてきた大きな問題、つまりクラウド ...

重要な報告 |今後のデジタル開発における9つの主要トレンド

2月20日、アリババクラウドリサーチセンターは「2019年デジタルトレンドレポート」を発表しました。...

「模倣アプリ」はアカウント、料金、データを盗みます。彼らはあらゆる悪事を働きます

今はモバイルの時代です。パソコン、携帯電話、タブレット、スマートテレビ、車など、さまざまなモバイル端...

郡レベルのポータルステーションは、最初のポータルステーションになった場合にのみ開発の機会を得ることができます。

多くの郡レベルのウェブサイトを分析した結果、ほとんどの郡にはまだ市場の可能性が残っていることがわかり...

hostnamaste: $3.99/KVM/512m メモリ/Windows|4 つのデータセンター

インド企業であるhostnamasteは、2017年にドメイン名を登録しました。同社は主にホスティン...

WeChat パブリックアカウントを目立たせるにはどうすればいいですか?

考えてみてください。WeChat のパブリック アカウントは、実際には雑誌、テレビ番組、有名ブランド...

Pacificrack: 米国クラスター VPS、32 C セグメント、無料スナップショット + フルバックアップ、月額 4 ドルから

Pacificrack は、まったく新しい「サイト クラスター VPS」を導入しました。これは、デフ...

企業はクラウドセキュリティの問題を弁証法的に捉える必要がある

セキュリティ問題に関する小さな提案でさえ、クラウド コンピューティング プロジェクトを台無しにし、ク...

SEOを学ぶための最も基本的な知識をいくつか教えます

SEO は長年にわたって発展してきました。検索エンジンのアルゴリズムが継続的に改善されるにつれて、多...

ウェブマスターネットワークからの毎日のレポート:テンセントが速達サービスを開始、グループ購入による遺伝子変異が増加

1. Weiboの主要アカ​​ウントが消滅。これはWeiboの急成長期の極端な例です。彼らはWeib...

hostodo-$18/年/メモリ 1g/ハードディスク 150g/トラフィック 3T/QuadraNet/ロサンゼルス

もう一度Hostodoを紹介させてください。その理由は、QuadraNetのロサンゼルスデータセンタ...

SEO情報は溢れています。研究のために質の高いコンテンツを選択するにはどうすればいいのでしょうか?

昨日、多くのSEO担当者の強い要望により、SEO業界最強のSEOフォーラムBSGの管理者がWeibo...

ハイブリッドクラウドと将来のクラウドアプリケーションの利点

過去 10 年間で、クラウド コンピューティングは、インターネット ベースのコンピューティングの一種...

racknerd: 年間 28.2 ドル、60 GB の高セキュリティ VPS、KVM/3 GB メモリ/3 コア/42 GB ハード ドライブ/5 TB、PayPal/Alipay

racknerd からの最新ニュース: (1) DC-02 のこれまでの VPS プロモーションはす...

「ラブアンドプロデューサー」の広告は、革新的なマーケティングとオンラインとオフラインの連携を生み出し、ブランドを強化します。

2018年最もホットなプロジェクト:テレマーケティングロボットがあなたの参加を待っています驚異的な国...