Kubernetes(K8s)_04_Service
Kubernetes(K8s)Pod暴露服务的介体-Service
Kubernetes(K8s)_04_Service
Service
Service(服务,SVC):为一组或多组提供相同服务的Pod的静态地址
1)SVC属于Kubernetes的一种资源类型;
2)SVC通过标签选择器,指定部分Pod属于特定SVC;
3)到达Service的IP和端口的请求,将被转发至该Service下容器IP和端口;
4)SVC可解决Pod不断变化的IP,同时在固定的IP和端口上对外暴露服务;
//当替换一个Pod时,新Pod会具有不同的IP
SVC须知:
1)SVC的IP是一个虚拟IP,只有结合端口时才有实际意义;
2)SVC的IP是无法Ping通的;
3)SVC和Pod并不是之间相连接的
如:SVC所承担的作用
如:SVC通过标签选择器归类Pod
创建Service
创建Service两种方式:expose命令和YAML文件
创建Service格式:
apiVersion:v1
kind:Service
metadata:
name: SVC名称
spec:
type: SVC类型
sessionAffinity: 会话亲和性
ports:
- name:端口名称1
port: 服务暴露端口号1
targetPort: 映射的容器端口号1
- name: 端口名称N
prot: 服务暴露端口号N
targetPort: 映射的容器端口号N
selector:
标签名1: 标签值1
标签名N: 标签值N
(1)SVC类型分为:
1)ExternalName:通过spec.externalName字段设置服务的FQDN别名;
2)NodePort:暴露服务;
3)LoadBalance:暴露服务
(2)会话亲和性分为2种:
1)None:不做任何处理;
2)ClientIP:将同一个IP的多次请求转发至同一个Pod
(3)标签选择器应用于整个服务设定(不能对每个端口做单独设置)
如:通过YAML文件生成Service
1)编写YAML文件
2)调用create命令生成Service,并验证
3)调用其他Pod访问该服务验证
//尚未配置,只能由内部Pod访问SVC
4)多次访问验证Service是随机转发到Pod
如:创建监听多个端口的SVC
1)编写Pod的YAML文件
2)编写Service的YAML文件;
3)调用create命令生成Service,并验证
4)访问服务的两个端口验证
//通过命名端口实现容器的端口号改变时,无需修改SVC的相关配置
发现服务
(1)环境变量
1)当Pod开始运行时,Kubernetes会初始化一系列环境变量指定已有的SVC;
2)若通过环境变量发现服务,SVC必须先于Pod创建
主要通过以下两个环境变量发现服务:
1)服务名称_SERVICE_HOST=服务的IP
2)服务名称_SERVICE_PORT=服务的端口
//服务名称在变为环境变量名称时,全为大写(若有横杠,则被转化为下划线)
如:查看已有服务下的Pod环境变量
(2)DNS
1)Kubernetes默认的系统Pod“kube-dns”运行集群的DNS服务;
2)集群种每个Pod可通过DNS查询所有运行的SVC相关信息;
//Pod是否使用内部DNS服务,根据其spec.dnsPolicy字段设置
(3)FQDN
SVC的FQDN定义为:SVC名.SVC所在的命名空间.集群名
1)若在同一个集群和命名空间下,可之间通过SVC名发现服务;
2)若与服务通信,仍需知其端口(可从环境变量种获取);
如:进入SVC管理的一个容器,查看的DNS解析器配置文件
endpoint
endpoint:位于Service和Pod中间的资源
1)endpoint属于Kubernetes的一种资源类型;
2)endpoint会记录SVC管理下所有Pod的IP和端口,且动态更新;
3)endpoint会将所有信息存储在Etcd中;
4)通过SVC和手动创建endpoint可实现服务将连接重定向到外部IP和端口
//若将SVC配置文件的标签选择器删除/添加,则endpoint会停止/启动更新
如:查看SVC的endpoint
//当接受请求时,SVC随机转发到列表中的IP和端口
创建endpoint
endpoint的创建方式分为:自动创建和手动创建
(1)创建SVC时,默认会同时创建endpoint
1)若SVC无标签选择器,则默认不会创建endpoint;
2)可手动创建endpoint和无标签选择器的SVC相匹配;
创建endpoint格式:
apiVersion: v1
kind: Endpoint
metadata:
name: 与SVC同名的名称
subsets:
- addresses:
- ip:IP地址1
- ip:IP地址N
ports:
- port:端口号
如:创建可重定向连接到外部IP和端口的SVC
1)编写SVC的YAML文件;
2)编写endpoint的YAML文件;
3)调用create命令生成SVC和endpoint,并验证
可通过创建ExternalName类型的SVC实现具有FQDN别名的外部SVC
创建ExternalName类型的SVC格式:
spec:
type: ExternalName
externalName: SVC实际的FQDN
1)创建完成后,内部Pod可通过“别名.命名空间.集群名”访问外部SVC
//若在同一命名空间和同一集群下的Pod,可省略后两者
2)通过该方式,可隐藏实际的SVC名称和Pod相关信息;
3)Pod是绕过服务代理直接连接到外部SVC,所以外部SVC无法获得集群IP
如:创建具有FQDN别名的外部SVC
暴露服务
暴露服务分为3种方式:
1)创建NodePort类型的SVC:将访问节点端口的请求重定向;
2)创建LoadBalance类型的SVC:NodePort类型的一种扩展(负载均衡);
3)创建Ingress资源:将单个IP公开多个服务
NodePort类型
默认情况下,Kubernetes集群会随机打开节点的一个端口以对外暴露服务,SVC可通过转发该端口的流量,实现内部Pod对外暴露
创建NodePort类型的服务格式:
spec:
type: NodePort
prots:
- port: 服务端口号
targetPort: Pod端口号
nodePort: 节点端口号
selector:
标签名1: 标签值1
标签名N: 标签值N
(1)NodePort类型的服务其他创建格式和普通类型类型的服务创建几乎相同;
(2)若不指定节点端口,Kubernetes会随机选择一个端口映射服务的端口;
//若手动指定端口,需配置防火墙
NodePort类型的服务转发请求流程:
1)外部请求访问到节点的端口;
2)节点将请求转发至NodePort类型的服务的端口;
3)NodePort类型的服务随机将请求转发至特定Pod端口
//可能节点1端口接受的请求,由节点2的Pod处理
如:NodePort类型的服务转发请求流程
//若用户请求被转发到的节点宕机,则用户会被拒绝访问
如:创建NodePort类型的服务
1)编写YAML文件;
2)调用create命令生成SVC,并验证
3)通过访问节点的IP和端口验证
//集群外部的主机也可通过访问节点的IP,实现访问Pod
LoadBanlancer类型
LoadBanlancer类型服务本质就是在NodePort类型服务上添加负载均衡器
1)负载均衡器具有独立的可公开访问的IP和端口;
2)负载均衡器能防止将请求转发至宕机的节点
创建LoadBanlancer类型的服务格式:
spec:
type: LoadBanlancer
prots:
- port: 服务端口号
targetPort: Pod端口号
nodePort: 节点端口号
selector:
标签名1: 标签值1
标签名N: 标签值N
(1)LoadBanlancer类型服务其他创建格式和普通类型类型服务创建几乎相同;
(2)若不指定节点端口,Kubernetes会随机选择一个端口;
//若手动指定端口,需配置防火墙
LoadBanlancer类型的服务转发请求流程:
1)外部请求访问到负载均衡器;
2)负载均衡器根据负载策略将请求转发至各个节点;
2)节点将请求转发至LoadBanlancer类型的服务的端口;
3)LoadBanlancer类型的服务随机将请求转发至特定Pod端口
//可能节点1端口接受的请求,由节点2的Pod处理
如:LoadBanlancer类型的服务转发请求流程
如:创建LoadBanlancer类型的服务
1)编写YAML文件;
2)调用create命令生成服务,并验证访问
NodePort类型服务和LoadBanlancer类型服务须知:
(1)可通过spec.externalTrafficPolicy字段减少请求的跳转次数;
1)格式:
spec:
externalTrafficPolicy: Local
2)默认情况下,接收到的请求将随机转发至各个节点下的Pod;
3)若指定为Local,则请求会转发至接受节点下的Pod;
4)若本节点无相关Pod,则该请求会被挂起(直接有Pod,会请求超时)
//各个节点Pod数量可能不相同,可能会导致Pod的负载分布不均衡
(2)Pod无法接收到的真实客户端IP
1)由于节点端口转发请求时,会对数据包执行源网络地址转换(SNAT),会导致数据包的源IP发生改变
Ingress
Ingress:通过一个公网IP实现多个服务的暴露
1)Ingress属于Kubernetes的一种资源类型;
2)Kubernetes集群中必须含有Ingress控制器,Ingress资源才有意义;
如:通过Ingress暴露多个服务
Ingress转发请求流程:
1)客户端针对域名执行DNS查询,得到Ingress控制器的IP;
2)客户端向该IP发请求,并在请求头中添加相关域名信息;
3)Ingress控制器根据域名信息,确定访问的服务;
4)通过与该服务关联的Endpoint得到Pod信息;
5)随机返回Pod给客户端;
如:Ingress转发请求流程
//Ingress控制器不会将请求转发至服务,直接转发至Pod
//若是在集群内部使用,需配置DNS相关配置文件(如:/etc/hosts)
创建Ingress
创建Ingress格式:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: Ingress名称
spec:
rules:
- host: 外部访问的域名
http:
paths:
- path: 域名相对路径
backend:
serviceName: SVC名称
servicePort: SVC的端口
如:创建Ingress
1)编写YAML文件
2)调用create命令生成Ingress,并验证
//由于没有Ingress控制器,该Ingress资源也无IP(无意义)
Ingress的rules和paths字段都可包含多个条目,可实现:
(1)单个主机上,不同路径上的多个服务
如:根据请求的URL中路径,请求发送至不同的服务
(2)不同主机上的多个服务
如:根据请求域名,请求发送至不同的服务
配置TLS
Ingress默认可处理HTTP连接,HTTPS连接需手动配置
1)需将证书和私钥添加到Ingress控制器和Ingress资源中;
2)将证书和私钥存储在Secret的资源中;
3)默认当Ingress控制接受到TLS相关连接时,会终止TLS连接
//客户端和Ingress控制器之间通信是加密的,控制器和Pod通信是透明的
如:创建支持TLS连接的Igress
1)生成证书和密钥文件;
2)将证书和密钥文件保存至Secret资源中;
3)编写YAML文件
就绪探针
就绪探针:判断Pod的容器是否准备就绪可接受客户端请求
1)就绪探针会周期性的对容器进行检查(默认为10s);
//成功启动后,就绪探针还会周期性地检查(若不符合条件,则移除服务队列)
2)每个容器的就绪探针不同,且每个容器必须配置等待时间已满足检查;
3)若容器未通过检查,该容器会被移除服务对立(容器不会被删除或重建)
//不将请求转发至Pod,直至Pod内的容器就绪探针返回准备就绪
如:就绪探针探测到Pod不满足条件时
//通过就绪探针可实现依赖服务的检查
就绪探针分为以下3种机制:
(1)HTTP GET探针:针对容器的IP执行HTTP GET请求
1)响应为正常响应代码(2XX和3XX),则容器已准备就绪
(2)TCP套接字探针:针对容器指定的端口建立TCP连接
1)建立连接成功,则容器已准备就绪
(3)Exec探针:指定容器运行时需执行的命令
1)执行命令的返回代码为0,则容器已准备就绪
创建就绪探针
创建存活探针格式(位于Pod的spec.containers字段下):
readinessProbe:
就绪探针机制
如:创建带有Exec就绪探针的RS
1)编写YAML文件
2)调用create命令生成RS,并验证
3)在其中一个容器创建探测文件,再次验证
就绪探针须知:
(1)务必定义就绪探针
1)Pod若不定义就绪探针,会创建后直接加入服务队列;
//不论该Pod是否准备就绪,加入服务队列后就直接处理客户端请求
(2)减少手动删除Pod
1)通过在Pod标签和标签选择器添加“enabled=true或false”实现自动管理;
headless
1)默认DNS服务器被查询后返回SVC的IP;
2)带有headless的SVC,再被查询DNS服务器后返回各个Pod的IP;
3)带有headless的SVC仍提供跨Pod的负载均衡;
创建headless
创建headless格式(位于SVC的spec字段下):
clusterIP: None
如:创建带有headless的SVC
1)编写YAML文件
2)调用create命令生成SVC,并验证
更多推荐
所有评论(0)