Deployen in Kubernetes
Kubernetes YAML-configuratiebestanden schrijven
In de GitHub-repository docker-course-examples vind je verschillende voorbeelden die je kunt gebruiken.
De voorbeelden die in deze sectie besproken worden, kun je ook lokaal uitproberen. Dit kan door eenvoudig een Kubernetes-cluster lokaal te starten met tools zoals Docker Desktop of Minikube.
Een pod beschrijven
Hieronder zie je een voorbeeld van een Kubernetes-configuratiebestand dat een pod beschrijft. Dit bestand bevat informatie over de containers die in de pod moeten draaien (in dit geval één container) en metadata die Kubernetes gebruikt.
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
Als je een Kubernetes-cluster lokaal hebt opgestart, kun je de pod uit het bovenstaande configuratiebestand starten door het bestand toe te passen op je cluster met het volgende commando:
kubectl apply -f nginx-pod.yml
De parameter na de -f optie geeft de bestandsnaam aan waarin de YAML-configuratie staat.
Om te controleren of de pod succesvol is gestart, kun je een lijst van draaiende pods in je cluster opvragen met dit commando:
kubectl get pods
Een deployment beschrijven
Als je de levenscyclus van een pod wilt automatiseren, kun je dat doen met een deployment. Een deployment doet in feite hetzelfde als de pod hierboven: een container starten met een Nginx-basisimage en een poort openstellen op poort 80. Het grote verschil is dat je in een deployment bijvoorbeeld kunt instellen hoeveel replica's van de pod er altijd beschikbaar moeten zijn.
Hieronder zie je een voorbeeld van een deployment-configuratiebestand:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
Je kunt dit op dezelfde manier toepassen op je cluster:
kubectl apply -f nginx-deployment.yml
# En om te zien wat er precies is opgestart:
kubectl get pods
In de lijst met pods zie je nu dat de deployment niet één, maar drie identieke pods heeft opgestart. Als je een van deze pods verwijdert of stopt en daarna de lijst opnieuw opvraagt, zie je dat er nog steeds drie pods actief zijn. De deployment zorgt er namelijk voor dat er altijd precies drie replica's beschikbaar zijn.
Gebruik van Docker images in Kubernetes
In Kubernetes kun je Docker-images gebruiken voor het draaien van containers in je pods. Er zijn verschillende manieren om met Docker-images om te gaan in Kubernetes, waaronder het definiëren van de imagePullPolicy en het omgaan met private registries.
imagePullPolicy
De imagePullPolicy bepaalt wanneer Kubernetes een nieuwe versie van een container-image ophaalt (pullt) van de Docker-registry. Dit is belangrijk voor het beheren van de levenscyclus van je containers, vooral als je werken met gecached of up-to-date images.
Er zijn drie mogelijke waarden voor imagePullPolicy:
- Always: Met
Alwayswordt het image altijd opnieuw opgehaald van de registry, zelfs als het al aanwezig is op de node. Dit is handig als je altijd de nieuwste versie van je image wilt gebruiken, zoals bij een continue integratie/deployment-pijplijn. - IfNotPresent: Met
IfNotPresenthaalt Kubernetes de image alleen op als het nog niet lokaal beschikbaar is op de node. Dit kan nuttig zijn om netwerkverkeer te besparen, aangezien Kubernetes het image niet opnieuw zal ophalen als het al in de cache van de node aanwezig is. - Never: Met
Neverwordt het image nooit opgehaald uit de registry, zelfs niet als het niet lokaal beschikbaar is. Dit kan nuttig zijn wanneer je volledige controle wilt hebben over de images die al op de node staan, bijvoorbeeld in een zeer gecontroleerde omgeving.
Wanneer je niet specifiek een imagePullPolicy configureert kan je aan de hand van de tags die je aan je image meegeeft toch de imagePullPolicy bepalen:
latesttag: Als je delatesttag gebruikt voor een image, wordt deimagePullPolicyautomatisch ingesteld opAlways, zelfs als je het niet expliciet definieert. Dit betekent dat Kubernetes elke keer de nieuwste versie van de image ophaalt.- Anders dan
latest: Als je een andere versie (bijvoorbeeldnginx:1.21.0) gebruikt, dan is deimagePullPolicystandaardIfNotPresent, wat betekent dat Kubernetes de image alleen zal ophalen als het nog niet lokaal aanwezig is.
Private Registries
In Kubernetes kun je ook gebruik maken van private Docker registries om je images op te slaan en binnen te trekken (pullen). Als je een private registry gebruikt, heb je een aantal aanvullende stappen die nodig zijn om Kubernetes toegang te geven tot die registry.
Docker Registry Secret
Om toegang te krijgen tot een private registry, moet je een Docker registry secret creëren. Dit secret bevat de authenticatie-informatie die Kubernetes nodig heeft om te kunnen inloggen bij de private registry.
-
Maak een secret voor de private registry: Gebruik het
kubectl create secret docker-registrycommando om een secret aan te maken. Je zult de gebruikersnaam, het wachtwoord en de server URL van je private registry nodig hebben.Voorbeeld:
kubectl create secret docker-registry my-registry-secret \
--docker-server=your-registry-domain.com \
--docker-username=your-username \
--docker-password=your-password \
--docker-email=your-email@example.comDit maakt een secret genaamd
my-registry-secretaan. Dit secret bevat de nodige authenticatiegegevens voor het registreren bij de private registry. -
Verwijs naar het secret in je Pod YAML: Nadat het secret is aangemaakt, kun je het gebruiken in je Kubernetes-pods door het
imagePullSecretsveld in te stellen. Dit vertelt Kubernetes welk secret het moet gebruiken om in te loggen op de private registry bij het ophalen van het image.Voorbeeld YAML voor Pod:
apiVersion: v1
kind: Pod
metadata:
name: my-private-image-pod
spec:
containers:
- name: my-container
image: your-registry-domain.com/your-image:latest
imagePullSecrets:
- name: my-registry-secretHier wordt het
imagePullSecretsveld gebruikt om Kubernetes te vertellen dat het hetmy-registry-secretmoet gebruiken om toegang te krijgen tot de private registry voor het imageyour-registry-domain.com/your-image:latest.
Private Registries in Deployments
Wanneer je private images gebruikt in een Kubernetes Deployment, kun je dezelfde imagePullSecrets gebruiken in de spec.template.spec van de deployment.
Voorbeeld YAML voor Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-private-deployment
spec:
replicas: 2
selector:
matchLabels:
app: my-private-app
template:
metadata:
labels:
app: my-private-app
spec:
containers:
- name: my-container
image: your-registry-domain.com/your-image:latest
imagePullSecrets:
- name: my-registry-secret
Hiermee wordt de private registry geconfigureerd voor de my-private-deployment deployment. Kubernetes zal de Docker registry secret gebruiken om het image uit de private registry op te halen.
Schalen van applicaties met Deployments
Handmatig
kubectl scale deployment <deployment-naam> --replicas=<aantal-replica's>
Deployment file
Je kan ook in de deployment file beheren hoeveel replicas er moeten zijn.
Horizontal Pod Autoscaler (=HPA)
Horizontaal autoschalen wilt zeggen dat je meer instanties van dezelfde applicatie gaat opstarten, naargelang de nood (de load).
Stel dat je bijvoorbeeld een deployment opstart met volgend commando:
kubectl autoscale deployment nginx-deployment --cpu-percent=50 --min=2 --max=10
In dit voorbeeld:
--cpu-percent=50: Dit betekent dat Kubernetes zal proberen het gemiddelde CPU-gebruik van de pods rond 50% te houden.--min=2: Het minimum aantal replica's is 2.--max=10: Het maximum aantal replica's is 10.
HPA in een yml
Je kan het horizontaal autoschalen van een deployment ook doen aan de hand van configuratie bestanden.
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: nginx-hpa
spec:
scaleRef:
apiVersion: apps/v1
kind: Deployment
name: nginx-deployment
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
Dit kan je dan toepassen op je cluster met volgende commando:
kubectl apply -f nginx-hpa.yaml
Opgelet met het schalen van stateful applicaties!!
Een applicatie is stateful wanneer er binnen de applicatie data wordt opgeslagen die belangrijk is voor het correct draaien van de applicatie. Bijvoorbeeld een webserver die in-memory bepaalde metadata van een gebruiker opslaat. Afhankelijk van aan welke instantie van die applicatie je die metadata opvraagt, ga je een ander antwoord krijgen. Het is over het algemeen best practise om applicaties die in een container gaan draaien stateless te houden om dit soort problemen te voorkomen.
Beheren van de levenscyclus van applicaties in Kubernetes
In Kubernetes kun je de levenscyclus van applicaties beheren met Rolling Updates en Rollbacks, twee krachtige mechanismen waarmee je applicaties kunt bijwerken en herstellen zonder downtime. Deze functies zijn vooral nuttig bij het beheren van productieomgevingen waar je minimale verstoring wilt hebben tijdens het uitvoeren van updates en het herstellen van een vorige versie.
Rolling Updates in Kubernetes
Een Rolling Update is een manier om een nieuwe versie van je applicatie uit te rollen zonder downtime. In plaats van de oude versie van je applicatie in één keer te stoppen en de nieuwe versie te starten, worden de pods geleidelijk bijgewerkt. Dit zorgt ervoor dat altijd een deel van je applicatie beschikbaar blijft tijdens de update.
Hoe Rolling Updates werken:
Wanneer je een Deployment bijwerkt (bijvoorbeeld door de container-image te wijzigen of de applicatieconfiguratie aan te passen), zorgt Kubernetes ervoor dat de nieuwe pods geleidelijk worden uitgerold en de oude pods geleidelijk worden verwijderd. Het doel is om de beschikbaarheid van de applicatie te behouden tijdens het updateproces.
Stappen bij een Rolling Update:
- Kubernetes maakt nieuwe pods met de bijgewerkte configuratie.
- Deze nieuwe pods worden stap voor stap gestart.
- Oude pods worden één voor één verwijderd zodra de nieuwe pods succesvol draaien.
- De update is voltooid wanneer het gewenste aantal nieuwe pods actief is en de oude pods zijn verwijderd.
Rolling Update configureren
Je kunt de rolling update-configuratie instellen met de maxUnavailable en maxSurge parameters. Deze bepalen hoeveel pods tegelijkertijd kunnen worden bijgewerkt.
maxUnavailable: Het aantal pods dat tijdelijk niet beschikbaar mag zijn tijdens de update.maxSurge: Het aantal extra pods dat tijdelijk kan worden toegevoegd boven het gewenste aantal replicas tijdens de update.
Voorbeeld YAML voor Rolling Update configuratie:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
In dit voorbeeld:
maxSurge: 1betekent dat er tijdelijk 1 extra pod kan worden toegevoegd om de nieuwe versie van de applicatie te ondersteunen.maxUnavailable: 1betekent dat maximaal 1 pod niet beschikbaar mag zijn tijdens de update, zodat de applicatie altijd beschikbaar blijft.
Rolling Update uitvoeren
Na het aanpassen van je Deployment YAML of het veranderen van je image, kun je een rolling update uitvoeren door de gewijzigde YAML opnieuw toe te passen met het volgende commando:
kubectl apply -f nginx-deployment.yaml
Kubernetes zorgt er dan voor dat de update op een gecontroleerde manier wordt uitgevoerd zonder downtime.
Rollbacks in Kubernetes
Een Rollback in Kubernetes is het proces waarbij je teruggaat naar een vorige versie van een applicatie, bijvoorbeeld als een update niet goed werkt of als er een probleem optreedt. Kubernetes maakt het gemakkelijk om snel terug te keren naar een vorige versie van een Deployment.
Rollback uitvoeren
Kubernetes slaat automatisch de vorige versies van je Deployment op (met een versiegeschiedenis). Je kunt de geschiedenis van een Deployment bekijken en terugrollen naar een eerdere versie als dat nodig is.
geschiedenis van een Deployment
Het kubectl rollout history commando toont de geschiedenis van je Deployment, inclusief de versies van de applicatie.
kubectl rollout history deployment/nginx-deployment
Dit toont de versies van je Deployment en de details van elke versie. Bijvoorbeeld:
deployment.apps/nginx-deployment
REVISION CHANGE-CAUSE
1 <none>
2 kubectl apply -f nginx-deployment-v2.yaml
3 kubectl apply -f nginx-deployment-v3.yaml
Rollback naar een vorige versie
Als een update niet goed werkt, kun je eenvoudig terugrollen naar een vorige versie van de Deployment met het kubectl rollout undo commando.
kubectl rollout undo deployment/nginx-deployment
Dit zal de Deployment terugrollen naar de vorige versie. Als je naar een specifieke versie wilt terugrollen, kun je de versie opgeven met --to-revision:
kubectl rollout undo deployment/nginx-deployment --to-revision=2
Dit commando brengt de Deployment terug naar versie 2.
Controleer de status van een rollback
Je kunt de voortgang van de rollback controleren met het kubectl rollout status commando:
kubectl rollout status deployment/nginx-deployment
Dit toont de voortgang van de update of rollback, bijvoorbeeld "deployment 'nginx-deployment' successfully rolled out".
Voordelen van Rolling Updates en Rollbacks
- Minimale downtime: Met Rolling Updates kan je applicatie up-to-date blijven met minimale impact op de gebruikerservaring. Kubernetes zorgt ervoor dat altijd een werkende versie van de applicatie beschikbaar is.
- Veiligheid: Als er iets misgaat tijdens een update, kun je eenvoudig een rollback uitvoeren en de vorige versie herstellen.
- Versiebeheer: Kubernetes houdt automatisch een versiegeschiedenis bij, waardoor het gemakkelijk is om eerdere versies van je applicatie terug te halen en eventuele problemen te verhelpen.