初识Kubernetes(K8s):各种资源对象的理解和定义⼀、Pod
Kubernetes为每个Pod都分配了唯⼀的IP地址,称之为Pod IP,⼀个Pod⾥的多个容器共享Pod IP地址。Kubernetes要求底层⽹络⽀持集群内任意两个Pod之间的TCP/IP直接通信,这通常采⽤虚拟⼆层⽹络技术来实现,例如Flannel、Open vSwitch等。因此,在Kubernetes⾥,⼀个Pod⾥的容器与另外主机上的Pod容器能够直接通信。
Pod有两种类型:普通的Pod和静态Pod(Static Pod),静态Pod不存放在etcd存储⾥,⽽是存放在某个具体的Node上的⼀个具体⽂件中,并且只在此Node上启动运⾏。普通的Pod⼀旦被创建,就会被存储到etcd中,随后会被Kubernetes Master调度到某个具体的Node 上并进⾏绑定(Binding),该Node上的kubelet进程会将其实例化成⼀组相关的Docker容器并启动起来。当Pod⾥的某个容器停⽌
sparkler时,Kubernetes会⾃动检测到这个问题并且重新启动这个Pod(重启Pod⾥的所有容器);如果Pod所在的Node宕机,则会将这个Node 上的所有Pod重新调度到其他节点上运⾏。
Pod、容器与Node的关系如下图:
名画呐喊Kubernetes⾥的所有资源对象都可以采⽤yaml或者JSON格式的⽂件来定义或描述,下⾯是⼀个简单的Pod资源定义⽂件:
apiVersion: v1
kind: Pod
metadata:
name: myweb
labels:
name: myweb
spec:
go for itcontainers:
- 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内存。
⼆、Label(标签)
Label相当于我们熟悉的“标签”,给某个资源对象定义⼀个Label,就相当于给它打了⼀个标签,随后可以通过Label Selector(标签选择器)查询和筛选拥有某些Label的资源对象,Kubernetes通过这种⽅式实现了类似SQL的简单⼜通⽤的对象查询机制。
Label Selector相当于SQL语句中的where查询条件,例如,name=redis-slave这个Label Selector作⽤于Pod时,相当于lect * from pod where pod’s name = ‘redis-slave’这样的语句。Label Selector的表达式有两种:基于等式的(Equality-bad)和基于集合的(Set-bad)。下⾯是基于等式的匹配例⼦。
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:
mayiname: myweb
already
labels:
app: myweb
RC和Service在spec中定义Selector与Pod进⾏关联:
apiVersion: v1
kind: ReplicationController
metadata:
name: myweb
spec:
replicas: 1
lector:
app: myweb
template:
…………
Deployment、ReplicaSet、DaemonSet和Job则可以在Selector中使⽤基于集合的筛选条件:
lector:
matchLabels:
app: myweb
matchExpressions:
- {key: tier, operator: In, values: [frontend]}
- {key: environment, operator: NotIn, values: [dev]}
matchLabels⽤于定义⼀组Label,与直接写在Selector中作⽤相同;matchExpressions⽤于定义⼀组基于集合的筛选条件,可⽤的条件运算符包括:In、NotIn、Exists和DoesNotExist。bane
如果同时设置了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:relea、env和role,不同的Pod定义了不同的Label。如下图所⽰,如果我们设置了“role=frontend”的Label Selector,则会选取到Node 1和Node 2上的Pod。
中考冲刺
如果我们设置“relea=beta”的Label Selector,则会选取到Node 2和Node 3上的Pod,如下图所⽰。
总结:使⽤Label可以给对象创建多组标签,Label和Label Selector共同构成了Kubernetes系统中最核⼼的应⽤模型,使得被管理对象能够被精细地分组管理,同时实现了整个集群的⾼可⽤性。
三、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
lector:
tier: frontend
template:
metadata:
labels:
app: app-demo
tier: frontend
spec:
containers:
- name: tomcat-demo
image: tomcat
imagePullPolicy: IfNotPrent
env:
- name: GET_HOSTS_FROM
value: dns
ports:
- containerPort: 80