16、使用 Docker API 指南

使用 Docker API 指南

在容器化技术的世界里,Docker 无疑是一颗耀眼的明星。而 Docker API 则为我们提供了一种强大的方式来与 Docker 守护进程进行交互,实现自动化和集成。本文将详细介绍如何使用 Docker Engine API,包括连接配置、测试、镜像和容器管理,以及如何改进应用程序和为 API 添加认证。

1. Docker Engine API 基础

Docker 提供了三种 API,其中 Docker Engine API 是与 Docker 守护进程集成的关键。默认情况下,Docker 守护进程绑定到本地的 Unix 套接字 unix:///var/run/docker.sock ,运行时需要 root 权限。如果系统中存在 docker 组,该组的用户可以在不使用 root 权限的情况下运行 Docker,但要注意这存在一定安全风险,因为 docker 组相当于 root 权限。

若要从本地查询 Docker API,可以使用 curl 命令,示例如下:

$ curl --unix-socket /var/run/docker.sock http:/info

如果需要远程访问 API,则需要将 Docker 守护进程绑定到网络接口。不同的 Linux 发行版需要编辑不同的配置文件,以下是一些常见发行版的配置文件:
| 发行版 | 配置文件 |
| ---- | ---- |
| 旧版 Ubuntu 或 Debian | /etc/default/docker |
| 使用 Upstart 的版本 | /etc/init/docker.conf |
| 使用 systemd 的版本 | /lib/systemd/system/docker.service |
| Red Hat、Fedora 等 | /etc/sysconfig/docker |
| 使用 Systemd 的 Red Hat 等 | /usr/lib/systemd/system/docker.service |

以运行 systemd 的 Red Hat 派生系统为例,编辑 /usr/lib/systemd/system/docker.service 文件,将默认启动选项:

ExecStart=/usr/bin/dockerd --selinux-enabled

修改为:

ExecStart=/usr/bin/dockerd --selinux-enabled -H tcp://0.0.0.0:2375

这将使 Docker 守护进程绑定到主机的所有网络接口,使用端口 2375。修改后,需要使用 systemctl 命令重新加载并重启守护进程:

$ sudo systemctl --system daemon-reload

同时,要确保防火墙允许对端口 2375 的 TCP 通信。

可以使用 docker 客户端二进制文件测试连接,通过 -H 标志指定 Docker 主机:

$ sudo docker -H docker.example.com:2375 info

也可以设置 DOCKER_HOST 环境变量来避免每次都使用 -H 标志:

$ export DOCKER_HOST="tcp://docker.example.com:2375"

需要注意的是,这种连接方式是未认证的,存在安全风险,后续会介绍如何添加认证。

2. 测试 Docker Engine API

在确认可以通过 docker 客户端连接到 Docker 守护进程后,我们可以使用 curl 命令直接连接到 API。例如,连接到 info 端点,获取与 docker info 命令类似的信息:

$ curl http://docker.example.com:2375/info | python3 -mjson.tool

这个命令会返回一个包含 Docker 守护进程系统信息的 JSON 哈希,通过 python3 -mjson.tool 可以将其格式化输出。

3. 使用 API 管理镜像

使用 Docker API 管理镜像非常方便。以下是一些常见的操作:
- 获取镜像列表

$ curl http://docker.example.com:2375/images/json | python3 -mjson.tool

这个命令会返回 Docker 守护进程上所有镜像的列表,与 docker images 命令的输出类似。
- 查询特定镜像

$ curl http://docker.example.com:2375/images/b608dbb10e2564f5bd0eef045bf297e56b1149edc70bece54fef4b217261a473/json | python3 -mjson.tool

通过镜像 ID 可以查询特定镜像的详细信息,类似于 docker inspect 命令。
- 搜索镜像

$ curl "http://docker.example.com:2375/images/search?term=jamtur01" | python3 -mjson.tool

可以在 Docker Hub 上搜索包含特定关键词的镜像。

4. 使用 API 管理容器

Docker Engine API 提供了与命令行相同的容器操作功能。
- 列出运行中的容器

$ curl -s "http://docker.example.com:2375/containers/json" | python3 -mjson.tool

该命令会列出 Docker 主机上所有运行中的容器,类似于 docker ps 命令。如果要查看所有容器(包括停止的),可以添加 all=1 参数:

http://docker.example.com:2375/containers/json?all=1
  • 创建容器
$ curl -X POST -H "Content-Type: application/json" \
  http://docker.example.com:2375/containers/create \
  -d '{
    "Image":"jamtur01/jekyll"
  }'

这个命令会创建一个基于 jamtur01/jekyll 镜像的容器,并返回容器的 ID。还可以通过添加键值对来进一步配置容器创建:

$ curl -X POST -H "Content-Type: application/json" \
  "http://docker.example.com:2375/containers/create?name=jekyll" \
  -d '{
    "Image":"jamtur01/jekyll",
    "Hostname":"jekyll"
  }'
  • 启动容器
$ curl -X POST -H "Content-Type: application/json" \
  http://docker.example.com:2375/containers/591ba02d8d149e5ae5ec2ea30ffe85ed47558b9a40b7405e3b71553d9e59bed3/start \
  -d '{
    "PublishAllPorts":true
  }'
  • 检查容器信息
$ curl http://docker.example.com:2375/containers/591ba02d8d149e5ae5ec2ea30ffe85ed47558b9a40b7405e3b71553d9e59bed3/json | python3 -mjson.tool
5. 改进应用程序

假设我们有一个 TProv 应用程序,之前使用直接调用 docker 二进制文件的方式来创建和删除 Docker 容器,这种方式存在一些问题,例如只能在安装了 Docker 客户端的环境中运行。我们可以使用 Ruby Docker-API 客户端库来改进这个应用程序。

首先,安装必要的依赖:

$ sudo yum -y install ruby ruby-irb
$ sudo gem install docker-api json

然后,在代码中建立与 Docker API 的连接:

require 'docker'

module TProvAPI
  class Application < Sinatra::Base
    Docker.url = ENV['DOCKER_URL'] || 'http://localhost:2375'
    Docker.options = {
      :ssl_verify_peer => false
    }
  end
end

可以使用 irb 测试连接:

$ irb
irb(main):001:0> require 'docker'; require 'pp'
irb(main):002:0> Docker.url = 'http://docker.example.com:2375'
irb(main):003:0> Docker.options = { :ssl_verify_peer => false }
irb(main):004:0> pp Docker.info
irb(main):005:0> pp Docker.version

最后,更新 TProv 应用程序的容器管理方法:

def get_war(name, url)
  container = Docker::Container.create('Cmd' => url, 'Image' => 'jamtur01/fetcher', 'name' => name)
  container.start
  container.id
end

def create_instance(name)
  container = Docker::Container.create('Image' => 'jamtur01/tomcat8')
  container.start('PublishAllPorts' => true, 'VolumesFrom' => name)
  container.id
end

def delete_instance(cid)
  container = Docker::Container.get(cid)
  container.kill
end

可以通过 gem 安装改进后的 TProv 应用程序:

$ sudo gem install tprov-api
6. 为 Docker Engine API 添加认证

目前我们的 API 连接是未认证的,任何人都可以连接,存在安全风险。Docker Engine API 从 0.9 版本开始提供了基于 TLS/SSL 证书的认证机制。

我们可以通过创建自己的证书颁发机构(CA)来实现认证,步骤如下:
1. 检查 openssl 是否安装

$ which openssl
  1. 创建 CA 目录
$ sudo mkdir /etc/docker
  1. 生成 CA 私钥
$ cd /etc/docker
$ echo 01 | sudo tee ca.srl
$ sudo openssl genrsa -des3 -out ca-key.pem

在生成私钥时,需要设置一个密码短语,要妥善保存这个短语,后续创建和签署证书时会用到。生成的 ca-key.pem 文件是 CA 私钥,不要共享或丢失。

接下来,我们将继续创建 CA 证书,完成认证配置。

graph LR
    A[检查 openssl] --> B[创建 CA 目录]
    B --> C[生成 CA 私钥]
    C --> D[创建 CA 证书]

以上就是使用 Docker API 的详细指南,通过这些步骤,你可以更好地利用 Docker API 实现自动化和集成,同时保障连接的安全性。

使用 Docker API 指南

7. 创建 CA 证书

在生成 CA 私钥之后,我们需要创建 CA 证书。继续在 /etc/docker 目录下执行以下操作:

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

执行该命令后,会提示你输入一些信息,如国家、省份、城市、组织等。你可以根据实际情况填写,也可以直接按回车键使用默认值。这个命令会创建一个有效期为 365 天的 CA 证书 ca.pem

8. 为服务器生成证书和私钥

接下来,我们要为 Docker 服务器生成证书和私钥。
1. 生成服务器私钥

$ sudo openssl genrsa -out server-key.pem 4096

这个命令会生成一个 4096 位的 RSA 私钥 server-key.pem
2. 生成服务器证书签名请求(CSR)

$ sudo openssl req -subj "/CN=docker.example.com" -sha256 -new -key server-key.pem -out server.csr

这里的 /CN=docker.example.com 需要替换为你的 Docker 服务器的实际域名或 IP 地址。该命令会生成一个证书签名请求 server.csr
3. 使用 CA 签署服务器证书

$ echo subjectAltName = DNS:docker.example.com,IP:192.168.1.100 | sudo tee extfile.cnf
$ sudo openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -extfile extfile.cnf

同样, DNS:docker.example.com IP:192.168.1.100 需要根据实际情况修改。这个命令会使用之前创建的 CA 来签署服务器证书,生成 server-cert.pem

9. 为客户端生成证书和私钥

客户端也需要有自己的证书和私钥来进行认证。
1. 生成客户端私钥

$ sudo openssl genrsa -out key.pem 4096

生成一个 4096 位的 RSA 私钥 key.pem
2. 生成客户端证书签名请求(CSR)

$ sudo openssl req -subj '/CN=client' -new -key key.pem -out client.csr
  1. 使用 CA 签署客户端证书
$ echo extendedKeyUsage = clientAuth | sudo tee -a extfile.cnf
$ sudo openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem -extfile extfile.cnf

这一系列操作会为客户端生成证书 cert.pem

10. 配置 Docker 守护进程使用证书

现在我们已经有了 CA 证书、服务器证书和私钥、客户端证书和私钥,接下来要配置 Docker 守护进程使用这些证书。
1. 编辑 Docker 守护进程启动配置文件
对于使用 systemd 的系统,编辑 /usr/lib/systemd/system/docker.service 文件,将 ExecStart 行修改为:

ExecStart=/usr/bin/dockerd --selinux-enabled -H tcp://0.0.0.0:2375 --tlsverify --tlscacert=/etc/docker/ca.pem --tlscert=/etc/docker/server-cert.pem --tlskey=/etc/docker/server-key.pem
  1. 重新加载并重启 Docker 守护进程
$ sudo systemctl --system daemon-reload
$ sudo systemctl restart docker
11. 使用认证后的 API 连接

现在我们可以使用认证后的方式连接到 Docker API 了。

$ curl https://docker.example.com:2375/info --cert cert.pem --key key.pem --cacert ca.pem | python3 -mjson.tool

这个命令会使用客户端证书、私钥和 CA 证书来安全地连接到 Docker API 的 info 端点。

12. 总结

通过以上步骤,我们详细介绍了如何使用 Docker Engine API,包括基础的连接配置、镜像和容器管理、改进应用程序以及为 API 添加认证。以下是整个过程的关键步骤总结表格:
| 操作 | 步骤 | 命令示例 |
| ---- | ---- | ---- |
| 基础配置 | 绑定网络接口 | ExecStart=/usr/bin/dockerd --selinux-enabled -H tcp://0.0.0.0:2375 |
| | 重新加载和重启守护进程 | sudo systemctl --system daemon-reload
sudo systemctl restart docker |
| 镜像管理 | 获取镜像列表 | curl http://docker.example.com:2375/images/json | python3 -mjson.tool |
| | 查询特定镜像 | curl http://docker.example.com:2375/images/[镜像 ID]/json | python3 -mjson.tool |
| | 搜索镜像 | curl "http://docker.example.com:2375/images/search?term=[关键词]" | python3 -mjson.tool |
| 容器管理 | 列出运行中的容器 | curl -s "http://docker.example.com:2375/containers/json" | python3 -mjson.tool |
| | 创建容器 | curl -X POST -H "Content-Type: application/json" http://docker.example.com:2375/containers/create -d '{"Image":"[镜像名称]"}' |
| | 启动容器 | curl -X POST -H "Content-Type: application/json" http://docker.example.com:2375/containers/[容器 ID]/start -d '{"PublishAllPorts":true}' |
| | 检查容器信息 | curl http://docker.example.com:2375/containers/[容器 ID]/json | python3 -mjson.tool |
| 应用改进 | 安装依赖 | sudo yum -y install ruby ruby-irb
sudo gem install docker-api json |
| | 建立连接 | require 'docker'
Docker.url = ENV['DOCKER_URL'] || 'http://localhost:2375'
Docker.options = { :ssl_verify_peer => false } |
| | 更新容器管理方法 | Ruby 代码示例见上文 |
| 认证配置 | 检查 openssl | which openssl |
| | 创建 CA 目录 | sudo mkdir /etc/docker |
| | 生成 CA 私钥 | sudo openssl genrsa -des3 -out ca-key.pem |
| | 创建 CA 证书 | sudo openssl req -new -x509 -days 365 -key ca-key.pem -out ca.pem |
| | 生成服务器证书和私钥 | 一系列命令见上文 |
| | 生成客户端证书和私钥 | 一系列命令见上文 |
| | 配置 Docker 守护进程 | 修改 ExecStart 行并重启 |
| | 使用认证连接 | curl https://docker.example.com:2375/info --cert cert.pem --key key.pem --cacert ca.pem | python3 -mjson.tool |

graph LR
    A[基础配置] --> B[镜像管理]
    A --> C[容器管理]
    A --> D[应用改进]
    A --> E[认证配置]
    B --> F[获取镜像列表]
    B --> G[查询特定镜像]
    B --> H[搜索镜像]
    C --> I[列出运行容器]
    C --> J[创建容器]
    C --> K[启动容器]
    C --> L[检查容器信息]
    D --> M[安装依赖]
    D --> N[建立连接]
    D --> O[更新方法]
    E --> P[检查 openssl]
    P --> Q[创建 CA 目录]
    Q --> R[生成 CA 私钥]
    R --> S[创建 CA 证书]
    S --> T[生成服务器证书和私钥]
    S --> U[生成客户端证书和私钥]
    U --> V[配置 Docker 守护进程]
    V --> W[使用认证连接]

通过这些操作,你可以充分利用 Docker API 实现自动化和集成,同时保障连接的安全性,让你的容器化应用更加稳定和可靠。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值