Back to Blogs
kubernetes
docker
devops
cloud-native
container

Kubernetes(K8S)基础知识

Soloman
2021-01-05

Kubernetes(K8S)基础知识

1 基本概念

1.1 Master

Kubernetes的Master指的是集群控制节点,每个Kubernetes集群里需要有一个Master节点来负责整个集群的管理和控制,基本上 Kubernetes所有的控制命令都是发给它,它来负责具体的执行过程。 Master节点上运行着以下一组关键进程:

  • Kubernetes API Server(kube-apiserver),提供了HTTP Rest接口的关键服务进程,是Kubernetes里所有资源的增、删、改、查等操作的唯一入口,也是集群控制的入口进程
  • Kubernetes Controller Manager(kube-controller-manager), Kubernetes里所有资源对象的自动化控制中心,可以理解为资源对象的“大总管”
  • Kubernetes Scheduler(kube-scheduler),负责资源调度(Pod调度)的进程,相当于公交公司的“调度室”
  • etcd Server,Kubernetes里的所有资源对象的数据全部是保存在etcd中的

Master-Node

1.2 Node

除了Master,Kubernetes集群中的其他机器被称为Node节点,在较早的版本中也被称为Minion。与Master一样,Node节点可以是一台物理主机,也可以是一台虚拟机。Node节点才是Kubernetes集群中的工作负载节点,每个Node都会被Master分配一些工作负载(Docker容器),当某个Node宕机时,其上的工作负载会被Master自动转移到其他节点上去。

每个Node节点上都运行着以下一组关键进程:

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

Master-Node

1.3 Pod

每个Pod都有一个特殊的被称为“根容器”的Pause容器。Pause容器对应的镜像属于Kubernetes平台的一部分,除了Pause容器,每个Pod还包含一个或多个紧密相关的用户业务容器。

  • Pod里的多个业务容器共享Pause容器的IP,共享Pause容器挂接的Volume,这解决了容器间通信和文件共享的问题
  • Endpoint:Pod的IP加上容器端口(containerPort),它代表着此Pod里的一个服务进程的对外通信地址

Master-Node

1.4 Label

一个Label是一个key=value的键值对,其中key与value由用户自己指定。Label可以附加到各种资源对象上,例如Node、Pod、Service、RC等,一个资源对象可以定义任意数量的Label,同一个Label也可以被添加到任意数量的资源对象上去,Label通常在资源对象定义时确定,也可以在对象创建后动态添加或者删除。

  • 主要功能是方便地进行资源分配、调度、配置、部署等管理工作
  • 可以通过Label Selector(标签选择器)查询和筛选拥有某些Label的资源对象
  • 版本标签:“release”:“stable”,“release”:“canary”...
  • 环境标签:“environment”:“dev”,“environment”:“qa”,“environment”:“production”...
  • 架构标签:“tier”:“frontend”,“tier”:“backend”,“tier”:“middleware”...
  • 分区标签:“partition”:“customerA”,“partition”:“customerB”...
  • 质量管控标签:“track”:“daily”,“track”:“weekly”...

1.5 Replication Controller(RC)

RC其实是定义了一个期望的场景,即声明某种Pod的副本数量在任意时刻都符合某个预期值,当不符合预期时要采取什么行动达到预期。

RC的定义包括如下几个部分:

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

当我们定义了一个RC并提交到Kubernetes集群中以后,Master节点上的Controller Manager组件就得到通知,定期巡检系统中当前存活的目标Pod,并确保目标Pod实例的数量刚好等于此RC的期望值,如果有过多的Pod副本在运行,系统就会停掉一些Pod,否则系统就会再自动创建一些Pod。 Kubernetes新版本提出了Replica Set概念,Replica Set支持基于集合的Label selector(Set-based selector),而RC只支持基于等式的Label Selector(equality-based selector),这使得Replica Set的功能更强 注意:删除RC并不会影响通过该RC已创建好的Pod。为了删除所有Pod,可以设置replicas的值为0,然后更新该RC。

  • 在大多数情况下,我们通过定义一个RC实现Pod的创建过程及副本数量的自动控制
  • RC里包括完整的Pod定义模板
  • RC通过Label Selector机制实现对Pod副本的自动控制
  • 通过改变RC里的Pod副本数量,可以实现Pod的扩容或缩容功能
  • 通过改变RC里Pod模板中的镜像版本,可以实现Pod的滚动升级功能

1.6 Deployment

Deployment是为了更好地解决Pod的编排问题,可以把它看作RC的一次升级。Replica Set与Deployment这两个重要资源对象逐步替换了之前的RC的作用

Deployment的典型使用场景:

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

1.7 Horizontal Pod Autoscaler(HPA)

HPA通过追踪分析RC控制的所有目标Pod的负载变化情况,来确定是否需要针对性地调整目标Pod的副本数,这是HPA的实现原理。 HPA有以下两种方式作为Pod负载的度量指标:

  • CPU Utilization Percentage
  • 应用程序自定义的度量指标,比如服务在每秒内的相应的请求数(TPS或QPS)

CPU Utilization Percentage是一个算术平均值,即目标Pod所有副本自身的CPU利用率的平均值。例如某一时刻CPU Utilization Percentage的值超过80%,则意味着当前的Pod副本数很可能不足以支撑接下来更多的请求,需要进行动态扩容,而当请求高峰时段过去后,Pod的CPU利用率又会降下来,此时对应的Pod副本数应该自动减少到一个合理的水平

1.8 Service

Kubernetes里的每个Service其实就是我们经常提起的微服务架构中的一个“微服务”。每个Service分配了一个全局唯一的虚拟IP地址,这个虚拟IP被称为Cluster IP

  • Node IP:Node节点的IP地址。Node IP是Kubernetes集群中每个节点的物理网卡的IP地址,这是一个真实存在的物理网络,所有属于这个网络的服务器之间都能通过这个网络直接通信
  • Pod IP:Pod的IP地址。Pod IP是每个Pod的IP地址,它是Docker Engine根据docker网桥的IP地址段进行分配的,通常是一个虚拟的二层网络,Kubernetes要求位于不同Node上的Pod能够彼此直接通信,所以Kubernetes里一个Pod里的容器访问另外一个Pod里的容器,就是通过Pod IP所在的虚拟二层网络进行通信的,而真实的TCP/IP流量则是通过Node IP所在的物理网卡流出的
  • Cluster IP:Service的IP地址。Cluster IP是一个虚拟的IP,仅仅作用于Kubernetes Service这个对象,并由Kubernetes管理和分配IP地址(来源于Cluster IP地址池)。Cluster IP无法被Ping,因为没有一个“实体网络对象”来响应。 Cluster IP只能结合Service Port组成一个具体的通信端口,单独的Cluster IP不具备TCP/IP通信的基础,并且Cluster IP属于Kubernetes集群内部的地址,无法在集群外部直接使用这个地址。

1.9 Volume

Volume是Pod中能够被多个容器访问的共享目录。Kubernetes中的Volume定义在Pod上,然后被一个Pod里的多个容器挂载到具体的文件目录下;Volume与Pod的生命周期相同,但与pod中docker容器的生命周期不相关,当docker容器终止或者重启时,Volume中的数据也不会丢失。 Kubernetes的Volume类型:

  1. emptyDir
  • 一个emptyDir Volume是在Pod分配到Node时创建的,无须指定宿主机上对应的目录文件,因为这是Kubernetes自动分配的一个目录
  • 当Pod从Node上移除时,emptyDir中的数据也会被永久删除
  • 临时空间,例如用于某些应用程序运行时所需的临时目录,且无须永久保留
  • 长时间任务的中间过程CheckPoint的临时保存目录
  • 一个容器需要从另一个容器中获取数据的目录(多容器共享目录)
  1. hostPath
  • hostPath为在Pod上挂载宿主机上的文件或目录
  • 容器应用程序生成的日志文件需要永久保存时,可以使用宿主机的高速文件系统进行存储
  • 需要访问宿主机上Docker引擎内部数据结构的容器应用时,可以通过定义hostPath为宿主机/var/lib/docker目录,使容器内部应用可以直接访问Docker的文件系统
  1. gcePersistentDisk
  • 使用谷歌公有云提供的永久磁盘(Persistent Disk,PD)存放Volume的数据
  • 数据会被永久保存
  1. awsElasticBlockStore
  • 与GCE类似,该类型的Volume使用亚马逊公有云提供的EBS Volume存储数据
  1. NFS
  • 使用NFS网络文件系统提供的共享目录存储数据时,我们需要在系统中部署一个NFS Server

1.10 Persistent Volume

PV可以理解成Kubernetes集群中的某个网络存储中对应的一块存储

  • PV只能是网络存储,不属于任何Node,但可以在每个Node上访问
  • PV并不是定义在Pod上的,而是独立于Pod之外定义
  • PV目前只有几种类型:GCE Persistent Disks、NFS、RBD、iSCSCI、AWS ElasticBlockStore、GlusterFS等

1.11 Namespace

Namespace 通过将集群内部的资源对象“分配”到不同的Namespace中,形成逻辑上分组管理。Namespace在很多情况下用于实现多租户的资源隔离。

1.12 Annotation

Annotation与Label类似,也使用key/value键值对的形式进行定义。 不同的是Label定义的是Kubernetes对象的元数据(Metadata),并且用于Label Selector。而Annotation则是用户任意定义的“附加”信息,可作为注解或备注信息

1.13 负载均衡

运行在每个Node上的kube-proxy进程其实就是一个智能的软件负载均衡器,它负责把对Service的请求转发到后端的某个Pod实例上,并在内部实现服务的负载均衡与会话保持机制。

2 Pod

2.1 基本使用

  • 在Kubernetes系统中对长时间运行容器的要求是:其主程序需要一直在前台执行,否则会立即销毁Pod。
  • Pod可以由1个或多个容器组合而成,属于一个Pod的多个容器应用之间相互访问时仅需要通过localhost就可以通信
# 使用YAML配置文件创建pod
kubectl create -f podname-pod.yaml

# 查看已创建的pod
kubectl get pods

# 查看pod详细信息
kubectl describe pod podname

2.2 静态Pod

  • 静态Pod是由kubelet进行管理的仅存在于特定Node上的Pod
  • 它们不能通过API Server进行管理,无法与ReplicationController、Deployment 或者DaemonSet进行关联,并且kubelet也无法对它们进行健康检查
  • 静态Pod总是由kubelet进行创建,并且总是在kubelet所在的Node上运行
  • 通过设置kubelet的启动参数“--config”,指定kubelet需要监控的配置文件所在的目录,kubelet会定期扫描该目录,并根据该目录中的.yaml或.json文件进行创建静态pod
  • 删除该Pod的操作只能是到其所在Node上,将其定义文件从配置文件所在的目录下删除

例如:假设配置目录为/etc/kubelet.d/,配置启动参数:--config=/etc/kubelet.d/,然后重启kubelet服务,在目录/etc/kubelet.d中放入static-podname.yaml文件即可,要删除静态pod时直接删static-podname.yaml即可

2.3 Pod容器共享Volume

  • 在同一个Pod中的多个容器能够共享Pod级别的存储卷Volume
  • 多个容器各自进行挂载操作,将一个Volume挂载为容器内部需要的目录

2.4 Pod生命周期和重启策略

  • Pod五大状态:Pending,Running, Succeed, Failed,Unknown
  • Pod三大重启策略:Always、OnFailure和Never,默认值为Always
  • Pod的重启策略与控制方式相关,当前可用于管理Pod的控制器包括Replication Controller、Job、DaemonSet及直接通过kubelet管理(静态Pod)
  • RC和DaemonSet:必须设置为Always,需要保证该容器持续运行
  • Job:OnFailure或Never,确保容器执行完成后不再重启
  • kubelet:在Pod失效时自动重启它,不论RestartPolicy设置为什么值,并且也不会对Pod进行健康检查

2.5 Pod调度

在Kubernetes系统中,Pod在大部分场景下都只是容器的载体而已, 通常需要通过RC、Deployment、DaemonSet、Job等对象来完成Pod的调度与自动控制功能

  1. RC、Deployment:全自动调度 Kubernetes Master上的Scheduler服务(kube-scheduler进程)负责实现Pod的调度,整个调度过程通过执行一系列复杂的算法,最终为每个Pod计算出一个最佳的目标节点,这一过程是自动完成的,通常我们无法知道Pod最终会被调度到哪个节点上

  2. NodeSelector:定向调度 在实际情况中,也可能需要将Pod调度到指定的一些Node上,可以通过Node的标签(Label)和Pod的nodeSelector属性相匹配,来达到上述目的 需要注意的是,如果指定了Pod的nodeSelector条件,且集群中不存在包含相应标签的Node,则即使集群中还有其他可供使用的Node,这个Pod也无法被成功调度

  3. NodeAffinity:亲和性调度

  4. DaemonSet:特定场景调度 DaemonSet的Pod调度策略与RC类似,除了使用系统内置的算法在 每台Node上进行调度,也可以在Pod的定义中使用NodeSelector或NodeAffinity来指定满足条件的Node范围进行调度

  5. Job:批处理调度

2.6 Pod的扩容和缩容

  1. kubectl scale命令完成Pod的扩容和缩容操作
kubectl scale rc rc-name --replicas=2
  1. Horizontal Pod Autoscaler(HPA) HPA控制器基于Master的kube-controller-manager服务启动参数--horizontal-pod-autoscaler-sync-period定义的时长(默认为30秒),周期性地监测目标Pod的CPU使用率,并在满足条件时对ReplicationController或Deployment中的Pod副本数量进行调整,以符合用户定义的平均Pod CPU使用率。

2.7 Pod的滚动升级

滚动升级通过执行kubectl rolling-update命令一键完成,该命令创建了一个新的RC,然后自动控制旧的RC中的Pod副本的数量逐渐减少到0,同时新的RC中的Pod副本的数量从0逐步增加到目标值,最终实现了Pod的升级 需要注意的是,系统要求新的RC需要与旧的RC在相同的命名空间(Namespace)内,即不能把别人的资产偷偷转移到自家名下