Installazione
Per installare il servizio aggiungere al server linux il repository ufficiale preso dal sito docker.com (versione CE o EE).
Terminata l’installazione va configurato per utilizzare i certificati in modo da potersi connettere in sicurezza anche sul pubblico
- aggiunta nei DNS del nome a dominio ca usare come CN nel certificato
- creazione del certificato per il server utilizzando una CA già presente (creazione chiave privata openssl genrsa -des3, creazione CSR openssl req -new -key, creazione csr e creazione certificato openssl ca -days 3650)
- creazione file /etc/docker/daemon.json nell’host con il seguente contenuto
{ "hosts": [ "tcp://0.0.0.0:2376", "fd://" ], "tls": true, "tlscacert": "/etc/docker/cacert.pem", "tlscert": "/etc/docker/hosting-docker.it.pem", "tlskey": "/etc/docker/hosting-docker.it.key", "tlsverify": true }
- disabilitazione della direttiva -H del servizio come da seguente issue https://github.com/docker/docker/issues/25471#issuecomment-263101090
Firewall
Impostare il loading all’avvio del sistema di un file contenente le regole di base del firewall (apertura porta per Zabbix, SSH, HTTP, porta 2376 Docker, ecc…).
*filter :INPUT DROP [70:9447] :FORWARD DROP [0:0] :OUTPUT ACCEPT [457:250858] -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT -A INPUT -i eth1 -p tcp -m tcp --dport 22 -m state --state NEW -j ACCEPT -A INPUT -i eth1 -p tcp -m tcp --dport 10000 -m state --state NEW -j ACCEPT -A INPUT -i eth1 -p tcp -m tcp --dport 10050 -m state --state NEW -j ACCEPT -A INPUT -i eth0 -p tcp -m tcp --dport 2376 -m state --state NEW -j ACCEPT -A INPUT -i eth1 -p tcp -m tcp --dport 2376 -m state --state NEW -j ACCEPT -A INPUT -i lo -j ACCEPT COMMIT
Evitare di salvare le regole impostate (tramite iptables-save) mentre il demone docker è in esecuzione in quanto verrebbero salvate anche le regole caricate dai container avviati e diverrebbero persistenti mentre in realtà non lo devono essere.
N.B.: Quando un container pubblica una porta questa viene raggiunta indipendentemente da eventuali regole di firewall INPUT. Nel caso si voglia restringere o non consentire l’accesso a tale porta utilizzare la regola FORWARD seguente
#Non consento l'apertura verso il frontend dei seguenti servizi va lanciato a mano dopo iptables -I FORWARD -i eth0 -o docker0 -p tcp --dport 9000 -j DROP
Connessione al server dai client
Il certificato per connettersi dai client al server è uno di quelli generati dalla stessa CA usata per il certificato del servizio Docker.
Gestione
Per la gestione delle macchine docker è utile il container portainer.io che fornisce un interfaccia grafica unificata per la gestione di più macchine docker.
Per visualizzare i container attivi su una macchina
docker ps
Per visualizzare tutti i container (anche gli spenti)
docker ps -a
Per liberare spazio inutilizzato si possono usare i comandi indicati qui https://gist.github.com/bastman/5b57ddb3c11942094f8d0a97d461b430#file-docker-cleanup-resources-md
- eliminare i volumi
// see: https://github.com/chadoe/docker-cleanup-volumes $ docker volume rm $(docker volume ls -qf dangling=true) $ docker volume ls -qf dangling=true | xargs -r docker volume rm
- eliminare le reti
$ docker network ls $ docker network ls | grep "bridge" $ docker network rm $(docker network ls | grep "bridge" | awk '/ / { print $1 }')
- eliminare le immagini
// see: http://stackoverflow.com/questions/32723111/how-to-remove-old-and-unused-docker-images $ docker images $ docker rmi $(docker images --filter "dangling=true" -q --no-trunc) $ docker images | grep "none" $ docker rmi $(docker images | grep "none" | awk '/ / { print $3 }')
- eliminare i container
// see: http://stackoverflow.com/questions/32723111/how-to-remove-old-and-unused-docker-images $ docker ps $ docker ps -a $ docker rm $(docker ps -qa --no-trunc --filter "status=exited")
Container utili
Di seguito alcuni comandi o compose file di alcuni container degni di nota. I compose file integrano la rete traefik per l’uso con l’omonimo reverse proxy.
nginx-proxy
Impostato come reverse proxy per l’hosting di più siti web (uno per container).
docker run --detach \ --publish 80:80 \ --publish 443:443 \ --volume /var/run/docker.sock:/tmp/docker.sock:ro \ --volume /opt/docker/nginx-rproxy/etc/nginx/certs:/etc/nginx/certs \ --volume /opt/docker/nginx-rproxy/etc/nginx/proxy.conf:/etc/nginx/proxy.conf \ --restart always \ --name nginx-rproxy \ jwilder/nginx-proxy
watchtower
Container che verifica se sono presenti versioni aggiornate dei container in esecuzione e li aggiorna automaticamente.
version: '3' services: watchtower: image: v2tec/watchtower container_name: watchtower restart: always labels: - traefik.enable=false volumes: - /var/run/docker.sock:/var/run/docker.sock command: --cleanup
php-apache
Container da utilizzare per l’esecuzione di un ambiente PHP e Apache.
docker run --detach \ --env VIRTUAL_HOST=www.prova.it \ --name hosting-prova.it \ --env WEB_ALIAS_DOMAIN=www.prova.it \ --env WEB_ALIAS_DOMAIN=prova.it \ --env LANG=it_IT.UTF-8 \ --env LC_ALL=it_IT.UTF-8 \ --volume /opt/docker/prova.it/html:/app/ \ --volume /opt/docker/prova.it/etc/php/php.ini:/opt/docker/etc/php/php.ini \ --volume /opt/docker/prova.it/etc/httpd/vhost.common.d:/opt/docker/etc/httpd/vhost.common.d/ \ --volume /opt/docker/prova.it/log/:/var/log/apache2 \ --restart always \ webdevops/php-apache
pureftp
Container per esporre il servizio ftp.
docker run --detach \ -e PUREFTP_PASSIVE_IP=IP_MACCHINA_DOCKER\ -p 2121:21 \ -p 40000-40009:40000-40009 \ -v /opt/dockerContainer/isp:/home/ftpuser/utente\ -e PUREFTP_CERT_SUBJ="/C=IT/O=Organization/CN=test.org" \ -e PUREFTP_PIPPO_PASSWORD=utente\ -e PUREFTP_UID=$(id -u) \ -e PUREFTP_GID=$(id -g) \ bamarni/pureftp
dockbix-agent-xxl-limited
Container per il monitoraggio del server docker e di tutti i container. Utilizzando net=host va creata la regola su iptables per aprire la porta 10050 in ingresso.
Siccome il container di Zabbix non supporta il restart è bene gestirlo così https://github.com/monitoringartist/dockbix-agent-xxl#dockbix-agent-xxl-service-managed-by-systemd
zabbix-xxl
Compose file per la realizzazione di un server Zabbix (maggiori info qui https://github.com/monitoringartist/zabbix-xxl)
version: '3' services: zabbix-db: image: monitoringartist/zabbix-db-mariadb container_name: zabbix-db restart: always networks: - backend volumes: - ./db/lib-mysql:/var/lib/mysql/ - ./db/backups/:/backups/ - /etc/localtime:/etc/localtime:ro environment: - MARIADB_USER=pass - MARIADB_PASS=pass zabbix: image: monitoringartist/zabbix-xxl:latest container_name: zabbix restart: always networks: - traefik - backend labels: - traefik.frontend.rule=Host:zabbix.domain - traefik.port=80 - traefik.enable=true - traefik.docker.network=traefik_webgateway depends_on: - zabbix-db ports: #- "192.168.15.8:80:80" - "192.168.15.8:10051:10051" volumes: - ./alertscripts/:/usr/local/share/zabbix/alertscripts/ - ./externalscripts/:/usr/local/share/zabbix/externalscripts/ - /etc/localtime:/etc/localtime:ro links: - zabbix-db:zabbix.db environment: - PHP_date_timezone=Europe/Rome - ZS_StartVMwareCollectors=1 - ZS_StartPollers=10 - ZS_StartPollersUnreachable=5 - ZS_StartDiscoverers=5 - ZA_Server=localhost - ZA_ServerActive=localhost - ZA_Hostname=Server docker - ZS_LogSlowQueries=100 - ZS_Timeout=30 - ZW_ZBX_SERVER_NAME=Zabbix Server - ZS_DBHost=zabbix.db - ZS_DBUser=pass - ZS_DBPassword=pass - XXL_grapher=true networks: backend: driver: bridge traefik: external: name: traefik_webgateway
Il container zabbix-xxl ha integrato l’agent ma non gestisce il monitoraggio dei container sulla macchina come fa dockbix-agent-xxl. È possibile installare sulla stessa macchina sia dockbix-agent-xxl che zabbix-xxl creando in Zabbix un secondo host (con l’ip dell’interfaccia di rete della macchina) agganciandogli il template Dockbix.
portainer.io
Container per il monitoraggio e gestione via GUI di docker.
version: '3' services: portainer: image: portainer/portainer container_name: portainer restart: always networks: - traefik labels: - traefik.port=9000 - traefik.enable=true #ports: #- "192.168.15.8:8080:9000" volumes: - ./data/:/data/ - /var/run/docker.sock:/var/run/docker.sock networks: traefik: external: name: traefik_webgateway restreamer
restreamer
Container per restream di flussi video.
version: '3' services: restreamer: image: datarhei/restreamer:latest container_name: restreamer restart: always networks: - traefik labels: - traefik.enable=true - traefik.port=8080 #ports: #- "8082:8080" volumes: - ./db:/restreamer/db environment: - RESTREAMER_USERNAME=admin - RESTREAMER_PASSWORD=password networks: traefik: external: name: traefik_webgateway
traefik
Si tratta di un potente e versatile reverse proxy, per maggiori info meglio visitare il sito web www.traefik.io. Nel compose file seguente è stato impostato per essere collegato a una rete definita ad hoc (impostando anche il nome che sull’host apparirà associato al relativo bridge) che viene poi associata a tutti i container che dovranno essere pubblicati tramite tale reverse proxy.
version: '2' services: traefik: image: traefik container_name: traefik restart: always command: --configfile=/etc/traefik.toml networks: - webgateway ports: - 80:80 - 443:443 - 8080:8080 volumes: - /var/run/docker.sock:/var/run/docker.sock - ./files/traefik.toml:/etc/traefik.toml - ./files/rules.toml:/etc/rules.toml - ./files/acme.json:/etc/acme.json networks: webgateway: driver: bridge driver_opts: com.docker.network.bridge.name: "docker_web" ipam: driver: default config: - subnet: 192.168.28.0/24 gateway: 192.168.28.1
docker-compose-ui
Interfaccia grafica web-ui per docker-compose
version: "2" services: dockerComposeUi: image: francescou/docker-compose-ui restart: always container_name: dockerComposeUi ports: - 5000:5000 working_dir: /opt/docker networks: - traefik labels: - traefik.port=5000 - traefik.enable=true - traefik.frontend.rule=Host:compose.domain #ports: #- "192.168.15.8:5000:5000" volumes: - /var/run/docker.sock:/var/run/docker.sock - /opt/docker:/opt/docker networks: traefik: external: name: traefik_webgateway