Bei der Bereitstellung von Kubernetes in einer Unternehmensumgebung oder hinter einer Firewall besteht häufig die Notwendigkeit, einen Proxy-Server für den Zugriff auf externe Ressourcen zu konfigurieren. Dies ist entscheidend für das Herunterladen von Container-Images, das Aktualisieren von Paketen und die Interaktion mit externen APIs. In diesem Leitfaden werden wir alle Ebenen der Proxy-Konfiguration in Kubernetes durchgehen – von der Konfiguration der Knoten bis hin zu einzelnen Pods.
Warum ein Proxy in Kubernetes-Clustern benötigt wird
Kubernetes-Cluster in Unternehmensumgebungen arbeiten häufig in isolierten Netzwerken mit eingeschränktem Internetzugang. Ein Proxy-Server erfüllt mehrere kritische Aufgaben:
- Herunterladen von Container-Images – Docker Hub, Google Container Registry und private Registries erfordern externen Zugriff
- Aktualisierung von Paketen – Installation von Abhängigkeiten über apt, yum, pip innerhalb von Containern
- Zugriff auf externe APIs – Integration mit Cloud-Diensten, Monitoring, Logging
- Sicherheit – Traffic-Kontrolle, Domain-Filterung, Anfrage-Logging
- Caching – Beschleunigung wiederholter Anfragen an dieselben Ressourcen
Ohne die richtige Proxy-Konfiguration werden Sie auf Fehler wie "image pull failed", "connection timeout" oder "network unreachable" stoßen, wenn Sie versuchen, Anwendungen bereitzustellen. Dies ist besonders kritisch für automatisierte CI/CD-Pipelines, bei denen jede Sekunde Ausfallzeit Geld kostet.
Wichtig: Für Unternehmenscluster wird empfohlen, Datacenter-Proxys mit hoher Bandbreite und stabiler Verbindung zu verwenden, da die Funktionsfähigkeit der gesamten Infrastruktur davon abhängt.
Ebenen der Proxy-Konfiguration in Kubernetes
Kubernetes hat eine mehrschichtige Architektur, und der Proxy muss auf jeder Ebene je nach Aufgabenstellung konfiguriert werden:
| Ebene | Was konfiguriert wird | Wozu es benötigt wird |
|---|---|---|
| Betriebssystem | Systemumgebungsvariablen | Zugriff auf Utilities (curl, wget, apt) |
| Container Runtime (Docker/containerd) | Konfiguration des Daemons | Herunterladen von Container-Images |
| kubelet | Startparameter für kubelet | Interaktion mit dem API-Server |
| Pods | Umgebungsvariablen in Manifests | Zugriff von Anwendungen auf externe APIs |
| kubectl | Umgebungsvariablen des Clients | Verwaltung des Clusters über Proxy |
Jede Ebene erfordert eine separate Konfiguration, und das Auslassen einer von ihnen kann zu Problemen führen. Wenn Sie beispielsweise den Proxy nur für Docker konfigurieren, aber nicht für die Pods, werden die Images heruntergeladen, aber die Anwendungen innerhalb der Container können nicht auf externe APIs zugreifen.
Proxy-Konfiguration für Docker und containerd
Die Container-Runtime ist die erste Komponente, die konfiguriert werden muss, da sie für das Herunterladen von Container-Images aus externen Registries verantwortlich ist. Lassen Sie uns die Konfiguration für beide beliebten Runtimes betrachten.
Proxy-Konfiguration für Docker
Für Docker müssen Sie eine systemd-Drop-in-Datei erstellen, die Umgebungsvariablen zum Docker-Dienst hinzufügt:
# Erstellen Sie ein Verzeichnis für die Konfiguration
sudo mkdir -p /etc/systemd/system/docker.service.d
# Erstellen Sie eine Datei mit den Proxy-Einstellungen
sudo tee /etc/systemd/system/docker.service.d/http-proxy.conf <<EOF
[Service]
Environment="HTTP_PROXY=http://proxy.company.com:8080"
Environment="HTTPS_PROXY=http://proxy.company.com:8080"
Environment="NO_PROXY=localhost,127.0.0.1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,.cluster.local,.svc"
EOF
# Laden Sie die systemd-Konfiguration neu
sudo systemctl daemon-reload
# Starten Sie Docker neu
sudo systemctl restart docker
# Überprüfen Sie, ob die Einstellungen angewendet wurden
sudo systemctl show --property=Environment docker
Danach kann Docker Images über den Proxy-Server herunterladen. Sie können die Funktionalität mit folgendem Befehl überprüfen:
docker pull nginx:latest
Proxy-Konfiguration für containerd
Containerd wird in modernen Kubernetes-Clustern als primäre Container-Runtime verwendet. Die Proxy-Konfiguration für ihn unterscheidet sich etwas:
# Erstellen Sie ein Verzeichnis für die Konfiguration
sudo mkdir -p /etc/systemd/system/containerd.service.d
# Erstellen Sie eine Datei mit den Proxy-Einstellungen
sudo tee /etc/systemd/system/containerd.service.d/http-proxy.conf <<EOF
[Service]
Environment="HTTP_PROXY=http://proxy.company.com:8080"
Environment="HTTPS_PROXY=http://proxy.company.com:8080"
Environment="NO_PROXY=localhost,127.0.0.1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,.cluster.local,.svc"
EOF
# Laden Sie die Konfiguration neu
sudo systemctl daemon-reload
sudo systemctl restart containerd
# Überprüfen Sie den Status
sudo systemctl status containerd
Hinweis: Wenn Sie ein privates Container-Registry verwenden, fügen Sie dessen Domain zu NO_PROXY hinzu, um unnötige Verzögerungen und Probleme mit SSL-Zertifikaten zu vermeiden.
Proxy-Konfiguration für kubelet
Kubelet ist der Kubernetes-Agent, der auf jedem Knoten des Clusters läuft. Er benötigt ebenfalls Zugriff auf den API-Server und externe Ressourcen. Die Konfiguration hängt von der Installationsmethode von Kubernetes ab.
Für kubeadm-Cluster
Wenn Sie kubeadm verwenden, konfigurieren Sie den Proxy über systemd:
# Erstellen Sie ein Verzeichnis für die kubelet-Konfiguration
sudo mkdir -p /etc/systemd/system/kubelet.service.d
# Erstellen Sie eine Datei mit den Proxy-Einstellungen
sudo tee /etc/systemd/system/kubelet.service.d/http-proxy.conf <<EOF
[Service]
Environment="HTTP_PROXY=http://proxy.company.com:8080"
Environment="HTTPS_PROXY=http://proxy.company.com:8080"
Environment="NO_PROXY=localhost,127.0.0.1,10.96.0.0/12,10.244.0.0/16,.cluster.local,.svc"
EOF
# Starten Sie kubelet neu
sudo systemctl daemon-reload
sudo systemctl restart kubelet
Für verwaltete Kubernetes (EKS, GKE, AKS)
In verwalteten Kubernetes-Diensten wird die kubelet-Konfiguration normalerweise über Startparameter der Knoten oder User-Data-Skripte durchgeführt. Zum Beispiel für AWS EKS:
#!/bin/bash
# User-Data-Skript für EKS-Worker-Knoten
# Proxy-Konfiguration für das System
cat <<EOF >> /etc/environment
HTTP_PROXY=http://proxy.company.com:8080
HTTPS_PROXY=http://proxy.company.com:8080
NO_PROXY=localhost,127.0.0.1,169.254.169.254,.ec2.internal,.cluster.local
EOF
# Konfiguration für kubelet
mkdir -p /etc/systemd/system/kubelet.service.d
cat <<EOF > /etc/systemd/system/kubelet.service.d/http-proxy.conf
[Service]
Environment="HTTP_PROXY=http://proxy.company.com:8080"
Environment="HTTPS_PROXY=http://proxy.company.com:8080"
Environment="NO_PROXY=localhost,127.0.0.1,169.254.169.254,.ec2.internal,.cluster.local"
EOF
systemctl daemon-reload
systemctl restart kubelet
Beachten Sie die Hinzufügung von 169.254.169.254 zu NO_PROXY – dies ist die Adresse des Metadaten-Dienstes von AWS, der ohne Proxy zugänglich sein muss.
Proxy-Konfiguration auf Pod-Ebene
Selbst wenn Sie den Proxy für Docker und kubelet konfiguriert haben, verwenden Anwendungen innerhalb von Pods nicht automatisch den Proxy. Sie müssen die Umgebungsvariablen explizit in den Kubernetes-Manifests angeben.
Konfiguration über den Deployment-Manifest
Der einfachste Weg ist, die Umgebungsvariablen in die Containerspezifikation hinzuzufügen:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: app
image: my-company/my-app:latest
env:
- name: HTTP_PROXY
value: "http://proxy.company.com:8080"
- name: HTTPS_PROXY
value: "http://proxy.company.com:8080"
- name: NO_PROXY
value: "localhost,127.0.0.1,.cluster.local,.svc,10.0.0.0/8"
ports:
- containerPort: 8080
Verwendung von ConfigMap für zentrale Konfiguration
Um die Proxy-Einstellungen nicht in jedem Deployment zu duplizieren, erstellen Sie eine ConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
name: proxy-config
namespace: default
data:
HTTP_PROXY: "http://proxy.company.com:8080"
HTTPS_PROXY: "http://proxy.company.com:8080"
NO_PROXY: "localhost,127.0.0.1,.cluster.local,.svc,10.0.0.0/8"
Verwenden Sie dann diese ConfigMap im Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
template:
spec:
containers:
- name: app
image: my-company/my-app:latest
envFrom:
- configMapRef:
name: proxy-config
Dieser Ansatz vereinfacht das Management: Wenn die Proxy-Adresse geändert wird, genügt es, die ConfigMap zu aktualisieren, und nach dem Neustart der Pods werden die neuen Einstellungen automatisch angewendet.
Automatische Injektion über MutatingWebhook
Um Umgebungsvariablen für alle Pods automatisch hinzuzufügen, können Sie MutatingAdmissionWebhook verwenden. Dies ist ein fortgeschrittener Ansatz, der die Entwicklung eines eigenen Webhook-Dienstes erfordert, aber es ermöglicht eine zentrale Verwaltung der Einstellungen ohne Änderung der Anwendungsmanifeste.
Richtige Konfiguration von NO_PROXY
Die NO_PROXY-Variable definiert, welche Adressen und Domains den Proxy-Server umgehen sollen. Eine falsche Konfiguration von NO_PROXY ist die häufigste Ursache für Probleme in Kubernetes-Clustern.
Obligatorische Ausnahmen für Kubernetes
Die folgenden Adressen und Bereiche MÜSSEN IMMER in NO_PROXY enthalten sein:
| Adresse/Bereich | Zweck |
|---|---|
localhost, 127.0.0.1 |
Lokale Verbindungen |
.cluster.local |
Interner Cluster-DNS |
.svc |
Kubernetes-Dienste |
10.0.0.0/8 |
Pod-Netzwerk (abhängig von CNI) |
10.96.0.0/12 |
Service-Netzwerk (Standard) |
172.16.0.0/12 |
Private Docker-Netzwerke |
192.168.0.0/16 |
Private lokale Netzwerke |
Beispiel einer vollständigen NO_PROXY-Konfiguration
NO_PROXY=localhost,127.0.0.1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,10.96.0.0/12,.cluster.local,.svc,.default.svc,.default.svc.cluster.local,kubernetes.default.svc,kubernetes.default.svc.cluster.local
Achtung: Einige Anwendungen unterstützen keine CIDR-Notation in NO_PROXY. In solchen Fällen verwenden Sie Wildcards: 10.* anstelle von 10.0.0.0/8.
Konfiguration von kubectl für die Verwendung über Proxy
Wenn Sie einen Cluster von einem Arbeitsplatz aus verwalten, der hinter einem Proxy steht, konfigurieren Sie die Umgebungsvariablen für kubectl:
# Für Linux/macOS - fügen Sie zu ~/.bashrc oder ~/.zshrc hinzu
export HTTP_PROXY=http://proxy.company.com:8080
export HTTPS_PROXY=http://proxy.company.com:8080
export NO_PROXY=localhost,127.0.0.1,kubernetes.default.svc,.cluster.local
# Für Windows PowerShell
$env:HTTP_PROXY="http://proxy.company.com:8080"
$env:HTTPS_PROXY="http://proxy.company.com:8080"
$env:NO_PROXY="localhost,127.0.0.1,kubernetes.default.svc,.cluster.local"
Danach kann kubectl über den Proxy auf den API-Server des Clusters zugreifen. Überprüfen Sie die Funktionalität:
kubectl cluster-info
kubectl get nodes
Proxy-Konfiguration mit Authentifizierung
Wenn der Proxy-Server eine Authentifizierung erfordert, fügen Sie die Anmeldeinformationen in die URL ein:
export HTTP_PROXY=http://username:password@proxy.company.com:8080
export HTTPS_PROXY=http://username:password@proxy.company.com:8080
Sicherheit: Speichern Sie keine Passwörter im Klartext in Konfigurationsdateien. Verwenden Sie Umgebungsvariablen oder Kubernetes-Secrets zur Speicherung der Proxy-Anmeldeinformationen.
Diagnose und Lösung typischer Probleme
Selbst bei richtiger Konfiguration können Probleme auftreten. Lassen Sie uns die häufigsten Fehler und deren Lösungen betrachten.
Fehler "ImagePullBackOff" beim Herunterladen von Images
Symptome: Pods starten nicht, in den Ereignissen wird der Fehler "Failed to pull image" oder "connection timeout" angezeigt.
Diagnose:
# Überprüfen Sie die Ereignisse des Pods
kubectl describe pod <pod-name>
# Überprüfen Sie die Proxy-Einstellungen in Docker/containerd
sudo systemctl show --property=Environment docker
sudo systemctl show --property=Environment containerd
# Versuchen Sie, das Image manuell auf dem Knoten herunterzuladen
sudo docker pull nginx:latest
sudo crictl pull nginx:latest
Lösung: Stellen Sie sicher, dass der Proxy für die Container-Runtime konfiguriert ist und die Domain des Image-Registrys nicht in NO_PROXY enthalten ist.
Probleme mit der DNS-Auflösung innerhalb des Clusters
Symptome: Pods können sich nicht gegenseitig über DNS-Namen ansprechen (z.B. service-name.namespace.svc.cluster.local).
Diagnose:
# Überprüfen Sie DNS aus dem Pod
kubectl run -it --rm debug --image=busybox --restart=Never -- nslookup kubernetes.default
# Überprüfen Sie die Proxy-Variablen im Pod
kubectl exec -it <pod-name> -- env | grep PROXY
Lösung: Fügen Sie .cluster.local und .svc zu NO_PROXY hinzu.
Langsame Leistung oder Timeouts beim Zugriff auf externe APIs
Symptome: Anwendungen arbeiten langsam oder erhalten Timeouts bei Anfragen an externe Dienste.
Diagnose:
# Überprüfen Sie die Erreichbarkeit des Proxys aus dem Pod
kubectl exec -it <pod-name> -- curl -v -x http://proxy.company.com:8080 https://www.google.com
# Messen Sie die Antwortzeit
kubectl exec -it <pod-name> -- time curl -x http://proxy.company.com:8080 https://api.example.com
Lösung: Das Problem könnte in der Leistung des Proxy-Servers liegen. Ziehen Sie in Betracht, residential Proxys mit geografisch nahegelegenen Standorten zu verwenden, um Verzögerungen zu reduzieren.
SSL/TLS-Fehler beim Arbeiten über Proxy
Symptome: Fehler wie "certificate verify failed" oder "SSL handshake failed".
Ursache: Einige Proxy-Server führen eine SSL-Inspektion (Entschlüsselung des HTTPS-Traffics) durch, was die Installation des Root-Zertifikats des Proxys erfordert.
Lösung:
# Erstellen Sie eine ConfigMap mit dem Zertifikat des Proxys
kubectl create configmap proxy-ca-cert --from-file=ca.crt=/path/to/proxy-ca.crt
# Montieren Sie das Zertifikat im Pod und fügen Sie es dem System-Zertifikatsspeicher hinzu
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
containers:
- name: app
volumeMounts:
- name: proxy-ca
mountPath: /usr/local/share/ca-certificates/proxy-ca.crt
subPath: ca.crt
volumes:
- name: proxy-ca
configMap:
name: proxy-ca-cert
Best Practices für Proxy in der Produktion
Basierend auf der Erfahrung mit der Nutzung von Kubernetes-Clustern in Unternehmensumgebungen sind hier Empfehlungen für eine zuverlässige Arbeit mit Proxys:
1. Verwenden Sie hochverfügbare Proxy-Server
Der Proxy wird zum Single Point of Failure für das gesamte Cluster. Richten Sie mehrere Proxy-Server hinter einem Load Balancer ein:
HTTP_PROXY=http://proxy-lb.company.com:8080
Wo proxy-lb.company.com der Load Balancer vor mehreren Proxy-Servern ist.
2. Zentrale Verwaltung der Konfiguration
Verwenden Sie ConfigMap oder Secret zur Speicherung der Proxy-Einstellungen anstelle von Hardcoding in jedem Manifest:
apiVersion: v1
kind: ConfigMap
metadata:
name: cluster-proxy-config
namespace: kube-system
data:
HTTP_PROXY: "http://proxy-lb.company.com:8080"
HTTPS_PROXY: "http://proxy-lb.company.com:8080"
NO_PROXY: "localhost,127.0.0.1,.cluster.local,.svc,10.0.0.0/8"
3. Monitoring und Alerting
Richten Sie das Monitoring der Verfügbarkeit von Proxy-Servern und Alarme bei Problemen ein:
- Antwortzeit des Proxys (sollte < 100ms für lokale Proxys sein)
- Anzahl der Verbindungsfehler zum Proxy
- Anzahl der ImagePullBackOff-Ereignisse im Cluster
- CPU- und Netzwerkbelastung auf den Proxy-Servern
4. Dokumentieren Sie die NO_PROXY-Ausnahmen
Führen Sie eine Dokumentation darüber, welche Domains und IP-Adressen in NO_PROXY hinzugefügt wurden und warum. Dies hilft bei der Fehlersuche und der Sicherheitsprüfung.
5. Testen Sie Änderungen in der Entwicklungsumgebung
Testen Sie Änderungen an den Proxy-Einstellungen immer in einem Dev/Staging-Cluster, bevor Sie sie in der Produktion anwenden:
# Test-Pod zur Überprüfung des Proxys
apiVersion: v1
kind: Pod
metadata:
name: proxy-test
spec:
containers:
- name: test
image: curlimages/curl:latest
command: ["sleep", "3600"]
env:
- name: HTTP_PROXY
value: "http://new-proxy.company.com:8080"
- name: HTTPS_PROXY
value: "http://new-proxy.company.com:8080"
# Überprüfen Sie die Erreichbarkeit externer Ressourcen
kubectl exec -it proxy-test -- curl -v https://registry.k8s.io
kubectl exec -it proxy-test -- curl -v https://docker.io
6. Verwenden Sie verschiedene Proxy-Typen für verschiedene Aufgaben
Verwenden Sie für kritische Komponenten (Herunterladen von Images, API des Clusters) schnelle Datacenter-Proxys, und für Anwendungen, die geografische Vielfalt der IPs erfordern, verwenden Sie Residential- oder Mobile-Proxys.
7. Aktualisieren Sie regelmäßig die NO_PROXY-Liste
Aktualisieren Sie NO_PROXY, wenn neue Dienste hinzugefügt oder die Netzwerktopologie geändert wird. Automatisieren Sie dies über Helm-Charts oder Kustomize:
# values.yaml für Helm-Chart
proxy:
enabled: true
http: "http://proxy.company.com:8080"
https: "http://proxy.company.com:8080"
noProxy:
- localhost
- 127.0.0.1
- .cluster.local
- .svc
- 10.0.0.0/8
- internal-service.company.com
Fazit
Die Konfiguration von Proxys in Kubernetes-Clustern ist eine mehrschichtige Aufgabe, die Aufmerksamkeit für Details auf jeder Ebene erfordert: vom Betriebssystem und der Container-Runtime bis hin zu einzelnen Pods. Die richtige Konfiguration gewährleistet den reibungslosen Betrieb des Clusters, sicheren Zugriff auf externe Ressourcen und die Einhaltung der Unternehmenssicherheitsrichtlinien.
Wichtige Punkte, die Sie beachten sollten:
- Konfigurieren Sie Proxys auf allen Ebenen: OS, Container-Runtime, kubelet, Pods
- Konfigurieren Sie NO_PROXY korrekt, einschließlich aller internen Netzwerke des Clusters
- Verwenden Sie zentrale Verwaltung über ConfigMap
- Überwachen Sie die Verfügbarkeit und Leistung der Proxy-Server
- Testen Sie Änderungen vor der Anwendung in der Produktion
Für kritische Kubernetes-Cluster empfehlen wir die Verwendung zuverlässiger Datacenter-Proxys mit hoher Verfügbarkeit und niedrigen Latenzen. Dies gewährleistet einen stabilen Betrieb der Infrastruktur und minimiert das Risiko von Ausfallzeiten aufgrund von Netzwerkzugangsproblemen.
Bei Problemen verwenden Sie einen systematischen Ansatz zur Diagnose: Überprüfen Sie die Einstellungen auf jeder Ebene, analysieren Sie Protokolle und Ereignisse, testen Sie die Verbindung manuell. Die meisten Probleme mit Proxys in Kubernetes lassen sich durch die richtige Konfiguration von Umgebungsvariablen und NO_PROXY lösen.