デプロイが壁にぶつかったときCI/CDパイプラインは順調に進んでいますが、突然 kubectl apply が30秒間ハングし、失敗します。デプロイが成功する代わりに、Kubernetes APIサーバーは新しいIngressリソースをすべてブロックする特定の内部エラーをスローします。以下のようなエラーです。
Error from server (InternalError): Internal error occurred: failed calling webhook "validate.nginx.ingress.kubernetes.io": service "ingress-nginx-controller-admission" not found
このエラーは通常、NGINX Ingress Controllerをアンインストールまたはアップグレードしようとした後に発生します。存在しないサービスを参照しているため、インフラの更新を停止させてしまう非常に厄介なエラーです。
APIサーバーに潜む幽霊アドミッションコントローラーは、クラスターのゲートキーパーとして機能します。オブジェクトが etcd データベースに保存される前に、これらのコントローラーがリクエストを審査します。NGINXは ValidatingWebhookConfiguration を使用して、IngressのYAMLにコントローラーを壊すような構文エラーがないか確認します。
この障害は、NGINXのPodやサービスを削除したものの、グローバルなWebhook設定が残っている場合に発生します。デフォルトの failurePolicy が Fail に設定されているため、APIサーバーはバリデーターから「許可」を得られない限り、いかなるIngressの変更も拒否します。無効な設定がクラスターに入るのを防ぐために、あえて「失敗(拒否)」を選択するのです。
解決策1:孤立したWebhookの削除NGINX Ingressをアンインストールした場合や、別のコントローラーに移行する場合は、古い設定を削除する必要があります。これは、ユーザーの90%に当てはまる最も一般的な修正方法です。
1. 原因の特定次のコマンドを実行して、現在クラスター内でアクティブなWebhookを確認します。
kubectl get validatingwebhookconfigurations
ingress-nginx-admission という名前のエントリを探します。古いHelmチャートでは、単に ingress-nginx という名前になっていることもあります。
2. 設定の削除グローバルオブジェクトを削除します。これは名前空間(namespace)に依存しないため、どこからでも実行できます。
kubectl delete validatingwebhookconfigurations ingress-nginx-admission
削除されると、APIサーバーは存在しないアドミッションサービスへの呼び出しを停止します。 kubectl apply コマンドはすぐに動作するはずです。
解決策2:破損したインストールの修復NGINXを削除するつもりはなかったのに、Helmのアップグレードが失敗したという場合もあります。IngressのPodは動作しているのにアドミッションサービスが見当たらない場合は、接続を復元する必要があります。
1. サービスの確認ingress-nginx 名前空間にアドミッションサービスが存在するか確認します。
kubectl get svc -n ingress-nginx
2. Helmの強制更新サービスが存在しない場合は、Helmを実行して欠落しているコンポーネントを再作成します。Webhookフラグを明示的に設定するために、次のコマンドを使用します。
helm upgrade --install ingress-nginx ingress-nginx/ingress-nginx \n --namespace ingress-nginx \n --set controller.admissionWebhooks.enabled=true
このコマンドにより、Webhookの設定が実際のサービスの状態と同期され、「サービスが見つからない」ことによる切断が修正されます。
解決策3:緊急時のバイパス午前2時にクリティカルな修正をプッシュする必要があるのに、アドミッションサービスがダウンしている理由がわからないとしましょう。そのような場合は、一時的にWebhookの失敗を無視するようにKubernetesに指示できます。
設定を編集用に開きます。
kubectl edit validatingwebhookconfigurations ingress-nginx-admission
failurePolicy を探し、 Fail から Ignore に変更します。
webhooks:\n- name: validate.nginx.ingress.kubernetes.io\n failurePolicy: Ignore\n # ...
保存後、APIサーバーは引き続きWebhookの呼び出しを試みますが、呼び出しが失敗してもバリデーションをスキップし、リソースの作成を許可します。
検証と予防テスト用のIngressまたは元のデプロイを適用して、修正を確認します。コマンドが遅延なく configured または unchanged を返せば、ブロックは解消されています。今後この問題を避けるために、次の2つのルールを守ってください。
- 名前空間を手動で削除しない: 常に
helm uninstallを使用してください。手動で削除すると、WebhookやCRDのようなグローバルリソースが削除されずに残ることがよくあります。- Webhookのレイテンシを監視する: Prometheusを使用してadmissions_webhook_admission_duration_secondsを追跡してください。急激なスパイクは、アドミッションコントローラーが実際に失敗する前に負荷がかかっているサインです。

