镜像
获取镜像
docker pull
查看镜像信息
docker images
docker inspect # 获取镜像的详细信息
搜寻镜像
docker search
删除镜像
docker rmi
当一个镜像拥有多个标签,docker rmi 只是删除该镜像指定的标签,并不影响镜像文件
当镜像只剩下一个标签时,再使用会彻底删除该镜像
先删除该镜像的所有容器,再删除镜像
创建镜像
2 种方法:
- 基于已有镜像的容器创建
- 基于 Dockerfile 创建(推荐)
基于已有镜像的容器创建
docker commit
-a: 作者信息
-m: 提交信息
-p 提交时暂停容器运行
-c changelist
存出和载入镜像
存出:sudo docker save -o ubuntu_16.04.tar ubuntu:16.04
载入:sudo docker load --input ubuntu_16.04.tar 或者 sudo docker load < ubuntu_16.04.tar
导入镜像,以及其相关的元数据信息(包括标签等)
容器
创建容器
使用交互式来运行容器:sudo docker run -it ubuntu:latest /bin/bash
docker run在后台执行的标准操作:
- 检查本地是否存在指定的镜像, 不存在就从公有仓库下载
- 利用镜像创建并启动一个容器
- 分配一个文件系统,并在只读的镜像层外面挂载一层可读写层
- 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去。
- 从地址池配置一个 IP 地址给容器
- 执行用户指定的应用程序
- 执行完毕后容器被终止
守护态运行
sudo docker run -d ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"
通过docker logs命令获取容器的输出信息:sudo docker -tf logs 2855b4d76ccb
-t: 打印时间戳
-f: 刷新日志到最后
2855b4d76ccb: 容器id
终止容器
sudo docker stop 2855b4d76ccb
查看所有容器的信息:sudo docker ps -a
处于终止状态的容器,可以通过 docker start 命令来重新启动:sudo docker start 2855b4d76ccb
重启容器:sudo docker restart 2855b4d76ccb
进入容器
attach指令
sudo docker attach 2855b4d76ccb
当多个窗口同时 attach 到同一个容器时, 所有窗口会同步显示。当某个窗口因命令阻塞时,其他窗口也无法执行操作。
exec 命令
sudo docker exec -ti 2855b4d76ccb /bin/bash
删除容器
sudo docker rm 2855b4d76ccb
-f 强制删除运行中的容器
-l 删除容器链接,但保留容器
-v 删除容器挂载的数据卷
导入/导出容器
导出
sudo docker export 2855b4d76ccb > test.tar
可以将这些文件传输到其他机器上, 在其他机器上通过导入命令实现容器迁移
导入
cat test.tar | sudo docker import - test/ubuntu:v1.0
docker load 导入镜像存储文件到本地的镜像库
docker import 导入一个容器快照到本地镜像库
区别:
容器快照文件将丢弃所有的历史记录和元数据信息(仅保存容器当时的快照状态),导入时可以重新指定标签等元数据信息。
镜像存储文件将保存完整记录, 体积也大。
仓库
Docker Hub
登录
docker login
搜索
docker search
docker tag
sudo docker tag ubuntu:14.04 10.0.2.2:5000/test
自动创建
步骤:
创建和使用私有仓库
使用 registry 镜像创建私有仓库
sudo docker -d -p 5000:5000 -v /opt/docker/registry/:/tmp/registry registry
监听端口映射到 5000,docker 容器中的 /tmp/registry 被映射到本地的 /opt/docker/registry/ 上。
管理私有仓库镜像
- 修改 tag 的 REGISTRYHOST sudo docker tag ubuntu:latest 172.17.0.1:5000/test
- 使用 docker push 上传 sudo docker push 172.17.0.1:5000/test
- 使用docker pull 下载 sudo docker pull 172.17.0.1:5000/test
数据管理
两种方式:
- 数据卷(Data Volumes)
- 数据卷容器(Data Volume Containers)
数据卷
特性:
- 可以在容器间共享和重用
- 对数据卷的修改会立马生效
- 对数据卷的更新, 不会影响容器
- 卷会一直存在, 直到没有容器使用
类似 Linux 的 mount 操作
挂载一个主机目录作为数据卷
sudo docker run -v /src/webapp:/opt/webapp training/webapp python app.py
加载主机的/src/webapp 目录到容器的 /opt/webapp 目录.
主机目录必须是绝对路径
默认权限是读写(rw), 可以设置为只读(ro) /src/webapp:/opt/webapp:ro
数据卷容器
数据卷容器其实就是普通的容器, 专门用它提供数据卷供其他容器挂载使用.
- 创建一个数据卷容器: sudo docker run -it -v /dbdata --name dbdata ubuntu
- 在其他容器中使用 volumes-from 来挂载 dbdata 容器中的数据卷.
- sudo docker run -it --volumes-from dbdata --name db1 ubuntu
- sudo docker run -it --volumes-from dbdata --name db2 ubuntu
复制代码3个容器任何一方在该目录写入, 其他容器都可以看到。
如果删除了容器, 数据卷并不会自动删除. 如果要删除数据卷, 必须在删除最后一个挂载着它的容器时显式使用 docker rm -v 命令来指定同时删除关联的容器
利用数据卷容器迁移数据
备份
sudo docker run --volumes-from dbdata -v $(pwd):/backup --name worker ubuntu tar cvf /backup/backup.tar /dbdata
恢复
- sudo docker run -v /dbdata --name dbdata2 ubuntu /bin/bash
- sudo docker run --volumes-from dbdata2 -v $(pwd):/backup busybox tar xvf /backup/backup.tar
复制代码 网络基础配置
端口映射实现访问容器
sudo docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py
-P: 映射到随机端口
查看端口映射配置
sudo docker port loving_montalcini
容器互联实现容器间通信
容器的连接(linking)系统, 它会在源和接收容器之间创建一个隧道, 接收容器可以看到源容器指定的信息.
连接系统依据容器的名称来执行.
在执行 docker run 的时候如果添加 --rm 标记, 则容器在终止后会立即删除. --rm 和 -d 无法同时使用.
容器互联
- sudo docker run -d --name db training/postgres # 创建一个新的数据库容器
- sudo docker run -d -P --name web --link db:db training/webapp python app.py # --link name:alias alias是连接的别名
复制代码 Docker通过2种方式为容器公开连接信息:
使用 env 命令查看web容器的环境变量:- $ docker exec web env
- PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
- HOSTNAME=62b19d3b5add
- DB_PORT=tcp://172.17.0.2:5432
- DB_PORT_5432_TCP=tcp://172.17.0.2:5432
- DB_PORT_5432_TCP_ADDR=172.17.0.2
- DB_PORT_5432_TCP_PORT=5432
- DB_PORT_5432_TCP_PROTO=tcp
- DB_NAME=/web/db
- DB_ENV_PG_VERSION=9.3
- HOME=/root
复制代码 /etc/hosts 文件:- $ docker exec web cat /etc/hosts
- 127.0.0.1 localhost
- ::1 localhost ip6-localhost ip6-loopback
- fe00::0 ip6-localnet
- ff00::0 ip6-mcastprefix
- ff02::1 ip6-allnodes
- ff02::2 ip6-allrouters
- 172.17.0.2 db 4288c4f9ad47
-
- 172.17.0.3 62b19d3b5add # 本容器
复制代码 也可以通过 ping 来测试:- $ docker exec web ping 172.17.0.2
- PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
- 64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.083 ms
- 64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.054 ms
- 64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.054 ms
- 64 bytes from 172.17.0.2: icmp_seq=4 ttl=64 time=0.053 ms
- 64 bytes from 172.17.0.2: icmp_seq=5 ttl=64 time=0.055 ms
- 64 bytes from 172.17.0.2: icmp_seq=6 ttl=64 time=0.057 ms
复制代码 使用 Dockerfile 创建镜像
基本结构
- 基础镜像信息
- 维护者信息
- 镜像操作指令
- 容器启动时执行指令
指令
FROM
第一条指令必须为 FROM 指令
MAINTAINER(已弃用)
制定维护者信息. 以后可以用 LABEL maintainer="CaseyCui cuikaidong@foxmail.com"
RUN
两种格式:
- RUN bash格式, 命令在bash中运行, 默认在Linux是 /bin/sh -c 在windows上是 cmd /S /C
- RUN ["executable", "param1", "param2"] (用 docker exec 执行)
每条RUN指令将在当前镜像基础上执行指定命令, 并提交为新的镜像.
最佳实践:
apt-get安装:- RUN apt-get update && apt-get install -y --no-install-recommends \
- aufs-tools \
- automake \
- build-essential \
- curl \
- dpkg-sig \
- libcap-dev \
- libsqlite3-dev \
- mercurial \
- reprepro \
- ruby1.9.1 \
- ruby1.9.1-dev \
- s3cmd=1.1.* \
- && rm -rf /var/lib/apt/lists/*
复制代码apt-get update && apt-get install 合用
apt-get install -y --no-install-recommends 不安装其他推荐的包, -no-install-suggests 也可以加上
ruby1.9.1 s3cmd=1.1.* 安装指定版本的包
rm -rf /var/lib/apt/lists/* 删除软件包残留
- ## a few minor docker-specific tweaks
- ## see https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap
- RUN set -xe \
- \
- ## https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap#L40-L48
- && echo '#!/bin/sh' > /usr/sbin/policy-rc.d \
- && echo 'exit 101' >> /usr/sbin/policy-rc.d \
- && chmod +x /usr/sbin/policy-rc.d \
- \
- ## https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap#L54-L56
- && dpkg-divert --local --rename --add /sbin/initctl \
- && cp -a /usr/sbin/policy-rc.d /sbin/initctl \
- && sed -i 's/^exit.*/exit 0/' /sbin/initctl \
- \
- ## https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap#L71-L78
- && echo 'force-unsafe-io' > /etc/dpkg/dpkg.cfg.d/docker-apt-speedup \
- \
- ## https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap#L85-L105
- && echo 'DPkg::Post-Invoke { "rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true"; };' > /etc/apt/apt.conf.d/docker-clean \
- && echo 'APT::Update::Post-Invoke { "rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true"; };' >> /etc/apt/apt.conf.d/docker-clean \
- && echo 'Dir::Cache::pkgcache ""; Dir::Cache::srcpkgcache "";' >> /etc/apt/apt.conf.d/docker-clean \
- \
- ## https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap#L109-L115
- && echo 'Acquire::Languages "none";' > /etc/apt/apt.conf.d/docker-no-languages \
- \
- ## https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap#L118-L130
- && echo 'Acquire::GzipIndexes "true"; Acquire::CompressionTypes::Order:: "gz";' > /etc/apt/apt.conf.d/docker-gzip-indexes \
- \
- ## https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap#L134-L151
- && echo 'Apt::AutoRemove::SuggestsImportant "false";' > /etc/apt/apt.conf.d/docker-autoremove-suggests
复制代码set -xe 调试模式, 返回非 0 (即不成功) 就退出
CMD
支持三种格式:
- CMD ["executable","param1","param2"] 使用 docker exec 执行, 推荐方式
- CMD ["param1","param2"] 作为 ENTRYPOINT 的默认参数
- CMD command param1 param2 bash
指定启动容器时执行的命令, 每个 Dockerfile 只能有一条 CMD 命令.
EXPOSE
EXPOSE 80 8443
暴露的端口号, 供互联系统使用. 在启动时可以通过 -P 或 -p 来指定映射
ENV
- ENV PG_MAJOR 9.3
- ENV PG_VERSION 9.3.4
- RUN curl -SL http://example.com/postgres-$PG_VERSION.tar.xz | tar -xJC /usr/src/postgress && …
- ENV PATH /usr/local/postgres-$PG_MAJOR/bin:$PATH
复制代码 ADD
推荐只在 src 为 tar 文件时(会自动解压)使用. 其他时候使用 COPY. 不推荐使用 URL 的方式.
COPY
COPY 当使用本例目录为 src 时, 推荐使用 COPY
ENTRYPOINT
两种格式:
- ENTRYPOINT ["executable", "param1", "param2"] exec 格式
- ENTRYPOINT command param1 param2 bash 格式
VOLUME
创建一个可以从本地主机或其他容器挂载的挂载点, 一般用来存放数据库和需要保持的数据等.
USER
指定运行容器时的用户名或 UID, 后续的 RUN 也会使用指定用户.
当服务不需要管理员权限时, 可以通过该命令指定运行用户.
要临时获取管理员权限推荐使用 gosu , 不推荐sudo
WORKDIR
为后续的 RUN CMD ENTRYPOINT 指令配置工作目录.
ONBUILD
ONBUILD [Dockerilfe的指令]
配置当所创建的镜像作为其他新创建镜像的基础镜像时, 所执行的操作指令.
使用 ONBUILD 指令的镜像, 推荐在 tag 中注明, 如 ruby:1.9-onbuild
创建镜像
docker build [选项] 路径
实现:
- 读取指定路径下(包括子目录)的 Dockerfile
- 将该路径下所有内容发送给 Docker 服务端
- 由服务端来创建镜像
一般建议放置 Dockerfile 的目录为空目录
可以通过 .dockerignore 文件来让 Docker 忽略路径下的目录和文件.- ## comment
- */temp*
- */*/temp*
- temp?
复制代码 指令示例: sudo docker build -t build_repo/first_image /tmp/docker_builder/
三人行, 必有我师; 知识共享, 天下为公. 本文由东风微鸣技术博客 EWhisper.cn 编写.
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |