Docker 基础概念

178 阅读8分钟

Docker 最核心的组件

  • image镜像:构建容器(我们将应用程序以及运行环境打包为镜像环境)
  • Container:容器(应用程序就跑在容器中)
  • 镜像仓库:保存镜像文件、上传和下载镜像
  • Dockerfile:将部署的操作写成脚本

docker ps 查看当前正在执行的容器:docker ps,当然如果现在执行什么都不会显示,因为我们还没有任何容器; docker ps -a 查看当前所有容器(包括正在执行的和已经结束的):docker ps -a,同样,现在执行,我们也不会看到任何结果; docker images 查看本地已经安装的docker镜像:docker images;

docker run ubuntu:latest ls -l 执行一个ubuntu 18.04容器

容器里究竟有些什么东西

docker inspect 这个命令需要接受一个容器ID或者NAME作为参数 返回的是: 这是一个JSON对象,包含了一个容器的全部内容。当然我们没必要逐一去讲每一个字段的含义,大家在终端里执行一下,然后自己去看看就好

两种访问inspect结果的方法

docker inspect原生支持的,它有一个-f参数,允许我们用go template的语法选择要使用的JSON字段。

例如,为了读取容器IP地址字段,我们可以这样

docker inspect -f {{.NetworkSettings.IPAddress}} 38867a291e60

jq stedolan.github.io/jq/ 它是一个很方便的基于命令行的JSON parser,我们直接执行brew install jq安装

docker inspect 1769e51eba1a | jq

image.png

可以看到,之前黑白的JSON结果变成彩色的了。并且,和docker inspect的-f参数类似,它接受一个-r参数也可以让我们访问指定的字段,例如之前的访问IP地址,现在可以这样: ocker inspect 7b479ec00c26 | jq -r ".[0].NetworkSettings.IPAddress"

为了读取容器IP地址字段,我们可以这样: docker inspect -f {{•NetworkSettings .IPAddress}} 176951ebala(id或者name)

docker inspect 7b479ec00c26(id或者name)

[
    {
        "Id": "7b479ec00c2624ac95911afb802629fc40000a9ae699881ed9d0828eb5824565",
        "Created": "2023-02-22T08:36:19.565910637Z",
        "Path": "ls",
        "Args": [
            "-l"
        ],
        "State": {
            "Status": "exited",
            "Running": false,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 0,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2023-02-22T08:36:19.881681804Z",
            "FinishedAt": "2023-02-22T08:36:19.882245971Z"
        },
        "Image": "sha256:a6be1f66f70f66ef43503292e38ccbfc14f2d5464e7736344783a8fc7bb339a8",
        "ResolvConfPath": "/var/lib/docker/containers/7b479ec00c2624ac95911afb802629fc40000a9ae699881ed9d0828eb5824565/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/7b479ec00c2624ac95911afb802629fc40000a9ae699881ed9d0828eb5824565/hostname",
        "HostsPath": "/var/lib/docker/containers/7b479ec00c2624ac95911afb802629fc40000a9ae699881ed9d0828eb5824565/hosts",
        "LogPath": "/var/lib/docker/containers/7b479ec00c2624ac95911afb802629fc40000a9ae699881ed9d0828eb5824565/7b479ec00c2624ac95911afb802629fc40000a9ae699881ed9d0828eb5824565-json.log",
        "Name": "/brave_stonebraker",
        "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,
            "CgroupnsMode": "private",
            "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": null,
            "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/ff9d0606845be43930e06b60620dd038a8eb9f8ac9a296bcda715823408276e5-init/diff:/var/lib/docker/overlay2/e14ea635896b3a2d25206bc250d75300b3f7d6d4fe8fe538dc9ee2204365cd66/diff",
                "MergedDir": "/var/lib/docker/overlay2/ff9d0606845be43930e06b60620dd038a8eb9f8ac9a296bcda715823408276e5/merged",
                "UpperDir": "/var/lib/docker/overlay2/ff9d0606845be43930e06b60620dd038a8eb9f8ac9a296bcda715823408276e5/diff",
                "WorkDir": "/var/lib/docker/overlay2/ff9d0606845be43930e06b60620dd038a8eb9f8ac9a296bcda715823408276e5/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [],
        "Config": {
            "Hostname": "7b479ec00c26",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": true,
            "AttachStderr": true,
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "ls",
                "-l"
            ],
            "Image": "ubuntu:latest",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {
                "org.opencontainers.image.ref.name": "ubuntu",
                "org.opencontainers.image.version": "22.04"
            }
        },
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "8331d4e6a11f85ae953e74328ea83d1d380424396be8a5f590a7a0a4d4e7b99c",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {},
            "SandboxKey": "/var/run/docker/netns/8331d4e6a11f",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "",
            "Gateway": "",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "",
            "IPPrefixLen": 0,
            "IPv6Gateway": "",
            "MacAddress": "",
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "3fa9b590b9d65f2616ef531808647648f599792ae50cbb159f1b004ba3cba3d7",
                    "EndpointID": "",
                    "Gateway": "",
                    "IPAddress": "",
                    "IPPrefixLen": 0,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "",
                    "DriverOpts": null
                }
            }
        }
    }
]

清理和容器有关的资源

如何删除容器 docker rm a243dd60b793 容器的ID docker rm priceless_hugle 容器的名字

清除容器列表 docker rm $(docker ps -a -q) 这里,-q是让docker ps命令只显示容器ID列表。我们也可以把-a -q写成-aq

每次执行完一个容器之后还要记得删掉很麻烦啊,能不能执行完就自动删掉呢? docker run --rm ubuntu:latest ls -l

如何删除镜像 docker rmi ubuntu:latest 使用name:tag的形式来指定镜像 按照容器ID来删除 docker rmi $(docker images -q)

如何与容器交互

为了能和容器里这个bash交互 docker run -i -t ubuntu:latest bash

  • -i是interactive,表示我们要和容器交互;
  • -t是tty,让docker创建一个虚拟终端,这样我们就能在屏幕上看到来自容器的控制台输出了;

除了正在打印消息的ps aux进程外,整个容器里只有一个bash进程。这是容器区别于虚拟机最明显的一个地方,容器就像一个沙箱一样,把进程隔离在容器里,而进程本身对此却不知情,以为自己就是这个操作系统中的唯一进程。

接下来,要退出这个容器,我们只要执行exit离开bash就好了

恢复已经结束的容器

我们再想在容器中执行bash的时候,除了使用docker run新启动一个容器之外,还可以重新启动之前退出的容器。例如,我们执行: docker start c7559a4d6165

交互模式重启 docker start -i c7559a4d6165

可以用docker stop ID停止一个在后台执行的容器; 可以用-i参数以交互模式恢复容器的执行;

通过容器启动一个Nginx server

基于上一节的结果,我们以交互模式启动一个执行bash的容器:docker run -i -t ubuntu:latest bash。接下来,用起来就和普通的Ubuntu一样了,我们先在Shell中执行下面的命令安装一下Nginx

apt-get update && apt-get install -y nginx

安装完成后,和普通的Ubuntu不同的是,Nginx不会自动启动,我们需要手工执行一下nginx命令。然后,当我们执行ps aux的时候,就会看到Nginx启动了

image.png

通过host访问容器中的Web服务

另起一终端 查看容器的IP地址 docker inspect c7559a4d6165 | jq -r ".[0].NetworkSettings.IPAddress"

由于是个容器需要把其端口映射到外面进行访问,Nginx的80端口是开放在容器内的 docker run -it -p 8080:80 ubuntu:latest bash

-p参数可以让我们用host_port:container_port的格式指定容器内外的端口映射规则

通过Volumn共享文件

最好的办法,则是可以像端口映射一样,把Host上的某个目录映射到容器里。为此,我们可以在启动容器的时候,使用-v参数

由于容器中的Nginx默认的web根目录是/var/www/html,最简单的,我们把这个目录映射出来就好了。

首先,在host中,创建一个/Myweb目录,并在其中添加一个demo.html文件

docker run -it -p 8080:80 -v /Myweb:/var/www/html ubuntu:latest bash

我们使用了-v host_dir:container_dir进行了目录映射。映射之后,在容器中,之前/var/www/html目录指定的内容就无法访问了。现在/var/www/html访问的,是host上的/tmp/web目录。

实际上,我们也可以用这样的方式给容器添加多个目录映射,只要使用多个-v参数就好了

构建自己的docker镜像

执行docker diff 9c961bfe148a

image.png

可以看到,Docker用类似git的形式记录了容器中的每一个文件变化。并且,我们还可以像Git中提交代码一样,去提交这些变化。在终端中,我们执行:

docker commit -a "bbb" -m "Install Nginx" 42f4ea144b73 lll/nginx:0.1.0

-a表示Author,即提交者的姓名; -m表示Message,即本次提交的注释; 42f4ea144b52,这是容器ID,它表示了我们要制作的镜像最终的状态; lll/nginx:0.1.0,这是新镜像的名称,以及版本号;