码迷,mamicode.com
首页 > Web开发 > 详细

Kubernetes 资源对象的理解和定义

时间:2019-06-15 17:40:43      阅读:194      评论:0      收藏:0      [点我收藏+]

标签:分布式文件系   c中   container   产生   gui   转发   两种   bec   应该   

Kubernetes里的所有资源对象都可以采用yaml或者JSON格式的文件来定义或描述,下面是一个简单的Pod资源定义文件:

apiVersion: v1
kind: Pod
metadata:
  name: myweb
  labels:
    name: myweb
spec:
  containers:
  - name: myweb
    image: kubeguide/tomcat-app: v1
    ports:
    - containerPort: 8080
    env:
    - name: MYSQL_SERVICE_HOST
      value: ‘mysql‘
    - name: MYSQL_SERVICE_PORT
      value: ‘3306‘

kind为pod表明这是一个Pod的定义,metadata里的name属性为Pod的名字,metadata里还能定义资源对象的标签(Label),这里声明myweb拥有一个name=myweb的标签(Label)。Pod里包含的容器组的定义则在spec一节中声明,这里定义了一个名字为myweb,对应镜像为kubeguide/tomcat-app: v1的容器,该容器注入了名为MYSQL_SERVICE_HOST=‘mysql‘和MYSQL_SERVICE_PORT=‘3306‘的环境变量(env关键字),并且在8080端口(containerPort)上启动容器进程。Pod的IP加上这里的容器端口,就组成了一个新的概念——Endpoint,它代表着此Pod里的一个服务进程的对外通信地址。一个Pod也存在着具有多个Endpoint的情况,比如我们把Tomcat定义为一个Pod时,可以对外暴露管理端口与服务端口这两个Endpoint。
Docker里的Volume在Kubernetes里也有对应的概念——Pod Volume,Pod Volume有一些扩展,比如可以用分布式文件系统GlusterFS等实现后端存储功能;Pod Volume是定义在Pod之上,然后被各个容器挂载到自己的文件系统中的。对于Pod Volume的定义我们后面会讲到。
这里顺便提一下Event概念,Event是一个事件的记录,记录了事件的最早产生时间、最后重现时间、重复次数、发起者、类型,以及导致此事件的原因等众多信息。Event通常会关联到某个具体的资源对象上,是排查故障的重要参考信息,当我们发现某个Pod迟迟无法创建时,可以用kubectl describe pod xxx来查看它的描述信息,用来定位问题的原因。
每个Pod都可以对其能使用的服务器上的计算资源设置限额,当前可以设置限额的计算资源有CPU和Memory两种,其中CPU的资源单位为CPU(Core)的数量,是一个绝对值。
对于容器来说一个CPU的配额已经是相当大的资源配额了,所以在Kubernetes里,通常以千分之一的CPU配额为最小单位,用m来表示。通常一个容器的CPU配额被定义为100-300m,即占用0.1-0.3个CPU。与CPU配额类似,Memory配额也是一个绝对值,它的单位是内存字节数。
对计算资源进行配额限定需要设定以下两个参数:

  • Requests:该资源的最小申请量,系统必须满足要求。
  • Limits:该资源最大允许使用的量,不能超过这个使用限制,当容器试图使用超过这个量的资源时,可能会被Kubernetes Kill并重启。

通常我们应该把Requests设置为一个比较小的数值,满足容器平时的工作负载情况下的资源需求,而把Limits设置为峰值负载情况下资源占用的最大量。下面是一个资源配额的简单定义:

spec:
  containers:
  - name: db
    image: mysql
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"

最小0.25个CPU及64MB内存,最大0.5个CPU及128MB内存。

2、Label(标签)

Label相当于我们熟悉的“标签”,给某个资源对象定义一个Label,就相当于给它打了一个标签,随后可以通过Label Selector(标签选择器)查询和筛选拥有某些Label的资源对象,Kubernetes通过这种方式实现了类似SQL的简单又通用的对象查询机制。
Label Selector相当于SQL语句中的where查询条件,例如,name=redis-slave这个Label Selector作用于Pod时,相当于select * from pod where pod’s name = ‘redis-slave’这样的语句。Label Selector的表达式有两种:基于等式的(Equality-based)和基于集合的(Set-based)。下面是基于等式的匹配例子。
name=redis-slave:匹配所有标签为name=redis-slave的资源对象。
env != production:匹配所有标签env不等于production的资源对象。
下面是基于集合的匹配例子

  • name in (redis-master, redis-slave):匹配所有标签为name=redis-master或者name=redis-slave的资源对象。
  • name not in (php-frontend):匹配所有标签name不等于php-frontend的资源对象。

还可以通过多个Label Selector表达式的组合实现复杂的条件选择,多个表达式之间用“,”进行分隔即可,几个条件之间是“AND”的关系,即同时满足多个条件,例如:

name=redis-slave, env!=production
name not in (php-frontend), env!=production

以Pod为例,Label定义在metadata中:

apiVersion: v1
kind: Pod
metadata:
  name: myweb
  labels:
    app: myweb

RC和Service在spec中定义Selector与Pod进行关联:

apiVersion: v1
kind: ReplicationController
metadata:
  name: myweb
spec:
  replicas: 1
  selector:
    app: myweb
  template:
  …………

Deployment、ReplicaSet、DaemonSet和Job则可以在Selector中使用基于集合的筛选条件:

selector:
  matchLabels:
    app: myweb
  matchExpressions:
    - {key: tier, operator: In, values: [frontend]}
    - {key: environment, operator: NotIn, values: [dev]}

matchLabels用于定义一组Label,与直接写在Selector中作用相同;matchExpressions用于定义一组基于集合的筛选条件,可用的条件运算符包括:In、NotIn、Exists和DoesNotExist。
如果同时设置了matchLabels和matchExpressions,则两组条件为“AND”关系,即所有条件需要同时满足才能完成Selector的筛选。
Label Selector在Kubernetes中的重要使用场景如下:

  • Kube-controller进程通过资源对象RC上定义的Label Selector来筛选要监控的Pod副本的数量,从而实现Pod副本的数量始终符合预期设定的全自动控制流程。
  • Kube-proxy进程通过Service的Label Selector来选择对应的Pod,自动建立起每个Service到对应Pod的请求转发路由表,从而实现Service的智能负载均衡机制。
  • 通过对某些Node定义特定的Label,并且在Pod定义文件中使用NodeSelector这种标签调度策略,kube-scheduler进程可以实现Pod“定向调度”的特性。

下面举个复杂点的例子,假设我们为Pod定义了3个Label:release、env和role,不同的Pod定义了不同的Label。如下图所示,如果我们设置了“role=frontend”的Label Selector,则会选取到Node 1和Node 2上的Pod。
技术图片
如果我们设置“release=beta”的Label Selector,则会选取到Node 2和Node 3上的Pod,如下图所示。
技术图片
总结:使用Label可以给对象创建多组标签,Label和Label Selector共同构成了Kubernetes系统中最核心的应用模型,使得被管理对象能够被精细地分组管理,同时实现了整个集群的高可用性。

3、Replication Controller

RC的作用是声明Pod的副本数量在任意时刻都符合某个预期值,所以RC的定义包括如下几个部分。

  • Pod期待的副本数量(replicas)。
  • 用于筛选目标Pod的Label Selector。
  • 当Pod的副本数量小于预期数量时,用于创建新Pod的Pod模板(template)。

下面是一个完整的RC定义的例子,即确保拥有tier=frontend标签的这个Pod(运行Tomcat容器)在整个Kubernetes集群中始终有三个副本:

apiVersion: v1
kind: ReplicationController
metadata:
  name: frontend
spec:
  replicas: 3
  selector:
    tier: frontend
  template:
    metadata:
      labels:
        app: app-demo
        tier: frontend
    spec:
      containers:
      - name: tomcat-demo
        image: tomcat
        imagePullPolicy: IfNotPresent
        env:
        - name: GET_HOSTS_FROM
          value: dns
        ports:
        - containerPort: 80

当我们定义了一个RC并提交到Kubernetes集群中后,Master节点上的Controller Manager组件就得到通知,定期巡检系统中当前存活的目标Pod,并确保目标Pod实例的数量刚好等于此RC的期望值。如果有过多的Pod副本在运行,系统就会停掉多余的Pod;如果运行的Pod副本少于期望值,即如果某个Pod挂掉,系统就会自动创建新的Pod以保证数量等于期望值。
通过RC,Kubernetes实现了用户应用集群的高可用性,并且大大减少了运维人员在传统IT环境中需要完成的许多手工运维工作(如主机监控脚本、应用监控脚本、故障恢复脚本等)。
下面我们来看下Kubernetes如何通过RC来实现Pod副本数量自动控制的机制,假如我们有3个Node节点,在RC里定义了redis-slave这个Pod需要保持两个副本,系统将会在其中的两个Node上创建副本,如下图所示。
技术图片
假如Node2上的Pod2意外终止,根据RC定义的replicas数量2,Kubernetes将会自动创建并启动一个新的Pod,以保证整个集群中始终有两个redis-slave Pod在运行。
系统可能选择Node1或者Node3来创建一个新的Pod,如下图。
技术图片
通过修改RC的副本数量,可以实现Pod的动态缩放(Scaling)功能。
kubectl scale rc redis-slave --replicas=3
此时Kubernetes会在3个Node中选取一个Node创建并运行一个新的Pod3,使redis-slave Pod副本数量始终保持3个。

Kubernetes 资源对象的理解和定义

标签:分布式文件系   c中   container   产生   gui   转发   两种   bec   应该   

原文地址:https://blog.51cto.com/14285333/2409338

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!