docker 学习笔记
概念理解
docker的功能比较像一个chroot应用,拥有一个守护进程daemon.
docker容器并不是一个完整的系统,不包含linux内核,并且只是一个最小系统.docker容器的内核依旧是宿主系统的内核.docker利用了linux内核的命名空间namespace,容器组cgroup,设备映射的技术.
docker的命令使用起来比较像git.
docker拥有官方hub和可以私有搭建的镜像库registry(默认docker官方的docker hub),提供镜像下载服务.
docker文件系统利用了联合加载(union mount)和写时复制(copy on write)的技术(aufs也是该技术),可以在文件系统上叠加文件结构,形成层级关系,但是从纵向看过去就像一个文件系统.通过镜像库下载的镜像作为最底层rootfs,并不能被修改,而是每次修改都记录在一个层中,在最顶层加载一个读写文件系统,使得看上去好像我们修改了底层系统一样.
docker目前使用时必须具有root权限.因为需要用到宿主底层的接口.
docker启动后会修改镜像中的/etc/hosts
和/etc/resolv.conf
文件,使得docker容器可以使用主机的网络环境,以及记录docker network子网路由解析信息等.docker会感知所使用网络下的所有容器并将相应的DNS信息写入每个容器的/etc/hosts
中,如果指定了容器的名称,主机可以使用hostname.netname的形式解析DNS.
docker容器默认不对外公开任何接口,是无法访问的,需要给容器指定对外的接口
docker默认使用172.17.x.x作为子网地址,除非该子网被占用.如果占用,则从172.16~172.30中尝试.
docker安装时会创建一个新的网络接口docker0,作为默认网络桥.它是一个虚拟的以太网桥,用于连接宿主和容器.docker每创建一个容器就会创建一组互联的网络接口,一端作为容器的eth0接口,一端作为veth开头的接口存在与宿主作为一个宿主端口,可以认为它是一根网线连接在docker0和容器内网卡上.
(1.9版本以上)可以创建自己的专用容器间网络,称为Docker Networking.使得容器可以跨越不同的主机进行通信,并且是支持可插拔的.
docker容器间通讯的两种方式: 通过docker网络 和 使用link链接连接容器.
docker常用命令
守护进程/usr/bin/docker启动选项
1 | --log-driver 下同docker run的 --log-driver,版本1.6以后可用 |
启动基于容器的本地registry
1 | sudo docker run -p 5000:5000 registry:2 |
docker run 创建并运行一个容器
1 | sudo docker run -i -t ubuntu:16.04 /bin/bash //镜像名ubuntu后加:16.04指定ubuntu仓库类目下的某一镜像16.04,/bin/bash是启动容器后需要执行的命令 |
docker ps 列出正在运行的容器
1 | -a 列出所有容器 |
docker start 启动已经创建并停止的容器
1 | sudo docker start ubuntu_test |
docker attach 重新附着到重启以后的容器会话上
1 | sudo docker attach ubuntu_test |
docker logs 获取容器的日志
1 | sudo docker logs ubuntu_test |
docker top 查看以守护式方式运行在后台的容器内的进程
1 | sudo docker top ubuntu_test |
docker exec 在正在运行容器内部执行新的命令或额外启动新的进程(1.3版本以后)
1 | sudo docker exec -d ubuntu_test touch 1.file |
docker stop 停止守护式的容器
1 | sudo docker stop c2c4e57c12 |
docker kill 发送信号给容器
1 | sudo docker kill -s <sibnal> <container> |
docker inspect 获取容器的详细信息
1 | sudo docker inspect ubuntu_test |
docker rm 删除不再使用的容器
1 | sudo docker rm 80430f8d |
docker rmi 删除一个或多个镜像
1 | sudo docker rmi ubuntu_test test //删除多个镜像 |
docker images 列出docker镜像
本地的镜像都保存在/var/lib/docker
下,所有容器在/var/lib/docker/container
下
docker pull 将某个镜像从registry中拉取下来到本地
sudo docker pull fedora:20
docker search 在registry中查询某个镜像
sudo docker search ubuntu
docker commit 提交某个镜像
1 | sudo docker commit -m "new image" -a "my" 433b23ce mydockeraccount/test:webser //将433b23ce这个镜像提交到docker hub中我的账号下名为test的仓库类目下并且使用:指定了镜像标签为webser |
docker build 使用Dockerfile文件构建镜像
1 | 可以使用 镜像名:标签 的格式可以设置镜像标签,如果没有指定标签自动设置latest标签 |
docker login 登录doker hub
sudo docker login
登录信息记录在$HOME/.dockercfg
或$HOME/.docker/config.json(1.7版本以上)
中
docker logout 退出registry
docker history 查看镜像构建的每一步都做了什么,是如何构建出来的
sudo docker history 22d48fg //列出该镜像构建时的每一层和Dockerfile指令
docker port 查看容器的端口映射情况
sudo docker port ubuntu-test 80 //查看ubuntu-test的80端口映射到宿主哪个端口
docker network docker networking 相关操作
1 | sudo docker network create mynet //创建名为mynet的docker桥接网络,命令返回该网络的ID.创建overlay网络会允许我们在多宿主间通信. |
Dockerfile文件
Dockerfile使用DSL语法,所有指令都必须为大写.
Dockerfile是顺序执行的.
在构建环境(上下文)目录(即使用当前所处在的目录位置为构建环境)下,新建名为Dockerfile的文件.Dockerfile大致执行流程为:从基础镜像运行一个容器,每次执行一个指令修改并提交操作生成新的镜像层,在该镜像层基础上运行新的容器,再重复执行下一条指令.某一指令执行失败可以使用上一指令执行后的容器名称进行调试.
docker构建每一步都会提交为镜像,就使得之前构建过程中的镜像可以被当作缓存,再次执行构建操作时如果构建操作没有变化会略过构建而直接使用缓存.
构建环境下.dockeignore文件可以指定目录下那些文件不被当作构建环境中的上下文的一部分,类似git的gitignore.该文件使用go的filepath中的匹配规则.
每个Dockerfile的第一条指令必须是FROM.
RUN
1 | 指定镜像被构建时运行的命令 |
CMD
1 | 指定容器启动时要运行的命令 |
ENTRYPOINT
1 | 指定在运行时要运行的命令,且不会轻易被run指令覆盖. |
WORKDIR
1 | 指定一个工作目录,后续的ENTRYPOINT和CMD指令会在这个目录下执行. |
ENV
1 | 指定镜像构建过程中的环境变量. |
USER
1 | 指定镜像以什么用户运行 |
VOLUME
1 | 指定一个目录位置,用来向基于镜像创建的容器添加卷 |
ADD
1 | 用来将构建环境下的文件和目录或URL位置对应的资源复制到镜像中. |
COPY
1 | 类似ADD,COPY只在构建上下文中复制本地文件,不做提取和解压工作. |
LABEL
1 | (1.6版本以上)为docker镜像添加元数据,元数据以键值对形式出现,推荐所有元数据放在一列,以免创建多层镜像. |
STOPSIGNAL
1 | (1.9版本以上)设置停止容器时发送的系统调用信号,必须是内核系统调用表中的合法的数,如 SIGKILL,9 |
ARG
1 | (1.9版本以上)定义可以在docker build 命令运行时传递给构建的变量.构建时只需使用--build-arg标志即可. |
ONBUILD
1 | 为镜像添加触发器,当一个镜像被用作其他镜像构建的基础镜像时会触发执行,在构建过程中插入新的指令.相当于这些指令紧跟在构建其他镜像的Dockerfile的FROM后面. |
Remote API
docker守护进程提供remote api, 默认情况下会在宿主创建套接字unix:///var/run/docker.sock
echo -e "GET /info HTTP/1.0\r\n" |sudo nc -U /var/run/dcoker.sock // 查询本地docker API
要启动docker API 需要使用-H给守护进程传递参数,可以修改守护进程的启动配置文件,将守护进程永久绑定到指定的网络接口上.
1 | Ubuntu/Debain: /etc/default/dcoker |
可以使用POST请求来调用/container/create接入点来创建容器,等同于docker run
:
1 | curl -X POST -H "Content-Type: application/json" http://localhost:2375/container/create -d '{"Image":"ubuntu-test"}' |
docker官网有docker Remote API客户端库的完整列表.
Docker Remote API 可以使用TLS/SSL进行认证,确保安全.需要自己创建CA证书.