Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Docker 远程连接 -- dockerd 命令详解

Docker 远程连接 -- dockerd 命令详解

作者头像
康怀帅
发布于 2018-02-28 08:15:21
发布于 2018-02-28 08:15:21
24.7K20
代码可运行
举报
文章被收录于专栏:康怀帅的专栏康怀帅的专栏
运行总次数:0
代码可运行

配置 TLS 实现安全的 Docker 远程连接。

GitHubhttps://github.com/khs1994-docker/dockerd-tls

本机:macOS

远程机:使用 VirtualBox 虚拟 CoreOS (IP 192.168.57.110)

目标:能在 macOS 远程操作 CoreOS。(注意不是 SSH 远程登录)。dockerd 命令仅能在 Linux 下使用。

官方文档:https://docs.docker.com/edge/engine/reference/commandline/dockerd/

官方文档:https://docs.docker.com/engine/admin/

本文适合有一定 Linux 基础的读者阅读,如果出现错误,请将各种操作之前修改过的文件恢复原状并删除新增的环境变量。

我们已经知道 Docker 是客户端/服务端架构。一般情况下我们使用的 Docker 客户端/服务端都在本机(macOS、Windows 实际上是在本机启动了一个虚拟机,这里指 Linux)。本文所指的情况是 Docker 客户端与服务端不在同一主机上。

Dokcer 架构

Typically, you start Docker using operating system utilities. For debugging purposes, you can start Docker manually using the dockerd command. You may need to use sudo, depending on your operating system configuration. When you start Docker this way, it runs in the foreground and sends its logs directly to your terminal.

非安全的连接方式

先介绍 非安全 的连接方式。

服务端配置

CoreOS 请使用第二种方法,其他 Linux 系统配置时选择以下两种方法之一

通常的配置方法

docker.servicedockerd-H 参数不能与 daemon.json 中的 hosts 键值对冲突。(其他参数同理)

新建 /etc/systemd/system/docker.service.d/docker.conf 文件。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd

/etc/docker/daemon.json (下文统一简称 daemon.json)中写入以下内容

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
  "hosts":[
    "unix:///var/run/docker.sock",
    "tcp://0.0.0.0:2375"
  ]
}

该文件必须符合 json 规范写法,否则 Docker 将不能启动。

重新启动 Docker。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ sudo systemctl daemon-reload
$ sudo systemctl restart docker

CoreOS 官方文档提供的方法

官方文档:https://coreos.com/os/docs/latest/customizing-docker.html

新建 /etc/systemd/system/docker-tcp.socket 文件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[Unit]
Description=Docker Socket for the API

[Socket]
# ListenStream=127.0.0.1:2375
ListenStream=2375
BindIPv6Only=both
Service=docker.service

[Install]
WantedBy=sockets.target

重新启动服务

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ sudo systemctl daemon-reload
$ sudo systemctl enable docker-tcp.socket
$ sudo systemctl stop docker
$ sudo systemctl start docker-tcp.socket
$ sudo systemctl start docker

注意:这种方法必须先启动 docker-tcp.socket,再启动 Docker,一定要注意启动顺序!

systemd socket 详情请查看:http://www.jinbuguo.com/systemd/systemd.socket.html

在客户端测试连接

macOS (下文中 macOS一律代指 Docker 客户端)上使用以下命令

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ docker -H 192.168.57.110:2375 info

成功输出信息,证明客户端可以成功连接到远程的服务端。

macOS 上远程操作 CoreOS 上的 Docker 每次执行命令时必须加上 -H 参数(这样太麻烦,我们可以通过将 Docker 命令 参数 配置成 环境变量 来简化命令)。

macOS 上执行如下命令。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ export DOCKER_HOST="tcp://0.0.0.0:2375"

$ docker info

这里写入的变量是临时生效的,重新登录环境变量就消失了(下文同理,之后不再赘述),让环境变量永久生效请写入 ~/.bashrc

fish shell

本人 macOS 上使用的 shell 是 fish,这里记录一下 fish 中的操作,使用 bash 的读者请忽略 fish 相关内容。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ set -Ux DOCKER_HOST "tcp://0.0.0.0:2375"

# 以上命令写入的环境变量是永久存在的,通过以下命令删除环境变量

$ set -Ue DOCKER_HOST

配置安全连接

官方文档:https://docs.docker.com/engine/security/https/

上面我们配置的远程连接是不安全的,只能用于测试环境中。在生产环境中需要配置 TLS 安全连接,只有拥有密钥的客户端,才能连接到远程的服务端。

服务端配置

只能使用 Linux 下的 openssl 生成密钥,macOS 下的不可以。在 CoreOS 下执行以下操作

手动执行命令生成证书(不推荐)

这一步较复杂,你可以跳过这一方法,使用容器生成证书。此方法来自 Docker 官方文档 https://docs.docker.com/engine/security/https/。

文件总览

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
├── ca-key.pem       # 妥善保管,连接时用不到
├── ca.pem           # clent & server
├── ca.srl           # 用不到
├── cert.pem         # client
├── client.csr       # 请求文件
├── extfile.cnf      # 配置文件
├── key.pem          # client
├── server-cert.pem  # server
├── server.csr       # 请求文件
└── server-key.pem   # server
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 生成 CA 私钥

$ openssl genrsa -aes256 -out ca-key.pem 4096

# 需要输入两次密码(自定义)

# 生成 CA 公钥

$ openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem

# 输入上一步中设置的密码,然后需要填写一些信息

# 下面是服务器证书生成

# 生成服务器私钥

$ openssl genrsa -out server-key.pem 4096

# 用私钥生成证书请求文件

$ openssl req -subj "/CN=localhost" -sha256 -new -key server-key.pem -out server.csr

$ echo subjectAltName = DNS:localhost,DNS:www.khs1994.com,DNS:tencent,IP:192.168.199.100,IP:192.168.57.110,IP:127.0.0.1 >> extfile.cnf

# 允许服务端哪些 IP 或 host 能被客户端连接,下文会进行测试。

# DNS 我也不是很理解,这里配置 localhost ,公共 DNS 解析的域名,/etc/hosts 文件中的列表进行测试。

$ echo extendedKeyUsage = serverAuth >> extfile.cnf

# 用 CA 来签署证书

$ openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem \
  -CAcreateserial -out server-cert.pem -extfile extfile.cnf

# 再次输入第一步设置的密码

# 下面是客户端证书文件生成

# 生成客户端私钥

$ openssl genrsa -out key.pem 4096

# 用私钥生成证书请求文件  

$ openssl req -subj '/CN=client' -new -key key.pem -out client.csr

$ echo extendedKeyUsage = clientAuth >> extfile.cnf

# 用 CA 来签署证书

$ openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem \
  -CAcreateserial -out cert.pem -extfile extfile.cnf

# 再次输入第一步设置的密码

# 删除文件,更改文件权限

$ rm -v client.csr server.csr

$ chmod -v 0400 ca-key.pem key.pem server-key.pem

$ chmod -v 0444 ca.pem server-cert.pem cert.pem

ca.pem server-cert.pem server-key.pem 三个文件移动到 /etc/docker/ 文件夹中。

使用容器生成证书(推荐)

GitHub:https://github.com/khs1994-docker/dockerd-tls

方法来自 CoreOS 官方文档:https://coreos.com/os/docs/latest/generate-self-signed-certificates.html

既然使用容器那就可以在任何系统运行,只要把生成的证书文件对应的放到 Docker 客户端和服务端即可。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ git clone --depth=1 https://github.com/khs1994-docker/dockerd-tls.git
$ cd dockerd-tls

./cfssl/*.json 中配置好 CN hosts

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ docker-compose up cfssl

命令执行完毕之后在 ./cfssl/cert 文件夹中可以看到证书文件,修改文件权限。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ chmod -v 0400 ca-key.pem key.pem server-key.pem

$ chmod -v 0444 ca.pem server-cert.pem cert.pem

ca.pem server-cert.pem server-key.pem 三个文件移动到服务端 /etc/docker/ 文件夹中。

CoreOS 请使用第二种方法,其他 Linux 系统根据上文选择的方法,这里选择对应的方法

通常的配置方法

修改 daemon.json 文件。

注意:非安全连接使用的是 2375 端口,安全连接使用的是 2376 端口。当然这是推荐的端口配置,你可以配置任何端口!

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
  "tlsverify": true,
  "tlscert": "/etc/docker/server-cert.pem",
  "tlskey": "/etc/docker/server-key.pem",
  "tlscacert": "/etc/docker/ca.pem",
  "hosts":[
    "unix:///var/run/docker.sock",
    "tcp://0.0.0.0:2376"
  ]
}

重新启动 Docker

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ sudo systemctl restart docker

CoreOS 官方文档的方法

首先需要修改 /etc/systemd/system/docker-tcp.socket 文件内容

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ListenStream=2375

# 修改为

ListenStream=2376

修改 CoreOS 上的 daemon.json 文件。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
  "tlsverify": true,
  "tlscert": "/etc/docker/server-cert.pem",
  "tlskey": "/etc/docker/server-key.pem",
  "tlscacert": "/etc/docker/ca.pem"
}

重新启动服务。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ sudo systemctl daemon-reload
$ sudo systemctl stop docker
$ sudo systemctl restart docker-tcp.socket
$ sudo systemctl restart docker

上文已经提到了启动顺序,这里提示一下,不再赘述。

客户端远程安全连接

ca.pem cert.pem key.pem 三个文件通过 scp 下载到 macOS

macOS 执行以下命令,密钥路径请根据实际情况填写。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ docker --tlsverify \
  --tlscacert=/Users/khs1994/test/ca.pem \
  --tlscert=/Users/khs1994/test/cert.pem \
  --tlskey=/Users/khs1994/test/key.pem \
  -H=192.168.57.110:2376 \
  info

把密钥放入 ~/.docker 文件夹中

每次操作需要跟那么多参数,太麻烦了。我们可以把 ca.pem cert.pem key.pem 三个文件放入客户端 ~/.docker 中,然后配置环境变量就可以简化命令了。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ export DOCKER_HOST=tcp://192.168.57.110:2376 DOCKER_TLS_VERIFY=1

$ docker info

你也可以选择其他路径,请通过环境变量 DOCKER_CERT_PATH 指定。

报错详情

不使用安全连接
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ docker -H 192.168.57.110:2376 info
Get http://192.168.57.110:2376/v1.34/containers/json?all=1: malformed HTTP response "\x15\x03\x01\x00\x02\x02".
* Are you trying to connect to a TLS-enabled daemon without TLS?
在非允许列表 IP 中登录

假如远程服务器还有一个 IP 10.141.20.83 ,现在我们尝试使用这个 IP 作为服务端地址,看看客户端能否连接到。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ docker -H 10.141.20.83:2376 info
error during connect: Get https://10.141.20.83:2376/v1.34/info: x509: certificate is valid for 192.168.57.110, 192.168.199.100, 127.0.0.1, not 10.141.20.83
在非允许列表 Host 中登录
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ docker -H localhost:2376 info
error during connect: Get https://localhost:2375/v1.34/info: x509: certificate is valid for coreos1, not localhost

fish shell

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ set -Ux DOCKER_HOST tcp://192.168.57.110:2376
$ set -Ux DOCKER_TLS_VERIFY 1

# 以上命令写入环境变量是永久存在的,通过以下命令删除环境变量

$ set -Ue DOCKER_HOST ; set -Ue DOCKER_TLS_VERIFY

服务端验证模式

  • tlsverify, tlscacert, tlscert, tlskey set: Authenticate clients
  • tls, tlscert, tlskey: Do not authenticate clients

客户端验证模式

  • tls: Authenticate server based on public/default CA pool
  • tlsverify, tlscacert: Authenticate server based on given CA
  • tls, tlscert, tlskey: Authenticate with client certificate, do not authenticate server based on given CA
  • tlsverify, tlscacert, tlscert, tlskey: Authenticate with client certificate and authenticate server based on given CA

测试远程构建 Docker 镜像

macOS 新建 demo 文件夹并进入。

我们首先建一个文本文件 test.txt

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
hello!

然后新建一个简单的 Dockerfile 文件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
FROM busybox

COPY ./test.txt /

CMD cat /test.txt

按照前面的方法设置好环境变量,这里不再赘述。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ docker -H 192.168.57.110:2375 --tlsverify build -t khs1994/busybox .

在远程服务端查看

SSH 登录到 CoreOS(这里为了便于理解,SSH 到远程服务器操作)。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ docker image ls
REPOSITORY                             TAG                 IMAGE ID            CREATED             SIZE
khs1994/busybox                        latest              368d23df8500        10 seconds ago      1.13MB

我们已经查看到了镜像。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ docker run -it --rm khs1994/busybox
hello!

运行成功。

客户端恢复原状

你如果想在 macOS 操作本地的服务端,请将上面配置的环境变量删除,这里不再赘述。

More Information

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017-10-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
2 条评论
热度
最新
你好!开启远程2376,能禁用本地连接吗?还有能配置客户端IP白名单吗?
你好!开启远程2376,能禁用本地连接吗?还有能配置客户端IP白名单吗?
回复回复点赞举报
容器生成证书搞不了,那个git地址是假的
容器生成证书搞不了,那个git地址是假的
回复回复点赞举报
推荐阅读
编辑精选文章
换一批
TLS加密远程连接Docker
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
程序员欣宸
2019/09/18
2.2K0
TLS加密远程连接Docker
centos7/6.9 docker-ce-17/1.7.1使用证书登陆(openssl tls)
出现 Error response from daemon: client is newer than server (client API version: 1.24, server API version: 1.19)
全栈程序员站长
2021/05/19
2960
Linux开启Docker远程访问并设置安全访问(证书密钥),附一份小白一键设置脚本哦!
找到 Service节点,修改ExecStart属性,增加 -H tcp://0.0.0.0:2375
JanYork_简昀
2023/02/02
4.8K0
Linux开启Docker远程访问并设置安全访问(证书密钥),附一份小白一键设置脚本哦!
Docker启用TLS进行安全配置
之前开启了docker的2375 Remote API,接到公司安全部门的要求,需要启用授权,翻了下官方文档
JadePeng
2019/08/14
9220
docker remote api 加密
1. 设置主机名 编辑/etc/hostname,服务器主机名 zouyujie.top
用户9347382
2022/01/10
6190
这就是你日日夜夜想要的docker!!!---------TLS加密远程连接Docker
作为一款应用 Docker 本身实现上会有代码缺陷。CVE官方记录 Docker 历史版本共有超过20项漏洞。 黑客常用的攻击手段主要有代码执行、权限提升、信息泄露、权限绕过等。目前 Docker版本更迭非常快,Docker 用户最好将 Docker 升级为最新版本。
不吃小白菜
2020/09/28
8160
这就是你日日夜夜想要的docker!!!---------TLS加密远程连接Docker
Docker开启远程安全访问
找到 Service 节点,修改 ExecStart 属性,增加 -H tcp://0.0.0.0:2375
niceyoo
2020/07/09
10K0
在Ubuntu16.10上开启docker17.03.0-ce的https认证
$ openssl genrsa -aes256 -out ca-key.pem 4096
cn華少
2018/09/11
3760
CoreOS配置Docker API TLS认证 顶
我们经常会利用Portainer来管理docker环境,也经常会用Jenkins来自动构建和部署docker,远程管理都会使用到Docker API,通常我们只是开启了没有安全保护的2375(通常)端口,这个比较危险,会导致远程劫持攻击。那么我们就需要配置TLS认证的2376(通常)端口。
bdcn
2018/09/12
2.6K0
CoreOS配置Docker API TLS认证
                                                    顶
04. Idea集成Docker
上一节中,我们介绍了Dockerfile的方式构建自己的镜像。但是在实际开发过程中,一般都会和开发工具直接集成,如Idea。今天就介绍下idea和Docker如何集成。
有一只柴犬
2023/08/24
5240
04. Idea集成Docker
Docker暴露2375端口,引起安全漏洞
前几天有小伙伴发现Docker暴露出2375端口,引起了安全漏洞。我现在给大家介绍整个事情的来龙去脉,并告诉小伙伴们,怎么修复这个漏洞。
全栈程序员站长
2022/09/05
3.6K0
Docker暴露2375端口,引起安全漏洞
Docker服务开放了这个端口,服务器分分钟变肉机!
Docker为了实现集群管理,提供了远程管理的端口。Docker Daemon作为守护进程运行在后台,可以执行发送到管理端口上的Docker命令。
macrozheng
2020/08/13
1.6K0
docker开启api访问,配置双向证书验证
Docker是一种容器化技术,可通过容器化技术提供的API进行访问和管理。您可以通过配置Docker API来开启对Docker API的访问,并使用双向证书验证确保通信的安全性。以下是配置Docker API以开启访问和双向证书验证的步骤:
堕落飞鸟
2023/03/31
1.8K0
Docker开启TLS和CA认证
前言:Docker直接开启2375端口是不安全的,别人只要连上之后就可以任意操作,下面是开启Docker的TLS和CA认证方法,并使用Jenkins和Portainer连接。 一、生成证书 查看服务器主机名 hostname [image-20210826174816658] 安装生成证书软件 yum install -y openssl [image-20210827003357785] 编写一键启动脚本 auto-generate-docker-tls-ca.sh # !/bin/bash # 一键生
小强崽
2022/05/20
1.7K0
docker安装篇,第二篇 在Ubuntu18.04上开启RESTful API接口,HTTP与HTTPS接口访问
https://docs.docker.com/install/linux/linux-postinstall/#next-steps
cn華少
2018/08/31
1.6K0
docker安装篇,第二篇 在Ubuntu18.04上开启RESTful API接口,HTTP与HTTPS接口访问
Docker API的使用
Docker作为最流行的容器化解决方案其API接口提供了强大的容器管理功能,通过Docker API我们可以实现自动化的容器lifecycle管理、数据管理、网络管理等,大大简化容器的使用难度,本篇文章我们主要介绍Docker API的基本使用
Al1ex
2023/12/22
9480
使用蜻蜓安全挖掘漏洞实践(一)
以下操作需要提前安装docker, 如果已安装docker请跳过这步, 安装docker命令如下:
婷婷的橙子
2022/04/30
4510
二进制安装k8s集群(3)-安装docker
在上一篇文章里我们主要介绍制作ssl证书,这里我们主要介绍安装docker。这里我们采用yum的方式安装docker,安装完成之后开启tcp通讯并且开启双向ssl验证。默认docker client和docker server是通过unix sock通讯的(在同一台机器),在实际环境中要根据自己需要来决定是否开启tcp通讯。当开启tcp通讯之后也要根据自己实际需要来看是否要开启ssl,是开启单向ssl还是双向ssl。
TA码字
2020/04/02
7810
docker2 Docker的daemon.json的作用
docker安装后默认没有daemon.json这个配置文件,需要进行手动创建。配置文件的默认路径:/etc/docker/daemon.json
用户1499526
2019/07/15
4.5K0
Docker踩坑,又涨知识了
新上线一个批处理功能,基于Docker发布的。上线之后出现一个问题,Docker批处理生成的文件目录,别的应用程序无法访问。
程序新视界
2022/11/23
3720
Docker踩坑,又涨知识了
相关推荐
TLS加密远程连接Docker
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验