Skip to content

Instantly share code, notes, and snippets.

@jahe
Last active July 5, 2017 07:47
Show Gist options
  • Save jahe/0fdf8cde3a9b59d050551cc3e58cb2f6 to your computer and use it in GitHub Desktop.
Save jahe/0fdf8cde3a9b59d050551cc3e58cb2f6 to your computer and use it in GitHub Desktop.
Docker Fundamentals - Notes

Innerhalb von Docker ist man root --> Hat aber nur noch 4-5 Rechte --> Capabilites

  • 47 Capabilities sind dabei deaktiviert

Limitierung

  • Capabilties - Limitierung von Kernel Zugriffen
  • CGroups - Limitierung von Ressourcen
  • ACL - Limitierung von Dateizugriffen

Dockercontainer so isolieren, dass sich diese nicht sehen können

Eigene Images bauen, um ein Audit darüber machen zu können, ohne sich auf Images aus dem Inet zu verlassen

Docker EE

  • Standard: Telefonsupport
  • ...
  • Advanced: Mit Security Scanning - Wird über alle Images innerhalb der eigenen Registry ausgeführt

Stable Releases:

  • Vierteljährig: v17.03 -> v17.06
  • DockerEE: Immer ein Jahr support für eine Version

Container sind Prozesse!

  • 1 Container == 1 Prozess
  • Vom Host-System aus ist es 1 Prozess: Einseitig Transparent
  • Child Prozesse im Container sind vom Host-System aus sichtbar
  • Innerhalb des Containers starten die Prozess-IDs bei 1, aber vom Host-System wird die ID weiterhochgezählt
  • Der Kernel ist der gleiche wie der Kernel vom Host  * uname -a gibt also die Kernel Infos vom Host-System aus
    • Anwendungen die für einen 3.7 Kernel kompiliert sind können aber von einem 4.2 Kernel ausgeführt werden: Die Kernelversionen sind abwärtskompatibel
    • Linux-Container können nur von einem Linux Kernel ausgeführt werden
    • NT Kernel (Windows) soll Linux syscalls bald verstehen, sodass für Linux kompilierte Anwendungen direkt in Windows ausgeführt werden können
    • Windows-Container können in Windows System ausgeführt werden

Prozesse vom Host-System aus gesehen

  • /sbin/init
  • -> /usr/bin/dockerd (Docker Deamon)
  • -> docker-containerd (Starts + Stops + Destroy containers)
  • -> docker-containerd-shim (1...n container instance)
  • -> /usr/bin/java
  • -> /usr/bin/java (Container. Dieser Prozess fängt bei Prozess-ID 1 an)

Keine Logs

  • Auf STDOUT und STDERR schreiben
  • Container sollte zustandslos sein (Mit Logdateien wäre er nicht mehr zustandslos)
  • docker container logs <container name>
  • Default ist, dass docker pro container ein logfile anlegt, in das stdout und stderr geschrieben wird
  • für ELK-Stack: Labels konfigurieren, um herauszufinden, welcher container das log geschrieben hat

Nur der Container Layer ist writeable

  • Die darunterliegende image layer sind nur lesend
  • Werden also mehrere Alpine Container gestartet, werden die Layer im Hostsystem wiederverwendet
  • Geänderte Dateien werden in den writeable Layer kopiert und dann dort geändert
    • Die Images sehen immer noch die alte Version der Datei
  • Wenn man bspw. eine andere Debian Version haben möchte, muss man den Container stoppen und neu bauen, weil die Image layer read-only sind

Das Ubuntu Docker Image ist lediglich die Ordnerstruktur von Ubuntu

Images erstellen: 3 Methoden

  • Aus bestehendem Container
  • aus Dockerfile
  • docker import - Import aus Root Dateisystem (Import the contents from a tarball to create a filesystem image)

Aus bestehendem Container

  • Ein writeble Layer kann commitet werden zu einem neuen Image

Dockerfile

  • Pro Instruktion wird jeweils ein commit gemacht und ein neuer Container aus einem Zwischenimage gestartet
  • Es werden also mehrere Layer innerhalb eines Dockerfiles generiert
    • Grund: Caching. Wenn sich nur die letzte Zeile in einem Dockerfile ändert, muss nur die letzte Schicht neu gebaut werden. Die anderen können aus dem cache genommen werden
  • Man kann auch die Zwischenimages ausführen um bspw. manuell einen bisher fehlgeschlagenen RUN Befehl nachzustellen
  • Da jeweils ein Zwischenimage commitet wird funktioniert auch folgendes nicht:
RUN cd /src
RUN bash setup.sh      # schlägt fehl, weil er setup.sh im WORKDIR nicht findet
  • Dann kann man aber folgendes tun:
RUN cd /src && bash setup.sh

Entrypoint

  • Entrypoint beim docker container run überschreiben mit --entrypoint
  • /bin/sh wird im Container genommen um den ENTRYPOINT Befehl auszuführen

Entrypoint - Shell vs. Exec Format

  • Das Shell-Format wird von einer Shell interpretiert und es können Platzhalter verwendet werden
  • Das Exec-Format wird direkt als syscall interpretiert ohne dazwischenliegende shell
  • Shell-Format: ENTRYPOINT sudo -u ${USER} java ...
  • Exec-Format: ENTRYPOINT ["sudo", "-u", "jdoe", "java"]

Interessante Fakten

  • Das Tag latest ist nur ein Name der defaultmäßig als Tag genutzt wird, wenn man kein explizites Tag angibt
  • Auch die in "." liegenden Dateien werden beobachtet --> Für den build cache
  • Oracle JDK darf nicht im Container installiert verkauft werden
    • Deswegen muss OpenJDK verwendet werden

Best Practices

  • RUN apt-get install curl && curl ... && apt-remove curl - Danach ist curl wieder weg: Wird halt nur hier benötigt und müllt das Image nicht zu
  • Fürs Caching die Befehle evtl. umsortieren

Befehle im Dockerfile

  • USER jahe - Alle nachfolgenden Befehle werden mit diesem Nutzer ausgeführt
  • COPY <src> <dest> - kopiert vom build context in das image
  • ADD - lieber Inhalte vorher herunterladen in den build context
  • ENV - Umgebungsvariablen in Container setzen  * kann mit -e beim Starten eines Containers überschrieben + erweitert werden

Image-Namen

  • Default: docker.io/library/ubuntu
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment