====== Docker ====== ===== Základy ===== * image * obsahuje celé prostředí, což je vlastně souborový systém * seznam lokálních images ''docker images'' * img lze odstranit přes ''docker rmi <[REPOSITORY[:TAG]] | IMAGE_ID>'' * pokud je na image navázán nějaký kontejner, je třeba přidat force přes ''-f'' * skládá se z layers, které jsou za sebou formou inkrementů * container * instance image * měl by být **jednoúčelový** (aplikace nebo databáze, ne obojí v jednom) * vytvoří se prvním spuštěním ''docker run [--name CONTAINER_NAME] [CMD_INSIDE]'' * jakmile doběhne příkaz, ukončí se, ale zůstává v systému. * při spuštění lze rovnou parametrem ''--rm'' zadat, že se má po ukončení smazat * parametrem ''-it'' lze zapnout interaktivní režim (čte STDIN) * spuštěné lze vypsat přes ''docker ps'' * všechny existující přes ''docker ps -a'' * ukončit lze přes ''docker stop CONTAINER_NAME'' nebo ''docker kill CONTAINER_NAME'' * všechny změny v conteiner jsou perzistentní * změněné soubory lze vypsat přes ''docker diff '' * container je možné smazat ''docker rm '' * z container lze vytvořit image přes ''docker commit '' * ve skutečnosti je se tomu neříká name ale [REPOSITORY[:TAG]] * Dockerfile * skript popisující jak sestavit vlastní obraz * image se vytvoří přes ''docker build -t REPOSITORY[:TAG] .'' * každý krok/příkaz vytváří novou layer, je proto dobré * shlukovat RUN příkazdy jen do jednoho RUN * dělat nejprve statické akce, aby šlo při dalším buildu využívat předchozí layers * například použít COPY dynamických souborů až po RUN instalaci balíčků přes apt * bacha, že RUN apt update se vlastně bere jako statický a cachuje se * další info v [[https://docs.docker.com/develop/develop-images/dockerfile_best-practices/|Dockerfile best practices]] * pro build a produkční img se hodí používat [[https://docs.docker.com/develop/develop-images/multistage-build/|multistage build]] * docker-compose.yml * popisuje jak vytvořit více kontejnerů najednou * zpracovává docker-compose napsaný v python (pip install docker-compose) * entrypoint * definuje, co je proces s PID 1 při spuštění kontejneru * pokud není definován, použjije se ''/bin/sh -c'' * COMMAND slouží jako další parametr k entrypoint. U default entry point jde tedy o ''/bin/sh -c COMMAND'' * pokud je třeba spustit složitější systém, s vlastním cronem a tak.. pouští se většinou ''/sbin/init'' ===== Komunikace mezi kontejnery ===== * docker má 3 předdefinované sítě, které lze nastavit kontejneru * **none** - kontejner nemá žádnou síť kromě loopbacku * **bridge** (výchozí) * kontejner může komunikovat se všemi kontejnery v této síti a dostane se i do internetu přes NAT. * Pokud je potřeba nějaký port otevřít vnějšímu světu, je třeba použít parametr ''-p HOST_PORT:CONTAINER_PORT'' * Každý kontejner má virtuální IP adresu, na kterou se ale NEdá dostat přes hostname odpovídající názvu kontejneru.. to podporuje až vlastní síť, ne ta defaultní * **host** * kontejner sdílí síťové rozhraní s hostem. Všechny porty kontejneru se otevírají přímo na hostu. * Žádná izolace. * Mohou nastávat konflikty portů různých kontejnerů. * Pro komunikaci se používá IP/hostname hosta. ===== Volume kontejnery ===== * připojení adresáře z hostitele do kontejneru * aplikace a data by neměla být v jednom kontejneru * data mohou být na hostiteli a připojena do kontejneru, není to ale doporučováno, protože to porušuje zapouzdření, hodí se spíš pro testování cloudsvet@ubuntu:~$ mkdir hostdata cloudsvet@ubuntu:~$ touch hostdata/data.txt cloudsvet@ubuntu:~$ docker run --rm -it -v ~/hostdata/:/mojedata debian bash root@f5c011e9716b:/# ls mojedata/ data.txt * lze udělat volume kontejnér, který si pak mohou připojovat ostatní kontejnery * ostatní mají závislost na tomto kontejneru, ne na hostu * ale vlastní volume kontejner stejně je propojen s host file systémem (nejsou v kontejneru) * pokud se u parametru ''-v'' nezadá explicitní adresář na hostovi, vytvoří se náhodně vygenerovaný někde v hostitelském systému // vytvoříme volume kontejner, nemusí se ani spouštět. Může to byt jen busybox. docker create -v /mojedata --name mujdatacont busybox // takhle ho pak použijeme docker run -it --rm --volumes-from mujdatacont debian bash ===== Časovače ===== * a) sleep v dockeru * kontejner trvale běží, ve sleepu * b) cron na hostu * c) suystemd timer na hostu * d) scheduler kuberneties ===== HTTPS routování ===== * dělá se přes reverzní HTTPS proxy * obecně se nejčastěji používá * Traefik - docker prostředí, podporuje i obnovu certifikátů přes letsencrypt * NGINX - obecně často použivané, měl by být rychlý a lightweight * HAProxy * Apache/Lighttpd ===== Příklady ===== Wordpress * jeden kontejnér pro data pro mysql * jeden pro mysql * jeden pro worpress aplikaci * jeden pro data wordpress * docker-compose.yml vypadá takto: data_mysql: image: busybox volumes: - /var/lib/mysql data_wp: image: busybox volumes: - /var/www/html/ wordpress: image: wordpress volumes_from: - data_wp links: - mysql environment: - WORDPRESS_DB_PASSWORD=heslo ports: - "8080:80" mysql: image: mysql:5.7 volumes_from: - data_mysql environment: - MYSQL_ROOT_PASSWORD=heslo - MYSQL_DATABASE=wordpress ===== Ladění ===== * logy lze prohlédnout přes ''docker logs CONTAINER_NAME'' * případně se dá připojit na spuštěný contejner přes ''docker attach CONTAINER_NAME'' * bacha, po CTRL+C se container ukončí * detach se dělá přes ctrl-p ctrl-q * přes ''docker exec CONTAINER_NAME COMMAND'' lze spustit libovolný příkaz v běžícím kontejneru * ''docker inspect CONTAINER_NAME'' vypíše všechny informace o kontejneru jako například s jakým env byl spuštěn, co je entrypoint, kde jsou datové soubory na hostovi, kde jsou logy... ===== Zdroje ===== * https://www.cloudsvet.cz/?p=198 (základy) * https://www.cloudsvet.cz/?p=272 (docker compose)