Différences
Ci-dessous, les différences entre deux révisions de la page.
Les deux révisions précédentesRévision précédenteProchaine révision | Révision précédente | ||
elearning:workbooks:kubernetes:k8s04 [2024/02/21 13:02] – admin | elearning:workbooks:kubernetes:k8s04 [2024/12/19 13:33] (Version actuelle) – admin | ||
---|---|---|---|
Ligne 1: | Ligne 1: | ||
+ | ~~PDF: | ||
+ | |||
+ | Version - **2024.01** | ||
+ | |||
+ | Dernière mise-à-jour : ~~LASTMOD~~ | ||
+ | |||
+ | |||
+ | ======DOF305 - Gestion du Réseau, des Services et d'une Architecture de Microservices====== | ||
+ | |||
+ | =====Contenu du Module===== | ||
+ | |||
+ | * **DOF305 - Gestion du Réseau, des Services et d'une Architecture de Microservices** | ||
+ | * Contenu du Module | ||
+ | * LAB #1 - Gestion du Réseau et des Services | ||
+ | * 1.1 - Présentation des Extensions Réseau | ||
+ | * 1.2 - DNS K8s | ||
+ | * Présentation | ||
+ | * Mise en Application | ||
+ | * 1.3 - Network Policies | ||
+ | * Présentation | ||
+ | * Mise en Application | ||
+ | * 1.4 - Services | ||
+ | * Le Service NodePort | ||
+ | * Présentation | ||
+ | * Mise en Application | ||
+ | * Le Service ClusterIP | ||
+ | * Présentation | ||
+ | * Mise en Application | ||
+ | * 1.5 - Services et le DNS k8s | ||
+ | * Présentation | ||
+ | * Mise en Application | ||
+ | * 1.6 - Gestion de K8s Ingress | ||
+ | * Présentation | ||
+ | * Mise en Application | ||
+ | * LAB #2 - Gestion de l' | ||
+ | * 2.1 - Présentation | ||
+ | * 2.2 - Création des Deployments | ||
+ | * 2.3 - Création des Services | ||
+ | * 2.4 - Déployer l' | ||
+ | * 2.5 - Scaling Up | ||
+ | |||
+ | =====Ressources===== | ||
+ | |||
+ | ====LAB #1==== | ||
+ | |||
+ | * https:// | ||
+ | * https:// | ||
+ | * https:// | ||
+ | * https:// | ||
+ | * https:// | ||
+ | * https:// | ||
+ | * https:// | ||
+ | * https:// | ||
+ | * https:// | ||
+ | |||
+ | |||
+ | ====LAB #2==== | ||
+ | |||
+ | * https:// | ||
+ | * https:// | ||
+ | * https:// | ||
+ | * https:// | ||
+ | * https:// | ||
+ | * https:// | ||
+ | * https:// | ||
+ | * https:// | ||
+ | * https:// | ||
+ | |||
+ | =====LAB #1 - Gestion du Réseau et des Services===== | ||
+ | |||
+ | ====1.1 - Présentation des Extensions Réseau==== | ||
+ | |||
+ | Kubernetes impose des conditions pour l’implémentation d'un réseau : | ||
+ | |||
+ | * Les PODs sur un nœud peuvent communiquer avec tous les PODs sur tous le nœuds sans utiliser NAT, | ||
+ | * Les agents sur un nœud (par exemple kubelet) peuvent communiquer avec tous les PODs sur le nœud. | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : La description technique et détaillée de l' | ||
+ | </ | ||
+ | |||
+ | Lors de l' | ||
+ | |||
+ | * **[[https:// | ||
+ | * **[[https:// | ||
+ | * **[[https:// | ||
+ | * **[[https:// | ||
+ | * **[[https:// | ||
+ | * **[[https:// | ||
+ | * **[[https:// | ||
+ | * **[[https:// | ||
+ | * Canal (utilise Flannel pour le réseau et Calico pour le pare-feu). | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Une étude comparative des extensions réseau pour Kubernetes peut être trouvée à la page : **[[https:// | ||
+ | </ | ||
+ | |||
+ | ====1.2 - DNS K8s==== | ||
+ | |||
+ | ===Présentation=== | ||
+ | |||
+ | Les services DNS du cluster utilisant le plugin **Calico** sont fournis par **CoreDNS** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | NAME READY | ||
+ | calico-kube-controllers | ||
+ | coredns | ||
+ | metrics-server | ||
+ | |||
+ | root@kubemaster: | ||
+ | NAME | ||
+ | kube-dns | ||
+ | metrics-server | ||
+ | </ | ||
+ | |||
+ | Tous les pods sont attribués un nom d' | ||
+ | |||
+ | < | ||
+ | adresse_ip_du_pod_sous_le_format_xxx-xxx-xxx-xxx.nom_namespace.pod.cluster.local | ||
+ | </ | ||
+ | |||
+ | ===Mise en Application=== | ||
+ | |||
+ | Pour tester le DNS, créez le fichier **dnstest.yaml** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | root@kubemaster: | ||
+ | apiVersion: v1 | ||
+ | kind: Pod | ||
+ | metadata: | ||
+ | name: busybox-dnstest | ||
+ | spec: | ||
+ | containers: | ||
+ | - name: busybox | ||
+ | image: radial/ | ||
+ | command: [' | ||
+ | --- | ||
+ | apiVersion: v1 | ||
+ | kind: Pod | ||
+ | metadata: | ||
+ | name: nginx-dnstest | ||
+ | spec: | ||
+ | containers: | ||
+ | - name: nginx | ||
+ | image: nginx: | ||
+ | ports: | ||
+ | - containerPort: | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que ce fichier va créer deux pods - **busybox-dnstest** et **nginx-dnstest**. | ||
+ | </ | ||
+ | |||
+ | Créez les deux pods à l'aide de ce fichier : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | pod/ | ||
+ | pod/ | ||
+ | </ | ||
+ | |||
+ | Copiez l' | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | NAME READY | ||
+ | nginx-dnstest | ||
+ | </ | ||
+ | |||
+ | Exécutez la commande **curl <adresse IP copiée> | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | % Total % Received % Xferd Average Speed | ||
+ | | ||
+ | 0 | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | ... | ||
+ | </ | ||
+ | < | ||
+ | < | ||
+ | <p>If you see this page, the nginx web server is successfully installed and | ||
+ | working. Further configuration is required.</ | ||
+ | |||
+ | < | ||
+ | <a href=" | ||
+ | Commercial support is available at | ||
+ | <a href=" | ||
+ | |||
+ | < | ||
+ | </ | ||
+ | </ | ||
+ | 100 | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que **busybox-dnstest** a pu contacter **nginx-dnstest** en utilisant son adresse IP. | ||
+ | </ | ||
+ | |||
+ | Utilisez maintenant le DNS K8s pour résoudre le nom d' | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | Server: | ||
+ | Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local | ||
+ | |||
+ | Name: 192-168-150-33.default.pod.cluster.local | ||
+ | Address 1: 192.168.150.33 | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que le nom d' | ||
+ | </ | ||
+ | |||
+ | Exécutez maintenant la commande **curl < | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | % Total % Received % Xferd Average Speed | ||
+ | | ||
+ | 0 | ||
+ | ... | ||
+ | < | ||
+ | ... | ||
+ | 100 | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que **busybox-dnstest** a pu contacter **nginx-dnstest** en utilisant son nom d' | ||
+ | </ | ||
+ | |||
+ | ====1.3 - Network Policies==== | ||
+ | |||
+ | ===Présentation=== | ||
+ | |||
+ | Un **NetworkPolicy** est un objet K8s qui permet de contrôler la communication vers et à partir des pods. | ||
+ | |||
+ | Les composants d'un NetworkPolicy sont : | ||
+ | |||
+ | * **from et to Selectors**, | ||
+ | * le **from selector** s' | ||
+ | * le mot Ingress indique du trafic réseau vers un pod, | ||
+ | * le **to selector** s' | ||
+ | * le mot Egress indique du trafic reçu d'un pod. | ||
+ | |||
+ | Les from et to Selectors utilisent des **Types** : | ||
+ | |||
+ | * **podSelector**, | ||
+ | * un podSelector peut sélectionner des pods en utilisant des Labels (// | ||
+ | * par défaut, un pod n'est pas isolé dans le cluster. Par contre dès qu'un podSelector sélectionne un pod, celui-ci est considéré comme isolé et ne peut que communiquer en suivant les **NetworkPolicies**, | ||
+ | * **namespaceSelector**, | ||
+ | * un namespaceSelector peut sélectionner des nameSpaces en utilisant des Labels (// | ||
+ | * **ipBlock**, | ||
+ | * un IPBlock peut sélectionner des pods en utilisant une plage d’adresses IP au format CIDR. | ||
+ | |||
+ | En complément des Types ci-dessus, il est aussi possible de spécifier : | ||
+ | |||
+ | * **Ports**, | ||
+ | * les ports spécifient le numéro de port ainsi que le protocole, | ||
+ | * le trafic réseau n'est accepté que dans le cas où les règles spécifiées par le Type **et** le port/ | ||
+ | |||
+ | ===Mise en Application=== | ||
+ | |||
+ | Pour mieux comprendre, créez un NameSpace dénommé **nptest** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | namespace/ | ||
+ | </ | ||
+ | |||
+ | Etiquettez ce NameSpace : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | namespace/ | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez l' | ||
+ | </ | ||
+ | |||
+ | Créez maintenant le fichier **npnginx.yaml** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | root@kubemaster: | ||
+ | apiVersion: v1 | ||
+ | kind: Pod | ||
+ | metadata: | ||
+ | name: npnginx | ||
+ | namespace: nptest | ||
+ | labels: | ||
+ | app: nginx | ||
+ | spec: | ||
+ | containers: | ||
+ | - name: nginx | ||
+ | image: nginx | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez l' | ||
+ | </ | ||
+ | |||
+ | Creéz le pod npnginx : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | pod/npnginx created | ||
+ | </ | ||
+ | |||
+ | Créez maintenant le fichier **npbusybox.yaml** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | root@kubemaster: | ||
+ | apiVersion: v1 | ||
+ | kind: Pod | ||
+ | metadata: | ||
+ | name: npbusybox | ||
+ | namespace: nptest | ||
+ | labels: | ||
+ | app: client | ||
+ | spec: | ||
+ | containers: | ||
+ | - name: busybox | ||
+ | image: radial/ | ||
+ | command: [' | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez l' | ||
+ | </ | ||
+ | |||
+ | Creéz le pod **npbusybox** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | pod/ | ||
+ | </ | ||
+ | |||
+ | Visualisez les informations des deux pods créés : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | NAME READY | ||
+ | npbusybox | ||
+ | npnginx | ||
+ | </ | ||
+ | |||
+ | Copiez l' | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | |||
+ | root@kubemaster: | ||
+ | 192.168.239.33 | ||
+ | </ | ||
+ | |||
+ | Testez la communication entre **npbusybox** et **npnginx** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | % Total % Received % Xferd Average Speed | ||
+ | | ||
+ | 100 | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | ... | ||
+ | </ | ||
+ | < | ||
+ | < | ||
+ | <p>If you see this page, the nginx web server is successfully installed and | ||
+ | working. Further configuration is required.</ | ||
+ | |||
+ | < | ||
+ | <a href=" | ||
+ | Commercial support is available at | ||
+ | <a href=" | ||
+ | |||
+ | < | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Rappelez-vous : par défaut, un pod n'est pas isolé dans le cluster. La communication a donc réussi. | ||
+ | </ | ||
+ | |||
+ | Créez maintenant le fichier **mynetworkpolicy.yaml** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | root@kubemaster: | ||
+ | apiVersion: networking.k8s.io/ | ||
+ | kind: NetworkPolicy | ||
+ | metadata: | ||
+ | name: mynetworkpolicy | ||
+ | namespace: nptest | ||
+ | spec: | ||
+ | podSelector: | ||
+ | matchLabels: | ||
+ | app: nginx | ||
+ | policyTypes: | ||
+ | - Ingress | ||
+ | - Egress | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez l' | ||
+ | </ | ||
+ | |||
+ | Créez maintenant la NetworkPolicy : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | networkpolicy.networking.k8s.io/ | ||
+ | </ | ||
+ | |||
+ | Testez de nouveau la communication entre **npbusybox** et **npnginx** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | % Total % Received % Xferd Average Speed | ||
+ | | ||
+ | 0 | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que la NetworkPolicy bloque la communication. Notez aussi l' | ||
+ | </ | ||
+ | |||
+ | Editez maintenant la NetworkPolicy : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | |||
+ | # Please edit the object below. Lines beginning with a '#' | ||
+ | # and an empty file will abort the edit. If an error occurs while saving this file will be | ||
+ | # reopened with the relevant failures. | ||
+ | # | ||
+ | apiVersion: networking.k8s.io/ | ||
+ | kind: NetworkPolicy | ||
+ | metadata: | ||
+ | creationTimestamp: | ||
+ | generation: 1 | ||
+ | name: mynetworkpolicy | ||
+ | namespace: nptest | ||
+ | resourceVersion: | ||
+ | uid: b130f09f-2ab1-4dc6-9059-95f900234be3 | ||
+ | spec: | ||
+ | podSelector: | ||
+ | matchLabels: | ||
+ | app: nginx | ||
+ | policyTypes: | ||
+ | - Ingress | ||
+ | - Egress | ||
+ | ingress: | ||
+ | - from: | ||
+ | - namespaceSelector: | ||
+ | matchLabels: | ||
+ | lab: nptest | ||
+ | ports: | ||
+ | - protocol: TCP | ||
+ | port: 80 | ||
+ | status: {} | ||
+ | :wq | ||
+ | |||
+ | root@kubemaster: | ||
+ | networkpolicy.networking.k8s.io/ | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez la création de la règle **ingress**. Cette règle utilise un namespaceSelector pour permettre du trafic à partir de pods dans un NameSpace ayant une étiquette **lab: nptest**. | ||
+ | </ | ||
+ | |||
+ | Testez de nouveau la communication entre **npbusybox** et **npnginx** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | % Total % Received % Xferd Average Speed | ||
+ | | ||
+ | 100 | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | ... | ||
+ | </ | ||
+ | < | ||
+ | < | ||
+ | <p>If you see this page, the nginx web server is successfully installed and | ||
+ | working. Further configuration is required.</ | ||
+ | |||
+ | < | ||
+ | <a href=" | ||
+ | Commercial support is available at | ||
+ | <a href=" | ||
+ | |||
+ | < | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que la communication a réussi. | ||
+ | </ | ||
+ | |||
+ | ====1.4 - Services==== | ||
+ | |||
+ | ===Présentation=== | ||
+ | |||
+ | Les services de K8s sont : | ||
+ | |||
+ | * NodePort, | ||
+ | * Ce Service rend un POD accessible sur un port du nœud le contenant, | ||
+ | * ClusterIP | ||
+ | * Ce Service crée une adresse IP virtuelle afin de permettre la communication entre de services différents dans le cluster, par exemple des serveurs front-end avec des serveurs back-end, | ||
+ | * LoadBalancer | ||
+ | * Ce service provisionne un équilibrage de charge pour une application dans certains fournisseurs de Cloud publique tels **A**mazon **W**eb **S**ervices et **G**oogle **C**loud **P**latform. | ||
+ | * ExternalName | ||
+ | * Ne fait pas parti de la certification CKA. | ||
+ | |||
+ | ===Mise en Application=== | ||
+ | |||
+ | Commencez par créer le deployment **myapp-deployment** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | deployment.apps/ | ||
+ | </ | ||
+ | |||
+ | Constatez l' | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | NAME | ||
+ | busybox-dnstest | ||
+ | myapp-deployment-7c4d4f7fc6-2km9n | ||
+ | myapp-deployment-7c4d4f7fc6-7pts7 | ||
+ | myapp-deployment-7c4d4f7fc6-9pw5x | ||
+ | mydaemonset-hmdhp | ||
+ | mydaemonset-kmf4z | ||
+ | nginx-dnstest | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que les adresses **192.168.239.x** sont associées aux PODs sur kubenode1 tandis que les adresses **192.168.150.x** sont associées aux PODs sur kubenode2. Ces adresses sont issues du réseau **192.168.0.0/ | ||
+ | </ | ||
+ | |||
+ | En sachant que dans chaque POD existe un conteneur Nginx, testez si vous pouvez afficher la page d' | ||
+ | |||
+ | < | ||
+ | trainee@kubemaster: | ||
+ | déconnexion | ||
+ | Connection to 10.0.2.65 closed. | ||
+ | trainee@gateway: | ||
+ | curl: (7) Failed to connect to 192.168.56.3 port 80: Connection refused | ||
+ | trainee@gateway: | ||
+ | curl: (7) Failed to connect to 192.168.56.4 port 80: Connection refused | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez l' | ||
+ | </ | ||
+ | |||
+ | Testez maintenant si vous pouvez afficher la page d' | ||
+ | |||
+ | < | ||
+ | trainee@gateway: | ||
+ | ^C | ||
+ | </ | ||
+ | |||
+ | Connectez-vous à **kubemaster** : | ||
+ | |||
+ | < | ||
+ | trainee@gateway: | ||
+ | trainee@192.168.56.2' | ||
+ | Linux kubemaster.ittraining.loc 4.9.0-19-amd64 #1 SMP Debian 4.9.320-2 (2022-06-30) x86_64 | ||
+ | |||
+ | The programs included with the Debian GNU/Linux system are free software; | ||
+ | the exact distribution terms for each program are described in the | ||
+ | individual files in / | ||
+ | |||
+ | Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent | ||
+ | permitted by applicable law. | ||
+ | Last login: Wed Jul 13 15:45:46 2022 from 10.0.2.40 | ||
+ | trainee@kubemaster: | ||
+ | Mot de passe : fenestros | ||
+ | root@kubemaster: | ||
+ | </ | ||
+ | |||
+ | Bien évidement, il est possible d' | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | body { | ||
+ | width: 35em; | ||
+ | margin: 0 auto; | ||
+ | font-family: | ||
+ | } | ||
+ | </ | ||
+ | </ | ||
+ | < | ||
+ | < | ||
+ | <p>If you see this page, the nginx web server is successfully installed and | ||
+ | working. Further configuration is required.</ | ||
+ | |||
+ | < | ||
+ | <a href=" | ||
+ | Commercial support is available at | ||
+ | <a href=" | ||
+ | |||
+ | < | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Retenez donc qu'à ce stade il n'est pas possible d' | ||
+ | </ | ||
+ | |||
+ | ===Le Service NodePort=== | ||
+ | |||
+ | ==Présentation== | ||
+ | |||
+ | Le Service NodePort définit trois ports : | ||
+ | |||
+ | * **TargetPort** : le port sur le POD, | ||
+ | * **Port** : le port sur le Service lié à un IP du Cluster, | ||
+ | * **NodePort** : le port sur le Nœud issu de la plage 30000-32767. | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | Si dans le même nœud, plusieurs PODs ont les étiquettes qui correspondent au **selector** du Service, le Service identifie les PODs et s' | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que dans ce cas l' | ||
+ | </ | ||
+ | |||
+ | De même, quand les PODs sont distribués sur plusieurs nœuds, le Service s' | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | ==Mise en Application== | ||
+ | |||
+ | Créez donc le fichier YAML **service-definition.yaml** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | root@kubemaster: | ||
+ | apiVersion: v1 | ||
+ | kind: Service | ||
+ | metadata: | ||
+ | name: myapp-service | ||
+ | |||
+ | spec: | ||
+ | type: NodePort | ||
+ | ports: | ||
+ | - targetPort: 80 | ||
+ | port: 80 | ||
+ | nodePort: 30008 | ||
+ | selector: | ||
+ | app: myapp | ||
+ | type: front-end | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que si le champ **type:** est manquant, sa valeur par défaut est **ClusterIP**. Notez aussi que dans **ports**, seul le champ **port** est obligatoire. Si le champ **targetPort** est manquant, sa valeur par défaut est celle du champ **port**. Si le champ **nodePort** est manquant, sa valeur par défaut est le premier port disponible dans la plage entre **30 000** et **32 767**. Dernièrement, | ||
+ | </ | ||
+ | |||
+ | Le champs **selector** contient les étiquettes des PODs concernés par la mise en place du Service : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | apiVersion: v1 | ||
+ | kind: Pod | ||
+ | metadata: | ||
+ | name: myapp-pod | ||
+ | labels: | ||
+ | app: myapp | ||
+ | type: front-end | ||
+ | spec: | ||
+ | containers: | ||
+ | - name: nginx-container | ||
+ | image: nginx | ||
+ | </ | ||
+ | |||
+ | Créez le Service en utilisant le fichier **service-definition.yaml** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | service/ | ||
+ | </ | ||
+ | |||
+ | Constatez la création du Service : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | NAME TYPE CLUSTER-IP | ||
+ | kubernetes | ||
+ | myapp-service | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que le Service a une adresse IP du cluster et qu'il a exposé le port **30 008**. | ||
+ | </ | ||
+ | |||
+ | Testez maintenant si vous pouvez afficher la page d' | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | déconnexion | ||
+ | |||
+ | trainee@kubemaster: | ||
+ | déconnexion | ||
+ | Connection to 192.168.56.2 closed. | ||
+ | |||
+ | trainee@gateway: | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | body { | ||
+ | width: 35em; | ||
+ | margin: 0 auto; | ||
+ | font-family: | ||
+ | } | ||
+ | </ | ||
+ | </ | ||
+ | < | ||
+ | < | ||
+ | <p>If you see this page, the nginx web server is successfully installed and | ||
+ | working. Further configuration is required.</ | ||
+ | |||
+ | < | ||
+ | <a href=" | ||
+ | Commercial support is available at | ||
+ | <a href=" | ||
+ | |||
+ | < | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | trainee@gateway: | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | body { | ||
+ | width: 35em; | ||
+ | margin: 0 auto; | ||
+ | font-family: | ||
+ | } | ||
+ | </ | ||
+ | </ | ||
+ | < | ||
+ | < | ||
+ | <p>If you see this page, the nginx web server is successfully installed and | ||
+ | working. Further configuration is required.</ | ||
+ | |||
+ | < | ||
+ | <a href=" | ||
+ | Commercial support is available at | ||
+ | <a href=" | ||
+ | |||
+ | < | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | ===Le Service ClusterIP=== | ||
+ | |||
+ | ==Présentation== | ||
+ | |||
+ | Le Service **ClusterIP** permet de regrouper les PODs offrant le même service afin de faciliter la communication entre pods à l' | ||
+ | |||
+ | ==Mise en Application== | ||
+ | |||
+ | Pour créer un Service ClusterIP, créez le fichier **clusterip-example.yaml** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | root@kubemaster: | ||
+ | apiVersion: apps/v1 | ||
+ | kind: Deployment | ||
+ | metadata: | ||
+ | name: deploymentclusterip | ||
+ | spec: | ||
+ | replicas: 3 | ||
+ | selector: | ||
+ | matchLabels: | ||
+ | app: clusteripexample | ||
+ | template: | ||
+ | metadata: | ||
+ | labels: | ||
+ | app: clusteripexample | ||
+ | spec: | ||
+ | containers: | ||
+ | - name: nginx | ||
+ | image: nginx: | ||
+ | ports: | ||
+ | - containerPort: | ||
+ | </ | ||
+ | |||
+ | Créez un deployment en utilisant le fichier **clusterip-example.yaml** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | deployment.apps/ | ||
+ | </ | ||
+ | |||
+ | Creéz maintenant un service de type ClusterIP pour exposer les pods du deplyment **deploymentclusterip** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | root@kubemaster: | ||
+ | apiVersion: v1 | ||
+ | kind: Service | ||
+ | metadata: | ||
+ | name: clusteripservice | ||
+ | spec: | ||
+ | type: ClusterIP | ||
+ | selector: | ||
+ | app: clusteripexample | ||
+ | ports: | ||
+ | - protocol: TCP | ||
+ | port: 80 | ||
+ | targetPort: 80 | ||
+ | </ | ||
+ | |||
+ | Créez un service en utilisant le fichier **clusterip-service.yaml** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | service/ | ||
+ | |||
+ | root@kubemaster: | ||
+ | NAME | ||
+ | clusteripservice | ||
+ | kubernetes | ||
+ | </ | ||
+ | |||
+ | Consultez les EndPoints du service en utilisant la commande suivante : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | NAME | ||
+ | clusteripservice | ||
+ | </ | ||
+ | |||
+ | Créez maintenant un pod qui utilisera le service **clusteripservice** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | root@kubemaster: | ||
+ | apiVersion: v1 | ||
+ | kind: Pod | ||
+ | metadata: | ||
+ | name: clusterippod | ||
+ | spec: | ||
+ | containers: | ||
+ | - name: busybox | ||
+ | image: radial/ | ||
+ | command: [' | ||
+ | </ | ||
+ | |||
+ | Créez le pod en utilisant le fichier **clusterippod.yaml** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | pod/ | ||
+ | </ | ||
+ | |||
+ | Vérifiez que le pod **clusterippod** est en cours de fonctionnement : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | NAME | ||
+ | clusterippod | ||
+ | </ | ||
+ | |||
+ | Consultez le service **clusteripservice** de l'' | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | % Total % Received % Xferd Average Speed | ||
+ | | ||
+ | 0 | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | ... | ||
+ | </ | ||
+ | < | ||
+ | < | ||
+ | <p>If you see this page, the nginx web server is successfully installed and | ||
+ | working. Further configuration is required.</ | ||
+ | |||
+ | < | ||
+ | <a href=" | ||
+ | Commercial support is available at | ||
+ | <a href=" | ||
+ | |||
+ | < | ||
+ | </ | ||
+ | </ | ||
+ | 100 | ||
+ | </ | ||
+ | |||
+ | ====1.5 - Services et le DNS k8s===== | ||
+ | |||
+ | Avant de poursuivre, nettoyez le cluster : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | service " | ||
+ | |||
+ | root@kubemaster: | ||
+ | deployment.extensions " | ||
+ | |||
+ | root@kubemaster: | ||
+ | daemonset.apps " | ||
+ | |||
+ | root@kubemaster: | ||
+ | pod " | ||
+ | pod " | ||
+ | </ | ||
+ | |||
+ | ===Présentation=== | ||
+ | |||
+ | Chaque service K8s est attribué un FQDN sous la forme : | ||
+ | |||
+ | < | ||
+ | nom-service.nom-namespace.svc.nom-cluster-domain.example | ||
+ | </ | ||
+ | |||
+ | Notez que : | ||
+ | |||
+ | * Le **nom-cluster-domain.example** par défaut est **cluster.local**. | ||
+ | * Le FQDN peut être utilisé pour atteindre un service à partir de n' | ||
+ | * Les pods du même NameSpace que le service peuvent l' | ||
+ | |||
+ | ===Mise en Application=== | ||
+ | |||
+ | Visualisez le service **clusteripservice** créé précédement : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | NAME | ||
+ | clusteripservice | ||
+ | </ | ||
+ | |||
+ | ainsi que les pods présents dans le cluster : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | NAME | ||
+ | clusterippod | ||
+ | deploymentclusterip-7776dc8d55-bmfjl | ||
+ | deploymentclusterip-7776dc8d55-pgmcg | ||
+ | deploymentclusterip-7776dc8d55-qvphh | ||
+ | </ | ||
+ | |||
+ | Visualisez le FQDN du service **clusteripservice** en utilisant le pod **clusterippod** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | Server: | ||
+ | Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local | ||
+ | |||
+ | Name: 10.109.80.217 | ||
+ | Address 1: 10.109.80.217 clusteripservice.default.svc.cluster.local | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que le FQDN du service est **clusteripservice.default.svc.cluster.local**. | ||
+ | </ | ||
+ | |||
+ | Vérifiez la communication avec le service en utilisant son adresse IP : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | % Total % Received % Xferd Average Speed | ||
+ | | ||
+ | 100 | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | body { | ||
+ | width: 35em; | ||
+ | margin: 0 auto; | ||
+ | font-family: | ||
+ | } | ||
+ | </ | ||
+ | </ | ||
+ | < | ||
+ | < | ||
+ | <p>If you see this page, the nginx web server is successfully installed and | ||
+ | working. Further configuration is required.</ | ||
+ | |||
+ | < | ||
+ | <a href=" | ||
+ | Commercial support is available at | ||
+ | <a href=" | ||
+ | |||
+ | < | ||
+ | </ | ||
+ | </ | ||
+ | | ||
+ | </ | ||
+ | |||
+ | Vérifiez la communication avec le service en utilisant son nom court : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | % Total % Received % Xferd Average Speed | ||
+ | | ||
+ | 100 | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | body { | ||
+ | width: 35em; | ||
+ | margin: 0 auto; | ||
+ | font-family: | ||
+ | } | ||
+ | </ | ||
+ | </ | ||
+ | < | ||
+ | < | ||
+ | <p>If you see this page, the nginx web server is successfully installed and | ||
+ | working. Further configuration is required.</ | ||
+ | |||
+ | < | ||
+ | <a href=" | ||
+ | Commercial support is available at | ||
+ | <a href=" | ||
+ | |||
+ | < | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que la communication a réussi parce que le pod **clusterippod** et le service **clusteripservice** sont dans le même namespace. | ||
+ | </ | ||
+ | |||
+ | Vérifiez la communication avec le service en utilisant son FQDN : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | % Total % Received % Xferd Average Speed | ||
+ | | ||
+ | 100 | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | body { | ||
+ | width: 35em; | ||
+ | margin: 0 auto; | ||
+ | font-family: | ||
+ | } | ||
+ | </ | ||
+ | </ | ||
+ | < | ||
+ | < | ||
+ | <p>If you see this page, the nginx web server is successfully installed and | ||
+ | working. Further configuration is required.</ | ||
+ | |||
+ | < | ||
+ | <a href=" | ||
+ | Commercial support is available at | ||
+ | <a href=" | ||
+ | |||
+ | < | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | Vérifiez maintenant la communication avec le service en utilisant son nom court à partir du pod **npbusybox** dans le namespace **nptest** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | curl: (6) Couldn' | ||
+ | command terminated with exit code 6 | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que la communication n'a pas réussi parce que le pod **npbusybox** et le service **clusteripservice** ne sont pas dans le même namespace. | ||
+ | </ | ||
+ | |||
+ | Vérifiez maintenant la communication avec le service en utilisant son FQDN à partir du pod **npbusybox** dans le namespace **nptest** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | % Total % Received % Xferd Average Speed | ||
+ | | ||
+ | 100 | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | body { | ||
+ | width: 35em; | ||
+ | margin: 0 auto; | ||
+ | font-family: | ||
+ | } | ||
+ | </ | ||
+ | </ | ||
+ | < | ||
+ | < | ||
+ | <p>If you see this page, the nginx web server is successfully installed and | ||
+ | working. Further configuration is required.</ | ||
+ | |||
+ | < | ||
+ | <a href=" | ||
+ | Commercial support is available at | ||
+ | <a href=" | ||
+ | |||
+ | < | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que la communication a réussi grâce à l' | ||
+ | </ | ||
+ | |||
+ | ====1.6 - Gestion de K8s Ingress==== | ||
+ | |||
+ | ====Présentation==== | ||
+ | |||
+ | Un Ingress est un objet k8s qui gère l' | ||
+ | |||
+ | * SSL, | ||
+ | * équilibrage de charge, | ||
+ | * hôtes virtuels par nom. | ||
+ | |||
+ | L' | ||
+ | |||
+ | ====Mise en Application ==== | ||
+ | |||
+ | Commencez par créer le fichier **myingress.yaml** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | root@kubemaster: | ||
+ | apiVersion: networking.k8s.io/ | ||
+ | kind: Ingress | ||
+ | metadata: | ||
+ | name: my-ingress | ||
+ | spec: | ||
+ | rules: | ||
+ | - http: | ||
+ | paths: | ||
+ | - path: /somepath | ||
+ | pathType: Prefix | ||
+ | backend: | ||
+ | service: | ||
+ | name: clusteripservice | ||
+ | port: | ||
+ | number: 80 | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que dans ce fichier Ingress nous avons une règle qui définie un **path**. Des requêtes qui référence le path, par exemple %%http://< | ||
+ | </ | ||
+ | |||
+ | Créez maintenant l' | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | ingress.networking.k8s.io/ | ||
+ | </ | ||
+ | |||
+ | Consultez maintenant l' | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | Name: | ||
+ | Labels: | ||
+ | Namespace: | ||
+ | Address: | ||
+ | Ingress Class: | ||
+ | Default backend: | ||
+ | Rules: | ||
+ | Host Path Backends | ||
+ | ---- ---- -------- | ||
+ | * | ||
+ | / | ||
+ | Annotations: | ||
+ | Events: | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que les endpoints du service **clusteripservice** sont affichés dans la sortie de la commande. | ||
+ | </ | ||
+ | |||
+ | Editez maintenant le fichier **clusterip-service.yaml** et ajoutez une ligne **name** dans la section **ports** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | root@kubemaster: | ||
+ | apiVersion: v1 | ||
+ | kind: Service | ||
+ | metadata: | ||
+ | name: clusteripservice | ||
+ | spec: | ||
+ | type: ClusterIP | ||
+ | selector: | ||
+ | app: clusteripexample | ||
+ | ports: | ||
+ | - name: myingress | ||
+ | protocol: TCP | ||
+ | port: 80 | ||
+ | targetPort: 80 | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que le nom peut être n' | ||
+ | </ | ||
+ | |||
+ | Appliquez la modification du clusteripservice : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | Warning: resource services/ | ||
+ | service/ | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que l' | ||
+ | </ | ||
+ | |||
+ | Editez maintenant le fichier **myingress.yaml** et ajoutez une ligne **name** dans la section **ports** et en supprimant la ligne **number: 80** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | apiVersion: networking.k8s.io/ | ||
+ | kind: Ingress | ||
+ | metadata: | ||
+ | name: my-ingress | ||
+ | spec: | ||
+ | rules: | ||
+ | - http: | ||
+ | paths: | ||
+ | - path: /somepath | ||
+ | pathType: Prefix | ||
+ | backend: | ||
+ | service: | ||
+ | name: clusteripservice | ||
+ | port: | ||
+ | name: myingress | ||
+ | </ | ||
+ | |||
+ | Appliquez la modification de l' | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | Warning: resource ingresses/ | ||
+ | ingress.networking.k8s.io/ | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que l' | ||
+ | </ | ||
+ | |||
+ | Consultez maintenant l' | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | Name: | ||
+ | Labels: | ||
+ | Namespace: | ||
+ | Address: | ||
+ | Ingress Class: | ||
+ | Default backend: | ||
+ | Rules: | ||
+ | Host Path Backends | ||
+ | ---- ---- -------- | ||
+ | * | ||
+ | / | ||
+ | Annotations: | ||
+ | Events: | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que l' | ||
+ | </ | ||
+ | |||
+ | =====LAB #2 - Gestion d'une Architecture de Microservices===== | ||
+ | |||
+ | Avant de continer, nettoyez le cluster : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | service " | ||
+ | |||
+ | root@kubemaster: | ||
+ | deployment.apps " | ||
+ | |||
+ | root@kubemaster: | ||
+ | ingress.networking.k8s.io " | ||
+ | |||
+ | root@kubemaster: | ||
+ | pod " | ||
+ | </ | ||
+ | |||
+ | Vérifiez qu'il ne reste que le service par défaut **kubernetes** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | NAME | ||
+ | service/ | ||
+ | </ | ||
+ | |||
+ | ====2.1 - Présentation==== | ||
+ | |||
+ | Vous allez mettre en place une application simple, appelé **demo-voting-app** et développé par Docker, sous forme de microservices : | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | Dans cette application le conteneur **voting-app** permet de voter pour des **chats** ou des **chiens**. Cette application tourne sous Python et fournit une interace HTML : | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | Lors de la vote, le résultat de celle-ci est stocké dans **Redis** dans une base de données en mémoire. Le résultat est ensuite passé au conteneur **Worker** qui tourne sous .NET et qui met à jour la base de données persistante dans le conteneur **db** qui tourne sous PostgreSQL. | ||
+ | |||
+ | L' | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | ====2.2 - Création des Deployments==== | ||
+ | |||
+ | Créez le répertoire **myapp**. Placez-vous dans ce répertoire et créez le fichier **voting-app-deployment.yaml** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | root@kubemaster: | ||
+ | root@kubemaster: | ||
+ | root@kubemaster: | ||
+ | --- | ||
+ | apiVersion: apps/v1 | ||
+ | kind: Deployment | ||
+ | metadata: | ||
+ | name: voting-app-deployment | ||
+ | labels: | ||
+ | app: demo-voting-app | ||
+ | spec: | ||
+ | replicas: 1 | ||
+ | selector: | ||
+ | matchLabels: | ||
+ | name: voting-app-pod | ||
+ | app: demo-voting-app | ||
+ | template: | ||
+ | metadata: | ||
+ | name: voting-app-pod | ||
+ | labels: | ||
+ | name: voting-app-pod | ||
+ | app: demo-voting-app | ||
+ | |||
+ | spec: | ||
+ | containers: | ||
+ | - name: voting-app | ||
+ | image: dockersamples/ | ||
+ | ports: | ||
+ | - containerPort: | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Ce fichier décrit un Deployment. Notez que le Deployment crée **un** replica du POD spécifié par **template** contenant un conteneur dénommé **voting-app** qui utilise le port 80 et qui est créé à partir de l' | ||
+ | </ | ||
+ | |||
+ | Créez maintenant le fichier **redis-deployment.yaml** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | root@kubemaster: | ||
+ | --- | ||
+ | apiVersion: apps/v1 | ||
+ | kind: Deployment | ||
+ | metadata: | ||
+ | name: redis-deployment | ||
+ | labels: | ||
+ | app: demo-voting-app | ||
+ | spec: | ||
+ | replicas: 1 | ||
+ | selector: | ||
+ | matchLabels: | ||
+ | name: redis-pod | ||
+ | app: demo-voting-app | ||
+ | template: | ||
+ | metadata: | ||
+ | name: redis pod | ||
+ | labels: | ||
+ | name: redis-pod | ||
+ | app: demo-voting-app | ||
+ | |||
+ | spec: | ||
+ | containers: | ||
+ | - name: redis | ||
+ | image: redis | ||
+ | ports: | ||
+ | - containerPort: | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Ce fichier décrit un Deployment. Notez que le Deployment crée **un** replica du POD spécifié par **template** contenant un conteneur dénommé **redis** qui utilise le port 6379 et qui est créé à partir de l' | ||
+ | </ | ||
+ | |||
+ | Créez le fichier **worker-deployment.yaml** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | root@kubemaster: | ||
+ | --- | ||
+ | apiVersion: apps/v1 | ||
+ | kind: Deployment | ||
+ | metadata: | ||
+ | name: worker-app-deployment | ||
+ | labels: | ||
+ | app: demo-voting-app | ||
+ | spec: | ||
+ | replicas: 1 | ||
+ | selector: | ||
+ | matchLabels: | ||
+ | name: worker-app-pod | ||
+ | app: demo-voting-app | ||
+ | template: | ||
+ | metadata: | ||
+ | name: worker-app-pod | ||
+ | labels: | ||
+ | name: worker-app-pod | ||
+ | app: demo-voting-app | ||
+ | |||
+ | spec: | ||
+ | containers: | ||
+ | - name: worker-app | ||
+ | image: dockersamples/ | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Ce fichier décrit un Deployment. Notez que le Deployment crée **un** replica du POD spécifié par **template** contenant un conteneur dénommé **worker-app** qui est créé à partir de l' | ||
+ | </ | ||
+ | |||
+ | Créez ensuite le fichier **postgres-deployment.yaml** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | root@kubemaster: | ||
+ | --- | ||
+ | apiVersion: apps/v1 | ||
+ | kind: Deployment | ||
+ | metadata: | ||
+ | name: postgres-deployment | ||
+ | labels: | ||
+ | app: demo-voting-app | ||
+ | spec: | ||
+ | replicas: 1 | ||
+ | selector: | ||
+ | matchLabels: | ||
+ | name: postgres-pod | ||
+ | app: demo-voting-app | ||
+ | template: | ||
+ | metadata: | ||
+ | name: postgres pod | ||
+ | labels: | ||
+ | name: postgres-pod | ||
+ | app: demo-voting-app | ||
+ | |||
+ | spec: | ||
+ | containers: | ||
+ | - name: postgres | ||
+ | image: postgres: | ||
+ | env: | ||
+ | - name: POSTGRES_USER | ||
+ | value: postgres | ||
+ | - name: POSTGRES_PASSWORD | ||
+ | value: postgres | ||
+ | ports: | ||
+ | - containerPort: | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Ce fichier décrit un Deployment. Notez que le Deployment crée **un** replica du POD spécifié par **template** contenant un conteneur dénommé **postgres** qui utilise le port 5432 et qui est créé à partir de l' | ||
+ | </ | ||
+ | |||
+ | Dernièrement, | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | root@kubemaster: | ||
+ | --- | ||
+ | apiVersion: apps/v1 | ||
+ | kind: Deployment | ||
+ | metadata: | ||
+ | name: result-app-deployment | ||
+ | labels: | ||
+ | app: demo-voting-app | ||
+ | spec: | ||
+ | replicas: 1 | ||
+ | selector: | ||
+ | matchLabels: | ||
+ | name: result-app-pod | ||
+ | app: demo-voting-app | ||
+ | template: | ||
+ | metadata: | ||
+ | name: result-app-pod | ||
+ | labels: | ||
+ | name: result-app-pod | ||
+ | app: demo-voting-app | ||
+ | |||
+ | spec: | ||
+ | containers: | ||
+ | - name: result-app | ||
+ | image: dockersamples/ | ||
+ | ports: | ||
+ | - containerPort: | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Ce fichier décrit un Deployment. Notez que le Deployment crée **un** replica du POD spécifié par **template** contenant un conteneur dénommé **result-app** qui utilise le port 80 et qui est créé à partir de l' | ||
+ | </ | ||
+ | |||
+ | ====2.3 - Création des Services==== | ||
+ | |||
+ | Créez maintenant le fichier **redis-service.yaml** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | root@kubemaster: | ||
+ | --- | ||
+ | apiVersion: v1 | ||
+ | kind: Service | ||
+ | metadata: | ||
+ | name: redis | ||
+ | labels: | ||
+ | name: redis-service | ||
+ | app: demo-voting-app | ||
+ | |||
+ | spec: | ||
+ | ports: | ||
+ | - port: 6379 | ||
+ | targetPort: 6379 | ||
+ | selector: | ||
+ | name: redis-pod | ||
+ | app: demo-voting-app | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Ce fichier décrit un Service **ClusterIP**. Notez que le Service expose le port **6379** sur tout POD ayant le nom **redis-pod**. | ||
+ | </ | ||
+ | |||
+ | Créez ensuite le fichier **postgres-service.yaml** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | root@kubemaster: | ||
+ | --- | ||
+ | apiVersion: v1 | ||
+ | kind: Service | ||
+ | metadata: | ||
+ | name: db | ||
+ | labels: | ||
+ | name: db-service | ||
+ | app: demo-voting-app | ||
+ | |||
+ | spec: | ||
+ | ports: | ||
+ | - port: 5432 | ||
+ | targetPort: 5432 | ||
+ | selector: | ||
+ | name: postgres-pod | ||
+ | app: demo-voting-app | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Ce fichier décrit un Service **ClusterIP**. Notez que le Service expose le port **5432** sur tout POD ayant le nom **postgres-pod**. | ||
+ | </ | ||
+ | |||
+ | Créez le fichier **voting-app-service.yaml** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | root@kubemaster: | ||
+ | --- | ||
+ | apiVersion: v1 | ||
+ | kind: Service | ||
+ | metadata: | ||
+ | name: voting-service | ||
+ | labels: | ||
+ | name: voting-service | ||
+ | app: demo-voting-app | ||
+ | |||
+ | spec: | ||
+ | type: NodePort | ||
+ | ports: | ||
+ | - port: 80 | ||
+ | targetPort: 80 | ||
+ | selector: | ||
+ | name: voting-app-pod | ||
+ | app: demo-voting-app | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Ce fichier décrit un Service **NodePort**. Notez que le Service expose le port **80** sur tout POD ayant le nom **voting-app-pod**. | ||
+ | </ | ||
+ | |||
+ | Dernièrement, | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | root@kubemaster: | ||
+ | --- | ||
+ | apiVersion: v1 | ||
+ | kind: Service | ||
+ | metadata: | ||
+ | name: result-service | ||
+ | labels: | ||
+ | name: result-service | ||
+ | app: demo-voting-app | ||
+ | |||
+ | spec: | ||
+ | type: NodePort | ||
+ | ports: | ||
+ | - port: 80 | ||
+ | targetPort: 80 | ||
+ | selector: | ||
+ | name: result-app-pod | ||
+ | app: demo-voting-app | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Ce fichier décrit un Service **NodePort**. Notez que le Service expose le port **80** sur tout POD ayant le nom **result-app-pod**. | ||
+ | </ | ||
+ | |||
+ | ====2.4 - Déployer l' | ||
+ | |||
+ | Vérifiez que vous avez créé tous les fichiers YAML necéssaires : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | postgres-deployment.yaml | ||
+ | postgres-service.yaml | ||
+ | </ | ||
+ | |||
+ | Utilisez ensuite la commande **kubectl create** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | deployment.apps/ | ||
+ | service/db created | ||
+ | deployment.apps/ | ||
+ | service/ | ||
+ | deployment.apps/ | ||
+ | service/ | ||
+ | deployment.apps/ | ||
+ | service/ | ||
+ | deployment.apps/ | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez l' | ||
+ | </ | ||
+ | |||
+ | Attendez que tous les Deployments soient **READY** (7 à 10 minutes) : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | NAME READY | ||
+ | postgres-deployment | ||
+ | redis-deployment | ||
+ | result-app-deployment | ||
+ | voting-app-deployment | ||
+ | worker-app-deployment | ||
+ | </ | ||
+ | |||
+ | Contrôlez ensuite l' | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | NAME | ||
+ | postgres-deployment-5b8bd66778-j99zz | ||
+ | redis-deployment-67d4c466c4-9wzfn | ||
+ | result-app-deployment-b8f9dc967-nzbgd | ||
+ | voting-app-deployment-669dccccfb-jpn6h | ||
+ | worker-app-deployment-559f7749b6-jh86r | ||
+ | </ | ||
+ | |||
+ | ainsi que la liste des Services : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | NAME | ||
+ | db | ||
+ | kubernetes | ||
+ | redis ClusterIP | ||
+ | result-service | ||
+ | voting-service | ||
+ | </ | ||
+ | |||
+ | Dans le cas donc de l' | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | ====2.5 - Scaling Up===== | ||
+ | |||
+ | Éditez le fichier **voting-app-deployment.yaml** et modifiez la valeur du champ **replicas** de 1 à 3 : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | root@kubemaster: | ||
+ | --- | ||
+ | apiVersion: apps/v1 | ||
+ | kind: Deployment | ||
+ | metadata: | ||
+ | name: voting-app-deployment | ||
+ | labels: | ||
+ | app: demo-voting-app | ||
+ | spec: | ||
+ | replicas: 3 | ||
+ | selector: | ||
+ | matchLabels: | ||
+ | name: voting-app-pod | ||
+ | app: demo-voting-app | ||
+ | template: | ||
+ | metadata: | ||
+ | name: voting-app-pod | ||
+ | labels: | ||
+ | name: voting-app-pod | ||
+ | app: demo-voting-app | ||
+ | |||
+ | spec: | ||
+ | containers: | ||
+ | - name: voting-app | ||
+ | image: dockersamples/ | ||
+ | ports: | ||
+ | - containerPort: | ||
+ | </ | ||
+ | |||
+ | Éditez le fichier **result-app-deployment.yaml** et modifiez la valeur du champ **replicas** de 1 à 3 : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | root@kubemaster: | ||
+ | --- | ||
+ | apiVersion: apps/v1 | ||
+ | kind: Deployment | ||
+ | metadata: | ||
+ | name: result-app-deployment | ||
+ | labels: | ||
+ | app: demo-voting-app | ||
+ | spec: | ||
+ | replicas: 3 | ||
+ | selector: | ||
+ | matchLabels: | ||
+ | name: result-app-pod | ||
+ | app: demo-voting-app | ||
+ | template: | ||
+ | metadata: | ||
+ | name: result-app-pod | ||
+ | labels: | ||
+ | name: result-app-pod | ||
+ | app: demo-voting-app | ||
+ | |||
+ | spec: | ||
+ | containers: | ||
+ | - name: result-app | ||
+ | image: dockersamples/ | ||
+ | ports: | ||
+ | - containerPort: | ||
+ | </ | ||
+ | |||
+ | Appliquez les modifications à l'aide de la commande **kubectl apply** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | Warning: kubectl apply should be used on resource created by either kubectl create --save-config or kubectl apply | ||
+ | deployment.apps/ | ||
+ | |||
+ | root@kubemaster: | ||
+ | Warning: kubectl apply should be used on resource created by either kubectl create --save-config or kubectl apply | ||
+ | deployment.apps/ | ||
+ | </ | ||
+ | |||
+ | Contrôlez ensuite les Deployments : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | NAME READY | ||
+ | postgres-deployment | ||
+ | redis-deployment | ||
+ | result-app-deployment | ||
+ | voting-app-deployment | ||
+ | worker-app-deployment | ||
+ | </ | ||
+ | |||
+ | ainsi que les PODs : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | NAME | ||
+ | postgres-deployment-5b8bd66778-j99zz | ||
+ | redis-deployment-67d4c466c4-9wzfn | ||
+ | result-app-deployment-b8f9dc967-nzbgd | ||
+ | result-app-deployment-b8f9dc967-r84k6 | ||
+ | result-app-deployment-b8f9dc967-zbsk2 | ||
+ | voting-app-deployment-669dccccfb-jpn6h | ||
+ | voting-app-deployment-669dccccfb-ktd7d | ||
+ | voting-app-deployment-669dccccfb-x868p | ||
+ | worker-app-deployment-559f7749b6-jh86r | ||
+ | </ | ||
+ | |||
+ | Dans le cas de l' | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | Retournez sur le navigateur de votre machine hôte et rafraichissez la page du voting-app : | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez le POD qui a servi la page. | ||
+ | </ | ||
+ | |||
+ | Rafraîchissez la page de nouveau : | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que le POD qui a servi la page a changé. | ||
+ | </ | ||
+ | |||
+ | Notez que ce changement de POD n' | ||
+ | |||
+ | Par contre, dans le cas d'une application sur GCP par exemple, il convient de modifier les deux fichiers suivants en changeant la valeur de champ **type** de NodePort à **LoadBalancer** puis de configurer une instance du Load Balancer natif de GCP : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | root@kubemaster: | ||
+ | --- | ||
+ | apiVersion: v1 | ||
+ | kind: Service | ||
+ | metadata: | ||
+ | name: voting-service | ||
+ | labels: | ||
+ | name: voting-service | ||
+ | app: demo-voting-app | ||
+ | |||
+ | spec: | ||
+ | type: LoadBalancer | ||
+ | ports: | ||
+ | - port: 80 | ||
+ | targetPort: 80 | ||
+ | selector: | ||
+ | name: voting-app-pod | ||
+ | app: demo-voting-app | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Ce fichier décrit un Service **LoadBalancer**. Notez que le Service expose le port **80** sur tout POD ayant le nom **voting-app-pod**. | ||
+ | </ | ||
+ | |||
+ | Dernièrement, | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | root@kubemaster: | ||
+ | --- | ||
+ | apiVersion: v1 | ||
+ | kind: Service | ||
+ | metadata: | ||
+ | name: result-service | ||
+ | labels: | ||
+ | name: result-service | ||
+ | app: demo-voting-app | ||
+ | |||
+ | spec: | ||
+ | type: LoadBalancer | ||
+ | ports: | ||
+ | - port: 80 | ||
+ | targetPort: 80 | ||
+ | selector: | ||
+ | name: result-app-pod | ||
+ | app: demo-voting-app | ||
+ | </ | ||
+ | |||
+ | ---- | ||
+ | Copyright © 2024 Hugh Norris | ||