@[TOC]Docker基础

容器简介

资源推荐

Docker 官方文档 https://docs.docker.com/

Docker 官网 DockerFile

Docker — 从入门到实践

github: https://github.com/yeasy/docker_practice

docker-image container 基本操作 -常用命令

基本

Docker 架构
16.png

Docker 镜像(Image)

是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像 不包含 任何动态数据,其内容在构建之后也不会被改变。

Docker 容器(Container)

镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的 类 和 实例 一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。

Docker 仓库 (Repository)

镜像构建完成后,可以很容易的在当前宿主机上运行,但是,如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry 就是这样的服务。

docker 命令

$ docker --help

Usage:  docker [OPTIONS] COMMAND

A self-sufficient runtime for containers

Options:
      --config string      Location of client config files (default
                           "C:\\Users\\水月情缘~雪飞飞\\.docker")
  -c, --context string     Name of the context to use to connect to the
                           daemon (overrides DOCKER_HOST env var and
                           default context set with "docker context use")
  -D, --debug              Enable debug mode
  -H, --host list          Daemon socket(s) to connect to
  -l, --log-level string   Set the logging level
                           ("debug"|"info"|"warn"|"error"|"fatal")
                           (default "info")
      --tls                Use TLS; implied by --tlsverify
      --tlscacert string   Trust certs signed only by this CA (default
                           "C:\\Users\\水月情缘~雪飞飞\\.docker\\ca.pem")
      --tlscert string     Path to TLS certificate file (default
                           "C:\\Users\\水月情缘~雪飞飞\\.docker\\cert.pem")
      --tlskey string      Path to TLS key file (default
                           "C:\\Users\\水月情缘~雪飞飞\\.docker\\key.pem")
      --tlsverify          Use TLS and verify the remote
  -v, --version            Print version information and quit

Management Commands:
  builder     Manage builds
  buildx*     Build with BuildKit (Docker Inc., v0.5.1-docker)
  compose*    Docker Compose (Docker Inc., 2.0.0-beta.4)
  config      Manage Docker configs
  container   Manage containers
  context     Manage contexts
  image       Manage images
  manifest    Manage Docker image manifests and manifest lists
  network     Manage networks
  node        Manage Swarm nodes
  plugin      Manage plugins
  scan*       Docker Scan (Docker Inc., v0.8.0)
  secret      Manage Docker secrets
  service     Manage services
  stack       Manage Docker stacks
  swarm       Manage Swarm
  system      Manage Docker
  trust       Manage trust on Docker images
  volume      Manage volumes

Commands:
  attach      Attach local standard input, output, and error streams to a running container
  build       Build an image from a Dockerfile
  commit      Create a new image from a container's changes
  cp          Copy files/folders between a container and the local filesystem
  create      Create a new container
  diff        Inspect changes to files or directories on a container's filesystem
  events      Get real time events from the server
  exec        Run a command in a running container
  export      Export a container's filesystem as a tar archive
  history     Show the history of an image
  images      List images
  import      Import the contents from a tarball to create a filesystem image
  info        Display system-wide information
  inspect     Return low-level information on Docker objects
  kill        Kill one or more running containers
  load        Load an image from a tar archive or STDIN
  login       Log in to a Docker registry
  logout      Log out from a Docker registry
  logs        Fetch the logs of a container
  pause       Pause all processes within one or more containers
  port        List port mappings or a specific mapping for the container
  ps          List containers
  pull        Pull an image or a repository from a registry
  push        Push an image or a repository to a registry
  rename      Rename a container
  restart     Restart one or more containers
  rm          Remove one or more containers
  rmi         Remove one or more images
  run         Run a command in a new container
  save        Save one or more images to a tar archive (streamed to STDOUT by default)
  search      Search the Docker Hub for images
  start       Start one or more stopped containers
  stats       Display a live stream of container(s) resource usage statistics
  stop        Stop one or more running containers
  tag         Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
  top         Display the running processes of a container
  unpause     Unpause all processes within one or more containers
  update      Update configuration of one or more containers
  version     Show the Docker version information
  wait        Block until one or more containers stop, then print their exit codes

Run 'docker COMMAND --help' for more information on a command.

To get more help with docker, check out our guides at https://docs.docker.com/go/guides/

容器安装

1.安装

Docker 官网

Docker Mac

  • 选择平台1:配备英特尔芯片的 Mac
  • 选择平台2:配备 Apple 芯片的 Mac

Docker Windows

  • 安装方式1:WSL 2 后端 微软WSL官网
  • 安装方式2: Hyper-V 后端和 Windows 容器
  • 注意:部分操作命令需要在前面加 winpty 参数。例如: winpty docker exec -it php bash

Docker Linux

镜像简介与操作

docker image 文档

$ docker image --help

Usage:  docker image COMMAND

Manage images

Commands:
  build       Build an image from a Dockerfile
  history     Show the history of an image
  import      Import the contents from a tarball to create a filesystem image
  inspect     Display detailed information on one or more images
  load        Load an image from a tar archive or STDIN
  ls          List images
  prune       Remove unused images
  pull        Pull an image or a repository from a registry
  push        Push an image or a repository to a registry
  rm          Remove one or more images
  save        Save one or more images to a tar archive (streamed to STDOUT by default)
  tag         Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE

Run 'docker image COMMAND --help' for more information on a command.

docker image

  • -a :列出本地所有的镜像(含中间映像层,默认情况下,过滤掉中间映像层);
  • –digests :显示镜像的摘要信息;
  • -f :显示满足条件的镜像;
  • –format :指定返回值的模板文件;
  • –no-trunc :显示完整的镜像信息;
  • -q :只显示镜像ID。

通过Dockerfile构建镜像

docker build [OPTIONS] PATH | URL | -

  • -f 指定要使用的Dockerfile路径;
  • -m :设置内存最大值;
  • –pull :尝试去更新镜像的新版本;
  • –rm :设置镜像成功后删除中间容器;
  • –squash :将 Dockerfile 中所有的操作压缩为一层。
  • –tag, -t: 镜像的名字及标签,通常 name:tag 或者 name 格式;可以在一次构建中为一个镜像设置多个标签
docker build -t php/php7:1 . 

history 展示镜像的历史

docker image history [OPTIONS] IMAGE

$ docker image history nginx
IMAGE          CREATED        CREATED BY                                      SIZE      COMMENT
08b152afcfae   4 months ago   /bin/sh -c #(nop)  CMD ["nginx" "-g" "daemon…   0B
<missing>      4 months ago   /bin/sh -c #(nop)  ENV NGINX_VERSION=1.21.1     0B
<missing>      4 months ago   /bin/sh -c #(nop) ADD file:45f5dfa135c848a34…   69.3MB

import 从归档文件中创建镜像

docker import [选项] <文件>||- [<仓库名>[:<标签>]]

docker import \
    http://download.openvz.org/template/precreated/ubuntu-16.04-x86_64.tar.gz \
    openvz/ubuntu:16.04

inspect 显示镜像的详细信息

docker image inspect [OPTIONS] IMAGE [IMAGE…]

[
    {
        "Id": "sha256:08b152afcfae220e9709f00767054b824361c742ea03a9fe936271ba520a0a4b",
        "RepoTags": [
            "nginx:latest"
        ],
        "RepoDigests": [
            "nginx@sha256:8f335768880da6baf72b70c701002b45f4932acae8d574dedfddaf967fc3ac90"
        ],
        "Parent": "",
        "Comment": "",
        "Created": "2021-07-22T10:13:19.618829582Z",
        "Container": "2997e2321de26e96aff43069d29f2d683a6c98fe395084cd3ca90721bc3e748a",
        "ContainerConfig": {
            "Hostname": "2997e2321de2",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "80/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "NGINX_VERSION=1.21.1",
                "NJS_VERSION=0.6.1",
                "PKG_RELEASE=1~buster"
            ],
            "Cmd": [
                "/bin/sh",
                "-c",
                "#(nop) ",
                "CMD [\"nginx\" \"-g\" \"daemon off;\"]"
            ],
            "Image": "sha256:6b7d95b7a3922d21287da04a02bac3bb129b38e7c96dc39b1be5da89d12de9ba",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": [
                "/docker-entrypoint.sh"
            ],
            "OnBuild": null,
            "Labels": {
                "maintainer": "NGINX Docker Maintainers <docker-maint@nginx.com>"
            },
            "StopSignal": "SIGQUIT"
        },
        "DockerVersion": "20.10.7",
        "Author": "",
        "Config": {
            "Hostname": "",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "80/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "NGINX_VERSION=1.21.1",
                "NJS_VERSION=0.6.1",
                "PKG_RELEASE=1~buster"
            ],
            "Cmd": [
                "nginx",
                "-g",
                "daemon off;"
            ],
            "Image": "sha256:6b7d95b7a3922d21287da04a02bac3bb129b38e7c96dc39b1be5da89d12de9ba",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": [
                "/docker-entrypoint.sh"
            ],
            "OnBuild": null,
            "Labels": {
                "maintainer": "NGINX Docker Maintainers <docker-maint@nginx.com>"
            },
            "StopSignal": "SIGQUIT"
        },
        "Architecture": "amd64",
        "Os": "linux",
        "Size": 133175501,
        "VirtualSize": 133175501,
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/a436496548610e9dfc4cde7c2215facffefa0ebc431bad2bb4182e4b3eb9019b/diff:/var/lib/docker/overlay2/644e8dc114adfd8ef6d6ced56c9a297636a3fd5032f3e38533f6ea416307992a/diff:/var/lib/docker/overlay2/a247c62ce0fc8a84d644528b7b2f5711e5f6b0b5aff17d5b22f002430d05beab/diff:/var/lib/docker/overlay2/27de522ac424a87a77fc7de283ce682e8b3424ace0303460372cb1b0c2318cc1/diff:/var/lib/docker/overlay2/7d22f77185c5dcc8e9263f931e5ff646c5714119ea0c536e3a886a3e03b75797/diff",
                "MergedDir": "/var/lib/docker/overlay2/8c8b3408e44272ed2497aa79b53302188656b253ee8f56946a9b528bd12678d6/merged",
                "UpperDir": "/var/lib/docker/overlay2/8c8b3408e44272ed2497aa79b53302188656b253ee8f56946a9b528bd12678d6/diff",
                "WorkDir": "/var/lib/docker/overlay2/8c8b3408e44272ed2497aa79b53302188656b253ee8f56946a9b528bd12678d6/work"
            },
            "Name": "overlay2"
        },
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:814bff7343242acfd20a2c841e041dd57c50f0cf844d4abd2329f78b992197f4",
                "sha256:7c0b223167b96d7deaacf1e1d2d35892166645b09b17bcc8675a4d882ef84893",
                "sha256:59b01b87c9e7f668b740d23eb872c5964636c33aef795f1186f08b172197bc35",
                "sha256:988d9a3509bbb7ea8037d4eba3a5e0ada5dc165144c8ff0df89c0048d1ac6132",
                "sha256:b857347059916922b353147882544f17bb96e64c639081c0677bf386c446be4f",
                "sha256:e3135447ca3e69c6975aee1621c406e3865e0e143c807bbdcf05abefa56054a2"
            ]
        },
        "Metadata": {
            "LastTagTime": "0001-01-01T00:00:00Z"
        }
    }
]

镜像的导入和导出 docker save 和 docker load

保存镜像 docker save [镜像名] -o [文件名]

导入镜像 docker load -i [文件名]

# 保存
$ docker save alpine -o filename
$ docker save alpine | gzip > alpine-latest.tar.gz
# 导入
$ docker load -i alpine-latest.tar.gz
Loaded image: alpine:latest

pull 获取镜像

格式: docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]

命令详解: docker pull --help
示例: docker pull centos

ls 列出镜像

docker image ls

REPOSITORYTAGIMAGE IDCREATEDSIZE
仓库名标签镜像ID创建时间所占用的空间
nginxlatest08b152afcfae3 months ago133MB
php8d88df285a5d96 months ago423MB

镜像体积

$ docker system df
TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          2         2         555.8MB   0B (0%)
Containers      2         0         248.4MB   248.4MB (100%)
Local Volumes   0         0         0B        0B
Build Cache     0         0         0B        0B

虚悬镜像

备注:由于新旧镜像同名,旧镜像名称被取消,从而出现仓库名为none的虚悬镜像

$  docker image ls -f dangling=true
REPOSITORY   TAG       IMAGE ID   CREATED   SIZE

中间层镜像

简介:为了加速镜像构建、重复利用资源

$ docker image ls -a
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
nginx        latest    08b152afcfae   3 months ago   133MB
php          8         d88df285a5d9   6 months ago   423MB

列出部分镜像(查找过滤)

# 根据仓库名列出镜像: 
$ docker image ls ubuntu
# 指定仓库名和标签:
$ docker image ls ubuntu:18.04
# 滤器参数 --filter,或者简写 -f
$ docker image ls -f since=mongo:3.2

以特定格式显示

$ docker image ls -q
08b152afcfae
d88df285a5d9

rm 删除本地镜像 prune 删除未使用的镜像

$ docker image rm [选项] <镜像1> [<镜像2> …]

docker image prune 命令删除

$ docker image rm centos
Untagged: centos:latest
Untagged: centos@sha256:b2f9d1c0ff5f87a4743104d099a3d561002ac500db1b9bfa02a783a46e0d366c
Deleted: sha256:0584b3d2cf6d235ee310cf14b54667d889887b838d3f3d3033acd70fc3c48b8a
Deleted: sha256:97ca462ad9eeae25941546209454496e1d66749d53dfa2ee32bf1faabd239d38

# 用 docker image ls 命令来配合
$ docker image rm $(docker image ls -q redis)
$ docker image rm $(docker image ls -q -f before=mongo:3.2)

commit 通过容器创建镜像(不建议使用)

docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]

docker commit \
    --author "Tao Wang <twang2218@gmail.com>" \
    --message "修改了默认网页" \
    webserver \
    nginx:v2
sha256:07e33465974800ce65751acc279adc6ed2dc5ed4e0838f8b86f0c87aa1795214

不建议使用

  • docker diff webserver 仅修改一个文件但是还有很多文件被改动或添加了
  • 所有对镜像的操作都是黑箱操作,生成的镜像也被称为 黑箱镜像,就是除了制作镜像的人知道执行过什么命令、怎么生成的镜像,别人根本无从得知,不利于维护。

push 将镜像推到仓库中

docker image push [OPTIONS] NAME[:TAG]

tag 标记本地镜像,将其归入某一仓库

docker image tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]

容器简介与操作

容器是独立运行的一个或一组应用,以及它们的运行态环境。对应的,虚拟机可以理解为模拟运行的一整套操作系统(提供了运行态环境和其他系统环境)和跑在上面的应用。

docker container 文档

$ docker container --help

Usage:  docker container COMMAND

Manage containers

Commands:
  attach      Attach local standard input, output, and error streams to a running container
  commit      Create a new image from a container's changes
  cp          Copy files/folders between a container and the local filesystem
  create      Create a new container
  diff        Inspect changes to files or directories on a container's filesystem
  exec        Run a command in a running container
  export      Export a container's filesystem as a tar archive
  inspect     Display detailed information on one or more containers
  kill        Kill one or more running containers
  logs        Fetch the logs of a container
  ls          List containers
  pause       Pause all processes within one or more containers
  port        List port mappings or a specific mapping for the container
  prune       Remove all stopped containers
  rename      Rename a container
  restart     Restart one or more containers
  rm          Remove one or more containers
  run         Run a command in a new container
  start       Start one or more stopped containers
  stats       Display a live stream of container(s) resource usage statistics
  stop        Stop one or more running containers
  top         Display the running processes of a container
  unpause     Unpause all processes within one or more containers
  update      Update configuration of one or more containers
  wait        Block until one or more containers stop, then print their exit codes

Run 'docker container COMMAND --help' for more information on a command.

启动容器

docker run [OPTIONS] IMAGE [COMMAND] [ARG…]

  • -a stdin: 指定标准输入输出内容类型,可选 STDIN/STDOUT/STDERR 三项;
  • -d: 后台运行容器,并返回容器ID;
  • -i: 以交互模式运行容器,通常与 -t 同时使用;
  • -P: 随机端口映射,容器内部端口随机映射到主机的端口
  • -p: 指定端口映射,格式为:主机(宿主)端口:容器端口
  • -t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用;
  • –name=“容器名”: 为容器指定一个名称;
  • –dns 8.8.8.8: 指定容器使用的DNS服务器,默认和宿主一致;
  • –dns-search example.com: 指定容器DNS搜索域名,默认和宿主一致;
  • -h 设置容器hostname
  • -e username=“ritchie”: 设置环境变量;
  • –env-file=[]: 从指定文件读入环境变量;
  • –cpuset=“0-2” or --cpuset=“0,1,2”: 绑定容器到指定CPU运行;
  • -m :设置容器使用内存最大值;
  • –net=“bridge”: 指定容器的网络连接类型,支持 bridge/host/none/container: 四种类型;
  • –link=[]: 添加链接到另一个容器;
  • –expose=[]: 开放一个端口或一组端口;
  • –rm 容器停止时,自动删除容器
  • -v 设置数据卷

创建容器时,Docker 在后台运行的标准操作包括

  • 检查本地是否存在指定的镜像,不存在就从 registry 下载
  • 利用镜像创建并启动一个容器
  • 分配一个文件系统,并在只读的镜像层外面挂载一层可读写层
  • 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去
  • 从地址池配置一个 ip 地址给容器
  • 执行用户指定的应用程序
  • 执行完毕后容器被终止
# 启动centos镜像
docker run -it --rm --name centos01 --network my-net centos bash
# 当前宿主机展示
docker run ubuntu:18.04 bash -c "echo 'hello docker'"
hello world
# 后台运行
$  docker run -d ubuntu:18.04 bash -c "echo 'hello docker'"
01f0167632b96fc24dd161dbb6279bc66b19397dd6903a358a2b231633dcceff
# docker logs 查看输出
$ docker logs 01f0167632b96fc24dd161dbb6279bc66b19397dd6903a358a2b231633dcceff
hello docker

容器启动终止与重启 start,stop,restart

docker start [OPTIONS] CONTAINER [CONTAINER…]

docker stop [OPTIONS] CONTAINER [CONTAINER…]

docker restart [OPTIONS] CONTAINER [CONTAINER…]

docker ps -a # 查看本地所有运行的容器
docker ps        # 产看正在运行的容器
docker start 容器id # 运行容器
docker rm 容器id    # 移出容器

# 查看已停止的容器
$ docker ps -a
CONTAINER ID   IMAGE          COMMAND                  CREATED              STATUS                          PORTS                NAMES
c737e7f64e1e   php:8          "docker-php-entrypoi…"   About a minute ago   Exited (0) About a minute ago                        vigilant_mestorf
618c48f1da0f   php:8          "docker-php-entrypoi…"   3 months ago         Exited (255) 6 weeks ago                             php8
2a3ed72f7494   nginx:latest   "/docker-entrypoint.…"   3 months ago         Exited (255) 6 weeks ago        0.0.0.0:80->80/tcp   nginx

$ docker start 618c48f1da0f
618c48f1da0f
# 容器id 停止容器运行
$ docker stop f1c29da395fe
f1c29da395fe
# 容器name 停止容器运行
$ docker stop romantic_ardinghelli
romantic_ardinghelli
# 重启
$ docker restart php8
php8

进入容器

attach 在容器运行结束后会被停止,而exec不会,推荐使用exec

attach

$ docker run -dit ubuntu
Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu
7b1a6ab2e44d: Pulling fs layer
7b1a6ab2e44d: Verifying Checksum
7b1a6ab2e44d: Download complete
7b1a6ab2e44d: Pull complete
Digest: sha256:626ffe58f6e7566e00254b638eb7e0f3b11d4da9675088f4781a50ae288f3322
Status: Downloaded newer image for ubuntu:latest
e896fc8f7f11f6bd2a493531b6ab6ed40420f8284c17bde74dc36f0cb78760dd
$ docker container ls
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS     NAMES
e896fc8f7f11   ubuntu    "bash"                   28 seconds ago   Up 26 seconds             musing_lumiere
618c48f1da0f   php:8     "docker-php-entrypoi…"   3 months ago     Up 19 minutes             php8
$ docker attach musing_lumiere
root@e896fc8f7f11:/# exit 
# 命令行如果退出则容器也会停止

exec 推荐使用

docker exec -i 容器id|names bash

  • -i 分配一个伪终端
  • 进入容器后不会随终端的退出而导致容器的停止
$ docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED        STATUS          PORTS     NAMES
618c48f1da0f   php:8     "docker-php-entrypoi…"   3 months ago   Up 23 minutes             php8
$ docker exec -i 618c48f1da0f bash
$ exit  # 终端 exet
$ docker ps  # 查看正在运行的容器,发现php:8依然在运行
CONTAINER ID   IMAGE     COMMAND                  CREATED        STATUS          PORTS     NAMES
618c48f1da0f   php:8     "docker-php-entrypoi…"   3 months ago   Up 25 minutes             php8

导出和导入容器

export 导出容器(导出容器快照到本地文件)

docker export

$ docker container ls -a
CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS                        PORTS                NAMES
e896fc8f7f11   ubuntu         "bash"                   14 minutes ago   Exited (0) 11 minutes ago                          musing_lumiere
# 导出容器到本地
$ docker export e896fc8f7f11 > ubuntu.tar

import 导入容器快照(容器快照文件中再导入为镜像)

docker import 文件导入和远程网址导入

# 文件导入
$ cat ubuntu.tar | docker import - test/ubuntu:v1.0
sha256:a4bf755ec36a1ce5794ec3d2ff43dbbe2e9b37c8ddf0a6e583002702e0ceddd2
# 查看导入的景象
$ docker image ls
REPOSITORY    TAG       IMAGE ID       CREATED          SIZE
test/ubuntu   v1.0      a4bf755ec36a   25 seconds ago   72.8MB
# 远程网址导入
$ docker import http://example.com/exampleimage.tgz example/imagerepo

rm 删除容器 prune 清理所有处于终止状态的容器

docker rm [OPTIONS] CONTAINER [CONTAINER…]

docker container prune

$ docker rm e896fc8f7f11
e896fc8f7f11
$ docker container prune
WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N] y
Deleted Containers:
7a7d3e5d4eb2bdcfadae02dacb8a75960398352eb59133dd43823e80cf483c74
01f0167632b96fc24dd161dbb6279bc66b19397dd6903a358a2b231633dcceff
f1c29da395fe59875dac98055140101a24147e28bb04cd0a0a88c6b3dbd90323
9527df056d90ecf50e13ee671330c0341eb9f60543b8ace762b850970c652d05
8df0d2994b05def934a29eb43a4f095a13928fc0f3ee8b34da807e7e1da4160d
c737e7f64e1e80053b8b8cec73fa6ef39dfa4f868cff83fa223e78f2c5536021
2a3ed72f7494f69148a377f668216a0a8080c18786441978844c9ccb67125066

Total reclaimed space: 154.5MB

Dockerfile 指令详解

构建命令: docker build -t [NAME]:[TAG] -f Dockerfile .

COPY 复制文件

  • COPY [–chown=:] <源路径>… <目标路径>
  • COPY [–chown=:] ["<源路径1>",… “<目标路径>”]

ADD 更高级的复制文件

  • ADD 源路径 目标路径 (拥有解压缩的功能,建议使用wget curl工具下载后解压)

CMD 容器启动命令

  • shell 格式:CMD <命令>
  • exec 格式:CMD [“可执行文件”, “参数1”, “参数2”…]
  • 参数列表格式:CMD [“参数1”, “参数2”…]。在指定了 ENTRYPOINT 指令后,用 CMD 指定具体的参数。
CMD ["nginx", "-g", "daemon off;"]

ENTRYPOINT 入口点

  • 场景一:让镜像变成像命令一样使用
docker run myip curl -s http://myip.ipip.net -i
# 改变成下面的ENTRYPOINT
FROM ubuntu:18.04
RUN apt-get update \
&& apt-get install -y curl \
&& rm -rf /var/lib/apt/lists/*
ENTRYPOINT [ "curl", "-s", "http://myip.ipip.net"]
  • 场景二:应用运行前的准备工作
FROM alpine:3.4
...
RUN addgroup -S redis && adduser -S -G redis redis
...
ENTRYPOINT ["docker-entrypoint.sh"]
EXPOSE 6379
CMD [ "redis-server" ]

ENV 设置环境变量

  • ENV
  • ENV <key1>=<value1> <key2>=<value2>…
ENV NODE_VERSION 7.2.0

RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz" \
  && curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc" \
  && gpg --batch --decrypt --output SHASUMS256.txt SHASUMS256.txt.asc \
  && grep " node-v$NODE_VERSION-linux-x64.tar.xz\$" SHASUMS256.txt | sha256sum -c - \
  && tar -xJf "node-v$NODE_VERSION-linux-x64.tar.xz" -C /usr/local --strip-components=1 \
  && rm "node-v$NODE_VERSION-linux-x64.tar.xz" SHASUMS256.txt.asc SHASUMS256.txt \
  && ln -s /usr/local/bin/node /usr/local/bin/nodejs

ARG 构建参数

  • ARG <参数名>[=<默认值>]

构建参数和 ENV 的效果一样,都是设置环境变量。所不同的是,ARG 所设置的构建环境的环境变量,在将来容器运行时是不会存在这些环境变量的。

VOLUME 定义匿名卷

  • VOLUME ["<路径1>", “<路径2>”…]
  • VOLUME <路径>

为了防止运行时用户忘记将动态文件所保存目录挂载为卷,在 Dockerfile 中,我们可以事先指定某些目录挂载为匿名卷,这样在运行时如果用户不指定挂载,其应用也可以正常运行,不会向容器存储层写入大量数据。

VOLUME /data

EXPOSE 声明端口

  • EXPOSE <端口1> [<端口2>…]

声明容器运行时提供服务的端口,这只是一个声明,在容器运行时并不会因为这个声明应用就会开启这个端口的服务

指定端口: -p <宿主端口>:<容器端口>

WORKDIR 指定工作目录

  • WORKDIR <工作目录路径>

使用 WORKDIR 指令可以来指定工作目录(或者称为当前目录),以后各层的当前目录就被改为指定的目录,如该目录不存在,WORKDIR 会帮你建立目录。

USER 指定当前用户

  • USER <用户名>[:<用户组>]

USER 指令和 WORKDIR 相似,都是改变环境状态并影响以后的层。WORKDIR 是改变工作目录,USER 则是改变之后层的执行 RUN, CMD 以及 ENTRYPOINT 这类命令的身份。

HEALTHCHECK 健康检查

  • HEALTHCHECK [选项] CMD <命令>:设置检查容器健康状况的命令
  • HEALTHCHECK NONE:如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令

LABEL 指令

  • LABEL <key>=<value> <key>=<value> <key>=<value> …

SHELL 指令

  • SHELL [“executable”, “parameters”]

ONBUILD 以当前镜像为基础镜像去构建其它镜像

  • ONBUILD <其它指令>

在当前镜像构建时并不会被执行。只有当以当前镜像为基础镜像,去构建下一级镜像的时候才会被执行。

FROM node:slim
RUN mkdir /app
WORKDIR /app
ONBUILD COPY ./package.json /app
ONBUILD RUN [ "npm", "install" ]
ONBUILD COPY . /app/
CMD [ "npm", "start" ]

这次我们回到原始的 Dockerfile,但是这次将项目相关的指令加上 ONBUILD,这样在构建基础镜像的时候,这三行并不会被执行。然后各个项目的 Dockerfile 就变成了简单地

FROM my-node

参考文档

Dockerfie 官方文档:https://docs.docker.com/engine/reference/builder/
Dockerfile 最佳实践文档:https://docs.docker.com/develop/develop-images/dockerfile_best-practices/
Docker 官方镜像 Dockerfile:https://github.com/docker-library/docs

多阶段构建

全部放入一个 Dockerfile,

  • 镜像层次多,镜像体积较大,部署时间变长
  • 源代码存在泄露的风险
FROM golang:alpine as builder
RUN apk --no-cache add git
WORKDIR /go/src/github.com/go/helloworld/
RUN go get -d -v github.com/go-sql-driver/mysql
COPY app.go .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
FROM alpine:latest as prod
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=0 /go/src/github.com/go/helloworld/app .
CMD ["./app"]
# 构建镜像
 docker build -t go/helloworld:3 .
 # 对比三个镜像大小
 $ docker image ls
REPOSITORY        TAG   IMAGE ID         CREATED            SIZE
go/helloworld     3     d6911ed9c846     7 seconds ago      6.47MB
go/helloworld     2     f7cf3465432c     22 seconds ago     6.47MB
go/helloworld     1     f55d3e16affc     2 minutes ago      295MB

示例

FROM centos:7
MAINTAINER Fisher "1837737522@qq.com"

# docker build -t centos:php73 -f php73_Dockerfile .

# 编译安装php73版本

# 声明 docker 地址变量
ARG DOCKER=/docker
# php 构建版本
ARG PHP_VERSION=php73

# 解压
COPY config ${DOCKER}/config
COPY php ${DOCKER}/php
COPY nginx ${DOCKER}/nginx

RUN set -e \
cd ${DOCKER} \
# 系统初始化
&& cd ${DOCKER}/config/ \
&& chmod +x system_init.sh && ./system_init.sh \
# php 安装
&& cd ${DOCKER}/php/${PHP_VERSION} && chmod +x install.sh && ./install.sh \
# nginx 安装
&& cd ${DOCKER}/nginx/ && chmod +x install.sh && ./install.sh \
&& chmod +x ${DOCKER}/config/system_php_start.sh
# 删除无用数据
# && cd / && rm -rf ${DOCKER}

# 声明端口
EXPOSE 80 443

# 启动 systemctl ,在cmd 或者 run 后面加入 /usr/sbin/init ,不能再加其他的shell命令
# 启用 systemctl 程序无需设置前台运行,依然保证容器不退出。(容器运行 1:程序设置前台运行  2 启用 systemctl,程序无需前台运行)
CMD ["/usr/sbin/init"]

# linux 运行
# 线上
# docker run --name php -d --privileged=true -p 80:80 -p 443:443 registry.cn-beijing.aliyuncs.com/modongxiao/docker:php73
# 本地
# docker run --name php -d --privileged=true -p 81:80 -p 443:443 -v /mvc:/mvc -v /alidata:/alidata -v /web:/web registry.cn-beijing.aliyuncs.com/modongxiao/docker:php73
# 本地原始
# docker run --name php -d --privileged=true -p 81:80 -p 443:443 -v /mvc:/mvc -v /alidata:/alidata -v /web:/web centos:php73

# windows 启动路径方式
# winpty docker run  --name php -d --privileged=true -ti  -p 80:80 -p 443:443  -v D:\\mvc:/mvc -v D:\\alidata:/alidata -v D:\\web:/web   registry.cn-beijing.aliyuncs.com/modongxiao/docker:php73 init

数据管理

数据卷(Volumes)

数据卷 是一个可供一个或多个容器使用的特殊目录

  • 数据卷 可以在容器之间共享和重用
  • 对 数据卷 的修改会立马生效
  • 对 数据卷 的更新,不会影响镜像
  • 数据卷 默认会一直存在,即使容器被删除

创建一个数据卷

docker volume create [NAME]

$ docker volume create my-vol
# 查看所有的 数据卷
$ docker volume ls
DRIVER    VOLUME NAME
local     my-vol

启动一个挂载数据卷的容器

在用 docker run 命令的时候,使用 --mount 标记来将 数据卷 挂载到容器里。在一次 docker run 中可以挂载多个 数据卷。

$ docker run -d -P \
    --name web \
    # -v my-vol:/usr/share/nginx/html \
    --mount source=my-vol,target=/usr/share/nginx/html \
    nginx:alpine

inspect 查看数据卷的具体信息

docker inspect [卷名]

$ docker inspect  my-vol
[
    {
        "CreatedAt": "2021-11-07T07:46:12Z",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/my-vol/_data",
        "Name": "my-vol",
        "Options": {},
        "Scope": "local"
    }
]

rm 删除数据卷 prune 无主的数据卷清理

docker volume rm [卷名]

docker volume prune

挂载主机目录 (Bind mounts)

挂载一个主机目录作为数据卷

–mount 标记可以指定挂载一个本地主机的目录到容器中去。

 docker run -d -P \
    --name web \
    # -v /src/webapp:/usr/share/nginx/html \
    --mount type=bind,source=/src/webapp,target=/usr/share/nginx/html \
    nginx:alpine

readonly 只读

$ docker run -d -P \
    --name web \
    # -v /src/webapp:/usr/share/nginx/html:ro \
    --mount type=bind,source=/src/webapp,target=/usr/share/nginx/html,readonly \
    nginx:alpine

挂载一个本地主机文件作为数据卷

$ docker run --rm -it \
   # -v $HOME/.bash_history:/root/.bash_history \
   --mount type=bind,source=$HOME/.bash_history,target=/root/.bash_history \
   ubuntu:18.04 \
   bash

root@2affd44b4667:/# history
1  ls
2  diskutil list

network网络

docker network COMMAND
文档

$ docker network --help

Usage:  docker network COMMAND

Manage networks

Commands:
  connect     Connect a container to a network
  create      Create a network
  disconnect  Disconnect a container from a network
  inspect     Display detailed information on one or more networks
  ls          List networks
  prune       Remove all unused networks
  rm          Remove one or more networks

Run 'docker network COMMAND --help' for more information on a command.

ls 列出所有网络

docker network ls

$ docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
8e6e06d6e8fe   bridge    bridge    local
c426cb16f1ba   host      host      local
642abd8a74a7   none      null      local

create 创建网络

docker network create [OPTIONS] NETWORK

$ docker network create my-net
e8dfaa20a66f77a3ac2a7f0d0ee69861cafcb37cd24f394a641eed7f24891c09
$ docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
8e6e06d6e8fe   bridge    bridge    local
c426cb16f1ba   host      host      local
e8dfaa20a66f   my-net    bridge    local
642abd8a74a7   none      null      local

connect 某个容器连接到一个docker网络

docker network connect [OPTIONS] NETWORK CONTAINER

docker network connect my-net php8

disconnect 将某个容器退出某个局域网络

docker network disconnect [OPTIONS] NETWORK CONTAINER

$ docker network disconnect my-net php8

inspect 显示某个局域网络信息

docker network inspect [OPTIONS] NETWORK [NETWORK…]

$ docker network inspect my-net
[
    {
        "Name": "my-net",
        "Id": "e8dfaa20a66f77a3ac2a7f0d0ee69861cafcb37cd24f394a641eed7f24891c09",
        "Created": "2021-11-20T09:37:38.5456146Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.18.0.0/16",
                    "Gateway": "172.18.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]

rm 删除网络 prune 删除未使用的网络

docker network rm NETWORK [NETWORK…]

docker network prune

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐