-1/ Contexte
Okay,
Ca fait un moment que je veux faire ça. Je veux passer de ma petite infra actuellement en podman vers du kube. Par le passé j’ai déjà eu à bosser avec du kubernetes (souvent open shift), mais j’ai jamais eu à gérer le tout du début à la fin en solo.
Et je vais être honnête, je me suis pris plus souvent les pieds dans le tapis que ce que je voudrais l’admettre et que j’avais prévu.
Outre le fait que les fois précédentes ou j’ai eu à faire du kube, je n’étais pas tout seul dans le déploiement et la MCO, là je suis le seul “architecte” de cette “équipe”. Du coup il faut pas mal lire et se taper des vidéos relou de youtubeur en mal de visibilité qui te présente des outils pour pouvoir faire son choix.
Et ça m’a pris du temppppps.
Je veux partir sur du kube car je me rends compte que j’étais entrain de ré inventer la roue: j’ai eu des petits besoins. Pour commencer un petit Nextcloud et donc un PostgreSQL, puis sont venus d’autres services, et d’autres utilisateurs, donc un petit LDAP, accompagné d’OAuth.
L’évolution de cette “infra” a suivi le parcours classique, et a surtout suivi “l’air du temps”. Je suis passé par des VM administrées entièrement à la mano, puis je suis passé sur du LXC dans du Proxmox pour alléger un peu tout ça. De nouveau une grosse VM dans laquelle on pose des containeurs. Au début du docker, puis du podman avec du Quadlet (bah ouais ça me permettait de faire un peu de IaC avec du Ansible). A chaque fois j’ai les backup (un peu) et le monitoring (beaucoup) à la traine. J’essaye de faire des petites conf réseaux entre les différentes machines qui gèrent tout ça mais je me retrouve avec des trucs vraiment bancals (bancaux ?).
Et je me suis rendu compte que kube est devenu plus accessible (plus besoin de méga infra). La marche d’entrée est un peu costaud, mais j’y gagne au final : vazy intègre proprement loki sur tous tes containeurs podman ou gère proprement ton mTLS sur ton propre CA avec des durées de certificats très courtes avec du podman.
En gros l’objectif :
- quelques applis web classiques (genre nextcloud, un lecteur rss)
- la possibilité de tester des applis web à la va vite
- une forge
- des runners
- BDD
- Backup
- Monitoring
Le tout en IaC pour redéployer à la va vite.
0/ Installation
Bon dans la période IA qui achete toutes les ressources ça devient galère de louer des serveurs Je me retrouve avec un serveur ARM64 Ampere chez Hertzner, on verra ça me va. Commande brute de décoffrage. On verra dans d’autres installations comment changer ça
curl -sfL https://get.k3s.io | sh -
Bon et vu que comme moi le nom de la machine ne correspond pas au certificat/domaine par lequel vous allez contacter le serveur. On regénère directement le certificat avec un SAN additionnel
systemctl stop k3s
k3s server --tls-san NOM-DE-DOMAINE-SUPPLEMENTAIRE
(petit coup de CTRL-C, j’avoue c’est crade, mais j’ai pas trouvé d’autres méthodes pour le moment.)
systemct restart k3s
Wouh, on a un piti cluster K3s 🎉🥳.
Aller première étape, on est en 2026, on va configurer le traefik qui est venu avec K3s en gateway.
1/ Traefik
La doc de K3s nous le dit , des morceaux de K3s sont configurés à l’aide de helm.
On va donc utiliser helm pour configurer notre traefik et on se base sur GitHub de K3s.
On ne prend pas la peine de mettre en place l’ancienne méthode, à base d’Ingress et on s’assure de pouvoir déclarer des Gateway dans tous les namespace.
Hop on applique ça:
apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
name: traefik
namespace: kube-system
spec:
valuesContent: |-
providers:
kubernetesIngress:
enabled: false
kubernetesGateway:
enabled: true
logs:
access:
enabled: true
gateway:
FromNamespaces: All
listeners:
web:
namespacePolicy:
from: All
Pour vérifier le fonctionnement de notre Gateway toute fraîche (encore un peu fragile), on va aller tester ça avec un petit containeur (trouvé dans la doc de traefik)
apiVersion: v1
kind: Namespace
metadata:
name: whoami
---
# Application to expose
kind: Deployment
apiVersion: apps/v1
metadata:
name: whoami
namespace: whoami
spec:
replicas: 1
selector:
matchLabels:
app: whoami
template:
metadata:
labels:
app: whoami
spec:
containers:
- name: whoami
image: traefik/whoami
---
# Service to reach the application on the cluster
apiVersion: v1
kind: Service
metadata:
name: whoami
namespace: whoami
labels:
app: whoami
spec:
type: ClusterIP
ports:
- port: 80
name: whoami
selector:
app: whoami
---
# HTTPRoute
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: whoami-httproute
namespace: whoami
spec:
parentRefs:
- name: traefik-gateway
namespace: kube-system
hostnames:
- whoami.hetzner.htnl.fr
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: whoami
namespace: whoami
port: 80
Dans ce petit extrait, outre le déploiement accompagné de son service, on crée surtout une HTTPRoute. Ça c’est la ressource qui “vient” avec les Gateway Kube. Et pour le moment la plateforme ne fait que servir notre petit containeur whoami en HTTP (oui sans le S, ça viendrait plus tard)
2/ ArgoCD
Allez, parce que c’est sympa d’avoir un peu de visuel, on va se mettre un ArgoCD (oui oui, il y a plein d’autres supers fonctions a ArgoCD, les rollback et tout…)
kubectl create namespace argocd
kubectl apply -n argocd --server-side --force-conflicts -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
Il nous faut maintenant rajouter une HTTPRoute et aussi un gRPCRoute.
L’API gRPC de ArgoCD sert sur le port 443, et à l’air de vouloir de l’enrober dans du SSL. Je veux pas que ArgoCD s’occupe du SSL, ça sera le job de la Gateway (d’où l’uasage du server.insecure).
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cmd-params-cm
namespace: argocd
labels:
app.kubernetes.io/name: argocd-cmd-params-cm
app.kubernetes.io/part-of: argocd
data:
server.insecure: "true"
Et pour les routes
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: httproute-argocd
namespace: argocd
spec:
parentRefs:
- name: traefik-gateway
namespace: kube-system
hostnames:
- argo.hetzner.htnl.fr
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: argocd-server
namespace: argocd
port: 80
---
apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
name: grpcroute-argocd
namespace: argocd
spec:
parentRefs:
- name: traefik-gateway
namespace: kube-system
hostnames:
- "argo.hetzner.htnl.fr"
rules:
- backendRefs:
- name: argocd-server
port: 443
matches:
- headers:
- name: Content-Type
type: RegularExpression
value: "^application/grpc.*$"
Pour récupérer votre mot de passe argocd:
k get secret argocd-initial-admin-secret -o jsonpath={.data.password} |base64 -d
*(Bien sur, on ne prend pas le % final)
Et vu qu’on vient de modifier la configmap pour dire au serveur ArgoCD de ne plus faire de SSL, il faut le reload
k delete pod -l app.kubernetes.io/name=argocd-server
(Aller on change son MdP, ou au moins on le retire de secret kube)
3/ Cert-Manager
Grooos sujet Maintenant qu’on a ArgoCD, on va souvent utiliser la resource “Application”
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: cert-manager
spec:
destination:
namespace: cert-manager
server: https://kubernetes.default.svc
source:
path: .
repoURL: oci://quay.io/jetstack/charts/cert-manager:v1.19.4
targetRevision: 1.19.4
helm:
parameters:
- name: crds.enabled
value: "true"
- name: installCRDs
value: "true"
values: |-
config:
enableGatewayAPI: true # <- MEGA IMPORTANT
sources: []
project: default
syncPolicy:
syncOptions:
- CreateNamespace=true
- ServerSideApply=true
Une fois cert-manager installé on a besoin de le configurer.
Le premier truc à faire c’est mettre en place un Issuer (en gros c’est quoi ton CA, et comment le contacter). Il existe Issuer et ClusterIssuer, il y en a un qui est défini dans un namespace, l’autre qui flotte dans l’ether.
Dans mon cas, je ne veux pas que l’Issuer soit limité à un namespace, donc je vais utiliser un ClusterIssuer, et mon CA, je vais le “contacter” en ACME (coucou Let’s Encrypt).
Pour commencer on va tester avec le service de test (staging) de Let’s Encrypt et donc on va créer un ClusterIssuer relié à ce CA.
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
namespace: kube-system
spec:
acme:
email: METTRE_SON_EMAIL_ICI
profile: tlsserver
privateKeySecretRef:
name: k3s-issuer-staging-account-key
server: https://acme-staging-v02.api.letsencrypt.org/directory
solvers:
- http01:
gatewayHTTPRoute:
parentRefs:
- name: traefik-gateway
namespace: kube-system
kind: Gateway
On peut déjà voir si on est en bonne relation avec Let’s Encrypt
kubectl get clusterissuers.cert-manager.io -o wide
Maintenant le but c’est de pousser cert-manager à générer les certificats par la déclaration dans la gateway.
D’abord pour la configuration générale de Traefik on va rester basé sur ce qu’offre K3s/Traefik.
Par contre on va arreter de gérer la configuration des différentes gateway par ce chart. La syntaxe de ce Helm chart est un peu trop “tordue” à mon gout pour ça
Petite note: il y a une valeur par défaut dans la chart pour le tag de l’image à déployer qui est ’erroné’ (je dois surement manquer quelque chose), le tag n’est pas préfixé par un ‘v’ ainsi je suis obligé de le préciser manuellement.
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: traefik
spec:
destination:
namespace: kube-system
server: https://kubernetes.default.svc
source:
path: charts/traefik/38.0.201+up38.0.2
repoURL: https://github.com/k3s-io/k3s-charts/
targetRevision: HEAD
helm:
values: |-
image:
tag: "3.6.7"
providers:
kubernetesIngress:
enabled: false
kubernetesGateway:
enabled: true
logs:
access:
enabled: true
gateway:
enabled: false
sources: []
project: default
Je met le manifest de “gestion” de la gateway dans un git (pour moi ça sera ici)
Le fichier hetzner/global-gateway.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: traefik-gateway
namespace: kube-system
annotations:
cert-manager.io/cluster-issuer: letsencrypt-staging
spec:
gatewayClassName: traefik
listeners:
- name: web
protocol: HTTP
port: 8000
allowedRoutes:
namespaces:
from: All
- name: whoami-https
protocol: HTTPS
port: 8443
hostname: whoami.hetzner.htnl.fr
tls:
certificateRefs:
- group: ""
kind: Secret
name: whoami-htnl-fr-tls
mode: Terminate
allowedRoutes:
namespaces:
from: All
Ce fichier, bien brut de décoffrage, mérite une transformation en Helm. On verra ça plus tard. Là, le but c’est de tester cert-manager.
L’application ArgoCD:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: traefik-gateway
spec:
destination:
namespace: kube-system
server: https://kubernetes.default.svc
source:
path: hetzner
repoURL: https://git.halletienne.fr/halletienne/traefik-gateway.git
targetRevision: HEAD
directory:
include: global-gateway.yaml
sources: []
project: default
Si tout s’est bien passé, on voit dans l’application ArgoCD le certificat généré. Bon actuellement si vous vous rendez à l’adresse du whoami vous aurez une alerte sécurité. Oui, l’environnement staging de Let’s Encrypt n’offre pas des certificats “trusted”.
Si quelqu’un suit ce ‘guide’, je vous conseille fortement, de vous assurer que votre génération de certificat marche avec l’environnement staging de Let’s Encrypt avant de passer sur leur prod. Ils ont des mécanismes de RateLimite plus sévère en prod (compréhensible), et c’est jamais agréable de devoir attendre quand on a fait des bêtises dans sa conf.
On va passer le tout sur l’environnement de prod chez Let’s Encrypt.
D’abord le ClusterIssuer de prod:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
namespace: kube-system
spec:
acme:
email: METTRE_SON_EMAIL_ICI
profile: tlsserver
privateKeySecretRef:
name: k3s-issuer-account-key
server: https://acme-v02.api.letsencrypt.org/directory
solvers:
- http01:
gatewayHTTPRoute:
parentRefs:
- name: traefik-gateway
namespace: kube-system
kind: Gateway
Et on met à jour la Gateway avec ce nouveau ClusterIssuer.
J’ai aussi rajouté le domaine ArgoCD:
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: traefik-gateway
namespace: kube-system
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod # <---- LAAAA
spec:
gatewayClassName: traefik
listeners:
- name: web
protocol: HTTP
port: 8000
allowedRoutes:
namespaces:
from: All
- name: whoami-https
protocol: HTTPS
port: 8443
hostname: whoami.hetzner.htnl.fr
tls:
certificateRefs:
- group: ""
kind: Secret
name: whoami-htnl-fr-tls
mode: Terminate
allowedRoutes:
namespaces:
from: All
- name: argocd-https
protocol: HTTPS
port: 8443
hostname: argo.hetzner.htnl.fr
tls:
certificateRefs:
- group: ""
kind: Secret
name: argo-htnl-fr-tls
mode: Terminate
allowedRoutes:
namespaces:
from: All
Petite note: quay.io (le fournisseur de la chart de cert-manager) peut parfois vous rate-limite si vous restez non authentifié. Il peut donc être intéressant de donner un couple Login/MdP pour avoir un peu plus de bande passante.
Si tu vois des HTTP 401 quand tu configures cert-manager, c’est surement ça.
Vous pouvez créer un secret pour ça:
---
apiVersion: v1
kind: Secret
metadata:
name: quay-oci-repo
namespace: argocd
labels:
argocd.argoproj.io/secret-type: repo-creds
stringData:
username: COUPLE_LOGIN_MDP
password: VOTRE_MDP
project: default
type: oci
url: oci://quay.io/jetstack/charts/cert-manager
4/ Local storage
Je sais que faire du stockage directos sur le node, c’est bof (et encore ça dépend des situations). Mais pour commencer on va faire comme ça. On réserve l’object storage et autre stockage, pour un autre article.
(Et en plus je lis que dans les reco CloudNative-PG, c’est pas trop mal de faire du local, puis d’utiliser la synchro native de PostgreSQL).
K3s met à dispo un petit mécanisme, largement suffisant pour notre usage actuel, le local-path-provisioner.
Pour le coup, je me suis ‘amusé’ et j’ai écrit ma petite chart Helm pour le gérer (git) comme je l’entendais: je voulais juste avoir à spécifier le nom du node, et indiquer où le stockage doit se faire.
Sinon de base k3s met tout dans /var/lib/rancher/k3s/storage (aller voir dans la cm local-patch-config -n kube-system).
En application ArgoCD ça donne :
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: local-path-k3s
spec:
destination:
namespace: kube-system
server: https://kubernetes.default.svc
source:
path: .
repoURL: https://git.halletienne.fr/halletienne/local-path-k3s.git
targetRevision: HEAD
helm:
values: |-
nodes:
- nodeName: k3s-demo
pathList:
- /opt/kubernetes
sources: []
project: default
5/ Metrics
5.1/ Prometheus
Bon, on commence à se rapprocher de plus en plus d’une situation de base que j’avais avec du Ansible + Podman Quadlets. Mais cette fois je veux avoir des metric tout de suite !
Par chance (non, c’est tout le but de la manoeuvre), il existe une super chart et des super conf déjà dispo sur GitHub.
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: prometheus-stack
spec:
destination:
namespace: monitoring
server: https://kubernetes.default.svc
source:
path: charts/kube-prometheus-stack
repoURL: https://github.com/prometheus-community/helm-charts/
targetRevision: kube-prometheus-stack-82.4.1
sources: []
project: default
syncPolicy:
syncOptions:
- CreateNamespace=true
- ServerSideApply=true
Attention, un peu lourd à déployer. ArgoCD peut croire qu’il se met en carafe car il mouline longtemps, mais normalement ça réussi sans soucis
Et pour avoir accès aux jolis dashboard de grafana, il nous faut une HTTPRoute:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: httproute-mon
namespace: monitoring
spec:
parentRefs:
- name: traefik-gateway
namespace: kube-system
hostnames:
- mon.hetzner.htnl.fr
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: prometheus-stack-grafana
namespace: monitoring
port: 80
Avec ça, on a déjà un paquet de dashboards.
Si on veut s’amuser à récolter les info Traefik, on modifie l’application ArgoCD du Traefik avec les infos suivantes (partie ‘metrics’)
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: traefik
spec:
destination:
namespace: kube-system
server: https://kubernetes.default.svc
source:
path: charts/traefik/38.0.201+up38.0.2
repoURL: https://github.com/k3s-io/k3s-charts/
targetRevision: HEAD
helm:
values: |-
image:
tag: "3.6.7"
providers:
kubernetesIngress:
enabled: false
kubernetesGateway:
enabled: true
logs:
access:
enabled: true
gateway:
enabled: false
metrics:
prometheus:
service:
enabled: true
serviceMonitor:
enabled: true
additionalLabels:
release: prometheus-stack
sources: []
project: default
5.2/ Collection de log
Bon c’est beaucoup moins sexy que les beaux dashboards de metrics, mais ça reste utile.
J’avoue que pour le sujet, je ne me casse pas trop la tête pour le moment.
J’ai créé deux applications ArgoCD, une pour Loki et une pour Alloy (le remplaçant de Promtail).
Et pour le moment, j’ai pas non plus cherché comment intégrer en IaC cette source de donnée dans Grafana, je l’ai rajouté à la main…
Pour Loki:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: loki
spec:
destination:
namespace: loki
server: https://kubernetes.default.svc
source:
path: ""
repoURL: https://grafana.github.io/helm-charts
targetRevision: 6.53.0
chart: loki
helm:
values: |-
loki:
commonConfig:
replication_factor: 1
storage:
type: "filesystem"
bucketNames:
chunks: chunks
ruler: ruler
admin: admin
schemaConfig:
configs:
- from: "2024-04-01"
store: tsdb
object_store: filesystem
schema: v13
index:
prefix: loki_index_
period: 24h
storage_config:
filesystem:
directory: /tmp/loki/chunks
pattern_ingester:
enabled: true
limits_config:
allow_structured_metadata: true
volume_enabled: true
ruler:
enable_api: true
auth_enabled: false
minio:
enabled: false
deploymentMode: SingleBinary
singleBinary:
replicas: 1
persistence:
storageClass: local-path
accessModes:
- ReadWriteOnce
size: 2Gi
resources:
requests:
cpu: "1"
memory: "1Gi"
limits:
cpu: "2"
memory: "2Gi"
sidecar:
image:
repository: kiwigrid/k8s-sidecar
tag: 1.30.0
resources:
requests:
cpu: 50m
memory: 50Mi
limits:
cpu: 100m
memory: 100Mi
backend:
replicas: 0
read:
replicas: 0
write:
replicas: 0
chunksCache:
allocatedMemory: 500
sources: []
project: default
syncPolicy:
syncOptions:
- CreateNamespace=true
- ServerSideApply=true
Et pour Alloy:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: alloy
spec:
destination:
namespace: loki
server: https://kubernetes.default.svc
source:
path: ""
repoURL: https://grafana.github.io/helm-charts
targetRevision: 1.6.0
chart: alloy
helm:
values: |-
alloy:
configMap:
content: |-
logging {
level = "debug"
format = "logfmt"
}
discovery.kubernetes "pods" {
role = "pod"
}
discovery.relabel "pods" {
targets = discovery.kubernetes.pods.targets
rule {
source_labels = ["__meta_kubernetes_namespace"]
target_label = "namespace"
action = "replace"
}
rule {
source_labels = ["__meta_kubernetes_pod_label_app_kubernetes_io_name"]
target_label = "app"
action = "replace"
}
rule {
source_labels = ["__meta_kubernetes_pod_container_name"]
target_label = "container"
action = "replace"
}
rule {
source_labels = ["__meta_kubernetes_pod_name"]
target_label = "pod"
action = "replace"
}
}
loki.source.kubernetes "pods" {
targets = discovery.relabel.pods.output
forward_to = [loki.process.process.receiver]
}
loki.process "process" {
forward_to = [loki.write.loki.receiver]
stage.drop {
older_than = "1h"
drop_counter_reason = "too old"
}
stage.match {
selector = "{instance=~\".*\"}"
stage.json {
expressions = {
level = "\"level\"",
}
}
stage.labels {
values = {
level = "level",
}
}
}
stage.label_drop {
values = [ "service_name" ]
}
}
loki.write "loki" {
endpoint {
url = "http://loki.loki.svc.cluster.local:3100/loki/api/v1/push"
}
}
mounts:
varlog: true
dockercontainers: true
resources:
limits:
cpu: 200m
memory: 128Mi
requests:
cpu: 100m
memory: 128Mi
sources: []
project: default
syncPolicy:
syncOptions:
- CreateNamespace=true
- ServerSideApply=true
La source de donnée à ajouter dans grafana est http://loki.loki.svc.cluster.local:3100
En vrai les logs centralisés c’est très bien, mais c’est un peu de boulot pour que ça soit propre.
Les configurations de cette sous section était fortement inspirée par cet article de blog
6/ Cloud Native PG
L’installation n’est pas si compliquée. Mais l’usage et la configuration de ce magnifique outil méritera un article à part. (C’est magique, Cloud Native PG)
Petite note: Un cluster est sensé être dédié à une base
7/ Git - Forgejo
Pour déployer Forgejo
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: forgejo
namespace: argocd
spec:
destination:
namespace: forgejo
server: https://kubernetes.default.svc
source:
path: .
repoURL: https://code.forgejo.org/forgejo-helm/forgejo-helm.git
targetRevision: v16.0.2
helm:
values: |-
httpRoute:
enabled: True
parentRefs:
- name: traefik-gateway
namespace: kube-system
port: 3000
hostnames:
- git.hetzner.htnl.fr
global:
storageClass: local-path
gitea:
config:
APP_NAME: "My humble forge"
admin:
email: ENTER_YOUR_EMAIL
username: gitea_admin
sources: []
project: default
syncPolicy:
syncOptions:
- CreateNamespace=true
Et on va rajouter l’entrée dans Traefik Gateway
- name: git-https
protocol: HTTPS
port: 8443
hostname: git.hetzner.htnl.fr
tls:
certificateRefs:
- group: ""
kind: Secret
name: git-htnl-fr-tls
mode: Terminate
allowedRoutes:
namespaces:
from: All
-2/ Améliorations
Toute cette mise en place est vraiment plaisante à faire. Mais il y a beaucoup de chose à redire sur tout ça:
-
Ressources
Les outils de monitoring sont vraiment bien pour ça. Il va falloir optimiser, voir où sont les abus . Et le premier que je vois, c’est l’usage en monitoring pour une infra si petite. Donc je pense qu’un des premiers trucs à faire c’est limiter les ressources. Ensuite, on va diviser les usages : l’application argocd prometheus-stack est sympa, mais elle fait venir grafana et prometheus en un seul tas. Je pense qu’il serait plus sympa de diviser ça en grafana d’un côté et prometheus d’un autre
-
mTLS de partoutttttt
Je sais qu’un des trucs que j’avais aimé faire quand je bidouillais avec mes podman, c’était la mise en place de certains services derrière du mTLS en plus de leur authentification classique. Soyons honnête ça rassure, ça évite l’usage à gogo d’un {tail,head}scale sur les machines d’usage.
-
Remplacer ArgoCD
J’ai lu à plein d’endroit des choses sur ‘flux’ qui ont l’air coule