Docker的/var/run/docker.sock参数

原文地址:Docker的/var/run/docker.sock参数 - 人艰不拆_zmc - 博客园

1、关于数据卷参数/var/run/docker.sock

在创建docker容器时,有时会用到/var/run/docker.sock这样的数据卷参数,例如fluentbit-operator  initContainers容器的数据卷参数带有/var/run/docker.sock:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

initContainers:

      - command:

        - /bin/sh

        - -c

        - set -ex; echo DOCKER_ROOT_DIR=$(docker info -f {{.DockerRootDir}}) > /fluentbit-operator/fluent-bit.env

        image: docker:19.03

        imagePullPolicy: IfNotPresent

        name: setenv

        resources: {}

        terminationMessagePath: /dev/termination-log

        terminationMessagePolicy: File

        volumeMounts:

        - mountPath: /fluentbit-operator

          name: env

        - mountPath: /var/run/docker.sock

          name: dockersock

          readOnly: true

      restartPolicy: Always

      schedulerName: default-scheduler

      securityContext: {}

      serviceAccount: fluentbit-operator

      serviceAccountName: fluentbit-operator

      terminationGracePeriodSeconds: 30

      volumes:

      - emptyDir: {}

        name: env

      - hostPath:

          path: /var/run/docker.sock

          type: ""

        name: dockersock

本文主要介绍数据卷参数/var/run/docker.sock的作用。

2、Docker架构

搞清楚/var/run/docker.sock参数的前提是了解docker的client+server架构,如下是执行docker version命令的结果:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

[root@node1 ~]# docker version

Client: Docker Engine - Community

 Version:           20.10.12

 API version:       1.41

 Go version:        go1.16.12

 Git commit:        e91ed57

 Built:             Mon Dec 13 11:45:41 2021

 OS/Arch:           linux/amd64

 Context:           default

 Experimental:      true

Server: Docker Engine - Community

 Engine:

  Version:          20.10.12

  API version:      1.41 (minimum version 1.12)

  Go version:       go1.16.12

  Git commit:       459d0df

  Built:            Mon Dec 13 11:44:05 2021

  OS/Arch:          linux/amd64

  Experimental:     false

 containerd:

  Version:          1.4.13

  GitCommit:        9cc61520f4cd876b86e77edfeb88fbcd536d1f9d

 runc:

  Version:          1.0.3

  GitCommit:        v1.0.3-0-gf46b6ba

 docker-init:

  Version:          0.19.0

  GitCommit:        de40ad0

可见在服务器上运行的docker由client和server组成,我们输入docker version命令实际上是通过客户端将请求发送到同一台服务器上的Doceker Daemon服务,由Docker Daemon返回信息,客户端收到信息后展示在控制台上,docker的架构图如下:

3、Docker的/var/run/docker.sock参数配置

官方地址:dockerd | Docker Documentation

1

2

3

4

5

Daemon socket option

The Docker daemon can listen for Docker Engine API requests via three different types of Socket: unix, tcp, and fd.

By default, a unix domain socket (or IPC socket) is created at /var/run/docker.sock, requiring either root permission, or docker group membership.

......

可见daemon默认监听的是/var/run/docker.sock这个文件,当你在服务器上安装并且启动好docker,docker daemon 会自动创建一个socket文件并且保存在/var/run/docker.sock目录下。docker daemon监听着socket中即将到来的链接请求(可以通过-H unix:///var/run/docker.sock设定docker daemon监听的socket文件,-H参数还可以设定监听tcp:port或者其它的unix socket),所以docker客户端只要把请求发往这里,daemon就能收到并且做出响应。

按照上面的解释来推理:我们也可以向/var/run/docker.sock发送请求,也能达到docker ps、docker images这样的效果。

4、向Docker Daemon发送请求

为了验证Docker Daemon可以通过/var/run/docker.sock接收请求,我们用curl命令来验证。

1)执行命令查看当前服务器有哪些镜像:

1

curl -s --unix-socket /var/run/docker.sock http:/images/json

此命令可以直接发http请求到Docker Daemon,获取本地镜像列表,等同于在服务器上执行docker images命令,收到的响应是JSON,格式化后如下所示,可见通过/var/run/docker.sock向Docker Daemon发送请求是没有问题的:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

{

  "alert": {

    "alert_name": "gdfgfdfg"

  },

  "resource_filter": {

    "resource_type": "node",

    "rs_type_id": "rst-3m8ZmxVylG90",

    "rs_filter_param": "{\"node_id\":\"zmc-manage-uat-107\"}",

    "_nodes": [

      "zmc-manage-uat-107"

    ],

    "_type": "node"

  },

  "policy": {

    "creator": "admin",

    "rs_type_id": "rst-3m8ZmxVylG90",

    "policy_name": "",

    "policy_description": "",

    "policy_config": "{\"critical\":{\"repeat_type\":\"fixed-minutes\",\"repeat_interval_initvalue\":30,\"max_send_count\":2147483648},\"major\":{\"repeat_type\":\"fixed-minutes\",\"repeat_interval_initvalue\":120,\"max_send_count\":5},\"minor\":{\"repeat_type\":\"not-repeat\",\"repeat_interval_initvalue\":0,\"max_send_count\":1}}",

    "available_start_time": "00:00:00",

    "available_end_time": "23:59:00",

    "language": "zh"

  },

  "rules": [

    {

      "rule_name": "容器组异常率",

      "_config": {

        "monitor_periods": 15,

        "consecutive_count": 3,

        "condition_type": ">",

        "thresholds": "90",

        "severity": "critical",

        "unit": "%",

        "_metricType": "node_pod_abnormal_ratio"

      },

      "monitor_periods": 15,

      "consecutive_count": 3,

      "condition_type": ">",

      "thresholds": "90",

      "severity": "critical",

      "unit": "%",

      "_metricType": "node_pod_abnormal_ratio",

      "metric_id": "mt-lgGwk9n1XYlx"

    }

  ],

  "action": {

    "action_name": "adl-PK2WWL66XRJn",

    "nf_address_list_id": "adl-PK2WWL66XRJn"

  }

}

2)执行以下命令,可以直接发http请求到Docker Daemon,获取运行中的容器列表,等同于docker ps: 

1

curl -s --unix-socket /var/run/docker.sock http:/containers/json

收到的响应是JSON,格式化后如下所示:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

[{

    "Id": "fa3fd1993f864ccd695d50f157883fd1ae948b91bad1ab96da891c73584104d2",

    "Names": ["/es_admin"],

    "Image": "mobz/elasticsearch-head:5",

    "ImageID": "sha256:b19a5c98e43bb87849b71f4389b9ed373f63e8c1fe0fabe2ac5a137497425db2",

    "Command": "/bin/sh -c 'grunt server'",

    "Created": 1622549687,

    "Ports": [{

        "IP": "0.0.0.0",

        "PrivatePort": 9100,

        "PublicPort": 9100,

        "Type": "tcp"

    }],

    "Labels": {},

    "State": "running",

    "Status": "Up 5 seconds",

    "HostConfig": {

        "NetworkMode": "default"

    },

    "NetworkSettings": {

        "Networks": {

            "bridge": {

                "IPAMConfig": null,

                "Links": null,

                "Aliases": null,

                "NetworkID": "a7499f080f7060c80ec68c66e347326df547817bed12f0317e602ec060d75098",

                "EndpointID": "6c29c0bb92596e91e20595dc075e5453515b6aec142fc677d50666cffa2d83bd",

                "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

            }

        }

    },

    "Mounts": []

}]

更多与Docker Daemon交互的请求信息请参考官方文档:Docker Engine API v1.39 Reference 。

至此,我们对docker的client、server架构有了清楚的认识:Docker Daemon相当于一个server,监听来自/var/run/docker.sock的请求,然后做出各种响应,例如返回镜像列表,创建容器。

5、总结

/var/run/docker.sock是docker daemon监听的套接字socket(ip+port),容器中的进程可以通过它与docker daemon通信。

再回到文章开篇处的问题,启动容器时的数据卷参数"/var/run/docker.sock:/var/run/docker.sock"有什么用?

宿主机的/var/run/docker.sock被映射到了容器内,有以下两个作用:

  • 在容器内只要向/var/run/docker.sock发送http请求就能和Docker Daemon通信了,可以做的事情前面已经试过了,官方提供的API文档中有详细说明,镜像列表、容器列表这些统统不在话下;
  • 如果容器内有docker二进制文件,那么在容器内执行docker ps、docker port这些命令,和在宿主机上执行的效果是一样的,虽然容器内和宿主机上的docker二进制可能不同,但是他们的请求发往的是同一个Docker Daemon;

基于以上结论,开篇问题中的fluentbit-operator  initContainers这个容器(使用镜像docker:19.03,通过此镜像可以使用docker客户端命令)用到了数据卷参数/var/run/docker.sock,通过此参数在容器内执行docker相关命令,即执行如下命令查询当前服务器的docker数据盘路径:

1

docker info -f {{.DockerRootDir}}

 参考:docker的/var/run/docker.sock参数_程序员欣宸的博客-CSDN博客_/var/run/docker.sock

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值