CLOUD & MANAGED SERVICESAWSCONTENT & COLLABORATIONCLOUD NATIVE
24/04/2023 • Bregt Coenen

Navigeren door het cloud-native landschap met Harbor Registry

In de snel veranderende IT-wereld neemt ACA Group voortdurend de tijd om innovatieve oplossingen en tools te onderzoeken en op die manier onze klanten de beste diensten aan te bieden. Onlangs nog deelden we onze ervaringen met Flux, een cloud-native continuous deployment tool die GitOps implementeert. 

Wat is Harbor?

Officieel logo van Harbor

Harbor is een cloud-native tool die werd ontworpen om de flexibiliteit, schaalbaarheid en veerkracht van de cloud te benutten. Het is een gecontaineriseerde oplossing die geavanceerde functies biedt, zoals een kwetsbaarheidsscanner en een artefactenregister. Harbor werkt op elke Kubernetes-gebaseerde oplossing in de openbare/privé cloud, maar ook op je lokale Kubernetes-cluster. Het is een self-managed oplossing die op je Kubernetes-cluster moet worden geïmplementeerd. Je kan de te implementeren componenten kiezen naargelang je behoeften. Voor sommige functies, zoals de kwetsbaarheidsscanner, is er keuze tussen verschillende tools.

De voordelen van Harbor registery

Waarom we zo enthousiast zijn om Harbor registery de komende maanden te gebruiken voor onze projecten?

  • Harbor is gemakkelijk te schalen: alle componenten kunnen worden geconfigureerd met meerdere replica's, waardoor onverwachte downtime wordt voorkomen en fail-over wordt geboden. Dat betekent dat je container images altijd beschikbaar zijn wanneer je ze nodig hebt.
  • Harbor is samenstelbaar: op die manier kan je enkel de workloads implementeren voor de functies die je gebruikt.
  • Harbor is niet alleen een container register: het kan bijvoorbeeld ook worden gebruikt als ChartMuseum om helm charts op te slaan.
  • Harbor is multi-tenant: projectspecifieke configuratie is mogelijk met specifieke quota en policy's.

Het heeft bovendien de meest complete reeks functies van alle container registers waar we ooit mee hebben gewerkt, zoals:

  • Verbinding met OpenID Connect.
  • Audit logging voor container pull-en push acties.
  • Policy's voor container images zoals tagbehoud en onveranderlijkheid van tags.
  • Replicatie naar andere registers (bijvoorbeeld ECR, ACR ...).
  • Webhooks kunnen worden geactiveerd wanneer specifieke acties plaatsvinden.
  • Een project kan dienstdoen als cache proxy voor openbare images.

Daarnaast heeft Harbor een goed gedocumenteerde API en gebruiken we een Terraform-provider om resources zoals projecten en gebruikers binnen Harbor te configureren met behulp van Terraform-code.

Zoals je ziet, heeft Harbor heel wat te bieden. ;-) In het volgende deel gaan we dieper in op enkele functies waar we het nog niet over hebben gehad, maar die zeker het vermelden waard zijn. 

Kwetsbaarheidsscanner voor container images

Een van de meest interessante functies is de ingebouwde kwetsbaarheidsscanner. Harbor heeft een ingebouwde kwetsbaarheidsscantool die automatisch container images scant op kwetsbaarheden wanneer ze naar het register worden gepusht. Er wordt een opdracht gepland wanneer een container image wordt gepusht en zodra het resultaat beschikbaar is, zal het zichtbaar zijn naast de container image.

Afbeelding van ingebouwde kwetsbaarheidsscantool

Je krijgt ook meer details over specifieke kwetsbaarheden die werden gevonden:

Voorbeelden van specifieke kwetsbaarheden

Vergeleken met het huidige containerregister dat we gebruiken, vormen deze inzichten over de kwaliteit van de containers een enorme verbetering voor ons. Door enkele extra configuraties door te voeren, kunnen we de ervaring met de kwetsbaarheidsscanner nog verder verbeteren. Enkele voorbeelden:

  • De pulling blokkeren van container images met kritieke CVE-kwetsbaarhden.
  • Regelmatig scans inplannen van images die al in het Harbor-register zijn opgeslagen.
  • Specifieke CVE's toestaan die momenteel niet kunnen worden verholpen.
  • Een webhook instellen om actie te ondernemen wanneer een CVE wordt gedetecteerd.
    .

Harbor gebruikt Trivy als standaard kwetsbaarheidsscantool, maar je kunt eenvoudig overschakelen naar een andere tool door deze op je cluster te installeren en te registreren in de Harbor-interface. Deze eenvoudige stappen volstaan om de beveiliging van containers naar een hoger niveau te tillen.

Container Image Signing

Harbor biedt ook een Container Image Signing-functie waarmee gebruikers de betrouwbaarheid van container images kunnen controleren. Als Notary of Cosign wordt gebruikt om container images te beveiligen, kan Harbor hun handtekeningen valideren, zodat je zeker weet dat er niet met de images werd geknoeid door andere onbevoegde bronnen dan jouw bouwtools. De Container Image Signing-functie wordt aangeduid met een groen vinkje in de Harbor-interface om aan te geven dat de image correct werd ondertekend.

Container image sigining functie

In deze blog leggen we niet uit hoe deze functie werkt, maar je vindt gedetailleerde documentatie over het proces via deze link.

Robot Accounts

Naast gewone gebruikers kunnen in Harbor ook robot accounts worden aangemaakt. Deze systeemgebruikers zijn niet gekoppeld aan persoonlijke accounts en worden vaak gebruikt door scripts en processen om zich te authenticeren bij het Harbor-register. Bij het bouwen van een container image bijvoorbeeld, kunnen scripts gebruik maken van een robot account om de container image naar het Harbor-register te pushen.

Afbeelding van een creatie van een robot account

Om de beveiliging te verhogen, kan voor robotgebruikers een vervaltijd worden ingesteld. De toegangsrechten kunnen bovendien worden beperkt tot een bepaald project en zelfs het toestemmingsniveau binnen dat project kan worden aangepast. Het auditlogboek registreert alle activiteiten die door het robot account worden uitgevoerd, net als bij gewone gebruikers.

Hoe ziet de setup van Harbor registery eruit?

Setup van een Harbor registery

We voeren het Harbor-register uit op EKS, de Kubernetes-service die door AWS wordt verstrekt. Omdat we gebruikmaken van AWS, kunnen we een aantal AWS-services gebruiken om enkele van de afhankelijkheden te leveren.

Deze setup bestaat uit 3 configuratielagen :

  1. AWS resources.
  2. Kubernetes resources.
  3. Resources binnen Harbor registery.
⬇️ Hieronder gaan we dieper in op deze configuratielagen.

1. De AWS-resources configureren

Binnen de ACA Group proberen we al onze infrastructuur als code te beheren. We gebruiken Terraform om alle afhankelijkheden voor ons Harbor-register in te stellen:

  • Route53 voor DNS.
  • RDS voor een multi-AZ postgres database.
  • ElastiCache voor een Redis-cluster met hoge beschikbaarheid voor sessiebeheer.
  • EFS voor multi-zone gedeelde opslag voor onze containers.
  • EKS voor de masterlaag van de Kubernetes-cluster.
  • Nodegroups verspreid over meerdere beschikbaarheidszones die zullen dienstdoen als rekencapaciteit voor onze Kubernetes-cluster.

Zodra deze resources beschikbaar zijn, kunnen we de Kubernetes-configuratie genereren en deze implementeren in onze Kubernetes-cluster.

2. De kubernetes-resources configureren

We gebruiken een helm chart om de Kubernetes-configuratiebestanden te genereren die nodig zijn om Harbor te configureren. Het gaat daarbij om YAML-bestanden die worden opgeslagen in GIT-repositories. Uiteindelijk zal Flux deze YAML-bestanden implementeren in de Kubernetes-cluster.

ℹ️ In een andere blog ontdek je alles over implementaties met Flux.

Resultaat? De volgende workloads worden aangemaakt op je Kubernetes-cluster.

  • Harbor core.
  • Harbor Portal, bedient de UI.
  • Harbor Registry, beheert het container register.
  • Harbor Jobservice, plant achtergrondtaken.
  • Harbor Trivy, CVE / kwetsbaarheidsscanner.
  • Notary resources, image signing.

Daarnaast worden verschillende Kubernetes-objecten gegenereerd, zoals Ingress, waarmee de user interface (UI) op je opgegeven URL wordt weergegeven. Als je meer details wilt, kan je Harbor rechtstreeks installeren op je lokale Kubernetes-cluster door het Helm-installatiecommando uit te voeren:

helm install my-release harbor/harbor

3. Resources configureren binnen Harbor

Nu het Harbor-register up and running is, kunnen we daarin efficiënt verschillende resources zoals projecten, robot accounts en behoudsbeleidsregels aanmaken.

Nogmaals, we willen deze resources beheren in code in plaats van ze aan te maken via de UI. Dit helpt ons niet alleen om de wijzigingen doeltreffend bij te houden, maar voorkomt ook mogelijke misconfiguraties door pull request-mechanismen.

Met zijn uitgebreide en goed gedocumenteerde API maakt Harbor het voor heel wat tools mogelijk om custom add-ons te ontwikkelen. Door onze expertise op het vlak van Terraform-code, geven we de voorkeur aan de Terraform Harbor add-on om de resources binnen het Harbor-register efficiënt te beheren.

Het volgende voorbeeld creëert een project binnen Harbor:

resource "harbor_project" "myproject" {
  name                    = "myproject"
  public                  = false
  vulnerability_scanning  = true
  enable_content_trust    = true
  deployment_security     = ""
}

Het Harbor register gebruiken

Na de implementatie van het Harbor-register en de aanmaak van projecten, wordt het een functioneel containerregister dat op dezelfde manier werkt als elk ander containerregister. Om container images naar het Harbor-register te pushen, kunnen conventionele build jobs worden gebruikt. De build job vereist echter authenticatiecredentials, meestal van een robot account.

Vervolgens moet je de configuratie van je jenkins-, tekton-, BitBucket Pipeline-, GitHub-actie of soortgelijke job bijwerken om het juiste project en de Harbor-URL te bepalen, bijvoorbeeld registry.example.be/myproject.

Het push-commando kan ook gevonden worden in de Harbor-interface:

Harbor interface

Nadat de container image naar het Harbor-register werd gepusht, kan deze vanaf andere locaties worden gepulled.

Om een image naar je lokale machine te pullen met Docker kan je de volgende commando's gebruiken:

docker login
docker pull registry.example.be/myproject/image:version

Om de container image in een Kubernetes-omgeving te gebruiken, maak je eerst een Secret aan van het type "docker-registry" dat de nodige credentials omvat voor de implementatie van de container image. Omdat een Secret specifiek is voor een namespace, moet je dit commando uitvoeren voor elke namespace die een container uit het Harbor-register gebruikt.

kubectl -n NAMESPACE create secret docker-registry registry.example.be --docker-server=registry.example.be --docker-username='firstname.lastname' --docker-password='mysupersecurepassword' --docker-email=me@company.be

Nu kan je naar de container image verwijzen binnen je Deployment, StatefulSet, Job ... Het imagePullSecrets-gedeelte verwijst naar het Secret dat in de bovenstaande stap werd aangemaakt.


        image: registry.example.be/myproject/image:version
…
    imagePullSecrets:
    - name: registry.example.be

Conclusie

Deze blog zette de vele voordelen en functies van het Harbor-register op een rijtje. We deelden ook onze manier van werken om het containerregister te configureren en te gebruiken.

Bij ACA gebruiken we Harbor als het containerregister voor een van onze belangrijkste projecten en zijn we er volop mee bezig om het als standaard register in te voeren voor nieuwe projecten. Zodra het helemaal is klaargestoomd, zullen we een plan opstellen om andere actieve projecten te migreren. Ons doel bestaat erin de stabiliteit, beschikbaarheid en veiligheid voor onze klanten te verbeteren.

Wil je meer weten over het Harbor-register, neem dan gerust contact met ons op!