K8S核心概念
# 一、K8S架构
我们再来简单的回顾下k8s的架构,kubernetes中有两类资源,分别是master和nodes,master和nodes上跑的服务如下图,
kube-apiserver | kubelet
kube-controller-manager |
kube-scheduler | kube-proxy
---------------------- --------------------
k8s master node (non-master)
2
3
4
5
- master:负责管理整个集群,例如,对应用进行调度(扩缩)、维护应用期望的状态、对应用进行发布等。
- node:集群中的宿主机(可以是物理机也可以是虚拟机),每个node上都有一个agent,名为kubelet,用于跟master通信。同时一个node需要有管理容器的工具包,用于管理在node上运行的容器(docker或rkt)。一个k8s集群至少要有3个节点。
kubelet通过master暴露的API与master通信,用户也可以直接调用master的API做集群的管理。
# 二、pod
k8s中的最小部署单元,不是一个程序/进程,而是一个环境(包括容器、存储、网络ip:port、容器配置)。其中可以运行1个或多个container(docker或其他容器),在一个pod内部的container共享所有资源,包括共享pod的ip:port和磁盘。 pod是临时性的,用完即丢弃的,当pod中的进程结束、node故障,或者资源短缺时,pod会被干掉。基于此,用户很少直接创建一个独立的pods,而会通过k8s中的controller来对pod进行管理。
controller通过pod templates来创建pod,pod template是一个静态模板,创建出来之后的pod就跟模板没有关系了,模板的修改也不会影响现有的pod。
# 三、services
由于pod是临时性的,pod的ip:port也是动态变化的。这种动态变化在k8s集群中就涉及到一个问题:如果一组后端pod作为服务提供方,供一组前端的pod所调用,那服务调用方怎么自动感知服务提供方。这就引入了k8s中的另外一个核心概念,services. service是通过apiserver创建出来的对象实例,举例,
kind: Service
apiVersion: v1
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
2
3
4
5
6
7
8
9
10
11
这个配置将创建出来一个新的Service对象,名为my-service,后端是所有包含app=MyApp的pod,目标端口是9376,同时这个service也会被分配一个ip,被称为集群ip,对应的端口是80. 如果不指定targetPort
, 那么 targetPort
与 port
相同。
关于targetPort更灵活的设定是,targetPort可以是一个String类型的名字,该名字对应的真实端口值由各个后端pod自己定义,这样同一组pod无需保证同一个port,更加灵活。
终于知道为什么k8s是目前风头最劲的服务编排技术了,它充分地做了解耦,由于google的业务复杂性,它的组件和组件之间,充分的解耦、灵活,整个系统松散且牢固。
services组件与bns不同的一点,bns的节点是自己指定了name和后端的关联关系,而services是根据pod上的标签(label)自动生成的,更灵活。ali的group就更别提了,group是隶属于app的,扩展性方面更弱一些。
上文说在创建service的时候,系统为service分配了一个集群虚IP和端口,服务使用方通过这个vip:port来访问真实的服务提供方。这里的vip就是kube-proxy提供出来的。
# 四、Ingress
Ingress是个什么鬼,网上资料很多(推荐官方),大家自行研究。简单来讲,就是一个负载均衡的玩意,其主要用来解决使用NodePort暴露Service的端口时Node IP会漂移的问题。同时,若大量使用NodePort暴露主机端口,管理会非常混乱。
好的解决方案就是让外界通过域名去访问Service,而无需关心其Node IP及Port。那为什么不直接使用Nginx?这是因为在K8S集群中,如果每加入一个服务,我们都在Nginx中添加一个配置,其实是一个重复性的体力活,只要是重复性的体力活,我们都应该通过技术将它干掉。
Ingress就可以解决上面的问题,其包含两个组件Ingress Controller和Ingress:
- Ingress 将Nginx的配置抽象成一个Ingress对象,每添加一个新的服务只需写一个新的Ingress的yaml文件即可
- Ingress Controller 将新加入的Ingress转化成Nginx的配置文件并使之生效