La « livraison continue » (Continuous Delivery) est une extension du concept d'intégration continue.

Dans cet article le but sera de partir d'un projet Docker de site statique, le "builder" et le "pusher" sur le Google container registry pour ensuite automatiser la gestion du code et son déploiement vers nos serveurs Kubernetes.

Untitled-Diagram

schéma du projet

On commence par cloner le projet avec git :

git clone https://github.com/nishanttotla/DockerStaticSite.git

Puis une fois positionné dans le dossier sur votre Mac, on lance le build du site statique grâce à Docker en utilisant votre nom d'utilisateur du hub Docker :

MBP-de-admin:DockerStaticSite-master admin$ docker build -t gsagnard/staticsite:1.0 .
Sending build context to Docker daemon  19.46kB
Step 1/3 : FROM nginx:alpine
alpine: Pulling from library/nginx
4fe2ade4980c: Pull complete 
82359930187f: Pull complete 
dd73d113d335: Pull complete 
4b94bac1a7e3: Pull complete 
Digest: sha256:fd0361ff0882d63eec241705ba169d83c042bf27f8b568aedd131c2ab97246f0
Status: Downloaded newer image for nginx:alpine
 ---> 33c5c6e11024
Step 2/3 : COPY default.conf /etc/nginx/conf.d/default.conf
 ---> 3d6603cc8c47
Step 3/3 : COPY index.html /usr/share/nginx/html/index.html
 ---> effb515b71d8
Successfully built effb515b71d8
Successfully tagged gsagnard/staticsite:1.0

Créons maintenant le cluster Gcloud :

MBP-de-admin:DockerStaticSite-master admin$ gcloud config set compute/zone europe-west1-b
Updated property [compute/zone].


MBP-de-admin:DockerStaticSite-master admin$ gcloud container clusters create MY_KUBERNETES_CLUSTER \
>   --enable-cloud-logging \
>   --enable-cloud-monitoring \
>   --subnetwork default

Ce qui donne :

Creating cluster website-static in europe-west1-b...done.                                                                                                 Created [https://container.googleapis.com/v1/projects/mythical-patrol-217720/zones/europe-west1-b/clusters/website-static].
    To inspect the contents of your cluster, go to: https://console.cloud.google.com/kubernetes/workload_/gcloud/europe-west1-b/website-static?project=mythical-patrol-217720
    kubeconfig entry generated for website-static.
    NAME            LOCATION        MASTER_VERSION  MASTER_IP     MACHINE_TYPE   NODE_VERSION  NUM_NODES  STATUS
    website-static  europe-west1-b  1.9.7-gke.6     35.205.190.4  n1-standard-1  1.9.7-gke.6   3          RUNNING

Une fois le cluster crée sur votre compte Gcloud, utiliser les registry d'images managés respectifs au cloud pour uploader notre image HelloWorld. Notez que pour simplifier nous aurions pu lancer une stack Kubernetes avec des images téléchargées depuis une registry publique comme Docker Hub.

Upload de notre image sur les Registry

MBP-de-admin:DockerStaticSite-master admin$ gcloud projects list
PROJECT_ID              NAME              PROJECT_NUMBER
helm-gitops-test        helm-gitops-test  770028763204
mythical-patrol-217720  My Project 88355  8908526602

Pour uploader notre image depuis notre registry local, nous devons tout d'abord taguer l'image. Nous suivrons la documentation officielle. Nous devons respecter cette syntaxe :

MBP-de-admin:DockerStaticSite-master admin$ sudo docker tag gsagnard/staticsite:1.0 eu.gcr.io/mythical-patrol-217720/staticsite
  • Source image : staticsite
  • Hostname : eu.gcr.io pour être en Europe
  • Project-id : Vous pouvez trouver cette info avec la commande gcloud projects list. Sur mon compte, c'est mythical-patrol-217720.
  • Image : nom de l'image sur GCR, nous garderons staticsite:1.0

Nous pouvons ensuite pousser l'image en indiquant le tag.

    MBP-de-admin:DockerStaticSite-master admin$ sudo gcloud docker -- push eu.gcr.io/mythical-patrol-217720/staticsite
WARNING: `gcloud docker` will not be supported for Docker client versions above 18.03.

As an alternative, use `gcloud auth configure-docker` to configure `docker` to
use `gcloud` as a credential helper, then use `docker` as you would for non-GCR
registries, e.g. `docker pull gcr.io/project-id/my-image`. Add
`--verbosity=error` to silence this warning: `gcloud docker
--verbosity=error -- pull gcr.io/project-id/my-image`.

See: https://cloud.google.com/container-registry/docs/support/deprecation-notices#gcloud-docker

The push refers to repository [eu.gcr.io/mythical-patrol-217720/staticsite]
91bcb19cc4bd: Pushed 
30f24d3b1602: Pushed 
2baa7a93b1ec: Layer already exists 
c06288185506: Layer already exists 
c3b00436f3b3: Layer already exists 
df64d3292fd6: Layer already exists 
latest: digest: sha256:f4e49a9ceb108b380ce449a3eee86dbaa5f4460bc23a5ba26e962a0bb68790cc size: 1567

On peut vérifier que l'image est bien uploadée avec la commande :

MBP-de-admin:DockerStaticSite-master admin$ gcloud container images list-tags eu.gcr.io/mythical-patrol-217720/staticsite
DIGEST        TAGS    TIMESTAMP
f4e49a9ceb10  latest  2018-09-28T08:07:18

Ce template contient la description du service que nous voulons lancer. En l'occurence, c'est un simple service web qui expose via un loadbalancer le port 80 de nos 3 conteneurs.

Téléchargez le template k8s, modifiez le champ image avec le nom de votre image uploadée sur la registry, puis lancer la stack avec kubectl.

# Modifiez l'URL de votre image avec celle de votre propre image
vi template.yml

# Lancement de la stack.
kubectl create -f template.yml

Vous devriez voir que les différentes ressources décrites dans le template ont été créés :

deployment.apps "helloworlddeployment" created
service "helloworldservice" created

Si vous avez bien suivi le tutoriel, vous devriez pouvoir accéder à votre service HelloWorld ! Pour connaitre l'IP publique, vous pouvez lister les services disponibles sur votre cluster. C'est la même commande pour tous les clouds :

MBP-de-admin:~ admin$ kubectl get services
NAME                TYPE           CLUSTER-IP      EXTERNAL-IP      PORT(S)        AGE
helloworldservice   LoadBalancer   10.47.251.146   35.195.208.249   80:31899/TCP   1m
kubernetes          ClusterIP      10.47.240.1     <none>           443/TCP        1d

Résultat à l'adresse donnée par Google :

Capture-d-e-cran-2018-09-29-a--13.34.30

C'est aussi simple que cela ! La majorité de cet article porte sur les créations des clusters, mais l'utilisation de Kubernetes une fois ces clusters lancés est complètement unifiée. Un seul outil à maîtriser, kubectl, sur tous les clouds. Enorme non ?