Tutorial

Comment développer des applications sur Kubernetes avec Okteto

DevelopmentOpen SourceKubernetesDigitalOcean Managed Kubernetes

L'auteur a sélectionné Girls Who Code pour recevoir un don dans le cadre de l'initiative Écrire pour des donations.

Introduction

La CLI d'Okteto est un projet open-source qui fournit une expérience de développement local pour les applications fonctionnant sur Kubernetes.  Avec elle, vous pouvez écrire votre code sur votre IDE local et dès que vous enregistrez un fichier, les changements peuvent être poussés vers votre cluster Kubernetes et votre application sera immédiatement mise à jour. Tout ce processus se déroule sans qu'il soit nécessaire de construire des images Docker ou d'appliquer des manifestes Kubernetes, ce qui peut prendre un temps considérable.

Dans ce tutoriel, vous utiliserez Okteto pour améliorer votre productivité lors du développement d'une application native de Kubernetes. Tout d'abord, vous allez créer un cluster Kubernetes et l'utiliser pour faire fonctionner une application standard “Hello World”. Ensuite, vous utiliserez Okteto pour développer et mettre à jour automatiquement votre application sans avoir à installer quoi que ce soit localement.

Conditions préalables

Avant de commencer ce tutoriel, vous aurez besoin des éléments suivants :

Étape 1 — Création de l'application Hello World

Le programme “Hello World” est une tradition bien ancrée dans le développement web. Dans ce cas, il s'agit d'un simple service web qui répond “Hello World” à chaque demande. Maintenant que vous avez créé votre cluster Kubernetes, créons une application “Hello World” dans Golang et les manifestes que vous utiliserez pour la déployer sur Kubernetes.

Tout d'abord, passez à votre répertoire d'origine :

  • cd ~

Maintenant, créez un nouveau répertoire appelé hello_world et déplacez-vous à l'intérieur de celui-ci :

  • mkdir hello_world
  • cd hello_world

Créez et ouvrez un nouveau fichier sous le nom main.go avec votre IDE ou éditeur de texte préféré :

  • nano main.go

main.go sera un serveur web Golang qui renvoie le message Hello world ! Alors, utilisons le code suivant :

main.go
package main

import (
    "fmt"
    "net/http"
)

func main() {
    fmt.Println("Starting hello-world server...")
    http.HandleFunc("/", helloServer)
    if err := http.ListenAndServe(":8080", nil); err != nil {
        panic(err)
    }
}

func helloServer(w http.ResponseWriter, r *http.Request) {
    fmt.Fprint(w, "Hello world!")
}

Le code dans main.go fait ce qui suit :

  • La première déclaration dans un fichier source Go doit être le nom du package. Les commandes exécutables doivent toujours utiliser le package main.
  • La section import indique de quels packages dépendent le code. Dans ce cas, il utilise fmt pour la manipulation des chaînes de caractères, et net/http pour le serveur HTTP.
  • La fonction main est le point d'entrée de votre binaire. La méthode http.HandleFunc est utilisée pour configurer le serveur afin qu'il appelle la fonction helloServer lorsqu'une requête vers le chemin d'accès / est reçue. http.ListenAndServe démarre un serveur HTTP qui écoute sur toutes les interfaces réseau sur le port 8080.
  • La fonction helloServer contient la logique de votre gestionnaire de demande. Dans ce cas, elle écrira Hello world ! comme réponse à la demande.

Vous devez créer une image Docker et la pousser vers votre registre Docker afin que Kubernetes puisse la tirer et ensuite exécuter l'application.

Ouvrez un nouveau fichier sous le nom de Dockerfile avec votre IDE ou éditeur de texte préféré :

  • nano Dockerfile

Le Dockerfile contiendra les commandes nécessaires pour construire le conteneur Docker de votre application. Utilisons le code suivant :

Dockerfile
FROM golang:alpine as builder
RUN apk --update --no-cache add bash
WORKDIR /app
ADD . .
RUN go build -o app

FROM alpine as prod
WORKDIR /app
COPY --from=builder /app/app /app/app
EXPOSE 8080
CMD ["./app"]

Le Dockerfile contient deux étapes, builder et prod :

  • L'étape builder contient les outils de construction de Go. Elle est chargée de copier les fichiers et de construire le binaire de Go.
  • L'étape prod est l'image finale. Il ne contiendra qu'un OS dépouillé et le binaire de l'application.

C'est une bonne pratique à suivre. Elle rend vos conteneurs de production plus petits et plus sûrs puisqu'ils ne contiennent que votre application et exactement ce qui est nécessaire pour la faire fonctionner.

Construire l'image du conteneur (remplacez your_DockerHub_username par votre nom d'utilisateur Docker Hub) :

  • docker build -t your_DockerHub_username/hello-world:latest

Maintenant, poussez-le vers Docker Hub :

  • docker push your_DockerHub_username/hello-world:latest

Ensuite, créez un nouveau dossier pour les manifestes Kubernetes :

  • mkdir k8s

Lorsque vous utilisez un manifeste Kubernetes, vous dites à Kubernetes comment vous voulez que votre application fonctionne. Cette fois, vous allez créer un objet de déploiement. Pour cela, créez un nouveau fichier deployment.yaml avec votre IDE ou éditeur de texte préféré :

  • nano k8s/deployment.yaml

Le contenu suivant décrit un objet de déploiement Kubernetes qui exécute l'image Docker okteto/hello-world:latest. Ajoutez ce contenu à votre nouveau fichier, mais dans votre cas, remplacez okteto figurant après l'étiquette de l’image par your_DockerHub_username :

~/hello_world/k8s/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-world
spec:
  selector:
    matchLabels:
      app: hello-world
  replicas: 1
  template:
    metadata:
      labels:
        app: hello-world
    spec:
      containers:
      - name: hello-world
        image: your_DockerHub_username/hello-world:latest
        ports:
        - containerPort: 8080

Le manifeste de déploiement comporte trois sections principales :

  • metadata définit le nom de votre déploiement.
  • replicas définit le nombre de copies que vous voulez exécuter.
  • template indique à Kubernetes ce qu'il faut déployer et les étiquettes à ajouter. Dans ce cas, un seul conteneur, avec l'image okteto/hello-world:latest, en écoute sur le port 8080, et avec l'étiquette app:hello-world. Notez que cette étiquette est la même que celle utilisée dans la section selector.

Vous devez maintenant trouver un moyen d'accéder à votre application. Vous pouvez exposer une application sur Kubernetes en créant un objet de service. Continuons à utiliser des manifestes pour ce faire. Créez un nouveau fichier appelé service.yaml avec votre IDE ou éditeur de texte préféré :

  • nano k8s/service.yaml

Le contenu suivant décrit un service qui expose l'objet de déploiement hello-world, qui secrètement utilisera un DigitalOcean Load Balancer :

k8s/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: hello-world
spec:
  type: LoadBalancer
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
      name: http
  selector:
    app: hello-world

Le manifeste de service comporte quatre sections principales :

  • metadata indique à Kubernetes comment nommer votre service.
  • type indique à Kubernetes comment vous voulez exposer votre service. Dans ce cas, il l'exposera à l'extérieur par le biais d'un Digital Ocean Load Balancer.
  • L'étiquette des ports indique à Kubernetes les ports que vous voulez exposer, et comment les faire correspondre à votre déploiement. Dans ce cas, vous exposerez le port 80 à l'extérieur et le dirigerez vers le port 8080 dans votre déploiement.
  • selector indique à Kubernetes comment diriger le trafic. Dans ce cas, tout pod portant l'étiquette app:hello-world recevra du trafic.

Tout est maintenant prêt pour que vous déployiez votre application “Hello World” sur Kubernetes. C'est ce que nous allons faire.

Étape 2 — Déploiement de votre application Hello World

Au cours de cette étape, vous déploierez votre application “Hello World” sur Kubernetes, puis vous validerez qu'elle fonctionne correctement.

Commencez par déployer votre application sur Kubernetes :

  • kubectl apply -f k8s

Vous verrez la sortie suivante :

Output
deployment.apps "hello-world" created service "hello-world" created

Au bout d'une minute environ, vous pourrez récupérer l'adresse IP de votre application. Utilisez cette commande kubectl pour vérifier votre service :

  • kubectl get service hello-world

Vous verrez une sortie comme celle-ci énumérant vos objets de service Kubernetes. Notez l'IP de votre application dans la colonne EXTERNAL-IP :

Output
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE hello-world ClusterIP your_cluster_ip your_external_ip 8080/TCP 37s

Ouvrez votre navigateur et allez à your_external_ip listé pour votre application “Hello World”. Confirmez que votre application est en cours d'exécution avant de passer à l'étape suivante.

Hello World Okteto

Jusqu'à présent, vous avez suivi une voie assez traditionnelle pour développer des applications avec Kubernetes. À l'avenir, chaque fois que vous voudrez modifier le code de votre application, vous devrez construire et pousser une nouvelle image de Docker, puis retirer cette image de Kubernetes. Ce processus peut prendre un certain temps. Okteto a été conçu pour rationaliser cette boucle interne de développement. Examinons la CLI d'Okteto et voyons comment elle peut nous aider.

Étape 3 — Installation de la CLI d'Okteto

Vous allez maintenant améliorer la productivité de votre développement Kubernetes en installant la CLI Okteto. L’interface en ligne de commande (CLI) Okteto est un projet open-source qui vous permet de synchroniser les changements de code d'une application à une application fonctionnant sur Kubernetes. Vous pouvez continuer à utiliser votre IDE, débogueur ou compilateur préféré sans avoir à commettre, construire, pousser ou redéployer des conteneurs pour tester votre application - comme vous l'avez fait dans les étapes précédentes.

Pour installer la CLI d'Okteto sur une machine MacOS ou Linux, exécutez la commande suivante :

  • curl https://get.okteto.com -sSfL | sh

Examinons de plus près cette commande :

  • La commande curl est utilisée pour transférer des données vers et depuis un serveur.
  • Le drapeau -s supprime toute sortie.
  • Le drapeau -S indique les erreurs.
  • Le drapeau -f provoque l'échec de la requête sur les erreurs HTTP.
  • Le drapeau -L fait que la requête suive des redirections.
  • L'opérateur | transmet cette sortie à la commande sh, qui téléchargera et installera le dernier binaire okteto sur votre machine locale.

Si vous utilisez Windows, vous pouvez alternativement télécharger le fichier via votre navigateur web et l'ajouter manuellement à votre $PATH.

Une fois la CLI d'Okteto installée, vous êtes prêt à mettre votre application “Hello World” en mode développement.

Étape 4 — Placer votre application Hello World en mode développement

La CLI d'Okteto est conçue pour échanger l'application fonctionnant sur un cluster Kubernetes avec le code que vous avez dans votre machine. Pour ce faire, Okteto utilise les informations fournies par un fichier de manifeste Okteto. Ce fichier déclare l'objet de déploiement Kubernetes qui sera échangé avec votre code local.

Créez un nouveau fichier appelé okteto.yaml avec votre IDE ou votre éditeur de texte préféré :

  • nano okteto.yaml

Ecrivons un manifeste de base où vous définissez le nom de l'objet de déploiement, l'image de base Docker à utiliser, et un shell. Nous reviendrons sur ces informations ultérieurement. Utilisez l'exemple de fichier de contenu suivant :

okteto.yaml
name: hello-world
image: okteto/golang:1
workdir: /app
command: ["bash"]

Préparez-vous à mettre votre application en mode développement en exécutant la commande suivante :

  • okteto up
Output
✓ Development environment activated ✓ Files synchronized Namespace: default Name: hello-world Welcome to your development environment. Happy coding! default:hello-world /app>

La commande okteto up convertit l'application “Hello World” en un environnement de développement, ce qui signifie :

  • Le conteneur de l'application Hello World est mis à jour avec l'image du docker okteto/golang:1. Cette image contient les outils de développement nécessaires pour construire, tester, déboguer et exécuter l'application “Hello World”.

  • Un service de synchronisation de fichiers est créé pour maintenir vos modifications à jour entre votre système de fichiers local et vos pods d'application.

  • Un shell à distance se lance dans votre environnement de développement. Vous pouvez maintenant construire, tester et exécuter votre application comme si vous étiez dans votre machine locale.

  • Quel que soit le processus que vous exécutez dans le shell distant, vous obtiendrez le même trafic entrant, les mêmes variables d'environnement, volumes ou secrets que les pods d'application “Hello World” d'origine. Cela vous donne un environnement de développement très réaliste, semblable à celui de la production.

Dans la même console, exécutez maintenant l'application comme vous le feriez normalement (sans construire et pousser une image Docker), comme ceci :

  • go run main.go
Output
Starting hello-world server...

La première fois que vous exécuterez l'application, Go téléchargera vos dépendances et compilera votre demande. Attendez la fin de ce processus et testez votre application en ouvrant votre navigateur et en rafraîchissant la page de votre application, comme vous l'avez fait précédemment.

Vous êtes maintenant prêt à commencer à développer directement sur Kubernetes.

Étape 5 — Développement direct sur Kubernetes

Commençons par apporter des modifications à l'application “Hello World” et voyons ensuite comment ces modifications se reflètent dans Kubernetes.

Ouvrez le fichier main.go avec votre IDE ou votre éditeur de texte préféré. Par exemple, ouvrez une console séparée et exécutez la commande suivante :

  • nano main.go

Ensuite, changez votre message de réponse pour Hello world from DigitalOcean! :

main.go
package main

import (
    "fmt"
    "net/http"
)

func main() {
    fmt.Println("Starting hello-world server...")
    http.HandleFunc("/", helloServer)
    if err := http.ListenAndServe(":8080", nil); err != nil {
        panic(err)
    }
}

func helloServer(w http.ResponseWriter, r *http.Request) {
    fmt.Fprint(w, "Hello world from DigitalOcean!")
}

C'est ici que votre workflow change. Au lieu de construire des images et de redéployer des conteneurs pour mettre à jour l'application “Hello World”, Okteto synchronisera vos changements dans votre environnement de développement sur Kubernetes.

Depuis la console où vous avez exécuté la commande okteto up, annulez l'exécution de go run main.go en appuyant sur CTRL + C. Ré-exécutez maintenant l'application :

  • default:hello-world /app> go run main.go
Output
Starting hello-world server...

Retournez au navigateur et rechargez la page pour votre application “Hello World”.

Hello world DigitalOcean"

Vos modifications de code ont été appliquées instantanément à Kubernetes, et tout cela sans nécessiter de commits, de builds ou de push.

Conclusion

Okteto transforme en un clic votre cluster Kubernetes en une plateforme de développement complète. Dans ce tutoriel, vous avez installé et configuré la CLI d'Okteto pour itérer vos changements de code directement sur Kubernetes aussi vite que vous pouvez taper du code. Vous pouvez maintenant vous rendre dans le répertoire d'échantillons d'Okteto pour voir comment utiliser Okteto avec différents langages de programmation et débogueurs.

Enfin, si vous partagez un cluster Kubernetes avec votre équipe, pensez à donner à chaque membre l'accès à un espace de nom Kubernetes sécurisé, configuré pour être isolé des autres développeurs travaillant sur le même cluster. Cette fonctionnalité très intéressante est également fournie par l’app Okteto dans le DigitalOcean Kubernetes Marketplace.

Creative Commons License