Précédents blog posts de la série "Kit de survie K8S pour les dévs avec K3S"

🇫🇷 Kit de survie K8S pour les dévs avec K3S - Partie 8 - un peu de réseau

Dans les précédents articles nous avons vu que nous utilisions le service nip.io pour les noms de domaine de nos microservices, et j'avais une url de ce type: http://<service-name>.<branch-name>.192.168.64.17.nip.io. nip.io est un sercice de wildcard DNS gratuit (quelques explications ici: https://cloud.google.com/run/docs/gke/default-domain?hl=fr#choose_an_alternatives_for_wildcard_dns).

Il y a quelques jours, pour écrire le précédent article, je suis passé en mode 🙀 panique, je n'arrivais plus à accéder aux url de mes microservices. En fait, c'était juste nip.io qui était "down" 🍓.

Mais alors, comment je fais si ça arrive en pleine démo chez un client ou pendant un talk?

Après avoir exprimé mon désespoir sur Twittter, la réponse qui est revenue le plus souvent était DNSMasq. Ce qui m'a fait "frémir" 😡, car j'avais déjà essayé de l'utiliser il y a un an, et j'étais resté sur un échec. Et à nouveau, j'ai rencontré quelques difficultés. Mais finalement un GRAND MERCI à Benoît Moussaud pour son aide qui m'a mis sur la piste. J'ai quand même galéré avant d'y arriver de ma,ière "reproductible", mais en croisant diverses informations j'ai fin par arriver à mes fins.

Installation de DNSMasq et paramétrage

Mes manipulations sont faites sous OSX, mais je suis après près sûr que les Linuxiens 🐧 sauront adapter mes explications (pour les Windowsiens, encore une fois désolé, je ne sais pas. Un jour si je gagne une Surface ...).

Mon objectif est de pouvoir déployer mes services avec une url de ce type: http://<nom_service>.<branch_name>.demo.k33g.

Tout d'abord, il faut installer DNSMasq:

brew install dnsmasq

Ensuite créez le fichier ci-dessous avec une entrée correspondant à votre domaine "wildcard" et l'IP de votre cluster:

echo "address=/.demo.k33g/192.168.64.17" > /usr/local/etc/dnsmasq.d/development.conf

Allez dans les paramètres réseaux de votre Mac pour ajouter 192.168.64.17 (et 127.0.0.1) comme DNS:

alt k9s

Clickez sur Ok puis sur Apply

Redémarrez DNSMasq:

sudo brew services restart dnsmasq

Créez un "resolver" associé à votre domaine:

sudo bash -c 'echo "nameserver 127.0.0.1" > /etc/resolver/demo.k33g'

Vérifiez que le routage se fait correctement:

dig coucou.demo.k33g @127.0.0.1

Vous devriez obtenir quelque chose comme ceci:

; <<>> DiG 9.10.6 <<>> coucou.demo.k33g @127.0.0.1
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 7844
;; flags: qr aa rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;coucou.demo.k33g.              IN      A

;; ANSWER SECTION:
coucou.demo.k33g.       0       IN      A       192.168.64.17

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Mon Mar 23 16:02:39 CET 2020
;; MSG SIZE  rcvd: 61

Vérifiez que le ping se fait correctement:

ping coucou.demo.k33g
PING coucou.demo.k33g (192.168.64.17): 56 data bytes
64 bytes from 192.168.64.17: icmp_seq=0 ttl=64 time=0.232 ms
64 bytes from 192.168.64.17: icmp_seq=1 ttl=64 time=0.324 ms

bien sûr, vous avez démarré votre cluster

Nous pouvons maintenant modifier nos déploiements.

Déploiement (ping)

Dans le post sur les microservices je déployais le projet ping comme ceci:

export KUBECONFIG=../create-cluster/k3s.yaml
export CLUSTER_IP=$(multipass info basestar | grep IPv4 | awk '{print $2}')
export NAMESPACE="training"
export CONTAINER_PORT=8080
export EXPOSED_PORT=80
export BRANCH=$(git symbolic-ref --short HEAD)
envsubst < ./deploy.template.yaml > ./kube/deploy.${TAG}.yaml
kubectl apply -f ./kube/deploy.${TAG}.yaml -n ${NAMESPACE}

Je vais juste changer cette ligne:

export HOST="${APPLICATION_NAME}.${BRANCH}.${CLUSTER_IP}.nip.io"

par:

export DOMAIN="demo.k33g"
export HOST="${APPLICATION_NAME}.${BRANCH}.${DOMAIN}"

Je relance le build:

. ./build.sh

Remarque: le . avant ./build.sh permet de conserver les variables d'environnement pour le script suivant

Je déploie à nouveau:

./deploy.sh

J'obtiens:

service/ping unchanged
deployment.apps/ping configured
ingress.extensions/ping configured
🌍 http://ping.master.demo.k33g
🤜 http://ping.master.demo.k33g/api/knock-knock

si j'interroge mon service:

http http://ping.master.demo.k33g/api/knock-knock                            
HTTP/1.1 200 OK
Content-Length: 56
Content-Type: application/json;charset=UTF-8
Date: Mon, 23 Mar 2020 15:12:46 GMT
Vary: Accept-Encoding

{
    "from": "ping-service",
    "message": "🏓 pong"
}

👋 mon DNS Wildcard fonctionne à merveille

Remarque: vous trouverez la modification sur la branche ping-v2 du projet: https://gitlab.com/learn-k3s/ping/-/tree/ping-v2 et ici pour pong: https://gitlab.com/learn-k3s/pong/-/tree/pong-v2

Nous allons faire la même chose pour le projet pong

Déploiement (pong)

Appliquons les mêmes modifications au projet pong, re-buildons et re-déployons. Vous pouvez vérifier que vous accédez à la page d'accueil de http://pong.master.demo.k33g. Maintenant, tentez d'appeler le service pong, qui lui même va faire un appel au service ping:

http http://pong.master.demo.k33g/api/knock-knock                            
HTTP/1.1 200 OK
Content-Length: 76
Content-Type: application/json;charset=UTF-8
Date: Mon, 23 Mar 2020 15:21:48 GMT
Vary: Accept-Encoding

{
    "error": "failed to resolve 'ping.master.demo.k33g' after 3 queries "
}

🙀 pong ne voit plus ping.

Discovery avec Redis

Si vous vous souvenez, nos services s'enregistrent dans une base Redis. Nous allons nous y connecter de l'extérieur:

export KUBECONFIG=$PWD/k3s.yaml
kubectl port-forward --namespace database svc/redis-master 6379:6379 &

Ensuite connectez vous à la base (j'utilise Medis)

alt k9s

  • Changez la ligne: "host": "ping.master.demo.k33g" par "host": "ping.training"
  • Sauvegardez:

alt k9s

Et re-interrogez le service pong (qui va interroger le service ping):

http http://pong.master.demo.k33g/api/knock-knock  
HTTP/1.1 200 OK
Content-Length: 120
Content-Type: application/json;charset=UTF-8
Date: Mon, 23 Mar 2020 15:30:00 GMT
Vary: Accept-Encoding

{
    "callingPing": {
        "from": "ping-service",
        "message": "🏓 pong"
    },
    "responseFromPong": "🏓 ping"
}

Cette fois ci cela fonctionne, car au sein du cluster les services ont joignables par <nom_application>.<namespace> (nous en avions parlé dans le post sur Redis). Il faudra juste revoir la façon d'enregistrer les service dans le Discovery Backend, en leur passant le namespace via une variable d'environnement par exemple, et d'utiliser les meta-data pour différencier les urls "de l'intérieur" de celles "de l'extérieur".

Il faudra aussi revoir la façon de gérer le nom de la branche utilisée (qui me permet de différencier la version du service que je déploie) et faire porter son nom par exemple par le namespace, car pour le moment avec "host": "ping.training" à la place de "host": "ping.master.demo.k33g", la notion de branche disparaît (ce qui peut-être problématique pour la CI). Mais je ferais une nouvelle version du code pour un prochain article.

👋 à bientôt pour la suite

Last Articles

Last Updated: 23/03/2020 à 15:56:12