Ein Git Repository in einen Kubernetes Container mounten

Es gibt in Kubernetes https://kubernetes.io/docs/concepts/storage/volumes/#gitrepo um ein Git Repository einzufügen. Diese Storage Art ist aber bereits als deprecated markiert und wird nicht mehr empfohlen.

Git Repos lassen sich dennoch recht einfach als Volume in einen Container einbinden. Man muss dafür einen InitContainer verwenden, der das Repository auscheckt und in einem Verzeichnir bereitstellt. Diese mounted man per emptyDir{} in den Container. Nun stehen die zuvor ausgecheckten Dateien aus dem Repository im Container bereit.

Beispiel

# Beispiel wie man InitContainers für die Bereitstellung
# eines GIT Repository nutzt. Die GitRepo Volumes sind
# deprecated und sollten nicht mehr verwendet werden. Dieses
# Beispiel nutzt den Ansatz das Git klonen in einem
# InitContainer auszuführen.
apiVersion: v1
kind: Pod
metadata:
  name: git-repository-demo
  annotations:
    seccomp.security.alpha.kubernetes.io/pod: 'docker/default'
spec:
  initContainers:
    # Dieser InitContainer klont das gewünschte Repository
    # in das EmptyDir Volume Verzeichnis
    - name: git-clone
      image: alpine/git # Alpine Linux mit Git
      args:
        - clone
        - --single-branch
        - --
        - https://github.com/test/testrepo # Das Repository
        - /repo # Put it in the volume
      securityContext:
        runAsUser: 1 # Hier ggf. Anpassungen vornehmen
        allowPrivilegeEscalation: false
        readOnlyRootFilesystem: true
      volumeMounts:
        - name: git-repo
          mountPath: /repo
  containers:
    # Hier muss das richtige Image angegeben werden
    # das genutzt werden soll. Bsp. BusyBox
    - name:  busybox
      image: busybox
      args: ['tail','-f','/dev/null'] # Demo tue nichts
      volumeMounts:
        - name: git-repo
          mountPath: /repo
  volumes:
    - name: git-repo
      emptyDir: {}

Speicherung der Credentials für GIT auf der Komandozeile

Oft ist es so, dass man auf einem Server (wo man nur die Kommandozeile zur Verfügung hat) sehr mühselig jedes Mal beim Pushen oder Pullen die Credentials einzugeben. GIT kann diese dauerhaft speichern, was den Komfort deutlich erhöhen kann. Ob dieses zu einem Sicherheitsrisiko führt, ist hier nicht Thema und wird nicht weiter betrachtet.

File Storage einrichten

git config --global credential.helper 'store --file ~/.my-credentials'

Ein privates Repository von GitHub per PAT clonen

Möchte man ein privates Repository von GitHub auschecken, so kann man Zugriff auf das Repository über ein PAT (Personal Access Token) erhalten.

Dazu muss folgendes Schema angewendet werden:

git clone https://xxxxzzzzxxxxzzzzxxxxzzzzxxxxzzzzxxxxzz:@github.com/MaxMeier/Projekt.git

Wichtig ist der :, da dieser ein leeres Passwort signalisiert, welches bei einem PAT nicht benötigt wird.

Git Credentials

Es ist auf Dauer müßig, immer und immer wieder die Credentials einzugeben. Daher gibt den internen Credentials Store von Git, aber dieser speichert nur SSH Credentials.

git config --global credentials.helper 'store --file ~/.git-credentials'

Lösung für HTTP(s) Verbindungen

Es gibt im AUR das Paket git-credential-gnome-keyring. Der Helper ermöglicht es auch für HTTP Verbindungen die Credentials zu speichern.

yaourt -S --noconfirm git-credential-gnome-keyring

Nun muss der Helper nur noch git bekannt gemacht werden:

git config --global credential.helper /usr/lib/git-core/git-credential-libsecret

Jetzt speichert Git die Credentials im Gnome-Keyring.

Installation

yaourt -S --noconfirm smartgit

Openrepo

Oft bewegt man sich in der Konsole in einem Git Repository und möchte dieses mit SmartGit verwenden. Normalerweise öffnet man SmartGit und verwendet Open Repository um ein existierendes Repository zu öffnen. Es gibt aber den CLI Parameter open. Dieser öffnet das Repository das als Parameter übergeben worden ist. Hier mag SmartGit keine Verzeichnisse die per Symlink geöffnet werden (z.B. Angabe von .). Das Eval von $(pwd) zur Hilfe wandelt das aktuelle Verzeichnis in einen absoluten Pfad um. Das ganze in ein Shell Skript openrepo verpackt, macht es jetzt sehr einfach ein Repository aus dem Verzeichnis heraus zu öffnen.

#!/bin/bash

#
# opens git repository in current dir in smartgit
#
smartgit --open $(pwd)

Pfade anpassen

Das Skript liegt im lokalen bin Pfad im Homeverzeichnisses (~/bin). Damit der Pfad beim starten einer shell eingebunden wird, empfiehlt es sich ein Skript local-user-bin.sh im /etc/profiles.d-Verzeichnis anzulegen mit folgendem Inhalt:

# If user ID is greater than or equal to 1000 & if ~/bin exists and is a directory & if ~/bin is not already in your $PATH
# then export ~/bin to your $PATH.
if [[ $UID -ge 1000 && -d $HOME/bin && -z $(echo $PATH | grep -o $HOME/bin) ]]
then
    export PATH="${PATH}:$HOME/bin"
fi

Gitea Dienst unter git.xxx.org soll mit SSL Verschlüsselung ausgestattet werden. Es werden verschiedene Domains auf dem Server bedient. Als Reverse Proxy ist bereits NginX vorgeschaltet. Daher muss nicht einmal die Gitea Konfiguration geändert werden. Es kann über NginX die Verschlüsselung mit SSL geschehen.

Die LetsEncrypt Initiative macht es sehr einfach Webseiten mit einem gültigen Zertifikat auszustellen. Dazu gibt es verschiedene Clients die die Verwaltung vornehmen. Ich verwende hier den Certbot.

Installation Certbot unter Arch Linux

yaourt -S --noconfirm certbot-nginx

Erstellen eines Zertifikates

Das Plugin für Certbot parst das ConfigFile von NginX und zeigt alle Domains an, die auf dem Server einen eigenen Serverblock besitzen. Da wir die Konfiguration nicht verändern wollen, rufen wir den certbot mit dem Parameter certonly auf. Damit wird nur ein Zertifikat für die gewählten Domains erstellt. Hierfür muss man natürlich im Besitz der Domain sein.

certbot --nginx certonly

[root@server conf]# certbot --nginx certonly
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator nginx, Installer nginx
Enter email address (used for urgent renewal and security notices) (Enter 'c' to
cancel): xxx@web.de

-------------------------------------------------------------------------------
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v01.api.letsencrypt.org/directory
-------------------------------------------------------------------------------
(A)gree/(C)ancel: A

-------------------------------------------------------------------------------
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about EFF and
our work to encrypt the web, protect its users and defend digital rights.
-------------------------------------------------------------------------------
(Y)es/(N)o: Y

Which names would you like to activate HTTPS for?
-------------------------------------------------------------------------------
1: ----
2: git.xxx.org
3: ----
-------------------------------------------------------------------------------
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel): 2
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for mrpeacockgit.duckdns.org
2018/06/02 09:50:20 [notice] 9946#9946: signal process started
Waiting for verification...
Cleaning up challenges
2018/06/02 09:50:25 [notice] 9948#9948: signal process started

IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/git.xxx.org/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/git.xxx.org/privkey.pem
Your cert will expire on 2018-08-31. To obtain a new or tweaked
version of this certificate in the future, simply run certbot
again. To non-interactively renew *all* of your certificates, run
"certbot renew"
- Your account credentials have been saved in your Certbot
configuration directory at /etc/letsencrypt. You should make a
secure backup of this folder now. This configuration directory will
also contain certificates and private keys obtained by Certbot so
making regular backups of this folder is ideal.
- If you like Certbot, please consider supporting our work by:

Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
Donating to EFF:                    https://eff.org/donate-le

Wie man in der Ausgabe erkennen kann, legt der certbot unterhalb /etc/letsencrypt/live/ für jede Domain ein Verzeichnis an. In diesem wird das Zertifikat und der private Schlüssel abgelegt.

Einbinden des Zertifikates in NginX

Die Konfiguration für den Gitea Service ist in eine eigene Datei ausgelagert. Diese wird per Include Anweisung eingebunden. Hierfür ist ein separates conf-Verzeichnis unterhalb /etc/nginx/ ratsam.

#
# Gitea Service
#
include conf/git.conf;

Damit alte Links bzw. der direkte Aufruf mit dem unverschlüsselten HTTP Protokoll weiterhin funtkioniert muss eine 301 Weiterleitung eingerichtet werden.

# Redirect http -> https
server {
    listen 80;
    server_name git.xxx.org;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;

    server_name git.xxx.org;

    # logging
    error_log /var/log/nginx/gitea_error.log debug;
    access_log /var/log/nginx/gitea_access.log;

    client_max_body_size 100M; # Push large Objects to gitea

    # Configuration for letsencrypt
    location ^~ /.well-known/acme-challenge/ {
        allow all;
        root /var/lib/letsencrypt/;
        default_type "text/plain";
        try_files $uri =404;
    }

    location / {
        proxy_pass http://127.0.0.1:3000;
    }

    # SSL
    ssl on;
    ssl_certificate /etc/letsencrypt/live/git.xxx.org/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/git.xxx.org/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}

Konfiguration von Gitea

Da in diesem Beispiel NGinX als Reverse Proxy vorgeschaltet ist, muss hier nur die Root URL angepasst werden. Es ist HTTPS als Protokoll und 443 als Port anzugeben. Gitea selbst arbeitet weiterhin mit dem HTTP Protokoll.

[server]
; Listen protocol. One of 'http', 'https', 'unix' or 'fcgi'.
PROTOCOL                   = http
DOMAIN                     = git.xxx.org
ROOT_URL                   = https://git.xxx.org:443/

Wildcard Zertifikate

In einem anderen Artikel beschreibe ich wie man lokale Dienste mit einem Wildcard Zertifikat absichern kann. Hierfür setzte ich den freien DNS Dienst DuckDNS ein.

SmartGIT

SmartGIT ist ein umfangreicher GIT Client. SmartGIT ist in Java geschrieben und benötigt bis Version 17.1 Java 8. Hat man ein aktuelles ArchLinux oder Manjaro System, dann ist Java in der 9 an Bord.

Java unter ArchLinux

ArchLinux unterstützt parallele Installation von Java Versionen. Diese befinden sich unter dem Vereichnis /usr/lib/jvm/. Der Pfad zur JRE kann im bin Verzeichnis von SmartGIT angegeben werden. Dazu muss in der smartgit.vm die Variabel jre gesetzt werden.

jre=/usr/lib/jvm/java-8-jdk/jre/