03-Docker核心概念-容器-镜像-镜像仓库操作

331 阅读16分钟

一、使用容器运行Nginx应用

1.1 使用docker run命令运行Nginx应用

  • 观察下载容器镜像过程

    • 查找本地容器镜像文件

      image-20230726202116550.png

    • 下载容器镜像

      image-20230726202131892.png

  • 观察容器运行情况

    ff8e80eea76fc243a23cbbc7a0fe3596d9e2c4ad3dc392d91c6eac82ff0b5b15

    # 命令解释:docker run -d nginx:latest
     - docker run 启动一个容器
     - -d把容器镜像中需要执行的命令以daemon(守护进程)的方式运行
     - nginx 应用容器镜像的名称,通常表示该镜像为某一个软件
     - latest表示上述容器镜像的版本,表示最新版本,用户可自定义其表示
    
  • 使用docker ps命令查看正在运行的容器

    image-20230726202551169.png

    # 命令解释:docker ps
    - 类似于Linux系统的ps命令,查看正在运行的容器,如果想查看没有运行的容器,需要在此命令后使用--all
    
  • 输出内容解释

    CONTAINERIDIMAGECOMMANDCREATEDSTATUSPORTSNAMES
    ff8e80eea76fnginx:latest"/docker-entrypoint.…"5 minutes agoUp 5 minutes80/tcploving_wozniak
    容器ID容器镜像容器中运行的命令容器创建时间容器状态容器提供访问应用端口容器名称

二、Docker命令

2.1 Docker命令获取帮助方法

# docker -h
Flag shorthand -h has been deprecated, please use --help
​
Usage:  docker [OPTIONS] COMMAND  用法
​
A self-sufficient runtime for containers 功能介绍
​
Options: 选项
      --config string      Location of client config files (default "/root/.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 "/root/.docker/ca.pem")
      --tlscert string     Path to TLS certificate file (default "/root/.docker/cert.pem")
      --tlskey string      Path to TLS key file (default "/root/.docker/key.pem")
      --tlsverify          Use TLS and verify the remote
  -v, --version            Print version information and quit
​
Management Commands: 管理类命令
  app*        Docker App (Docker Inc., v0.9.1-beta3)
  builder     Manage builds
  buildx*     Docker Buildx (Docker Inc., v0.7.1-docker)
  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.12.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

2.2 Docker官网提供的命令说明

网址链接:docs.docker.com/reference/

image-20230726203907949.png

2.3 Docker命令应用

  • docker run

    # docker run -i -t --name c1 centos:latest bash
        docker run:运行一个命令在容器中,命令是主体,没有命令容器就会消亡
        -i: 交互式
        -t: 提供终端
        --name c1: 把将运行的容器命名为c1
        centos:latest: 使用centos最新版本容器镜像
        bash: 在容器中执行的命令
    
  • docker ps

    # docker ps
        查看正在运行的容器
    # docker ps --all
        查看正在运行的和停止运行的容器
    
  • docker inspect

    # docker inspect
        查看容器详细信息
    "Networks": {
                    "bridge": {
                        "IPAMConfig": null,
                        "Links": null,
                        "Aliases": null,
                        "NetworkID": "d3de2fdbc30ee36a55c1431ef3ae4578392e552009f00b2019b4720735fe5a60",
                        "EndpointID": "d1a2b7609f2f73a6cac67229a4395eef293f695c0ac4fd6c9c9e6913c9c85c1c",
                        "Gateway": "172.17.0.1",
                        "IPAddress": "172.17.0.2",
                        "IPPrefixLen": 16,
                        "IPv6Gateway": "",
                        "GlobalIPv6Address": "",
                        "GlobalIPv6PrefixLen": 0,
                        "MacAddress": "02:42:ac:11:00:02",
                        "DriverOpts": null
                    }
                }
            }
        }
    ]
    
  • docker exec

    # docker exec -it 容器名称 ls /root
        docker exec:在容器外实现与容器交互执行某命令
        -it:交互式
        c2:正在运行的容器
        ls /root:在正在运行的容器中运行相关的命令
    anaconda-ks.cfg  anaconda-post.log  original-ks.cfg
    
  • docker attach

    # docker attach 容器名称
    [root@9f2eea16da4c /]#
        docker attach 类似于ssh命令,可以进入到容器中
    
  • docker stop

    # docker stop 容器id
        关闭正在运行的容器
    
  • docker start

    # docker start 容器id
        启动容器
    
  • docker top

    # docker top 容器名称
        查看container内进程信息,指在docker host上查看。
    
  • docker rm

    如果容器已停止,使用此命令可以直接删除;如果容器处于运行状态,则需要提前关闭容器后,再删除容器。

    • 删除指定容器

      # docker rm 容器名称/容器id
      
    • 批量删除容器

      # docker ps --all | awk '{if (NR>=2){print $1}}' | xargs docker rm
      

三、Docker容器镜像操作

3.1 查看本地容器镜像

  • 使用docker images命令查看

    # docker images
    REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
    nginx        latest    021283c8eb95   3 weeks ago     187MB
    centos       latest    5d0da3dc9764   22 months ago   231MB
    
  • 使用docker image命令查看

    # docker image list
    REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
    nginx        latest    021283c8eb95   3 weeks ago     187MB
    centos       latest    5d0da3dc9764   22 months ago   231MB
    
  • 查看docker 容器镜像本地存储位置

    考虑到docker容器会占用本地存储空间,建议搭建其它存储系统挂载到本地以便解决占用大量本地存储的问题

    # ls /var/lib/docker
    buildkit  containers  engine-id  image  network  overlay2  plugins  runtimes  swarm  tmp  volumes
    

3.2 搜索Docker Hub容器镜像

  • 命令行搜索

    # docker search centos
    NAME                                         DESCRIPTION                                      STARS     OFFICIAL   AUTOMATED
    centos                                       DEPRECATED; The official build of CentOS.        7618      [OK]       
    kasmweb/centos-7-desktop                     CentOS 7 desktop for Kasm Workspaces             39                   
    bitnami/centos-base-buildpack                Centos base compilation image                    0                    [OK]
    couchbase/centos7-systemd                    centos7-systemd images with additional debug…   8                    [OK]
    continuumio/centos5_gcc5_base                                                                 3                    
    
  • Docker Hub Web界面搜索

    hub.docker.com/

  • docker 容器镜像下载

    # docker pull centos
    
  • docker容器镜像删除方法

    # docker rmi 镜像名称/镜像id
    

四、Docker容器镜像介绍

4.1 Docker Image

镜像是一种轻量级的,可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时所需的库、环境变量和配置文件。

  • Docker镜像是只读的容器模板,是Docker容器基础
  • 为Docker容器提供了静态文件系统运行环境
  • 是容器的静止状态,容器是镜像的运行状态

4.2 联合文件系统

联合文件系统是实现联合挂载技术的文件系统,可以实现在一个挂载点同时挂载多个文件系统,将挂载点的原目录与被挂载内容进行整合,使得最终可见的文件系统包含整合之后的各层文件和目录

image-20230726214731288

4.3 Docker Overlay2

容器文件系统有多种存储驱动实现方式:aufs,devicemapper,overlay,overlay2 等,本次以overlay2为例进行说明。

4.3.1 概念
  • registry/repository: registry 是 repository 的集合,repository 是镜像的集合。
  • image:image 是存储镜像相关的元数据,包括镜像的架构,镜像默认配置信息,镜像的容器配置信息等等。它是“逻辑”上的概念,并无物理上的镜像文件与之对应。
  • layer:layer(镜像层) 组成了镜像,单个 layer 可以被多个镜像共享。

image-20230726214731288.png

4.3.2 查看Docker Host存储驱动方式
# docker info | grep overlay
 Storage Driver: overlay2
4.3.3 了解images分层
# docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
a2abf6c4d29d: Pull complete
a9edb18cadd1: Pull complete
589b7251471a: Pull complete
186b1aaa4aa6: Pull complete
b4df32aa5a72: Pull complete
a0bcbecc962e: Pull complete
Digest: sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest

可以看到上述下载的镜像分为6层,如何找到这6层存储在Docker Host哪个位置呢?

首先查看nginx镜像

# docker images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
nginx        latest    605c77e624dd   3 weeks ago    141MB

通过其Image ID 605c77e624dd 就可以找到存储位置

# ls /var/lib/docker/image/overlay2/
distribution  imagedb  layerdb  repositories.json

这个目录是查找的入口,非常重要。它存储了镜像管理的元数据。

  • repositories.json 记录了 repo 与镜像 ID 的映射关系
  • imagedb 记录了镜像架构,操作系统,构建镜像的容器 ID 和配置以及 rootfs 等信息
  • layerdb 记录了每层镜像层的元数据。

通过短 ID 查找 repositories.json 文件,找到镜像 nginx 的长 ID,通过长 ID 在 imagedb 中找到该镜像的元数据:

# cat /var/lib/docker/image/overlay2/repositories.json | grep 605c77e624dd
{"Repositories":"nginx":{"nginx:latest":"sha256:605c77e624ddb75e6110f997c58876baa13f8754486b461117934b24a9dc3a85","nginx@sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31":"sha256:605c77e624ddb75e6110f997c58876baa13f8754486b461117934b24a9dc3a85"}}}}
# cat /var/lib/docker/image/overlay2/imagedb/content/sha256/605c77e624ddb75e6110f997c58876baa13f8754486b461117934b24a9dc3a85
......
"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:2edcec3590a4ec7f40cf0743c15d78fb39d8326bc029073b41ef9727da6c851f","sha256:e379e8aedd4d72bb4c529a4ca07a4e4d230b5a1d3f7a61bc80179e8f02421ad8","sha256:b8d6e692a25e11b0d32c5c3dd544b71b1085ddc1fddad08e68cbd7fda7f70221","sha256:f1db227348d0a5e0b99b15a096d930d1a69db7474a1847acbc31f05e4ef8df8c","sha256:32ce5f6a5106cc637d09a98289782edf47c32cb082dc475dd47cbf19a4f866da","sha256:d874fd2bc83bb3322b566df739681fbd2248c58d3369cb25908d68e7ed6040a6"]}}

这里仅保留我们想要的元数据 rootfs。在 rootfs 中看到 layers 有6层,这6层即对应镜像的6层镜像层。并且,自上而下分别映射到容器的底层到顶层。找到了镜像的6层,接下来的问题是每层的文件内容在哪里呢?

layerdb 元数据会给我们想要的信息,通过底层 diff-id: 2edcec3590a4ec7f40cf0743c15d78fb39d8326bc029073b41ef9727da6c851f 我们查到最底层镜像层的 cache_id,通过 cache_id 即可查找到镜像层的文件内容:

# ls /var/lib/docker/image/overlay2/layerdb/sha256/2edcec3590a4ec7f40cf0743c15d78fb39d8326bc029073b41ef9727da6c851f
cache-id  diff  size  tar-split.json.gz
# cat /var/lib/docker/image/overlay2/layerdb/sha256/2edcec3590a4ec7f40cf0743c15d78fb39d8326bc029073b41ef9727da6c851f/cache-id
85c4c5ecdac6c0d197f899dac227b9d493911a9a5820eac501bb5e9ae361f4c7
# cat /var/lib/docker/image/overlay2/layerdb/sha256/2edcec3590a4ec7f40cf0743c15d78fb39d8326bc029073b41ef9727da6c851f/diff
sha256:2edcec3590a4ec7f40cf0743c15d78fb39d8326bc029073b41ef9727da6c851f

使用 cacheID 查找文件内容

# ls /var/lib/docker/overlay2/85c4c5ecdac6c0d197f899dac227b9d493911a9a5820eac501bb5e9ae361f4c7
committed  diff  link
# ls /var/lib/docker/overlay2/85c4c5ecdac6c0d197f899dac227b9d493911a9a5820eac501bb5e9ae361f4c7/diff
bin   dev  home  lib64  mnt  proc  run   srv  tmp  var
boot  etc  lib   media  opt  root  sbin  sys  usr

上示例中,镜像元数据和镜像层内容是分开存储的。因此通过 cache-id 我们需要到 /var/lib/docker/overlay2 目录下查看镜像层内容,它就存在 diff 目录下,其中 link 存储的是镜像层对应的短 ID,后面会看到它的用场。

找到了镜像层的最底层,接着查找镜像层的“中间层”,发现在 layerdb 目录下没有 diff-id e379e8aedd4d72bb4c529a4ca07a4e4d230b5a1d3f7a61bc80179e8f02421ad8的镜像层:

# ls /var/lib/docker/image/overlay2/layerdb/sha256/e379e8aedd4d72bb4c529a4ca07a4e4d230b5a1d3f7a61bc80179e8f02421ad8
ls: 无法访问/var/lib/docker/image/overlay2/layerdb/sha256/e379e8aedd4d72bb4c529a4ca07a4e4d230b5a1d3f7a61bc80179e8f02421ad8: 没有那个文件或目录

这是因为 docker 引入了内容寻址机制,该机制会根据文件内容来索引镜像和镜像层。docker 利用 rootfs 中的 diff_id 计算出内容寻址的 chainID,通过 chainID 获取 layer 相关信息,最终索引到镜像层文件内容。

对于最底层镜像层其 diff_id 即是 chainID。因此我们可以查找到它的文件内容。除最底层外,chainID 需通过公式 chainID(n) = SHA256(chain(n-1) diffID(n)) 计算得到,计算“中间层” chainID:

# echo -n "sha256:2edcec3590a4ec7f40cf0743c15d78fb39d8326bc029073b41ef9727da6c851f sha256:e379e8aedd4d72bb4c529a4ca07a4e4d230b5a1d3f7a61bc80179e8f02421ad8" | sha256sum -
780238f18c540007376dd5e904f583896a69fe620876cabc06977a3af4ba4fb5  -

根据 “中间层” chainID 查找文件内容:

# ls /var/lib/docker/image/overlay2/layerdb/sha256/780238f18c540007376dd5e904f583896a69fe620876cabc06977a3af4ba4fb5
cache-id  diff  parent  size  tar-split.json.gz
# cat /var/lib/docker/image/overlay2/layerdb/sha256/780238f18c540007376dd5e904f583896a69fe620876cabc06977a3af4ba4fb5/cache-id
57e1f1b11e26f748161b7fccbf2ba6b24c2f98dc8a821729f0be215ad267498c
# cat /var/lib/docker/image/overlay2/layerdb/sha256/780238f18c540007376dd5e904f583896a69fe620876cabc06977a3af4ba4fb5/diff
sha256:e379e8aedd4d72bb4c529a4ca07a4e4d230b5a1d3f7a61bc80179e8f02421ad8
# cat /var/lib/docker/image/overlay2/layerdb/sha256/780238f18c540007376dd5e904f583896a69fe620876cabc06977a3af4ba4fb5/parent
sha256:2edcec3590a4ec7f40cf0743c15d78fb39d8326bc029073b41ef9727da6c851f
镜像层文件内容
# ls /var/lib/docker/overlay2/57e1f1b11e26f748161b7fccbf2ba6b24c2f98dc8a821729f0be215ad267498c
committed  diff  link  lower  work
# ls /var/lib/docker/overlay2/57e1f1b11e26f748161b7fccbf2ba6b24c2f98dc8a821729f0be215ad267498c/diff/
docker-entrypoint.d  etc  lib  tmp  usr  var
镜像层文件内容短 ID
# cat /var/lib/docker/overlay2/57e1f1b11e26f748161b7fccbf2ba6b24c2f98dc8a821729f0be215ad267498c/link
24GM2IZVPTUROAG7AWJO5ZWE6B
“父”镜像层文件内容短 ID
# cat /var/lib/docker/overlay2/57e1f1b11e26f748161b7fccbf2ba6b24c2f98dc8a821729f0be215ad267498c/lower
l/SICZO4QNVZEVOIJ4HDXVDKNYA2

找到最底层文件内容和“中间层”文件内容,再去找最顶层文件内容就变的不难了

五、Docker容器镜像操作命令

  • docker commit

    # docker commit 容器id
        docker通过commit和build操作实现镜像的构建,commit将容器提交为一个镜像,build在一个镜像的基础上构建镜像。
    
  • docker save

    # docker save -o xxx.tar 镜像名称
        导出容器镜像
    
  • docker load

    # docker load -i xxx.tar
        把他人分享的容器镜像导入到本地,这通常是容器镜像分发方式之一
    
  • docker export

    # docker export -o xxx.tar 容器id
        把正在运行的容器导出
    
  • docker import

    # docker import xxx.tar 镜像名称
        导入使用docker export导入的容器作为本地容器镜像
    

六、容器镜像加速器

由于国内访问国外的容器镜像仓库速度比较慢,因此国内企业创建了容器镜像加速器,以方便国内用户使用容器镜像。

6.1 获取阿里云容器镜像加速地址

image-20230726223203481.png

6.2 配置docker daemon使用加速器

# sudo mkdir -p /etc/docker
# sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://mu666krw.mirror.aliyuncs.com"]
}
EOF
# sudo systemctl daemon-reload
# sudo systemctl restart docker