Maison >développement back-end >Golang >Pipeline Devops sur une application Web Golang avec Gitops et Kubernetes

Pipeline Devops sur une application Web Golang avec Gitops et Kubernetes

Patricia Arquette
Patricia Arquetteoriginal
2024-10-24 02:44:29423parcourir

Dans cet article de blog, je vais vous guider tout au long du parcours d'automatisation du déploiement d'une application Web dans Golang avec des pipelines CI/CD et en utilisant l'approche Gitops.

Nous passerons par la conteneurisation de notre application, son déploiement sur Kubernetes et l'utilisation d'ArgoCD pour le déploiement.

Exigences

  1. Un cluster Kubernetes Vous pouvez utiliser n'importe lequel des services gérés des fournisseurs de cloud pour Kubernetes ou si votre système dispose de suffisamment de ressources pour provisionner un cluster Kubernetes, vous pouvez configurer un cluster Kubernetes local à l'aide de Minikube/kind
  2. Un compte github Un compte gratuit est suffisant car nous utiliserons Github Actions pour l'intégration continue (CI)
  3. Un compte dockerhub Nous utiliserons Dockerhub pour extraire les images de conteneurs
  4. Désir d'apprendre
  5. Ne pas abandonner C'est le problème le plus important auquel vous serez confronté et vous devriez être en mesure de les dépanner et de les résoudre. J'ai dû dépanner plusieurs fois avant de pouvoir mener à bien ce projet.

Commençons

Conteneuriser l'application avec des builds Docker en plusieurs étapes

Pour que l'application Web soit disponible sur toutes les machines, nous devons la conteneuriser et lorsque la conteneurisation est le mot, quoi de mieux que Docker.
J'ai créé un Dockerfile pour exécuter l'application mais j'ai utilisé un format en plusieurs étapes

Pourquoi des builds en plusieurs étapes ?

La raison est simple : si je crée une image en une seule étape, cela consommerait plus d'espace sur la machine alors qu'en utilisant des builds en plusieurs étapes, nous optimisons la taille finale de l'image en séparant les environnements de build et d'exécution et réduisons également l'attaque. surface de notre image pour une meilleure sécurité

Voici comment procéder

  1. Créer un fichier docker
  2. Compilez l'application en phase de build
  3. Copiez le binaire compilé dans une image de base minimale
  4. Créez l'image et transférez-la vers Dockerhub afin qu'elle puisse être utilisée par Github Actions dans CI
# Start with a base image
FROM golang:1.22 as base
WORKDIR /app
COPY go.mod ./
RUN go mod download
COPY . .
RUN go build -o main .

#######################################################
# Reduce the image size using multi-stage builds
# We will use a distroless image to run the application
FROM gcr.io/distroless/base

# Copy the binary from the previous stage
COPY --from=base /app/main .

# Copy the static files from the previous stage
COPY --from=base /app/static ./static

# Expose the port on which the application will run
EXPOSE 8080

# Command to run the application
CMD ["./main"]

Maintenant que nous avons le fichier docker, construisons-le et déployons-le sur dockerhub

docker build -t pankaj892/webapp:v1 .

Nous essayons de vérifier si l'application fonctionne comme prévu sur la machine locale
docker run -p 8080:8080 pankaj892-webapp:v1

Poussons-le vers Dockerhub
docker push pankaj892/webapp:v1 .

Création de cluster Kubernetes

Vous pouvez créer un cluster localement à l'aide de mininkube/kind ou utiliser l'une des solutions gérées sur le cloud. J'utiliserai Elastic Kubernetes Service (EKS) d'AWS.

Vous pouvez lancer un cluster dans EKS à l'aide de la console ou depuis la ligne de commande. J'utiliserai la ligne de commande

eksctl create cluster--instance-selector-vcpus=2 --instance-selector-memory=4 --name <name-of-cluster> --region <region-code> 

Cela choisira uniquement les types de machines pour les groupes de nœuds dotés de 2 processeurs virtuels et d'une mémoire de 4 Go

Création et configuration de graphiques de barre

Nous pouvons déployer toutes les ressources une par une mais il serait difficile de les gérer à mesure qu'elles évoluent, c'est là que Helm entre en jeu, il agit comme un gestionnaire de packages pour gérer toutes nos ressources à l'aide de graphiques

Créer un graphique de barre

# Start with a base image
FROM golang:1.22 as base
WORKDIR /app
COPY go.mod ./
RUN go mod download
COPY . .
RUN go build -o main .

#######################################################
# Reduce the image size using multi-stage builds
# We will use a distroless image to run the application
FROM gcr.io/distroless/base

# Copy the binary from the previous stage
COPY --from=base /app/main .

# Copy the static files from the previous stage
COPY --from=base /app/static ./static

# Expose the port on which the application will run
EXPOSE 8080

# Command to run the application
CMD ["./main"]

Helm créera des fichiers pour notre usage mais nous n'en avons pas besoin de la plupart pour notre projet.

Créez les fichiers suivants et ajoutez-les dans le répertoire helm

Déploiement

eksctl create cluster--instance-selector-vcpus=2 --instance-selector-memory=4 --name <name-of-cluster> --region <region-code> 

Service

helm create web-app

Entrée

# This is a sample deployment manifest file for a simple web application.
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
  labels:
    app: web-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: web-app
  template:
    metadata:
      labels:
        app: web-app
    spec:
      containers:
      - name: web-app
        image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
        ports:
        - containerPort: 8080

Mettez à jour le fichier de valeurs avec ceci

# Service for the application
apiVersion: v1
kind: Service
metadata:
  name: web-app
  labels:
    app: web-app
spec:
  ports:
  - port: 80
    targetPort: 8080
    protocol: TCP
  selector:
    app: web-app
  type: ClusterIP

La partie Helm est terminée maintenant passons au déploiement de notre CI

Intégration continue (CI) avec les actions Github

Les actions Github nous permettent d'automatiser le processus de construction de notre application en fonction de certains événements de notre dépôt comme push,pull.

Créons notre fichier pipeline
Le fichier de workflow est stocké dans (.github/workflows/cicd.yml)

# Ingress resource for the application
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: web-app
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
  - host: web-app.local
    http:
      paths: 
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-app
            port:
              number: 80

Ce fichier de workflow construit d'abord notre image à partir de dockerfile, puis la transmet à dockerhub, puis met à jour la balise de l'image dans notre fichier charts.yaml dans helm.

Configuration d'ArgoCD pour une livraison continue

Nous utiliserons argocd pour notre pipeline Cd car argocd pourra récupérer les modifications de notre dépôt git et les mettre à jour dans l'application.

Installons argocd sur notre cluster

kubectl crée un espace de noms argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

Pour accéder au serveur argocd, nous devons changer le service en type d'équilibrage de charge

kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'

Pour Windows, ce serait
kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'

Si cela ne fonctionne pas, modifiez simplement le service via kubectl et changez le type en LoadBalancer, cela devrait fonctionner

Obtenez maintenant l'adresse IP du service

kubectl obtient svc argocd-server -n argocd

Nous avons l'adresse IP mais nous avons besoin du mot de passe pour nous connecter à argocd

kubectl obtient le secret argocd-initial-admin-secret -n argocd -o jsonpath="{.data.password}" | base64 --decode

Cette commande obtiendrait le mot de passe et décoderait le mot de passe puisque le mot de passe est codé au format base64

Après vous être connecté, cliquez sur Nouveau projet > Ajoutez le nom de votre projet > Ajoutez le dépôt pour qu'argocd puisse synchroniser le dépôt. Argocd recherchera automatiquement le fichier de valeurs et le récupérera après cela, cliquez sur soumettre

Devops pipeline on a Golang Web App with Gitops and Kubernetes

Ingress et mappage DNS

Nous avons construit notre pipeline, mais comment accéder à notre application, vous ne pouvez pas saisir l'URL du cluster d'EKS à chaque fois pour y accéder, nous devons utiliser une entrée pour cela

J'utilise Nginx Ingress d'AWS pour pouvoir accéder à l'application

Déployer l'ingress sur notre cluster

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.11.1/deploy/static/provider/aws/deploy.yaml

Maintenant, l'entrée est déployée et nous devons ajouter l'adresse IP de notre cluster depuis EKS dans notre fichier d'hôtes local pour Linux, son /etc/hosts pour Windows, il se trouve dans C:WindowsSystem32etchosts

# Start with a base image
FROM golang:1.22 as base
WORKDIR /app
COPY go.mod ./
RUN go mod download
COPY . .
RUN go build -o main .

#######################################################
# Reduce the image size using multi-stage builds
# We will use a distroless image to run the application
FROM gcr.io/distroless/base

# Copy the binary from the previous stage
COPY --from=base /app/main .

# Copy the static files from the previous stage
COPY --from=base /app/static ./static

# Expose the port on which the application will run
EXPOSE 8080

# Command to run the application
CMD ["./main"]

Nous pouvons désormais accéder à notre application sur web-app.local

Nous avons effectué toutes les étapes, testons notre application

Devops pipeline on a Golang Web App with Gitops and Kubernetes

Comme vous pouvez le voir, l'url en haut est ce que nous avons défini dans notre fichier hosts

Devops pipeline on a Golang Web App with Gitops and Kubernetes

Nous avons l'application en cours d'exécution, ajoutons quelque chose et validons notre dépôt afin qu'argocd puisse récupérer ce changement et le déployer sur l'application

J'ai apporté une modification à mon dépôt et cela devrait déclencher le pipeline

Devops pipeline on a Golang Web App with Gitops and Kubernetes

Le pipeline a démarré et une fois terminé, voyons si argocd récupère ce changement

Devops pipeline on a Golang Web App with Gitops and Kubernetes

Oui, nous constatons des changements dans notre application, argocd a récupéré les modifications et synchronisé notre application avec les dernières modifications

Si vous êtes arrivé jusqu'ici, alors félicitations !!!

Ce projet a été une excellente expérience d'apprentissage pour moi, depuis le déploiement de Kubernetes sur AWS jusqu'à la création de mes pipelines et déploiements et leur dépannage. Ce projet m'a aidé à créer un pipeline DevOps de bout en bout pour une application Go et il peut être évolutif en fonction des besoins. Je prévois d'explorer davantage, comme peut-être le déploiement de l'eks clutser à l'aide de piles terraform ou cloudformation et d'affiner davantage.

Si vous êtes bloqué quelque part, vous pouvez référencer ce dépôt

Faites-moi savoir dans les commentaires quelle a été votre expérience dans la création de ce pipeline.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn