Lasst uns beginnen
Damit die Web-App auf allen Maschinen verfügbar ist, müssen wir sie in Container umwandeln, und wenn Containerisierung angesagt ist, was ist besser als Docker.
Ich habe eine Docker-Datei erstellt, um die App auszuführen, aber ich habe ein mehrstufiges Format verwendet
Der Grund ist einfach: Wenn ich ein Image in einem einzigen Schritt erstelle, würde es mehr Platz auf dem Computer beanspruchen, wohingegen wir durch die Verwendung mehrstufiger Builds die endgültige Größe des Images optimieren, indem wir Build- und Laufzeitumgebungen trennen und auch den Angriff reduzieren Oberfläche unseres Bildes für mehr Sicherheit
So können Sie es machen
# 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"]
Da wir nun die Docker-Datei haben, erstellen wir sie und stellen sie auf Dockerhub bereit
docker build -t pankaj892/webapp:v1 .
Wir versuchen zu überprüfen, ob die App auf dem lokalen Computer wie erwartet funktioniert
docker run -p 8080:8080 pankaj892-webapp:v1
Schieben wir es auf den Dockerhub
docker push pankaj892/webapp:v1 .
Sie können einen Cluster lokal mit mininkube/kind erstellen oder eine der verwalteten Lösungen in der Cloud verwenden. Ich verwende Elastic Kubernetes Service (EKS) von AWS.
Sie können einen Cluster in EKS über die Konsole oder über die Befehlszeile starten. Ich werde die Befehlszeile verwenden
eksctl create cluster--instance-selector-vcpus=2 --instance-selector-memory=4 --name <name-of-cluster> --region <region-code>
Dadurch werden nur die Maschinentypen für Knotengruppen ausgewählt, die über 2 vCPUs und 4 GB Arbeitsspeicher verfügen
Wir können alle Ressourcen einzeln bereitstellen, aber es wäre schwierig, sie zu verwalten, da sie skaliert werden. Hier kommt Helm ins Spiel, der als Paketmanager fungiert, um alle unsere Ressourcen mithilfe von Diagrammen zu verwalten
Erstellen Sie ein Ruderdiagramm
# 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 erstellt Dateien für unsere Verwendung, aber die meisten davon benötigen wir nicht für unser Projekt.
Erstellen Sie die folgenden Dateien und fügen Sie sie im Helmverzeichnis hinzu
Bereitstellung
eksctl create cluster--instance-selector-vcpus=2 --instance-selector-memory=4 --name <name-of-cluster> --region <region-code>
Service
helm create web-app
Eindringen
# 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
Aktualisieren Sie die Wertedatei entsprechend
# 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
Der Steuerteil ist nun erledigt. Fahren wir nun mit der Bereitstellung unseres CI fort
Github-Aktionen ermöglichen es uns, den Erstellungsprozess unserer App basierend auf einigen Ereignissen in unserem Repo wie Push, Pull zu automatisieren.
Lassen Sie uns unsere Pipeline-Datei erstellen
Die Workflow-Datei wird in (.github/workflows/cicd.yml)
gespeichert
# 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
Diese Workflow-Datei erstellt zunächst unser Image aus der Docker-Datei, schiebt es dann an Dockerhub und aktualisiert dann das Tag des Bildes in unserer charts.yaml-Datei in Helm.
Wir werden argocd für unsere CD-Pipeline verwenden, da argocd Änderungen aus unserem Git-Repo übernehmen und in der App aktualisieren kann.
Lasst uns argocd auf unserem Cluster installieren
kubectl erstellt den Namensraum argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
Um auf den argocd-Server zuzugreifen, müssen wir den Dienst in den Loadbalancer-Typ ändern
kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'
Für Windows wäre dies
kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'
Wenn es nicht funktioniert, bearbeiten Sie einfach den Dienst über kubectl und ändern Sie den Typ in LoadBalancer. Es sollte funktionieren
Jetzt erhalten Sie die IP des Dienstes
kubectl get svc argocd-server -n argocd
Wir haben die IP, aber wir brauchen das Passwort, um uns bei argocd anzumelden
kubectl get Secret argocd-initial-admin-secret -n argocd -o jsonpath="{.data.password}" | base64 --decode
Dieser Befehl würde das Passwort abrufen und das Passwort dekodieren, da das Passwort im Base64-Format kodiert ist
Klicken Sie nach dem Anmelden auf Neues Projekt > Fügen Sie den Namen für Ihr Projekt hinzu > Fügen Sie das Repo hinzu, damit argocd das Repo synchronisieren kann. argocd sucht automatisch nach der Wertedatei und holt diese ab. Klicken Sie dann auf „Senden“
Wir haben unsere Pipeline aufgebaut, aber wie greifen wir auf unsere App zu? Sie können nicht jedes Mal die Cluster-URL von EKS eingeben, um darauf zuzugreifen. Dafür müssen wir einen Ingress verwenden
Ich verwende Nginx Ingress von AWS, damit ich auf die App zugreifen kann
Stellen Sie den Ingress auf unserem Cluster bereit
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.11.1/deploy/static/provider/aws/deploy.yaml
Jetzt ist Ingress bereitgestellt und wir müssen die IP unseres Clusters von EKS in unsere lokale Hosts-Datei für Linux einfügen, /etc/hosts für Windows, sie befindet sich in 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"]
Jetzt können wir über web-app.local auf unsere App zugreifen
Wir haben alle Schritte erledigt und testen unsere App
Wie Sie sehen können, ist die URL oben das, was wir in unserer Hosts-Datei definiert haben
Wir lassen die App laufen. Fügen wir etwas hinzu und verpflichten uns zu unserem Repo, damit argocd diese Änderung übernehmen und in der App bereitstellen kann
Ich habe eine Änderung an meinem Repo vorgenommen und dies sollte die Pipeline auslösen
Pipeline wurde gestartet und nach ihrer Fertigstellung wollen wir sehen, ob argocd diese Änderung übernimmt
Ja, wir sehen Änderungen in unserer App, argocd hat Änderungen übernommen und unsere App mit den neuesten Änderungen synchronisiert
Wenn du es bis hierher geschafft hast, dann herzlichen Glückwunsch!!!
Dieses Projekt war für mich eine großartige Lernerfahrung, angefangen bei der Bereitstellung von Kubernetes auf AWS über die Erstellung meiner Pipelines und Bereitstellungen bis hin zur Fehlerbehebung. Dieses Projekt hat mir geholfen, eine End-to-End-Entwicklungspipeline für eine Go-App zu erstellen, die je nach Bedarf skalierbar ist. Ich habe vor, mehr zu erforschen, wie etwa die Bereitstellung des EKS-Clutsers mithilfe von Terraform- oder Cloudformation-Stacks, und weitere Verbesserungen vorzunehmen.
Wenn Sie irgendwo nicht weiterkommen, können Sie auf dieses Repo verweisen
Lassen Sie mich in den Kommentaren wissen, wie Ihre Erfahrungen beim Aufbau dieser Pipeline waren.
Das obige ist der detaillierte Inhalt vonDevops-Pipeline auf einer Golang-Web-App mit Gitops und Kubernetes. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!