CONTINUOUS DELIVERY OF CONTINUOUS DELIVERY Gerd Aschemann TUTORIAL / SCHULUNG Gerd Aschemann [email protected] http://aschemann.net twitter: @GerdAschemann Slack: https://jvm­german.slack.com/ (Channel: #build- systems) AGENDA Vagrant-Setup! Stufe 0: Motivation/Setup/Architektur… (45 Min) Stufe 1: Von der eigenen VagrantBox zum Build-Server und zurück (60 + 30 Min) Stufe 2: Aufbau Jenkins (60 Minuten) Stufe 3: Automatisierung Jobs (90 Minuten) Stufe 4: Miniprojekt mit SCM-Manager und Maven Release (60 Minuten) Abschluß: Diskussion/Kleinere Ergänzungen/Ausblick/Feedback (15 Minuten) Ein großer Teil der Umsetzung wird im Laufe des Tutorials als Git- Repository bereitgestellt! MOTIVATION Einführung/Vorstellungsrunde, 10 Min.) Setup (Vagrant, 10 Min.) Continuous Delivery (5 Min.) Architektur (20 Min.) SETUP (VAGRANT + VIRTUALBOX) Details folgen später! Vagrant Install Vagrant Init Vagrant Start Vagrant SSH Vagrant Destroy VAGRANT INSTALL Download (Vagrant + VirtualBox) + Installation gemäß Anleitung(en) https://www.vagrantup.com/downloads.html https://www.virtualbox.org/wiki/Downloads Alternative: Installation über Package Manager Debian/Ubuntu: [sudo] apt-get install vagrant virtualbox VAGRANT INIT Arbeitsverzeichnis anlegen, z.B. demo, und Vagrant initialisieren $ mkdir demo $ cd demo $ vagrant init -f bento/ubuntu-16.04 lädt Image und erzeugt eine Datei Vagrantfile # -*- mode: ruby -*- # vi: set ft=ruby : # All Vagrant configuration is done below. The "2" in Vagrant.configure ... Vagrant.configure(2) do |config| # ... config.vm.box = "bento/ubuntu-16.04" ... VAGRANT START Vagrant wird gestartet mit $ vagrant up Erzeugt zahlreiche Ausgaben: Bringing machine 'default' up with 'virtualbox' provider... ==> default: Importing base box 'bento/ubuntu-16.04'... ... ==> default: Machine booted and ready! ==> default: Checking for guest additions in VM... ... ==> default: Mounting shared folders... ... VAGRANT SSH Anschließend kann man sich auf der VM einloggen $ vagrant ssh ... vagrant@vagrant-ubuntu-trusty-64:~$ Hier kann man nun als Benutzer vagrant arbeiten, privilegierte Operationen können mit sudo ausgeführt werden, z.B. vagrant $ sudo apt-get install screen Das Arbeitsverzeichnis (demo) wird als /vagrant in die VM eingeblendet (Datei-Austausch, Provisionierung, … ) VAGRANT STOP / DESTROY Nach dem Ausloggen (oder von einer anderen Shell) kann man die VM zerstören: $ vagrant destroy Oder auch nur anhalten $ vagrant suspend Und weiterlaufen lassen $ vagrant resume WAS IST CONTINUOUS DELIVERY? Frei nach Martin Fowler Software ist jederzeit deploybar Deploybarkeit hat Vorrang vor Erweiterungen Aussagefähigkeit über Production-readiness nach jedem Change Push-button Deployment beliebiger Versionen in beliebige Umgebungen Hohe Automatisierung Continuous Delivery ist NICHT Continuous Deployment! CONTINUOUS DELIVERY CYCLE (?) Build Deploy Cycle??? Release? Test CONTINUOUS DELIVERY CASCADE (???) no no Develop (OK?) yes (OK?) yes Int. Test UAT Production +Unit Test CONTINUOUS DELIVERY LOOP (!) Feedback (loop?) Develop Int. Test UAT Production +Unit Test RÜCKBLICK: DEVELOPMENT Development Code Build Test no (OK?) yes Commit/Push DEVELOPMENT NOCH EINFACHER Development Code Test no (OK?) yes Commit/Push CONFIGURATION MANAGEMENT Config Mgmt. Configure Test no (OK?) yes Use JENKINS SCM­MANAGER SO NICHT: PET BESSER SO: CATTLE CM SYSTEMATISCH: WAS FEHLT? Configuration Management am "lebenden Herzen" Feedback-Loop ist sehr kurz! Feedback-Loop ist sehr lang!? "Blood, Sweat, and Tears"-Management Keine systematische Qualitätssicherung! CM EBENEN Infrastruktur: OS/Linux (Windows, OSX, Android, Embedded, … ) Plattform: Build Server (Jenkins, Bamboo, Travis, … ) Source Code Repo (Apache/SVN, SCM­Manager, Gitlab, Github, … ) Artifact Repo (Nexus, Artifactory, … ) QS-Management (Findbugs/Checkstyle/PMD, Surefire/Failsafe, … Sonar Qube) Application: Maven, Gradle, … PLATFORM AS CODE (PAC) Vagrant Puppet (+ Shell + Perl) Jenkins (+ Maven) Docker/Nexus ZIEL­ARCHITEKTUR (VEREINFACHT) «Linux/Windows/OSX/...» Developer-PC develop local deploy PaC Development commit/push PaC DevOps-Engineer «Linux» Meta-Build-Server (james) check out PaC check out PaC Source Code Repository Operator deliver Jenkins deliver Test Prod DETAIL­VIEW: DEVELOPER DevOps-Engineer Change «Linux/Windows/OSX/...» DevOps-PC LocalDevelopment «Git» Test Test Local_Repository vagrant up / vagrant provision «Vagrant» LocalVM pull/checkout «Jenkins» upload/download «Nexus» «SCM-Manager» Jenkins Local Nexus Local SCM-Manager Local DETAIL­VIEW: META­BUILD­SERVER «Linux» Meta-Build-Server poll «SCM-Manager» Source Code Repository Jenkins check out Test «Git» Test Test Test_Repository vagrant up / vagrant provision «Vagrant» TestVM pull/checkout «Jenkins» upload/download «Nexus» «SCM-Manager» Jenkins_Test Nexus Test SCM-Manager_Test DETAIL­VIEW: PRODUKTION Operator pull/checkout «Linux» Production Server «Git» Production_Repository deploy deploy deploy pull/checkout «Jenkins» upload/download «Nexus» «SCM-Manager» Jenkins Production Nexus Production SCM-Manager Production VAGRANT Setup virtueller Maschinen Provider Lokal/On-Premise: VirtualBox, libvirt (Qemu/KVM), Parallels, VMware, … Cloud: AWS Provisioner Default: Shell Infrastruktur CM-Tools: Puppet, Chef, Ansible, SaltStack?, … VAGRANTFILE Ruby-Syntax Provider + Box Konfiguration Name Speicher Netzwerk (Port forwards) Dateisystem(e): /vagrant Provisioner VAGRANTFILE (SAMPLE) Vagrant.configure(2) do |config| # ... config.vm.box = "ubuntu/trusty64" config.vm.provider "virtualbox" do |vbox, override| vbox.name = "demo-jugf" vbox.memory = 2048 override.vm.network "private_network", ip: "192.168.50.17", virtualbox__intnet: true # Jenkins override.vm.network "forwarded_port", guest: 8080, host: "17080" # Nexus override.vm.network "forwarded_port", guest: 8081, host: "17081" ... STUFE 1: VAGRANT→GIT→SCM­ MANAGER→JENKINS Vagrant ins Git Git in den SCM-Manager Job in Jenkins anlegen Job ausführen VAGRANT→GIT Git Repository anlegen git init Vagrantfile einchecken git add Vagrantfile git commit -m'Vagrant started' Optional: .gitignore anlegen und einchecken (s.u.) GIT→SCM (ANLEGEN) Repository im SCM-Manager anlegen GIT→SCM (ZUGRIFFSRECHTE) Zugriffsrechte im SCM-Manager vergeben: Reiter: Permissions Account hinzufügen (+) Keine Gruppe (?) Name: demo Permissions: WRITE GIT→SCM (SCREENSHOT) PUSH LOCAL REPOSITORY Remote-Repository URL hinzufügen Jeder Nutzer/Gruppe bekommt ein eigenes Repository <reponame> git remote add origin http://demo@james:8082/scm/git/<reponame> User/Host/Port/Pfad beachten! Push des aktuellen Standes git push --set-upstream origin master JENKINS: JOB ANLEGEN Neuen Job tutorial-<reponame> als Freestyle project anlegen JENKINS: CHECKOUT AUS GIT Source Code Management: Git mit URL: http://localhost:8082/scm/git/<reponame>; Achtung: Ohne User! Ggf. anderer Host/Port? Credentials: jenkins/* (ggf. mit Add hinzufügen) JENKINS: CHECKOUT AUS GIT (SC) JENKINS: BUILD TRIGGER + ANSI COLOR Build-Trigger (ähnlich crontab-Eintrag) Poll-SCM: Schedule H/3 * * * * H/3 verteilt Minute gleichmäßig auf Stunde * verteilen Stunde/Tag/Monat/Wochentag Ansi-Color (Plugin) wg. Vagrant JENKINS: BUILD TRIGGER + ANSI COLOR (SC) JENKINS: BUILD EXECUTE SHELL Build Execute shell Aktuell nur vagrant up Save! JENKINS: BUILD EXECUTE SHELL (SC) JENKINS: FERTIGER JOB Let’s Go: Build Now JENKINS: CONSOLE OUTPUT DISKUSSION 1A Wie unterscheiden wir verschiedene Instanzen in der VBox? DISKUSSION 1B Was passiert bei erneutem Start? DISKUSSION 1C Wie kommt man von außen auf die VM? Wie stoppt man die VM? STUFE 1A: VAGRANT­BOXEN MIT NAMEN Vagrantfile Vagrant.configure(2) do |config| config.vm.box = "bento/ubuntu-16.04" config.vm.hostname = 'tutorial-<reponame>' // (1) config.vm.provider "virtualbox" do |config| config.name = "tutorial-<reponame>" // (2) end end 1 Der Hostname ist nicht der Name der VirtualBox 2 Hier bekommt die Box einen Namen, das Setzen ist abhängig vom Provider AUSFLUG: IGNORIEREN VON DATEIEN FÜR GIT Kleiner Tipp für git: Datei .gitignore mit z.B. .vagrant/ anlegen und einchecken: .gitignore .vagrant/ $ git add .gitignore $ git commit -m'Ignore local vagrant files' STUFE 1B: RE­BUILD IM JENKINS? Problem: Box läuft schon im Jenkins Symptom: vagrant up macht nichts Lösung: Vor dem vagrant up noch ein vagrant destroy -f ausführen STUFE 1C: WIE KOMMT MAN VON AUSSEN AUF DIE BOX? Per Port-Mapping kann man die Box von außen erreichen (neben dem dynamischen Mapping des ssh-Ports)? Vagrantfile Vagrant.configure(2) do |config| config.vm.box = "bento/ubuntu-16.04" config.vm.hostname = 'demo' config.vm.provider "virtualbox" do |config, override| // (1) config.name = "demo" # SSH access override.vm.network "forwarded_port", guest: 22, host: "10022" // (1) end end 1 override beachten! Wenn alle den gleichen Port nehmen, haben wir im Jenkins ein Problem! PROVISIONIERUNG MIT VAGRANT PER SHELL Vagrant kann nach Start der VM eine weitere Provisionierung durchführen. Vagrantfile Vagrant.configure(2) do |config| config.vm.box = "bento/ubuntu-16.04" config.vm.hostname = 'demo' config.vm.provider "virtualbox" do |config, override| config.name = "demo" # SSH access override.vm.network "forwarded_port", guest: 22, host: "10022" end config.vm.provision "shell", path: "apt-update.sh" // (1) end 1 Beispielsweise kann ein Shell-Skript ausgeführt werden: PROVISION: APT-GET UPDATE … apt-update.sh #!/bin/bash set -eu sudo apt-get update sudo apt-get -qq dist-upgrade PROVISIONIERUNG: ALTERNATIVEN Alternativen sind Puppet Chef Ansible Saltstack … OPTIMIERUNG: APT­CACHE IN VAGRANT
Details
-
File Typepdf
-
Upload Time-
-
Content LanguagesEnglish
-
Upload UserAnonymous/Not logged-in
-
File Pages150 Page
-
File Size-