<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Remote-Api on Liangweidong's blog</title><link>https://liangweidonggood.github.io/tags/remote-api/</link><description>Recent content in Remote-Api on Liangweidong's blog</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Sun, 15 Jun 2014 00:00:00 +0800</lastBuildDate><atom:link href="https://liangweidonggood.github.io/tags/remote-api/index.xml" rel="self" type="application/rss+xml"/><item><title>Docker Remote API 与 2375 端口：从开启到 IDE 集成的安全实践</title><link>https://liangweidonggood.github.io/p/docker-remote-api-2375/</link><pubDate>Sun, 15 Jun 2014 00:00:00 +0800</pubDate><guid>https://liangweidonggood.github.io/p/docker-remote-api-2375/</guid><description>&lt;img src="https://liangweidonggood.github.io/p/docker-remote-api-2375/image/cover.jpg" alt="Featured image of post Docker Remote API 与 2375 端口：从开启到 IDE 集成的安全实践" /&gt;&lt;p&gt;Docker 1.0 在 2014 年 6 月正式发布时，&lt;strong&gt;伴随的不仅是一个稳定版，更是一套被广泛复用的管理接口&lt;/strong&gt;——Docker Remote API。基于 HTTP + REST 风格，把 daemon 暴露在 2375 端口（未加密）或 2376 端口（TLS 加密），让 IDEA、Portainer、Shipyard、命令行客户端都能远程控制容器。&lt;/p&gt;
&lt;p&gt;这一篇把&amp;quot;如何开启 2375 端口 + 如何用 IDEA 远程连接 + 为什么必须配 TLS&amp;quot;这条主线串起来。&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;阅读对象&lt;/strong&gt;：需要从开发机远程管理服务器 Docker daemon 的开发者、运维同学
&lt;strong&gt;覆盖范围&lt;/strong&gt;：systemd 开启 2375/2376 端口 + IDEA Docker 插件 + TLS 证书生成 + 风险与替代方案&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h2 id="一为什么需要-remote-api"&gt;一、为什么需要 Remote API
&lt;/h2&gt;&lt;p&gt;本地 &lt;code&gt;docker&lt;/code&gt; 命令行直接走 &lt;code&gt;/var/run/docker.sock&lt;/code&gt; Unix socket。&lt;strong&gt;一旦要在另一台机器上管理这个 daemon，要么 SSH 登过去，要么把 daemon 暴露成 HTTP 服务&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;Remote API 的典型场景：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;开发机远程管理生产 / 测试 Docker daemon&lt;/strong&gt;——开发笔记本 IDEA 上点 &amp;ldquo;Redeploy&amp;rdquo;，触发远端容器重建&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可视化平台集中管控&lt;/strong&gt;——Portainer、Shipyard、Rancher 通过 Remote API 拉取容器列表 / 镜像 / 日志&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CI 节点操作远端 daemon&lt;/strong&gt;——Jenkins Agent 在 K8s 节点内，通过 Remote API 控制宿主机 Docker（早期 docker-in-docker 方案）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;到 2014 年中 Docker 1.0 时代，&lt;strong&gt;2375 是事实上的标准端口&lt;/strong&gt;。Docker 1.11+（2016-04）又新增了 2376 作为 TLS 加密端口，逐步成为生产推荐。&lt;/p&gt;
&lt;h2 id="二开启-2375-端口systemd-方式"&gt;二、开启 2375 端口（systemd 方式）
&lt;/h2&gt;&lt;p&gt;绝大多数 Linux 发行版（CentOS 7+、Debian 8+、Ubuntu 16.04+）的 Docker 由 &lt;code&gt;docker.service&lt;/code&gt; 守护，通过 systemd 管理。&lt;strong&gt;修改启动参数是开启 Remote API 的标准做法&lt;/strong&gt;。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 编辑 docker.service&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;vim /usr/lib/systemd/system/docker.service
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;在 &lt;code&gt;ExecStart&lt;/code&gt; 这一行&lt;strong&gt;追加&lt;/strong&gt; &lt;code&gt;-H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock&lt;/code&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[Service]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;notify&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;ExecStart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/usr/bin/dockerd \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; -H fd:// \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; -H tcp://0.0.0.0:2375 \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; -H unix:///var/run/docker.sock&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;ExecReload&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/bin/kill -s HUP $MAINPID&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;Why 加 &lt;code&gt;-H fd://&lt;/code&gt; + &lt;code&gt;-H unix:///var/run/docker.sock&lt;/code&gt;&lt;/strong&gt;：保留 fd 协议（systemd socket activation）和 Unix socket，&lt;strong&gt;让本机 &lt;code&gt;docker&lt;/code&gt; 命令继续可用&lt;/strong&gt;。如果不加 Unix socket，本机 &lt;code&gt;docker ps&lt;/code&gt; 会全部失效。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;修改完之后：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;span class="lnt"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 重新加载 systemd 配置&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl daemon-reload
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 重启 docker&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl restart docker
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 验证端口是否真的开了&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ss -tlnp &lt;span class="p"&gt;|&lt;/span&gt; grep &lt;span class="m"&gt;2375&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 期望输出：LISTEN 0 128 *:2375 *:* users:((&amp;#34;dockerd&amp;#34;,pid=...,fd=...))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;从远端测试一下：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 在另一台机器上&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker -H tcp://&amp;lt;docker-host&amp;gt;:2375 images
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 期望输出：该 daemon 上的镜像列表&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：&lt;code&gt;&amp;lt;docker-host&amp;gt;&lt;/code&gt; 是 daemon 所在机器的 IP。&lt;strong&gt;不要写 &lt;code&gt;0.0.0.0&lt;/code&gt;&lt;/strong&gt;——客户端必须用真实可达 IP（如内网 IP 或公网 IP）。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h2 id="三idea-集成-docker"&gt;三、IDEA 集成 Docker
&lt;/h2&gt;&lt;p&gt;IntelliJ IDEA（2017.2+ Ultimate 内置 Docker 插件，2017.3 起 Community 也支持）能直接连 Docker daemon。&lt;/p&gt;
&lt;h3 id="31-在-idea-中配置"&gt;3.1 在 IDEA 中配置
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;Settings → Build, Execution, Deployment → Docker&lt;/code&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;TCP Socket&lt;/strong&gt;: &lt;code&gt;tcp://&amp;lt;docker-host&amp;gt;:2375&lt;/code&gt;（明文）或 &lt;code&gt;tcp://&amp;lt;docker-host&amp;gt;:2376&lt;/code&gt;（TLS）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Docker Compose executable&lt;/strong&gt;：选 &lt;code&gt;docker-compose&lt;/code&gt; 可执行文件路径&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果走 TLS，需要提前准备：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;字段&lt;/th&gt;
					&lt;th&gt;含义&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;CA cert&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;证书颁发机构（&lt;code&gt;.crt&lt;/code&gt; 文件）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Client cert&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;客户端证书（&lt;code&gt;.cert&lt;/code&gt; 文件）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Client key&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;客户端私钥（&lt;code&gt;.key&lt;/code&gt; 文件）&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;填完之后，IDEA 会在底部 Services 面板里新增 &lt;code&gt;Docker&lt;/code&gt; 节点，&lt;strong&gt;可以看到远端容器、镜像、卷、网络&lt;/strong&gt;，并支持：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一键 Run / Debug 容器（自动构建镜像 → 启动）&lt;/li&gt;
&lt;li&gt;实时查看容器 stdout / stderr&lt;/li&gt;
&lt;li&gt;Exec into container（类似 &lt;code&gt;docker exec -it&lt;/code&gt;）&lt;/li&gt;
&lt;li&gt;资源图表（CPU / 内存 / 网络 IO）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="32-实际工作流"&gt;3.2 实际工作流
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[IDEA]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓ Run &amp;#39;Docker&amp;#39; configuration
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓ docker build -t myapp:dev .
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓ docker run -d -p 8080:8080 myapp:dev
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[远端 Docker daemon (2375/2376)]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓ 拉取基础镜像 / 构建 / 启动容器
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓ 把 stdout/stderr 推回 IDEA
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;开发阶段，&lt;strong&gt;所有 build / run / debug 都在远端完成&lt;/strong&gt;，本地不需要装 Docker Desktop——这是 2014-2017 时代跨平台开发的常见模式。&lt;/p&gt;
&lt;h2 id="四风险与生产建议"&gt;四、风险与生产建议
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;明文 2375 端口 = 把 daemon root 权限交给任何能访问到的人&lt;/strong&gt;。攻击者只要能连到这个端口，就能：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;跑特权容器 → 逃逸到宿主机&lt;/li&gt;
&lt;li&gt;拉取 / 推送任意镜像&lt;/li&gt;
&lt;li&gt;删除所有数据卷&lt;/li&gt;
&lt;li&gt;挂载宿主机任意目录&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="41-必须做的安全加固"&gt;4.1 必须做的安全加固
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;绝不放公网&lt;/strong&gt;：2375 端口&lt;strong&gt;只能在 VPC 内网&lt;/strong&gt;开放，&lt;strong&gt;不要&lt;/strong&gt;在云厂商安全组里把 2375 对 &lt;code&gt;0.0.0.0/0&lt;/code&gt; 开放&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;必须配 TLS&lt;/strong&gt;（2376）：用 OpenSSL 生成 CA、server、client 证书，配置 &lt;code&gt;tlsverify&lt;/code&gt; + &lt;code&gt;tlscacert&lt;/code&gt; + &lt;code&gt;tlscert&lt;/code&gt; + &lt;code&gt;tlskey&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;防火墙白名单&lt;/strong&gt;：iptables / nftables / 云安全组&lt;strong&gt;只放行&lt;/strong&gt;可信 IP 段&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;避免 rootless 之外运行&lt;/strong&gt;：Docker 默认以 root 运行，&lt;strong&gt;任何 Remote API 调用都是 root 等价&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="42-最小化配置示例tls"&gt;4.2 最小化配置示例（TLS）
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1. 生成 CA、server、client 证书（简化版，参考 dockerd 官方文档）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /etc/docker/tls
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;openssl genrsa -aes256 -out ca-key.pem &lt;span class="m"&gt;4096&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;openssl req -new -x509 -days &lt;span class="m"&gt;365&lt;/span&gt; -key ca-key.pem -sha256 -out ca.pem
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ... 生成 server-cert.pem / server-key.pem / client-cert.pem / client-key.pem&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 2. 修改 docker.service&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;ExecStart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/usr/bin/dockerd &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --tlsverify &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --tlscacert&lt;span class="o"&gt;=&lt;/span&gt;/etc/docker/tls/ca.pem &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --tlscert&lt;span class="o"&gt;=&lt;/span&gt;/etc/docker/tls/server-cert.pem &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --tlskey&lt;span class="o"&gt;=&lt;/span&gt;/etc/docker/tls/server-key.pem &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -H tcp://0.0.0.0:2376 &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -H unix:///var/run/docker.sock
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl daemon-reload
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl restart docker
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="43-替代方案"&gt;4.3 替代方案
&lt;/h3&gt;&lt;p&gt;如果不想在每台机器上维护 TLS 证书，&lt;strong&gt;SSH 隧道是更轻量的选择&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 在客户端机器上，把远端 docker.sock 转到本地&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh -L 2375:localhost:2375 user@&amp;lt;docker-host&amp;gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -o &lt;span class="s2"&gt;&amp;#34;StreamLocalBindUnlink=yes&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -- docker system
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 现在本地 docker 命令会走 SSH 隧道&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker -H tcp://localhost:2375 ps
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;或者用&lt;strong&gt;反向 SSH 隧道&lt;/strong&gt;让远端 daemon 主动连出：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 在 docker-host 上&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh -R 2375:unix:///var/run/docker.sock user@jumphost
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="五常见问题"&gt;五、常见问题
&lt;/h2&gt;&lt;h3 id="51-cannot-connect-to-the-docker-daemon-at-tcp"&gt;5.1 &lt;code&gt;Cannot connect to the Docker daemon at tcp://...&lt;/code&gt;
&lt;/h3&gt;&lt;p&gt;按顺序排查：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;端口是否真的开放：&lt;code&gt;ss -tlnp | grep 2375&lt;/code&gt; / &lt;code&gt;telnet &amp;lt;host&amp;gt; 2375&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;防火墙是否放行：&lt;code&gt;iptables -L -n&lt;/code&gt; / &lt;code&gt;firewall-cmd --list-all&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;云安全组：检查入方向规则&lt;/li&gt;
&lt;li&gt;&lt;code&gt;dockerd&lt;/code&gt; 启动参数：检查 &lt;code&gt;-H tcp://0.0.0.0:2375&lt;/code&gt; 是否拼对（注意是 &lt;code&gt;tcp://&lt;/code&gt; 不是 &lt;code&gt;tcp:\\\\&lt;/code&gt;）&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="52-idea-连上之后看不到容器"&gt;5.2 IDEA 连上之后看不到容器
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;确认 IDEA 里填的端口和 daemon 一致&lt;/li&gt;
&lt;li&gt;如果是 2376，&lt;strong&gt;所有三份证书&lt;/strong&gt;都要正确（CA + client cert + client key）&lt;/li&gt;
&lt;li&gt;在 &lt;code&gt;daemon.json&lt;/code&gt; 里查看 &lt;code&gt;&amp;quot;hosts&amp;quot;&lt;/code&gt; 字段确认没被覆盖&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="53-tls-连不上"&gt;5.3 TLS 连不上
&lt;/h3&gt;&lt;p&gt;检查证书的 SAN（Subject Alternative Name）字段，&lt;strong&gt;必须包含客户端实际访问的 IP / 域名&lt;/strong&gt;。Docker 18.09+ 启用了严格的证书校验，SAN 不匹配直接 &lt;code&gt;tls: invalid certificate&lt;/code&gt; 报错。&lt;/p&gt;
&lt;h2 id="六要点回顾"&gt;六、要点回顾
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;2375 = 明文，2376 = TLS&lt;/strong&gt;——生产环境&lt;strong&gt;只用 2376&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;保留 Unix socket&lt;/strong&gt;——&lt;code&gt;-H unix:///var/run/docker.sock&lt;/code&gt; 必须有，否则本机 &lt;code&gt;docker&lt;/code&gt; 命令会失效&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;systemd reload ≠ restart&lt;/strong&gt;——改完 docker.service 必须 &lt;code&gt;daemon-reload&lt;/code&gt; + &lt;code&gt;restart&lt;/code&gt;，reload 不会重读 service 文件&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;IDEA Docker 插件&lt;/strong&gt; 是 Remote API 最常见的消费方，从 2017.2 起 Ultimate 内置，2017.3 起 Community 可用&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SSH 隧道是 2375 的&amp;quot;穷人版安全&amp;quot;&lt;/strong&gt;——比明文好，但仍需 root 信任 SSH 通道&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="七小结"&gt;七、小结
&lt;/h2&gt;&lt;p&gt;Remote API 打开了 Docker 生态的&amp;quot;分布式管理&amp;quot;大门——从 CI 节点到 IDE，从可视化平台到跨主机编排，&lt;strong&gt;几乎所有上层工具都建立在 Remote API 之上&lt;/strong&gt;。但 2375 明文端口的安全代价极高，&lt;strong&gt;生产部署必须走 2376 + TLS&lt;/strong&gt;。&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;下一步&lt;/strong&gt;：理解了 Remote API，下一层是 Docker Compose v2（2020-08 GA）的声明式管理——把多个容器、网络、卷用一个 YAML 描述，daemon 自动调谐到期望状态。Compose v2 内部仍依赖 Docker SDK（Remote API 的 Go 封装），&lt;strong&gt;2375/2376 是它的&amp;quot;地基&amp;quot;&lt;/strong&gt;。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h2 id="参考资料"&gt;参考资料
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.docker.com/engine/api/" target="_blank" rel="noopener"
 &gt;Docker Engine API 官方文档&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.docker.com/engine/security/protect-access/" target="_blank" rel="noopener"
 &gt;Protect the Docker daemon socket&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.jetbrains.com/help/idea/docker.html" target="_blank" rel="noopener"
 &gt;IDEA Docker 插件文档&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.docker.com/blog/docker-1-0/" target="_blank" rel="noopener"
 &gt;Docker 1.0 公告（2014-06-09）&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>