{"id":780,"date":"2015-02-19T15:32:53","date_gmt":"2015-02-19T15:32:53","guid":{"rendered":"https:\/\/www.taywa.ch\/blog\/?p=780"},"modified":"2015-02-19T15:49:53","modified_gmt":"2015-02-19T15:49:53","slug":"setup-tipps-und-tricks-fuer-docker","status":"publish","type":"post","link":"https:\/\/www.taywa.ch\/blog\/server\/docker\/setup-tipps-und-tricks-fuer-docker\/","title":{"rendered":"Setup Tipps und Tricks f\u00fcr Docker"},"content":{"rendered":"<p>Meist\u00a0programmiere ich\u00a0in python und javascript (plus ein paar golang Experimente). F\u00fcr die lokale Entwicklung benutzte ich bis jetzt virtualenv, macports und vagrant (f\u00fcr komplexere Projekte).<\/p>\n<p>Ein Projekt ben\u00f6tige\u00a0mehrere virtuelle Maschinen, um es vern\u00fcnftig testen zu k\u00f6nnen. Mir graute es schon davor mehrere vagrant Maschinen gleichzeitig\u00a0laufen zu lassen. Das j\u00e4hrliche OS X Update stand vor der T\u00fcr, somit ein idealer Zeitpunkt was neues auszuprobieren, da ich sowieso alles neu installieren wollte.<\/p>\n<p>Ich entschied mich dazu virtualenv, macports, vagrant mit docker zu ersetzen (virtualenv hat in docker \u00fcberlebt&#8230;).<\/p>\n<p>English version of this post is\u00a0<a title=\"here\" href=\"http:\/\/yas.ch\/blog\/2015\/01\/28\/tweaking-docker-on-osx\/\" target=\"_blank\">here<\/a>.<\/p>\n<h2>Docker installieren<\/h2>\n<p>Auf <a title=\"www.docker.com\" href=\"https:\/\/www.docker.com\" target=\"_blank\">www.docker.com<\/a> gehen und das entsprechende Tutorial f\u00fcr das entsprechende OS durchf\u00fchren. Unter Mac\/Windows wird eine virtuelle Maschine ben\u00f6tigt, dies funktioniert mit boot2docker (virtualbox). Bei Linux ist es einfacher, da docker eine Linux Technologie ist. Hier wird die Vorgehensweise f\u00fcr OS X beschrieben. Viele Tipps und Tricks sind aber auch auf Linux anwendbar.<\/p>\n<p>&nbsp;<\/p>\n<p>Nach der Installation f\u00fcr OS X muss man \u00a0`boot2docker init` ausf\u00fchren.<\/p>\n<h2>btrfs<\/h2>\n<p>Docker benutzt AUFS als default. Seit 0.8 (0.10 stable) kann auch btrfs verwendet\u00a0werden. Btrfs hat einige\u00a0interessante Features. Bis jetzt habe ich Btrfs noch nie auf einem Server eingesetzt, wollte es aber schon lange mal ausprobieren.<\/p>\n<p>Btrfs unterst\u00fctzt Komprimierung im Filesystem, das ist sehr n\u00fctzlich auf einem Laptop mit einer SSD.<\/p>\n<p>In VMs k\u00f6nnen virtuelle dynamische Disks nur automatisch\u00a0wachsen, kleiner werden sie leider nicht automatisch, wenn Platz frei wird. Vor dem kleiner machen einer virtuellen Disk, muss man Nullen in den freien Platz schreiben. Insbesondere f\u00fcr SSD ist dies nicht zu empfehlen da dieses limitierte Schreibzyklen haben.<\/p>\n<p>Eine alternative ist die Disk zu kopieren und dann die alte Kopie zu l\u00f6schen. Mit dem clonezilla iso image geht dies einfach von der Hand. Clonezilla unterst\u00fctzt btrfs, da native im Linux Kernel vorhanden, aber nicht AUFS. Siehe auch\u00a0<a href=\"https:\/\/github.com\/boot2docker\/boot2docker\/blob\/master\/doc\/WORKAROUNDS.md\" target=\"_blank\">boot2docker WORKAROUNDS.md<\/a>.<\/p>\n<p>Das Lifecycle Management der virtuellen Docker Maschine wird so einfacher.<\/p>\n<div class=\"bash dean_ch\">docker<span class=\"sy0\">@<\/span>boot2docker:~$ docker pull debian:latest<br \/>\nPulling repository debian<br \/>\n&#8230;<br \/>\ndocker<span class=\"sy0\">@<\/span>boot2docker:~$ docker run <span class=\"re5\">-i<\/span> <span class=\"re5\">-t<\/span> <span class=\"re5\">&#8211;rm<\/span> <span class=\"re5\">&#8211;privileged<\/span> <span class=\"re5\">-v<\/span> <span class=\"sy0\">\/<\/span>dev:<span class=\"sy0\">\/<\/span>hostdev debian <span class=\"kw2\">bash<\/span><br \/>\nroot<span class=\"sy0\">@<\/span>ac3507fcae63:<span class=\"sy0\">\/<\/span><span class=\"co0\"># fdisk \/hostdev\/sda # if you need to partition your disk<\/span><br \/>\nCommand: o<br \/>\nCommand: n<br \/>\nSelect: p<br \/>\nPartition: <span class=\"sy0\">&lt;<\/span>enter<span class=\"sy0\">&gt;<\/span><br \/>\nFirst sector: <span class=\"sy0\">&lt;<\/span>enter<span class=\"sy0\">&gt;<\/span><br \/>\nLast sector: <span class=\"sy0\">&lt;<\/span>enter<span class=\"sy0\">&gt;<\/span><br \/>\nCommand: <span class=\"kw2\">w<\/span><br \/>\nroot<span class=\"sy0\">@<\/span>ac3507fcae63:<span class=\"sy0\">\/<\/span><span class=\"co0\"># apt-get update &amp;amp;&amp;amp; apt-get install btrfs-tools<\/span><br \/>\n&#8230;<br \/>\nThe following NEW package will be installed:<br \/>\n&nbsp;btrfs-tools<br \/>\n&#8230;<br \/>\nSetting up btrfs-tools <span class=\"br0\">&#40;<\/span>&#8230;<span class=\"br0\">&#41;<\/span> &#8230;<br \/>\nroot<span class=\"sy0\">@<\/span>ac3507fcae63:<span class=\"sy0\">\/<\/span><span class=\"co0\"># mkfs.btrfs -L boot2docker-data \/hostdev\/sda1<\/span><br \/>\n&#8230;<br \/>\nfs created label boot2docker-data on <span class=\"sy0\">\/<\/span>hostdev<span class=\"sy0\">\/<\/span>sda1<br \/>\n&#8230;<br \/>\nroot<span class=\"sy0\">@<\/span>ac3507fcae63:<span class=\"sy0\">\/<\/span><span class=\"co0\"># exit<\/span><br \/>\ndocker<span class=\"sy0\">@<\/span>boot2docker:~$ <span class=\"kw2\">sudo<\/span> reboot<\/div>\n<h3>btrfs Optionen permanten setzen<\/h3>\n<p>Da boot2docker ein iso image ist kann man nichts in diesem Image ver\u00e4ndern. Im File `\/mnt\/sda1\/var\/lib\/boot2docker\/bootlocal.sh` kann man eigene Modifikation anbringen da dies die docker Daten Disk ist.<\/p>\n<p>Hier mein `\/mnt\/sda1\/var\/lib\/boot2docker\/bootlocal.sh` file:<\/p>\n<div class=\"bash dean_ch\"><span class=\"co0\">#!\/bin\/sh<\/span><br \/>\n<span class=\"kw2\">sudo<\/span> <span class=\"kw2\">mount<\/span> <span class=\"re5\">-o<\/span> remount,compress-force=zlib <span class=\"sy0\">\/<\/span>dev<span class=\"sy0\">\/<\/span>sda1<\/div>\n<h2>Performance Probleme<\/h2>\n<p>Anfangs hat ich sehr komische CPU Performance Probleme unter docker. Als ich die virtualbox\u00a0Einstellungen auf 1 anstatt 2 CPUs ge\u00e4ndert habe, ging es wesentlich schneller. Jetzt scheint das Problem aber nicht mehr zu bestehen.<\/p>\n<h2>Ein paar n\u00fctzliche Shell Funktionen<\/h2>\n<p>Die folgenden Snippets kommen ins lokale `.profile` file.<\/p>\n<div class=\"bash dean_ch\"><span class=\"kw3\">export<\/span> <span class=\"re2\">DOCKER_HOSTIP<\/span>=$<span class=\"br0\">&#40;<\/span><span class=\"kw3\">echo<\/span> <span class=\"re1\">$DOCKER_HOST<\/span><span class=\"sy0\">|<\/span><span class=\"kw2\">cut<\/span> <span class=\"re5\">-d<\/span> <span class=\"st0\">&quot;:&quot;<\/span> <span class=\"re5\">-f<\/span> <span class=\"nu0\">2<\/span><span class=\"sy0\">|<\/span> <span class=\"kw2\">sed<\/span> <span class=\"re5\">-e<\/span> <span class=\"st0\">&quot;s#\/\/##&quot;<\/span><span class=\"br0\">&#41;<\/span><br \/>\n<span class=\"kw3\">export<\/span> <span class=\"re2\">DOCKER_GATEWAYIP<\/span>=$<span class=\"br0\">&#40;<\/span><span class=\"kw2\">ifconfig<\/span><span class=\"sy0\">|<\/span><span class=\"kw2\">grep<\/span> $<span class=\"br0\">&#40;<\/span><span class=\"kw3\">echo<\/span> <span class=\"re1\">$DOCKER_HOSTIP<\/span><span class=\"sy0\">|<\/span><span class=\"kw2\">cut<\/span> <span class=\"re5\">-d<\/span> <span class=\"st0\">&quot;.&quot;<\/span> -f-<span class=\"nu0\">3<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">|<\/span><span class=\"kw2\">cut<\/span> <span class=\"re5\">-d<\/span> <span class=\"st0\">&quot; &quot;<\/span> <span class=\"re5\">-f<\/span> <span class=\"nu0\">2<\/span><span class=\"br0\">&#41;<\/span><\/div>\n<p>Die Variablen\u00a0`DOCKER_HOSTIP` und\u00a0`DOCKER_GATEWAYIP` k\u00f6nnen hilfreich sein.<\/p>\n<h3>In einen docker container &#8222;reingehen&#8220;<\/h3>\n<p>Seit docker 1.3 gibt es das exec sub command. Vorher konnte\u00a0man das externe tool `nsenter` benutzten. Damit braucht\u00a0es keine ssh um ein Terminal in einem Container laufen zu lassen. Mit dieser Shell Funktion geht dies noch etwas einfacher.<\/p>\n<div class=\"bash dean_ch\"><span class=\"kw1\">function<\/span> docker-enter<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><br \/>\n<span class=\"br0\">&#123;<\/span><br \/>\n&nbsp;docker <span class=\"kw3\">exec<\/span> <span class=\"re5\">-it<\/span> <span class=\"re4\">$1<\/span> <span class=\"kw2\">bash<\/span> <span class=\"re5\">-l<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><\/div>\n<p>Jetzt einfach `docker-enter mycontainer_1` ausf\u00fchren um in den container zu kommen.<\/p>\n<h3>Datenvolumen anschauen<\/h3>\n<p>Diese Shell Funktion brauche ich auch recht h\u00e4ufig.<\/p>\n<div class=\"bash dean_ch\"><span class=\"kw1\">function<\/span> docker-vol<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><br \/>\n<span class=\"br0\">&#123;<\/span><br \/>\n&nbsp;docker run <span class=\"re5\">-it<\/span> <span class=\"re5\">&#8211;rm<\/span> <span class=\"re5\">&#8211;volumes-from<\/span> <span class=\"re4\">$1<\/span> <span class=\"re5\">&#8211;name<\/span> vol_<span class=\"re4\">$1<\/span>_$<span class=\"br0\">&#40;<\/span><span class=\"kw2\">date<\/span> +<span class=\"sy0\">%<\/span>s<span class=\"br0\">&#41;<\/span> <span class=\"re5\">-h<\/span> <span class=\"re4\">$1<\/span> debian <span class=\"kw2\">bash<\/span> <span class=\"re5\">-l<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><\/div>\n<p>Mit\u00a0`docker-vol data_container_1` hat man nun eine shell mit der man sich im Datencontainer umschauen kann.<\/p>\n<h3>Nun doch ssh<\/h3>\n<p>In der Regel braucht es kein ssh f\u00fcr docker container. Aber manchmal eben doch, z.B. f\u00fcr ein Desktop Programm in docker (mit X forward) oder um via sshfs etwas zu mounten. Der default\u00a0ssh port ist in der Regel schon belegt und potenziell k\u00f6nnen nat\u00fcrlich auch mehrere ssh container laufen. Man muss also f\u00fcr jeden container einen eigenen ssh Port benutzen. Um sich nicht die verschiednen Ports merken zu m\u00fcssen hier eine Shell Funktion.<\/p>\n<div class=\"bash dean_ch\"><span class=\"kw1\">function<\/span> docker-ssh<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><br \/>\n<span class=\"br0\">&#123;<\/span><br \/>\n&nbsp;<span class=\"re2\">SSHPORT<\/span>=<span class=\"sy0\">`<\/span>docker inspect <span class=\"re5\">&#8211;format<\/span>=<span class=\"st_h\">&#8218;{{index .NetworkSettings.Ports &quot;22\/tcp&quot;}}&#8216;<\/span> <span class=\"re4\">$1<\/span><span class=\"sy0\">|<\/span><span class=\"kw2\">cut<\/span> <span class=\"re5\">-d<\/span> <span class=\"st0\">&quot;:&quot;<\/span> <span class=\"re5\">-f<\/span> <span class=\"nu0\">3<\/span><span class=\"sy0\">|<\/span> <span class=\"kw2\">sed<\/span> <span class=\"re5\">-e<\/span> <span class=\"st0\">&quot;s\/]]\/\/&quot;<\/span><span class=\"sy0\">`<\/span><br \/>\n&nbsp;<span class=\"kw2\">ssh<\/span> <span class=\"re5\">-X<\/span> <span class=\"re5\">-l<\/span> root <span class=\"re5\">-p<\/span> <span class=\"re1\">$SSHPORT<\/span> <span class=\"re1\">$DOCKER_HOSTIP<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><\/div>\n<p>Mit\u00a0`docker-ssh myssh_container_1` kommt man nun ohne Angabe des Ports in den container, inkl X forward.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Meist programmiere ich in python und javascript (plus ein paar golang Experimente). F\u00fcr die lokale Entwicklung benutzte ich bis jetzt virtualenv, macports und vagrant (f\u00fcr komplexere Projekte).<\/p>\n<p>Ein Projekt ben\u00f6tige mehrere virtuelle Maschinen, um es vern\u00fcnftig testen zu k\u00f6nnen. Mir graute es schon davor mehrere vagrant Maschinen gleichzeitig laufen zu lassen. Das j\u00e4hrliche OS X Update stand vor der T\u00fcr, somit ein idealer Zeitpunkt was neues auszuprobieren, da ich sowieso alles neu installieren wollte.<\/p>\n","protected":false},"author":4,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[162],"tags":[165,193,164,163],"class_list":["post-780","post","type-post","status-publish","format-standard","hentry","category-docker","tag-btrfs","tag-docker","tag-linux","tag-osx"],"_links":{"self":[{"href":"https:\/\/www.taywa.ch\/blog\/wp-json\/wp\/v2\/posts\/780","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.taywa.ch\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.taywa.ch\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.taywa.ch\/blog\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/www.taywa.ch\/blog\/wp-json\/wp\/v2\/comments?post=780"}],"version-history":[{"count":12,"href":"https:\/\/www.taywa.ch\/blog\/wp-json\/wp\/v2\/posts\/780\/revisions"}],"predecessor-version":[{"id":792,"href":"https:\/\/www.taywa.ch\/blog\/wp-json\/wp\/v2\/posts\/780\/revisions\/792"}],"wp:attachment":[{"href":"https:\/\/www.taywa.ch\/blog\/wp-json\/wp\/v2\/media?parent=780"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.taywa.ch\/blog\/wp-json\/wp\/v2\/categories?post=780"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.taywa.ch\/blog\/wp-json\/wp\/v2\/tags?post=780"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}