美文网首页
AWS服务建设之路-Docker集群

AWS服务建设之路-Docker集群

作者: Jude95 | 来源:发表于2019-02-07 15:55 被阅读23次

    最近的项目处于种种原因要放到亚马逊上面,也正好体验一下世界最大云计算平台的服务。于是又开始了漫长的爬坑路。不得不说AWS的管理交互台设计充满了工业气息,新手很难上手,但熟练工会觉得很直观。
    简单来说分4步:

    • 上传镜像
    • 创建任务定义
    • 创建集群
    • 创建服务

    ECR 存储库

    ECR是私有镜像仓库,先把自己的镜像上传上来,这一步的坑就在于要上传镜像不能直接 docker login 需要

    • 安装 awscli
    • 创建拥有ECR权限的IAM用户
    • awscli 配置账户
    • 使用awscli登陆 $(aws ecr get-login --no-include-email --region ap-southeast-1)
    • 创建正确的镜像仓库
    • 再正常的 docker push
      image.png

    Task Definitions 任务定义

    ECS有一个很重要的概念,任务定义。这个概念类似于 k8s 的 pod。任务定义抽象出了任务这个概念,一项任务可以包含多个docker镜像及对应的参数/环境配置,并且拥有CPU,内存限额。
    任务定义拥有版本号,只能创建新版本不能修改以前版本。
    而在集群中的调度则是以任务定义为对象。
    所以我们为我们每一个服务创建了1个任务定义,一个任务定义包含1个镜像。


    image.png

    网络模式

    image.png

    这里有3种网络模式供选择:

    • 桥接模式 略
    • 注解模式 略
    • awsvpc
      这个是最有意思的模式,是ECS独有的,单独为这个任务分配一个网卡及IP,这样就可以实现比如,1台EC2上多个容器同时监听同一端口,因为监听的是不同IP的端口。当然还有更骚的操作,后面介绍,是一个大杀器。
      但要注意因为一台EC2至多只能额外绑定3张网卡(不同机型不一样),所以一台EC2上最多只能运行3个 awsvpc 模式的任务。

    大部分情况我们都使用桥接模式,少部分情况使用 awsvpc。主机模式则尽量不要使用,不利于编排。awsvpc的具体使用场景会在下文服务发现章节介绍。

    动态端口映射

    动态端口映射技术,是指将容器在宿主机上的外部端口随机映射,只在桥接模式下有效。

    image.png
    在桥接模式下,容器的端口映射项,主机端口填0,ECS就会为这个任务随机的开放主机端口,为什么要随机端口?因为利于编排!如果不动态映射,就需要自己管理端口分配,比如A服务8080端口,B服务8081端口,很麻烦。
    使用动态端口映射,端口不用自己管理,当将服务与负载均衡绑定,端口变化时会自动修改负载均衡的目标组。
    也会存在一些问题,主要是在服务发现这里,但可以完美解决,详见服务发现章节。

    简单日志

    image.png

    勾上日志配置,ECS就会自动把镜像的标准输出定向到 CloudWatch,就可以去那里查看镜像日志了,当然专业的日志系统还是得ELK。

    集群

    image.png

    ECS有2种集群,Fargate 与 EC2 Linux。

    • Fargate
      Fargate 是无服务器架构,不需要自己构建真实EC2集群,只需要设定好所需CPU/内存,提交任务定义后AWS自动帮你调度运行。
    • EC2
      在自己建立的EC2集群上运行。

    Fargate是很酷炫的架构,特别是在资源占用量不稳定,时间不确定的情况下很合适。而且全部使用awsvpc网络模式,所有的服务都可以拥有独立IP,纯正的无服务器架构。只有一个缺点,贵(同样资源量是EC2的3倍价格...


    image.png

    建议创建空集群,再自行添加服务器,不然容易触发一些 keng

    任务

    上面说了任务定义,那么任务这个概念也很简单,被运行的任务定义。
    一个任务可能包含多个容器,这个任务可能是在有限时间内执行完毕就停止的,比如一次性脚本,也可能是无限运行的,比如nginx服务器。

    服务

    服务这个概念比较复杂,一个服务会管理一个任务定义在运行时的方方面面

    • 运行数量
      比如服务配置了要保持3个任务数,那么当某个任务停止了,服务会立即再启动一个新任务。
    • 任务放置
      比如是在多个EC2实例上尽可能分布,还是尽量集中在一台EC2实例上。
    • 负载均衡配置
      直接将任务定义的容器绑定到负载均衡的目标组,这也就是为什么上面说要使用动态端口映射,这样就不需要再做端口分配管理,不管容器的宿主机端口分配到哪,负载均衡都能正确转发流量到容器。
      不暴露到外网的内部服务不需要负载均衡。
    • 任务运行监控

    服务没有停止功能,只能修改任务数为0。
    服务删除后,需要手动停止已经运行的任务。

    服务发现

    AWS提供基于Router53(DNS服务)的服务发现,其实很难用,awsvpc模式的很方便,桥接模式下特难用。
    在awsvpc模式中,因为每个任务都有自己的IP,所以端口可以直接固定,不会存在冲突,配合基于Router53的服务发现可以直接完成完美的服务发现--无论如何更新重启服务,总能通过固定域名访问到服务。但因为一台服务器只能绑定3张网卡,所以只能启动3个awsvpc模式容器。
    在桥接模式中,每个任务都使用宿主机的ip,以及随机分配的端口,所以服务发现需要带上端口,不然也不能正常发现。AWS提供SRV类型的DNS记录用作服务发现,本身是没有问题,但SRV并不是被广泛接受的记录类型,浏览器与网络库均不能解析SRV记录,所以要访问服务还需要定制DNS解析。
    所以我们最终选择使用Eureka作为服务发现服务,使用awsvpc作为补充的服务发现服务,比如将Eureka本身及xxl-job等使用awsvpc部署。

    服务注册

    在选用了Eureka之后,又遇到了问题。因为使用了动态端口映射,所以向Eureka注册的端口不是Spring的监听端口,并且容器内部无法知道宿主机的ip与端口。
    这里通过多种方式配合破局:

    • 读取ECS元数据
      ECS服务提供metadata服务,启用后会向容器挂着一个文件,文件内会写入容器相关信息,端口,宿主机信息,启动参数等等。在 entrypoint.sh 中,读取解析metadata获取ip,与端口,写进环境变量。
        export ECS_INSTANCE_IP_ADDRESS=$(curl --retry 5 --connect-timeout 3 -s 169.254.169.254/latest/meta-data/local-ipv4)
        export ECS_TASK_NON_SECURE_INSTANCE_PORT=$(cat ${ECS_CONTAINER_METADATA_FILE} | grep HostPort | awk -F ": " '{print $2}' | sed 's/,$//g')
    

    不过要注意,启用元数据服务,需要修改ECS代理配置,而这个配置是在集群创建时就写入服务器的,所以要修改ECS代理配置,必须要先修改自动伸缩组的初始化脚本,再删除伸缩组内所有服务器,再重新添加服务器。

    • Eureka修改注册地址
    eureka:
      client:
        serviceUrl:
          defaultZone: http://eureka.xxx/eureka/
      instance:
        prefer-ip-address: true
        ip-address: ${ECS_INSTANCE_IP_ADDRESS}
        non-secure-port: ${ECS_TASK_NON_SECURE_INSTANCE_PORT}
        instance-id: ${eureka.instance.ip-address}:${eureka.instance.non-secure-port}
        home-page-url: http://${eureka.instance.ip-address}:${eureka.instance.non-secure-port}/actuator
        status-page-url: http://${eureka.instance.ip-address}:${eureka.instance.non-secure-port}/actuator/info
        health-check-url: http://${eureka.instance.ip-address}:${eureka.instance.non-secure-port}/actuator/health
    

    这样就可以在Eureka中心正确展示服务信息了。

    相关文章

      网友评论

          本文标题:AWS服务建设之路-Docker集群

          本文链接:https://www.haomeiwen.com/subject/emvwsqtx.html