最近在学习k8s,这是笔记
应用类资源主要是围绕Service
和Pod
两个资源类型展开的。
一般来说,Service
指的是无状态服务,通常由对应的多个程序副本(Pod
实例)提供,在特殊情况下也可以是有状态单实例服务,比如MySQL
这种数据库存储服务。Service
既可以是TCP
服务,也可以是UDP
服务,还可以是SCTP
服务,对具体的应用层协议的内容并没有任何限制。SCTP(Stream Control Transmission Protocol,流控制传输协议)是一个基于IP的可靠的面向控制信令的传输层协议,在电信领域被广泛应用,可以为电信级信令提供高效、可靠的传输服务,在5G核心网中也被应用。
与我们常规理解的服务不同,Kubernetes中的Service
具有全局唯一的虚拟ClusterIP
地址,Service
一旦被创建,Kubernetes就会自动为它分配一个可用的ClusterIP
地址,而且在Service
的整个生命周期内,它的ClusterIP
都不会改变,客户端可以通过【虚拟IP地址+服务的端口】的形式直接访问服务,在通过部署Kubernetes集群的DNS服务,就可以实现Service Name(域名)到ClusterIP
地址的DNS映射功能,我们只要使用服务的名称(DNS名称)即可顺利完成到目标服务的访问请求。这样,【服务发现】这个传统架构中的棘手问题首次得到完美解决。同时,凭借ClusterIP
地址的独特设计,Kubernetes进一步实现了Service
透明负载均衡和故障自动转移和恢复的高级特性。
通过分析、识别并建模系统中的所有服务为微服务 —— Kubernetes Service, 我们的系统最终由多个提供不同业务能力而又彼此独立的微服务单元组成,服务之间通过 TCP/IP通信,形成了强大又灵活的弹性网络,拥有强大的分布式、弹性扩展和容错能力,程序框架也变得简单和直观许多。
接下来说说与Service
密切相关的核心资源对象 —— Pod
。
Pod
是Kubernetes中最重要的基础概念之一,每个Pod
都有一个特殊的被称为【根容器】的Pause
容器,Pause
容器对应的镜像属于Kubernetes的一部分,除了Pause
容器,每个Pod
都还有一个或者多个紧密相关的用户业务容器。
为什么Kubernetes会设计出一个全新的Pod
概念,并且Pod
会有这样的特殊组成结构?原因如下:
Pod
作为基本的调度、复制等管理工作的最小单位,能让多个应用进程一起有效的调度和伸缩Pod
中的多个业务容器共享Pause
容器的IP,并且共享Pause
容器挂接的Volume
,这样既简化了密切关联的业务容器之间的通信问题,也很好的解决了他们之间的文件共享问题。Kubernetes 为每个Pod
都分配了一个唯一的IP,称之为【Pod IP】,一个Pod
中的多个容器共享Pod IP地址。Kubernetes要求底层网络支持集群中任意两个Pod
之间的TCP/IP直接通信,这通常采用虚拟二层网络技术实施,例如Flannel、Open vSwitch等,因此我们需要记住一点:在Kubernetes中,一个Pod
中的容器与其他主机上的Pod
容器能够直接通信。
Pod
其实有两种类型:普通Pod
和静态Pod(Static Pod)
。静态Pod比较特殊,并没有被存放在Kubernetes的etcd
中,而是被存放在某个具体的Node
上的一个具体文件中,并且只能在此Node
上启动、运行。而普通Pod
一旦被创建,就会被存放在etcd
中,随后进程实例化成一组相关的Docker
容器并启动。在默认情况下,当Pod
中的某个容器停止时,Kubernetes会自动检测到这个问题并且重新启动这个Pod
(重启Pod
中的所有容器),如果Pod
所在的Node
宕机,就会将这个Node
上所有的Pod
都重新调度到其他节点。
下面是我们在之前的Hello, World实例里用到的myweb这个Pod
的资源定义文件:
apiVersion: v1
kind: Pod
metadata:
name: myweb
labels:
name: myweb
spec:
containers:
- name: myweb
image: kubeguide/tomcat-app:v1
ports:
- containerPort: 8080
在以上定义中,kind
属性的值为Pod
,表明这是一个Pod
类型的资源对象; metadata
里的name
属性为Pod
的名称,在metadata
里还能定义资源对象的标签,这里生命myweb
拥有一个name=myweb
标签。在Pod
中所包含的容器组的定义则在spec
部分中声明,这里定义里一个名为myweb
且对应的镜像为kubeguide/tomcat-app:v1
的容器,并在8080
端口(containerPort)启动容器进程。Pod
的IP地址加上这里的容器端口组成里一个新的概念 —— Endpoint,代表此Pod
的一个服务进程的对外通信地址。一个Pod
也存在具有多个Endpoint
的情况,比如当我们把Tomcat
定义为一个Pod
时,可以对外暴露管理端口和服务端口这两个Endpoint
。
我们所熟悉的Docker Volume在Kubernetes也有对应的概念 —— Pod Volume, Pod Volume被定义在Pod
中,然后被Pod
的各个容器挂载(Mount)到自己的文件系统中。Volume简单来说就是被挂载到Pod
容器中的文件目录。
这里顺便提一下Kubernetes中的Event
概念,Event
是一个事件记录,记录里事件的最早产生时间、最后重现时间、重复次数、发起者、类型,以及导致此次事件的原因等众多信息。Event
记录通常会被关联到某个具体的资源对象上,是排查故障的重要参考信息。之前我们看到在Node
的描述信息中包括Event
,而在Pod
的描述信息中同样包括Event
,当我们发现某个Pod
迟迟无法创建时,可以通过kubectl describe pod xxxx
命令查看它的描述信息,以定位问题的成因。
在继续说明Service
和Pod
的关系之前,我们需要先理解Kubernetes中的一个重要机制 —— 标签匹配机制。