• Feeds

  • Posts Tagged ‘Google’


    Kubernetes – Google分布式容器技术初体验

    Kubernetes是Google开源的容器集群管理系统。前几天写的 分布式服务框架的4项特性 中提到一个良好的分布式服务框架需要实现

    服务的配置管理。包括服务发现、负载均衡及服务依赖管理。
    服务之间的调度及生命周期管理。

    由于Kubernetes包含了上述部分特性,加上最近Google新推出的Container Engine也是基于Kubernetes基础上实现,因此最近对Kubernetes进行了一些尝试与体验。

    运行环境

    Kubernetes目前处于一个快速迭代的阶段,同时它的相关生态圈(比如docker,etcd)也在快速发展,这也意味没有适合新手使用非常顺畅的版本,网上的各种文档(也包括官方文档)和当前最新的发布版会有不同程度滞后或不适用的情况,因此在使用时可能会碰到各种细节的障碍,而且这些新版本碰到的问题,很有可能在网上也搜索不到解决方案。

    Kubernetes设计上并未绑定Google Cloud平台,但由于以上原因,为了减少不必要的障碍,初次尝试建议使用GCE作为运行环境(尽管GCE是一个需要收费的环境)。默认的cluster启动脚本会创建5个GCE instance,测试完需要自己及时主动删除。为了避免浪费,可以将minions减少,同时instance类型选择f1-micro。费用方面一个f1-micro instance运行1个月大约50元人民币,因此用GCE来测试Kubernetes,如果仅是测试时候开启的话,并不会产生太多费用。

    Pods及Replication Controller

    Kubernetes的基本单元是pods,用来定义一组相关的container。Kubernetes的优点是可以通过定义一个replicationController来将同一个模块部署到任意多个容器中,并且由Kubernetes自动管理。比如定义了一个apache pod,通过replicationController设置启动100个replicas,系统就会在pod创建后自动在所有可用的minions中启动100个apache container。并且轻松的是,当container或者是所在的服务器不可用时,Kubernetes会自动通过启动新的container来保持100个总数不变,这样管理一个大型系统变得轻松和简单。

    kubernetes

    Service 微服务

    在解决部署问题之后,分布式服务中存在的一大难题是服务发现(或者叫寻址),用户访问的前端模块需要访问系统内部的后端资源或者其他各种内部的服务,当一个内部服务通过replicationController动态部署到不同的节点后,而且还存在前文提到的动态切换的功能,前端应用如何来发现并访问这些服务?Kubernetes的另外一个亮点功能就是service,service是一个pod服务池的代理抽象,目前的实现方法是通过一个固定的虚拟IP及端口来定义,并且通过分布在所有节点上的proxy来实现内部服务对service的访问。

    Kubernetes自身的配置是保存在一个etcd(类似ZooKeeper)的分布式配置服务中。服务发现为什么不通过etcd来实现?Tim的判断更多的是为了Kubernetes上的系统和具体的配置服务解耦。由于服务发现属于各个系统内部的业务逻辑,因此如果使用etcd将会出现业务代码的逻辑中耦合了etcd,这样可能会让很多架构师望而却步。

    尽管没有耦合etcd,部署在Kubernetes中的服务需要通过container中的环境变量来获得service的地址。环境变量虽然简单,但它也存在很多弊端,如存在不方便动态更改等问题。另外service目前的实现是将虚拟IP通过iptables重定向到最终的pod上,作者也提到iptables定向的局限性,不适合作为大型服务(比如上千个内部service一起运作时)的实现。

    services_detail

    由于service定位是系统内部服务,因此默认情况下虚拟IP无法对外提供服务,但Kubernetes当前版本并没直接提供暴露公网IP及端口的能力,需要借助云服务(比如GCE)的load balancer来实现。

    小结

    总的看来Kubernetes提供的能力非常令人激动,pod、replicationController以及service的设计非常简单实用。但如果立即将服务迁移到Kubernetes,还需要面对易变的环境。另外尽管Kubernetes提供health check的机制,但service生产环境所需的苛刻的可用性还未得到充分的验证。Service发现尽管不跟Kubernetes的内部实现解耦,但利用环境变量来实现复杂系统的服务发现也存在一些不足。

    安装说明

    Kubernetes cluster简单安装说明如下,需要尝试的朋友可参考。

    前提准备
    一个64 bit linux环境,最好在墙外的,避免访问google cloud出现超时或reset等问题;另外创建Google Cloud帐号,确保创建instances以及Cloud Storage功能可用;

    安装步骤
    1. 安装go语言环境(可选,如果需要编译代码则需要)

    2. 安装Google cloud sdk
    $ curl https://sdk.cloud.google.com | bash
    $ gcloud auth login
    按提示完成授权及登录

    3. 安装 etcd 二进制版本(V0.4.6), 解压后将其目录加入PATH

    4. 安装 kubernetes最新的relase binary版本(V0.5.1)
    修改 cluster/gce/config-default.sh,主要是修改以下字段以便节约资源。

    MASTER_SIZE=f1-micro
    MINION_SIZE=f1-micro
    NUM_MINIONS=3
    

    在kubernetes目录运行
    $ cluster/kube-up.sh

    执行成功后会显示 done

    5. 测试pod
    以上脚本启动了examples/monitoring 下面定义的service,如果尝试启动其它自己的pods,比如启动一个tomcat集群

    {
      "id": "tomcatController",
      "kind": "ReplicationController",
      "apiVersion": "v1beta1",
      "desiredState": {
        "replicas": 2,
        "replicaSelector":{"name": "tomcatCluster"},
        "podTemplate":{
      "desiredState": {
        "manifest": {
          "version": "v1beta1",
          "id": "tomcat",
          "containers": [{
            "name": "tomcat",
            "image": "tutum/tomcat",
         "ports": [
         {"containerPort":8080,"hostPort":80}
         ]
         }]
        }
      },
      "labels": {"name": "tomcatCluster"}}
      },
      "labels": {
        "name": "tomcatCluster",
      }
    }
    

    其中pod的tomcat image可以通过Docker Hub Registry https://registry.hub.docker.com/ 搜索及获取

    $ cluster/kubectl.sh create -f tomcat-pod.json

    创建成功后通过 cluster/kubectl.sh get pods 来查看它所在minion及ip,可以通过curl或浏览器来访问(请开启GCE防火墙端口设置)。

    再定义一个 service

    {
      "id": "tomcat",
      "kind": "Service",
      "apiVersion": "v1beta1",
      "port": 8080,
      "containerPort": 8080,
      "labels": {
        "name": "tomcatCluster"
      },
      "selector": {
        "name": "tomcatCluster"
      }
    }
    

    保存为 tomcat-service.json

    $ cluster/kubectl.sh create -f tomcat-service.json
    检查service启动后的ip及端口,由于service是内部ip,可以在GCE上通过curl来测试及验证。
    $ cluster/kubectl.sh get services

    6. 关闭cluster
    cluster/kube-down.sh

    Google的系统工程师(SA)如何工作

    本文根据系统管理领域知名博客 Thomas A. LimoncelliWhat is system administration like at Google 整理而成,添加了部分笔者观点。

    Google的系统工程师(System Administrator)如何工作

    由于Google的服务已经集群化,系统工程师并不大量接触硬件比如做安装服务器等事情。另外大部分工作也已经自动化了,比如架设LDAP, 负载均衡等。对照而言,国内目前大部分互联网公司SA仍然要做大量重复的底层工作,比如拿一个业务的数据库过大需要拆分为例,从系统管理员的角度,需要做以下事情

    1. 同技术人员沟通目前业务特点,制定拆分方案并评估程序风险
    2. 搭建测试环境,技术人员测试程序兼容性
    3. 制定实施方案,保证业务的不停机平稳过渡
    4. 深夜上线
    5. 观察1-2天运行情况

    我们需要思考上面工作是否是系统管理员以及技术人员有价值的工作。像Cassandra这样解决了分布式存储自动化扩展的问题是业内一种发展方向,尽管Cassandra的稳定性还需要改进)。

    Google的系统工程师怎么做?
    他们会通常1周值班,响应各种问题,比如完成上述场景中的扩容业务。然后有大约5周左右脱离一线工作来自由思考将这1周内碰到的工作进行自动化改进,将那些会反复碰到的问题通过脚本及监控程序完成,或者进一步反馈给技术人员改进应用程序来实现自动化。1:5只是个大约比例,时段可以灵活安排。比如也可以按天来安排,1天值班/7天改进。当改进完成之后,下次遇到相同的场景,自动化程序会完成大部分工作。如果在其他公司,SA通常忙碌在一线机械重复上述工作,但是在Google, 给系统工程师预留了相当多的时间让大家思考改进。

    这就是Google的System Administrator自称SRE(Site Reliability Engineers)的原因。SRE会不断在优化所负责的系统,一些人关注运维层面,另外一些可能关注自动化工具。所有的SA都需要具备一定程序或脚本开发能力。

    因此,当遇到Google的数据规模,自动化不是是否需要,而是如何更好实现的问题。

    在Google其他一些令人兴奋的工作还包括

    • 与开发技术人员是协同的关系。
    • 只需关心技术,在技术领域也有职业生涯上升通道,不必转向技术管理岗位或其他。
    • 同事都非常聪明,通常会觉得自己是最逊的那一个。
    • 很多挑战,保守的估计领先行业2-10年,在这里工作就象给了你一个魔法水晶球,通过你的工作可以预见这个行业的未来。

    受Google方式的启发,以下想到的一些可以研究的自动化方向

    1. 程序部署

    C/C++/Java/PHP/Python/Ruby/C# 等语言如何不停机自动发布
    自动发布如何简洁的解决模块依赖性,比如1天需要同时更新10个有相互依赖的模块,并且不能停止服务
    Web容器虚拟化,同一Web容器上可以部署多个业务,业务之间互相隔离,互不影响。
    将新开发的服务程序运维自动化。一般的服务程序从数量上来说,10是一个分水岭,10台以下的服务通过人工重复操作方式来管理也问题不大,但是10台以上就需要自动化管理的方法。很多优秀的开源程序(比如Tokyo Cabinet, Redis等)在单机上表现优秀,但是大规模部署不能。大公司中很多技术人员经常提到很多开源软件不适合他们就有这方面原因。

    2. 资源部署

    MySQL
    分布式文件存储
    Cache,拿cache自动化管理举例
    端口资源管理,不同业务使用不同端口,同一应用内不同的数据使用不同的端口,相关原因可以参看以前cache相关博文。
    容量管理,不同的数据需要不同的容量
    动态扩容,应用业务规模增长,比如从10G扩容到100G
    Proxy功能,比如虚拟化端口映射,程序访问的是固定虚拟端口,这样不需要重启服务也可以随时扩充,应用也不需要一致性hash, proxy帮你做了。

    3. 系统部署

    OS
    反向代理与负载均衡
    本地分区容量,批量管理
    程序发布与停止,比如一个程序一个点击部署到100台服务器
    虚拟化,比物理服务器更容易部署,资源利用率更高,部署更可控

    大部分国内互联网公司基础技术还是比较原始的,这跟行业过分强调“好产品是运营出来的”也有关系,基础研发通常不受重视,长此以往,只能在门槛低的领域打拼,与Google的技术差异就不止10年了。
    paper tape
    (图:大型机GEORGE的纸带编程年代)

    Google说,一个Datacenter就是一台计算机

    要实现一个典型的可扩展Web应用,有一大部分时间要花在Load balance, High availability, Consistent, Scalability等方面。这些都是有经验可循,但是通常无法简单重用。另外目前成熟的相关的部署经验都是孤立的,比如数据库,存储及文件系统,Web服务器都需要分别考虑。另外还有不少非核心的也经常需要用到,如cache, 全文检索, SSO、分布式计算如Hadoop等。所以大部分架构师的工作就是利用已有的经验,利用已有的硬件资源来对系统的负载进行一个平衡。

    由于这些组合技术含量并不是特别高,而且也无大的新技术来替代,所以大部分网站架构设计师的工作和10年前没什么区别,而且更糟糕的是,这些重复工作无法避免。新的一个应用,由于数据库表设计改了,所以所有的工作又得重来一次。因此是改变现状的时候了。

    最近,Google的Luiz André Barroso and Urs Hölzle写了一个paper, The Datacenter as a Computer – An Introduction to the Design of Warehouse-Scale Machines (PDF) 提出可以将一个Datacenter视为一台计算机。
    warehouse-scale-computer

    目前的操作系统在管理单机资源方面已经做到了相当完善,但还没有简单易用的软件体系将一Datacenter中的资源合理分配及利用,WSC也许是一个方向。Paper中比较了在WSC中,使用各种资源Latency, Bandwidth, Capacity的区别。
    wsc-latency

    因此,将来的程序可能会是这样,由几个简单的PHP组成, 运行在一个Datacenter上,使用的内存可大可小,可以从1M到100G;使用的存储可以无限,使用的数据库无需关心切分逻辑。程序员需要做的工 作,只需把PHP写好。其他的工作,通过一个Datacenter OS来完成。与Google AppEngine的区别是,这个OS是Open的。

    作者在上述paper中呼吁计算机科学家应该加强WSC这一新兴领域的研究,因此如果把LAMP这一记组合拳及相关经验理解为网站架构设计的话,或许不久的几年之后,这一定义将重新改写。我的Google Reader里面有上百篇加星的有关LAMP架构经验的文章,那时,它们对于大部分架构设计师不再具有借鉴意义。

    Google的paper最早是从The datacenter is the new mainframeThe Datacenter as a computer看到的。