Aller au contenu principal

3 articles tagués avec « docker »

Voir tous les tags

· 6 minutes de lecture
TheBidouilleur

Introduction

Depuis que le mouvement DevOps a commencé (ou plutôt Platform engineering), on met le thème de la haute-disponibilité sur le devant de la scène. Et une des solutions les plus polyvalentes pour faire de la haute disponibilité est de créer des clusters d'applications. (et de facto : des conteneurs)

J'ai donc administré un cluster Swarm pendant quelques années et je suis récemment passé sous Kubernetes (k3s pour être précis). Et à force d'avoir des clusters contenant plusieurs centaines de conteneurs, on en oublie la maintenance et la mise à jour.

Et dans cet article, on va parler des mises à jour.

Solutions de mise à jour de conteneur hors cluster

WatchTower

Je pense que la solution la plus connue est Watchtower

Watchtower est facile d'utilisation et se base (comme beaucoup d'autre) sur les labels. Un label permet de définir quelques paramètres et d'activer (ou de désactiver) la surveillance des mises à jour.

Mettre à jour, ce n'est pas toujours bien…

Attention à ne pas mettre à jour automatiquement des programmes sensibles ! Nous ne pouvons pas vérifier ce que contient une mise à jour si elle ne va pas casser quelque chose. Il ne tient qu'à vous de choisir les applications à surveiller, et à déclencher une mise à jour ou non.

WatchTower vous notifiera de plusieurs manières :

  • email
  • slack
  • msteams
  • gotify
  • shoutrrr

Et parmi ces méthodes, vous n'avez pas que des solutions propriétaires, libre à vous d'héberger un shoutrrr, un gotify ou d'utiliser votre smtp pour que ces informations ne sortent pas de votre SI ! (Je reproche beaucoup l'usage de msteams, slack, discord pour recevoir ses notifications)

WatchTower scannera les mises à jour de manière régulière (configurable).

container-updater (de @PAPAMICA)

La solution la plus fournie/complexe n'est pas toujours la meilleure. Papamica a mis en place un script bash répondant à ses besoins précis (que beaucoup d'autres personnes doivent avoir) : un système de mise à jour le notifiant par Discord et Zabbix.

Celui-ci se base aussi par les labels et prend également en charge le cas où l'on veut mettre à jour par docker-compose. (au lieu de faire un docker pull, docker restart comme Watchtower)

labels:
- "autoupdate=true"
- "autoupdate.docker-compose=/link/to/docker-compose.yml"

Même si je ne m'en sers pas, j'ai eu une époque où j'utilisais Zabbix et où j'avais le besoin d'être notifié sur mon Zabbix. (qui lui me notifiait par Mail/Gotify)

Papamica précise qu'il compte ajouter le support de registre privé (pour le moment que le github registry ou dockerhub) ainsi que d'autres méthodes de notification.

Solutions pour Swarm

Swarm est surement l'orchestrateur de conteneur sur lequel j'ai pris le plus de plaisir : c'est **simple** ! On apprend vite, on découvre vite et on a vite des résultats. Mais j'ai déjà écrit des éloges à Swarm dans un autre article...

Sheperd

Ce que j'aime dans le programme de Papamica (et qui va avec Sheperd) c'est qu'on garde le bash comme langage central. Un langage que l'on connait tous dans les grandes lignes grâce à Linux, et que l'on peut lire et modifier pour peu qu'on y prenne le temps.

Le code de Sheperd ne fait que ~200 lignes et fonctionne très bien comme ça.

version: "3"
services:
...
shepherd:
build: .
image: mazzolino/shepherd
volumes:
- /var/run/docker.sock:/var/run/docker.sock
deploy:
placement:
constraints:
- node.role == manager

Celui-ci acceptera plusieurs registres privés, ce qui donne un bel avantage comparé aux autres solutions présentées. Exemple :

    deploy:
labels:
- shepherd.enable=true
- shepherd.auth.config=blog

Sheperd n'inclut pas (par défaut) de système de notification. C'est pourquoi son créateur a décidé de proposer un sidecar Apprise en alternative. Qui peut rediriger vers beaucoup de choses comme Telegram, SMS, Gotify, Mail, Slack, msteams etc....

Je pense que c'est la solution la plus simple et la plus polyvalente. J'espère qu'on la retrouvera dans d'autres contextes. (mais je ne m'étale pas trop sur le sujet, j'aimerais bien écrire un article sur ça).

J'ai utilisé Sheperd pendant une bonne période et je n'ai eu aucun soucis.

Solutions pour Kubernetes

Pour Kubernetes, on commence à perdre en simplicité. D'autant plus qu'avec l'option imagePullPolicy: Always, il suffit juste de redémarrer un pod pour récupérer la dernière image avec le même tag. Pendant un long moment, j'ai utilisé ArgoCD pour mettre à jour mes configurations et re-déployer mes images à chaque mise à jour sur Git.

Mais ArgoCD ne sert qu'à mettre à jour la configuration et non pas l'image. La méthodologie est incorrecte et il est nécessaire de trouver un outil adapté pour ça.

Keel.sh

Keel est un outil répondant au même besoin : Mettre à jour les images des pods. Mais il incorpore plusieurs fonctionnalités qu'on ne retrouve pas ailleurs.

Keel

Si on souhaite garder le même fonctionnement que les alternatives (c.-à-d régulièrement vérifier les mises à jour), c'est possible :

metadata:
annotations:
keel.sh/policy: force
keel.sh/trigger: poll
keel.sh/pollSchedule: "@every 3m"

Mais là où Keel brille, c'est qu'il propose des triggers et des approvals.

Un trigger, c'est un événement qui va déclencher la mise à jour de Keel. On peut imaginer un webhook provenant de Github, Dockerhub, Gitea qui va déclencher la mise à jour du serveur. (On évite donc une crontab régulière et on économise des ressources, du trafic et du temps) Comme l'usage de webhook s'est beaucoup répandu dans les systèmes de CICD, on peut coupler ça à de nombreux cas d'usages.

Les approvals, c'est la petite perle qui manquait aux autres outils. En effet, j'ai précisé que mettre à jour des images : c'est dangereux et il faut ne pas cibler des applications sensibles dans les mises à jour automatiques. Et c'est juste en réponse à ça que Keel a développé les approvals.

L'idée est de donner l'autorisation à Keel de mettre à jour le pod. On peut de ce fait choisir le moment et vérifier manuellement.

Je trouve quand même dommage qu'on ait Slack ou MSTeams d'imposé pour les approvals, c'est alors une fonctionnalité que je n'utiliserai pas.

Une UI

Alors pour le moment, j'utilise Keel sans son interface web, il se peut qu'elle apporte de nouvelles fonctionnalités, mais j'aimerais éviter une énième interface à gérer.

Conclusion

Mettre à jour un conteneur, ce n'est pas si simple que ça quand on cherche l'automatisation et la sécurité. Si aujourd'hui, je trouve que Keel correspond à mes besoins, j'ai l'impression que les outils se ressemblent sans proposer de réelles innovations. (j'envisage d'aborder le principe de canary un jour) J'espère découvrir de nouvelles solutions prochainement en espérant qu'elles collent plus à mes besoins.

· 8 minutes de lecture
TheBidouilleur

[ Cet article provient de mon ancien-blog, celui-ci sera également disponible dans la partie "Documentation" du site ]

Introduction

Depuis que jai commencé l'informatique (depuis un peu moins d'une dizaine d'année), je ne me suis jamais préoccupé de comment je visualisais mes logs. Un petit view par ci, un gros grep par là.. mais aucune gestion avancée.

J'ai basé ma supervision sur Zabbix et Grafana qui m'affichent les metriques de chaque machine virtuelle individuellement. Et même si c'est bien pratique, je n'ai presque aucun visuel sur l'état de mes applications ! J'ai donc décidé de me renseigner sur Graylog et Elastic Search proposant un stack assez fiable et facile à mettre en place. Puis en voyant les ressources demandées, j'ai remis ce besoin à "plus tard", et j'ai remis "plus tard" à l'année prochaine.. Et ainsi de suite !

2 ans plus tard...

Aujourd'hui (Decembre 2021), une grosse faille 0day est dévoilée concernant Log4J, et on ne parle pas d'une "petite" faille, c'est une bonne grosse RCE comme on les aime !

Je ne suis pas concerné par Log4J, ce n'est pas utilisé dans Jenkins, et je n'ai aucune autre application basée sur Java ouverte sur internet. Mais j'aurai bien aimé savoir si mon serveur a été scanné par les mêmes IP que l'on retrouve sur les listes à bannir. Et c'est avec cet évenement que j'ai décidé de me renseigner sur "Comment centraliser et visualiser ses logs?".

Le choix du stack

Un stack est un groupement de logiciel permettant de répondre à une fonction. Un exemple classique est celui du stack "G.I.T." (et non pas comme l'outil de versioning!) :

  • Grafana
  • Influxdb
  • Telegraf

C'est un stack qui permet de visualiser les mectriques de différentes machines, InfluxDB est la base de donnée stockant les informations, Telegraf est l'agent qui permet aux machines d'envoyer les métriques, et Grafana est le service web permettant de les visualiser.

Comme dit dans l'introduction, j'utilise Zabbix qui me permet de monitorer et collecter les metriques, et j'y ai couplé Grafana pour les afficher avec beaucoup de paramètrages.

Dans la centralisation de logs (et la visualisation), on parle souvent du stack suivant:

ELK:

  • ElasticSearch
  • Logstash
  • Kibana

Mais ce stack n'est pas à déployer dans n'importe quel environnement, il est efficace, mais très lourd.

Dans ma quête pour trouver un stack permettant la centralisation de logs, j'apprécierai utiliser des services que je dispose déjà.
Et voici le miracle à la mode de 2021 ! Le Stack GLP : Grafana, Loki, Promtail.

Stack GLP

Là où j'apprécie particulièrement ce stack, c'est qu'il est léger. Beaucoup plus léger que ELK qui, même si très efficace, demande beaucoup.

De même que Graylog2 + Elastic Search (une très bonne alternative) qui demande presque un serveur baremetal low-cost à lui seul.

Alors que Grafana / Loki ne demanderont que 2Go pour fonctionner efficacement et sans contraintes. (Grand maximum, à mon échelle : j'utiliserai beaucoup moins que 2Go)

Installer notre stack

Je pars du principe que tout le monde sait installer un Grafana, c'est souvent vers ce service que les gens commencent l'auto-hebergement (en même temps, les graphiques de grafana sont super sexy !).

Mais si vous n'avez pas encore installé votre Grafana (dans ce cas, quittez la salle et revenez plus tard), voici un lien qui vous permettra de le faire assez rapidement

Par simplicité, je ne vais pas utiliser Docker dans cette installation.

Partie Loki

J'ai installé Loki sur un conteneur LXC en suivant le guide sur le site officiel ici. Je passe par systemd pour lancer l'executable, et je créé à l'avance un fichier avec le minimum syndical (qui est disponible sur le github de Grafana)

auth_enabled: false

server:
http_listen_port: 3100
grpc_listen_port: 9096

common:
path_prefix: /tmp/loki
storage:
filesystem:
chunks_directory: /tmp/loki/chunks
rules_directory: /tmp/loki/rules
replication_factor: 1
ring:
instance_addr: 127.0.0.1
kvstore:
store: inmemory

schema_config:
configs:
- from: 2020-10-24
store: boltdb-shipper
object_store: filesystem
schema: v11
index:
prefix: index_
period: 24h

Je n'ai pas pris la peine d'activer l'authentification en sachant que je suis dans un LAN avec uniquement mes machines virtuelles. Je considère pas que mon Loki comme un point sensible de mon infra.

Après seulement 2-3 minutes de configuration, notre Loki est déjà disponible !

On peut dès maintenant l'ajouter en tant que datasource sur notre Grafana :

(J'utilise localhost car la machine possédant le grafana héberge également le Loki)

Il se peut que Grafana rale un peu car notre base de donnée Loki est vide.

Partie Promtail

Promtail est l'agent qui va nous permettre d'envoyer nos logs à Loki, j'ai écris un role Ansible assez simple me permettant d'installer notre agent sur de nombreuses machines en surveillant les logs provenant de Docker, varlog et syslog.

Voici ma template Jinja2 à propos de ma configuration :

server:
http_listen_port: 9080
grpc_listen_port: 0

positions:
filename: /tmp/positions.yaml

clients:
{% if loki_url is defined %}
- url: {{ loki_url }}
{% endif %}


scrape_configs:


- job_name: authlog
static_configs:
- targets:
- localhost
labels:
{% if ansible_hostname is defined %}
host: {{ ansible_hostname }}
{% endif %}
job: authlog
__path__: /var/log/auth.log


- job_name: syslog
static_configs:
- targets:
- localhost
labels:
{% if ansible_hostname is defined %}
host: {{ ansible_hostname }}
{% endif %}
job: syslog
__path__: /var/log/syslog

- job_name: Containers
static_configs:
- targets:
- localhost
labels:
{% if ansible_hostname is defined %}
host: {{ ansible_hostname }}
{% endif %}
job: containerslogs
__path__: /var/lib/docker/containers/*/*-json.log

- job_name: DaemonLog
static_configs:
- targets:
- localhost
labels:
{% if ansible_hostname is defined %}
host: {{ ansible_hostname }}
{% endif %}
job: daemon
__path__: /var/log/daemon.log

Si vous n'êtes pas à l'aise avec des templates Jinja2, vous trouverez une version "pure" de la config ici

Vous pouvez bien evidemment adapter cette template à vos besoins. Mon idée première est d'avoir une "base" que je peux mettre sur chaque machine (en sachant aussi que si aucun log n'est disponible, comme pour Docker, Promtail ne causera pas une erreur en ne trouvant pas les fichiers)

Une fois Promtail configuré, on peut le démarrer : via l'executable directement :

/opt/promtail/promtail -config.file /opt/promtail/promtail-local-config.yaml

ou via systemd (automatique si vous passez par mon playbook) :
systemctl start promtail

Une fois cet agent un peu partout, on va directement aller s'amuser sur Grafana !

Faire des requetes à Loki depuis Grafana

On va faire quelque chose d'assez contre-intuitif : nous n'allons pas commencer par faire un Dashboard : on va d'abord tester nos requetes ! Scrollez pas, je vous jure que c'est la partie la plus fun !

Sur Grafana, nous avons un onglet "Explore". Celui-ci va nous donner accès à Loki en écrivant des requetes, celles-ci sont assez simple, et surtout en utilisant l'outil "click-o-drome" en dépliant le Log Browser

Pardon j'ai un chouïa avancé sans vous...

Avec la template que je vous ai donné, vous aurez 4 jobs :

  • daemon
  • authlog
  • syslog
  • containersjobs

Ces jobs permettent de trier les logs, on va tester ça ensemble. Nous allons donc selectionner la machine "Ansible", puis demander le job "authlog". Je commence par cliquer sur Ansible, puis Authlog. Grafana me proposera exactement si je souhaite choisir un fichier spécifique. Si on ne précise pas de fichier(filename) Grafana prendra tous les fichiers (donc aucune importance si nous n'avons qu'un seul fichier)

(vous remarquerez plus tard que dès notre 1ere selection, grafana va cacher les jobs/hôte/fichier qui ne concernent pas notre début de requete)

En validant notre requete (bouton show logs)

Nous avons donc le résultat de la requete vers Loki dans le lapse de temps configuré dans Grafana (1h pour moi). Mon authlog n'est pas très interessant, et mon syslog est pollué par beaucoup de message pas très pertinents.

Nous allons donc commencer à trier nos logs !

En cliquant sur le petit "?" au dessus de notre requete, nous avons une "cheatsheet" résumant les fonctions basiques de Loki. Nous découvrons comment faire une recherche exacte avec |=, comment ignorer les lignes avec != et comment utiliser une expression regulière avec |~

Je vous partage également une cheatsheet un peu plus complète que j'ai trouvé sur un blog : ici

Ainsi, on peut directement obtenir des logs un peu plus colorés qui nous permettrons de cibler l'essentiel !

(L'idée est de cibler les logs sympas avec les couleurs qui vont avec)

Conclusion

Si on entend souvent parler de la suite ELK, ça n'est pas non-plus une raison pour s'en servir à tout prix ! Loki est une bonne alternative proposant des fonctionnalitées basiques qui suffiront pour la plupart.

· 6 minutes de lecture
TheBidouilleur

[ Cet article provient de mon ancien-blog, celui-ci sera également disponible dans la partie "Documentation" du site ]

Docker Swarm

Introduction

Le monde de la conteneurisation a apporté de nombreuses choses dans l'administration système, et a actualisé le concept de DevOps. Mais une des choses principales que nous apporte les conteneurs (et particulièrement Docker), c'est l'automatisation. Et bien que Docker soit déjà complet avec le déploiement de service, on peut aller un peu plus loin en automatisant la gestion des conteneurs ! Et pour répondre à ça : Docker Inc. propose un outil adapté pour l'orchestration automatique d'instance : Docker Swarm.