Docker 编排、服务发现及 API 使用指南
1. 分布式应用与服务发现
在分布式应用中,服务发现至关重要。例如,
distributed_client
应用通过查询 HTTP API,找到了
distributed_app
及其
server1
和
server2
工作节点在
larry
和
curly
节点上的服务条目。同时,它还进行了 DNS 查找,发现运行该服务的节点 IP 地址为
162.243.167.159
和
162.243.170.66
。
Application distributed_app with element server1 on port 2001
found on node curly (162.243.170.66).
We can also resolve DNS - distributed_app resolves to
162.243.167.159 and 162.243.170.66.
如果这是一个真实的分布式应用,客户端和工作节点可以利用这些信息来配置、连接和路由分布式应用的各个元素。这为构建运行在独立 Docker 容器和主机内的分布式应用提供了一种简单、便捷且有弹性的方式。
2. Docker Swarm 介绍
2.1 Docker Swarm 概述
Docker Swarm 是 Docker 的原生集群工具,它能将多个 Docker 主机池转换为一个单一的虚拟 Docker 主机。Swarm 架构简单,它将多个 Docker 主机集群在一起,并在该集群之上提供标准的 Docker API。这非常强大,因为它将 Docker 容器的抽象提升到了集群级别,而无需用户学习新的 API,便于与支持 Docker API 的工具集成,包括标准的 Docker 客户端。
2.2 Swarm 设计原则与发展历程
Swarm 遵循“内置电池但可移除”的设计原则,它为简单用例提供了工具和后端集成,并为更复杂的工具和用例提供了 API。自 Docker 1.12 起,Swarm 集成到 Docker 中,在此之前,它是一个遵循 Apache 2 许可的独立应用。
2.3 Swarm 节点与服务
一个 Swarm 集群由管理节点和工作节点组成:
-
管理节点
:负责调度和组织 Swarm 上的工作,每个工作单元称为一个任务。管理节点还处理所有集群管理功能,以确保 Swarm 健康活跃。如果有多个管理节点,它们会选举出一个领导者。
-
工作节点
:运行从管理节点调度的任务。默认情况下,所有节点(包括管理节点和工作节点)都会运行任务,但也可以将管理节点配置为仅执行管理活动而不运行任务。
Swarm 使用服务作为构建块,服务定义了在节点上执行的任务。服务由容器镜像和一系列在节点上的一个或多个容器内执行的命令组成。服务可以以以下模式运行:
-
复制服务
:Swarm 管理器根据指定的规模在工作节点之间分配复制任务。
-
全局服务
:Swarm 管理器在每个可用的工作节点上为服务调度一个任务。
Swarm 还像本地 Docker 主机一样管理负载均衡和 DNS,每个 Swarm 可以暴露端口,这些端口可以自动或手动定义。
3. 安装与设置 Docker Swarm
3.1 安装 Swarm
安装 Swarm 最简单的方法是使用 Docker 本身。假设已经按照相关说明安装了 Docker。在 Docker 1.12 之前,Swarm 是一个独立应用,可以通过 Docker Inc 团队提供的名为
swarm
的 Docker 镜像使用。
3.2 设置 Swarm 集群
我们将使用
larry
、
curly
和
moe
主机来演示 Swarm。这些主机已经安装了最新的 Docker 版本,我们将把它们转换为 Swarm 集群的节点。
3.2.1 节点角色与端口
| 主机 | IP 地址 | 角色 |
|---|---|---|
| larry | 162.243.167.159 | 管理节点 |
| curly | 162.243.170.66 | 工作节点 |
| moe | 159.203.191.16 | 工作节点 |
同时,需要确保节点之间开放以下端口:
| 端口 | 用途 |
| — | — |
| 2377 | 集群管理 |
| 7946 + udp | 节点通信 |
| 4789 + udp | 覆盖网络 |
3.2.2 初始化 Swarm
首先,在
larry
节点上获取公共 IP 地址:
larry$ PUBLIC_IP="$(ifconfig eth0 | awk -F ' *|:' '/inet addr/{
print $4}')"
larry$ echo $PUBLIC_IP
162.243.167.159
然后,使用该地址初始化 Swarm:
$ sudo docker swarm init --advertise-addr $PUBLIC_IP
Swarm initialized: current node (bu84wfix0h0x31aut8qlpbi9x) is
now a manager.
To add a worker to this swarm, run the following command:
docker swarm join \
--token SWMTKN-1-2
mk0wnb9m9cdwhheoysr3pt8orxku8c7k3x3kjjsxatc5ua72v-776
lg9r60gigwb32q329m0dli \
162.243.167.159:2377
To add a manager to this swarm, run the following command:
docker swarm join \
--token SWMTKN-1-2
mk0wnb9m9cdwhheoysr3pt8orxku8c7k3x3kjjsxatc5ua72v-78
bsc54abf35rhpr3ntbh98t8 \
162.243.167.159:2377
3.2.3 查看 Swarm 状态
可以使用
docker info
命令查看 Swarm 的状态:
larry$ sudo docker info
...
Swarm: active
NodeID: bu84wfix0h0x31aut8qlpbi9x
Is Manager: true
ClusterID: 0qtrjqv37gs3yc5f7ywt8nwfq
Managers: 1
Nodes: 1
Orchestration:
Task History Retention Limit: 5
Raft:
Snapshot interval: 10000
Heartbeat tick: 1
Election tick: 3
Dispatcher:
Heartbeat period: 5 seconds
CA configuration:
Expiry duration: 3 months
Node Address: 162.243.167.159
...
使用
docker node ls
命令查看 Swarm 中的节点列表:
larry$ sudo docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
bu84wfix0h0x31aut8qlpbi9x * larry Ready Active Leader
3.2.4 添加工作节点
使用初始化 Swarm 时输出的命令,将
curly
和
moe
节点添加为工作节点:
curly$ sudo docker swarm join \
--token SWMTKN-1-2
mk0wnb9m9cdwhheoysr3pt8orxku8c7k3x3kjjsxatc5ua72v-776
lg9r60gigwb32q329m0dli \
162.243.167.159:2377
再次查看节点列表:
larry$ sudo docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
bu84wfix0h0x31aut8qlpbi9x * larry Ready Active Leader
c6viix7oja1twnyuc8ez7txhd curly Ready Active
dzxrvk6awnegjtj5aixnojetf moe Ready Active
4. 在 Swarm 上运行服务
4.1 创建复制服务
使用以下命令创建一个简单的复制服务:
$ sudo docker service create --replicas 2 --name heyworld ubuntu \
/bin/sh -c "while true; do echo hey world; sleep 1; done"
8bl7yw1z3gzir0rmcvnrktqol
4.2 查看服务列表
使用
docker service ls
命令查看服务列表:
$ sudo docker service ls
ID NAME REPLICAS IMAGE COMMAND
8bl7yw1z3gzi heyworld 2/2 ubuntu /bin/sh -c while true; do echo hey world; sleep 1; done
4.3 检查服务详细信息
使用
docker service inspect
命令检查服务的详细信息:
$ sudo docker service inspect --pretty heyworld
ID: 8bl7yw1z3gzir0rmcvnrktqol
Name: heyworld
Mode: Replicated
Replicas: 2
Placement:
UpdateConfig:
Parallelism: 1
On failure: pause
ContainerSpec:
Image: ubuntu
Args: /bin/sh -c while true; do echo hey world; sleep 1; done
Resources:
4.4 检查服务进程
使用
docker service ps
命令检查服务进程:
$ sudo docker service ps heyworld
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE
103q... heyworld.1 ubuntu larry Running Running about a minute ago
6ztf... heyworld.2 ubuntu moe Running Running about a minute ago
4.5 扩展服务
使用
docker service scale
命令扩展服务:
$ sudo docker service scale heyworld=3
heyworld scaled to 3
再次检查服务进程:
$ sudo docker service ps heyworld
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE
103q... heyworld.1 ubuntu larry Running Running 5 minutes ago
6ztf... heyworld.2 ubuntu moe Running Running 5 minutes ago
1gib... heyworld.3 ubuntu curly Running Running about a minute ago
4.6 运行全局服务
使用以下命令运行全局服务:
$ sudo docker service create --name heyworld_global --mode global \
ubuntu /bin/sh -c "while true; do echo hey world; sleep 1; done"
检查全局服务进程:
$ sudo docker service ps heyworld_global
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE
c8c1... heyworld_global ubuntu moe Running Running 30 seconds ago
48wm... _heyworld_global ubuntu curly Running Running 30 seconds ago
8b8u... _heyworld_global ubuntu larry Running Running 29 seconds ago
4.7 删除服务
使用
docker service rm
命令删除服务:
$ sudo docker service rm heyworld
heyworld
查看剩余服务列表:
$ sudo docker service ls
ID NAME REPLICAS IMAGE COMMAND
5k3t... heyworld_global global ubuntu /bin/sh -c...
5. 编排替代工具和组件
除了 Compose 和 Consul,Docker 编排工具的生态系统正在快速发展,以下是一些可用的工具,大致分为两类:
-
调度和集群管理
:
-
Fleet 和 etcd
:由 CoreOS 团队发布,Fleet 是集群管理工具,etcd 是用于共享配置和服务发现的高可用键值存储。Fleet 结合了 systemd 和 etcd,为容器提供集群管理和调度功能。
-
Kubernetes
:由 Google 开源的容器集群管理工具,允许使用 Docker 在多个主机上部署和扩展应用程序,主要针对由多个容器组成的应用程序,如弹性分布式微服务。
-
Apache Mesos
:高度可用的集群管理工具,自 Mesos 0.20.0 起内置 Docker 集成,许多初创公司(如 Twitter 和 Airbnb)都在使用。
-
Helios
:由 Spotify 团队发布的 Docker 编排平台,用于在整个主机群中部署和管理容器。
-
Centurion
:由 New Relic 团队开源的基于 Docker 的部署工具,用于从 Docker 注册表中获取容器并在主机群上运行,旨在帮助实现 Docker 的持续部署。
-
服务发现
:部分工具也具备服务发现功能。
6. Docker API 介绍
6.1 Docker API 的重要性
在与 Docker 集成时,使用 Docker API 比在命令行中使用
docker
二进制文件并捕获输出更为优雅。
6.2 Docker API 分类
Docker 生态系统中有三种特定的 API:
-
注册表 API
:提供与存储镜像的 Docker 注册表的集成。
-
Docker Hub API
:提供与 Docker Hub 的集成。
6.3 使用 Docker API 的步骤
- 绑定 Docker 守护进程到网络端口 :具体操作将在后续详细介绍。
- 了解 API 概述 :从高层次介绍 API 的关键方面。
-
重写应用代码
:以 TProv 应用为例,将部分代码重写为使用 API 而不是
docker二进制文件。 - API 认证 :通过 TLS 对 API 进行认证。
通过以上内容,我们了解了 Docker 分布式应用的服务发现、Docker Swarm 的安装与使用,以及 Docker API 的相关信息,这些知识有助于我们更好地构建和管理 Docker 应用。
7. 绑定 Docker 守护进程到网络端口
要使用 Docker API,首先需要将 Docker 守护进程绑定到网络端口。以下是一般的操作步骤:
1.
编辑 Docker 守护进程配置文件
:不同的操作系统配置文件位置可能不同,例如在 Ubuntu 上,配置文件通常位于
/etc/docker/daemon.json
。
2.
添加监听地址
:在配置文件中添加如下内容:
{
"hosts": ["tcp://0.0.0.0:2375", "unix:///var/run/docker.sock"]
}
这里
tcp://0.0.0.0:2375
表示监听所有网络接口的 2375 端口,
unix:///var/run/docker.sock
是默认的 Unix 套接字监听方式。
3.
重启 Docker 守护进程
:使用以下命令重启 Docker 服务:
sudo systemctl restart docker
8. 深入了解 Docker API
8.1 注册表 API
注册表 API 允许我们与 Docker 注册表进行交互,例如列出镜像、上传和下载镜像等。以下是一个简单的使用 Python 脚本调用注册表 API 列出镜像的示例:
import requests
registry_url = "https://registry.example.com/v2/_catalog"
response = requests.get(registry_url)
if response.status_code == 200:
data = response.json()
print("Available repositories:", data.get("repositories", []))
else:
print("Error:", response.text)
8.2 Docker Hub API
Docker Hub API 可以让我们与 Docker Hub 进行集成,例如获取镜像的详细信息、查看用户的仓库等。以下是一个使用 Python 脚本获取 Docker Hub 上某个镜像详细信息的示例:
import requests
image_name = "ubuntu"
hub_api_url = f"https://hub.docker.com/v2/repositories/library/{image_name}/"
response = requests.get(hub_api_url)
if response.status_code == 200:
data = response.json()
print("Image description:", data.get("description", ""))
else:
print("Error:", response.text)
8.3 API 关键方面分析
-
请求方法
:常见的请求方法有
GET、POST、PUT、DELETE等。GET用于获取资源信息,POST用于创建新资源,PUT用于更新资源,DELETE用于删除资源。 - 响应格式 :API 的响应通常是 JSON 格式,方便解析和处理。
- 错误处理 :当请求出现错误时,API 会返回相应的错误码和错误信息,我们需要根据这些信息进行相应的处理。
9. 重写 TProv 应用使用 API
假设 TProv 应用中有部分功能是通过命令行调用
docker
二进制文件实现的,现在我们将其重写为使用 Docker API。以下是一个简单的示例,将原来通过命令行创建容器的功能重写为使用 API:
9.1 原命令行方式
docker run -d --name my_container ubuntu sleep 3600
9.2 使用 API 实现
import requests
docker_api_url = "http://localhost:2375/containers/create"
headers = {
"Content-Type": "application/json"
}
data = {
"Image": "ubuntu",
"Cmd": ["sleep", "3600"],
"name": "my_container"
}
response = requests.post(docker_api_url, headers=headers, json=data)
if response.status_code == 201:
container_id = response.json().get("Id")
start_url = f"http://localhost:2375/containers/{container_id}/start"
start_response = requests.post(start_url)
if start_response.status_code == 204:
print("Container started successfully.")
else:
print("Error starting container:", start_response.text)
else:
print("Error creating container:", response.text)
10. 通过 TLS 认证 API
为了确保 API 通信的安全性,我们可以通过 TLS 对 API 进行认证。以下是具体的操作步骤:
10.1 生成证书和密钥
可以使用 OpenSSL 生成自签名的证书和密钥:
# 生成私钥
openssl genrsa -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,IP:127.0.0.1 > extfile.cnf
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
openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem -extfile extfile.cnf
10.2 配置 Docker 守护进程使用 TLS
在
/etc/docker/daemon.json
中添加如下配置:
{
"hosts": ["tcp://0.0.0.0:2376", "unix:///var/run/docker.sock"],
"tls": true,
"tlscacert": "/path/to/ca.pem",
"tlscert": "/path/to/server-cert.pem",
"tlskey": "/path/to/server-key.pem",
"tlsverify": true
}
然后重启 Docker 服务。
10.3 使用 TLS 认证调用 API
import requests
docker_api_url = "https://localhost:2376/containers/json"
cert = ("/path/to/cert.pem", "/path/to/key.pem")
ca_cert = "/path/to/ca.pem"
response = requests.get(docker_api_url, cert=cert, verify=ca_cert)
if response.status_code == 200:
containers = response.json()
print("Running containers:", containers)
else:
print("Error:", response.text)
总结
通过本文,我们全面了解了 Docker 相关的多个重要方面。从分布式应用的服务发现开始,认识到服务发现对于构建分布式应用的重要性,它能让客户端和工作节点更好地配置、连接和路由应用元素。接着深入学习了 Docker Swarm,包括其概念、安装、设置以及在 Swarm 上运行服务的详细操作,Swarm 为我们提供了强大的集群管理和调度能力。之后介绍了多种 Docker 编排替代工具和组件,让我们看到了 Docker 编排工具生态系统的多样性。最后,详细探讨了 Docker API,包括绑定守护进程到网络端口、深入了解不同类型的 API、重写应用代码使用 API 以及通过 TLS 认证 API 等内容,这些知识有助于我们更高效、更安全地使用 Docker 来构建和管理应用。掌握这些知识和技能,将使我们在 Docker 应用开发和管理领域更加得心应手。
超级会员免费看
1223

被折叠的 条评论
为什么被折叠?



