Docker
Installation
RHEL 7+:
yum -y install yum-utils
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum -y install docker-ce docker-ce-cli containerd.io
systemctl start docker
# Docker Compose
curl -L "https://github.com/docker/compose/releases/download/1.28.6/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
docker-compose --version
Docker Cheat Sheet
docker run hello-world
docker run --interactive \
--tty=false \
--detach=false \
--publish 80:80 \
onlyoffice/documentserver
docker run --name=mongo \
mongo:4.2
docker run --name=elasticsearch \
--env="http.host=0.0.0.0" \
--env="discovery.type=single-node" \
--env="ES_JAVA_OPTS=-Xms512m -Xmx512m" \
docker.elastic.co/elasticsearch/elasticsearch-oss:7.10.2
docker run --name=graylog \
--env=GRAYLOG_HTTP_EXTERNAL_URI="http://127.0.0.1:9000/" \
--link=mongo --link=elasticsearch \
--publish=9000:9000 --publish=12201:12201 --publish=1514:1514 \
graylog/graylog:4.0
docker run --log-driver gelf –-log-opt gelf-address=udp://1.2.3.4:12201 mycontainer anyoptions
docker restart $CONTAINER
docker container ls --all
docker image ls --all
docker ps
# where are images located?
docker info
docker rm
# inspect a container, get IP address etc.
docker inspect
docker inspect --type container
docker inspect -f '{{.HostConfig.LogConfig.Type}}' 8e8323567545
# get the logs
docker logs -f ea87dde67282
docker logs -f container-name
# get a bash shell in the container
docker exec -it <container name> /bin/bash
docker stats --no-stream
docker stats --no-stream $(docker inspect -f {{.Name}} $(docker ps -q))
curl --unix-socket /var/run/docker.sock "http:/localhost/containers/<container id or name>/stats?stream=False"
docker --host=ssh://docker-host container stop $(docker --host=ssh://docker-host ps -a -q)
docker --host=ssh://docker-host container prune -f
docker --host=ssh://docker-host rmi $(docker --host=ssh://docker-host image ls -q)
Firewalling
Das Firewalling der Docker-Container ist kompliziert, da der Docker-Daemon selbst dynamisch Firewall-Regeln anlegt.
Firewalling ist aber gerade bei Docker sehr wichtig, denn wenn bei --publish keine IP mitgegeben wird, hört der Port auf allen Interfaces des Hosts - inklusive Firewall-Regel, die einkommende Verbindungen erlaubt.
Da dies den Usern meistens nicht bewusst ist, stellt das ein Sicherheitsrisiko dar.
FwBuilder / Firewall Builder und Docker vertragen sich leider nicht, da beim Neustarten der Firewall alle Regeln gelöscht werden - somit auch die des Docker-Daemons. Hier ist die einzige Option, dass die Erstellung der Regeln im Docker-Daemon deaktiviert und die Regeln manuell erstellt (siehe auch einen Blog-Post von firewalld) werden. Allerdings ist das nur möglich, wenn die Docker-Container IPs und Ports bekannt sind - somit nicht für den Einsatz auf einer Workstation geeignet.
Bei firewalld ist der Reload granularer implementiert, somit werden die Docker-Regeln nicht beeinflusst. Allerdings funktioniert hierbei eine Policy mit Ingress-Zone ANY und Egress-Zone docker nicht wie erwartet, da firewalld alle DNAT-Verbindungen schon vor den Regeln der Policy akzeptiert (ct status dnat accept in der firewalld filter_FORWARD). Das Problem wird in einem GitHub-Issue thematisiert aber nicht zufriedenstellend gelöst.
Daher müssen die Regeln in der DOCKER-USER Chain abgelegt werden. Das geht mithilfe den (deprecated) Direct-Regeln in firewalld:
firewall-cmd --permanent --direct --add-chain ipv4 filter DOCKER-USER
firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 0 -i lo -j ACCEPT
firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 1 -j LOG --log-level info --log-prefix "DOCKER-USER DENY "
firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 2 -j DROP
So werden nur Verbindungen von den Docker-Host aus erlaubt.
DNS
Docker interessiert in der Regel nicht, welche DNS lokal im System auf der Netzwerkkarte konfiguriert sind - es soll aber gezwungen werden, einen bestimmten DNS zu verwenden?
{
"dns": [
"1.1.1.1",
"1.0.0.1"
]
}
systemctl restart docker
Test:
docker run busybox nslookup www.linuxfabrik.ch
Timezones
Zeitzone setzen:
docker run --env TZ=Europe/Zurich debian:jessie date
Logging mit Docker
Docker und Logserver wie Graylog: Docker besitzt eine Feldbegrenzung bei „message“ von 16KB. Mehr ist nicht möglich - laut Docker müssen die Log-Plugins eine Art von „max log size“-Option anbieten, tut aber Stand heute (2018-06) kein einziger. Ein pures Weiterleiten per GELF und anderen macht also nicht glücklich. Statt dessen müssen die Container über filebeats direkt per Beats auf den Log-Server schreiben. Die Container, die das nicht können (sollen), schreiben per journald. journalctl wird dann per journal2gelf an den Log-Server weitergeleitet.
docker run --log-driver=gelf --log-opt gelf-address=tcp://192.168.209.9:12201
alpine echo 'Hello World'
Journald als Logging-Driver:
GELF als Logging-Driver:
{
"log-driver": "gelf",
"log-opts": {
"gelf-address": "udp://192.168.209.6:12201"
}
}
docker-compose
cd path/to/docker-compose.yml
docker-compose up
# daemonize:
docker-compose up -d
docker-compose down
Troubleshooting
- unable to configure the Docker daemon with file /etc/docker/daemon.json: the following directives are specified both as a flag and in the configuration file: log-driver
In einem systemd-File befindet sich sehr wahrscheinlich genau die gleiche Config-Einstellung wie in
/etc/docker. Docker führt die Anweisungen nicht zusammen.- Error starting daemon: error initializing graphdriver: /var/lib/docker contains several valid graphdrivers: devicemapper, overlay2; Please cleanup or explicitly choose storage driver (-s )
rm -rf /var/lib/docker/devicemapper systemctl start docker
Built on 2026-03-13