Es ist nicht immer angebracht, eigene Container-Images in eine öffentliche Registry zu pushen. Dieser Beitrag zeigt einen schnellen Weg, eine private Image-Registry innerhalb eines K3s Kubernetes-Clusters zu erstellen.
Bitte beachte, dass mit dem folgenden Manifest, wenn die Registry-Ressourcen aus dem Cluster entfernt werden, alle Images ebenfalls entfernt werden. Es gibt ein TODO in der allerletzten Zeile, das dies adressiert.
Auch wichtig: Die Registry ist ungesichert. Weitere Schritte (zum Beispiel Benutzername/Passwort oder Zertifikate) sind erforderlich, um sie zu sichern; das liegt außerhalb des Umfangs dieses Tutorials.
Kubernetes-Ressourcen
Bevor dieses Manifest angewendet wird, muss der Domainname unter spec:rules:host entsprechend geändert werden.
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: docker-registry-ingress
annotations:
kubernetes.io/ingress.class: "traefik"
spec:
rules:
- host: registry.domain.de
http:
paths:
- path: /
backend:
serviceName: docker-registry-service
servicePort: 5000
---
apiVersion: v1
kind: Service
metadata:
name: docker-registry-service
labels:
run: docker-registry
spec:
selector:
app: docker-registry
ports:
- protocol: TCP
port: 5000
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: docker-registry
labels:
app: docker-registry
spec:
replicas: 1
selector:
matchLabels:
app: docker-registry
template:
metadata:
labels:
app: docker-registry
spec:
containers:
- name: docker-registry
image: registry
ports:
- containerPort: 5000
protocol: TCP
volumeMounts:
- name: storage
mountPath: /var/lib/registry
env:
- name: REGISTRY_HTTP_ADDR
value::5000
- name: REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY
value: /var/lib/registry
volumes:
- name: storage
emptyDir: {} # TODO - make this more permanent later
Wende das Manifest an mit:
kubectl apply -f registry.yaml
Einstellungen
Auf den K3s-Nodes erstelle die Datei /etc/rancher/k3s/registries.yaml mit folgendem Inhalt. Der Domainname muss mit dem im Manifest oben übereinstimmen.
mirrors:
"registry.domain.de":
endpoint:
- "http://registry.domain.de"
Ich habe das sowohl auf den Server- als auch auf den Agent-Nodes gemacht. Ich bin nicht sicher, ob es auf den Agents gemacht werden muss, aber ich habe es dort gemacht.
Danach starte Server und Agents neu.
Auf dem Server führe aus:
systemctl restart k3s
Auf dem Agent-Node führe aus:
systemctl restart k3s-agent
Du kannst überprüfen, ob die Änderungen angewendet wurden mit:
crictl info
Es gibt einen Abschnitt namens registry, der die neu erstellte private Registry auflisten sollte.
Die lokale Workstation muss auch von der neuen Registry wissen. Ich benutze macOS mit Docker Desktop. Unter “Preferences → Docker Engine” erweitere die Einstellungen mit folgendem Eintrag:
{
...
"insecure-registries": [
"registry.domain.de"
]
}
Die Registry testen
Um das Pushen eines Images in die neue Registry zu testen, habe ich ein kleines Image gebaut, das Nginx mit einer benutzerdefinierten HTML-Datei enthält:
<html>
<head><title>Hello World!</title>
<style>
html {
font-size: 500.0%;
}
div {
text-align: center;
}
</style>
</head>
<body>
<div>Hello World!</div>
</body>
</html>
Das Dockerfile für das Image:
FROM nginx:alpine
COPY index.html /usr/share/nginx/html
Baue und tagge das Image entsprechend deiner Registry-Domain:
docker build -t registry.domain.de/hello:latest.
Pushe das Image:
docker push registry.domain.de/hello:latest
Wenn das funktioniert hat, kannst du weiter testen, indem du das Image lokal entfernst und es erneut aus der privaten Registry pullst:
docker rmi registry.domain.de/hello:latest
docker pull registry.domain.de/hello:latest