Einführung
Jenkins startet normalerweise als nicht initialisierter Controller. Der erste Administrator schaltet den Controller mit dem anfänglichen Passwort frei, erstellt ein dauerhaftes Administratorkonto und bestätigt, dass Jenkins betriebsbereit ist.
In diesem Lab üben Sie diesen Workflow für den ersten Start in einer sicheren Umgebung. Da der Haupt-Jenkins-Dienst in der VM bereits für andere Labs konfiguriert ist, starten Sie einen zweiten, temporären Jenkins-Controller auf Port 18080. Sie werden nur diesen temporären Controller initialisieren, das Ergebnis überprüfen und ihn anschließend wieder entfernen.
Starten eines isolierten, frischen Jenkins-Controllers
In diesem Schritt starten Sie einen neuen Jenkins-Controller, ohne den Haupt-Jenkins-Dienst zu beeinträchtigen. Ein Jenkins-Controller speichert seine Konfiguration unter /var/jenkins_home. Daher verwendet dieses Lab ein separates Docker-Volume namens jenkins-init-lab-home.
Der folgende docker run-Befehl startet den temporären Controller im Hintergrund. Die Option -d steht für den Detached-Modus, --name gibt dem Container einen festen Namen, -p 18080:8080 veröffentlicht Jenkins auf dem Host-Port 18080 und -v bindet das isolierte Jenkins-Home-Volume ein.
docker run -d \
--name jenkins-init-lab \
-p 18080:8080 \
-v jenkins-init-lab-home:/var/jenkins_home \
jenkins/jenkins:latest
Docker gibt die neue Container-ID aus. Da die ID bei jedem Start anders ist, ist jeder lange hexadezimale Wert akzeptabel.
Warten Sie als Nächstes, bis Jenkins auf HTTP-Anfragen antwortet. Die folgende Schleife fragt den lokalen Controller so lange nach /login ab, bis ein HTTP-Statuscode zurückgegeben wird. Eine 200-Antwort bedeutet, dass die Anmeldeseite verfügbar ist.
until [ "$(curl -s -o /dev/null -w '%{http_code}' http://localhost:18080/login)" = "200" ]; do
echo "Warten auf den temporären Jenkins-Controller..."
sleep 5
done
Sie sollten die Wartemeldung einige Male sehen, danach kehrt die Eingabeaufforderung zurück. Überprüfen Sie den Container und das Port-Mapping:
docker ps --filter name=jenkins-init-lab --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}'
Die Ausgabe sollte den Containernamen und den Port 18080 enthalten:
NAMES STATUS PORTS
jenkins-init-lab Up ... 0.0.0.0:18080->8080/tcp, ...
Abrufen des anfänglichen Administrator-Passworts
In diesem Schritt rufen Sie das Einmal-Passwort ab, das Jenkins für den ersten Administrator erstellt. Jenkins speichert dieses Passwort im Home-Verzeichnis des Controllers unter /var/jenkins_home/secrets/initialAdminPassword.
Verwenden Sie docker exec, um cat innerhalb des temporären Jenkins-Containers auszuführen, und speichern Sie das Passwort in Ihrem Projektverzeichnis:
docker exec jenkins-init-lab cat /var/jenkins_home/secrets/initialAdminPassword > /home/labex/project/jenkins-init-password.txt
Der Befehl verwendet die >-Umleitung, um die Ausgabe in eine Datei zu schreiben. Dadurch bleibt das Passwort für die nächsten Schritte verfügbar, ohne dass eine Shell-Variable erforderlich ist.
Zeigen Sie nur die ersten paar Zeichen an, um sicherzustellen, dass die Datei nicht leer ist, ohne den vollständigen Wert in Ihrem Terminalverlauf preiszugeben:
cut -c1-8 /home/labex/project/jenkins-init-password.txt
Sie sollten acht Zeichen des Passworts sehen, ähnlich wie hier:
1a2b3c4d
Erstellen eines dauerhaften Administratorkontos
In diesem Schritt verwenden Sie das anfängliche Passwort, um einen echten Jenkins-Administrator namens lab-admin zu erstellen. Das erste Passwort ist nur für die Einrichtung gedacht. Ein normales Administratorkonto ist das, was Teams nach der Initialisierung des Controllers verwenden.
Jenkins schützt Formularübermittlungen mit einem Crumb-Token. Ein Crumb ist an dieselbe Browser- oder HTTP-Sitzung gebunden, die es angefordert hat. Daher speichert der folgende Befehl auch Jenkins-Cookies in einer Cookie-Datei.
INIT_PASSWORD=$(tr -d '\r\n' < /home/labex/project/jenkins-init-password.txt)
COOKIE_JAR=/home/labex/project/jenkins-init-cookies.txt
curl -fsS -c "${COOKIE_JAR}" -u "admin:${INIT_PASSWORD}" \
http://localhost:18080/crumbIssuer/api/json \
> /home/labex/project/jenkins-init-crumb.json
Der nächste Befehl sendet ein kleines Groovy-Skript an Jenkins. Das Skript erstellt ein privates Sicherheits-Realm, fügt den Benutzer lab-admin hinzu, gewährt angemeldeten Benutzern die volle Kontrolle und markiert den Einrichtungsassistenten als abgeschlossen.
CRUMB_FIELD=$(sed -n 's/.*"crumbRequestField":"\([^"]*\)".*/\1/p' /home/labex/project/jenkins-init-crumb.json)
CRUMB_VALUE=$(sed -n 's/.*"crumb":"\([^"]*\)".*/\1/p' /home/labex/project/jenkins-init-crumb.json)
cat > /home/labex/project/initialize-controller.groovy <<'GROOVY'
import jenkins.model.Jenkins
import jenkins.install.InstallState
import hudson.security.HudsonPrivateSecurityRealm
import hudson.security.FullControlOnceLoggedInAuthorizationStrategy
def jenkins = Jenkins.get()
def realm = new HudsonPrivateSecurityRealm(false)
realm.createAccount('lab-admin', 'LabEx-Admin-123')
jenkins.setSecurityRealm(realm)
def strategy = new FullControlOnceLoggedInAuthorizationStrategy()
strategy.setAllowAnonymousRead(false)
jenkins.setAuthorizationStrategy(strategy)
jenkins.setInstallState(InstallState.INITIAL_SETUP_COMPLETED)
jenkins.save()
println('created lab-admin and completed setup')
GROOVY
curl -fsS -b "${COOKIE_JAR}" -u "admin:${INIT_PASSWORD}" \
-H "${CRUMB_FIELD}: ${CRUMB_VALUE}" \
--data-urlencode "script@/home/labex/project/initialize-controller.groovy" \
http://localhost:18080/scriptText \
> /home/labex/project/jenkins-init-result.txt
Lesen Sie die Ergebnisdatei:
cat /home/labex/project/jenkins-init-result.txt
Die erwartete Meldung lautet:
created lab-admin and completed setup
Bestätigen des initialisierten Controller-Dashboards
In diesem Schritt bestätigen Sie, dass der temporäre Controller nicht mehr nur aus einem Entsperrbildschirm besteht. Ein korrekt initialisierter Controller sollte den Benutzer lab-admin authentifizieren und die Jenkins-Hauptseite zurückgeben.
Verwenden Sie curl mit -u zur Authentifizierung. Die Option -o schreibt das HTML in eine Datei, und -w '%{http_code}' gibt nur den HTTP-Statuscode aus.
curl -s -u 'lab-admin:LabEx-Admin-123' \
-o /home/labex/project/jenkins-init-dashboard.html \
-w '%{http_code}\n' \
http://localhost:18080/
Der Statuscode sollte sein:
200
Suchen Sie nun auf der gespeicherten Dashboard-Seite nach typischem Jenkins-Text:
grep -o -E 'Dashboard|Welcome to Jenkins|Jenkins' /home/labex/project/jenkins-init-dashboard.html | head
Sie sollten mindestens eine übereinstimmende Zeile sehen. Das genaue HTML kann sich zwischen Jenkins-Versionen ändern, aber es sollte die Seite als Jenkins identifizieren.
Stoppen und Entfernen des temporären Controllers
In diesem Schritt bereinigen Sie den temporären Controller. Die Bereinigung ist wichtig, da der Haupt-Jenkins-Dienst derjenige ist, der von den anderen Jenkins-Labs verwendet wird, und der temporäre Controller nur zum Üben der ersten Initialisierung diente.
Stoppen und entfernen Sie zuerst den temporären Container:
docker rm -f jenkins-init-lab
Entfernen Sie dann das isolierte Jenkins-Home-Volume:
docker volume rm jenkins-init-lab-home
Überprüfen Sie abschließend, ob der temporäre Controller entfernt wurde:
docker ps -a --filter name=jenkins-init-lab --format '{{.Names}}'
Dieser Befehl sollte nichts ausgeben. Ein leeres Ergebnis bedeutet, dass kein Container mit diesem Namen mehr vorhanden ist.
Zusammenfassung
Sie haben einen isolierten Jenkins-Controller gestartet, dessen anfängliches Administrator-Passwort abgerufen, ein dauerhaftes Administratorkonto erstellt, bestätigt, dass das initialisierte Dashboard erreichbar ist, und den temporären Controller bereinigt. Dies ist der grundlegende Workflow für die erste Initialisierung eines einsatzbereiten Jenkins-Controllers.