Master
是整个Kubernetes的控制节点,是集群的首脑,Master节点上运行着一下一组关键进程:
- Kubernetes API Server(kube-apiserver),提供了HTTP Rest接口的关键服务进程,是Kubernetes里所有资源的增、删、改、查等操作的唯一入口,也是集群控制的入口进程
- Kubernetes Controller Manager(kube-controller-manage),Kubernetes里所有资源对象的自动化控制中心,
- Kubernetes Scheduler(kube-scheduler),负责资源调度(Pod调度)的进程
Node
除了Master结点外的其它机器被称为Node结点,是集群的工作结点,可以是一台物理机或虚拟机,每个Node结点上都运行了一组关键进程:
- kubelet:负责Pod对应的容器的创删、启停等任务,同时与Master结点密切协作,实现集群管理的基本功能
- kube-proxy:实现Kubernetes Service的通信与负载均衡机制的重要组件
- Docker Engine:负责本机容器的创建和管理工作
注意:已经正确安装、配置和启动上述关键进程的Node可以动态增加到Kubernetes集群中,在默认情况下kubelet会想Master注册自己,一旦Node纳入管理范围,kubelet进程会定时向Master结点汇报自身的情况,如操作系统、Docker版本、机器CPU和内存情况,以及运行了哪些Pod等,Master会根据Node的资源使用情况,进行高效均衡的资源调度策略,如果某个Node超过指定时间不上报信息,会被Master判断为“失联”,Node被标记为不可用,随后该几点上的工作负载会转移到其他节点上。
kubectl get nodes可以查看集群结点数
kubectl describe node 节点名可以查看结点详细信息
[root@localhost Kubernetes]# kubectl get nodes
NAME STATUS AGE
127.0.0.1 Ready 4d
[root@localhost Kubernetes]# 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: <none>
CreationTimestamp: Thu, 29 Nov 2018 05:34:09 -0500
Phase:
Conditions:
Type Status LastHeartbeatTime LastTransitionTime Reason Message
---- ------ ----------------- ------------------ ------ -------
OutOfDisk False Tue, 04 Dec 2018 03:01:30 -0500 Thu, 29 Nov 2018 05:34:09 -0500 KubeletHasSufficientDisk kubelet has sufficient disk space available
MemoryPressure False Tue, 04 Dec 2018 03:01:30 -0500 Thu, 29 Nov 2018 05:34:09 -0500 KubeletHasSufficientMemory kubelet has sufficient memory available
DiskPressure False Tue, 04 Dec 2018 03:01:30 -0500 Thu, 29 Nov 2018 05:34:09 -0500 KubeletHasNoDiskPressure kubelet has no disk pressure
Ready True Tue, 04 Dec 2018 03:01:30 -0500 Fri, 30 Nov 2018 01:31:48 -0500 KubeletReady kubelet 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: 1865284Ki
pods: 110
Allocatable:
alpha.kubernetes.io/nvidia-gpu: 0
cpu: 1
memory: 1865284Ki
pods: 110
System Info:
Machine ID: e0cf5490988c4a65acc364c5e1f70ae1
System UUID: 45F64D56-A209-D65C-6D99-6AF0C29DF941
Boot ID: 4333a69d-1e09-4a1f-b75b-9bfbe0759fcb
Kernel Version: 3.10.0-862.el7.x86_64
OS Image: CentOS Linux 7 (Core)
Operating System: linux
Architecture: amd64
Container Runtime Version: docker://1.13.1
Kubelet Version: v1.5.2
Kube-Proxy Version: v1.5.2
ExternalID: 127.0.0.1
Non-terminated Pods: (1 in total)
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits
--------- ---- ------------ ---------- --------------- -------------
default mysql-pkxgr 0 (0%) 0 (0%) 0 (0%) 0 (0%)
Allocated resources:
(Total limits may be over 100 percent, i.e., overcommitted.
CPU Requests CPU Limits Memory Requests Memory Limits
------------ ---------- --------------- -------------
0 (0%) 0 (0%) 0 (0%) 0 (0%)
Events:
FirstSeen LastSeen Count From SubObjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
46m 46m 1 {kubelet 127.0.0.1} Normal Starting Starting kubelet.
46m 46m 1 {kubelet 127.0.0.1} Warning ImageGCFailed unable to find data for container /
46m 46m 1 {kubelet 127.0.0.1} Normal NodeHasSufficientDisk Node 127.0.0.1 status is now: NodeHasSufficientDisk
46m 46m 1 {kubelet 127.0.0.1} Normal NodeHasSufficientMemoryNode 127.0.0.1 status is now: NodeHasSufficientMemory
46m 46m 1 {kubelet 127.0.0.1} Normal NodeHasNoDiskPressure Node 127.0.0.1 status is now: NodeHasNoDiskPressure
46m 46m 1 {kubelet 127.0.0.1} Warning Rebooted Node 127.0.0.1 has been rebooted, boot id: 4333a69d-1e09-4a1f-b75b-9bfbe0759fcb
46m 45m 2 {kubelet 127.0.0.1} Warning MissingClusterDNS kubelet does not have ClusterDNS IP configured and cannot create Pod using "ClusterFirst" policy. pod: "mysql-pkxgr_default(af042e71-f469-11e8-8738-000c299df941)". Falling back to DNSDefault policy.
Pod
pod的组成与容器的关系
每个Pod都有一个特殊容器称为根容器的Pause容器,以及一个或多个container。
Pod里的多个容器共享Pause容器的IP,共享Pause容器挂载的Volume,将密切关联的业务捆绑起来,可以很好解决文件共享问题,例如,php的web服务器中的nginx和php
Pod的两种类型:普通Pod与静态Pod
- 普通Pod:普通Pod一旦被创建,就会被放入到etcd中存储,所有会被Kubernetes Master调度到具体的Node上进行绑定,随后被该Node上的kubelet进行实例化成一组相关的Docker容器,一旦该node或pod宕机或停止了,该Pod会被重新调度到其他结点上
- 静态Pod:该Pod不会被放在Kubernetes的etcd存储里,而是放在某个具体的Node的文件里,并且只在该Node上启动运行,如果该Node宕机了,该Pod也不会被重新调度。
Kubernetes里的所有资源对象都可以采用yml或者JSON格式的文件来定义或描述
例如myweb这个Pod的资源文件的定义:
对Pod进行资源限额:
Label
Label是Kubernetes系统中的核心概念之一,一个Label是一个key=value的键值对,其中key与value由用户指定。Label可以附加到各种资源对象上,例如Node、Pod、Service、RC等,一个资源对象可以定义任意数量的Label,同一个Label也可以被添加到任意数量的资源对象上去。
LabelSelector
Label Selector与SQL中的where查询条件类似,例如name=redis-slave这个Label Selector作用于Pod是,可以被类比为select * from pod where pod’s name = ‘redis-slave’。当前有两种Label Selector的表达式:基于等式和基于集合,例如:name = redis-slave,env != production;name in (redis-master,redis-slave),name not in (php-frontend)
可以指定多个Label Selector表示式进行组合,多个表达式之间用“ , ”间隔。
使用场景:
- kube-controller进程通过资源对象RC上的Label Selector来筛选要监控的Pod副本的数量
- kube-proxy进程通过Service的Label Selector来选择对应的Pod,自动建立每个Service到对应Pod的请求转发路由,实现负载均衡机制
- 通过某些Node定义特定的Label,并且在Pod定义文件使用NodeSelector这种标签调度策略,kube-scheduler进程可以实现Pod“定向调度”的特性
Replication Controller(RC)
Kubernetes系统的核心概念之一,定义一个期望场景,即声明某种Pod的副本数量在任意时刻都符合某个预期值。所以RC的定义包含如下几个部分:
- POD期待的副本数
- 用于筛选目标Pod的Label Selector
- 当Pod的副本数量小于预期数量的时候,用于创建Pod的Pod模板
在运行时,可以通过修改RC的副本数量来实现Pod的动态缩放:
下一代RC–Replica Set*与RC的唯一区别是Replica Set支持基于集合的Label Selector,而RC只支持基于等式的Label Selector
通常Replica Set很少单独使用,它主要被Deployment这个更高层的资源对象使用,从而形成一整套Pod创建、删除、更新的编排机制。
RC的一些特性与作用:
Deployment
Kubernetes 1.2引入的新概念,可以看成RC的升级版,相对于RC的最大升级是我们可以随时知道当前Pod“部署”的进度。
典型的使用场景:
- 创建一个Deployment对象来生成对应的Replica Set并完成Pod副本的创建过程
- 检查Deployment的状态来看部署是否完成
- 更新Deployment以创建新的Pod(镜像升级)
- 如果当前Deployment不稳定,回滚到一个早先的deployment版本
- 挂起或者回复一个Deployment
Deployment的yaml文件实例:
Horizontal Pod Autoscaler(HPA)
根据集群的负载情况实现Pod的自动扩容和缩容
HPA可以有以下两种方式作为Pod负载的度量指标:
- CPUUtilizationPercentage,是一个算术平均值,即目标Pod所有副本自身的CPU利用率的平均值。
- 应用程序自定义的度量指标,比如服务在每秒内的响应请求数。
Service
Kubernetes里最核心的资源对象之一,每个Service其实就是一个“微服务”。
每个Service都被分配一个全局唯一的虚拟IP地址(Cluster IP),与Pod不同的是,在Service的整个生命周期里,它的Cluster IP不会发生变化,而Pod的Endpoint在Pod销毁和重新创建时会发生变化。
Service的yaml文件举例:
创建Service
查看tomcat-service的Endpoint
查看Service被分配的Cluster IP
Service的多端口问题,很多服务都存在多个端口,Kubernetes Service支持多个Endpoint,在存在多个Endpoint的情况下,要求每个Endpoint定义一个名字来区分。
Kubernetes的服务发现机制
最早的Kubernetes采用Linux的环境变量的方式解决服务发现问题,由于Service有唯一的名字和Cluster IP,所以为每个Service生成一些对应的Linux环境变量,在Pod的容器启动时,自动注入这些环境变量,以tomact-service举例:
后来Kubernetes通过Add-On增值包的方式引入DNS系统,把服务名作为DNS域名,通过域名解析来实现服务发现。
外部系统访问Service
Kubernetes的三种IP:
- Node IP是每个结点的物理网卡的IP地址,是一个真实的物理网络,所有属于这个网络的服务器之间都能通过这个网络直接通信。集群之外的结点只能通过该IP访问集群之内的结点
- Pod IP是每个Pod的IP地址,是docker0网桥的IP地址段分配的一个虚拟地址,Kubernetes要求不同Node上的Pod能够彼此通信,所以集群内的一个Pod里的容器访问另一个个Pod的容器时使用这个地址
- Cluster IP,是一个虚拟IP,
通过上面可知Cluster IP是一个虚拟IP,无法从集群外部直接访问,采用NodePort可以解决这个问题。
NodePort的实现方式是在Kubernetes集群里的每个Node上为需要外部访问的Service开启一个对应的TCP监听端口,外部系统只需要用任意一个Node的IP地址+具体的NodePort端口号即可访问此服务。
Volume(存储卷)
Kubernetes中的Volume被一个Pod中的多个容器挂载,与Pod的生命周期相同,与容器的生命周期无关。
Volume的使用,大多数情况下,我面先声明一个Volume,然后在容器里面应用该Volume。
Kubernetes中的Volume的类型:
1.emptyDir:Pod分配到Node时创建该卷,初始内容为空,无须指定宿主机上对应的目录文件,因为Kubernetes会自动分配一个目录,当Pod从Node上移除时,emptyDir中的数据也会被永久删除。目前用户无法控制emptyDir使用的介质种类,emptyDir的一些用途:
2.hostPath:在Pod上挂载宿主机上的文件或目录,通常用于以下几个方面
3.gcePersistentDisk:使用谷歌公有云提供的永久磁盘存放Volume的数据,PD上的内容会永久保存。
4.awsElasticBlockStore:与GCE类似,使用亚马逊公有云
5.NFS:使用NFS网络文件系统提供的共享目录存储数据,我们需要在系统中部署一个NFS Server,定义NFS类型的Volume:
Persistent Volume
Namespace(命名空间)
是Kubernetes中的一个非常重要的概念,用于实现多租户的资源隔离。
Kubernetes集群启动后会创建一个名为“ default ”的Namespace,可以使用kubectl查看
接下来如果不特别指明Namespace,则用户创建的Pod、RC、Service都会被系统创建到default的Namespace中。
定义Namespace的yaml文件实例:
创建资源时指定Namespace
此时kubectl get命令无法查到该pod,因为kubectl get默认查询“ default ”命名空间的资源,所以需要加上–namespace参数
Annotation(注解)
Annotation与Label类似,也是用key/value键值对形式定义,不同的是,Label具有严格的命名规则并且勇于Label Selector,Annotation则是用户任意定义的“附加”信息,以便外部工具进行查找。