|
|
#+SETUPFILE: /home/vaab/dev/el/org-html-themes/setup/theme-readtheorg.setup #+PROPERTY: Effort_ALL 0 0:30 1:00 2:00 0.5d 1d 1.5d 2d 3d 4d 5d #+PROPERTY: Max_effort_ALL 0 0:30 1:00 2:00 0.5d 1d 1.5d 2d 3d 4d 5d #+PROPERTY: header-args:python :var filename=(buffer-file-name) #+PROPERTY: header-args:sh :var filename=(buffer-file-name) #+TODO: TODO WIP BLOCKED POSTPONED | DONE CANCELED #+LATEX_HEADER: \usepackage[margin=0.5in]{geometry} #+LaTeX_CLASS: article #+OPTIONS: H:8 ^:nil prop:("Effort" "Max_effort") tags:not-in-toc #+COLUMNS: %50ITEM %Effort(Min Effort) %Max_effort(Max Effort)
#+begin_LaTeX \hypersetup{ linkcolor=blue, pdfborder={0 0 0 0} } #+end_LaTeX
#+TITLE: Architecture 0k.io
#+LATEX: \pagebreak
* Process de déploiement
Description du process de déploiement pour une nouvelle installation
** Base myc
*** Qu'est ce c'est ?
A partir d'une debian 9, on peut installer la machine pour être prête à utiliser un déploiement myc.
Une fois executé, la machine aura toute les deps pour lancer une commande compose qui fera peut-être appel à des registry de mycéliandre. Un compose de base est aussi proposé.
*** Déploiement
**** Hôte linux base debian 9 et debian 10
***** Accès ssh standardisé
Via la commande =0km=, depuis votre poste, permet de standardiser l'accès avec vos clés SSH, et positionner le nom de domaine si nécessaire.
#+BEGIN_SRC sh 0km vps-setup HOST #+END_SRC
Note: ceci fonctionnera que si vous avez un fichier de configuration dans =/etc/0km/config.yml= (si vous allez l'utiliser en root) ou dans =~/.config/0km/config.yml= autrement. Ce fichier doit au moins contenir une clé ssh (ou plusieurs) ainsi:
#+begin_src yaml ssh-access: public-keys: - ssh-rsa AAAAB3NzaC1yc2EAAAAD...qGy20KlAOGPf nom_clef #+end_src
***** Déploiement de la solution
Depuis le VPS, en root:
#+BEGIN_SRC sh export WITHOUT_DOCKER_CLEAN=1 ## only if you want to remove docker clean from cron wget https://justodooit.myceliandre.fr/r/deploy -qO - | bash #+END_SRC
Si vous souhaitez positionner le nom de domaine:
#+BEGIN_SRC sh export WITHOUT_DOCKER_CLEAN=1 ## only if you want to remove docker clean from cron export DOMAIN=myhost.com wget https://justodooit.myceliandre.fr/r/deploy -qO - | bash #+END_SRC
**** Hôte macosx
- install bash, docker - Uncheck "Securely store docker logins in macOS keychain"
*** Ce que cela fait **** Mettre la machine en état charm-ready
- installation du strict minimu pour lancer les =charms=
- téléchargement de la dernière version des =0k-charms= (collection de recettes d'installation et de gestion de docker)
**** Mettre la machine en état compose ready (notre docker qui va bien)
via le lancement du charm =docker-host= qui installe:
- docker, docker-compose, compose avec des versions qui vont bien - paquets maisons (kal-scripts, 0k-manage, 0k-pgm, lxc-scripts, 0k-docker) - accès pour le repository deb de kalysto.org - clé SSH pour repos git.kal.fr - login sur le docker registry docker.0k.io
**** Commandes spécifique à myc
- login sur le registry myc - téléchargement du compose de base dans =/opt/apps/myc-deploy=
** Modification du compose
*** Qu'est-ce que c'est ?
Il y a des update client à faire souvent sur le compose. Cette étape doit être externalisée au plus possible, sont consigné ici ce qu'il faut encore faire à la main.
*** Commande
**** Création de clé OVH pour letsencrypt/lexicon
Ceci n'est nécessaire qu'en cas d'utilisation de la méthode DNS pour valider la possession du domaine auprès de letsencrypt.
#+BEGIN_SRC shell APPLICATION_KEY=XXXXXXXXXXXXXXXXX REDIR_WEBSITE=https://0k.io
req=$(cat <<EOF { "accessRules": [ { "method": "GET", "path": "/*" }, { "method": "POST", "path": "/*" }, { "method": "PUT", "path": "/*" }, { "method": "DELETE", "path": "/*" } ], "redirection":"$REDIR_WEBSITE" } EOF ) res=$(curl -X POST \ -H "X-Ovh-Application: ${APPLICATION_KEY}" \ -H "Content-type: application/json" \ https://eu.api.ovh.com/1.0/auth/credential \ -d "$req") consumer_key=$(echo "$res" | jq -r .consumerKey) validation_url=$(echo "$res" | jq -r .validationUrl) echo "Visit: $validation_url" echo "ConsumerKey: $consumer_key" #+END_SRC
Il s'agit alors de remplir le compose.yml
#+BEGIN_SRC yaml ovh: ## see: https://api.ovh.com/g934.first_step_with_api entrypoint: ovh-eu application: key: XXXXXXXXXXXXXXXX secret: YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY consumer_key: ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ #+END_SRC
Puis de valider que tout est ok:
#+BEGIN_SRC shell check-compose-ovh-credentials compose.yml #+END_SRC
** Lancement/Deploy de service odoo
*** Qu'est ce que c'est ?
A partir d'une base myc, cette commande permet d'envoyer la construction et l'assemblage de tous les services décrit dans le =compose.yml= fourni par défaut.
*** commandes
#+BEGIN_SRC sh cd /opt/apps/myc-deploy compose --debug up odoo frontend #+END_SRC
De manière générale:
#+BEGIN_SRC sh compose [--debug] up [SERVICES...] #+END_SRC
*** Ce que ça fait
Les charms vont s'occuper de séparer la config des donnée, de tout stocker dans =/srv/datastore=, il vont s'occuper de la petite maintenance:
- le charm postgres (qui est une dépendance du service odoo) va créer un mot de passe et le filer à odoo - le charm apache (qui implémente le service frontend) va créer les fichiers de conf apache pour déclarer un virtualhost et mettre les clés SSL s'il y a lieu.
* Gestion
Description des process de gestion d'une installation existante.
** Connection aux serveurs
*** installation commande =st=
Le mieux est d'utiliser la commande =st= que l'on peut installer ainsi sur un poste linux ayant =apt=:
Se mettre en =root=:
#+begin_src sh cat <<'EOF' > /usr/local/bin/st #!/bin/bash
echo "Trying mosh to $1" TERM=xterm-256color mosh "$1" -- bash -c "tmux attach || { tmux; }" if [ "$?" == "5" ]; then echo "Fallback to ssh $1" ssh "$1" -tM "TERM=xterm-256color tmux attach || TERM=xterm-256color tmux" fi EOF chmod +x /usr/local/bin/st apt install mosh #+end_src
*** utilisation de la commande =st=
=st= utilise =ssh= ou =mosh= et se met dans un =tmux= sur la destination.
#+begin_src sh st root@monvps.fr #+end_src
On note qu'il faut penser à mettre les clé SSH sur la destination.
** Mise à jour de l'ensemble
Pour mettre à jour un VPS:
#+BEGIN_SRC sh myc-update #+END_SRC
Cette commande va ré-appliquer l'installation du charm =docker-host= qui installe ou met à jour chaque composant.
** Gestion des dockers *** Relancement
si on veut relancer parce que le compose a changé :
on fait pareil qu'au lancement : lors du "up", docker-compose se rend compte que la définition des services a changé et relance les docker voulu.
*** Arrêt
#+BEGIN_SRC sh compose --debug down #+END_SRC
*** Voir les logs
#+BEGIN_SRC sh cd /opt/apps/myc-deploy compose --debug logs odoo #+END_SRC
*** Obtenir les IPs des dockers
#+BEGIN_SRC sh docker-ip #+END_SRC
** Par services
*** odoo **** Backups ***** Backuping odoo account (filestore and database)
There are still some quirks, so be sure: - to change your current directory to =/opt/apps/myc-deploy= - your odoo instance should be already up. - to have =admin-password= defined in your =compose.yml=, in your =odoo= service's =options=.
#+BEGIN_SRC yaml odoo: options: admin-password: XXXXXX #+END_SRC
#+BEGIN_SRC sh MYODOOSERVICENAME=odoo DBNAME="$MYODOOSERVICENAME" OUTPUTFILE=backup-odoo.zip cd /opt/apps/myc-deploy && compose save "$MYODOOSERVICENAME" "$DBNAME" "$OUTPUT_FILE" #+END_SRC
The backup file should be in the same directory.
***** Restoring odoo account (filestore and database)
There are still some quirks, so be sure: - to change your current directory to =/opt/apps/myc-deploy= and put your backup file in the same directory - your odoo instance should be already up. - to have =admin-password= defined in your =compose.yml=, in your =odoo= service's =options=.
#+BEGIN_SRC yaml odoo: options: admin-password: XXXXXX #+END_SRC
*IMPORTANT* you might want to consider the usage of docker-cutoff if you are restoring a production odoo onto a dev or staging odoo that you don't want to allow to go mess around with sending mails or fetching mails.
#+BEGIN_SRC yaml docker-cutoff 25 993 465 #+END_SRC
These are the normal loading instructions:
#+BEGIN_SRC sh MYODOOSERVICENAME=odoo DBNAME="$MYODOOSERVICENAME" SOURCEFILE=backup-odoo.zip cd /opt/apps/myc-deploy && compose load "$MYODOOSERVICENAME" "$SOURCEFIE" "$DBNAME" #+END_SRC
***** charger un dump SQL dans odoo
Supporte *.dump ou sql (non compressé), *.gz ou *.bz2:
#+BEGIN_SRC sh compose load-db odoo MONFICHIER.dump.bz2 #+END_SRC
***** sauvegarder dump db de odoo
Pour l'instant on passe par pgm
#+BEGIN_SRC sh compose save-db odoo MONFICHIER.dump.bz2 #+END_SRC
**** Update de modules
#+BEGIN_SRC sh compose update odoo MABASE [MODULE [MODULE ...]] #+END_SRC
**** lancement d'une commande odoo
Si l'ensemble n'est pas up:
#+BEGIN_SRC sh compose --debug run odoo --help #+END_SRC
**** Mod dev d'odoo
Il est souhaitable de lancer odoo en mode dev avec un terminal prêt à accueillir un pdb par exemple, et pouvoir changer facilement la ligne de commande.
On peut tout a fait lancer odoo directement, par exempe:
#+BEGIN_SRC sh compose run --rm --use-aliases odoo --dev=wdb --config=/opt/odoo/auto/odoo.conf #+END_SRC
On récupère ainsi tous les volumes et autres options (sauf ce qui est dans =command:=) défini dans =compose.yml=.
Un problème cependant: si on utilise apache comme frontend, celui-ci ne pourra pas résoudre le nom =odoo= à cause de problèmes autour de =docker-compose= et/ou =docker network=. En effet, si on fait un =up= comme d'habitude, et qu'on souhaite simplement arrêter le service classique pour ensuite le remplacer par la commande au dessus, cela ne fonctionnera pas. En effet, l'alias réseau =odoo= n'est plus adjoignable (même avec les commandes =docker network {dis,}connect=), et même si le container original de odoo est détruit ou éjecté du réseau, ou que l'on essaye de connecter soi-même le nouveau container.
Un moyen (bancal) de passer outre cependant: - =down= pour fermer le réseau - =create= sur le service apache, puis =restart=. - enfin, le =run= tel que décrit au dessus
Soit:
#+BEGIN_SRC sh compose down && compose create apache && compose restart apache && compose run --rm --use-aliases odoo --dev=wdb --config=/opt/odoo/auto/odoo.conf #+END_SRC
Le container odoo crée par la dernière ligne se retirera proprement des tables DNS interne, et donc peut tout a fait être relancée autant de fois que l'on souhaitera.
*** letsencrypt
Le service letsencrypt fourni des certificat SSL à la demande et les renouvelle automatiquement.
**** configuration dans compose ***** Authentification HTTP
Il n'y a besoin d'aucune option dans le service =letsencrypt=.
Le charm =apache= doit trouver un service utilisant le charm =letsencrypt=, cette connection se fera automatiquement si un servce de type =letsencrypt= est lancé soit parce que directement mentionné dans la racine ou dans une relation explicite.
La relation construite automatiquement (ou manuellement) d'un service =apache= vers un service =letsencrypt= s'appelle =cert-provider=.
Une fois que ce service est relié à apache, on peut s'en servir comme clé dans la configuration =ssl= des relations =*-->web-proxy-->apache=.
Par défaut, =apache= utilisera du ssl pour tout se virtual-host s'il trouve un =cert-provider= à disposition.
Aussi la configuration suivante est suffisante pour avoir un site publié en SSL: #+BEGIN_SRC yaml
www.mydomain.org: charm: odoo
apache:
letsencrypt:
#+END_SRC
Cela équivaut à :
#+BEGIN_SRC yaml
www.mydomain.org: charm: odoo relations: web-proxy: myapache: domain: www.mydomain.org ssl: myletsencrypt: challenge-type: http
myapache: charm: apache
myletsencrypt: charm: letsencrypt
#+END_SRC
***** Authentification DNS ****** créer un nouveau jeu de clé OVH pour l'authentification DNS
When =letsencrypt= is setup and running::
#+BEGIN_SRC sh compose --debug add letsencrypt DOMAIN [DOMAIN...] #+END_SRC
Exemple de setup (dans =compose.yml=):
#+BEGIN_SRC yaml letsencrypt: options: email: admin@0k.io ovh: entrypoint: ovh-eu application: key: ZZZ secret: XXX consumer_key: YYYYY #+END_SRC
Le résultat est dans =/srv/datastore/data/letsencrypt/etc/letsencrypt/live/DOMAIN1= Il apparaît entre 30sec et 1 minute après la demande.
****** Vérifier que le jeu de clé ovh est bon
Cette commande prend le compose yml et va vérifier que les accès sont valides:
#+BEGIN_SRC shell check-compose-ovh-credentials compose.yml #+END_SRC
**** Utilisation manuelle
On peut utiliser le service =letsencrypt= manuellement
***** creation d'un certificat http
#+BEGIN_SRC shell compose crt letsencrypt create DOMAIN [DOMAIN...] #+END_SRC
Cette action crée un certificat (et force le renouvellement si existant).
On peut y injecter une configuration via =--add-compose-content= si nécessaire::
#+BEGIN_SRC shell compose --add-compose-content=' letsencrypt: ovh: ## see: https://api.ovh.com/g934.first_step_with_api entrypoint: ovh-eu application: key: XXX secret: YYY consumer_key: ZZZ challenge-type: dns #renew-before-expiry: 30' crt letsencrypt create DOMAIN [DOMAIN...] #+END_SRC
***** Renew de tous les certificats
Cela renew uniquement les certificats dont la date de validité est inférieure à 30j
#+BEGIN_SRC shell compose crt letsencrypt renew #+END_SRC
***** Liste des certificats gérés et infos connexes
#+BEGIN_SRC shell compose run letsencrypt crt list #+END_SRC
***** suppression d'un certificat
#+BEGIN_SRC shell compose run letsencrypt certbot delete --cert-name DOMAIN #+END_SRC
*** apache
**** Utiliser letsencrypt
Pour ajouter la fonctionalité de génération automatique de certificat via le service =letsencrypt=, il faut: - déclarer un service =letsencrypt= si cela n'est pas déjà fait - le lier au charm apache via une relation =cert-provider=:
#+BEGIN_SRC yaml frontend: charm: apache relations: cert-provider: letsencrypt
letsencrypt: ... #+END_SRC
Et l'on peut alors utiliser la valeur =letsencrypt= (le nom du service qui implémente qui est en relation =cert-provider= avec apache) dans le champ =ssl=::
#+BEGIN_SRC yaml web-proxy: apache: ... ssl: letsencrypt #+END_SRC
**** Changer les clés SSL
Voici un exemple de ce qu'on peut mettre dans les options de la relation apache pour déclarer le certificat que l'on souhaite:
#+BEGIN_SRC yaml
ssl: ca-cert: -----BEGIN CERTIFICATE----- MIIF6TCCA9GgAwIBAgIQBeTcO5Q4qzuFl8umoZhQ4zANBgkqhkiG9w0BAQwFADCB iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl ... m9T8bJUox04FB6b9HbwZ4ui3uRGKLXASUoWNjDNKD/yZkuBjcNqllEdjB+dYxzFf BT02Vf6Dsuimrdfp5gJ0iHRc2jTbkNJtUQoj1iM= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIFdzCCBF+gAwIBAgIQE+oocFv07O0MNmMJgGFDNjANBgkqhkiG9w0BAQwFADBv MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFk ... Le9Gclc1Bb+7RrtubTeZtv8jkpHGbkD4jylW6l/VXxRTrPBPYer3IsynVgviuDQf Jtl7GQVoP7o81DgGotPmjw7jtHFtQELFhLRAlSv0ZaBIefYdgWOWnU914Ph85I6p 0fKtirOMxyHNwu8= -----END CERTIFICATE----- cert: | -----BEGIN CERTIFICATE----- MIIF/TCCBOWgAwIBAgIRALUydpTpCApfYMuJchDJv5AwDQYJKoZIhvcNAQELBQAw XzELMAkGA1UEBhMCRlIxDjAMBgNVBAgTBVBhcmlzMQ4wDAYDVQQHEwVQYXJpczEO ... lIxY9HJanHrWvjiz7+eToxXpZJtAPXTx5hxzcJrtWROlq7IJCMIhzr/EVA37jTCk Xs5S6mr0T6Dqx6MQkPATSsEEJlLH5wq3DxXQcrMqnM/WHMRYUCkoTl37sXplflHe jw== -----END CERTIFICATE----- key: | -----BEGIN PRIVATE KEY----- MIIJRQIBADANBgkqhkiG9w0BAQEFAASCCS8wggkrAgEAAoICAQDONqqTCS4CiSi/ XeNpp2nUsq1299spGc7mlRs+PDrXNHscB5lUB5/yo2yEetYXrJacQ8n4NV9hkID5 ... 44eHDYsofcnRbidGR+QT8PQgiiDNCkbpi2u4QnLTs0w4oW+53ZTyHYEYF2rcLbIb vRt4kR4KG6ULXrmsRA4WQjBDJ9vZw2aK+w== -----END PRIVATE KEY-----
#+END_SRC
**** Ajouter des rêgles particulière de apache
#+BEGIN_SRC yaml relations: web-proxy: apache: ... apache-custom-rules: | RewriteEngine On RewriteCond %{HTTPS} off RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=302,L,QSA]
#+END_SRC
**** Vérification des derniers logs de renouvellement automatique
#+BEGIN_SRC shell tail -f /srv/datastore/data/cron/var/log/cron/letsencrypt-renew_script.log -n 200 #+END_SRC
*** postgres
**** utilisation de pgm
récupérer l'IP du docker postgres via =docker-ip=
#+BEGIN_SRC sh PGHOST=172.19.0.2 PGUSER=postgres pgm ls #+END_SRC
**** base corrompue, réparation
Il s'agit de lancer un =pg_resetwal=, il faut veiller à plusieurs élément: - bien arréter tout process utilisant le répertoire de =data= du postgres en question, généralement un =compose stop postgres= suffit. - utiliser l'image du postgres via son nom (habituellement =myc_postgres=). - monter le répertoire data =directement=
Le tout peut se faire ainsi dans une installation qui fait tourner un postgres actuellement:
#+begin_src sh compose stop postgres && docker run --rm --entrypoint pg_resetwal \ -u postgres -v /srv/datastore/data/postgres/var/lib/postgresql/data:/var/lib/postgresql/data \ myc_postgres \ /var/lib/postgresql/data && docker start myc_postgres_1 #+end_src
*** mysql
**** sur installation mailcow
Le script =mailcow-backup-install= fourni via =myc-manage= s'occupe de mettre en place le dump de =mysql=, et le système pour envoyer les backup régulièrement via rsync.
**** docker sans compose
#+begin_src sh export MYSQL_ROOT_PASSWORD=xxx export MYSQL_CONTAINER=mailcowdockerized_mysql-mailcow_1
/srv/charm-store/mysql/hooks/install.d/60-backup.sh #+end_src
*** rsync-backup
**** Installation du backup via compose
A faire depuis le serveur ayant des services géré par =compose= à backupper.
#+begin_src sh DOMAIN=xxx.fr
## CODE BACKUP_SERVER=core-06.0k.io:10023
ssh-keygen -t rsa -N "" -f /root/.ssh/rsync_rsa -C "rsync@$DOMAIN" cat <<EOF >> /opt/apps/myc-deploy/compose.yml
rsync-backup: options: ident: $DOMAIN target: $BACKUP_SERVER private-key: | $(cat /root/.ssh/rsync_rsa | sed -r 's/^/ /g') EOF
dest="$BACKUP_SERVER" dest="${dest%/*}" dest="${dest%%:*}" echo "Contacting '$dest' host, to add key in authorized key:" ssh -o "StrictHostKeyChecking=no" "root@${dest}" -- compose-add-rsync-key -R "\"$DOMAIN\"" "\"$(cat /root/.ssh/rsync_rsa.pub)\""
#+end_src
**** Installation du backup sur une installe mailcow
Le script suivant va s'occuper de tout, il doit être lancé depuis l'hôte faisant tourner l'installation =mailcow=.
#+begin_src sh mailcow-backup-install #+end_src
**** Installation du backup sur un host debian
Cela fonctionnera sur tout host ayant une base debian.
#+begin_src sh export DOMAIN=mail.myceliandre.fr export BACKUP_SERVER=core-06.0k.io:10023
/srv/charm-store/rsync-backup/hooks/install.d/60-install.sh
#+end_src
Note, il est possible de spécifier des exclusions pour chaque répértoire mirroré de telle façon:
#+begin_src sh cat <<EOF > /etc/mirror-dir/config.yml /home: exclude: - /*/.cache/ - /*/.gvfs/ - /*/.local/share/Trash/files/ - /*/.Trash/ - /*/.mozilla/firefox/*/Cache/ - /*/.mozilla/firefox/*/storage/default/*/cache/ /media/data: exclude: - /binary/games/_steam - /incoming - /.Trash* - /lost+found - /backup/device EOF #+end_src
* Interventions avancées
Description des process avancés d'intervention sur une installation existante.
** Modification du compose
Y a un exemple en commentaire dans le =/opt/apps/myc-deploy/compose.yml=
Petit exemple:
#+BEGIN_SRC yaml odoo: ...
docker-compose: ## Important to keep as a list: otherwise it'll overwrite charm's arguments. command: - "--log-level=debug" environment: TOTO: TUTU image: masuperimage
#+END_SRC
** Troubleshooting
S'il semble qu'il y ait un soucis, tu peux visualiser le =docker-compose.yml= qui est généré à la fin via l'ajout de =--debug= AVANT la commande:
#+BEGIN_EXAMPLE compose --debug up odoo frontend #+END_EXAMPLE
* Comment ça marche
La surcouche =compose= est là pour créer un =docker-compose.yml= et le lancer tout a fait normalement. Le long du chemin, il peut aussi préparer des trucs utiles si c'est nécessaire.
Il part du =compose.yml= et accède aux définitions en yaml des charms à déployer et qui sont dans /srv/charms ... (qui en fait sont dans =/opt/apps/0k-charms=).
Chaque charm possède une définition générale (le =metadata.yml=) qui peut aussi injecter des trucs dans le =docker-compose.yml= final.
Et puis il y a des =hooks=, qui sont juste des scripts bash qui sont lancés avec des infos dans des variables d'environment, qui vont généralement créer des trucs à l'init ou lors de liaison avec d'autres charms.
|