在阿里云上体验Docker 1.12的路由能力和容器应用分发部署

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: Docker 1.12除了提供内置的编排能力,也提供了服务路由支持 routing mesh,和新的多容器应用分发和部署机制, Docker Stack和Distributed Application Bundle

14680725458431

阿里云容器服务团队将为大家奉献一系列深入学习的文章来帮助大家了解Docker 1.12的最新动态。

简述

Docker 1.12除了提供内置的编排能力,也提供了服务路由支持 routing mesh,和新的多容器应用分发和部署机制。

这里我们先介绍两个概念

  • 分布式应用打包 (Distributed Application Bundle,简称DAB):DAB 是一个用于应用分发的文件格式,其中可以包含多个容器服务定义。
  • Stack(应用栈):可以从一个DAB文件创建一个应用栈实例,一个应用栈中包含多个服务实例。

如果你熟悉Docker Compose,这些概念听起来是不是很熟悉?一个Docker Compose模板中可以包含多个服务的描述,而利用Compose模板可以创建一个完整的应用。但是Docker Compose本身被设计成为面向单机的开发工具,并不能对分布式应用进行部署、管理。而DAB提供了一个标准化的分发格式解决了这个问题。另外Docker提供了工具,可以将一个已有Docker Compose模板转换成DAB格式,并部署为Docker Stack实例。

14680556259171

本文中,我们会部署一个WordPress DAB应用到阿里云上的Swarm模式Docker集群中,其中包含两个服务wordpress和mysql。我们还会利用阿里云 SLB实现wordpress任务容器的路由和负载均衡。

集群创建

首先我们先构建一个Docker Swarm模式集群,有两种方法一种是利用ROS资源编排模板一键创建一个Swarm集群,另一种方法则是我们前文介绍的利用Docker Machine手工创建完整的环境。为了加深理解,我们这次采用分解动作,使用第二种方法进行集群创建。

在这个环境中我们将创建一个三个ECS实例构成的Swarm集群,其中一个是manager。另外我们会创建一个SLB实例来实现服务的路由和负载均衡,集群中三个ECS实例都会作为SLB的后端服务器。我们会在集群上部署应用,并配置服务路由。大概的拓扑示意图如下:

14694976178970

首先我们创建一个SLB实例

14679813399994

SLB创建成功之后,我们利用docker-machine来创建三个ECS节点来组成Docker集群执行环境。

我们首先在命令行上配置一些共用的环境变量

export DEBUG=true 
export ECS_ACCESS_KEY_ID=<您的Access Key ID>
export ECS_ACCESS_KEY_SECRET=<您的Access Key Secret>
export ECS_REGION=cn-beijing
export ECS_ZONE=cn-beijing-b
export ECS_SSH_PASSWORD=<ECS实例SSH密码>
export ECS_UPGRADE_KERNEL=true
export MACHINE_DOCKER_INSTALL_URL= http://acs-public-mirror.oss-cn-hangzhou.aliyuncs.com/docker-engine/experimental/intranet
export ENGINE_REGISTRY_MIRROR=https://6udu7vtl.mirror.aliyuncs.com
export ECS_SLB_ID=<您的SLB实例ID>
AI 代码解读

然后我们可以通过如下命令在阿里云上创建3个ECS实例,它还会自动升级操作系统内核,安装配置最新的测试版Docker引擎,并将新创建的SLB实例添加为指定SLB的后端服务器。

docker-machine create -d aliyunecs node-1
docker-machine create -d aliyunecs node-2
docker-machine create -d aliyunecs node-3
AI 代码解读

等待三个ECS实例会创建完成,我们可以通过如下命令登录到 node-1,初始化Docker Swarm集群,显示master节点的ECS内网"eth0"地址

docker-machine ssh node-1 ip addr show eth0
docker-machine ssh node-1 docker swarm init --advertise-addr <NODE1_IP>
AI 代码解读

上面的命令会返回如下内容

Swarm initialized: current node (xxxxxxx) is now a manager.

To add a worker to this swarm, run the following command:
    docker swarm join \
    --token SWMTKN-1-1xxxxxxx-xxxxxxx \
    10.xx.xx.xx:2377

To add a manager to this swarm, run the following command:
    docker swarm join \
    --token SWMTKN-1-1xxxxxxx-xxxxxxx \
    10.xx.xx.xx:2377
AI 代码解读

之后,我们把node-2和node-3作为worker加入Docker Swarm集群,执行docker-machine ssh <NODE> 之后拷贝上文返回的第一个命令来添加一个worker节点

docker-machine ssh node-2 docker swarm join --token <WORKER_TOKEN> <NODE1_IP>:2377
docker-machine ssh node-3 docker swarm join --token <WORKER_TOKEN> <NODE1_IP>:2377
AI 代码解读

这样整个Docker集群就已经创建成功了,现在我们来部署一个WordPress应用。

生成Distributed Application Bundle

注:这一节是为了介绍DAB的创建过程,心急的同学可以忽略。

本文使用Wordpress作为实例,其Docker Compose模板如下

version: '2'
services:
  wordpress:
    image: wordpress:4.5.3
    environment:
      - WORDPRESS_DB_PASSWORD=password
      - WORDPRESS_AUTH_KEY=changeme
      - WORDPRESS_SECURE_AUTH_KEY=changeme
      - WORDPRESS_LOGGED_IN_KEY=changeme
      - WORDPRESS_NONCE_KEY=changeme
      - WORDPRESS_AUTH_SALT=changeme
      - WORDPRESS_SECURE_AUTH_SALT=changeme
      - WORDPRESS_LOGGED_IN_SALT=changeme
      - WORDPRESS_NONCE_SALT=changeme
      - WORDPRESS_NONCE_AA=changeme
    ports:
      - 80:80
    restart: always
  mysql:
    image: mysql:5.7.13
    environment:
      - MYSQL_ROOT_PASSWORD=password
    restart: always
AI 代码解读

这里我们可以看到它包含两个服务"wordpress"和"mysql", 我们可以利用 docker-compose bundle 命令生成DAB格式文件。

yili@yili-mbp:~/work/docker-experimental/wordpress$ docker-compose bundle
WARNING: Unsupported key 'restart' in services.wordpress - ignoring
WARNING: Unsupported key 'restart' in services.mysql - ignoring
Wrote bundle to wordpress.dab
AI 代码解读

注:目前DAB/Docker Service/Stack的能力还不完备,有很多Docker Compose声明还不能被正确处理,比如volume支持等等。

产生的"wordpress.dab"文件内容如下

{
  "Services": {
    "mysql": {
      "Env": [
        "MYSQL_ROOT_PASSWORD=password"
      ], 
      "Image": "mysql@sha256:a9a5b559f8821fe73d58c3606c812d1c044868d42c63817fa5125fd9d8b7b539", 
      "Networks": [
        "default"
      ]
    }, 
    "wordpress": {
      "Env": [
        "WORDPRESS_AUTH_SALT=changeme", 
        "WORDPRESS_LOGGED_IN_KEY=changeme", 
        "WORDPRESS_AUTH_KEY=changeme", 
        "WORDPRESS_NONCE_AA=changeme", 
        "WORDPRESS_SECURE_AUTH_SALT=changeme", 
        "WORDPRESS_NONCE_KEY=changeme", 
        "WORDPRESS_DB_PASSWORD=password", 
        "WORDPRESS_LOGGED_IN_SALT=changeme", 
        "WORDPRESS_NONCE_SALT=changeme", 
        "WORDPRESS_SECURE_AUTH_KEY=changeme"
      ], 
      "Image": "wordpress@sha256:7bb9549fb6d80c230bec2da6bd181be8f30e5199687e53e5ad5744a3144eae1b", 
      "Networks": [
        "default"
      ], 
      "Ports": [
        {
          "Port": 80, 
          "Protocol": "tcp"
        }
      ]
    }
  }, 
  "Version": "0.1"
}
AI 代码解读

关于DAB格式的详细定义请参见官方文档注意:目前DAB依然是一个实验性质的特性,其格式可能会在未来进行调整。

创建Wordpress Stack

我们要登录到集群的master节点来部署应用,首先我们从Github上获取相应的示例文件

git clone https://github.com/denverdino/docker-experimental
cd docker-experimental/wordpress/
AI 代码解读

利用 docker deploy命令来部署"wordpress" stack,Docker命令缺省会在本目录寻找同名的.dab文件作为Stack部署描述。

root@node-1:~/docker-experimental/wordpress# docker deploy wordpress
Loading bundle from wordpress.dab
Creating network wordpress_default
Creating service wordpress_mysql
Creating service wordpress_wordpress
AI 代码解读

之后,我们可以利用docker service lsdocker stack tasks命令来查看相应service/task状态

root@node-1:~/docker-experimental/wordpress# docker service ls
ID            NAME                 REPLICAS  IMAGE                                                                              COMMAND
3p616th5ypgc  wordpress_wordpress  1/1       wordpress@sha256:7bb9549fb6d80c230bec2da6bd181be8f30e5199687e53e5ad5744a3144eae1b  
dzyof5wz1s5y  wordpress_mysql      1/1       mysql@sha256:a9a5b559f8821fe73d58c3606c812d1c044868d42c63817fa5125fd9d8b7b539      
root@node-1:~/docker-experimental/wordpress# docker stack tasks wordpress
ID                         NAME                   SERVICE              IMAGE                                                                              LAST STATE       DESIRED STATE  NODE
2d9bjq6htn7xbcweocy192ubx  wordpress_wordpress.1  wordpress_wordpress  wordpress@sha256:7bb9549fb6d80c230bec2da6bd181be8f30e5199687e53e5ad5744a3144eae1b  Running 1 hours  Running        node-2
b31ol0r0eow2b4a5ut684dofy  wordpress_mysql.1      wordpress_mysql      mysql@sha256:a9a5b559f8821fe73d58c3606c812d1c044868d42c63817fa5125fd9d8b7b539      Running 1 hours  Running        node-3
AI 代码解读

现在我们通过docker service inspect命令检查"wordpress_wordpress"服务状态

root@node-1:~# docker service inspect wordpress_wordpress
[
    {
        "ID": "3p616th5ypgcrfxfb4a9v44ew",
        "Version": {
            "Index": 498
        },
        "CreatedAt": "2016-07-09T07:43:25.368994849Z",
        "UpdatedAt": "2016-07-09T07:43:25.378275593Z",
        "Spec": {
            "Name": "wordpress_wordpress",
            "Labels": {
                "com.docker.stack.namespace": "wordpress"
            },
            "TaskTemplate": {
                "ContainerSpec": {
                    "Image": "wordpress@sha256:7bb9549fb6d80c230bec2da6bd181be8f30e5199687e53e5ad5744a3144eae1b",
                    "Env": [
                        "WORDPRESS_AUTH_SALT=changeme",
                        "WORDPRESS_LOGGED_IN_KEY=changeme",
                        "WORDPRESS_AUTH_KEY=changeme",
                        "WORDPRESS_NONCE_AA=changeme",
                        "WORDPRESS_SECURE_AUTH_SALT=changeme",
                        "WORDPRESS_NONCE_KEY=changeme",
                        "WORDPRESS_DB_PASSWORD=password",
                        "WORDPRESS_LOGGED_IN_SALT=changeme",
                        "WORDPRESS_NONCE_SALT=changeme",
                        "WORDPRESS_SECURE_AUTH_KEY=changeme"
                    ]
                }
            },
            "Mode": {
                "Replicated": {
                    "Replicas": 1
                }
            },
            "Networks": [
                {
                    "Target": "5cb3ojhzk5snap2s3nsjtexsf",
                    "Aliases": [
                        "wordpress"
                    ]
                }
            ],
            "EndpointSpec": {
                "Mode": "vip",
                "Ports": [
                    {
                        "Protocol": "tcp",
                        "TargetPort": 80
                    }
                ]
            }
        },
        "Endpoint": {
            "Spec": {
                "Mode": "vip",
                "Ports": [
                    {
                        "Protocol": "tcp",
                        "TargetPort": 80
                    }
                ]
            },
            "Ports": [
                {
                    "Protocol": "tcp",
                    "TargetPort": 80,
                    "PublishedPort": 30000
                }
            ],
            "VirtualIPs": [
                {
                    "NetworkID": "6qj71vtgeipenr838hbjt1ash",
                    "Addr": "10.255.0.6/16"
                },
                {
                    "NetworkID": "5cb3ojhzk5snap2s3nsjtexsf",
                    "Addr": "10.0.0.5/24"
                }
            ]
        }
    }
]
AI 代码解读

我们可以看到这个"wordpress_wordpress"服务发布了一个tcp端口“30000”来对外提供服务。那么我们怎么访问这个服务呢?

利用SLB创建服务路由

阿里云的SLB提供了对多台ECS服务器进行流量分发的负载均衡服务。下面我们将利用SLB服务来配置对Swarm集群中的服务的路由和负载均衡。

首先添加侦听端口,我们选择"http"和"8080"(可以任选)作为前端协议[端口], "http"和"30000"作为后端的协议[端口]。注意 :后端端口必须与服务状态中的"PublishedPort"端口值保持一致。

14680524171808

配置健康检查配置时,可以把“/license.txt”作为检查路径,这样只要wordpress服务的Apache可以被访问就认为服务是健康的

14680521587487

完成配置

14680519323177

随后,我们就会在SLB负载均衡实例上看到相应的侦听端口和健康检查状态

14680666664389

访问SLB实例的公网IP地址,我们就可以看到熟悉的Wordpress设置界面了,

14680523321519

我们还可以利用docker service scale命令对服务进行伸缩,也可以试验一下负载均衡的效果

root@node-1:~# docker service scale wordpress_wordpress=6
wordpress_wordpress scaled to 6
root@node-1:~# docker service ps wordpress_wordpress
ID                         NAME                   SERVICE              IMAGE                                                                              LAST STATE         DESIRED STATE  NODE
2d9bjq6htn7xbcweocy192ubx  wordpress_wordpress.1  wordpress_wordpress  wordpress@sha256:7bb9549fb6d80c230bec2da6bd181be8f30e5199687e53e5ad5744a3144eae1b  Running 1 hours    Running        node-2
8w2dsfyyjb9cjiiw3d4j0111h  wordpress_wordpress.2  wordpress_wordpress  wordpress@sha256:7bb9549fb6d80c230bec2da6bd181be8f30e5199687e53e5ad5744a3144eae1b  Running 2 minutes  Running        node-1
42ym2i9lic0bvg1763acdudwc  wordpress_wordpress.3  wordpress_wordpress  wordpress@sha256:7bb9549fb6d80c230bec2da6bd181be8f30e5199687e53e5ad5744a3144eae1b  Running 2 minutes  Running        node-1
6f33yfwbrpj9g601z2c2gs3qu  wordpress_wordpress.4  wordpress_wordpress  wordpress@sha256:7bb9549fb6d80c230bec2da6bd181be8f30e5199687e53e5ad5744a3144eae1b  Running 2 minutes  Running        node-3
6xxkek3t8dgg48zs5mjwrakg8  wordpress_wordpress.5  wordpress_wordpress  wordpress@sha256:7bb9549fb6d80c230bec2da6bd181be8f30e5199687e53e5ad5744a3144eae1b  Running 2 minutes  Running        node-2
5idxgssy8t439jgoj65d6g4ln  wordpress_wordpress.6  wordpress_wordpress  wordpress@sha256:7bb9549fb6d80c230bec2da6bd181be8f30e5199687e53e5ad5744a3144eae1b  Running 2 minutes  Running        node-2
AI 代码解读

Docker的Routing Mesh简析

看完上面的示例,大家一定非常关心相应服务和路由的网络配置。我们就来简单分析一下。在"node-1"节点上,我们执行下面的命令

root@node-1:~# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
29de61a371e7        bridge              bridge              local               
bdeb358293a3        docker_gwbridge     bridge              local               
78ee3e892931        host                host                local               
6qj71vtgeipe        ingress             overlay             swarm               
70d0aaba61cc        none                null                local               
5cb3ojhzk5sn        wordpress_default   overlay             swarm               
AI 代码解读

我们可以看到有两个集群范围的overlay网络"ingress"和"wordpress_default"。其中"ingress"是在集群创建之后就自动创建的接入路由网络,而后者是部署"wordpress.dab"的时候自动创建的。

如果没有手工指定,Swarm manager会自动给需要对外访问的服务分配一个在30000-32767之内的PublishedPort。在上文中"wordpress_wordpress"所分配的端口为30000。

在Swarm集群内的每个节点上,都侦听着相同的PublishedPort来为服务提供接入路由。所以我们可以在SLB上配置一个侦听端口对集群中节点进行转发和负载均衡,而不管后端节点是否运行着服务的任务容器。Swarm集群中的所有节点都可以通过ingress网络连接到运行的任务容器,并保证入口流量被引导到正确的容器实例上。

关于Routing mesh的Ingress网络的负载均衡,其设计如下图。我们可以看到每个服务实际上都被分配了一个虚拟IP,而虚拟IP到服务任务容器端口之间的负载均衡是通过IPVS来实现的。

注意:Routing mesh的端口映射机制和bridge网络下容器publish端口的实现完全不同,不要混淆。

14680691310281

我们可以通过下面的命令来看看iptables中ECS节点主机端口到服务虚拟IP的转发配置

root@node-1:~# iptables -L DOCKER-INGRESS -t nat
Chain DOCKER-INGRESS (2 references)
target     prot opt source               destination         
DNAT       tcp  --  anywhere             anywhere             tcp dpt:30000 to:172.18.0.2:30000
RETURN     all  --  anywhere             anywhere            
AI 代码解读

总结

Docker 1.12带来了新的分布式应用打包格式,可以给在集群上部署多容器应用带来很多便利。但是目前DAB的能力和成熟度都有待提高,和Docker Compose的兼容性也存在一些问题,希望会在未来版本中逐渐解决。

如果你了解阿里云容器服务,会发现很多新Swarm模式下的服务概念和我们实现有很多相似性。我们目前是通过对现有开源编排方案上做增强来提供类似的能力。比如我们扩展了Docker Compose中Service的概念,加强生命周期管理,提供服务伸缩和自动恢复支持等。不远的未来我们也会提供平滑的升级,支持Docker最新的编排技术。

在网络方面,Docker Swarm模式的routing mesh可以和外部的负载均衡技术结合。在阿里云上我们利用SLB实现了Docker服务路由和负载均衡。目前这个工作还需要一些手动工作来完成的,在稍后我们会推出全自动化的方式自动配置SLB监听端口,让整个流程完全自动化。

此外,我们可以看到Docker Swarm模式和阿里云容器服务的路由设计原理上是类似的,只是容器服务中每个节点利用HAProxy为服务提供7层或4层的路由实现,而Docker Engine是每个节点利用IPVS做为4层的路由实现。7层的优势在于可以支持virtual host、session affinity等较复杂的路由策略,而基于kernel空间的4层路由可以有更好的性能表现。我们计划会融合这些技术在阿里云容器服务中给大家带来更好的体验。

想了解更多容器服务内容,请访问 https://www.aliyun.com/product/containerservice

相关实践学习
巧用云服务器ECS制作节日贺卡
本场景带您体验如何在一台CentOS 7操作系统的ECS实例上,通过搭建web服务器,上传源码到web容器,制作节日贺卡网页。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
打赏
0
0
0
7
80333
分享
相关文章
Docker部署RocketMQ5.2.0集群
本文详细介绍了如何使用Docker和Docker Compose部署RocketMQ 5.2.0集群。通过创建配置文件、启动集群和验证容器状态,您可以快速搭建起一个RocketMQ集群环境。希望本文能够帮助您更好地理解和应用RocketMQ,提高消息中间件的部署和管理效率。
262 91
zabbix7.0.9安装-以宝塔安装形式-非docker容器安装方法-系统采用AlmaLinux9系统-最佳匹配操作系统提供稳定运行环境-安装教程完整版本-优雅草卓伊凡
zabbix7.0.9安装-以宝塔安装形式-非docker容器安装方法-系统采用AlmaLinux9系统-最佳匹配操作系统提供稳定运行环境-安装教程完整版本-优雅草卓伊凡
90 30
揭秘 Microsoft.Docker.SDK:让容器开发更轻松的强大工具揭秘
随着云计算和容器技术的快速发展,`Docker` 已经成为容器化技术的事实标准。`Microsoft` 作为 `Docker` 的主要支持者和参与者,推出了 `Microsoft.Docker.SDK`,旨在帮助开发者更轻松地进行容器开发。本文将深入揭秘 Microsoft.Docker.SDK 的功能、使用方法以及它在容器开发中的应用。
36 12
自学软硬件第755 docker容器虚拟化技术youtube视频下载工具
docker容器虚拟化技术有什么用?怎么使用?TubeTube 项目使用youtube视频下载工具
|
7天前
|
在Docker上部署Ollama+AnythingLLM完成本地LLM Agent部署
通过以上步骤,您可以成功在Docker上部署Ollama和AnythingLLM,实现本地LLM Agent的功能。在部署过程中,确保环境和配置正确,以避免不必要的问题。希望本文能够帮助您顺利完成部署,并在本地环境中高效地使用LLM模型。
241 8
Stirling-PDF:51.4K Star!用Docker部署私有PDF工作站,支持50多种PDF操作,从此告别在线工具
Stirling-PDF 是一款基于 Docker 的本地化 PDF 编辑工具,支持 50 多种 PDF 操作,包括合并、拆分、转换、压缩等,同时提供多语言支持和企业级功能,满足个人和企业用户的多样化需求。
104 6
Stirling-PDF:51.4K Star!用Docker部署私有PDF工作站,支持50多种PDF操作,从此告别在线工具
容器化浪潮下的AI赋能:智能化运维与创新应用
近年来,容器技术以其轻量、高效、可移植的特性成为云原生时代的基石,推动应用开发和部署方式革新。随着容器化应用规模扩大,传统运维手段逐渐力不从心。AI技术的引入为容器化生态带来新活力,实现智能监控、自动化故障诊断与修复及智能资源调度,提升运维效率和可靠性。同时,AI驱动容器化创新应用,如模型训练、边缘计算和Serverless AI服务,带来更多可能性。未来,AI与容器技术的融合将更加紧密,推动更智能、高效的运维平台和丰富的创新应用场景,助力数字化转型。
docker快速部署OS web中间件 数据库 编程应用
通过Docker,可以轻松地部署操作系统、Web中间件、数据库和编程应用。本文详细介绍了使用Docker部署这些组件的基本步骤和命令,展示了如何通过Docker Compose编排多容器应用。希望本文能帮助开发者更高效地使用Docker进行应用部署和管理。
60 19
Linux服务器部署docker windows
在当今软件开发中,Docker成为流行的虚拟化技术,支持在Linux服务器上运行Windows容器。流程包括:1) 安装Docker;2) 配置支持Windows容器;3) 获取Windows镜像;4) 运行Windows容器;5) 验证容器状态。通过这些步骤,你可以在Linux环境中顺利部署和管理Windows应用,提高开发和运维效率。
80 1
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等