通过SSH协议与DockerDaemon通信

简介: Docker系列

本文阐述如何通过SSH协议与Docker Daemon通信。

Docker客户端通常通过Unix套接字在本地与守护程序通信 /var/run/docker.sock,或通过网络通过TCP套接字。 以下是启动时提供给Docker守护程序的选项的典型示例:

# ssh root@123.57.79.224
Last login: Mon Mar 23 00:35:48 2020 from 111.199.154.70
  Welcome to Qiniu Cloud Elastic Compute Service !

[root@iZ2zebzqqnls3u8zisdw00Z ~]# ps -ef |grep dockerd
root     23438     1  0 00:41 ?        00:00:03 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
root     24354 24336  0 08:15 pts/0    00:00:00 grep --color=auto dockerd

Docker的客户端和服务端通信有三种方式

  • -H unix:// 指的是Docker使用本地的unix套接字/var/run/docker.sock进行通信
  • -H tcp://0.0.0.0:2376使守护程序可以通过端口2376上的任何网络接口使用。需要在安全组中打开此端口(并且,如果可能的话,请将该端口限制为IP地址白名单),以便远程客户端可以访问守护程序,为了安全起见,一般不建议开启。
  • -H fd:// 这是在systemd内部运行Docker是使用的远程通信方式,由systemd创建套接字并激活Docker守护进程。

如何通过ssh协议远程操作Docker服务

由于SSH被广泛使用,并且通常是默认情况下允许的协议之一,因此直接通过SSH访问Docker守护程序可能很方便。Docker 18.09使这成为可能,下面进行一下。

  1. 准备一个安装好版本在18.09或者更新的Docker服务
curl -s https://get.docker.com | sh
systemctl enable --now docker.service
ps -ef |grep dockerd | egrep -v grep
root     23438     1  0 00:41 ?        00:00:06 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
  1. 然后创建一个私钥,用于无密访问远程主机
ssh-keygen -t rsa
  1. 使用Docker -H通过ssh协议操作远程主机上的Docker
docker -H ssh://root@123.57.79.224 run hello-world

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/

For more examples and ideas, visit:
https://docs.docker.com/get-started/

现在就有了4种远程访问Docker的方式了,但是前面三种你还记得如何使用的吗?

回顾如何通过tcp/fd/unix远程访问Docker

-H fd://如何使用

每次安装完Docker服务之后,在systemd文件中都会发现-H fd:// 这究竟是什么意思呢?我们是否能通过fd://的方式进行访问docker daemon,测试一下:

  1. 先停下Docker服务
systemctl stop docker
  1. 查看是否有Docker的进程
# ps aux | grep 'docker' | egrep -v grep
lsof -Ua | grep 'docker' | egrep -v grep
  1. 启动docker.socket
# systemctl start docker.socket
# ps aux | grep 'docker' | egrep -v grep
# lsof -Ua | grep 'docker' | egrep -v grep
systemd       1    root   29u  unix 0xffff88022d286800      0t0 118203 /var/run/docker.sock

启动之后docker.socket,我们可以看到仍然没有docker进程在运行,但是套接字/var/run/docker.sock已经创建,它属于该进程systemd,实际上,套接字现在已经准备好接收请求,即使docker尚未运行。systemd将docker.service在第一个请求到来时启动,将已创建的套接字传递给Docker

  1. 开始 docker.service
# systemctl start docker.service
# ps aux | grep 'docker' | egrep -v grep
root     25748  3.3  0.8 580192 71484 ?        Ssl  09:19   0:00 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

Docker现在正在运行.

  1. 现在我们将docket.socket和docker.service停止掉,然后手动使用fd://启动docker
# systemctl stop docker.socket
# systemctl stop docker.service
# ps aux | grep 'docker' | egrep -v grep
# lsof -Ua | grep 'docker' | egrep -v grep
# /usr/bin/dockerd -H fd://
INFO[2020-03-23T09:21:21.010104928+08:00] Starting up
failed to load listeners: no sockets found via socket activation: make sure the service was started by systemd

​ 当使用时-H fd://,docker将期望套接字通过其父进程传递,而不是自己创建。由Systemd启动时, Systemd会执行此工作,但是在终端上手动启动时,您不会执行此工作,因此docker守护进程失败并中止。

-H tcp://ip:port如何使用
  1. 我们查看一下docker.service的位置,然后增加一个tcp访问方式
# diff /usr/lib/systemd/system/docker.service /usr/lib/systemd/system/docker.service.bak
14c14
< ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:8888 -H fd:// --containerd=/run/containerd/containerd.sock
.> ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
  1. 重启查看是否添加成功
systemctl daemon-reload
systemctl restart docker.service
# ps aux | grep 'docker' | egrep -v grep
root     26277  0.7  0.8 449120 69460 ?        Ssl  09:29   0:00 /usr/bin/dockerd -H tcp://0.0.0.0:8888 -H fd:// --containerd=/run/containerd/containerd.sock
  1. 在添加成功之后,我们在通过tcp和fd的方式远程尝试一下:
# docker -H fd://192.168.0.230:8888 ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
# docker -H tcp://192.168.0.230:8888 ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
  1. 所以你明白了吗?但是为了安全起见,不建议开启docker的tcp端口,或者对Docker远程访问开启证书安全访问,不然你会摊上事儿的。
  2. 然后我们在恢复一下现场。😆
-H unix:// 如何使用
  1. 首先准备一个nginx镜像
docker pull nginx
  1. 使用unix套接字创建一个nginx容器
# curl -XPOST --unix-socket /var/run/docker.sock -d '{"Image":"nginx"}' -H 'Content-Type: application/json' http://localhost/containers/create
{"Id":"c4a739ff6d6ba66e80be9a669aa9ce7cf0044b524e0606433e09810b4cc084de","Warnings":[]}
  1. 通过返回的容器ID,启动该容器
# curl -XPOST --unix-socket /var/run/docker.sock http://localhost/containers/c4a739ff6d6ba66e80be9a669aa9ce7cf0044b524e0606433e09810b4cc084de/start
# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS               NAMES
c4a739ff6d6b        nginx               "nginx -g 'daemon of…"   About a minute ago   Up 13 seconds       80/tcp              reverent_edison
  1. 我们也可以通过unix套接字监听Docker的事件:
# curl --unix-socket /var/run/docker.sock http://localhost/events
"status":"create","id":"c4a739ff6d6ba66e80be9a669aa9ce7cf0044b524e0606433e09810b4cc084de","from":"nginx","Type":"container","Action":"create","Actor":{"ID":"c4a739ff6d6ba66e80be9a669aa9ce7cf0044b524e0606433e09810b4cc084de","Attributes":{"image":"nginx","maintainer":"NGINX Docker Maintainers \u003cdocker-maint@nginx.com\u003e","name":"reverent_edison"}},"scope":"local","time":1584924907,"timeNano":1584924907738224502}
{"Type":"network","Action":"connect","Actor":{"ID":"8ca197c838f66decc5fc79996f78021597d928a26c0d011984416a6c9616a315","Attributes":{"container":"c4a739ff6d6ba66e80be9a669aa9ce7cf0044b524e0606433e09810b4cc084de","name":"bridge","type":"bridge"}},"scope":"local","time":1584924984,"timeNano":1584924984914048199}
{"status":"start","id":"c4a739ff6d6ba66e80be9a669aa9ce7cf0044b524e0606433e09810b4cc084de","from":"nginx","Type":"container","Action":"start","Actor":{"ID":"c4a739ff6d6ba66e80be9a669aa9ce7cf0044b524e0606433e09810b4cc084de","Attributes":{"image":"nginx","maintainer":"NGINX Docker Maintainers \u003cdocker-maint@nginx.com\u003e","name":"reverent_edison"}},"scope":"local","time":1584924985,"timeNano":1584924985130585919}

好了。万字长文书写到此,你学到了吗?

相关文章
|
4月前
|
移动开发 监控 安全
通过SSH协议实现的屏幕局域网电脑监控:屏幕安全访问代码
随着科技的不断发展,网络安全问题愈发突出。为了确保屏幕数据的安全,我们需要一种高效可靠的监控方法。本文介绍了一种基于SSH协议的屏幕局域网电脑监控方案,同时提供了相关代码示例,确保屏幕数据的安全传输和访问。
242 0
|
安全 网络安全 C++
基于Windows下VSCode安装及安装相关插件通过SSH协议远程连接服务器详细方法(一)
基于Windows下VSCode安装及安装相关插件通过SSH协议远程连接服务器详细方法
348 0
基于Windows下VSCode安装及安装相关插件通过SSH协议远程连接服务器详细方法(一)
|
1月前
|
安全 算法 Linux
SSH协议的原理和使用:深入剖析SSH协议的原理和使用方法
SSH协议的原理和使用:深入剖析SSH协议的原理和使用方法
74 0
|
1月前
|
存储 弹性计算 算法
SSH学习(三)- SSH协议中的Public Key Algorithm
在SSH协议中,有两个地方涉及到公钥算法,分别是: 1. 服务端认证:服务端在进行密钥协商的时候证明自己身份,防止中间人攻击,此时为SSH-TRANS协议发生的事情; 2. 客户端认证:客户端通过PublicKey方式证明自己身份,完成SSH登录认证,此时SSH-USERAUTH发生的事情; 这两种情况下的公钥算法使用的是同一个概念,接下来本文将主要基于PublicKey公钥认证方式,学习对应的内容。
44 1
SSH学习(三)- SSH协议中的Public Key Algorithm
|
3月前
|
安全 Shell 网络安全
远程登录安全连接协议SSH(Secure Shell)
SSH(Secure Shell)协议是一种用于在不安全网络上提供安全远程登录、命令执行和数据传输的加密网络协议,通过公钥加密和身份验证技术确保通信的安全性和隐私性。
89 0
|
20天前
|
存储 网络安全 开发工具
Git的GUI图形化工具&ssh协议&IDEA集成Git
Git的GUI图形化工具&ssh协议&IDEA集成Git
111 0
|
4月前
|
Shell 网络安全 开发工具
git02->gui图形化界面使用,ssh协议,idea集成GIT
git02->gui图形化界面使用,ssh协议,idea集成GIT
51 0
git02->gui图形化界面使用,ssh协议,idea集成GIT
|
4月前
|
安全 网络安全 开发工具
更安全的ssh协议与Gui图形化界面使用
更安全的ssh协议与Gui图形化界面使用
|
4月前
|
安全 网络安全 开发工具
【Git】gui图形化界面的使用、ssh协议以及idea集成Git
【Git】gui图形化界面的使用、ssh协议以及idea集成Git
62 0
|
5月前
|
网络安全 开发工具 数据安全/隐私保护
【Git】Git使用Gui图形化界面,Git中SSH协议,Idea集成Git(下)
【Git】Git使用Gui图形化界面,Git中SSH协议,Idea集成Git
43 0