5 Best Practices für GoLang-CI/CD

Entwicklern, die in etablierten Sprachen wie Java, JavaScript oder Python programmieren, ist die optimale Art und Weise Continuous-Integration- und Continuous-Delivery-Workflows (CI/CD) mit Artifactory aufzubauen, ziemlich vertraut. Eine ausgereifte Reihe von Systemen zur Verwaltung von Abhängigkeiten für diese Sprachen und Container-Lösungen wie Docker bieten eine klare Roadmap.

Aber wie schwer ist es, wenn Sie Ihre Anwendungen in GoLang programmieren, CI/CD mit der gleichen Effizienz zu betreiben?

Wie sich herausstellt, ist es viel einfacher geworden, besonders mit einigen der neuesten Innovationen in Go. Mit der nativen Unterstützung von Artifactory für GoLang ist der Weg zu einwandfreier CI/CD viel klarer.

Mit den neuesten Innovationen in Go, wie der nativen Unterstützung von Artifactory, ist der Weg zu einwandfreier CI/CD viel klarer. Klick um zu Tweeten

Best Practices

Wir bei JFrog sind große Fans von GoLang und verwenden es als Sprache für mehrere unserer renommiertesten Lösungen. Und wir praktizieren auch, was wir propagieren, indem wir Artifactory als Herzstück unserer CI/CD einsetzen. Hier sind einige der Praktiken, die wir empfehlen können:

1. Go-Module verwenden

Anders als viele etablierte Programmiersprachen haben die ersten Versionen von GoLang keinen gemeinsamen Mechanismus für die Verwaltung von versionierten Abhängigkeiten bereitgestellt. Stattdessen hatte das Go-Team andere Entwickler aufgefordert, Zusatz-Tools für die Versionierung von Go-Paketen zu entwickeln.

Das änderte sich mit der Veröffentlichung von Go 1.11 im August 2018, da ab diesem Zeitpunkt Go-Module unterstützt werden. Go-Module sind Sammlungen von zusammengehörigen Go-Paketen, die als eine Einheit versioniert werden, und bilden nun die native Lösung zur Verwaltung von Abhängigkeiten für GoLang. Dies ermöglicht es Entwicklern, Code gemeinsam zu nutzen, ohne ihn wiederholt herunterzuladen.

Ein Go-Modul wird durch eine go.mod -Datei im Stammverzeichnis des Projekts definiert, die den Modulnamen zusammen mit seinen Modulabhängigkeiten angibt. Die Modulabhängigkeit wird durch Modulname und Versionsnummer angegeben.

Wenn Sie Go-Module noch nicht übernommen haben, müssen Sie die folgenden Schritte ausführen:

  1. Verwenden Sie go mod init , um eine go.mod -Datei zu erzeugen, wenn frühere Paketmanager verwendet wurden.
  2. Verwenden Sie go mod tidy , wenn keine anderen Paketmanager verwendet wurden. Mit diesem Befehl wird eine ausgefüllte go.mod-Datei erzeugt.
  3. Wenn es sich um Version v2 und höher handelt, dann ist die Änderung des Modulnamens erforderlich, um das entsprechende Suffix hinzuzufügen, Aktualisierungen des Importpfads, die Verwendung von modulorientierten statischen Analysetools und schließlich die Aktualisierung von Codegenerator-Dateien wie zum Beispiel .proto -Dateien, um den neuen Importpfad wiederzugeben.

Hier ist zum Beispiel eine go.mod -Datei für ein öffentlich verfügbares Go-Modul für einen strukturierten Logger:

modul github.com/sirupsen/logrus

require (
	github.com/davecgh/go-spew v1.1.1 // indirect
	github.com/konsorten/go-windows-terminal-sequences v1.0.1
	github.com/pmezard/go-difflib v1.0.0 // indirect
	github.com/stretchr/objx v0.1.1 // indirect
	github.com/stretchr/testify v1.2.2
	golang.org/x/sys v0.0.0-20190422165155-953cdadca894
)

Beachten Sie, dass die Versionsnummern der Semver-Konvention entsprechen müssen (z. B. v1.2.1 anstelle von 20190812 oder 1.2.1) gemäß go-Befehl. Sie sollten es vermeiden, Pseudo-Versionen wie die oben gezeigt (v0.0.0-yyyymmddhhmmss-abcdefabcdef) zu verwenden – obwohl Pseudo-Versionen mit Commit-Hash eingeführt wurden, um Go-Module-Support für nicht markierte Projekte zu ermöglichen, sollten sie nur als Fallback-Mechanismus verwendet werden. Wenn die Abhängigkeiten, die Sie benötigen, Release-Tags haben, verwenden Sie diese Tags in Ihren require-Anweisungen.

In Ihrem eigenen Code können Sie dieses Go-Modul zusammen mit anderen Abhängigkeiten importieren:

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"os"

// Öffentliches Go-Modul für das Logging
	log "github.com/sirupsen/logrus"
)

Dann können Sie die Modulfunktionen in Ihrem GoLang-Code referenzieren:

   // Text zum Log senden
   log.Printf("Hello Log!")

2. Verwenden Sie GOPROXY, um die Unveränderlichkeit und Verfügbarkeit sicherzustellen

Sobald Sie Ihre GoLang-Abhängigkeiten als versionierte Module pflegen, können Sie sie als unveränderliche Instanzen behalten, indem Sie eine GOPROXY einrichten. Auf diese Weise können Sie immer garantieren, was eine bestimmte Version eines Moduls enthält, sodass Ihre Builds immer wiederholbar sind.

Werden Sie Go-Module verwenden, die öffentlich verfügbare Open Source-Pakete sind? Solche, die Sie erstellen und mit der OSS-Community teilen? Module, die Sie nur für Ihr Team privat vorhalten? Hier finden Sie Möglichkeiten, wie Sie schrittweise vorgehen oder alles auf einmal machen können und sicherstellen, dass diese unveränderten versionierten Module immer für Ihre Builds verfügbar sind.

GOLANG.ORG

Das Go-Team bei Google unterhält einen Satz von GOPROXY-Diensten für öffentlich verfügbare Module. Ab Go 1.13 wird der Modulspiegel proxy.golang.org automatisch als Standard-GOPROXY festgelegt, wenn Go installiert oder aktualisiert wird. Dieser Dienst wird auch durch einen Indexdienst zum Auffinden neuer Module unterstützt (index.golang.org) sowie durch eine globale go.sum-Datenbank zur Authentifizierung von Modulinhalten (sum.golang.org).

Die go.dev-Website wird ebenfalls vom Go-Team gepflegt und ist der Hub für Go-Benutzer, der zentralisierte und kuratierte Ressourcen aus dem gesamten Go-Ökosystem bereitstellt. Auf dieser Website können Sie pkg.go.dev unter Tausenden von Open-Source-Go-Paketen über eine bedienungsfreundliche Benutzeroberfläche suchen.

Artifactory Go-Registries

Auch wenn es gut ist, sie gemeinsam zu nutzen, müssen Sie wahrscheinlich auch die Verwendung einiger von Ihnen erstellter Go-Module auf Ihre Organisation beschränken. Mit Artifactory können Sie sowohl lokale als auch externe Go-Registries einrichten, sodass öffentliche und private Module gleichermaßen für Ihre Builds verfügbar sind.

Sie können den Go-Spiegeldienst als Proxy für eine externe Go-Registrierung in Artifactory verwenden, um Ihrem Build-System einen lokalen Cache zur Verfügung zu stellen. Dieser beschleunigt Ihre Builds und trägt zum Schutz vor Ausfällen der Netzwerkverbindung bei. Das Einrichten ist einfach.

Artifactory Go Registry

Sie können auch eine oder mehrere lokale Go-Registrierungen für Module konfigurieren, die Sie innerhalb Ihrer Organisation privat pflegen müssen.

Wenn Sie lokale und externe Registries in einem virtuellen Repository kombinieren, können Ihre Builds Go-Modulabhängigkeiten auflösen, die sowohl von einer öffentlichen Quelle stammen als auch von Modulen, die Sie privat erstellen und pflegen.

Mehr darüber, wie Sie Ihre GOPROXY for Artifactory-Repositories konfigurieren, erfahren Sie in diesem Blogbeitrag über die Auswahl Ihrer GOPROXY for Go-Module.

3. Artifactory-Repository-Layouts verwenden

Wo werden, wenn Sie Ihre App erstellen (mit go build), die erzeugten binären Artefakte gespeichert? Ihr Build-Prozess kann diese Zwischenergebnisse an Repositories in einem Binärdatei-Repository-Manager wie Artifactory übergeben.

Für diese dazwischenliegenden Go-Artefakte werden Sie die generischen Repositories von Artifactory verwenden. Eine intelligente Strukturierung dieser Repositories kann Ihnen dabei helfen, den Fluss Ihrer Binärdateien durch Entwicklung, Test und Produktion mit separaten Repositories für jede dieser Phasen zu kontrollieren. Um Sie dabei zu unterstützen, verwenden Sie die benutzerdefinierte Repository-Layout-Funktion von Artifactory mit diesen generischen Repositories.

Erstellen Sie ein benutzerdefiniertes Layout, das ähnlich wie das folgende aussieht:

[org]/[name<.+>]/[module]-[arch<.+>]-[baseRev].[ext]

Wenn Sie das benutzerdefinierte Layout konfigurieren, sollten Sie die Artefakt-Pfadauflösung testen, um zu bestätigen, wie Artifactory die Modulinformationen aus dem Pfad unter Verwendung der Layoutdefinitionen aufbaut.

4. Einmal bauen und heraufstufen

Wenn Sie Ihre Repositories für Ihre Go-Builds richtig eingerichtet haben, können Sie damit beginnen, diese effizient durch Ihre Pipeline-Stufen zu bewegen.

Viele Software-Entwicklungsverfahren erfordern bei jedem Staging-Übergang von Entwicklung, Test und Produktion einen vollständig oder teilweise neuen Build. Aber da die Entwickler den gemeinsam genutzten Code immer wieder ändern, bringt jeder neue Build neue Ungewissheiten mit sich; Sie können nicht sicher sein, was darin enthalten ist. Selbst mit Sicherheitsvorkehrungen zur Sicherstellung deterministischer Builds kann es erforderlich sein, die gleichen Qualitätsprüfungen in jeder Phase zu wiederholen.

Erstellen Sie stattdessen Ihre Go-basierten Microservices einmal und befördern Sie sie dann auf die nächste Stufe, sobald Beförderungskriterien wie Tests oder Scans erfüllt sind. Wenn Sie planen, Ihren Go-Microservice zu containerisieren, gilt das gleiche Prinzip: Jedes Docker-Image einmal zu erstellen und es über eine Reihe von Staging-Repositories heraufzustufen. Auf diese Weise können Sie garantieren, dass das, was getestet wurde, genau das ist, was für die Produktion freigegeben wird.

Build Promotion

5. Vermeiden Sie monolithische Pipelines

Anstelle einer einzigen, monolithischen Pipeline für Ihre App ist es besser, mehrere zu haben, wobei jede eine andere Schicht erstellt, testet, prüft und heraufstuft. Dadurch können Sie Ihren CI/CD-Prozess flexibler gestalten, wobei unterschiedliche Teams für jede Schicht verantwortlich sind. Außerdem wird ein ein "Fail Fast"-System gefördert, das hilft, Fehler frühzeitig zu erkennen.

Beispielsweise kann die Bereitstellung einer containerisierten Anwendung aus fünf Pipelines bestehen, was in der Regel der Fall ist:

  1. Erstellen Sie die Go-Anwendung mit der JFrog CLI. Diese Pipeline zieht den Quellcode, erstellt die Anwendung mit Artifactory-Repositories für Abhängigkeiten und Ausgabe-Binärdateien, testet und stuft von einem Dev-Repository zu einem Staging-Repository in Artifactory herauf.
  2. Erstellen Sie eine Basisschicht der containerisierten App, z. B. ein Docker-Framework. Je nach den Risiko- und Upgrade-Richtlinien des Unternehmens können statische oder dynamische Tags verwendet werden. Wenn zum Beispiel ein dynamisches Tag wie alpine:3.10 als Basisschicht des Docker-Frameworks verwendet wird, werden alle Patch-Updates bei jeder Erstellung des Docker-Frameworks einbezogen. Diese Pipeline umfasst die Phasen Erstellung, Test und Heraufstufung.
  3. Rufen Sie die heraufgestuften Artefakte ab, die von den vorherigen Pipelines erzeugt wurden, und erstellen Sie eine containerisierte App, zu der ebenfalls die Phasen Erstellung, Test, Scan und Heraufstufen gehören.
  4. Erstellen Sie ein Helm-Chart , das auf eine statisch getaggte und heraufgestufte Version einer containerisierten App verweist, die von einer vorherigen Pipeline produziert wurde.
  5. Stellen Sie die containerisierte Go-App mithilfe des Helm-Diagramms in Kubernetes bereit.

Artifactory fungiert als "Quelle der Wahrheit" für Ihre Go-Builds und bietet eine GOPROXY für öffentliche und private Module sowie die Speicherung kompilierter Binärdateien. Die Verwendung der JFrog CLI zur Erstellung Ihrer Go-App hilft dem Build-Prozess, mit Artifactory zu interagieren und die Build-Informationen zu erfassen, die Ihre Builds vollständig nachvollziehbar machen. Hier ist ein Beispiel-Snippet:

// Configure Artifactory
jfrog rt c

// Configure the project's repositories
jfrog rt go-config

// Build the project with go and resolve the project dependencies
from Artifactory.
jfrog rt go build --build-name=my-build --build-number=1

// Publish the package we build to Artifactory.
jfrog rt gp go v1.0.0 --build-name=my-build --build-number=1

// Collect environment variables and add them to the build info.
jfrog rt bce my-build 1

// Publish the build info to Artifactory.
jfrog rt bp my-build 1

 

Um mehr darüber zu erfahren, werfen Sie einen Blick auf unsere Beispiel-Demo-Dateien für GoLang CI/CD, die wir auf der GopherCon verwenden werden.

Go – Einfach

Wie Sie sehen, können einige einfache Best Practices bei der Verwaltung Ihrer GoLang-Anwendungen den Weg zu effektivem CI/CD erleichtern. Artifactory kann als der wesentliche Manager Ihrer Software-Artefakt-Lieferkette eine zentrale Rolle dabei spielen, diese Methoden in Ihre Software-Entwicklungspipeline einzuführen.

Noch Fragen? Wir beantworten sie gerne auf Gophercon. Tauchen Sie mit uns ein, um die besten Möglichkeiten zu erkunden, wie Sie Ihre Go-Anwendungen schnell und in höchster Qualität veröffentlichen können. Sie können aber auch die kostenlose Testversion von Artifactory nutzen, um die Möglichkeiten in der Praxis umzusetzen!