当在一个单独的物理结点上工作时,一般的工具通常不会以批量的方式对容器进行操作。但是在容器集群上进行工作的时候,你可能希望很轻易地就能实现服务的跨结点扩展。为了实现这一目标,你需要以集合的方式进行思考,而并非像之前一样按照单例模式考虑。并且你还希望这些容器集合都可以通过很容易地方式进行配置。在Kubernets中,我们引入了两个额外的概念来管理一系列pod:label以及replication controllers。
Kubernets中的每一个pod都有一套key-value键值对与其相绑定,我们把这个键值对称为labels。你可以通过构建一个基于这些labels查询,来筛选出一系列pods。Kubernets没有一个所谓的组织pod的“正确的方式”。这完全取决于用户,只要是适合用户的组织方式就是合适的。用户可以根据应用程序的层来结构来组织,也可以根据地理位置来组织,或者是部署环境等等。实际上,因为labels是非层次结构的(non-hierarchical),你可以同时以多种方式组织你的pod。
举例来说:比如你有一个简单的服务,这个服务同时包含前端和后端两个层次。同时你还有不同的环境:测试环境,交付环境(staging environment)以及生产环境。你可以同时利用多个标签来标记你pod,比如用于生产环境的前端pod可以标记为:env=prod、tier=fe 同时,用于生产环境后端pod可以标记为env=prod、tier=be。同理,你也可以按照类似方法来标记你在测试和交付环境中使用的pod。接下来,当用户需要对集群进行操作或者检查的时候,就可以将操作范围限制在标记为env=prod的pod中,这样就可以同时看到在生产环境中的前端和后端的pod。或者你只想查看你的前端环境,此时只需要查找标记为tier=fe的pods,这样就可以查看跨越了测试、交付和生产三个不同的环境的前端pods。随着你添加更多的层次和不同的运行环境,你也可以按照自己的方式来设想和规划,按照自己的方式定义这个系统将,使其更好地满足你的需求。
既然我们之前已经可以对拥有类似配置的物理服务器资源池进行识别和维护。我们可以参考这个功能来对容器集群进行水平扩展(即“scaling out”)。为了使这个步骤更加容易,我们在Kubernets中维护了一个helper对象,我们称其为replication controller 。它维护着一个存有pods的资源池,还有一些属性用于描述这个资源池,包括期望进行扩展的数目 replication count ,还有一个pod 模板以及一个用于进行选择/查询的label。 实际上这个对象的原理理解起来也并不困难,下面是伪代码:
object replication_controller {property num_replicas
property template
property label_selector
runReplicationController(num_desired_pods, template, label_selector) {
loop forever {
num_pods = length(query(label_selector))
if num_pods > num_desired_pods {
kill_pods(num_pods - num_desired_pods)
} else if num_pods < num_desired_pods {
create_pods(template, num_desired_pods - num_pods)
}
}
}
}