Docker命令使用经验总结

0x00 前言

Docker作为现在常用的服务部署方式,日常工作中免不了要做些buildpush之类的操作。为了避免每次都要查文档,这里将一些常用的命令和技巧做一些总结。

以下以Ubuntu 16.04 x64系统作为演示环境。

0x01 环境准备

安装docker

  1. $ apt install docker
  2. $ docker --version
  3. Docker version 18.06.1-ce, build e68fc7a
COPY

重启docker服务

  1. $ systemctl daemon-reload
  2. $ systemctl restart docker
COPY

设置docker代理

此代理主要用于docker访问镜像仓库

创建配置文件:/etc/systemd/system/docker.service.d/http-proxy.conf,写入以下内容:

  1. [Service]
  2. Environment="HTTP_PROXY=http://web-proxy.com:8080" "HTTPS_PROXY=http://web-proxy.com:8080" "NO_PROXY=internal.com"
COPY

重启docker服务,配置生效

0x02 编写Dockerfile

要编译docker镜像,需要先编写Dockerfile文件。以下是一个Dockerfile的例子:

  1. FROM python:2.7
  2. # 基于python2.7镜像
  3. RUN apt update && apt install python-pip -y \
  4. && rm -rf /var/lib/apt/lists/* \
  5. && pip install uwsgi \
  6. && pip install tornado \
  7. && mkdir /data
  8. # 编译时执行的命令,需要尽量写成一条命令
  9. WORKDIR /data
  10. # 设置工作目录
  11. COPY adb /usr/bin/
  12. # 拷贝文件
  13. COPY api/ /data/api/
  14. # 拷贝目录
  15. VOLUME ["/data1","/data2"]
  16. # 挂载目录
  17. ENV TZ="Asia/Shanghai"
  18. # 设置时区
  19. EXPOSE 80/tcp 8080/tcp
  20. # 暴露服务端口
  21. ENTRYPOINT sh /data/start.sh
  22. # 指定入口命令,如果这个命令退出,docker容器也会一起退出
COPY

可以看出,格式还是相对比较简单的,照着例子,基本都能写出来。

ADD与COPY指令的区别

两者都可以用于向镜像中添加文件/目录,主要区别是:COPY只能添加本地文件/目录,ADD可以添加url指向的文件;并且,ADD如果指定的源地址是一个本地的tar文件,还会自动解压到目标目录中。

ENTRYPOINT和CMD指令的区别

两者都可以设置docker run的入口命令行,如果指定了多个,只有最后一个生效,两者主要区别是:如果Dockerfile中同时存在ENTRYPOINTCMD,只有ENTRYPOINT会执行;ENTRYPOINT配置的命令行允许被--entrypoint参数覆盖,而CMD配置的命令行允许被启动参数覆盖。

因此,优先级顺序是:

–entrypoint > ENTRYPOINT > 启动参数 > CMD

HEALTHCHECK

这是docker 1.12新增的指令,可以用于检查容器的健康状态。

  1. HEALTHCHECK --interval=10s --timeout=5s --retries=3 \
  2. CMD curl -fs http://localhost/ || exit 1
COPY

上面的指令是用来检测web服务是否正常方法,如果重试5次都失败后,容器状态会变成unhealthy,可以使用docker inspect命令查看容器状态。

ONBUILD

这条指令允许在使用当前镜像作为基础镜像去构建的时候触发,也就是说,在构建当前镜像时并不会触发这条指令。

  1. ONBUILD COPY ./package.json /app
  2. ONBUILD RUN [ "npm", "install" ]
COPY

0x03 编译镜像

  1. $ docker build -t demo .
COPY

表示使用当前目录的Dockerfile构建镜像demo

指定代理

如果要指定编译时的HTTP代理,可以使用--build-arg参数:

  1. $ docker build -t demo . --build-arg http_proxy=http://web-proxy.com:8080
COPY

指定dns服务器

如果要指定编译时的dns服务器,可以修改docker的配置文件:/etc/docker/daemon.json,增加以下配置,并重启docker服务。

  1. "dns": ["10.0.0.1"]
COPY

设置默认镜像源

在配置文件:/etc/docker/daemon.json中增加以下配置项,并重启docker服务。

  1. "registry-mirrors": ["https://mirror.ccs.tencentyun.com"]
COPY

上面的镜像源是在腾讯云内部使用的镜像源地址。

指定Dockerfile路径

如果Dockerfile文件不在当前目录下,可以在docker build命令中使用-f /path/to/Dockerfile参数来制定Dockerfile文件的路径。

查看镜像的层信息

  1. $ docker history demo
  2. IMAGE CREATED CREATED BY SIZE COMMENT
  3. 9088b64a2ef3 15 seconds ago /bin/sh -c #(nop) ENTRYPOINT ["/bin/sh" "-c… 0B
  4. 6949219d8872 16 seconds ago /bin/sh -c #(nop) EXPOSE 80/tcp 8080/tcp 0B
  5. 80ff6b9185da 16 seconds ago /bin/sh -c #(nop) ENV TZ=Asia/Shanghai 0B
  6. d069fdc8190a 58 seconds ago /bin/sh -c #(nop) COPY file:f005afea09a30b4d… 10B
  7. a09c0e999ca0 About a minute ago /bin/sh -c #(nop) WORKDIR /data 0B
  8. 28ed536148c6 About a minute ago |0 /bin/sh -c apt update && apt install pyth 35.4MB
  9. d8690ef56706 2 years ago /bin/sh -c #(nop) CMD ["python2"] 0B
  10. <missing> 2 years ago /bin/sh -c pip install --no-cache-dir virtua 6.37MB
  11. <missing> 2 years ago /bin/sh -c set -ex; wget -O get-pip.py 'ht… 5.26MB
  12. <missing> 2 years ago /bin/sh -c #(nop) ENV PYTHON_PIP_VERSION=9.… 0B
  13. <missing> 2 years ago /bin/sh -c set -ex && buildDeps=' dpkg-de 45.6MB
  14. <missing> 2 years ago /bin/sh -c #(nop) ENV PYTHON_VERSION=2.7.14 0B
  15. <missing> 2 years ago /bin/sh -c #(nop) ENV GPG_KEY=C01E1CAD5EA2C… 0B
  16. <missing> 2 years ago /bin/sh -c apt-get update && apt-get install 8.67MB
  17. <missing> 2 years ago /bin/sh -c #(nop) ENV LANG=C.UTF-8 0B
  18. <missing> 2 years ago /bin/sh -c #(nop) ENV PATH=/usr/local/bin:/… 0B
  19. <missing> 2 years ago /bin/sh -c set -ex; apt-get update; apt-ge 324MB
  20. <missing> 2 years ago /bin/sh -c apt-get update && apt-get install 123MB
  21. <missing> 2 years ago /bin/sh -c set -ex; if ! command -v gpg > /… 0B
  22. <missing> 2 years ago /bin/sh -c apt-get update && apt-get install 44.6MB
  23. <missing> 2 years ago /bin/sh -c #(nop) CMD ["bash"] 0B
  24. <missing> 2 years ago /bin/sh -c #(nop) ADD file:f1509ab9c2cd38107… 123MB
COPY

使用--no-trunc参数可以显示完整信息

0x04 运行容器

  1. $ docker run -it demo bash
COPY

使用-d参数可以在后台启动容器。

指定运行时的dns服务器

  1. $ docker run -i --dns=10.0.0.1 demo
COPY

指定运行时的环境变量

  1. $ docker run -i --env http_proxy=http://web-proxy.com:8080 demo
COPY

挂载主机目录

  1. $ docker run -i -v /home/ubuntu/data:/data demo
COPY

这样可以把主机上的/home/ubuntu/data目录挂载到容器里的/data下。

映射端口

默认情况下无法从外部访问容器内的服务,但是可以通过在启动容器时加上-p port1:port2参数,将容器内的端口port2映射到本机的port1端口。

覆盖ENTRYPOINT

使用--entrypoint参数可以覆盖Dockerfile中配置的ENTRYPOINT命令行,但是需要注意的是:如果需要传参的话需要写成--entrypoint mongod mongo:latest --replSet rs0这样的形式,也就是命令和参数是分开的。

进入容器shell

  1. $ docker ps
  2. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  3. e6ae7638a58d demo "/bin/sh -c '/data/start.sh'" 8 seconds ago Up 7 seconds 80/tcp, 8080/tcp loving_neumann
  4. $ docker exec -i -t e6ae7638a58d sh
  5. # id
  6. uid=0(root) gid=0(root) groups=0(root)
COPY

如果默认进去的不是root权限,可以增加-u root参数。

清理磁盘空间

  1. $ docker system prune -a -f
COPY

0x05 登录docker仓库

登录官方仓库

  1. $ docker login
  2. Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
  3. Username: drunkdream
  4. Password:
  5. WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
  6. Configure a credential helper to remove this warning. See
  7. https://docs.docker.com/engine/reference/commandline/login/#credentials-store
  8. Login Succeeded
COPY

登录非官方仓库

  1. $ docker login hub.tencentyun.com
  2. Username: drunkdream
  3. Password:
  4. WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
  5. Configure a credential helper to remove this warning. See
  6. https://docs.docker.com/engine/reference/commandline/login/#credentials-store
  7. Login Succeeded
COPY

如果仓库使用的不是HTTPS的443端口,需要在主机名后面加上:port

如果提示以下错误:

  1. Error response from daemon: Get https://hub.private.com:8080/v2/: http: server gave HTTP response to HTTPS client
COPY

说明Server不支持HTTPS协议,需要在配置文件:/etc/docker/daemon.json中增加以下配置:

  1. "insecure-registries": ["hub.private.com:8080"]
COPY

重启docker服务,再登录就可以了

登录协议

抓包可得以下结果:

  1. GET /v2/ HTTP/1.1
  2. Host: hub.private.com:8080
  3. User-Agent: docker/18.06.1-ce go/go1.10.4 git-commit/e68fc7a kernel/4.10.0-28-generic os/linux arch/amd64 UpstreamClient(Docker-Client/18.06.1-ce \(linux\))
  4. Authorization: Basic YWRtaW46YWRtaW4=
  5. Accept-Encoding: gzip
  6. Connection: close
  7. HTTP/1.1 200 OK
  8. Content-Length: 2
  9. Content-Type: application/json; charset=utf-8
  10. Date: Mon, 25 Feb 2019 04:09:50 GMT
  11. Docker-Distribution-Api-Version: registry/2.0
  12. X-Content-Type-Options: nosniff
  13. Connection: close
  14. {}
COPY

说明: docker是使用了HTTP协议的Authorization头进行了身份认证,很容易获取明文密码。因此,为了安全,一定要使用HTTPS协议。

0x06 push新镜像到仓库

查询镜像

  1. $ docker search python
  2. NAME DESCRIPTION STARS OFFICIAL AUTOMATED
  3. python Python is an interpreted, interactive, objec 5022 [OK]
  4. django Django is a free web application framework, 941 [OK]
  5. pypy PyPy is a fast, compliant alternative implem 234 [OK]
  6. kaggle/python Docker image for Python scripts run on Kaggle 138 [OK]
  7. arm32v7/python Python is an interpreted, interactive, objec 48
  8. joyzoursky/python-chromedriver Python with Chromedriver, for running automa 43 [OK]
  9. nikolaik/python-nodejs Python with Node.js 40 [OK]
  10. centos/python-35-centos7 Platform for building and running Python 3.5 38
  11. circleci/python Python is an interpreted, interactive, objec 37
  12. centos/python-36-centos7 Platform for building and running Python 3.6 28
  13. hylang Hy is a Lisp dialect that translates express 27 [OK]
  14. arm64v8/python Python is an interpreted, interactive, objec 21
  15. centos/python-27-centos7 Platform for building and running Python 2.7 17
  16. publicisworldwide/python-conda Basic Python environments with Conda. 6 [OK]
  17. bitnami/python Bitnami Python Docker Image 6 [OK]
  18. dockershelf/python Repository for docker images of Python. Test 5 [OK]
  19. i386/python Python is an interpreted, interactive, objec 3
  20. centos/python-34-centos7 Platform for building and running Python 3.4 2
  21. komand/python-plugin DEPRECATED: Komand Python SDK 2 [OK]
  22. ppc64le/python Python is an interpreted, interactive, objec 2
  23. amd64/python Python is an interpreted, interactive, objec 1
  24. ccitest/python CircleCI test images for Python 0 [OK]
  25. s390x/python Python is an interpreted, interactive, objec 0
  26. openshift/python-33-centos7 DEPRECATED: A Centos7 based Python v3.3 imag 0
  27. saagie/python Repo for python jobs 0
COPY

如果想获取python镜像的tag列表,可以使用以下命令:

  1. $ wget -q https://registry.hub.docker.com/v1/repositories/python/tags -O - | sed -e 's/[][]//g' -e 's/"//g' -e 's/ //g' | tr '}' '\n' | awk -F: '{print $3}'
COPY

拉取镜像到本地

  1. $ docker pull python
  2. Using default tag: latest
  3. latest: Pulling from library/python
  4. 741437d97401: Pull complete
  5. 34d8874714d7: Pull complete
  6. 0a108aa26679: Pull complete
  7. 7f0334c36886: Pull complete
  8. 65c95cb8b3be: Pull complete
  9. 9107d7193263: Pull complete
  10. dd6f212ec984: Pull complete
  11. 43288b101abf: Pull complete
  12. 89dd65885f16: Pull complete
  13. Digest: sha256:a570ef00b7348c85b546c0e67955fa3be233c27bc2379d0f87fc8e4ff25aa006
  14. Status: Downloaded newer image for python:latest
COPY

打标签

  1. $ docker tag python:latest hub.tencentyun.com/drunkdream/python:latest
COPY

如果要push到非官方仓库,需要在打tag时加上仓库的地址。

push镜像到仓库

  1. $ docker push hub.tencentyun.com/drunkdream/python:latest
  2. The push refers to repository [hub.tencentyun.com/drunkdream/python:latest]
  3. b2f7bd391363: Pushed
  4. 08a5b66845ac: Pushed
  5. 88a85bcf8170: Pushed
  6. 65860ac81ef4: Pushed
  7. a22a5ac18042: Pushed
  8. 6257fa9f9597: Pushed
  9. 578414b395b9: Pushed
  10. abc3250a6c7f: Pushed
  11. 13d5529fd232: Pushed
  12. latest: digest: sha256:35a3001b1defafa4611f764a9c6d07c2146aefc17be2c24ee0200fd37b19b1c7 size: 2218
COPY

0x07 镜像导出与导入

镜像导出

  1. $ docker save -o demo.tar demo:latest
COPY

镜像导入

  1. $ docker load -i demo.tar
COPY

0x08 Compose

Compose项目是Docker官方的开源项目,实现了对Docker容器集群的快速编排。从功能上看,跟OpenStack中的Heat十分类似。

其代码在https://github.com/docker/compose上开源。

安装

  1. $ pip install docker-compose
COPY

编写docker-compose.yml

这个文件描述了容器之间的关系。

  1. version: '3'
  2. services:
  3. webapp:
  4. build: .
  5. # Dockerfile所在目录
  6. dockerfile: Dockerfile
  7. # Dockerfile 文件名
  8. command: echo "hello world"
  9. # 覆盖容器启动后的默认命令
  10. depends_on:
  11. - db
  12. - redis
  13. # 服务依赖
  14. dns:
  15. - 8.8.8.8
  16. - 114.114.114.114
  17. # 配置DNS
  18. env_file: .env
  19. # 指定环境变量文件
  20. environment:
  21. - DEBUG=1
  22. # 设置环境变量
  23. expose:
  24. - "8080"
  25. # 暴露端口,只在服务间被访问
  26. extra_hosts:
  27. - "www.drunkdream.com:1.1.1.1"
  28. # 添加额外hosts
  29. healthcheck:
  30. test: ["CMD", "curl", "-f", "http://localhost"]
  31. interval: 10s
  32. timeout: 5s
  33. retries: 3
  34. # 健康检查
  35. image: ubuntu
  36. # 指定镜像
  37. ports:
  38. - "80"
  39. - "8080:80"
  40. - "127.0.0.1:8001:8001"
  41. # 映射端口,格式为:HOST:CONTAINER
  42. volumes:
  43. - "/localhost/postgres.sock:/var/run/postgres/postgres.sock"
  44. - "/localhost/data:/var/lib/postgresql/data"
  45. # 磁盘映射
  46. networks:
  47. - front-tier
  48. - back-tier
  49. # 配置网络
  50. networks:
  51. front-tier:
  52. driver: bridge
  53. back-tier:
  54. driver: bridge
COPY

常用命令

  1. $ docker-compose up
COPY

启动所有服务,使用-d参数可以在后台启动服务,-f参数可以指定docker-compose.yml。

  1. $ docker-compose down
COPY

停止和删除容器、网络

  1. $ docker-compose logs
COPY

查看日志

  1. $ docker-compose build
COPY

构建所有容器

分享

Related Issues not found

Please contact @drunkdream to initialize the comment