6
votes

Nginx Ingress Controller - Échec de l'appel du Webhook

J'ai configuré un cluster k8s à l'aide de kubeadm (v1.18) sur une machine virtuelle Ubuntu. Maintenant, je dois ajouter un contrôleur d'entrée. J'ai opté pour nginx (mais je suis ouvert à d'autres solutions). Je l'ai installé conformément à la documentation , section "bare-metal":

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-0.31.1/deploy/static/provider/baremetal/deploy.yaml

L'installation me semble correcte:

kubectl get all -n ingress-nginx

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: my-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - http:
      paths:
      - path: /someroute/fittingmyneeds
        pathType: Prefix
        backend:
          serviceName: some-service
          servicePort: 5000

Cependant, lorsque j'essaie d'appliquer une entrée personnalisée, j'obtiens l'erreur suivante:

Error from server (InternalError): error when creating "yaml/xxx/xxx-ingress.yaml": Internal error occurred: failed calling webhook "validate.nginx.ingress.kubernetes.io": Post https://ingress-nginx-controller-admission.ingress-nginx.svc:443/extensions/v1beta1/ingresses?timeout=30s: Temporary Redirect

Une idée de ce qui ne va pas?

Je soupçonnais DNS, mais d'autres services NodePort fonctionnent comme prévu et DNS fonctionne dans le cluster.

La seule chose que je peux voir est que je n'ai pas de backend http par défaut qui est mentionné dans la documentation ici . Cependant, cela semble normal dans mon cas, selon ce fil .

Enfin, j'ai également essayé l' installation avec les manifestes (après avoir supprimé l'espace de noms ingress-nginx de l'installation précédente) et l' installation via le graphique Helm . Cela a le même résultat.

Je suis à peu près un débutant sur les k8 et c'est mon groupe de jeux. Je suis donc également ouvert aux solutions alternatives, tant que je n'ai pas besoin de configurer tout le cluster à partir de zéro.

Mise à jour: avec "application d'une entrée personnalisée", je veux dire: kubectl apply -f <myIngress.yaml>

Contenu de myIngress.yaml

NAME                                            READY   STATUS      RESTARTS   AGE
pod/ingress-nginx-admission-create-b8smg        0/1     Completed   0          8m21s
pod/ingress-nginx-admission-patch-6nbjb         0/1     Completed   1          8m21s
pod/ingress-nginx-controller-78f6c57f64-m89n8   1/1     Running     0          8m31s

NAME                                         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
service/ingress-nginx-controller             NodePort    10.107.152.204   <none>        80:32367/TCP,443:31480/TCP   8m31s
service/ingress-nginx-controller-admission   ClusterIP   10.110.191.169   <none>        443/TCP                      8m31s

NAME                                       READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/ingress-nginx-controller   1/1     1            1           8m31s

NAME                                                  DESIRED   CURRENT   READY   AGE
replicaset.apps/ingress-nginx-controller-78f6c57f64   1         1         1       8m31s

NAME                                       COMPLETIONS   DURATION   AGE
job.batch/ingress-nginx-admission-create   1/1           2s         8m31s
job.batch/ingress-nginx-admission-patch    1/1           3s         8m31s


3 commentaires

Que voulez-vous dire when trying to apply a custom Ingress ? Quelle est exactement votre Ingress personnalisée?


@OhHiMark: Je veux dire `kubectl apply -f <myIngress.yaml>. J'ai ajouté les informations dans le message d'origine.


Il semble que votre Ingress.yaml soit mal configuré. Je vois que vous essayez d'utiliser l'annotation de réécriture, mais aucun groupe de capture n'est défini. Ici , vous trouverez un exemple expliqué comment utiliser cette annotation. Jetez un œil et faites-moi savoir si cela vous aide.


4 Réponses :


3
votes

Enfin, j'ai réussi à exécuter correctement Ingress Nginx en changeant le mode d'installation. Je ne comprends toujours pas pourquoi l'installation précédente n'a pas fonctionné, mais je vais néanmoins partager la solution avec quelques informations supplémentaires sur le problème d'origine.

Solution

Désinstaller ingress nginx: supprimez l'espace de noms ingress-nginx. Cela ne supprime pas la configuration de validation du webhook - supprimez celle-ci manuellement. Ensuite, installez MetalLB et réinstallez ingress nginx. J'ai maintenant utilisé la version du repo stable Helm. Maintenant, tout fonctionne comme prévu. Merci à Long sur la chaîne Slack de Kubernetes!

Quelques informations supplémentaires sur le problème d'origine

Les yamls fournis par le guide d'installation contiennent un ValidatingWebHookConfiguration:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    helm.sh/chart: ingress-nginx-2.0.3
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 0.32.0
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: controller
  name: ingress-nginx-controller
  namespace: ingress-nginx
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: ingress-nginx
      app.kubernetes.io/instance: ingress-nginx
      app.kubernetes.io/component: controller
  revisionHistoryLimit: 10
  minReadySeconds: 0
  template:
    metadata:
      labels:
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/instance: ingress-nginx
        app.kubernetes.io/component: controller
    spec:
      dnsPolicy: ClusterFirst
      containers:
        - name: controller
          image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.32.0
          imagePullPolicy: IfNotPresent
          lifecycle:
            preStop:
              exec:
                command:
                  - /wait-shutdown
          args:
            - /nginx-ingress-controller
            - --election-id=ingress-controller-leader
            - --ingress-class=nginx
            - --configmap=ingress-nginx/ingress-nginx-controller
            - --validating-webhook=:8443
            - --validating-webhook-certificate=/usr/local/certificates/cert
            - --validating-webhook-key=/usr/local/certificates/key
          securityContext:
            capabilities:
              drop:
                - ALL
              add:
                - NET_BIND_SERVICE
            runAsUser: 101
            allowPrivilegeEscalation: true
          env:
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
          livenessProbe:
            httpGet:
              path: /healthz
              port: 10254
              scheme: HTTP
            initialDelaySeconds: 10
            periodSeconds: 10
            timeoutSeconds: 1
            successThreshold: 1
            failureThreshold: 3
          readinessProbe:
            httpGet:
              path: /healthz
              port: 10254
              scheme: HTTP
            initialDelaySeconds: 10
            periodSeconds: 10
            timeoutSeconds: 1
            successThreshold: 1
            failureThreshold: 3
          ports:
            - name: http
              containerPort: 80
              protocol: TCP
            - name: https
              containerPort: 443
              protocol: TCP
            - name: webhook
              containerPort: 8443
              protocol: TCP
          volumeMounts:
            - name: webhook-cert
              mountPath: /usr/local/certificates/
              readOnly: true
          resources:
            requests:
              cpu: 100m
              memory: 90Mi
      serviceAccountName: ingress-nginx
      terminationGracePeriodSeconds: 300
      volumes:
        - name: webhook-cert
          secret:
            secretName: ingress-nginx-admission

La validation est effectuée chaque fois que je crée ou mets à jour une entrée (le contenu de mon ingress.yaml n'a pas d'importance). La validation a échoué, car lors de l'appel du service, la réponse est une redirection temporaire. Je ne sais pas pourquoi. Le service correspondant est:

apiVersion: v1
kind: Service
metadata:
  labels:
    helm.sh/chart: ingress-nginx-2.0.3
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 0.32.0
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: controller
  name: ingress-nginx-controller-admission
  namespace: ingress-nginx
spec:
  type: ClusterIP
  ports:
    - name: https-webhook
      port: 443
      targetPort: webhook
  selector:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/component: controller

Le pod correspondant au sélecteur provient de ce déploiement:

apiVersion: admissionregistration.k8s.io/v1beta1
kind: ValidatingWebhookConfiguration
metadata:
  labels:
    helm.sh/chart: ingress-nginx-2.0.3
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 0.32.0
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: admission-webhook
  name: ingress-nginx-admission
  namespace: ingress-nginx
webhooks:
  - name: validate.nginx.ingress.kubernetes.io
    rules:
      - apiGroups:
          - extensions
          - networking.k8s.io
        apiVersions:
          - v1beta1
        operations:
          - CREATE
          - UPDATE
        resources:
          - ingresses
    failurePolicy: Fail
    clientConfig:
      service:
        namespace: ingress-nginx
        name: ingress-nginx-controller-admission
        path: /extensions/v1beta1/ingresses

Quelque chose dans cette chaîne de validation ne va pas. Ce serait intéressant de savoir, quoi et pourquoi, mais je peux continuer à travailler avec ma solution MetalLB. Notez que cette solution ne contient pas du tout de webhook de validation.


0 commentaires

3
votes

J'ai résolu ce problème. Le problème était que vous utilisiez Kubernetes version 1.18, mais la ValidatingWebhookConfiguration dans l'entrée actuelle-Nginx utilise l'API la plus ancienne; voir la doc: https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#prerequisites

Assurez-vous que le cluster Kubernetes est au moins aussi récent que la v1.16 (pour utiliser admissionregistration.k8s.io/v1) ou la v1.9 (pour utiliser admissionregistration.k8s.io/v1beta1).

Et en yaml actuel:

apiVersions:
          - v1beta1
          - v1

et dans les règles:

apiVersion: admissionregistration.k8s.io/v1

Vous devez donc le changer sur la v1:

apiVersions:
          - v1beta1

et ajoutez la règle -v1:

 # Source: ingress-nginx/templates/admission-webhooks/validating-webhook.yaml
    # before changing this value, check the required kubernetes version
    # https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#prerequisites
apiVersion: admissionregistration.k8s.io/v1beta1

Après l'avoir modifié et redéployé, votre service d'entrée personnalisé se déploiera avec succès


0 commentaires

13
votes

Une autre option dont vous disposez est de supprimer entièrement le Webhook de validation:

kubectl delete -A ValidatingWebhookConfiguration ingress-nginx-admission

J'ai trouvé que je devais le faire sur un autre problème , mais la solution de contournement / solution fonctionne également ici.

Ce n'est pas la meilleure réponse; la meilleure réponse est de comprendre pourquoi cela ne fonctionne pas. Mais à un moment donné, vous vivez avec des solutions de contournement.

baremetal sur Docker pour Mac, j'ai donc utilisé le cloud plutôt que la version baremetal :

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.34.1/deploy/static/provider/cloud/deploy.yaml


2 commentaires

kubectl delete -A ValidatingWebhookConfiguration ingress-nginx-admission résolu pour moi sur minikube 1.12 avec k8s 1.18.


@Patrick Gardella, cela semble être la solution pratique pour de nombreuses personnes, comme le démontrent les nombreux votes positifs sur votre article associé stackoverflow.com/a/62044090/1549918 . Je ne suis même pas sûr que ce soit seulement une solution de contournement.



1
votes

Dans mon cas, j'avais mélangé les installations. J'ai résolu le problème en exécutant les étapes suivantes:

$ `kubectl delete validatingwebhookconfigurations [configuration-name]`

J'ai parcouru la liste des configurations reçues des étapes ci-dessus et supprimé la configuration en utilisant

$ kubectl get validatingwebhookconfigurations 


0 commentaires