Docker篇(基础命令)
目录
一、启动与停止
二、镜像相关的命令
1. 查看镜像
2. 搜索镜像
3. 拉取镜像
4. 删除镜像
三、容器创建与启动容器
1. 查看容器
2. 创建容器
交互式方式创建容器
守护式方式创建容器
3. 容器启动与停止
四、容器操作命令
1. 文件拷贝
2. 目录(文件)挂载
3. 删除容器
五、docker inspect
1. 功能介绍
2. 参数说明
2.1. -f
2.2. --type
2.3. -s
3. docker inspect -f 更多用法
3.1. Go 模版 详解
3.2. 数据类型
3.3. 数据结构
3.4. 函数
3.5. if 语句
3.6. range迭代数据
3.7. 打印信息
3.8. 管道
3.9. Docker内置函数
json
join
lower
upper
title
split
3.10. 常用docker inspect --format 输出示例
4. 参考文档
六、容器服务日志
1. 简介
2. 常用命令
查看docker容器
查看容器日志(全部)
查看容器日志,只显示最后100行
查看容器最近三十分钟的日志
查看容器某个时间之后的日志
查看容器某个时间段的日志
查看容器日志并显示时间戳
查看容器日志某个时间最近的日志
将容器日志写入到文件
根据某个关键字查询日志
查询容器某个时间段的日志,并且根据关键字进行查询
一、启动与停止
详细命令:
# 启动docker:
systemctl start docker
# 停止docker:
systemctl stop docker
# 重启docker:
systemctl restart docker
# 查看docker状态:
systemctl status docker
# 开机启动:
systemctl enable docker
# 查看docker概要信息
docker info
# 查看docker帮助文档
docker --help
注意:systemctl命令是系统服务管理器指令
二、镜像相关的命令
1. 查看镜像
docker images
REPOSITORY:镜像名称
TAG:镜像标签 (默认是可以省略的,也就是latest)
IMAGE ID:镜像ID
CREATED:镜像的创建日期(不是获取该镜像的日期)
SIZE:镜像大小
这些镜像都是存储在Docker宿主机的/var/lib/docker目录下
2. 搜索镜像
如果你需要从网络中查找需要的镜像,可以通过以下命令搜索
docker search 镜像名称
NAME:仓库名称
DESCRIPTION:镜像描述
STARS:用户评价,反应一个镜像的受欢迎程度
OFFICIAL:是否官方
AUTOMATED:自动构建,表示该镜像由Docker Hub自动构建流程创建的
3. 拉取镜像
拉取镜像就是从中央仓库中下载镜像到本地
docker pull 镜像名称
例如,我要下载centos7镜像
docker pull centos:7
#如果不指定版本号,下载最新版本
docker pull centos
docker pull centos:latest
4. 删除镜像
按镜像ID删除镜像
docker rmi 镜像ID
docker rmi 镜像名称
docker rmi docker images -q 删除所有镜像(谨慎操作)
三、容器创建与启动容器
1. 查看容器
查看最后一次运行的容器
docker ps -l
查看运行容器
docker ps
查看所有容器
docker ps -a
进入容器
其中字符串为容器ID:
docker exec -it d27bd3008ad9 /bin/bash
1.停用全部运行中的容器:
docker stop $(docker ps -q)
2.删除全部容器:
docker rm $(docker ps -aq)
3.一条命令实现停用并删除容器:
docker stop $(docker ps -q) & docker rm $(docker ps -aq)
2. 创建容器
创建容器常用的参数说明:
创建容器命令:docker run
-i:表示运行容器
-t:表示容器启动后会进入其命令行。加入这两个参数后,容器创建就能登录进去。即分配一个伪终端。
--name :为创建的容器命名。
-v:表示目录映射关系(前者是宿主机目录,后者是映射到容器上的目录),可以使用多个-v做多个目录或文件映射。注意:最好做目录映射,在宿主机上做修改,然后共享到容器上。
-d:在run后面加上-d参数,则会创建一个守护式容器在后台运行(这样创建容器后不会自动登录容器,如果只加-i -t两个参数,创建后就会自动进去容器)。
-p:表示端口映射,前者是宿主机端口,后者是容器内的映射端口。可以使用多个-p做多个端口映射
交互式方式创建容器
交互式方式创建容器(创建以后就进入到容器内部了)
这时我们通过ps命令查看,发现可以看到启动的容器,状态为启动状态
docker run -it --name=容器名称 镜像名称:标签 /bin/bash
退出当前容器
exit
守护式方式创建容器
登录守护式容器方式:
docker run -di --name=容器名称 镜像名称:标签
docker exec -it 容器名称 (或者容器ID) /bin/bash
3. 容器启动与停止
#停止容器:
docker stop 容器名称(或者容器ID)
# 启动容器:
docker start 容器名称(或者容器ID)
四、容器操作命令
1. 文件拷贝
如果我们需要将文件拷贝到容器内可以使用cp命令
docker cp 需要拷贝的文件或目录 容器名称:容器目录
> docker cp hello.txt mynginx:/usr/local
#也可以将文件从容器内拷贝出来
docker cp 容器名称:容器目录 需要拷贝的文件或目录
> docker cp mynginx:/usr/local/hello.txt hello.txt
2. 目录(文件)挂载
目录(文件)挂载其实就是修改宿主机的文件,会自动修改容器内部的文件。
我们可以在创建容器的时候,将宿主机的目录与容器内的目录进行映射,
这样我们就可以通过修改宿主机某个目录的文件从而去影响容器。
创建容器 添加-v参数 后边为 宿主机目录:容器目录,例如:
docker run -di -v /usr/local/myhtml:/usr/local/myhtml --name=mycentos3 centos:7
查看IP
docker inspect [容器名|容器ID]
> docker inspect tomcat
> docker inspect nginx
3. 删除容器
# 删除指定的容器:
docker rm 容器名称(容器ID)
# 比如
> docker stop mynginx2
> docker rm mynginx2
注意:
删除容器的时候,一定要先执行停止容器命令。
docker stop 容器名称(容器ID) 然后在执行 docker rm 容器名称(容器ID)
五、docker inspect
1. 功能介绍
docker inspect
会以 json 格式得到 docker 镜像/容器的元数据。
如下,查看mysql镜像的完整元数据:
docker inspect mysql:5.7
[
{
"Id": "sha256:1d7aba9171693947d53f474014821972bf25d72b7d143ce4af4c8d8484623417",
"RepoTags": [
"mysql:5.7"
],
"RepoDigests": [
"mysql@sha256:d9b934cdf6826629f8d02ea01f28b2c4ddb1ae27c32664b14867324b3e5e1291"
],
"Parent": "",
"Comment": "",
"Created": "2021-09-03T07:25:25.419696974Z",
"Container": "9979ac05c87381fb984ce556c94ac87ef0b0209eca50e9a0d81d28756557c2ce",
"ContainerConfig": {
"Hostname": "9979ac05c873",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"3306/tcp": {},
"33060/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"GOSU_VERSION=1.12",
"MYSQL_MAJOR=5.7",
"MYSQL_VERSION=5.7.35-1debian10"
],
"Cmd": [
"/bin/sh",
"-c",
"#(nop) ",
"CMD [\"mysqld\"]"
],
"Image": "sha256:cae8446f5d2e62008d7a1e3bc66ca14ced29fa4c4d0237cf4e6857fd5ca0c18d",
"Volumes": {
"/var/lib/mysql": {}
},
"WorkingDir": "",
"Entrypoint": [
"docker-entrypoint.sh"
],
"OnBuild": null,
"Labels": {}
},
"DockerVersion": "20.10.7",
"Author": "",
"Config": {
"Hostname": "",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"3306/tcp": {},
"33060/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"GOSU_VERSION=1.12",
"MYSQL_MAJOR=5.7",
"MYSQL_VERSION=5.7.35-1debian10"
],
"Cmd": [
"mysqld"
],
"Image": "sha256:cae8446f5d2e62008d7a1e3bc66ca14ced29fa4c4d0237cf4e6857fd5ca0c18d",
"Volumes": {
"/var/lib/mysql": {}
},
"WorkingDir": "",
"Entrypoint": [
"docker-entrypoint.sh"
],
"OnBuild": null,
"Labels": null
},
"Architecture": "amd64",
"Os": "linux",
"Size": 448211969,
"VirtualSize": 448211969,
"GraphDriver": {
"Data": {
"RootDir": "/var/lib/docker/overlay/e96512345b168f8f1f03e341bdc1e305687a8a54eefab1dfd5e21665ee01933a/root"
},
"Name": "overlay"
},
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:d000633a56813933cb0ac5ee3246cf7a4c0205db6290018a169d7cb096581046",
"sha256:731f7c21360385893ff752e1200bf901f7936f973801eb6f10dc81f249920994",
"sha256:b2830993d63aac4a4c4c3cdea0ccae39c14d53e69d82d4a6541b35670431f244",
"sha256:97a2a3481f0d61f26f855842ffb8170680a68659ab724042b3a000941a5a0a4e",
"sha256:35e94dafc854af4a22dd101bc5f6b0b453c91d50ef9893228ae9b41d5fd99226",
"sha256:2eaac5532d4479e5e821f724c854b8bc38527708ff484397b841561e21a8fc9a",
"sha256:89638afc97cdd7709e24a927a87520751464fbb3af9b564e591f0a783b6276fc",
"sha256:71cabb0b234c522858b8398181aac5ff1a98ec6be8ba71c4079a3cb093f6b4de",
"sha256:b09979068448d00f4513f2bb8b5a4e3734bbbddc526ed5205fbd52f442727167",
"sha256:67536a20af848ab1861ea5e5bf336e223a474e7c411bf21761b8b55f40bde9b9",
"sha256:7449e60227868d770c9fd6437a85717bd6d09667e1e066190af887f687c62372"
]
},
"Metadata": {
"LastTagTime": "0001-01-01T00:00:00Z"
}
}
]
如下为以mysql:5.7启动的容器的完整元数据:
docker run -itd mysql:5.7 /bin/sh
492c91fb2b8ff1a334fcd64ba3e46585701e7e5809f564bc2c65f3a655458db3
docker inspect 492c91fb2b8ff1a334fcd64ba3e46585701e7e5809f564bc2c65f3a655458db3
[
{
"Id": "492c91fb2b8ff1a334fcd64ba3e46585701e7e5809f564bc2c65f3a655458db3",
"Created": "2022-06-13T09:01:22.321391083Z",
"Path": "docker-entrypoint.sh",
"Args": [
"/bin/sh"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 48552,
"ExitCode": 0,
"Error": "",
"StartedAt": "2022-06-13T09:01:22.584406847Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:1d7aba9171693947d53f474014821972bf25d72b7d143ce4af4c8d8484623417",
"ResolvConfPath": "/var/lib/docker/containers/492c91fb2b8ff1a334fcd64ba3e46585701e7e5809f564bc2c65f3a655458db3/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/492c91fb2b8ff1a334fcd64ba3e46585701e7e5809f564bc2c65f3a655458db3/hostname",
"HostsPath": "/var/lib/docker/containers/492c91fb2b8ff1a334fcd64ba3e46585701e7e5809f564bc2c65f3a655458db3/hosts",
"LogPath": "/var/lib/docker/containers/492c91fb2b8ff1a334fcd64ba3e46585701e7e5809f564bc2c65f3a655458db3/492c91fb2b8ff1a334fcd64ba3e46585701e7e5809f564bc2c65f3a655458db3-json.log",
"Name": "/silly_antonelli",
"RestartCount": 0,
"Driver": "overlay",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": {
"Binds": null,
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {
"max-file": "10",
"max-size": "100m"
}
},
"NetworkMode": "default",
"PortBindings": {},
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"CapAdd": null,
"CapDrop": null,
"CgroupnsMode": "host",
"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": [
{
"Name": "NOFILE",
"Hard": 655350,
"Soft": 655350
}
],
"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/overlay/e96512345b168f8f1f03e341bdc1e305687a8a54eefab1dfd5e21665ee01933a/root",
"MergedDir": "/var/lib/docker/overlay/3fbd4444a83b03d8684acd87e38bcaac658d4e038f6e27aaabc10b20152f1563/merged",
"UpperDir": "/var/lib/docker/overlay/3fbd4444a83b03d8684acd87e38bcaac658d4e038f6e27aaabc10b20152f1563/upper",
"WorkDir": "/var/lib/docker/overlay/3fbd4444a83b03d8684acd87e38bcaac658d4e038f6e27aaabc10b20152f1563/work"
},
"Name": "overlay"
},
"Mounts": [
{
"Type": "volume",
"Name": "cb8a9a3d23814b91df3566e7b14b355cc381aa5719297907a68f6d99a1472294",
"Source": "/var/lib/docker/volumes/cb8a9a3d23814b91df3566e7b14b355cc381aa5719297907a68f6d99a1472294/_data",
"Destination": "/var/lib/mysql",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
"Config": {
"Hostname": "492c91fb2b8f",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"3306/tcp": {},
"33060/tcp": {}
},
"Tty": true,
"OpenStdin": true,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"GOSU_VERSION=1.12",
"MYSQL_MAJOR=5.7",
"MYSQL_VERSION=5.7.35-1debian10"
],
"Cmd": [
"/bin/sh"
],
"Image": "mysql:5.7",
"Volumes": {
"/var/lib/mysql": {}
},
"WorkingDir": "",
"Entrypoint": [
"docker-entrypoint.sh"
],
"OnBuild": null,
"Labels": {}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "a2f0fe86422968b0c5e1d0b7e4dd66a742dedfc8b01b56eb30649449969f4f12",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {
"3306/tcp": null,
"33060/tcp": null
},
"SandboxKey": "/data/docker/exec/netns/a2f0fe864229",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "d41dfa3aadb23af2c459845e9ba11e87a13e7d96e170c879b6b14db76d443168",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.4",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:04",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "9cbe344a6886a489cd1b3d4cef5befc454d477d4c5ac59756d8bdf579739f20a",
"EndpointID": "d41dfa3aadb23af2c459845e9ba11e87a13e7d96e170c879b6b14db76d443168",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.4",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:04",
"DriverOpts": null
}
}
}
}
]
2. 参数说明
2.1. -f
通常我们需要获取某一个具体的key,会用grep,如下,grep会获取到其他的数据,不够完整或者有冗
余,还得进一步处理,但是 -f 可以解决这个问题:
docker inspect mysql:5.7 | grep Layers
"Layers": [
docker inspect mysql:5.7 | grep -A 30 Layers
"Layers": [
"sha256:d000633a56813933cb0ac5ee3246cf7a4c0205db6290018a169d7cb096581046",
"sha256:731f7c21360385893ff752e1200bf901f7936f973801eb6f10dc81f249920994",
"sha256:b2830993d63aac4a4c4c3cdea0ccae39c14d53e69d82d4a6541b35670431f244",
"sha256:97a2a3481f0d61f26f855842ffb8170680a68659ab724042b3a000941a5a0a4e",
"sha256:35e94dafc854af4a22dd101bc5f6b0b453c91d50ef9893228ae9b41d5fd99226",
"sha256:2eaac5532d4479e5e821f724c854b8bc38527708ff484397b841561e21a8fc9a",
"sha256:89638afc97cdd7709e24a927a87520751464fbb3af9b564e591f0a783b6276fc",
"sha256:71cabb0b234c522858b8398181aac5ff1a98ec6be8ba71c4079a3cb093f6b4de",
"sha256:b09979068448d00f4513f2bb8b5a4e3734bbbddc526ed5205fbd52f442727167",
"sha256:67536a20af848ab1861ea5e5bf336e223a474e7c411bf21761b8b55f40bde9b9",
"sha256:7449e60227868d770c9fd6437a85717bd6d09667e1e066190af887f687c62372"
]
},
"Metadata": {
"LastTagTime": "0001-01-01T00:00:00Z"
}
}
]
docker inspect -f '{{.RootFS.Layers}}' mysql:5.7
[sha256:d000633a56813933cb0ac5ee3246cf7a4c0205db6290018a169d7cb096581046 sha256:731f7c21360385893ff752e1200bf901f7936f973801eb6f10dc81f249920994 sha256:b2830993d63aac4a4c4c3cdea0ccae39c14d53e69d82d4a6541b35670431f244 sha256:97a2a3481f0d61f26f855842ffb8170680a68659ab724042b3a000941a5a0a4e sha256:35e94dafc854af4a22dd101bc5f6b0b453c91d50ef9893228ae9b41d5fd99226 sha256:2eaac5532d4479e5e821f724c854b8bc38527708ff484397b841561e21a8fc9a sha256:89638afc97cdd7709e24a927a87520751464fbb3af9b564e591f0a783b6276fc sha256:71cabb0b234c522858b8398181aac5ff1a98ec6be8ba71c4079a3cb093f6b4de sha256:b09979068448d00f4513f2bb8b5a4e3734bbbddc526ed5205fbd52f442727167 sha256:67536a20af848ab1861ea5e5bf336e223a474e7c411bf21761b8b55f40bde9b9 sha256:7449e60227868d770c9fd6437a85717bd6d09667e1e066190af887f687c62372]
# 格式要求
'{{.一级key值.二级key值}}'
# 容器同样适用
docker inspect -f '{{.Config.Env}}' 492c91fb2b8ff1a334fcd64ba3e46585701e7e5809f564bc2c65f3a655458db3
[PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin GOSU_VERSION=1.12 MYSQL_MAJOR=5.7 MYSQL_VERSION=5.7.35-1debian10]
2.2. --type
指定具体类型 如:–type container 声明查看容器的元数据
docker inspect --type container 492c91fb2b8ff1a334fcd64ba3e46585701e7e5809f564bc2c65f3a655458db3
[
{
"Id": "492c91fb2b8ff1a334fcd64ba3e46585701e7e5809f564bc2c65f3a655458db3",
"Created": "2022-06-13T09:01:22.321391083Z",
"Path": "docker-entrypoint.sh",
"Args": [
"/bin/sh"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 48552,
"ExitCode": 0,
"Error": "",
"StartedAt": "2022-06-13T09:01:22.584406847Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
...
docker inspect --type image mysql:5.7
[
{
"Id": "sha256:1d7aba9171693947d53f474014821972bf25d72b7d143ce4af4c8d8484623417",
"RepoTags": [
"mysql:5.7"
],
"RepoDigests": [
"mysql@sha256:d9b934cdf6826629f8d02ea01f28b2c4ddb1ae27c32664b14867324b3e5e1291"
],
"Parent": "",
"Comment": "",
"Created": "2021-09-03T07:25:25.419696974Z",
"Container": "9979ac05c87381fb984ce556c94ac87ef0b0209eca50e9a0d81d28756557c2ce",
"ContainerConfig": {
"Hostname": "9979ac05c873",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"3306/tcp": {},
"33060/tcp": {}
},
...
2.3. -s
显示总的文件大小
docker inspect -s 492c91fb2b8ff1a334fcd64ba3e46585701e7e5809f564bc2c65f3a655458db3 | grep Size
"ShmSize": 67108864,
"ConsoleSize": [
"SizeRw": 37,
"SizeRootFs": 448212006,
docker inspect 492c91fb2b8ff1a334fcd64ba3e46585701e7e5809f564bc2c65f3a655458db3 | grep Size
"ShmSize": 67108864,
"ConsoleSize": [
3. docker inspect -f 更多用法
简单地说,-f 的实参是个 Go 模版,并在容器/镜像的元数据上以该 Go 模版作为输入,最终返回模版指定的数
据。Go 模版是一种模板引擎,让数据以指定的模式输出。这个概念对于 Web 开发者是非常熟悉的,Web 领域有
很多模版引擎,比如 Jinga2(用于 Python 和 Flask)、Mustache、JSP 等等,看下面的简单示例:
docker inspect -f "The image's repotags is {{.RepoTags}}" mysql:5.7
The image's repotags is [mysql:5.7]
3.1. Go 模版 详解
模版指令
{{ }} 语法用于处理模版指令,大括号外的任何字符都将直接输出。
上下文
“.” 表示“当前上下文”。大多数情况下表示了容器元数据的整个数据结构,但在某些情况下可以重新规
定上下文,比如使用 with 函数:
docker inspect -f '{{.State.Pid}}' 492c91fb2b8ff1a334fcd64ba3e46585701e7e5809f564bc2c65f3a655458db3
48552
docker inspect -f '{{with .State}} {{.Pid}} {{end}}' 492c91fb2b8ff1a334fcd64ba3e46585701e7e5809f564bc2c65f3a655458db3
48552
可以使用 $ 来获取根上下文,只能获取一级key值
docker inspect -f '{{$.Name}} has pid {{with .State}} {{.Pid}} {{end}}' 492c91fb2b8ff1a334fcd64ba3e46585701e7e5809f564bc2c65f3a655458db3
/silly_antonelli has pid 48552
注意,单独使用 “.” 本身也是可以的,将输出未格式化的完整元数据:
3.2. 数据类型
inspect 数据可以由浮点数、字符串和布尔组成,可以使用 Go 模版内置函数进行比较判断。虽然 Go 模版
支持整数,但目前 inspect 数据中的数值类型都是浮点数,而整数应该对于大多数场景更方便(详见该
Issue)。使用字符串时可以使用双引号。
数据中不存在的值是不可以用来比较的:
docker inspect -f '{{.ExecIDs}}' 492c91fb2b8ff1a334fcd64ba3e46585701e7e5809f564bc2c65f3a655458db3
[]
docker inspect 492c91fb2b8ff1a334fcd64ba3e46585701e7e5809f564bc2c65f3a655458db3 | grep ExecIDs
"ExecIDs": null,
docker inspect -f '{{eq .ExecIDs .ExecIDs}}' 492c91fb2b8ff1a334fcd64ba3e46585701e7e5809f564bc2c65f3a655458db3
Template parsing error: template: :1:2: executing "" at <eq .ExecIDs .ExecIDs>: error calling eq: invalid type for comparison
3.3. 数据结构
inspect 数据使用 map 以及数组保存。Map 结构可以通过 . 的链式来访问 map 内部数据:
docker inspect -f '{{.State.ExitCode}}' 492c91fb2b8ff1a334fcd64ba3e46585701e7e5809f564bc2c65f3a655458db3
0
1、如果需要获取的属性名称包含 “/”(比如下列示例数据)或者以数字开头,则不能直接通过级联调用
获取信息。因为属性名称中的点号会被解析成级联信息,进而导致返回错误结果。即便使用引号将其包含
也会提示语法格式错误。此时,需要通过 index 来读取指定属性信息。前面卷的例子可以这样写:
docker inspect -f '{{.Config.Volumes./var/lib/mysql}}' 492c91fb2b8ff1a334fcd64ba3e46585701e7e5809f564bc2c65f3a655458db3
Template parsing error: template: :1: bad character U+002F '/'
# 双引号也不行
docker inspect -f '{{.NetworkSettings.Ports.3306/tcp}}' 492c91fb2b8ff1a334fcd64ba3e46585701e7e5809f564bc2c65f3a655458db3
Template parsing error: template: :1: unexpected ".3306" in operand
#docker inspect -f '{{.NetworkSettings.Ports."3306/tcp"}}' 492c91fb2b8ff1a334fcd64ba3e46585701e7e5809f564bc2c65f3a655458db3
Template parsing error: template: :1: bad character U+0022 '"'
# 正确写法 !!!注意 index 与之后的数据之间包含空格,与之后双引号括起来的也有空格,否则报错
docker inspect -f '{{index .NetworkSettings.Ports "3306/tcp"}}' 492c91fb2b8ff1a334fcd64ba3e46585701e7e5809f564bc2c65f3a655458db3
<no value>
docker inspect -f '{{index .Config.Volumes "/var/lib/mysql"}}' 492c91fb2b8ff1a334fcd64ba3e46585701e7e5809f564bc2c65f3a655458db3
{}
#报错如下
docker inspect -f '{{index.NetworkSettings.Ports "3306/tcp"}}' 492c91fb2b8ff1a334fcd64ba3e46585701e7e5809f564bc2c65f3a655458db3
Template parsing error: template: :1:2: executing "" at <index>: wrong number of args for index: want at least 1 got 0
2、如果返回结果是一个 map, slice, array 或 string,则可以使用 index 加索引序号(从零开始计数)来
读取属性值
docker inspect -f '{{.HostConfig.ReadonlyPaths}}' 492c91fb2b8ff1a334fcd64ba3e46585701e7e5809f564bc2c65f3a655458db3
[/proc/bus /proc/fs /proc/irq /proc/sys /proc/sysrq-trigger]
docker inspect -f '{{index .HostConfig.ReadonlyPaths 0}}' 492c91fb2b8ff1a334fcd64ba3e46585701e7e5809f564bc2c65f3a655458db3
/proc/bus
# 另一种类型,包含多个键值对的获取
想要获取EndpointID的值:
"NetworkSettings": {
"Bridge": "",
"SandboxID": "a2f0fe86422968b0c5e1d0b7e4dd66a742dedfc8b01b56eb30649449969f4f12",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {
"3306/tcp": null,
"33060/tcp": null
},
"SandboxKey": "/data/docker/exec/netns/a2f0fe864229",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "d41dfa3aadb23af2c459845e9ba11e87a13e7d96e170c879b6b14db76d443168",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.4",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:04",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "9cbe344a6886a489cd1b3d4cef5befc454d477d4c5ac59756d8bdf579739f20a",
"EndpointID": "d41dfa3aadb23af2c459845e9ba11e87a13e7d96e170c879b6b14db76d443168",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.4",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:04",
"DriverOpts": null
}
}
}
docker inspect -f '{{index .NetworkSettings.Networks.bridge 4}}' 492c91fb2b8ff1a334fcd64ba3e46585701e7e5809f564bc2c65f3a655458db3
Template parsing error: template: :1:2: executing "" at <index .NetworkSettings.Networks.bridge 4>: error calling index: value has type int; should be string
docker inspect -f '{{index .NetworkSettings.Networks.bridge "4"}}' 492c91fb2b8ff1a334fcd64ba3e46585701e7e5809f564bc2c65f3a655458db3
<no value>
docker inspect -f '{{index .NetworkSettings.Networks.bridge "EndpointID"}}' 492c91fb2b8ff1a334fcd64ba3e46585701e7e5809f564bc2c65f3a655458db3
d41dfa3aadb23af2c459845e9ba11e87a13e7d96e170c879b6b14db76d443168
3.4. 函数
除了 index 函数,其他很多函数也很常用。比如逻辑函数 and、or 可以返回布尔结果。
注意,函数是不能放在中间:
docker inspect -f '{{true and true}}' 492c91fb2b8ff1a334fcd64ba3e46585701e7e5809f564bc2c65f3a655458db3
Template parsing error: template: :1:2: executing "" at <true>: can't give argument to non-function true
docker inspect -f '{{and true true}}' 492c91fb2b8ff1a334fcd64ba3e46585701e7e5809f564bc2c65f3a655458db3
true
下面是一些常用的比较函数:
eq (等于)
ne (不等于)
lt (小于)
le (小于等于)
gt (大于)
ge (大于等于)
我们可以用这些函数来比较字符串、浮点数或整数:
docker inspect -f '{{and true true}}' 492c91fb2b8ff1a334fcd64ba3e46585701e7e5809f564bc2c65f3a655458db3
true
docker inspect -f '{{eq "abc" "abc"}}' 492c91fb2b8ff1a334fcd64ba3e46585701e7e5809f564bc2c65f3a655458db3
true
docker inspect -f '{{ge 1 3}}' 492c91fb2b8ff1a334fcd64ba3e46585701e7e5809f564bc2c65f3a655458db3
false
docker inspect -f '{{lt 4.5 4.6}}' 492c91fb2b8ff1a334fcd64ba3e46585701e7e5809f564bc2c65f3a655458db3
true
docker inspect -f '{{ne 4.5 4.5}}' 492c91fb2b8ff1a334fcd64ba3e46585701e7e5809f564bc2c65f3a655458db3
false
要注意的是操作数类型必须匹配,数字比较时也需要类型匹配:
docker inspect -f '{{ne 4 4.5}}' 492c91fb2b8ff1a334fcd64ba3e46585701e7e5809f564bc2c65f3a655458db3
Template parsing error: template: :1:2: executing "" at <ne 4 4.5>: error calling ne: incompatible types for comparison
docker inspect -f '{{lt 4.5 4.6}}' 492c91fb2b8ff1a334fcd64ba3e46585701e7e5809f564bc2c65f3a655458db3
true
docker inspect -f '{{gt .State.Pid 1}}' 492c91fb2b8ff1a334fcd64ba3e46585701e7e5809f564bc2c65f3a655458db3
true
docker inspect -f '{{gt .State.Pid 1.0}}' 492c91fb2b8ff1a334fcd64ba3e46585701e7e5809f564bc2c65f3a655458db3
Template parsing error: template: :1:2: executing "" at <gt .State.Pid 1.0>: error calling gt: incompatible types for comparison
比较特殊的是,它支持多个参数进行与比较,此时,它会将第一个参数和其余参数依次比较,返回下式的
结果:
{{if eq true .Var1 .Var2 .Var3}}{{end}}
# 效果等同于:
arg1==arg2 || arg1==arg3 || arg1==arg4
另外,可以使用 json 函数来生成 JSON 输出:
docker inspect -f '{{json .NetworkSettings.Ports}}' 492c91fb2b8ff1a334fcd64ba3e46585701e7e5809f564bc2c65f3a655458db3
{"3306/tcp":null,"33060/tcp":null}
3.5. if 语句
条件语句 if 可以和前面的比较函数一起使用:
docker inspect -f '{{if eq .State.ExitCode 0}} Normal Exit {{else if eq .State.ExitCode 1}} Not a Normal Exit {{else}} Still Not a Normal Exit {{end}}' 492c91fb2b8ff1a334fcd64ba3e46585701e7e5809f564bc2c65f3a655458db3
Normal Exit
优化显示后为:
$ docker inspect -f '{{if eq .State.ExitCode 0}}
Normal Exit
{{else if eq .State.ExitCode 1}}
Not a Normal Exit
{{else}}
Still Not a Normal Exit
{{end}}' 492c91fb2b8ff1a334fcd64ba3e46585701e7e5809f564bc2c65f3a655458db3
Normal Exit //假设ExitCode为0时的结果
注意,{{end}} 语句必须有,else if 和 else 按需使用。
3.6. range迭代数据
range 用于遍历结构内返回值的所有数据。支持的类型包括 array, slice, map 和 channel。
使用要点:
对应的值长度为 0 时,range 不会执行。
结构内部如要使用外部的变量,需要在前面加 引用,比如Var2。
range 也支持 else 操作。效果是:当返回值为空或长度为 0 时执行 else 内的内容。
{{range pipeline}}{{.}}{{end}}
{{range pipeline}}{{.}}{{else}}{{.}}{{end}}
* 查看容器网络下已挂载的所有容器名称,如果没有挂载任何容器,则输出 "With No Containers"
docker inspect --format '{{range .Containers}}{{.Name}}{{println}}{{else}}With No Containers{{end}}' bridge
brtest
peaceful_brown
test
docker inspect --format '{{range .Containers}}{{.Name}}{{println}}{{else}}With No Containers{{end}}' none
With No Containers
1234567891011
3.7. 打印信息
docker --format 默认调用 go语言的 print 函数对模板中的字符串进行输出。
而 go语言还有另外几种相似的内置函数,对比说明如下:
print: 将传入的对象转换为字符串并写入到标准输出中。如果后跟多个参数,输出结果之间会自动填充空格进行分隔。
println: 功能和 print 类似,但会在结尾添加一个换行符。也可以直接使用 {{println}} 来换行。
printf: 与 shell 等环境一致,可配合占位符用于格式化输出。
docker inspect --format '{{.State.Pid}}{{.State.ExitCode}}' $INSTANCE_ID
240390
docker inspect --format '{{print .State.Pid .State.ExitCode}}' $INSTANCE_ID
24039 0
docker inspect --format '{{.State.Pid}}{{println " 从这换行"}}{{.State.ExitCode}}' $INSTANCE_ID
24039 从这换行
0
docker inspect --format '{{printf "Pid:%d ExitCode:%d" .State.Pid .State.ExitCode}}' $INSTANCE_ID
Pid:24039 ExitCode:0
123456789101112
3.8. 管道
管道 即 pipeline ,与 shell 中类似,可以是上下文的变量输出,也可以是函数通过管道传递的返回值。
{{.Con | markdown | addlinks}}
{{.Name | printf "%s"}}
3.9. Docker内置函数
json
Docker 默认以字符串显示返回结果。而该函数可以将结果格式化为压缩后的 json 格式数据。
# 获取 Config 字段对应的 json 数据
docker inspect --format='{{json .Config}}' $INSTANCE_ID
join
用指定的字符串将返回结果连接后一起展示。操作对象必须是字符串数组
# 输出容器配置的所有 Entrypoint 参数,以 " , " 分隔:
docker inspect --format '{{join .Config.Entrypoint " , "}}' $INSTANCE_ID
lower
将返回结果中的字母全部转换为小写。操作对象必须是字符串。
docker inspect --format "{{lower .Name}}" $INSTANCE_ID
upper
将返回结果中的字母全部转换为大写。操作对象必须是字符串。
docker inspect --format "{{lower .Name}}" $INSTANCE_ID
title
将返回结果的首字母转换为大写。操作对象必须是字符串,而且不能是纯数字。
docker inspect --format "{{title .State.Status}}" $INSTANCE_ID
split
使用指定分隔符将返回结果拆分为字符串列表。操作对象必须是字符串且不能是纯数字。
同时,字符串中必须包含相应的分隔符,否则会直接忽略操作。
docker inspect --format '{{split .HostsPath "/"}}' $INSTANCE_ID
3.10. 常用docker inspect --format 输出示例
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2ed603e52896 172.16.60.214:5000/nginx "/bin/sh -c '/usr/..." 13 minutes ago Up 13 minutes docker-test111
24e6607534f1 172.16.60.214:5000/nginx "/bin/sh -c '/usr/..." 13 minutes ago Up 13 minutes docker-test11
19be6b264b6e 172.16.60.214:5000/nginx "/bin/sh -c '/usr/..." 13 minutes ago Up 13 minutes docker-test1
1) 获取容器的IP (后面使用容器名或容器ID都可以)
$ docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -q)
192.10.160.193
173.20.19.128
17.16.10.128
$ docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' docker-test1
17.16.10.128
2) 获取容器的MAC地址
$ docker inspect --format='{{range .NetworkSettings.Networks}}{{.MacAddress}}{{end}}' $(docker ps -a -q)
ee:ee:ee:ee:ee:ee
ee:ee:ee:ee:ee:ee
ee:ee:ee:ee:ee:ee
[root@node1 ~]# docker inspect --format='{{range .NetworkSettings.Networks}}{{.MacAddress}}{{end}}' docker-test1
ee:ee:ee:ee:ee:ee
3) 获取容器Name
$ docker inspect --format='{{.Name}}' $(docker ps -aq)
/docker-test111
/docker-test11
/docker-test1
/calico-node
$ docker inspect --format='{{.Name}}' $(docker ps -aq)|cut -d"/" -f2
docker-test111
docker-test11
docker-test1
$ docker inspect --format='{{.Name}}' docker-test1
/docker-test1
$ docker inspect --format='{{.Name}}' docker-test1|cut -d"/" -f2
docker-test1
4) 获取容器Hostname
$ docker inspect --format '{{ .Config.Hostname }}' $(docker ps -q)
2ed603e52896
24e6607534f1
19be6b264b6e
$ docker inspect --format '{{ .Config.Hostname }}' docker-test1
19be6b264b6e
5) Hostname Name IP
$ docker inspect --format 'Hostname:{{ .Config.Hostname }} Name:{{.Name}} IP:{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -q)
Hostname:2ed603e52896 Name:/docker-test111 IP:192.10.160.193
Hostname:24e6607534f1 Name:/docker-test11 IP:173.20.19.128
Hostname:19be6b264b6e Name:/docker-test1 IP:17.16.10.128
$ docker inspect --format 'Hostname:{{ .Config.Hostname }} Name:{{.Name}} IP:{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' docker-test1
Hostname:19be6b264b6e Name:/docker-test1 IP:17.16.10.128
6) 获取容器的log path
$ docker inspect --format='{{.LogPath}}' `docker ps -a -q`
$ docker inspect --format='{{.LogPath}}' docker-test1
7) 获取容器的image镜像名称
$ docker inspect --format='{{.Config.Image}}' `docker ps -a -q`
172.16.60.214:5000/nginx
172.16.60.214:5000/nginx
172.16.60.214:5000/nginx
quay.io/calico/node:v2.6.10
$ docker inspect --format='{{.Config.Image}}' docker-test1
172.16.60.214:5000/nginx
8) 获取容器绑定的端口(port bindings)
$ docker inspect --format='{{range $p, $conf := .NetworkSettings.Ports}} {{$p}} -> {{(index $conf 0).HostPort}} {{end}}' `docker ps -a -q`
$ docker inspect --format='{{range $p, $conf := .NetworkSettings.Ports}} {{$p}} -> {{(index $conf 0).HostPort}} {{end}}' docker-test1
9) 获取service实例的Ip
$ docker service ps my-test
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
t71gqufekv2o my-test.1 172.16.60.214:5000/nginx:latest swarm-node2 Running Running 16 seconds ago
9cuq2yf10d60 my-test.2 172.16.60.214:5000/nginx:latest swarm-manager-node Running Running 16 seconds ago
srt2yo817kpv my-test.3 172.16.60.214:5000/nginx:latest swarm-node1 Running Running 16 seconds ago
$ docker inspect ` docker service ps my-test -q` --format '{{range .NetworksAttachments}}{{.Addresses}}{{end}}' | cut -d '[' -f2|cut -d ']' -f1
10.255.0.7/16
10.255.0.8/16
10.255.0.9/16
10) 获取service示例的container ID (获取的是ID的全称,一般只要取ID前面12个字符就可以了)
$ docker inspect ` docker service ps my-test -q` --format '{{ .Status.ContainerStatus.ContainerID }}'
c6c18a74a465163757fe928fec9e633223200f92d1c59e5d2d77eabfaa5ae93a
5f558bb014ea3d3eef5c8d4bd70e2e3048d7fc6725538303be960ac658d93b32
dde578bf60190a63ed5c8c4a9f5a3044566a159e8debe8717342e263c6199f26
4. 参考文档
1、Docker教程小白实操入门(19)--如何通过inspect指令查看数据卷的信息_docker inspect --type container-CSDN博客
2、docker inspect -f 详解(查询在主机上的进程pid)-CSDN博客
3、https://ld246.com/article/1427784659823
六、容器服务日志
1. 简介
查看docker日志通常会使用到docker log指令,可以通过指令docker help logs来查看docker log提供
的功能:
Options(可选参数):
–details 显示更多详细的信息
-f, --follow 跟踪实时日志
–since string 显示自某个(时间)timestamp之后的日志,或相对时间,如42m(即42分钟)
–tail string 显示日志末尾后N行, 默认是全部显示
-t, --timestamps 在每行日志前加上timestamp(时间戳)
–until string 显示日志某个时间戳之前的日志,或相对时间,如42m(即42分钟)
2. 常用命令
docker log 提供了根据时间或者时间段查询日志,以及根据某个关键字查询日志的功能,
以下将举例常用日志查看命令:
查看docker容器
docker ps : 列出容器
OPTIONS说明:
- -a :显示所有的容器,包括未运行的。
- -f :根据条件过滤显示的内容。
- –format :指定返回值的模板文件。
- -l :显示最近创建的容器。
- -n :列出最近创建的n个容器。
- –no-trunc :不截断输出。
- -q :静默模式,只显示容器编号。
- -s :显示总的文件大小。
查看容器日志(全部)
docker logs -f 容器ID
查看容器日志,只显示最后100行
docker logs --tail 100 容器ID
查看容器最近三十分钟的日志
docker logs --since 30m 容器ID
查看容器某个时间之后的日志
这里演示的是查询2023年3月3日上午10点13分58秒后的日志
docker logs --since 2023-03-03T10:13:58.655 容器ID
查看容器某个时间段的日志
docker logs --since 2023-03-03T10:13:58.655 --until 2023-03-03T10:13:58.880 容器ID
查看容器日志并显示时间戳
docker logs -t 容器ID
查看容器日志某个时间最近的日志
这里演示的是十天内最新的十行日志信息
docker logs --tail 10 --since 240h 容器
将容器日志写入到文件
这里演示的是将指定容器最后100日志写入error文件中
docker logs --tail 100 容器ID>>error.log
根据某个关键字查询日志
这里演示的是根据error关键字查询日志
docker logs 容器ID | grep error
查询容器某个时间段的日志,并且根据关键字进行查询
这里演示查看容器在2023年3月3日上午10点13分58秒665到880的日志,并根据关键字’
Tomcat started on port’进行筛选
docker logs --since 2023-03-03T10:13:58.655 --until 2023-03-03T10:13:58.880 容器ID | grep ‘Tomcat
started on port’