“大家好,我是幽灵代笔,这篇文章主要介绍Docker inspect -f(--format)
命令的实战应用,docker --format
其实是提供了基于 Go模板 的日志格式化输出辅助功能,并提供了一些内置的增强函数,这篇文章原文来自博客园 散尽浮华
博主,再次基础上增添了命令场景应用案例。”
上图是大家熟悉的 MVC 框架(Model View Controller): Model(模型,通常在服务端)用于处理数据、View(视图,客户端代码)用于展现结果、Controller(控制器)
用于控制数据流,确保 M 和 V 的同步,即一旦 M 改变,V 也应该同步更新。
而对于 View 端的处理,在很多动态语言中是通过在静态 HTML 代码中插入动态数据来实现的。例如 JSP 的 <%=....=%>
和 PHP 的 <?php.....?>
语法。
由于最终展示给用户的信息大部分是静态不变的,只有少部分数据会根据用户的不同而动态生成。比如,对于 docker ls 的输出信息会根据附加参数的不同而不同,但其表头信息是固定的。所以,将静态信息固化为模板可以复用代码,提高展示效率。
格式: {
{/*注释内容*/}}
$ docker network inspect --format='{
{/*查看容器的默认网关*/}}{
{range .IPAM.Config}}{
{.Gateway}}{
{end}}' $INSTANCE_ID
点号表示当前对象及上下文,和 Java、C++ 中的 this 类似。可以直接通过{
{.}}获取当前对象。
另外,如果返回结果也是一个 Struct 对象(Json 中以花括号/大括号包含),则可以直接通过点号级联调用,获取子对象的指定属性值。
#可以通过级联调用直接读取子对象 State 的 Status 属性,以获取容器的状态信息:
$ docker inspect --format '{
{/*读取容器状态*/}}{
{.State.Status}}' $INSTANCE_ID
注意: 如果需要获取的属性名称包含点号(比如下列示例数据)或者以数字开头,则不能直接通过级联调用获取信息。因为属性名称中的点号会被解析成级联信息,进而导致返回错误结果。即便使用引号将其包含也会提示语法格式错误。此时,需要通过
index
来读取指定属性信息。
"Options": {
"com.docker.network.bridge.default_bridge": "true",
"com.docker.network.bridge.enable_icc": "true",
"com.docker.network.bridge.enable_ip_masquerade": "true",
"com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
"com.docker.network.bridge.name": "docker0",
"com.docker.network.driver.mtu": "1500"
},
# 直接级联调用会提示找不到数据:
$ docker inspect --format '{
{.Options.com.docker.network.driver.mtu}}' bridge
<no value>
# 用引号括起来会提示语法错误:
$ docker inspect --format '{
{.Options."com.docker.network.driver.mtu"}}' bridge
Template parsing error: template: :1: bad character U+0022 '"'
# 正确的用法,必须用 index 读取指定属性名称的属性值:
$ docker inspect --format '{
{/*读取网络在hosts上的名称*/}}{
{index .Options "com.docker.network.bridge.name"}}' bridge
docker0
实例:
$ docker inspect -f '{
{.Id}}' prometheus
9094fdeb64edf75d52189e1b985d0926cf4e6d53880a8f09ab30fc2d6c8a0908
$ docker inspect --format='{
{.Name}}' cadvisor
/cadvisor
$ docker inspect --format='{
{.Name}}' cadvisor |cut -d"/" -f2
cadvisor
$ docker inspect --format='{
{.Name}}' $(docker ps -aq) |cut -d"/" -f2
cadvisor
node_exporter
qingscan
mysqlser
$ docker inspect --format '{
{ .Config.Hostname }}' cadvisor
681a3c5206b1
$ docker inspect --format='{
{.Config.Image}}' cadvisor
google/cadvisor:latest
$ docker inspect -f '{
{.State.Status}}' prometheus
running
$ docker inspect -f '{
{"status:"}}{
{.State.Status}}' prometheus
status:running
$ docker inspect -f '{
{"status:"}}{
{index .State.Status}}' prometheus
status:running
log path
$ docker inspect --format='{
{.LogPath}}' `docker ps -a -q`
/data/docker/containers/681a3c5206b106463a3f4f65a2c44e6ecfe14ff0bc22ee76a153ebdf5e3d4084/681a3c5206b106463a3f4f65a2c44e6ecfe14ff0bc22ee76a153ebdf5e3d4084-json.log
/data/docker/containers/ac80df13976f7cb17ce54768adafdea14a6845c0f7d127b7d146adf52c50c788/ac80df13976f7cb17ce54768adafdea14a6845c0f7d127b7d146adf52c50c788-json.log
/data/docker/containers/6cac92ad7938c33f67f94524ca27caa7c670cb9a19871dcab7af8c6435b557d4/6cac92ad7938c33f67f94524ca27caa7c670cb9a19871dcab7af8c6435b557d4-json.log
/data/docker/containers/e311bdc95cf25fa80962a86e8047b60ec09eabb9db02cbdfa51efd444b3382d2/e311bdc95cf25fa80962a86e8047b60ec09eabb9db02cbdfa51efd444b3382d2-json.log
可以在处理过程中设置自定义变量,然后结合自定义变量做更复杂的处理。 如果自定义变量的返回值是对象,则可以通过点号进一步级联访问其属性。比如 {
{$Myvar.Field1}}
。
# 结合变量的使用,对输出结果进行组装展现,以输出容器的所有绑定端口列表:
$ docker inspect --format '{
{/*通过变量组合展示容器绑定端口列表*/}}已绑定端口列表:{
{println}}{
{range $p,$conf := .NetworkSettings.Ports}}{
{$p}} -> {
{(index $conf 0).HostPort}}{
{println}}{
{end}}' Web_web_1
# 示例输出信息
已绑定端口列表:
80/tcp -> 32770
8081/tcp -> 8081
格式:
{
{
range pipeline}}{
{
.}}{
{
end}}
{
{
range pipeline}}{
{
.}}{
{
else}}{
{
.}}{
{
end}}
range 用于遍历结构内返回值的所有数据。支持的类型包括 array
, slice
, map
和 channel
。使用要点:
查看容器网络下已挂载的所有容器名称,如果没有挂载任何容器,则输出 “With No Containers
”
"NetworkSettings": {
"Bridge": "",
"SandboxID": "a4ae52dfb055599b4b582d4c91f5a38d297bbed30f3e1d698f1c199be572c1e3",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {
"9090/tcp": [
{
"HostIp": "0.0.0.0",
"HostPort": "9090"
}
]
},
"SandboxKey": "/var/run/docker/netns/a4ae52dfb055",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "16dbaea3aef149379a83673284c9adb843dab363246e6eb3255e40b149003580",
"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": "2045baaf0ce3f404298a1a57035b6cc6c91ebd4ee05ce219b818f255c198b44b",
"EndpointID": "16dbaea3aef149379a83673284c9adb843dab363246e6eb3255e40b149003580",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:02"
}
}
}
}
]
实例
$ docker inspect --format='{
{range .NetworkSettings.Networks}}{
{.IPAddress}}{
{end}}' prometheus
172.17.0.2
$ docker inspect --format='{
{range .NetworkSettings.Networks}}{
{.IPAddress}}{
{end}}' $(docker ps -q)
172.17.0.3
172.17.0.2
$ docker inspect --format='{
{range $p, $conf := .NetworkSettings.Ports}} {
{$p}} -> {
{(index $conf 0).HostPort}} {
{end}}' prometheus
9090/tcp -> 9090
$ docker inspect --format='{
{range .NetworkSettings.Networks}}{
{.MacAddress}}{
{end}}' $(docker ps -a -q)
02:42:ac:11:00:03
02:42:ac:11:00:02
02:42:ac:14:00:02
$ docker inspect --format 'Hostname:{
{ .Config.Hostname }} Name:{
{.Name}} IP:{
{range .NetworkSettings.Networks}}{
{.IPAddress}}{
{end}}' $(docker ps -q)
Hostname:681a3c5206b1 Name:/cadvisor IP:172.17.0.3
Hostname:ac80df13976f Name:/node_exporter IP:172.17.0.2
如果返回结果是一个 map, slice, array 或 string,则可以使用 index 加索引序号(从零开始计数)来读取属性值。
$ docker inspect --format='{
{
(index (index .NetworkSettings.Ports "9090/tcp") 0).HostPort}}' prometheus
9090
返回单一参数的布尔否定值,即返回输入参数的否定值。
# 如果容器的 restarting 设置为 false,则返回信息“容器没有配置重启策略”
$ docker inspect --format '{
{if not .State.Restarting}}容器没有配置重启策略{
{end}}' $(docker ps -q)
容器没有配置重启策略
{
{or x y}}
: 表示如果 x 为真返回 x,否则返回 y。{
{or x y z}}
:后面跟多个参数时会逐一判断每个参数,并返回第一个非空的参数。如果都为 false,则返回最后一个参数。示例:
$ docker inspect --format '{
{or .State.Status .State.Restarting}}' $(docker ps -q)
running
判断语句通常需要结合判断条件一起使用,使用格式基本相同:
{
{
if 判断条件 .Var1 .Var2}}{
{
end}}
go模板支持如下判断方式:
eq
: 相等,即 arg1 == arg2。比较特殊的是,它支持多个参数进行与比较,此时,它会将第一个参数和其余参数依次比较,返回下式的结果:{
{
if eq true .Var1 .Var2 .Var3}}{
{
end}}
效果等同于:
arg1==arg2 || arg1==arg3 || arg1==arg4 ...
2) ne: 不等,即 arg1 != arg2。
3) lt: 小于,即 arg1 < arg2。
4) le: 小于等于,即 arg1 <= arg2。
5) gt: 大于,即 arg1 > arg2。
6) ge: 大于等于,即 arg1 >= arg2。
{
{
if pipeline}}{
{
end}}
{
{
if pipeline}}{
{
else}}{
{
if pipeline}}{
{
end}}{
{
end}}
{
{
if pipeline}}{
{
else if pipeline}}{
{
else}}{
{
end}}
# 输出所有已停止的容器名称:
$ docker inspect --format '{
{if ne 0.0 .State.ExitCode}}{
{.Name}}{
{end}}' $(docker ps -aq)
$ docker inspect --format '{
{if ne 0.0 .State.ExitCode}}{
{.Name}}{
{else}}该容器还在运行{
{end}}' $(docker ps -aq)
$ docker inspect --format '{
{if ne 0.0 .State.ExitCode}}{
{.Name}}{
{else if .}}该容器还在运行{
{end}}' $(docker ps -aq)
# 输出所有已停止或配置了 Restarting 策略的容器名称
$ docker inspect --format '{
{if ne 0.0 .State.ExitCode}}{
{.Name}}{
{else if eq .State.Restarting true}}容器{
{.Name}}配置了Restarting策略.{
{else}}{
{end}}' $(docker ps -aq)
docker --format
默认调用 go语言的 print 函数对模板中的字符串进行输出。而 go语言还有另外 2 种相似的内置函数,对比说明如下:
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
管道 即 pipeline
,与 shell 中类似,可以是上下文的变量输出,也可以是函数通过管道传递的返回值。
{
{
.Con | markdown | addlinks}}
{
{
.Name | printf "%s"}}
内置函数 len 返回相应对象的长度
$ docker inspect --format '{
{len .Name}}' prometheus
11
Docker 基于 go模板的基础上,构建了一些内置函数。
Docker 默认以字符串显示返回结果。而该函数可以将结果格式化为压缩后的 json 格式数据。
示例:
$ docker inspect nginx -f '{
{json .State}}' | jq
{
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 23773,
"ExitCode": 0,
"Error": "",
"StartedAt": "2021-08-04T09:27:06.018089509Z",
"FinishedAt": "0001-01-01T00:00:00Z"
}
用指定的字符串将返回结果连接后一起展示。操作对象必须是字符串数组。
# 查看容器的Entrypoint命令
$ docker ps --no-trunc
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
681a3c5206b106463a3f4f65a2c44e6ecfe14ff0bc22ee76a153ebdf5e3d4084 google/cadvisor:latest "/usr/bin/cadvisor -logtostderr" 9 days ago Up 9 days 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp cadvisor
# 输出容器配置的所有 Entrypoint 参数,以 " , " 分隔:
$ docker inspect --format '{
{join .Config.Entrypoint ","}}' cadvisor
/usr/bin/cadvisor,-logtostderr
$ docker inspect --format '{
{join .Config.Entrypoint " "}}' cadvisor
/usr/bin/cadvisor -logtostderr
将返回结果中的字母全部转换为小写。操作对象必须是字符串。
$ docker inspect --format "{
{lower .Name}}" cadvisor
/cadvisor
将返回结果中的字母全部转换为大写。操作对象必须是字符串。
$ docker inspect --format "{
{upper .Name}}" cadvisor
/CADVISOR
将返回结果的首字母转换为大写。操作对象必须是字符串,而且不能是纯数字。
$ docker inspect --format "{
{title .State.Status}}" cadvisor
Running
使用指定分隔符将返回结果拆分为字符串列表。操作对象必须是字符串且不能是纯数字。同时,字符串中必须包含相应的分隔符,否则会直接忽略操作。
$ docker inspect --format '{
{split .HostsPath "/"}}' cadvisor
[ data docker containers 681a3c5206b106463a3f4f65a2c44e6ecfe14ff0bc22ee76a153ebdf5e3d4084 hosts]
“谢谢坚持看能到最后,由于本人能力水平有限,文章或许存在错误、不足,希望大家可以后台留言。最后,本公众号文章的梳理归纳主要目的不仅仅是与大家一起成长、积累知识,而且还有应急之需便于查询。如果觉得对你有帮助,记得收藏,日后为自己的知识库迭代统一归纳,收获会更大奥。”
参考:
文章浏览阅读331次。第一部分:准备工作1 安装虚拟机2 安装centos73 安装JDK以上三步是准备工作,至此已经完成一台已安装JDK的主机第二部分:准备3台虚拟机以下所有工作最好都在root权限下操作1 克隆上面已经有一台虚拟机了,现在对master进行克隆,克隆出另外2台子机;1.1 进行克隆21.2 下一步1.3 下一步1.4 下一步1.5 根据子机需要,命名和安装路径1.6 ..._创建一个hadoop项目
文章浏览阅读1.7k次。心脏滴血漏洞HeartBleed CVE-2014-0160 是由heartbeat功能引入的,本文从深入码层面的分析该漏洞产生的原因_heartbleed代码分析
文章浏览阅读1.4k次。前言ofd是国家文档标准,其对标的文档格式是pdf。ofd文档是容器格式文件,ofd其实就是压缩包。将ofd文件后缀改为.zip,解压后可看到文件包含的内容。ofd文件分析工具下载:点我下载。ofd文件解压后,可以看到如下内容: 对于xml文件,可以用文本工具查看。但是对于印章文件(Seal.esl)、签名文件(SignedValue.dat)就无法查看其内容了。本人开发一款ofd内容查看器,..._signedvalue.dat
文章浏览阅读1.8w次,点赞29次,收藏313次。整体系统设计本设计主要是对ADC和DAC的使用,主要实现功能流程为:首先通过串口向FPGA发送控制信号,控制DAC芯片tlv5618进行DA装换,转换的数据存在ROM中,转换开始时读取ROM中数据进行读取转换。其次用按键控制adc128s052进行模数转换100次,模数转换数据存储到FIFO中,再从FIFO中读取数据通过串口输出显示在pc上。其整体系统框图如下:图1:FPGA数据采集系统框图从图中可以看出,该系统主要包括9个模块:串口接收模块、按键消抖模块、按键控制模块、ROM模块、D.._基于fpga的信息采集
文章浏览阅读2.5w次。1.背景错误信息:-- [http-nio-9904-exec-5] o.s.c.n.z.filters.post.SendErrorFilter : Error during filteringcom.netflix.zuul.exception.ZuulException: Forwarding error at org.springframework.cloud..._com.netflix.zuul.exception.zuulexception
文章浏览阅读358次。1.介绍图的相关概念 图是由顶点的有穷非空集和一个描述顶点之间关系-边(或者弧)的集合组成。通常,图中的数据元素被称为顶点,顶点间的关系用边表示,图通常用字母G表示,图的顶点通常用字母V表示,所以图可以定义为: G=(V,E)其中,V(G)是图中顶点的有穷非空集合,E(G)是V(G)中顶点的边的有穷集合1.1 无向图:图中任意两个顶点构成的边是没有方向的1.2 有向图:图中..._给定一个邻接矩阵未必能够造出一个图
文章浏览阅读321次。(十二)、WDS服务器安装通过前面的测试我们会发现,每次安装的时候需要加域光盘映像,这是一个比较麻烦的事情,试想一个上万个的公司,你天天带着一个光盘与光驱去给别人装系统,这将是一个多么痛苦的事情啊,有什么方法可以解决这个问题了?答案是肯定的,下面我们就来简单说一下。WDS服务器,它是Windows自带的一个免费的基于系统本身角色的一个功能,它主要提供一种简单、安全的通过网络快速、远程将Window..._doc server2012上通过wds+mdt无人值守部署win11系统.doc
文章浏览阅读219次。python–xlrd/xlwt/xlutilsxlrd只能读取,不能改,支持 xlsx和xls 格式xlwt只能改,不能读xlwt只能保存为.xls格式xlutils能将xlrd.Book转为xlwt.Workbook,从而得以在现有xls的基础上修改数据,并创建一个新的xls,实现修改xlrd打开文件import xlrdexcel=xlrd.open_workbook('E:/test.xlsx') 返回值为xlrd.book.Book对象,不能修改获取sheett_xlutils模块可以读xlsx吗
文章浏览阅读8.2w次,点赞267次,收藏656次。运行Selenium出现'WebDriver' object has no attribute 'find_element_by_id'或AttributeError: 'WebDriver' object has no attribute 'find_element_by_xpath'等定位元素代码错误,是因为selenium更新到了新的版本,以前的一些语法经过改动。..............._unresolved attribute reference 'find_element_by_id' for class 'webdriver
文章浏览阅读198次。一:模态窗口//父页面JSwindow.showModalDialog(ifrmehref, window, 'dialogWidth:550px;dialogHeight:150px;help:no;resizable:no;status:no');//子页面获取父页面DOM对象//window.showModalDialog的DOM对象var v=parentWin..._jquery获取父window下的dom对象
文章浏览阅读1.7w次,点赞15次,收藏129次。算法(algorithm)是解决一系列问题的清晰指令,也就是,能对一定规范的输入,在有限的时间内获得所要求的输出。 简单来说,算法就是解决一个问题的具体方法和步骤。算法是程序的灵 魂。二、算法的特征1.可行性 算法中执行的任何计算步骤都可以分解为基本可执行的操作步,即每个计算步都可以在有限时间里完成(也称之为有效性) 算法的每一步都要有确切的意义,不能有二义性。例如“增加x的值”,并没有说增加多少,计算机就无法执行明确的运算。 _算法
文章浏览阅读1.5k次,点赞18次,收藏26次。网络安全的标准和规范是网络安全领域的重要组成部分。它们为网络安全提供了技术依据,规定了网络安全的技术要求和操作方式,帮助我们构建安全的网络环境。下面,我们将详细介绍一些主要的网络安全标准和规范,以及它们在实际操作中的应用。_网络安全标准规范