thomas-guettler.de / Vorträge Index

Index

Hintergrund

  • Serveranwendungen: zB Archiv, digitaler Posteingang, .... (im folgenden Text "core")
  • Die Anwendung wird für mehrere Firmen zur Verfügung gestellt.
  • Linux-Server von uns (root Zugang, kein "billig Account" eines Webhosters).
  • Für jede Firma gibt es einen eigenen Server, außer bei Entwicklungssystemen. Hier teilen sich die Entwicklungsumgebungen ein Betriebssystem.

In unserer Firma (TBZ-PARIV) haben wir folgendes Schema für Projekte eingeführt:
Serveranwendung laufen unter einem Linuxbenutzer mit folgendem Namensschema:
core_customer_stage
  • core: Zentrale Anwendung (bei uns zB MODWORK (digitaler Posteingang) oder MODARCH (Archiv), ....). In den Beispielen: mycms, myshop
  • customer: Firmenkürzel des Kunden
  • stage: d für DEV, q für QUAL, p für PROD.
  • Optional kann nach Stage noch ein Kürzel kommen: Bsp pro Entwickler ein eigenes System.
Beispiel: Linuxnutzer modwork_eins_p ist "MODWORK für Firma eins-energie, Produktivsystem"
Weiterer Aufbau der Systemlandschaft:
  • Unser Quelltext ist in $HOME des Nutzers. Unser Code ist nicht per RPM/DEB installiert.
  • Auf einem Linux-Server können beliebig viele Systeme parallel laufen.
  • Zentral installiert (RPM/DEB), unverändert von Distribution: Python, PostgreSQL, psycopg2, Apache, ...
  • Ebenfalls in $HOME: Pakete, die in der Distribution nicht verfügbar sind: Django, South, ...
  • Datenbankname und Datenbanknutzer haben in der Regel den gleichen Nutzernamen (core_customer_stage)

  • Jedes System hat eigene Crontab
  • Jedes System hat eine eigene Mailadresse: Mails (ggf Fehlermeldungen) können an einer zentralen Stelle leicht anhand des Absenders sortiert werden
  • Eigene Logfiles: zB /var/log/nginx/mycms_foo_p-access.log
  • Eigene Init-Scripte: /etc/init.d/mycms_foo_p-myserver (Switch user in init script)
  • Systeme können sich kaum untereinander beeinflussen (Dateien löschen, Signale senden (kill))
  • Prod-System ist identisch mit DEV/QUAL System: Nicht hier virtualenv, dort ohne ...
  • Dev-System hat die gleiche OS-Version (Bsp RHEL 6.3) wie Prod: Weniger Überraschungen...
  • Entwicklungssysteme können sich ein Betriebssystem teilen: Weniger Aufwand als bei N virtuellen Servern.

  • Native GUIs
  • Vermutlich nicht für Cloud-Computing

  • Preiswerte Hostingangebote: N Linuxuser teilen sich einen Server
  • Android: Jede APP bekommt zum Installationszeitpunkt einen Linuxuser zugewiesen.

core=mycms: ein fiktives Content-Management-System das von mehreren Kunden eingesetzt wird.
firma=foo: der Auftraggeber, bzw die spezielle Anpassung von mycms für den konkreten Anwendungsfall.

mycms_foo_d@ubuntu1204: Entwicklungssystem (gleiche OS-Version wie Produktivsystem!)
mycms_foo_q@server-foo: Qualitätssicherungssystem (ebenfalls Ubuntu 12.04, teilt sich OS mit Prod)
mycms_foo_p@server-foo: Produktivsystem
core=myshop, firma=bar
myshop_bar_d@ubuntu1204: Entwicklungssystem (teilt sich OS mit mycms_foo_d)
myshop_bar_q@q-server-bar: Qualitätssicherungssystem ebenfalls Ubuntu 12.04: Q hier auf anderem Server
myshop_bar_p@p-server-bar: Produktivsystem

Warum nicht für jedes System eine eigene virtuelle Maschine aufsetzen?
  • Prinzipiell möglich, aber Verwaltungsaufwand ist insbesondere für Entwicklungssysteme höher. Bei uns laufen auf den Entwicklungsserver derzeit rund 60 Systeme. Man braucht nur pro unterstütztes Betriebssystem eine (meist virtuelle) Maschine.

Behauptung: Mit virtualenv kann man den Versionsstand einfrieren (requirements.txt) ....
Halt: Das ist ein Feature von PIP und lässt sich bei unserem Schema genauso nutzen.

Behauptung2: Mit virtualenv kann man verschiedene Versionsstände testen ...
Geht mit unserem Schema einfach, da alle Pakete in $HOME installiert sind. Möchte man andere Python Versionen testen, dann muss man an anderes Betriebssystem, bei dem die gewünschte Version vorhanden ist.

Behauptung3: Eine virtualenv ist einfacher angelegt als ein neuer Linuxnutzer: Das stimmt.

Siehe auch: Do I need virtualenv?
  • Do not pollute your global site packages: Bereich unterhalb /usr/lib nicht verändern. Dieser Bereich wird mit den Paketen der Distribution (Ubuntu/RedHat/SuSE) verwaltet.
  • http://www.python.org/dev/peps/pep-0370/
  • per user site-packages directory
  • ~/.local/lib/python2.7/site-packages

settings.STAGE
STAGE 0 --> PROD: Produktivsystem
STAGE 1 --> QUAL Qualitätssicherung: Hier kann der Kunde neue Änderungen vor der Freigabe prüfen.
STAGE 2 --> INT (Integration verschiedener DEV-Systeme) (optional)
STAGE 3 --> DEV: Es kann mehrere Entwicklungssysteme geben: Pro Entwickler, für automatisierte Tests, ....
if settings.STAGE:
    # ... dev/qual System

stageutils.get_next_stage() # Sinnvoll für Scripts die zwischen zwei Systemen Code oder DB-Tabellen vergleichen
                            # TODO: wir haben bisher immer nur einen nächsten Server. Vielleicht lieber im Plural: get_next_stages() (falls es mehrere Produktivsserver gibt. Code muss bei der Installation auf N Server ...)
Derzeit leider noch nicht open source.

SSH Config

.ssh/config
host qual
   hostname ...
   username modwork_fm_q
# weniger ist mehr: "ssh qual" funktioniert auf allen DEV Systemen: Man kommt
# zum passenden Qual-System.
modwork_fm_d@workepdevel113:~$ ssh qual

Automatisierte Tests

Für automatisierte Tests wird bei uns ein "t" angehängt: mycms_foo_dt System in dem die automatisierten Tests durchgeführt werden.

Keine Softwareentwicklung unter "persönlichem" Account

Wie kann dann das Commit personenbezogen ins Repository? Schließlich will man in der Versiongeschichte sehen wer das "eingecheckt" hat.
#~mycmd_foo_d/.ssh/authorized_keys
environment="DEVELOPER=tguettler" ssh-rsa AAAAB3NzaC1yc2EAA... 
--> Umgebungsvariable verfügbar. Hinweis, in der Server-Config muss folgendes stehen: PermitUserEnvironment yes

.bashrc: GIT_SSH, SVN_SSH oder entsprechend anpassen, damit $DEVELOPER verwendet wird.