Migrieren Sie NGINX aus dem "stabilen" Helm-Diagramm-Repository mit ChartCenter

 

UPDATE: 1. Mai 2021 – Das zentrale Repository ChartCenter einschließlich aller Funktionen wurde eingestellt. Weitere Informationen zur Einstellung der Center finden Sie im Blog-Post zu veralteten Centern

 

In den letzten vier Jahren hat jeder, der den Ingress NGINX Controller für Kubernetes einsetzen wollte, dessen offizielles Helm-Diagramm nginx-ingress im stabilen Repository gefunden, das vom Helm-Projekt gepflegt wird.

Diese Zeiten sind vorbei. Und das nicht nur für NGINX, den beliebtesten Ingress Controller, der als Reverse Proxy und Load Balancer eingesetzt wird, sondern für alle Open-Source-K8s-Apps.

Mit der Einführung von Helm 3 stellt das Helm-Projekt die stabilen Repositories ein. Ab November 2019 werden keine Diagramme mehr als Neuzugänge zu den stabilen Repositories angenommen, da Diagrammbesitzer zu individuellen Repositories übergehen. Diese Übergangszeit ist nun vorbei – stabile Repositories wurden vom Helm Hub ausgelistet und sind ab kommenden November offiziell veraltet.

Was bedeutet dies für diejenigen, die NGINX-Deployments installieren und warten? Zunächst unterhält das NGINX-Projekt jetzt ein neues ingress-nginx -Helm-Diagramm in den GitHub-Repositories für Kubernetes. Jeder, der ein Deployment von NGINX Ingress Controller installiert oder aktualisiert, sollte nun das Diagramm aus diesem Repository verwenden.

Auch wenn das neue Diagramm derzeit die gleiche Version der NGINX-App einsetzt, ist es nicht identisch mit dem Diagramm im stabilen Repository. Dies erfordert einige Anpassungen, wenn eine bestehende NGINX-Installation mit dem neuen Diagramm aktualisiert wird.

Lassen Sie uns einen Blick darauf werfen, was damit verbunden ist, und wie JFrog ChartCenter Ihnen bei der Umstellung helfen kann.

Ein zentrales Helm-Repository

Der stabile Satz von Helm-Diagrammen hat bedeutet, dass offizielle Diagramme für viele beliebte Kubernetes-Apps immer in einem zentralen Repository zu finden waren. Sie haben einfach das stabile Repository dem Helm-Client hinzugefügt:

$ helm repo add stable https://kubernetes-charts.storage.googleapis.com/

 

Von diesem einzelnen stabilen Repository konnten Sie getrost nginx-ingress unter Verwendung des neuesten, vom Autor genehmigten Helm-Diagramms einsetzen.

Da das stabile Repository fast veraltet ist, ist es nicht mehr als zentrale Quelle für bekanntermaßen gute Helm-Diagramme verfügbar. NGINX weist Sie nun an, ingress-nginx individuell dem Helm-Client hinzuzufügen:

$ helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx

 

Ohne ein zentrales Repository müssen Sie jedes Mal ein helm repo add ausführen, wenn Sie eine andere K8s-App warten müssen.

Gibt es eine bessere Möglichkeit?

Ingress NGINX Controller in ChartCenter

JFrog ChartCenter ist ein kostenloses zentrales Helm-Diagramm-Repository , das entwickelt wurde, um der Helm-Community zu helfen, unveränderliche, sichere und zuverlässige Diagramme zu finden und sich einer einzigen Quelle zu bedienen, um alle Diagramme von einem Ort aus abzubilden. Es kann als ein zentrales Helm-Repository vom Helm-Client genutzt werden, so dass Sie nicht viele öffentliche Helm-Repositories hinzufügen müssen, sondern stattdessen nur eines verwenden.

Über ChartCenter sind über 30.000 versionierte Helm-Diagramme verfügbar, und viele beliebte App-Diagramme – einschließlich für den NGINX Ingress Controller – werden auf der Startseite angezeigt, so dass Sie bequem auffindbar sind.

Über die Suche von ChartCenter können wir das stabile Helm-Diagramm nginx-ingress finden:

Wir können auch das aktuelle Diagramm ingress-nginx in ChartCenter ausfindig machen:

ChartCenter verwenden

Wenn wir ChartCenter zu unserem Helm-Client hinzugefügt haben, können wir es als zentrales Repository für alle unsere Helm-Diagramme verwenden, einschließlich der beiden NGINX-Repositories, die wir in unserer Demonstration verwenden werden.

Schritt 1: Fügen Sie ChartCenter als Ihr Helm-Repository hinzu

Stellen Sie Ihren Helm-Client so ein, dass er das ChartCenter-Repository als zentralen Speicherort verwendet, von dem Sie Diagramme abrufen:

$ helm repo add center https://repo.chartcenter.io
$ helm repo update

 

Schritt 2: ChartCenter als Repository verwenden

Prüfen wir nun auf die nginx-ingress- und ingress-nginx- Diagramme vom Helm-Client:

$ helm search repo center/stable/nginx-ingress
NAME                       	CHART VERSION	APP VERSION	DESCRIPTION
center/stable/nginx-ingress	1.41.2       	v0.34.1    	Ein nginx Ingress-Controller, der ConfigMap verwendet...
 
$ helm search repo center/kubernetes-ingress-nginx/ingress-nginx
NAME                                         	CHART VERSION	APP VERSION	DESCRIPTION
center/kubernetes-ingress-nginx/ingress-nginx	2.11.2       	0.34.1     	Ingress-Controller für Kubernetes unter Verwendung von NGINX und...

 

Schön, wir sehen die gleiche Version der Diagramme wie im ChartCenter UI.

Und hier können Sie sehen, wie viel einfacher es ist, ein zentrales Helm-Repository für Diagramme aus verschiedenen Helm-Repositories zu verwenden.

nginx-ingress Helm-Diagramm installieren

Um das Upgrade zu testen, müssen wir zunächst ein nginx-ingress- Diagramm installieren. Ich werde ein kleines Shell-Skript nginx-ingress.sh verwenden, das eine Datei mit Überschreibungswerten erstellt und dann nginx-ingress installiert.

Das nginx-ingress.sh hat einen Diagrammnamen und eine Version, sowie eine statische IP für den Load Balancer:

#!/bin/bash
 
CHART_NAME="center/stable/nginx-ingress"
CHART_VERSION="1.41.2"
RELEASE=nginx-ingress
NAMESPACE=nginx-ingress
VALUES_FILE=nginx-ingress.yaml
LB_STATIC_IP=35.197.192.35
 
generateValues() {
   cat << EOF > "${VALUES_FILE}"
# Werte für nginx-ingress überschreiben
 
controller:
 
 ## Host-Ports 80 und 443 verwenden
 daemonset:
   useHostPort: true
 
 kind: DaemonSet
 
 service:
 
   ## Statische IP für LoadBalancer einstellen
   loadBalancerIP: ${LB_STATIC_IP}
 
   externalTrafficPolicy: Local
 
 stats:
   enabled: true
 
 metrics:
   enabled: true
EOF
}
 
generateValues
kubectl create ns nginx-ingress || true
echo
helm upgrade --install ${RELEASE} -n ${NAMESPACE} ${CHART_NAME} --version ${CHART_VERSION} -f ${VALUES_FILE}
echo
kubectl -n ${NAMESPACE} get all

 

Lassen Sie uns nginx-ingress.sh ausführen, um nginx-ingress zu installieren:

$ ./nginx-ingress.sh
namespace/nginx-ingress erstellt
 
Release "nginx-ingress" existiert nicht. Es wird jetzt installiert.
NAME: nginx-ingress
LAST DEPLOYED: Mon Aug 10 17:27:13 2020
NAMESPACE: nginx-ingress
STATUS: deployed
REVISION: 1
TEST-SUITE: None
NOTES:
Der nginx-ingress-Controller wurde installiert.
Es kann ein paar Minuten dauern, bis die LoadBalancer-IP verfügbar ist.
Sie können den Status beobachten, indem Sie "kubectl --namespace nginx-ingress get services -o wide -w nginx-ingress-controller" ausführen
 
Ein Beispiel-Ingress, bei dem der Controller verwendet wird:
 
  apiVersion: extensions/v1beta1
  kind: Ingress
  metadata:
    annotations:
      kubernetes.io/ingress.class: nginx
    name: example
    namespace: foo
  spec:
    rules:
      - host: www.example.com
        http:
          paths:
            - backend:
                serviceName: exampleService
                servicePort: 80
              path: /
    # Dieser Abschnitt ist nur erforderlich, wenn TLS für den Ingress aktiviert werden soll
    tls:
        - hosts:
            - www.example.com
          secretName: example-tls
 
Wenn TLS für den Ingress aktiviert ist, muss auch ein Secret angegeben werden, das das Zertifikat und den Schlüssel enthält:
 
  apiVersion: v1
  kind: Secret
  metadata:
    name: example-tls
    namespace: foo
  data:
    tls.crt: 
    tls.key: 
  type: kubernetes.io/tls
 
NAME                                                 READY   STATUS              RESTARTS   AGE
pod/nginx-ingress-controller-rrsl9                   0/1     ContainerCreating   0          1s
pod/nginx-ingress-default-backend-5b967cf596-wrrfl   0/1     ContainerCreating   0          1s
 
NAME                                       TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
service/nginx-ingress-controller           LoadBalancer   10.242.2.213         80:30643/TCP,443:31622/TCP   2s
service/nginx-ingress-controller-metrics   ClusterIP      10.242.10.112           9913/TCP                     2s
service/nginx-ingress-default-backend      ClusterIP      10.242.11.172           80/TCP                       2s
 
NAME                                      DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
daemonset.apps/nginx-ingress-controller   1         1         0       1            0                     3s
 
NAME                                            READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nginx-ingress-default-backend   0/1     1            0           2s
 
NAME                                                       DESIRED   CURRENT   READY   AGE
replicaset.apps/nginx-ingress-default-backend-5b967cf596   1         1         0       2s

 

Und lassen Sie uns auf Pods und Service prüfen:

$ kubectl -n nginx-ingress get pods
NAME                                             READY   STATUS    RESTARTS   AGE
nginx-ingress-controller-rrsl9                   1/1     Running   0          78s
nginx-ingress-default-backend-5b967cf596-wrrfl   1/1     Running   0          78s
 
$ kubectl -n nginx-ingress get svc
NAME                               TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)                      AGE
nginx-ingress-controller           LoadBalancer   10.242.2.213    35.197.192.35   80:30643/TCP,443:31622/TCP   89s
nginx-ingress-controller-metrics   ClusterIP      10.242.10.112             9913/TCP                     89s
nginx-ingress-default-backend      ClusterIP      10.242.11.172             80/TCP                       89s

 

Schön, der NGINX Ingress Controller-Pod läuft, und sein Dienst hat vom Load Balancer eine externe IP zugewiesen bekommen.

Ok, wir haben das nginx-ingress -Diagramm erfolgreich installiert, machen wir mit dem Upgrade weiter.

Upgrade auf ingress-nginx Helm-Diagramm

Versuchen wir, den NGINX Ingress Controller mit dem aktuelleren Diagramm zu aktualisieren.

Wir verwenden wieder ein Shell-Skript, diesmal mit dem anderen Namen ingress-nginx.sh.
Das ingress-nginx.sh hat einen anderen Diagrammnamen und eine andere Version, aber den gleichen Helm-Versionsnamen und die gleiche statische IP für den Load Balancer.

#!/bin/bash
 
CHART_NAME="center/kubernetes-ingress-nginx/ingress-nginx"
CHART_VERSION="2.11.1"
RELEASE=nginx-ingress
NAMESPACE=nginx-ingress
VALUES_FILE=ingress-nginx.yaml
LB_STATIC_IP=35.197.192.35
 
generateValues() {
   cat << EOF > "${VALUES_FILE}"
# Werte für ingress-nginx überschreiben
 
controller:
 
 ## Host-Ports 80 und 443 verwenden
 hostPort:
   enabled: true
 
 kind: DaemonSet
 
 service:
 
   ## Statische IP für LoadBalancer einstellen
   loadBalancerIP: ${LB_STATIC_IP}
 
   externalTrafficPolicy: Local
 
 stats:
   enabled: true
 
 metrics:
   enabled: true
 
 admissionWebhooks:
   enabled: false
 
defaultBackend:
 enabled: true
EOF
}
 
generateValues
echo
helm upgrade --install ${RELEASE} -n ${NAMESPACE} ${CHART_NAME} --version ${CHART_VERSION} -f ${VALUES_FILE}
echo
kubectl -n ${NAMESPACE} get all

 

Das ingress-nginx.sh weist einige Unterschiede zu nginx-ingress.sh auf:

controller:
 
 ## Host-Ports 80 und 443 verwenden
 daemonset:
   useHostPort: true

 

da einige Werte geändert wurden in:

controller:
 
 ## Host-Ports 80 und 443 verwenden
 hostPort:
   enabled: true
 
 kind: DaemonSet

 

und einige zusätzliche wurden hinzugefügt:

admissionWebhooks:
   enabled: false
 
defaultBackend:
  enabled: true

 

In diesem Upgrade-Szenario verwenden wir admissionWebhooks nicht, also deaktivieren wir es und aktivieren defaultBackend , da es in nginx-ingress -Diagramm standardmäßig aktiviert ist. Und natürlich können Sie die Werte Ihren Bedürfnissen entsprechend anpassen.

Lassen Sie uns ingress-nginx.sh ausführen, um auf nginx-ingress zu aktualisieren:

Release "nginx-ingress" wurde aktualisiert. Viel Spaß!
NAME: nginx-ingress
LAST DEPLOYED: Mon Aug 10 18:00:31 2020
NAMESPACE: nginx-ingress
STATUS: deployed
REVISION: 2
TEST-SUITE: None
NOTES:
Der ingress-nginx-Controller wurde installiert.
Es kann ein paar Minuten dauern, bis die LoadBalancer-IP verfügbar ist.
Sie können den Status prüfen, indem Sie "kubectl --namespace nginx-ingress get services -o wide -w nginx-ingress-ingress-nginx-controller" ausführen
 
Ein Beispiel-Ingress, bei dem der Controller verwendet wird:
 
  apiVersion: networking.k8s.io/v1beta1
  kind: Ingress
  metadata:
    annotations:
      kubernetes.io/ingress.class: nginx
    name: example
    namespace: foo
  spec:
    rules:
      - host: www.example.com
        http:
          paths:
            - backend:
                serviceName: exampleService
                servicePort: 80
              path: /
    # Dieser Abschnitt ist nur erforderlich, wenn TLS für den Ingress aktiviert werden soll
    tls:
        - hosts:
            - www.example.com
          secretName: example-tls
 
Wenn TLS für den Ingress aktiviert ist, muss auch ein Secret angegeben werden, das das Zertifikat und den Schlüssel enthält:
 
  apiVersion: v1
  kind: Secret
  metadata:
    name: example-tls
    namespace: foo
  data:
    tls.crt: 
    tls.key: 
  type: kubernetes.io/tls
 
NAME                                                              READY   STATUS        RESTARTS   AGE
pod/nginx-ingress-controller-rrsl9                                1/1     Terminating   0          33m
pod/nginx-ingress-default-backend-5b967cf596-wrrfl                0/1     Terminating   0          33m
pod/nginx-ingress-ingress-nginx-controller-f9ztr                  0/1     Pending       0          5s
pod/nginx-ingress-ingress-nginx-defaultbackend-845f7cfd46-56grw   1/1     Running       0          5s
 
NAME                                                     TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)                      AGE
service/nginx-ingress-controller                         LoadBalancer   10.242.2.213    35.197.192.35   80:30643/TCP,443:31622/TCP   33m
service/nginx-ingress-ingress-nginx-controller           LoadBalancer   10.242.13.184          80:30601/TCP,443:30644/TCP   6s
service/nginx-ingress-ingress-nginx-controller-metrics   ClusterIP      10.242.12.190             9913/TCP                     6s
service/nginx-ingress-ingress-nginx-defaultbackend       ClusterIP      10.242.11.112             80/TCP                       5s
 
NAME                                                    DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
daemonset.apps/nginx-ingress-ingress-nginx-controller   1         1         0       1            0                     6s
 
NAME                                                         READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nginx-ingress-ingress-nginx-defaultbackend   1/1     1            1           6s
 
NAME                                                                    DESIRED   CURRENT   READY   AGE
replicaset.apps/nginx-ingress-ingress-nginx-defaultbackend-845f7cfd46   1         1         1       6s

 

Überprüfen wir nun die Pods und den Dienst:

$ kubectl -n nginx-ingress get pods
NAME                                                          READY   STATUS    RESTARTS   AGE
nginx-ingress-ingress-nginx-controller-f9ztr                  0/1     Running   0          34s
nginx-ingress-ingress-nginx-defaultbackend-845f7cfd46-56grw   1/1     Running   0          34s

$ kubectl -n nginx-ingress get svc
NAME                                             TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)                      AGE
nginx-ingress-controller                         LoadBalancer   10.242.2.213    35.197.192.35   80:30643/TCP,443:31622/TCP   34m
nginx-ingress-ingress-nginx-controller           LoadBalancer   10.242.13.184          80:30601/TCP,443:30644/TCP   40s
nginx-ingress-ingress-nginx-controller-metrics   ClusterIP      10.242.12.190             9913/TCP                     40s
nginx-ingress-ingress-nginx-defaultbackend       ClusterIP      10.242.11.112             80/TCP                       39s

 

Sie sehen dort, dass die Pods aktualisiert werden und wir sehen zwei Dienste, einen alten und einen neuen.

Lassen Sie uns kubectl -n nginx-ingress get svc wieder:

$ kubectl -n nginx-ingress get svc
NAME                                             TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)                      AGE
nginx-ingress-ingress-nginx-controller           LoadBalancer   10.242.13.184   35.197.192.35   80:30601/TCP,443:30644/TCP   3m26s
nginx-ingress-ingress-nginx-controller-metrics   ClusterIP      10.242.12.190             9913/TCP                     3m26s
nginx-ingress-ingress-nginx-defaultbackend       ClusterIP      10.242.11.112             80/TCP                       3m25s

 

Voila, der alte Dienst wurde gelöscht und der neue erstellt, indem einfach helm upgrade ausgeführt und kein anderer Zaubertrick mit kubectl verwendet wird. Natürlich ist beim Austausch des Dienstes eine gewisse Ausfallzeit zu erwarten, da der neue Load Balancer für den neuen Dienst erstellt werden muss.

Danke und viel Glück

Ziemlich einfach, oder? Ein großes Dankeschön an die Maintainer des NGINX-Ingress-Controller-Diagramms für ein so nahtloses Upgrade zwischen zwei verschiedenen Diagrammen!

Mit etwas Glück wird der Übergang zu individuellen Diagramm-Repositories für Ihre anderen K8s-Apps ebenso reibungslos verlaufen. Die Verwendung von ChartCenter als Ihr zentrales Helm-Diagramm-Repository kann dabei helfen, diese Updates in Gang zu bringen.

Fröhliches Ingressen