阿里云容器服务--自定义路由和负载均衡策略

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 阿里云容器服务已经提供了默认的简单路由服务来提供http请求的路由和负载均衡,但是对某些对路由和负载均衡有定制需求的用户来说,这往往不能满足用户的需求,下面我们就来介绍阿里云容器服务推出的自定义路由镜像acs/proxy

简单示例

让我们先从一个简单的例子开始,我们会部署一个acs/proxy容器,容器前面配置一个slb实例,让大家可以访问,同时在后端挂上一个nginx,这里我们只展示nginx的首页。 compose模板如下所示:

lb:
    image:  registry.aliyuncs.com/acs/proxy:0.5
    ports:
            -  '80:80'
    restart:  always
    labels:
        # addon 使得proxy镜像有订阅注册中心的能力,动态加载服务的路由
        aliyun.custom_addon:  "proxy"
        # 每台vm 部署一个该镜像的容器
        aliyun.global:  "true"
        #  前端绑定SLB
        aliyun.lb.port_80: tcp://proxy_test:80
    environment:
        #  支持加载路由的后端容器的范围,"*"表示整个集群,默认为应用内的服务
        ADDITIONAL_SERVICES:  "*"
appone:
    expose:  # 被代理的服务一定要使用expose或者ports告诉proxy容器暴露哪个端口
        -  80/tcp 
    image:  'nginx:latest'
    labels:
        #  此处支持http/https/ws/wss  协议,必须使用用户自己的域名而不是容器服务提供的测试域名
        aliyun.proxy.VIRTUAL_HOST:  "http://appone.example.com"
    restart:  always

服务启动成功后,页面如下图所示
Screen_Shot_2016_09_10_at_2_28_08_PM

开启会话保持

lb:
    image:  registry.aliyuncs.com/acs/proxy:0.5
    ports:
            -  '80:80'
    restart:  always
    labels:
        # addon 使得proxy镜像有订阅注册中心的能力,动态加载服务的路由
        aliyun.custom_addon:  "proxy"
        # 每台vm 部署一个该镜像的容器
        aliyun.global:  "true"
        #  前端绑定SLB
        aliyun.lb.port_80: tcp://proxy_test:80
    environment:
        #  支持加载路由的后端容器的范围,"*"表示整个集群,默认为应用内的服务
        ADDITIONAL_SERVICES:  "*"
appone:
    ports:
        -  80/tcp
        -  443/tcp
    image:  'nginx:latest'
    labels:
        #  此处支持http/https/ws/wss  协议
        aliyun.proxy.VIRTUAL_HOST:  "http://appone.example.com"
        # 此处支持会话保持,使用cookie的方式,键为 CONTAINERID
        aliyun.proxy.COOKIE: "CONTAINERID insert indirect"
    restart:  always

自定义503页面

当我们直接输入SLB的VIP地址而不是域名时,访问的页面如下图所示,返回503错误页面
Screen_Shot_2016_09_10_at_2_31_55_PM
我们希望在503页面增加一些提示信息。在容器所在的vm增加文件夹/errors,同时增加文件/errors/503.http,文件内容如下:

HTTP/1.0 503 Service Unavailable
Cache-Control: no-cache
Connection: close
Content-Type: text/html;charset=UTF-8

<html><body><h1>503 Service Unavailable</h1>

<h3>No server is available to handle this request.</h3>

<h3>如果您看到这个页面,说明您访问服务出现了问题,请按如下步骤排查解决问题:</h3>
<li>如果您是应用的访问者,请寻求应用的维护者解决问题。</li>
<li>如果您是应用的维护者,继续查看下面的信息。</li>
<li>您现在使用的是简单路由服务,整个请求会从SLB -> acsrouting应用容器 -> 您的应用容器, 请按下列步骤排查。</li>
<li>请登陆容器服务控制台,在左侧边栏选择"服务",在"服务列表"选择相应的"集群",点击暴露到公网的"服务",查看服务的"访问端点",仔细检查您的访问域名与在相应的服务中配置的域名是否一致。</li>
<li>按照<a href="https://help.aliyun.com/knowledge_detail/42660.html">简单路由服务链路排查</a>进行问题定位和排查。</li>
<li>查看<a href="https://help.aliyun.com/knowledge_detail/42658.html">路由常见问题文档</a>。</li>
<li>如果上面的方式还没有解决您的问题,请<a href="https://workorder.console.aliyun.com/#/ticket/add?productId=1254">提交工单</a>,联系技术人员协助解决,我们会竭诚为您服务。</li>
</body></html>

你也可以修改为你展示的错误页面。修改compose模板如下:

lb:
    image:  registry.aliyuncs.com/acs/proxy:0.5
    ports:
            -  '80:80'
    restart:  always
    labels:
        # addon 使得proxy镜像有订阅注册中心的能力,动态加载服务的路由
        aliyun.custom_addon:  "proxy"
        # 每台vm 部署一个该镜像的容器
        aliyun.global:  "true"
        #  前端绑定SLB
        aliyun.lb.port_80: tcp://proxy_test:80
    environment:
        #  支持加载路由的后端容器的范围,"*"表示整个集群,默认为应用内的服务
        ADDITIONAL_SERVICES:  "*"
        EXTRA_FRONTEND_SETTINGS_80: "errorfile 503 /usr/local/etc/haproxy/errors/503.http"
    volumes:
        - /errors/:/usr/local/etc/haproxy/errors/
appone:
    ports:
        -  80/tcp
        -  443/tcp
    image:  'nginx:latest'
    labels:
        #  配置url,支持指定path,此处支持http/https/ws/wss  协议
        aliyun.proxy.VIRTUAL_HOST:  "http://appone.example.com"
    restart:  always

输入SLB的VIP之后,显示的503页面如下图所示:
Screen_Shot_2016_09_10_at_2_47_49_PM

支持泛域名

我们希望nginx的后端支持泛域名,即appone.example.com能访问到nginx首页,*.example.com也能访问到nginx的首页,修改配置如下即可:

lb:
    image:  registry.aliyuncs.com/acs/proxy:0.5
    ports:
            -  '80:80'
    restart:  always
    labels:
        # addon 使得proxy镜像有订阅注册中心的能力,动态加载服务的路由
        aliyun.custom_addon:  "proxy"
        # 每台vm 部署一个该镜像的容器
        aliyun.global:  "true"
        #  前端绑定SLB
        aliyun.lb.port_80: tcp://proxy_test:80
    environment:
        #  支持加载路由的后端容器的范围,"*"表示整个集群,默认为应用内的服务
        ADDITIONAL_SERVICES:  "*"
        EXTRA_FRONTEND_SETTINGS_80: "errorfile 503 /usr/local/etc/haproxy/errors/503.http"
    volumes:
        - /errors/:/usr/local/etc/haproxy/errors/
appone:
    ports:
        -  80/tcp
        -  443/tcp
    image:  'nginx:latest'
    labels:
        #  配置url,支持指定path,此处支持http/https/ws/wss  协议
        aliyun.proxy.VIRTUAL_HOST:  "http://*.example.com"
    restart:  always

绑定host,输入域名www.example.com之后,显示nginx首页如下图所示:
Screen_Shot_2016_09_10_at_3_01_49_PM

配置默认的后端

有时候,我们希望直接通过IP也能访问到后端的nginx,把url配置去掉,把修改配置如下即可:

lb:
    image:  registry.aliyuncs.com/acs/proxy:0.5
    ports:
            -  '80:80'
    restart:  always
    labels:
        # addon 使得proxy镜像有订阅注册中心的能力,动态加载服务的路由
        aliyun.custom_addon:  "proxy"
        # 每台vm 部署一个该镜像的容器
        aliyun.global:  "true"
        #  前端绑定SLB
        aliyun.lb.port_80: tcp://proxy_test:80
    environment:
        #  支持加载路由的后端容器的范围,"*"表示整个集群,默认为应用内的服务
        ADDITIONAL_SERVICES:  "*"

        # 返回503时,指定错误页面
        EXTRA_FRONTEND_SETTINGS_80: "errorfile 503 /usr/local/etc/haproxy/errors/503.http"
    volumes:
        # 从主机挂载错误页面到容器内部
        - /errors/:/usr/local/etc/haproxy/errors/
appone:
    ports:
        -  80/tcp
        -  443/tcp
    image:  'nginx:latest'
    labels:
        #  配置url,支持指定path,此处支持http/https/ws/wss  协议
        aliyun.proxy.required: "true"
    restart:  always

输入SLB的VIP之后,显示nginx首页如下图所示:
Screen_Shot_2016_09_10_at_2_55_59_PM

url参数值选择后端

有些用户希望能够根据url参数值不同的来代理不同的后端,以下示例将通过http://www.example.com?backend=appone 访问服务appone,即nginx首页,通过http://www.example.com?backend=apptwo 访问服务apptwo,即hello world首页。应用模板代码如下所示:

lb:
    image:  registry.aliyuncs.com/acs/proxy:0.5
    ports:
            -  '80:80'
    restart:  always
    labels:
        # addon 使得proxy镜像有订阅注册中心的能力,动态加载服务的路由
        aliyun.custom_addon:  "proxy"
        # 每台vm 部署一个该镜像的容器
        aliyun.global:  "true"
        #  前端绑定SLB
        aliyun.lb.port_80: tcp://proxy_test:80
    environment:
        #  支持加载路由的后端容器的范围,"*"表示整个集群,默认为应用内的服务
        ADDITIONAL_SERVICES:  "*"
        #  获取url中参数名称为backend的参数值,同时将HOST header 修改为要匹配的后端的域名
        EXTRA_FRONTEND_SETTINGS_80:  "  http-request set-header HOST %[urlp(backend)].example.com"
appone:
    ports:
        -  80/tcp
        -  443/tcp
    image:  'nginx:latest'
    labels:
        #   配置url,支持指定path,此处支持http/https/ws/wss  协议
        aliyun.proxy.VIRTUAL_HOST:  "http://appone.example.com"
    restart:  always
apptwo:
    ports:
        -  80/tcp
    image:  'registry.cn-hangzhou.aliyuncs.com/linhuatest/hello-world:latest'
    labels:
        #   配置url,支持指定path,此处支持http/https/ws/wss  协议
        aliyun.proxy.VIRTUAL_HOST:  "http://apptwo.example.com"
    restart:  always

绑定host,输入链接http://www.example.com?backend=appone ,显示服务appone的nginx首页,如下所示
Screen_Shot_2016_09_10_at_3_40_04_PM
绑定host,输入链接http://www.example.com?backend=apptwo ,显示服务apptwo的hello world首页,如下所示
Screen_Shot_2016_09_10_at_3_40_20_PM

记录访问日志

lb:
    image:  registry.aliyuncs.com/acs/proxy:0.5
    ports:
            -  '80:80'
    restart:  always
    labels:
        # addon 使得proxy镜像有订阅注册中心的能力,动态加载服务的路由
        aliyun.custom_addon:  "proxy"
        # 每台vm 部署一个该镜像的容器
        aliyun.global:  "true"
        #  前端绑定SLB
        aliyun.lb.port_80: tcp://proxy_test:80
    environment:
        #  支持加载路由的后端容器的范围,"*"表示整个集群,默认为应用内的服务
        ADDITIONAL_SERVICES:  "*"
        EXTRA_DEFAULT_SETTINGS: "log rsyslog local0,log global,option httplog"
    links:
        - rsyslog:rsyslog
rsyslog:
    image: registry.cn-hangzhou.aliyuncs.com/linhuatest/rsyslog:latest
appone:
    ports:
        -  80/tcp
        -  443/tcp
    image:  'nginx:latest'
    labels:
        #  此处支持http/https/ws/wss  协议
        aliyun.proxy.VIRTUAL_HOST:  "http://appone.example.com"
    restart:  always

日志会直接打到rsyslog容器的标准输出中,通过docker logs $rsyslog_container_name 即能看到自定义路由的访问日志

服务间的负载均衡

以下模板创建一个负载均衡服务lb和一个应用服务appone,整体对外提供域名为appone.example.com的服务

lb:
    image:  registry.aliyuncs.com/acs/proxy:0.5
    hostname: proxy  # 指定该服务的域名为proxy,即proxy会解析到所有部署了该镜像的容器
    ports:
            -  '80:80'
    restart:  always
    labels:
        # addon 使得proxy镜像有订阅注册中心的能力,动态加载服务的路由
        aliyun.custom_addon:  "proxy"
        # 每台vm 部署一个该镜像的容器
        aliyun.global:  "true"
        #  前端绑定SLB
        aliyun.lb.port_80: tcp://proxy_test:80
    environment:
        #  支持加载路由的后端容器的范围,"*"表示整个集群,默认为应用内的服务
        ADDITIONAL_SERVICES:  "*"
appone:
    ports:
        -  80/tcp
        -  443/tcp
    image:  'nginx:latest'
    labels:
        #  此处支持http/https/ws/wss  协议
        aliyun.proxy.VIRTUAL_HOST:  "http://appone.example.com"
    restart:  always

以下模板作为一个客户端,访问应用服务appone,但是它的访问路径是请求访问负载均衡服务lb,然后再反向代理到应用服务appone的。

restclient: # 模拟rest服务消费者
  image: registry.aliyuncs.com/acs-sample/alpine:3.3
  command: "sh -c 'apk update; apk add curl; while true; do curl --head http://appone.example.com; sleep 1; done'" #访问rest服务,测试负载均衡
  tty: true  
  external_links: 
    - "proxy:appone.example.com" #指定link的服务的域名,以及该域名的别名

在服务restclient的容器中,你会发现域名appone.example.com是解析到负载均衡服务lb的所有容器IP的。

/ # drill appone.example.com
;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 60917
;; flags: qr rd ra ; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;; appone.example.com.  IN      A
;; ANSWER SECTION:
appone.example.com.     600     IN      A       172.18.3.4
appone.example.com.     600     IN      A       172.18.2.5
appone.example.com.     600     IN      A       172.18.1.5
;; AUTHORITY SECTION:
;; ADDITIONAL SECTION:
;; Query time: 0 msec
;; SERVER: 127.0.0.11
;; WHEN: Mon Sep 26 07:09:40 2016
;; MSG SIZE  rcvd: 138   

配置监控页面示例

lb:
    image:  registry.aliyuncs.com/acs/proxy:0.5
    ports:
            -  '80:80'
            -  '127.0.0.1:1935:1935'       # 监控页面对公网暴露的端口,有安全风险,请谨慎配置
    restart:  always
    labels:
        aliyun.custom_addon:  "proxy"
        aliyun.global:  "true"
        aliyun.lb.port_80: tcp://proxy_test:80
    environment:
        ADDITIONAL_SERVICES:  "*"
        STATS_AUTH: "admin:admin"         # 监控时用于登录的账号和密码,可以自定义
        STATS_PORT: "1935"                # 监控使用的端口,可以自定义
appone:
    expose: 
        -  80/tcp 
    image:  'nginx:latest'
    labels:
        aliyun.proxy.VIRTUAL_HOST:  "http://appone.example.com"
    restart:  always

登录到自定义路由镜像所在的每一台机器(每一台机器都可能接收请求,不管应用容器在哪台机器上面),请求 acs/proxy 健康检查页面,注意按照应用模版的STATS_AUTH环境变量配置正确的用户名和密码,如下所示。

root@c68a460635b8c405e83c052b7c2057c7b-node2:~# curl -Ss -u admin:admin 'http://127.0.0.1:1935/' &> test.html

将页面 test.html 拷贝到有浏览器的机器,用浏览器打开本地文件 test.html,查看stats监控统计页面,显示为绿色,表示acs/proxy容器到后端容器的网络是连通的,在正常工作,显示为其他颜色则为异常。

相关实践学习
Docker镜像管理快速入门
本教程将介绍如何使用Docker构建镜像,并通过阿里云镜像服务分发到ECS服务器,运行该镜像。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
22天前
|
运维 Kubernetes 监控
构建高效自动化运维系统:基于容器技术的策略与实践
【4月更文挑战第19天】随着云计算和微服务架构的兴起,传统的运维模式正逐渐向自动化、智能化转型。本文将探讨如何利用容器技术构建一个高效、可靠的自动化运维系统,涵盖系统设计原则、关键技术选型以及实践经验分享。通过引入容器技术,我们可以实现应用的快速部署、弹性伸缩和故障自愈,从而提高运维效率,降低系统维护成本。
|
13天前
|
运维 JavaScript Java
Serverless 应用引擎产品使用之在阿里云函数计算中想为两个不同的服务分别开通自定义域名如何解决
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
26 1
|
2天前
|
存储 安全 数据安全/隐私保护
【Docker 专栏】Docker 容器化应用的备份与恢复策略
【5月更文挑战第9天】本文探讨了Docker容器化应用的备份与恢复策略,强调了备份在数据保护、业务连续性和合规要求中的关键作用。内容涵盖备份的重要性、内容及方法,推荐了Docker自带工具和第三方工具如Portainer、Velero。制定了备份策略,包括频率、存储位置和保留期限,并详细阐述了恢复流程及注意事项。文章还提及案例分析和未来发展趋势,强调了随着技术发展,备份与恢复策略将持续演进,以应对数字化时代的挑战。
【Docker 专栏】Docker 容器化应用的备份与恢复策略
|
3天前
|
Java Linux 数据安全/隐私保护
Docker自定义JDK镜像并拉取至阿里云镜像仓库全攻略
Docker自定义JDK镜像并拉取至阿里云镜像仓库全攻略
|
4天前
|
负载均衡 算法 Java
Ribbon自定义负载均衡算法
Ribbon自定义负载均衡算法
13 1
|
4天前
|
监控 安全 数据安全/隐私保护
【Docker专栏】Docker容器安全:防御与加固策略
【5月更文挑战第7天】本文探讨了Docker容器安全,指出容器化技术虽带来便利,但也存在安全隐患,如不安全的镜像、容器逃逸、网络配置不当等。建议采取使用官方镜像、镜像扫描、最小权限原则等防御措施,并通过安全的Dockerfile编写、运行时安全策略、定期更新和访问控制等加固容器安全。保持警惕并持续学习安全实践至关重要。
【Docker专栏】Docker容器安全:防御与加固策略
|
11天前
|
负载均衡
Ribbon负载均衡策略
Ribbon负载均衡策略
|
13天前
|
运维 IDE Serverless
Serverless 应用引擎产品使用之阿里函数计算中,阿里云容器镜像服务(Container Registry)中创建自定义镜像,然后将其部署到FC上如何解决
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
27 0
|
13天前
|
运维 网络协议 安全
Serverless 应用引擎产品使用之阿里云函数计算中添加自定义域名进行域名DNS验证如何解决
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
22 1
|
29天前
|
Kubernetes Docker 容器
Kubernetes容器的重启策略
Kubernetes容器的重启策略
16 0
Kubernetes容器的重启策略

相关产品

  • 容器计算服务