Kubernetes的概念和术语

Master

       在Kubernetes中,Master指集群控制节点,负载集群的管理和控制,基本上Kubernetes所有的控制命令都是发给它,它来负责集体的执行过程。Master节点通常至少会占据一个独立的服务器或者虚拟机,它是整个集群的“首脑”,如果它宕机或者不可用,那所有的控制指令都将失效。

Master节点上运行的关键进程:

  • Kubernetes API Server(kube-apiserver),提供HTTP Rest接口的关键服务进程,是Kubernetes里所有资源的增、删、改、查等操作的唯一入口,也是集群控制的入口进程。
  • Kubernetes Controller Manager(Kube-controller-manager),Kubernetes中所有资源对象的自动化控制中心。
  • Kubernetes Scheduler(Kube-scheduler),负责资源调度(Pod调度)的进程。

 Master节点上往往还启动一个etcd Server进程,用于保存Kubernetes里的所有资源对象的数据。

Node

    在Kubernetes集群中,除了Master节点外的机器节点,都被称为Node节点。Node节点是真正的工作负载节点,当某个Node宕机时,其上的工作负载(容器)会被Master自动转移到其它节点上去。

每个Node节点上运行的关键进程:

  • kubelet:负责pod对应的容器的创建、启停等任务,同时与Master节点密切协作,实现集群管理的基本功能。
  • kube-proxy:实现Kubernetes Service的通信与负载均衡机制的重要组建。
  • Docker Engine(docker):负责本机容器创建和管理

Node节点可以动态增加到Kubernetes集群中,前提是已经正确安装、配置和启动上述关键进程。Node向Master注册自己,一旦Node被纳入集群管理范围,kubelet进程就会定时向Master节点汇报自身的情况,如操作系统、Docker版本、机器的CPU和内存情况,以及有哪些pod在运行等。这样Master可以获知每个Node的资源使用情况,并实现高效均匀的资源调度策略。如果某个Node超过这顶时间不上报信息,会被Master判定为“失联”,这个Node节点被标记为不可用(Not Ready),Master节点将触发“工作负载大转移”的自动流程。

kubectl get nodes  #查看集群中有多少个Node

kubectl describe node <node_name> #查看某个Node的详细信息

Pod

      Pod是Kubernetes最重要也是最基本的概念,每个Pod都有一个特殊的被称为“根容器”的Pause容器,Pause容器对应的镜像属于Kubernetes平台的一部分,另外,每个Pod还包含一个或者多个紧密相关的用户业务容器。多个业务容器共享Pause容器的IP(Pod IP)和Pause任凭器挂接的Volume。Kubernetes底层网络支持集群内任意两个Pod之间的TCP/IP直接通信,通过虚拟二层网络技术来实现。因此,一个Pod里的容器与另外主机上的Pod容器能够直接通信。

     Pod包含两种类型:普通Pod和静态Pod(static Pod)。静态Pod不存储在Kubernetes的etcd中,而是存放在某个具体Node的一个具体文件中,并且只在次Node上启动运行。而普通Pod一旦被创建,会被放在etcd中存储,随后被Kubernetes Master调度到某个具体的Node上并进行绑定(Binding),该Pod被对Node上的Kubelet进程实例化成一组相关的Docker容器并启动起来。

  Kubernetes中所有的资源对象都可以采用yaml或者JSON格式的文件来定义和描述。

Label

Label是Kubernetes中另外一个核心概念。一个Label是一个key=value的键值对。Label可以附加到各种资源对象上,一个资源对象可以定义任意数量的Label,用一个Label也可以添加到任意数量的资源对象上去。通过给指定的资源对象捆绑一个或者多个Label来实现多维度的资源分组管理,随后可以通过Label Selector(标签选择器)查询和筛选拥有某些Label的资源对象。

Label Selector有两种表达式,基于等式(Equality-based)和基于集合的(Set-based),下面的例子:

等式类

name = redis-salve

env != production

集合类

name in (redis-master,redis-slave)

name not in(php-frontend)

可以通过多个表达式的组合实现复杂的条件选择,多个表达式之间用“,”分割,几个条件之间是“AND”的关系。

Label Selector通常在一下场景中使用:

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

总结,使用Label可以给对象创建多组标签,Label和Label Selector共同构成了Kubernetes系统中最核心的应用模型,实现对管理对象进行精细地分组管理,并实现了整个集群的高可用。

Replication Controller(RC)

RC是Kubernetes的核心概念之一,用于定义Pod的副本数量在任意时刻都符合某个预期值,RC定义包含一下几个部分:

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

在运行时,可以通过修改RC的副本数量实现Pod的动态缩放(Scaling),命令如下:

kubectl scale rc redis-slave --replicas=3  #原来设置的replicas是2

为了删除Pod,可以将replicas的值设置为0,然后更新该RC。kubectl delete用来一次性删除RC和RC控制的全部Pod。

  • 基于Pod.yaml定义的名称删除Pod
    kubectl delete -f pod.yaml
  • 删除所有包含某个label的Pod和service
    kubectl delete pods,services -l name=<label-name>
  • 删除所有Pod
    kubectl delete pods --all

之前版本中,RC只支持基于等式的Label Selector,从Kubernetes 1.2开始,Replication Controller升级为Relica Set,支持基于集合的Label Selector。kubectl命令行工具适用于RC的绝大部分命令都同样适用于Replica Set。

RC(Replica Set)的特性和作用:

  • 可用通过定义一个RC实现Pod的常见过程及副本数量的自动控制。
  • RC里包含完成的Pod定义模版。
  • RC通过Label Selector机制实现Pod副本的自动控制。
  • 通过改变RC里的Pod副本数量,可以实现Pod的扩容或者缩容。
  • 通过改变RC里的Pod模版中的镜像版本,可以实现Pod的滚动升级。

Deployment

   为了更好的解决Pod编排问题,从Kubernetes 1.2开始,引入了Deployment的概念。Deployment内部使用 Replica Set。

   Deployment典型使用场景:

  • 创建一个Deployment对象来生成对应的Replica Set,并完成Pod副本创建。
  • 检查Deployment的状态来查看部署动作是否完成(Pod副本数量是否达到预期值)。
  • 更新Deployment来创建新的Pod(如镜像升级)。
  • 如果当前版本不稳定,回滚到一个早先的Deployment版本。
  • 挂起或者恢复一个Deployment。

Deployment的定义与Replica Set定义很类似,只有API声明与Kind类型等有所区别:

apiVersion: extensions/v1beta1                                                                apiVersion:  V1

kind: Deployment                                                                                      kind: ReplicaSet

metadata:                                                                                                  metadata:

     name: nginx-deployment                                                                           name: nginx-deployment

 

kubectl create -f tomcat-deployment.yaml   #创建Deployment(假设yaml文件名为tomcat-deployment.yaml)

kubectl get deployments  #查看Deployment的信息

kubectl get rs  #查看对应的Replica Set

kubectl get pods  #查看创建的Pod

kubectl describe deployments   #查看Deployment控制的Pod的水平扩展过程

Horizontal Pod Autoscaler(HPA)

Horizontal Pod Autoscaler 是指Pod横向自动扩容,与RC、Deployment一样,属于Kubernetes资源对象。通过追踪分析RC控制的所有目标Pod的负载变化情况,来确定是否针对性地调整目标Pod的副本数,这是HPA的实现原理。

HPA支持两种方式作为Pod负载的度量指标。

  • CPU使用百分比(CPUUtilizationPercentage)
  • 应用程序自定义的度量指标,如服务每秒内响应的请求数TPS或QPS)

CPUUtilizationPercentage是一个算术平均值,即目标Pod所有副本自身的CPU利用率的平均值。

         一个Pod自身CPU利用率 = 当前CPU的使用量/Pod Request值

        CPU使用量通常是1分钟内的平均值, Pod Request是我们定义的一个值,如0.4。

根据这个公式,可以计算出一个RC控制的所有Pod副本的CPU利用率的算术平均值,如果这个值超过80%,则意味着当前的Pod副本数不足以支持接下来更多的请求,需要进行动态扩容。当请求高峰时段过去,Pod的CPU利用率会降下来,此时,对应的副本数将会减少到一个合理水平。

HPA资源可以通过两种方式来定义。

  • 定义yaml文件,并且通过kubectl create命令调用
  • 直接执行命令创建HPA:kubectl autoscale deployment php-apache --cpu-percent=90 --min=1 --max=10

服务(Service)

1、概述

  Service也是Kubernetes中最核心的资源对象之一。Service定义了一个服务的访问入口地址,其它应用Pod通过这个入口地址访问其背后的一组由Pod副本组成的集群实例,Service与后端Pod副本集群通过Label Selector来实现“无缝对接”。

客户端访问Pod集群提供的服务时,一般部署一个负载均衡器(软件或者硬件),开启一个对外服务的访问端口,然后将Pod的Endpoint(Pod IP+ContainerPort)列表加入端口的转发列表中,客户端通过负载均衡器地址+访问端口来访问Pod集群提供的服务,客户端的请求经过负载均衡器的算法来决定转发到哪个Pod上。

Service上分配的全局唯一虚拟IP地址被称为Cluster IP,Server Name与Service的Cluster IP地址进行DNS域名映射。

很多服务存在多个端口,Kubernetes Service支持多个Endpoint,在多个Endpoint的情况下,要求每个Endpoint定义一个名字来区分,这与Kubernetes的服务发现机制相关。

2、Kubernetes的服务发现机制

Kubernetes中,每个Service都有一个唯一的Cluster IP,名字由用户定义,并且在部署过程中没有必要更改,所以可以固定在配置中。而Service与Cluster IP间的解析由Kubernetes Add-On引入的DNS系统来完成,把服务名作为DNS域名,这样,程序就可以直接使用服务名来建立通信连接了。

3、外部系统访问Service

Kubernetes中的“三种IP”:

  • Node IP:Node节点的IP地址

        每个节点物理网卡的IP地址,属于真是存在的物理网络

  • Pod IP:Pod的IP地址

       Docker Engine根据docker0网桥的IP地址段给Pod分配的IP地址,通常是一个虚拟的二层网络。不同Node上的Pod容器通信,就是通过Pod IP所在的虚拟二层网络进行通信的。

  • Cluster IP:Service的IP地址

         一个虚拟的IP,具有一下特点:

          1)Cluster IP由Kubernetes 管理和分配IP地址(来源于Cluster IP地址池),只在Kubernetes集群内部有效。

          2)Cluster IP无法被Ping,因为没有“实体网络对象”来响应。

          3)Cluster IP需要结合Service Port组成一个具体的通信端口,单独的Cluster IP不具备TCP/IP通信的基础,并且他们只属于Kubernetes集群内部,如果外部想要访问这个通信端口,需要做一些额外的工作。

         4)Node IP网、Pod IP网与Cluster IP网之间的通信采用的是Kubernetes自己设计的一种编程方式的特殊路由规则,与IP路由有很大的不同。

      综上所述,Service的Cluster IP无法在集群外直接访问到,实际上业务系统中很多都是需要用户来使用的,这里采用的NodePort来解决这个问题。具体做法如下:

apiVersion: v1
kind: Service
metadata:
     name: tomcat-service
spec:
 type: NodePort
ports:
 - port: 8080
   nodePort: 31002
selector:
    tier:frontend

其中,nodePort: 31002这个属性标明我们手动指定tomcat-service的NodePort为31002,否则Kubernetes会自动分配一个可用的端口。NodePort的实现方式是在Kubernetes集群里的每个Node上为需要外部访问的Service开启一个对应的TCP监听端口。

但是NodePort无法解决用户访问是的负载均衡问题,所以需要一个负载均衡器,外部请求访问负载均衡器的IP,由负载均衡器负载转发流量到后端某个node的NodePort上去。Load balancer组建独立于Kubernetes集群之外。

Volume(存储卷)

Volume是Pod中能够被多个容器访问的共享目录。它可以实现多个Pod中的多个容器共享文件,让容器的数据写到宿主机磁盘或者写文件到网络存储中,Kubernetes Volume还扩展出一个非常有价值的功能,即容器配置文件集中化定义与管理,通过资源对象ConfigMap来实现。

下面是Kubernetes提供的Volume类型

1、emptyDir

  一个emptyDir Volume在Pod分配到Node时创建,提的初始内容为空,无需指定宿主机上对应的目录文件 ,以为它是Kubernetes自动分配的一个目录。当Pod从Node中移除是,该目录中的数据也会被永久删除。主要用途如下:

  • 临时空间。
  • 长时间任务的中间过程CheckPoint的临时保存目录。
  • 一个容器需要从另一个容器中获取数据的目录(多容器共享目录) 。

2、hostPath

     hostPath为在Pod上挂载宿主机上的文件或目录,主要用途:

  • 容器应用程序生成的日志文件需要永久保存时。
  • 容器需要访问宿主机上Docker引擎内部数据结构,可定义hostPath为宿主机/var/lib/docker目录,是容器内部应用可以直接访问Docker的文件系统

     使用hostPath Volume的注意事项

  • 在不同Node上具有相同配置的Pod,可能由于宿主机上目录或者文件不同,导致访问异常。
  • 资源配额管理无法管理hostPath Volume使用的资源。

3、NFS

     使用NFS共享目录存储数据,需要在系统中部署一台NFS Server,实例如下:

volumes:
  - name: nfs
   nfs:
     #改为自己的NFS服务器地址
     server: nfs-server.localhost
     path: " / "

4、其它类型的Volume:公有云提供的云盘等,iscsi、flocker、glusterfs、rbd、gitRepo、secret等

Persistent Volume(持久卷)

Persistent Volume简称PV,Kubernetes集群中某个网络存储中对应的一块存储,与Volume的区别:

  • PV只是网络存储,不属于任何Node,但可以在Node上访问。
  • PV不是定义在Pod上,独立于Pod之外。
  • PV类型:GCE Persistent Disks、NFS、RBD、iSCSCI、AWS ElasticBlockStore、GlusterFS等。

PV的accessModes属性支持以下类型:

  • ReadWriteOnce:读写权限、并且只能被单个Node挂载。
  • ReadOnlyMany:只读权限、允许被多个Node挂载。
  • ReadWriteMany:读写权限、允许被多个Node挂载。

如果 Pod想申请PV,首先需要定义一个PersistentVolumeClaim(PVC),然后在Pod的Volume定义中引用PVC。

PV是有状态的对象,有以下集中状态。

  • Available:空闲状态。
  • Bound:已绑定到某个PVC上。
  • Released:对应的PVC已经删除,但资源没有被集群收回。
  • Failed:PV自动回收失败。

Namespace(命名空间)

      Namespace用于实现多租户的资源隔离,通过将集群内部的资源对象“分配”到不同的Namespace中,形成逻辑上分组的不同项目、小组或者用户组,不同分组在共享使用整个集群资源的同时,还能被分别管理。

    Namespace的定义:

apiVersion: v1
kind: pod
metadata:
  name: busybox
  namespace: development
spec:
  containers:
  - images: busybox
    command: 
      - sleep
      - "3600"
    name: busybox

查看某名称空间中的对象:kubectl get pods --namespace=development

如果不加--namespace参数,默认显示default名称空间中的对象。

Namespace与Kubernetes的资源配额管理,可以限定不同租户能占用的资源。

Annotation(注解)

Annotation使用key/value键值对的形式进行定义,是用户定义的“附加”信息,便于外部工具进行查找。

用Annotation记录的信息如下:

  • build、release、Docker镜像等信息,例如时间戳、release id号、镜像hash值、docker register地址等
  • 日志库、监控库、分析库等资源库的地址信息。
  • 程序调试工具信息,例如工具名称、版本号等。
  • 团队的联系信息,例如电话号码、负责人名称等。

小结

上述是Kubernetes系统的核心组建,通过对它们进行灵活组合,用户就可以快速、方便地对容器集群进行配置、创建和管理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值