Tout ensemble : une application¶
Rappels K8s¶
Vocabulaire¶
Node : Master ou Worker
Control plane : tous les master
Objets : pod / deployment / service / etc.
namespace
Un objet est une spécification et un état; il appartient à un namespace (sauf exception).
On fixe la spécification et kubernetes se débrouille pour que l’état corresponde à cette spécification.
Les objets peuvent suivre des spécifications nouvelles (CRD : Custom Resource Definition ). Il faut imaginer alors k8s comme un espace de stockage de ces objets, et c’est à nous de faire une application qui les traite. Les « addons » de k8s s’appuient beaucoup sur ce mécanisme.
Manipulation¶
Au travers de l’API qui est exposée sur le port 6443 d’un master node.
(Note : comme le port 6443 n’est pas ouvert, on fait un tunnel ssh entre localhost et un noeud master via ssh -L 6443:127.0.0.1:6443 147.100.164.212 . Ceci expose le port 6443 de la machine sur laquelle on se connecte sur le port 6443 de localhost)
On configure un fichier kubernetes.conf contenant l’adresse d’un master node + identifiants.
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: ......
server: https://127.0.0.1:6443
name: cluster.local
kind: Config
preferences: {}
users:
- name: kubernetes-admin
user:
client-certificate-data: .....
client-key-data: LS.......
On peut alors accéder aux objets k8s :
export KUBECONFIG=$(pwd)/kubernetes.conf
kubectl get pods -o wide --all-namespaces
Exemple d’application¶
Une application pour moi¶
Une application c’est à la fois :
plusieurs programmes qui communiquent entre eux
un point d’entrée (https://truc.com)
un certificat ssl
une base de données
…
C’est tout l’écosystème qui doit être déployé pour que ce soit en état de marche et qu’on puisse l’utiliser.
Exemple¶
Je suis développeur, j’écris une application pour laquelle, pour chaque nouvelle version, je crée un conteneur :
registry.forgemia.inra.fr/sol_k8s/argocd_examples/hello_flask:0.1registry.forgemia.inra.fr/sol_k8s/argocd_examples/hello_flask:0.2etc.
Ce conteneur écoute sur le port 8000. Je le sais car je suis développeur et en plus je le documente dans le Dockerfile :
FROM python:3
WORKDIR /app/
COPY . /app/
RUN pip install -r requirements.txt
EXPOSE 8000
CMD ["flask","run","-h","0.0.0.0","-p","8000"]
Pour le déployer sur k8s il faut beaucoup d’objets :
---
# UN DEPLOIEMENT
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-hello-flask
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: hello-flask
app.kubernetes.io/instance: app
template:
metadata:
labels:
app.kubernetes.io/name: hello-flask
app.kubernetes.io/instance: app
spec:
containers:
- name: hello-flask
image: "registry.forgemia.inra.fr/sol_k8s/argocd_examples/hello_flask:0.1"
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 8000
protocol: TCP
---
# UN SERVICE
apiVersion: v1
kind: Service
metadata:
name: app-hello-flask
spec:
type: ClusterIP
ports:
- port: 8000
targetPort: http
protocol: TCP
name: http
selector:
app.kubernetes.io/name: hello-flask
app.kubernetes.io/instance: app
---
# UN INGRESS
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-hello-flask
spec:
rules:
- host: "test.amoi"
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: app-hello-flask
port:
number: 8000
Pour essayer, créez un fichier yaml pour chaque objet : deployment.yaml, service.yaml, ingress.yaml.
Créez l’objet deployment :
kubectl apply -f deployment.yaml
Observez la création du pod.
De la même manière créez les autres objets :
kubectl apply -f service.yaml
kubectl apply -f ingress.yaml
Et kubernetes fait le reste : il crée d’autres objets si nécessaire (par exemple pour les certificats) et fait converger les états.
Après avoir modifié le fichier /etc/hosts, vous pourrez accéder à l’application en allant sur http://test.amoi.
Pour mettre à jour mon application, il suffira de modifier l’image pointée par ce fichier.
Remarque : ce serait sympa d’avoir un template et de séparer les données utiles du reste..
Helm¶
Helm permet justement d’avoir un template et de séparer les données utiles du reste :
helm create hello-flask.
Cela génère une arborescence avec à la racine un fichier values.yaml et dans le reste de l’arborescence, des templates contenant le yaml de description d’objets k8s.
Dans les values on a l’essentiel :
replicaCount: 1
image:
repository: registry.forgemia.inra.fr/sol_k8s/argocd_examples/hello_flask
pullPolicy: IfNotPresent
tag: 0.1
service:
type: ClusterIP
port: 8000
ingress:
enabled: true
className: ""
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-clusterissuer
hosts:
- host: hello.inrae.jrobert-orleans.fr
paths:
- path: /
pathType: ImplementationSpecific
tls:
- secretName: hello-flask-ssl
hosts:
- hello.inrae.jrobert-orleans.fr
Et si je veux voir le résultat de ce “helm chart” :
helm template .
Argocd¶
Et si on versionne ce « helm chart » dans un dépot git, on a une application toute prète à être déployée.
Pour déployer une application versionnée dans un dépot on doit alors faire le lien entre git et kubernetes :
télécharger le helm chart
helm template
appliquer ce qu’on obtient avec kubectl
vérifier que tout s’est bien passé (et alerter si ce n’est pas le cas)
rester en veille sur des changements du dépot et revenir au point 1 si c’est le cas.
Argocd fait tout ça pour nous. À voir en live :
déclaration d’un dépot dans argocd
modification des valeurs dans App details -> parameters
visualisation de l’état:
pods
network
logs des pods
différence entre état demandé et actuel
sync / rollback
Petits détails¶
Accès à la forge par argocd pour cloner le dépot
Accès à la forge par kubernetes pour télécharger l’image