本文记录了一些基础的 docker 知识。
reference
Docker —— 从入门到实践 非常不错的一本书,与时俱进
你确定你会写 Dockerfile 吗
Docker stop或者Docker kill为何不能停止容器
P2P镜像分发Dragonfly使用
Docker 数据持久化的三种方案
Docker — 从入门到实践
docker-proxy 存在合理性分析
Docker 的原理
Docker 存储驱动与磁盘文件系统 内含格式化磁盘,挂载磁盘
深入理解 cgroup 中的 cpuset
一次有趣的 Docker 容器网络排查
安装 docker 分享一篇CentOS 7 下 yum 方式安装 Docker 环境
1 2 3 4 5 6 7 sudo yum install -y yum-utils device-mapper-persistent-data lvm2 sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo yum install -y docker-ce sudo systemctl start docker
一个“容器”,实际上是一个由 Linux Namespace、Linux Cgroups 和 rootfs 三种技术构建出来的进程的隔离环境。 这三种技术介绍? Namespace 的作用是“隔离”,它让应用进程只能看到该 Namespace 内的“世界”;而 Cgroups 的作用是“限制”
rootfs 只是一个操作系统所包含的文件、配置和目录,并不包括操作系统内核。在 Linux 操作系统中,这两部分是分开存放的,操作系统只有在开机启动时才会加载指定版本的内核镜像。正是由于 rootfs 的存在,容器才有了一个被反复宣传至今的重要特性:一致性。
docker commit,实际上就是在容器运行起来后,把最上层的“可读写层”,加上原先容器镜像的只读层,打包组成了一个新的镜像。当然,下面这些只读层在宿主机上是共享的,不会占用额外的空间。
docker volume 镜像的各个层,保存在 /var/lib/docker/aufs/diff 目录下,在容器进程启动后,它们会被联合挂载在 /var/lib/docker/aufs/mnt/ 目录中,这样容器所需的 rootfs 就准备好了。 volume /test 挂载出来之后,文件会出现在了宿主机上对应的临时目录里,但是如果你在宿主机上查看该容器的可读写层,虽然可以看到这个 /test 目录,但其内容是空的。 而由于使用了联合文件系统,你在容器里对镜像 rootfs 所做的任何修改,都会被操作系统先复制到这个可读写层,然后再修改。这就是所谓的:Copy-on-Write。 有些时候,会由于配置文件的出错导致容器运行失败,这个时候不能进入容器修改文件,只能去 /var/lib/docker/overlay2/ID/diff 下面,找到对应的配置文件进行修改。
docker 常用命令 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 systemctl start docker systemctl enable docker docker info docker pull image_name docker pull centos:latest docker images REPOSITORY TAG IMAGE ID CREATED SIZE mysql 5.7 1b30b36ae96a 8 days ago 372MB zabbix/zabbix-web-nginx-mysql centos-4.0-latest 8be5f91b2fa1 3 weeks ago 415MB zabbix/zabbix-server-mysql centos-4.0-latest 8e5becf45c4e 3 weeks ago 326MB docker rmi image_name/image_id docker rmi zabbix/zabbix-web-nginx-mysql:centos-4.0-latest 或者 docker rmi 8be5f91b2fa1 docker ps docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b30307ad65be zabbix/zabbix-web-nginx-mysql:centos-4.0-latest "docker-entrypoint.sh" 7 days ago Exited (255) 8 minutes ago 443/tcp, 0.0.0.0:8080->80/tcp zabbix-web-nginx-mysql 0ad822cd52b7 zabbix/zabbix-server-mysql:centos-4.0-latest "docker-entrypoint.sh" 7 days ago Exited (255) 8 minutes ago 0.0.0.0:10051->10051/tcp zabbix-server-mysql d01c89a112f7 mysql:5.7 "docker-entrypoint.s…" 7 days ago Exited (255) 8 minutes ago 3306/tcp, 33060/tcp mysql-server docker start container_name/container_id docker stop container_name/container_id docker restart container_name/container_id docker attach container_name/container_id docker rm container_name/container_id docker logs -f container_name/container_id docker inspect container_name/container_id docker exec -it container_name/container_id bash [root@localhost tmp] Usage: docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|- docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH Copy files/folders between a container and the local filesystem docker cp zabbix_config.sql mysql-server:/tmp docker cp mysql-server:/tmp/zabbix_config.sql /tmp docker rm -v $(docker ps -aq -f status=exited) docker rm -v $(docker ps -aq -f status=created)
docker logs 删除 logs 设置 logs Daemon configuration file
docker iptables docker 默认会修改 iptables,但有时候会造成 iptables ip 限制失效的问题。如果对 iptables 比较了解的同学,可以 Prevent Docker from manipulating iptables
1 2 3 4 5 6 7 8 9 10 11 12 13 { "iptables" : false , "log-driver" :"json-file" , "log-opts" : {"max-size" :"500m" , "max-file" :"3" } } max-size=500m,意味着一个容器日志大小上限是500M, max-file=3,意味着一个容器有三个日志,分别是id +.json、id +1.json、id +2.json。 systemctl daemon-reload systemctl restart docker
还有一种办法就是添加 DOCKER-USER If you need to add rules which load before Docker’s rules, add them to the DOCKER-USER chain. These rules are loaded before any rules Docker creates automatically.
1 2 3 4 5 6 7 8 9 10 11 12 13 *filter :INPUT DROP [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] :DOCKER-USER - [0:0] -A FORWARD -j DOCKER-USER -A DOCKER-USER -s x.x.x.x -p tcp --dport 80 -j RETURN -A DOCKER-USER -p tcp --dport 80 -j DROP -A DOCKER-USER -p udp --dport 80 -j DROP -A DOCKER-USER -j RETURN COMMIT
Dockerfile 首先,安利一下 Dockerfile 优化指南
1 2 3 4 5 6 7 8 9 10 11 12 13 FROM python:3.7 RUN apt-get update \ && rm -rf /var/lib/apt/lists/* WORKDIR /usr/src/app COPY requirements.txt ./ RUN pip install -r requirements.txt COPY . . EXPOSE 8000 CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]
tag docker 镜像有许多的版本,不同版本间差异需要注意。举个例子,我遇到因为版本不同,ip route get 结尾多了一个 uid 0
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 ip -4 route get 8.8.8.8 8.8.8.8 via 192.168.0.1 dev eth0 src 192.168.0.105 uid 0 8.8.8.8 via 192.168.0.1 dev eth0 src 192.168.0.105 root@feiy:/etc/apt iproute2: Installed: 4.9.0-1+deb9u1 Candidate: 4.9.0-1+deb9u1 Version table: *** 4.9.0-1+deb9u1 500 500 http://deb.debian.org/debian stretch/main amd64 Packages 100 /var/lib/dpkg/status root@feiy:/etc/apt iproute2: Installed: 4.20.0-2 Candidate: 4.20.0-2 Version table: *** 4.20.0-2 500 500 http://deb.debian.org/debian buster/main amd64 Packages 100 /var/lib/dpkg/status
network docker 是基于 iptables 进行流量的转发,添加了一个虚拟的网卡 docker0 。 如果想从容器内部访问宿主机的 IP,比如从 172.17.0.3 访问宿主机的内网地址 192.168.1.10 , 我们从 tcpdump 在网卡 docker0 抓包可以看到流量。 但是在内网网卡抓包没有结果。猜测原因是:当数据包从网卡 docker0 转发后,直接在内核进入 INPUT 链。所以,如果想访问宿主机的 IP, 需要在 INPUT 添加相关规则,允许访问。 iptables -A INPUT -i docker0 -j ACCEPT
mac 上使用 docker
volume 的位置和 linux 不同,解决办法如下
1 2 3 4 5 6 7 8 cd ~/Library/Containers/com.docker.docker/Data/vms/0/screen tty cd /var/lib/docker/volumes/
如果想从容器内部访问 mac,也和 Linux 不同。详情可以看官网docker mac network 在容器内部可以使用 host.docker.internal 就可以访问到 Mac 宿主机啦。 而在 Linux 机器上, 容器可以直接使用宿主机的 IP 来访问宿主机 NIA_URL=http://host.docker.internal:5000
docker-proxy can refer this (article)[https://mp.weixin.qq.com/s/S4aMdmQW50HR7Lj2z2-VZQ]
1 2 3 “userland-proxy”:false
find process In one hosts, if we have many dockers, sometimes we need find some proceess belong to which docker.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 pstree -laps [pid] pstree -laps 38564 systemd,1 `-dockerd,171350 `-docker-containe,171362 --config /var/run/docker/containerd/containerd.toml `-docker-containe,332151 -namespace moby -workdir /var/lib/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/38dfefa95c1f8b4827e0a95834119b3756775d389820ea90d95878d3518eed67 -address /var/run/docker/containerd/docker-containerd.sock -containerd-binary /usr/bin/docker-containerd -runtime-root /var/run/docker/runtime-runc `-smb,332174 /usr/local/bin/smb run -e live -c id -i sg `-sh,332221 -c gunicorn webapi.wsgi -c webapi/gunicorn_config.py `-gunicorn: maste,332306 `-gunicorn: worke,38564 |-{gunicorn: worke},38613 |-{gunicorn: worke},83641 |-{gunicorn: worke},83642 |-{gunicorn: worke},83643 |-{gunicorn: worke},83644 |-{gunicorn: worke},83645 |-{gunicorn: worke},83646 `-{gunicorn: worke},83647
docker-compose https://wiki.jikexueyuan.com/project/docker-technology-and-combat/commands.html
docker cron cron failed http://blog.allen-mo.com/2018/04/17/docker_crontab/
1 chmod -R 0600 /var/spool/cron/crontabs