3-kubernetes-基本概念

来源:互联网 时间:2017-06-16

在kubernetes中Node,Pod,Replication Controller,Service等概念都可以看作一种资源对象,通过kubernetes提供的kubectl工具或API调用进行操作,并保存在etcd中
1.Node(节点)
Node是kubernetes集群中相对于Master而言的工作主机,在早期版本中成为minion,Node可以是一台物理机,也可以是一台虚拟机,在每个Node上运行用于启动和管理Pod的服务-kubectl,并且能够被Master管理,在Node上运行的服务进程包括kubelet,kube-proxy和docker daemon
Node的信息如下:
Node地址:主机ip,或者NodeId
Node运行状态:包括Pending,Runing,Terminated三种状态
Node Condition:描述Running状态Node的运行条件,目前只有一种Ready,表示Node处于健康状态,可以接受从master发来的创建Pod指令
Node系统容量:描述Node可用的系统资源,包括CPU,内存,最大可调度Pod数量等
其他:Node的其他信息,包括实例内核版本,kubernetes版本号,docker版本号,操作系统等
可以通过kubectl describe node node_name来查看Node的详细信息
[[email protected] ~]# kubectl describe node 127.0.0.1
Name:127.0.0.1
Role:
Labels:beta.kubernetes.io/arch=amd64
beta.kubernetes.io/os=linux
kubernetes.io/hostname=127.0.0.1
Taints:
CreationTimestamp:Thu, 15 Jun 2017 02:31:36 +0800
Phase:
Conditions:
TypeStatusLastHeartbeatTimeLastTransitionTimeReasonMessage
----------------------------------------------------------
OutOfDiskFalseThu, 15 Jun 2017 16:11:00 +0800Thu, 15 Jun 2017 02:31:36 +0800KubeletHasSufficientDiskkubelet has sufficient disk space available
MemoryPressureFalseThu, 15 Jun 2017 16:11:00 +0800Thu, 15 Jun 2017 02:31:36 +0800KubeletHasSufficientMemorykubelet has sufficient memory available
DiskPressureFalseThu, 15 Jun 2017 16:11:00 +0800Thu, 15 Jun 2017 02:31:36 +0800KubeletHasNoDiskPressurekubelet has no disk pressure
ReadyTrueThu, 15 Jun 2017 16:11:00 +0800Thu, 15 Jun 2017 02:31:36 +0800KubeletReadykubelet is posting ready status
Addresses:127.0.0.1,127.0.0.1,127.0.0.1
Capacity:
alpha.kubernetes.io/nvidia-gpu:0
cpu:1
memory:999936Ki
pods:110
Allocatable:
alpha.kubernetes.io/nvidia-gpu:0
cpu:1
memory:999936Ki
pods:110
System Info:
Machine ID:9d4ea80aa7594758813e8fed1f572e2b
System UUID:DDBF4D56-3C3C-F602-0160-ACD94A574B9A
Boot ID:92f6fecd-61e0-4e6a-8698-663c9baa053e
Kernel Version:3.10.0-514.el7.x86_64
OS Image:CentOS Linux 7 (Core)
Operating System:linux
Architecture:amd64
Container Runtime Version:docker://1.12.6
Kubelet Version:v1.5.2
Kube-Proxy Version:v1.5.2
ExternalID:127.0.0.1
Non-terminated Pods:(6 in total)
NamespaceNameCPU RequestsCPU LimitsMemory RequestsMemory Limits
---------------------------------------------------------------
defaultfrontend-kkb8q0 (0%)0 (0%)0 (0%)0 (0%)
defaultfrontend-p5hwm0 (0%)0 (0%)0 (0%)0 (0%)
defaultfrontend-r70dz0 (0%)0 (0%)0 (0%)0 (0%)
defaultredis-master-1t0n60 (0%)0 (0%)0 (0%)0 (0%)
defaultredis-slave-0nh1g0 (0%)0 (0%)0 (0%)0 (0%)
defaultredis-slave-cz3420 (0%)0 (0%)0 (0%)0 (0%)
Allocated resources:
(Total limits may be over 100 percent, i.e., overcommitted.
CPU RequestsCPU LimitsMemory RequestsMemory Limits
--------------------------------------------------
0 (0%)0 (0%)0 (0%)0 (0%)
Events:
FirstSeenLastSeenCountFromSubObjectPathTypeReasonMessage
------------------------------------------------------------
12m12m1{kubelet 127.0.0.1}NormalStartingStarting kubelet.
12m12m1{kubelet 127.0.0.1}WarningImageGCFailedunable to find data for container /
12m12m1{kubelet 127.0.0.1}NormalNodeHasSufficientDiskNode 127.0.0.1 status is now: NodeHasSufficientDisk
12m12m1{kubelet 127.0.0.1}NormalNodeHasSufficientMemoryNode 127.0.0.1 status is now: NodeHasSufficientMemory
12m12m1{kubelet 127.0.0.1}NormalNodeHasNoDiskPressureNode 127.0.0.1 status is now: NodeHasNoDiskPressure
12m12m1{kubelet 127.0.0.1}WarningRebootedNode 127.0.0.1 has been rebooted, boot id: 92f6fecd-61e0-4e6a-8698-663c9baa053e
12m12m2{kubelet 127.0.0.1}WarningMissingClusterDNSkubelet does not have ClusterDNS IP configured and cannot create Pod using "ClusterFirst" policy. pod: "redis-master-1t0n6_default(8eefc9c3-5131-11e7-8b46-000c29574b9a)". Falling back to DNSDefault policy.
12m12m2{kubelet 127.0.0.1}WarningMissingClusterDNSkubelet does not have ClusterDNS IP configured and cannot create Pod using "ClusterFirst" policy. pod: "frontend-r70dz_default(57a259d8-5138-11e7-8b46-000c29574b9a)". Falling back to DNSDefault policy.
12m12m2{kubelet 127.0.0.1}WarningMissingClusterDNSkubelet does not have ClusterDNS IP configured and cannot create Pod using "ClusterFirst" policy. pod: "redis-slave-0nh1g_default(7b71e8e9-5136-11e7-8b46-000c29574b9a)". Falling back to DNSDefault policy.
12m12m2{kubelet 127.0.0.1}WarningMissingClusterDNSkubelet does not have ClusterDNS IP configured and cannot create Pod using "ClusterFirst" policy. pod: "frontend-kkb8q_default(57a24b8d-5138-11e7-8b46-000c29574b9a)". Falling back to DNSDefault policy.
12m11m2{kubelet 127.0.0.1}WarningMissingClusterDNSkubelet does not have ClusterDNS IP configured and cannot create Pod using "ClusterFirst" policy. pod: "redis-slave-cz342_default(7b725553-5136-11e7-8b46-000c29574b9a)". Falling back to DNSDefault policy.
12m11m2{kubelet 127.0.0.1}WarningMissingClusterDNSkubelet does not have ClusterDNS IP configured and cannot create Pod using "ClusterFirst" policy. pod: "frontend-p5hwm_default(57a26405-5138-11e7-8b46-000c29574b9a)". Falling back to DNSDefault policy.
1.1 Node的管理
使用Node Controller对Node进行管理,它是kubernetes Master中一个组件用于管理Node对象。
它的主要功能:
集群范围内的Node信息同步
单个Node生命周期管理
Node信息同步可以通过kube-controller-manager启动参数--node-sync-period设置同步的时间周期
Node的自注册当kubelet的--register-node参数设置为ture默认也为ture,kubelet会向apiserver注册自己这也是kubernetes推荐的Node管理方式
kubelet进行自注册启动参数如下
--apiserver:apiserver地址
--kubeconfig:登录apiserver所需证书目录
--cloud_provider:云服务商地址,用于获取metadata
--register-node:设置ture表示自动注册到apiserver
手动管理Node
要手动管理Node需要把kubelet启动参数--register-node参数设置为false,这样Node上的kubelet不会自动注册到apiserver中去
1.2 Pod
kubernetes的最基本操作单元,包含一个或多个紧密相关的容器,一个Pod可以被一个容器化的环境看作应用层的逻辑宿主机,一个Pod中的多个容器通常是紧耦合的,Pod在Node上创建,启动,销毁
kubernetes在容器之上在封装一层Pod,一个重要的原因是docker容器之间的通信收到docker网络机制的限制,一个容器需要link方式才能访问另外一个容器提供的服务,大量容器之间的link将是一件非常繁重的工作,通过Pod将多个容器组合在一个虚拟的主机内可以实现容器之间仅需要Localhost就能互相通信了
container N--->Pod N--->Node N----->Master
一个Pod中的应用容器共享一组资源:
Pid命名空间:Pod中不同应用程序可以看到其他应用程序进程的ID
网络命名空间:Pod中的多个容器能够访问统一个IP和端口范围
IPC命名空间:Pod中的多个容器能够使用systemV IPC或POSIX消息队列进行通信
UTS命名空间:Pod中的多个容器共享一个主机名
Volumes共享存储卷:Pod中的各个容器可以访问在Pod级别定义的Volumes
对Pod的定义通过yaml或json格式的配置文件来完成下面的配置文件内容是定义一个redis-slave的Pod,其中kind为Pod,spec中包含了对container的定义,可以定义多个容器
apiVersion: v1
kind: Pod
metadata:
name: redis-slave
labels:
name: redis-slave
spec:
containers:
- name: slave
image: kubeguide/guestbook-redis-slave
env:
- name: GET_HOSTS_FROM
value: env
ports:
- containerPort: 6379
Pod的生命周期是通过RC(Replication Controller)来管理的Pod的生命周期包括:通过模版定义,然后分配到一个Node上运行,在Pod所含容器运行结束后Pod也结束,整个过程Pod处于以下4中状态
Pengding:Pod定义正确,提交到Master后,但其所包含容器镜像还未完全创建,通常Master对Pod进行调度需要一些时间,之后Node对镜像进行下载也需要一些时间
Running:Pod已经被分配到某个Node上且包含所有容器镜像已经创建完成并成功运行起来
Succeeded:Pod中所有容器都成功结束,并且不会被重启这是Pod的一种最终状态
Failed:Pod中所有容器都结束了,但是至少一个容器是以失败状态结束的这也是Pod的一种最终状态
kubernetes为Pod设计了一套独特的网络配置:包括为每个Pod分配一个IP地址使用Pod名作为容器之间通信的主机名,1.3 Label
kubernetes的一个核心概念,Label已key/value键值对的形式附加到各种对象上,Pod,Service,RC,Node;Label定义了这些对象的可识别属性,用来对他们进行管理和选择,Label可以创建对象时附加到对象,也可以在对象创建后通过API进行管理
在为对象定义好Label后,其他对象就可以使用Label Sekector来定义其作用的对象了
当前有两种label Selector
基于等式的:
name=redis-slave:选择所有包含Label中key=name且value=redis-slave的对象
env !=production:选择所有包括Label中key=env且value不等于production的对象
基于集合的:
name in (redis-master,redis-slave):选择所有Label中key=name且value=redis-master或redis-slave的对象

在某些对象需要对另一些对象进行选择时,可以将多个Label Selector进行组合,使用逗号分隔,等式和集合都任意组合
name=redis-slave,env!=production
name notin (php-frontend),env!=production

一般来说我们会给一个Pod定义多个Labels以便于配置,部署,例如部署不同版本的应用到不同的环境中,或者监控和分析应用等,通过对多个Label的设置,就可以多维度对Pod或其他对象进行精细的管理
前面我们的例子都使用一个name=xxxx的Label Selector,来一个更复杂的
假设Pod定义了3个Label:release,env,role,不同的Pod定义了不同的取值
Node1:Labels
release:a
env:development
role:frontend
Node2:Labels
release:b
env:test
role:frontend
Node3:Labels
release:b
env:production
role:backend
如果设置role=frontend的Selector只会选择到Node1和Node2上的Pod,设置了release=b的Selector则会选择到Node2和Node3上Pod这样使用Label创建多组标签,Service,RC等组件通过Label Selector来选择范围对象,Label和Label Selector共同组成了kubernetes系统中最核心的应用模型,使用被管理的对象能够精细的分组管理。
1.4 RC Replication Controller
用于定义Pod副本的数量,在master内Controller Manager进程通过RC定义来完成Pod的创建监控启停等
根据RC的定义,kubernetes能够在任何时刻都能运行用户指定的Pod副本replica数量,如果有过多的Pod副本在运行,系统就会停掉一些Pod,如果运行Pod副本数量太少,系统就会再启动一些Pod,总之通过RC的定义,kubernetes总是保证集群中运行用户期望的副本数量
同时kubernetes会对全部运行的Pod进行监控和管理,如果有需要,就会将Pod重启命令提交给Node上的某个程序来完成
通过对RC的使用,kubernetes实现了应用集群的高可用并且大大减少了系统管理员在传统IT环境中需要手动运维的工作
在运行时可以通过修改RC的副本数量来实现Pod的动态缩放scaling
kubernetes提供kubectl scale来完成
kubectl scale rc redis-slave --replicas=3
注意:删除RC并不会影响通过该RC已创建好的Pod,为了删除所有Pod可以设置replicas的值为0,然后更新RC,另外kubectl提供了stop和delete来完成一次性删除RC和RC控制的全部Pod
另外通过RC可以实现应用的滚动升级1.5 Service服务
在kubernetes中每个Pod都会被分配到一个单独的ip地址,但是这个ip地址会随着Pod的销毁而消失,那么如果有一组Pod组成一个集群来提供服务那么该如何访问他们呢?
kubernetes的Service服务就是解决这个问题的
一个Service可以看组一组提供相同服务的Pod的对外访问借口,Service作用于那些Pod是通过Label Selector来定义的
例如,redis-salve Pod运行两个副本replica,这两个副本对于前端程序来说没有区别,所以前端程序不关心那个后端副本提供服务,并且后端redis-slave Pod发生变化时,也不需要跟踪这些变化,Service就是用来实现这种解耦的抽象概念对Service的定义
同样使用Yaml或者Json格式进行配置
apiVersion: v1
kind: Service
metadata:
name: redis-slave
labels:
name: redis-slave
spec:
ports:
- port: 6379
selector:
name: redis-slave
通过定义kubernetes会创建一个名为redis-slave的服务并在6379端口上监听,spec.selector的定义表示将所有包含name=redis-slave的Label的Pod
在Pod正常启动后,系统将会根据Service的定义创建出与Pod对应的Endpoint对象,以建立起Service和后端Pod的对应关系,随着Pod的创建销毁,Endpoint对象也将被更新,Endpoint对象主要用Pod的Ip地址和容器需要监听的端口号组成,通过kubectl get endpoints命令可以查看
Pod的ip地址和Service的Cluster IP地址
Pod的ip地址是Docker Daemon根据docker0往前的ip地址段进行分配的,但Service的Cluster IP地址是kubernetes系统中的虚拟IP地址,用系统动态分配,Service的Cluster IP地址相对于Pod的ip地址来说相对稳定,Service被创建时即被分配一个IP地址,在销毁该Service之前这个ip地址都不会在变化了,而Pod在kubernetes集群中生命周期较短,可能被ReplicationController销毁,新创建的Pod将会分配到一个新的IP地址外部访问Service
用于Service对象在cluster ip range池中分配到的IP只能在内部访问,所以其他Pod都可以无障碍的访问到他,但如果这个Service作为前端服务,准备为集群外的客户提供服务,这就需要公共IP了
kubernetes支持两种对外服务的Service的type定义
NodePort:在定义Service时指定spec.type=NodePort并指定spec.ports.nodePort的值,系统就会在kubernetes集群中每个Node上打开一个主机上真实的端口号,这样就能够访问Node的客户就能过这个端口号访问到内部的Service
以php-frontend service的定义为例,nodePort=80这样,在每一个启动该php-frontend Pod的Node节点上都打开80端口
假设有3个php-frontend Pod运行在三个不同的Node上,客户端访问其中任意一个Node都可以访问到这个服务
LoadBalancer:如果云服务提供商支持外界负载均衡负载器,则可以通过spec.type=LoadBalancer定义Service,同时需要指定负载均衡器的IP地址,使用这种类型需要指定Service的nodePort和clusterIP

apiVersion: v1
kind: Service
metadata:{
"kind": "Service",
"apiVersion": "v1",
"metadata": {
"name": "my-service"
},
"sepc": {
"type": "LoadBanlancer",
"clusterIP": "1.1.1.1",
"selector": {
"app": "MyApp"
},
"ports": [
{
"protocol": "TCP",
"port": 80,
"targetPort":9376,
"nodePort":30061
}
],
},
"status" : {
"loadBanlancer": {
"ingress": [
{
"ip": "2.2.2.2"
}
]
}
}
}
在这个例子中status.loadBanlancer.ingress.ip设置的2.2.2.2为云服务商提供的负载均衡器的IP地址,之后对该Service的访问请求会通过LoadBanlancer转发后到后端Pod上去,负载分发的实现方式依赖于云服务提供商的LoadBanlancer的实现机制
在很多情况下一个服务需要暴露多个端口号在这种情况下可以对端口进行命名
{
"kind": "Service",
"apiVersion": "v1",
"metadata": {
"name": "my-service"
},
"sepc": {
"type": "LoadBanlancer",
"clusterIP": "1.1.1.1",
"selector": {
"app": "MyApp"
},
"ports": [
{
"name": "http"
"protocol": "TCP",
"port": 80,
"targetPort":9376
},
{
"name": "https"
"protocol": "TCP",
"port": 443,
"targetPort":9377
}
]
}
}
1.6 volume 存储卷
待续

相关阅读:
Top