这就是Docker

290 阅读10分钟

前言

每次自己定好的写博文计划都只是被各种原因打断,算了,不扯了,开始!

啥是Docker

Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。(来自百度百科)

Docker的优势

  • 灵活:即使是最复杂的应用也可以集装箱化。
  • 轻量级:容器利用并共享主机内核。
  • 可互换:您可以即时部署更新和升级。
  • 便携式:您可以在本地构建,部署到云,并在任何地方运行。
  • 可扩展:您可以增加并自动分发容器副本。
  • 可堆叠:您可以垂直和即时堆叠服务。

Docker的架构

src=http___i.loli.net_2020_08_01_9VSxDTPkYJ5n6eZ.png&refer=http___i.loli.jfif

  • Client(客户端):通过一些命令与 Docker 服务器作交互,比如说 docker build:构建一个容器;docker pull:接取一个容器;docker run:运行一个容器

  • Docker_host(服务器):Docker 的操作都在这里执行

    1. Docker daemon(守护进程):Docker架构中的主体部分

      1. 提供 Server 的功能使其可以接受 Docker Client 的请求
      2. 当需要容器镜像时,则从Registry中下载镜像
    2. Images(镜像):docker镜像就好比是一个模板,可以通过这个模板来创建容器服务,通过这个镜像可以创建多个容器(最终服务运行或者项目运行就是在容器中的)。

    3. Containers(容器):Docker 利用容器技术,独立运行一个或者一个组应用,通过镜像来创建的。(初学者可以暂时把这个容器理解为就是一个简易的linux)

      可以把镜像理解成是 java 中的类,而容器理解成 java 中的对象实例,一个类可以拥有多个对象实例

  • Register(远程仓库):存放镜像的地方,分为公有仓库和私有仓库

咋安装Docker

这是官方文档传送门:Docker安装,我就不瞎扯了。

Docker常用命令

Docker的所有命令看这里:Docker命令,我总结下常用的:

1. 查看信息

1. docker --help(帮助信息)

命令说明
docker --help查看全部命令
docker 命令 --help查看某个命令的帮助信息

2. docker info(详细信息)

命令说明
docker info显示docker的系统信息,包括镜像和容器的数量

3. docker version(版本信息)

命令说明
docker version打印docker版本信息

2. 镜像命令

1. docker images(查看镜像)

  • 命令:docker images [OPTIONS] [REPOSITORY[:TAG]]

  • 常用可选项:

    名称,速记默认描述
    --all , -a列出所有镜像(默认隐藏中间镜像)
    --quiet , -q只显示镜像的ID
  • 例子:

    [root@localhost ~]# docker images
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    hello-world         latest              bf756fb1ae65        5 months ago        13.3kB
    复制代码
    
    • 解释

      • REPOSITORY:镜像的仓库源(名字)
      • TAG:镜像的标签(版本)
      • IMAGE ID:镜像的 id
      • CREATED:镜像的创建时间
      • SIZE:镜像的大小

2. docker search(在仓库中搜索镜像)

  • 命令:docker search [OPTIONS] TERM

  • 常用可选项:

    名称,速记默认描述
    --filter , -f根据提供的条件过滤输出,格式为key=value对。 如果有多个过滤器,则传递多个标志 (例如--filter is-automated=true --filter stars=3
  • 例子:

    docker search --filter stars=3 busybox
    
    NAME                 DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
    busybox              Busybox base image.                             325       [OK]
    复制代码
    

3. docker pull(下载镜像)

  • 命令:docker pull [OPTIONS] NAME[:TAG|@DIGEST] 如果不写 tag(版本),默认就是 latest

  • 例子:

    # 拉取最新版,下面的命令相当于: docker pull mysql:latest
    docker pull mysql
    
    # 拉取指定版本,需要确定在仓库中存在该版本
    docker pull mysql:5.7
    复制代码
    

4. docker rmi(删除镜像)

  • 命令:docker rmi [OPTIONS] IMAGE [IMAGE...] 可以删除一个或多个镜像,可以通过镜像的名字或者 id 删除

  • 常用可选项:

    名称,速记默认描述
    --force , -f强制删除
  • 例子:

    # 删除指定镜像
    docker rmi -f e73346bdf465
    
    # 删除所有的镜像
    docker rmi -f $(docker images -aq)
    复制代码
    

5. docker commit(通过容器生成镜像)

  • 命令:docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]

  • 常用可选项:

    名称,速记默认描述
    -m指定提交的说明信息
    -a指定更新的用户信息
  • 例子:

    # 对一个tomcat容器进行了修改后(webapps文件中添加了app),其中7e119b82cff6表示一个容器
    docker commit -a "xiaoMaNong" -m "add webapps app" 7e119b82cff6 tomcat:v01
    
    # 然后查看本地的镜像,可以发现看到刚提交的镜像
    docker images
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    tomcat              v01                 37af1236adef        15 seconds ago      652 MB
    复制代码
    

6. docker save/load(镜像的打包与加载)

  • docker save:将一个或多个镜像保存到 tar 存档(默认情况下流式传输到STDOUT)

    • 命令:docker save [OPTIONS] IMAGE [IMAGE...]
    • 常用可选项:
    名称,速记默认描述
    --output , -o写入文件,而不是STDOUT
  • docker load:从 tar 存档或STDIN加载图像

    • 命令:docker load [OPTIONS]
    • 常用可选项:
    名称,速记默认描述
    --input , -i从 tar 存档文件而非 STDIN 中读取
  • 例子:

    # 将镜像保存到本地 tar 文件
    docker save -o mysql5.7 mysql:5.7
    
    # 另一台服务器上无外网,将上面保存的 tar 包发送到该服务器,然后加载
    sudo docker load -i mysql5.7
    复制代码
    

3. 容器命令

说明:有了镜像才可以创建容器

1. docker run(新建容器并启动)

  • 命令:docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

  • 常用可选项:

    名称,速记默认描述
    --name="Name"为容器分配一个名称,名称是唯一的,可以用名称来确定容器
    --detach , -d后台方式运行
    -it使用交互方式运行,进入容器查看内容
    --rm退出时自动删除容器
    --publish , -p将容器的端口发布到主机,使用方法: -p ip:主机端口:容器端口 -p 主机端口:容器端口(常用) -p 容器端口 容器端口
    --publish-all , -P将容器的端口随机分配到主机的空闲端口上,可以使用docker ps -a 查看
    --volume, -v绑定挂载目录,使用方法:-v /本地目录:容器目录 匿名挂载:-v 容器目录 具名挂载:-v 卷的名字:容器目录 (详见 四、容器数据卷)
    --netbridge将容器连接到一个网络中,不指定会以桥接的方式连接到 docker0
    --restart=always设置容器自启动,docker 服务重启后容器也跟着重启
  • 例子:

    在这里插入图片描述

设置容器自启动

在运行 docker 容器时可以加如下参数来保证每次 docker 服务重启后容器也自动重启:

docker run --restart=always
复制代码

如果容器已经启动了则可以使用如下命令:

docker update --restart=always <CONTAINER ID>
复制代码

后台启动容器的坑

当以后台运行的方式启动了一个容器后,再使用 docker ps 命令发现,容器并没有在运行

[root@localhost ~]# docker run --name="centos_test" -d centos
1f38528aade344433c9d9c0b35125e3ea8007380e599c7b4a875944599481d30
[root@localhost ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
复制代码
  • 原因:docker 容器使用后台运行,就必须要有一个前台进程,如果 docker 发现没有应用,就会自动停止。

  • 解决方法:docker run -dit centos /bin/bash

    • 添加-it 参数交互运行
    • 添加-d 参数后台运行
    • 这样就能启动一个一直停留在后台运行的Centos了
    • 注意:进入容器的方法要使用exec,不要使用attach命令,attach命令就是使用现有终端,如果你要退出容器操作,那么bash结束,容器也就退出了

2. docker ps(列出容器)

  • 命令:docker ps [OPTIONS] 不加任何参数默认显示为正在运行的容器

  • 常用可选项:

    名称,速记默认描述
    --all , -a显示所有容器
    --last , -n=?-1显示n个最后创建的容器(包括所有状态)
    --quiet , -q仅显示数字ID
  • 例子:

    [root@localhost /]# docker ps -a
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
    6097bc8e3852        centos              "/bin/bash"         10 minutes ago      Exited (0) 9 minutes ago                       sad_lamport
    ea55e44464ae        bf756fb1ae65        "/hello"            3 hours ago         Exited (0) 3 hours ago                         unruffled_chandrasekhar
    复制代码
    
    • 解释:

      • CONTAINER ID:容器id
      • IMAGE:镜像
      • COMMAND:引用命令
      • CREATED:创建容器的时间
      • STATUS:容器状态
      • PORTS:暴露的端口
      • NAMES:容器名称

3. exit/Ctrl + P + Q(退出容器)

docker run -it name 进入容器之后,使用如下的命令退出容器 exit:容器停止并退出 Ctrl + P + Q:==容器不停止==退出

4. docker rm(删除容器)

  • 命令:docker rm [OPTIONS] CONTAINER [CONTAINER...] 命令中的 CONTAINER 用容器的 id/name

  • 常用可选项:

    名称,速记默认描述
    --force , -f强制删除正在运行的容器(使用SIGKILL)
  • 例子:

    # 删除所有的容器
    docker rm -f $(docker ps -aq)
    docker ps -aq | xargs docker rm -f
    复制代码
    

5. docker start/stop(启动和停止容器)

docker start 容器id/name		# 启动容器
docker restart 容器id/name	# 重启容器
docker stop 容器id/name		# 停止当前运行的容器
docker kill 容器id/name		# 强制停止运行的容器
复制代码

6.docker exec(进入当前正在运行的容器(打开新终端))

  • 命令:docker exec [OPTIONS] CONTAINER COMMAND [ARG...]

  • 常用可选项:

    名称,速记默认描述
    -it以交互模式运行
  • 例子:

    docker exec -it centos1 /bin/bash
    复制代码
    

7. docker attach(进入当前正在运行的容器(进入容器启动命令的终端,不会启动新的线程))

  • 命令:docker attach [OPTIONS] CONTAINER

8. docker cp(在容器和本地文件系统之间复制文件/文件夹)

  • 命令:

    # 在本地系统执行
    
    # 将容器中的文件拷贝到本地文件系统中
    docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH
    
    # 将本地系统文件拷贝到容器中
    docker cp [OPTIONS] SRC_PATH CONTAINER:DEST_PATH
    复制代码
    

9. docker top(查看容器中进程信息)

# 类似于 linux 中的 top 命令
docker top CONTAINER
复制代码

10. docker logs(日志信息)

  • 命令:docker logs [OPTIONS] CONTAINER

  • 常用可选项:

    名称,速记默认描述
    --follow , -f跟踪日志输出
    --tailall从日志末尾开始显示的行数
    --timestamps , -t显示时间戳
  • 例子:

# 显示全部日志
docker logs -ft centos_test

# 显示10条日志
docker logs -ft --tail 10 centos_test
复制代码

11. docker inspect(返回容器详细信息)

docker inspect CONTAINER
复制代码

例子(标注了常用的信息):

[root@localhost ~]# docker inspect c2b030acf83a
[
    {
        "Id": "c2b030acf83a23b33471b28d58e20d96f9eb22fceab5ffb9b0a848841a3045b6",//容器id,一般使用的是前12位
        "Created": "2020-06-07T15:04:33.788916436Z",//容器创建时间
        "Path": "/bin/bash",	//默认控制台
        "Args": [],	//传递的参数
        "State": {	//容器的状态
            "Status": "running",	//running 表示正在运行
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 101264,	//进程id
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2020-06-07T15:04:35.115091831Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
        "Image": "sha256:470671670cac686c7cf0081e0b37da2e9f4f768ddc5f6a26102ccd1c6954c1ee",//镜像的id
        "ResolvConfPath": "/var/lib/docker/containers/c2b030acf83a23b33471b28d58e20d96f9eb22fceab5ffb9b0a848841a3045b6/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/c2b030acf83a23b33471b28d58e20d96f9eb22fceab5ffb9b0a848841a3045b6/hostname",
        "HostsPath": "/var/lib/docker/containers/c2b030acf83a23b33471b28d58e20d96f9eb22fceab5ffb9b0a848841a3045b6/hosts",
        "LogPath": "/var/lib/docker/containers/c2b030acf83a23b33471b28d58e20d96f9eb22fceab5ffb9b0a848841a3045b6/c2b030acf83a23b33471b28d58e20d96f9eb22fceab5ffb9b0a848841a3045b6-json.log",
        "Name": "/zyx",
        "RestartCount": 0,
        "Driver": "overlay2",
        "Platform": "linux",
        "MountLabel": "",
        "ProcessLabel": "",
        "AppArmorProfile": "",
        "ExecIDs": null,
        "HostConfig": {	// 主机的配置
            "Binds": null,
            "ContainerIDFile": "",
            "LogConfig": {
                "Type": "json-file",
                "Config": {}
            },
            "NetworkMode": "default",
            "PortBindings": {},
            "RestartPolicy": {
                "Name": "no",
                "MaximumRetryCount": 0
            },
            "AutoRemove": false,
            "VolumeDriver": "",
            "VolumesFrom": null,
            "CapAdd": null,
            "CapDrop": null,
            "Capabilities": null,
            "Dns": [],
            "DnsOptions": [],
            "DnsSearch": [],
            "ExtraHosts": null,
            "GroupAdd": null,
            "IpcMode": "private",
            "Cgroup": "",
            "Links": null,
            "OomScoreAdj": 0,
            "PidMode": "",
            "Privileged": false,
            "PublishAllPorts": false,
            "ReadonlyRootfs": false,
            "SecurityOpt": null,
            "UTSMode": "",
            "UsernsMode": "",
            "ShmSize": 67108864,
            "Runtime": "runc",
            "ConsoleSize": [
                0,
                0
            ],
            "Isolation": "",
            "CpuShares": 0,
            "Memory": 0,
            "NanoCpus": 0,
            "CgroupParent": "",
            "BlkioWeight": 0,
            "BlkioWeightDevice": [],
            "BlkioDeviceReadBps": null,
            "BlkioDeviceWriteBps": null,
            "BlkioDeviceReadIOps": null,
            "BlkioDeviceWriteIOps": null,
            "CpuPeriod": 0,
            "CpuQuota": 0,
            "CpuRealtimePeriod": 0,
            "CpuRealtimeRuntime": 0,
            "CpusetCpus": "",
            "CpusetMems": "",
            "Devices": [],
            "DeviceCgroupRules": null,
            "DeviceRequests": null,
            "KernelMemory": 0,
            "KernelMemoryTCP": 0,
            "MemoryReservation": 0,
            "MemorySwap": 0,
            "MemorySwappiness": null,
            "OomKillDisable": false,
            "PidsLimit": null,
            "Ulimits": null,
            "CpuCount": 0,
            "CpuPercent": 0,
            "IOMaximumIOps": 0,
            "IOMaximumBandwidth": 0,
            "MaskedPaths": [
                "/proc/asound",
                "/proc/acpi",
                "/proc/kcore",
                "/proc/keys",
                "/proc/latency_stats",
                "/proc/timer_list",
                "/proc/timer_stats",
                "/proc/sched_debug",
                "/proc/scsi",
                "/sys/firmware"
            ],
            "ReadonlyPaths": [
                "/proc/bus",
                "/proc/fs",
                "/proc/irq",
                "/proc/sys",
                "/proc/sysrq-trigger"
            ]
        },
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/bbe44f663e7c732f43fa3a35633008e8d7027fed9d41400a1aa970d5bdf45c90-init/diff:/var/lib/docker/overlay2/02399b4c6980e3092721d60619f83c651885c0b0eb1241a6417f0bddb44b5463/diff",
                "MergedDir": "/var/lib/docker/overlay2/bbe44f663e7c732f43fa3a35633008e8d7027fed9d41400a1aa970d5bdf45c90/merged",
                "UpperDir": "/var/lib/docker/overlay2/bbe44f663e7c732f43fa3a35633008e8d7027fed9d41400a1aa970d5bdf45c90/diff",
                "WorkDir": "/var/lib/docker/overlay2/bbe44f663e7c732f43fa3a35633008e8d7027fed9d41400a1aa970d5bdf45c90/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [],	//数据卷挂载
        "Config": {		//基本配置
            "Hostname": "c2b030acf83a",		//容器名字
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "Tty": true,
            "OpenStdin": true,
            "StdinOnce": false,
            "Env": [	//基本的环境变量
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "/bin/bash"
            ],
            "Image": "centos",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {
                "org.label-schema.build-date": "20200114",
                "org.label-schema.license": "GPLv2",
                "org.label-schema.name": "CentOS Base Image",
                "org.label-schema.schema-version": "1.0",
                "org.label-schema.vendor": "CentOS",
                "org.opencontainers.image.created": "2020-01-14 00:00:00-08:00",
                "org.opencontainers.image.licenses": "GPL-2.0-only",
                "org.opencontainers.image.title": "CentOS Base Image",
                "org.opencontainers.image.vendor": "CentOS"
            }
        },
        "NetworkSettings": {	//网络的一些设置
            "Bridge": "",
            "SandboxID": "70097fb845389da1a20faf75eabb2f84866ba4b38ea8388397a840b9a344aa85",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {},
            "SandboxKey": "/var/run/docker/netns/70097fb84538",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "cb235799991b3c585bf97ea5fcdfc7a069aa13554a5f84ea35e6172c9cad2ed5",
            "Gateway": "172.17.0.1",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "172.17.0.2",
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
            "MacAddress": "02:42:ac:11:00:02",
            "Networks": {
                "bridge": {		//桥接
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "020a4fab0d00a01941b764d9f16740807b2c2673b8138d7e1ece968086b5475b",
                    "EndpointID": "cb235799991b3c585bf97ea5fcdfc7a069aa13554a5f84ea35e6172c9cad2ed5",
                    "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
                }
            }
        }
    }
]
复制代码

12. docker stats(监控容器资源消耗)

  • 命令:docker stats [OPTIONS] [CONTAINER...]

  • 常用可选项:

    名称,速记默认描述
    --all, -a默认仅显示运行中的容器显示所有容器
    --format string格式化输出
    --no-stream只返回当前的状态

例子:

# 查看当前运行中的所有容器资源
> docker stats
CONTAINER ID   NAME                            CPU %     MEM USAGE / LIMIT     MEM %     NET I/O           BLOCK I/O         PIDS
fdedc094cd26   dockercompose_nginx_1           0.00%     2.148MiB / 3.696GiB   0.06%     4.86MB / 4.78MB   0B / 0B           3
68189b6d290f   dockercompose_kibana_1          0.00%     413.7MiB / 3.696GiB   10.93%    125MB / 96.4MB    263MB / 113MB     22
22ed88ee3afa   dockercompose_elasticsearch_1   0.39%     524.9MiB / 3.696GiB   13.87%    133MB / 252MB     72.4MB / 2.85MB   62

# 格式化为 json
> docker stats --no-stream --format "{"container":"{{ .Container }}","memory":{"raw":"{{ .MemUsage }}","percent":"{{ .MemPerc }}"},"cpu":"{{ .CPUPerc }}"}"
{"container":"fdedc094cd26","memory":{"raw":"2.148MiB / 3.696GiB","percent":"0.06%"},"cpu":"0.00%"}
{"container":"68189b6d290f","memory":{"raw":"413.8MiB / 3.696GiB","percent":"10.93%"},"cpu":"0.45%"}
{"container":"22ed88ee3afa","memory":{"raw":"525.1MiB / 3.696GiB","percent":"13.87%"},"cpu":"0.94%"}
复制代码

结果说明:

默认情况下,stats 命令会每隔 1 秒钟刷新一次输出的内容直到你按下 ctrl + c。下面是输出的主要内容:

字段说明
CONTAINER以短格式显示容器的 ID。
CPU %CPU 的使用情况。
MEM USAGE / LIMIT当前使用的内存和最大可以使用的内存。
MEM %以百分比的形式显示内存使用情况。
NET I/O网络 I/O 数据。
BLOCK I/O磁盘 I/O 数据。
PIDSPID 号。

自定义的格式中可以使用的所有占位符:

点位符说明
.Container根据用户指定的名称显示容器的名称或 ID
.Name容器名称
.ID容器 ID
.CPUPercCPU 使用率
.MemUsage内存使用量
.NetIO网络 I/O
.BlockIO磁盘 I/O
.MemPerc内存使用率
.PIDsPID 号