#+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
#+BEGIN_SRC sh
wget https://justodooit.myceliandre.fr/r/deploy -qO - | bash
#+END_SRC
If you want to setup odoo admin password and domain in one go:
#+BEGIN_SRC sh
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 <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
*** 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
***** 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
*** mysql
**** docker sans compose
***** backup régulier depuis l'hôte
#+begin_src sh
MYSQL_ROOT_PASSWORD=xxx
MYSQL_CONTAINER=mailcowdockerized_mysql-mailcow_1
apt-get install -y mysql-client ~/.my.cnf
[client]
password=${MYSQL_ROOT_PASSWORD}
EOF
chmod 600 ~/.my.cnf
cat <<'EOF' > /usr/local/sbin/mysql-backup
#!/bin/bash
. /etc/shlib
include common
include pretty
usage="$exname [--host HOST] [DATABASE...]"
DBS=()
host=
while [ "$1" ]; do
case "$1" in
"--help"|"-h")
print_usage
exit 0
;;
"--host")
host="$2"
shift
;;
*)
DBS+=("$1")
;;
esac
shift
done
mysql_opts=()
if [ "$host" ]; then
mysql_opts+=(-h "$host")
fi
m() {
mysql "${mysql_opts[@]}" -Bs "$@"
}
md() {
mysqldump "${mysql_opts[@]}" "$@"
}
mysql_databases() {
echo "SHOW DATABASES" | m
}
mysql_tables() {
local db="$1"
echo "SHOW TABLES" | m "$db"
}
if [ "${#DBS[@]}" == 0 ]; then
DBS=($(mysql_databases)) || exit 1
fi
mkdir -p /var/backups/mysql
for db in "${DBS[@]}"; do
if [[ "$db" == "information_schema" || "$db" == "performance_schema" || "$db" == "mysql" ]]; then
continue
fi
echo "Dumping database $db..." >&2
# omitting all the rotation logic
dst=/"var/backups/mysql/$db"
[ -d "$dst.old" ] && rm -rf "$dst.old"
[ -d "$dst" ] && mv "$dst" "$dst.old"
mkdir -p "$dst.inprogress"
(( start = SECONDS ))
md "$db" --routines --no-data --add-drop-database --database "$db" | gzip --rsyncable > "$dst.inprogress/schema.sql.gz"
tables=$(mysql_tables "$db")
for table in $tables; do
backup_file="$dst.inprogress/${table}.sql.gz"
echo " Dumping $table into ${backup_file}"
md "$db" "$table" | gzip --rsyncable > "$backup_file" || break
done
mv "$dst.inprogress" "$dst"
[ -d "$dst.old" ] && rm -rf "$dst.old"
(( elapsed = SECONDS - start ))
echo " ..dumped $db to $dst ($(du -sh "$dst" | cut -f 1) in ${elapsed}s)" >&2
done
EOF
chmod +x /usr/local/sbin/mysql-backup
cat < /etc/cron.d/mysql-backup
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
0 * * * * root /usr/local/sbin/mysql-backup --host \$(docker-ip "$MYSQL_CONTAINER" 2>/dev/null | sed -r 's/ +/ /g' | cut -f 3 -d " ") | logger -t mysql-backup
EOF
mkdir -p /etc/mirror-dir &&
cat <> /etc/mirror-dir/mirror-dir.conf
/var/backups/mysql:
exclude:
- "/*.inprogress"
EOF
#+end_src
*** rsync-backup
**** Installation du backup via compose
A faire depuis le serveur ayant des services à backupper.
Il y a une partie à copier-coller sur le serveur de backup.
Ne pas oublier de relancer le serveur de backup pour le prendre en compte.
#+begin_src sh
DOMAIN=xxx.fr
BACKUP_SERVER=core-06.0k.io:10023
ssh-keygen -t rsa -N "" -f /root/.ssh/rsync_rsa -C "rsync@$DOMAIN"
cat <> /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
echo "copier-coller ceci dans le '/etc/compose/compose.yml' de ${BACKUP_SERVER%:*}:"
echo
cat < /etc/cron.d/mirror-dir
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
$((RANDOM % 60)) * * * * root mirror-dir -d $BACKUP_SERVER -u rsync ${DESTS[@]} 2>&1 | logger -t mirror-dir
EOF
#+end_src
les logs sont dans =/var/log/mirror.log=.
Note, il est possible de spécifier des exclusions pour chaque
répértoire mirroré de telle façon:
#+begin_src sh
cat < /etc/mirror-dir/mirror-dir.conf
/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.