Kubernetes集群将所有节点上的资源都整合到一个大的虚拟资源池里,以代替一个个单独的服务器。如果把集群类比为一台传统的服务器,那么Kubernetes(Master)就好比是操作系统内核,其主要职责在于抽象资源并调度任务,而Pod资源对象就是那些运行于用户空间中的进程。
资源对象
API Server提供了RESTful风格的编程接口,其管理的资源是Kubernetes API中的端点,用于存储某种API对象的集合。Pod、Deployment和Service等都是最常用的核心对象。
Pod资源对象
Pod资源对象是一种集合了一到多个应用容器、存储资源、专用IP及支撑容器运行的其他选项的逻辑组件,是Kubernetes的部署单元及原子运行单元。 Kubernetes的网络模型要求其各Pod对象的IP地址位于同一网络平面内(同一IP网段),可以将每个Pod对象想象成一个逻辑主机,类似常规的物理主机或VM,运行于同一个Pod对象中的多个进程也类似于物理机或VM上独立运行的进程。 不过,Pod对象中的各进程均运行于彼此隔离的容器中,并于各容器间共享两种关键资源:网络和存储卷
- 网络:每个Pod对象都会被分配一个集群内专用的IP地址(PodIP),同一Pod内部的所有容器共享Pod对象的主机名、IP地址和端口等。因此,这些容器间可以通过本地回环地址进行通信。
- 存储卷:还为Pod对象配置一组“存储卷”资源,这些资源可以共享给其内部的所有容器使用。
一个Pod对象代表某个应用程序的一个特定实例,如果需要扩展应用程序,就可以通过为此应用程序创建多个Pod实例来实现。
Controller资源对象
在工作节点甚至是调度器自身导致了运行失败时,Pod对象将会被删除;同样,资源耗尽或节点故障导致的回收操作也会删除相关的Pod对象。 Kubernetes使用Controller实现对一次性的(用后即弃)Pod对象的管理操作,例如,要确保部署的应用程序的Pod副本数量符合用户的设定,以及基于Pod模板来重建Pod对象等,从而实现Pod对象的扩缩容、滚动更新和自愈能力等。
Controller本身也是一种资源类型,它有着多种实现,其中与工作负载相关的实现如:
- ReplicationController
- Deployment
- StatefulSet
- DaemonSet
- Jobs
也可统称它们为Pod控制器,控制器的定义通常由期望的**副本数量、Pod模板和标签选择器(Label Selector)**组成。它会根据标签选择器对Pod对象的标签进行匹配检查,所有满足选择条件的Pod对象都将受控于当前控制器并计入其副本总数,并确保此数目能够精确反映期望的副本数。
需要注意的是:在实际的应用场景中,在接收到的请求流量负载显著低于或接近于已有Pod副本的整体承载能力时,用户需要手动修改Pod控制器中的期望副本数量以实现应用规模的扩容或缩容。不过,若集群中部署了HeapSter或Prometheus一类的资源指标监控附件时,用户还可以使用“HorizontalPodAutoscaler”(HPA)计算出合适的Pod副本数量,并自动修改Pod控制器中期望的副本数以实现应用规模的动态伸缩,提高集群资源利用率。
Service资源对象
Service主要有三种常用类型:
- 仅用于集群内部通信的ClusterIP类型
- 接入集群外部请求的NodePort类型
- LoadBalancer类型
仅用于集群内部通信的ClusterIP类型
Pod对象重启或被重建后IP地址通常会发生变化,Service资源对象的作用便是在被访问的Pod对象与客户端之间添加一个有着固定IP地址的中间层,客户端向此地址发起访问请求后,相关的Service资源会负责将请求调度并代理至后端的Pod对象。Service IP是一种虚拟IP,也称为Cluster IP,它专用于集群内通信。
Service是“微服务”的一种实现,事实上它是一种抽象:通过规则定义出由多个Pod对象组合而成的逻辑集合,并附带访问这组Pod对象的策略。Service对象挑选、关联Pod对象的方式同Pod控制器一样,都是要基于Label Selector进行。
接入集群外部请求的NodePort类型
ClusterIP仅对集群内部开放,外部访问集群可通过NodePort,根据某个Node的IP和端口(NodePort)接入请求,并将其代理至相应的Service对象的Cluster IP上的服务端口,而后由Service对象将请求代理至后端的Pod对象的PodIP及应用程序监听的端口。这种请求需要经过两次转发。
LoadBalancer类型
NodePort会部署于集群中的每一个节点,只能访问到指定Node上的Service,如果存在集群外部的LoadBalancer,即可将用户请求负载均衡至集群中的部分或者所有节点。LoadBalancer通常是由Cloud Provider自动创建并提供的软件负载均衡器,也可以是由管理员手工配置的硬件设备。
K8S部署应用程序的基本过程
容器技术使得部署程序时不再需要直接更改主机环境,而K8S又使得创建和运行容器的操作不必再关注其主机位置,并在一定程度上赋予了它动态扩缩容及自愈的能力,从而让用户从主机、系统及应用程序的维护工作中解脱出来。
部署某个应用程序时,用户首先要向API Server请求创建一个Pod控制器,由控制器根据镜像等信息向API Server请求创建出一定数量的Pod对象,并由Master之上的调度器指派至选定的工作节点以运行容器化应用。此外,用户一般还需要创建一个具体的Service对象以便为这些Pod对象建立起一个固定的访问入口,从而使得其客户端能够通过其服务名称或ClusterIP进行访问。 API Server的客户端工具有kubectl和Dashboard。
kubectl的基础使用
Kubernetes API(API Server)是管理其各种资源对象的唯一入口,它提供了一个RESTful风格的CRUD(Create、Read、Update和Delete)接口用于查询和修改集群状态,并将结果存储于集群状态存储系统etcd中。 用户可以通过kubectl访问API Server来操作Kubernetes的各种资源对象。
创建资源对象
kubectl run nginx-deploy --image=nginx:1.12 --replicas=1
这样的命令创建了一个名为nginx-deploy的deployment控制器资源,然后由这个资源来根据指定的镜像名称、副本数量来负责pod的创建。
查看资源对象 kubectl get
命令用于查看资源对象
~ kubectl get namespaces
NAME STATUS AGE
default Active 23h
kube-node-lease Active 23h
kube-public Active 23h
kube-system Active 23h
~ kubectl get pods
NAME READY STATUS RESTARTS AGE
myapp 1/1 Running 0 14h
nginx-deploy 1/1 Running 0 14h
Kubernetes系统的大部分资源都隶属于某个Namespace对象,缺省的名称空间为default,若需要获取指定Namespace对象中的资源对象的信息,则需要使用-n或--namespace指明其名称
打印资源对象的详细信息 kubectl get -o {yaml|josn}
或kubectl describe
命令都能够打印出指定资源对象的详细描述信息. kubectl get -o {yaml|josn}
可以查看资源对象的用户期望状态(Spec)和现有的实际状态(Status),比如查看default namespaces下所有pods的状态信息并输出为yaml格式:
~ kubectl get pods -n default -o yaml
kubectl describe
命令可以显示资源的event、controller等信息。
~ kubectl describe pods myapp
打印容器中的日志信息 命令格式为:
kubectl logs [-f] [-p](POD|TYPE/NAME) [-c CONTAINER][options]
可打印指定Pod内指定容器的日志,如果Pod内只有一个容器,则容器名可省略,-f可用于持续监控日志输出。
在容器中执行命令 命令格式为:
kubectl exec [-p](POD|TYPE/NAME) [-c CONTAINER][options] -- [COMMAND]
删除资源对象 kubectl delete
命令可以删除资源对象,但对于受控于控制器的对象来说,删除之后其控制器可能会重建出类似的对象,例如,Deployment控制器下的Pod对象在被删除时就会被重建。 有些资源类型(如Pod),支持优雅删除的机制,它们有着默认的删除宽限期,可以在命令中使用--grace-period选项或--now选项来覆盖默认的宽限期。
学习资料
《Kubernetes实战进阶》 马永亮著