图片来源:自己画的
图片来源:k8s官网
首先,什么是ingress?
是服务还是控制器?
都不精确
ingress是一个api资源
service和deployment也是api资源。
这几个相互协作,组建成一个对外提供服务的架构。
ingress提供的作用是什么?
ingress资源的生成,系统会给ingress资源一个ip地址
这个ip地址下的不同路径,会定位到后端的不同服务
比如ingress资源的ip地址是192.168.1.3
那么客户端访问http://192.168.1.3/websvc_path
ingress资源会把这个请求
转发给后端一个服务
这个服务的名称为websvc (举例,具体是在ingress资源文件中指定)
这个服务的端口号为6789 (举例,具体是在ingress资源文件中指定)
这个服务真实的提供者
是后端的pod,
这些pod监听着6789端口
这些pod与websvc服务绑定
如何绑定?
是通过服务资源文件中定义的selector标签选择器
而pod资源文件中给pod都加了这个标签
通过这个标签
服务能找到pod
这个叫服务的自动感知功能。
如果某个带有这个标签的pod删除了,
重新在别的节点上以别的ip产生了
拥有同样标签的pod
服务能自动感知到这个新的pod,
服务是如何感知到这个新的pod的?
这个就和服务的程序设计有关,
从开发代码的层面,
其核心是跟网络插件对于ip的管理
和数据库组件对于新pod 的信息的记录有关。
核心也是标签选择器。
服务还有一个功能是负载均衡,
外部对于服务的请求,会分摊到后端的pod
如何实现的?
是通过kube-proxy组件
kube-proxy组件是如何实现负载均衡的?
是调用ipvs内核模块
也就是使用lvs进行负载均衡
服务还有一个功能,是自动注册
就是把ip地址注册为域名
服务创建时,自动在内部dns上注册域名
域名格式为:
<服务名称>.<名称空间>.svc.cluster.local
说服务的目的是什么?跟ingress什么关系?
ingress的资源文件中
需要指定
把对于集群的某一个/path的访问
转发给后端的一个服务及其监听的端口
而这个后端的服务
是一个服务名
那么ingress怎么通过这个服务的名称
找到这个服务呢
就跟服务的自动注册有关系,
内部dns上,记录了这个服务的名称和ip的对应关系
所以ingress可以通过名称的方式找到后端的服务
ingress需要选择一个控制器,
nginx或者haproxy
一般用nginx的比较多
那么ingress怎么使用这个nginx来
进行负载均衡反向代理这些操作呢
就要通过选择ingressclass来实现
是选nginx?
还是选haproxy?
还是选别的?
要选择nginx
就要在ingress的资源文件中声明
ingressClassName: nginx
那么,ingressclass
也就是ingress的类之一
nginx
这个nginx是从哪来的呢?
是在ingressclass的资源文件中
要在.spec的字段下
定义一个
controller: k8s.io/ingress-nginx
这个ingressclass中定义了
名称为nginx的ingress的类
这是一个标识符
实际上的控制器是ingress-nginx
ingress-nginx这个控制器是以什么形态存在的?
是以pod的形态存在的
pod里面运行着实现控制器功能的容器
容器里面运行着实现控制器功能的进程
容器来自于docker镜像
镜像在部署k8s平台的时候
就需要部署在harbor仓库里
ingress-nginx这个控制器的pod从哪来的?
是用deployment无状态控制器来实现的
deployment中定义了
ingress-nginx控制器的pod的容器模版
如何启动ingress-nginx这个控制器?
常用两种方式
-
Helm Chart方式,部署k8s集群的时候,就自动部署好了,也就是集群已经有这个ingress-nginx
-
yaml资源文件方式
ingress-nginx控制器要实现功能,需要有一个资源文件,这个资源文件里面有相关的service资源和deployment资源,也就是一个文件中有多个资源,来实现ingress-nginx控制器。说白了就是,service接收访问ingress-nginx控制器的请求,转发给后端的ingress-nginx的pod,这些pod同时由deployment进行自动部署、维护、扩容、滚动更新。
根本上来说,ingress-nginx控制器来源于
镜像文件,以及用镜像文件启动容器的时候,配置的一些启动参数
还有存放这个容器的pod中,配置的一些可选项
比如initcontainer 初始化容器
startupPorbe
livenessProbe
readinessProbe
这三个容器探针
还有
postStart
preStop
这两个事件处理函数,也叫钩子函数。
以镜像文件、
启动参数、
configMap注入配置文件
还有pod内的一系列要素
构建了ingress-nginx这个控制器的核心
通过service对ingress-nginx进行发布
让ingress在集群内能找到这个控制器
通过deployment对于ingress-nginx进行自动化部署和维护
包括扩容和滚动更新
这样,形成了一个ingress资源对外提供请求分发的功能
ingress自己本身由于有service来管理后端ingress-nginx的pod
所以自身也是负载均衡的
而且有deployment的存在
ingress资源本身的pod也是能自动部署和维护的
比如提供ingress服务的pod出错了
deployment会自动修复,部署新的
如果有必要的话,deployment里面的副本数量
写成2个3个以上,这样能更加保障
ingress资源本身的高可用,而且是自维护
ingress对流量进行分发之后
后端提供计算服务的,
比如web服务
也是可以利用同样的架构
service+pod+deployment的方式
实现负载均衡和高可用
在传统方式中,用到的lvs、nginx、keepalived
负载均衡和高可用技术。
在容器化环境中,
在k8s平台,
以kube-porxy调用ipvs
ingress调用nginx
deployment调用keepalived (不一定相同,但原理类似)
实现了负载均衡和高可用
而且在deployment的基础上
k8s提供了
HPA监理功能
HorizontalPodAutoscaling
水平 pod 自动 伸缩
deployment的扩缩容需要
管理员去手工scale
根据资源的使用量调整
而HPA可以自动根据pod的资源使用量
调整pod的数量
也就是自动扩缩容
管理员只需要提前配置好就行。
这么来看,k8s对于容器化环境的
负载均衡、
高可用、
自动化部署(给个模版,自动创建pod)、
自动化维护(pod删掉了,自动新建)、
自动化调整服务器规模
(pod不够用了,自动扩容;
pod太多了,请求没那么多,自动缩容)
都设计的比较ok
从pod的监控方面来讲
pod中的
容器探针
钩子函数
初始化容器
包括利用临时卷
configMap
emptyDir
可以实现很多功能。
总的来说
k8s作为云原生时代的平台
也称为云原生时代的操作系统,
对于传统方式的容器化提供了很多功能。
资源利用率更高
服务的管理更加自动化。
安全性也比较高