kubernetes-服务发现service(九)
service
•防止Pod失联 •定义一组Pod的访问策略 •支持ClusterIP,NodePort以及LoadBalancer三种类型 •Service的底层实现主要有iptables和ipvs二种网络模式
pod与service的关系:
•通过label-selector相关联 •通过Service实现Pod的负载均衡(TCP/UDP 4层)
每个 Node 运行一个 kube-proxy
进程。kube-proxy
负责为 Service
实现了一种 VIP(虚拟 IP)的形式
kube-proxy 这个组件始终监视着apiserver中有关service的变动信息,获取任何一个与service资源相关的变动状态,通过watch监视,一旦有service资源相关的变动和创建,kube-proxy都要转换为当前节点上的能够实现资源调度规则(例如:iptables、ipvs)
service代理模式
iptables代理模式:
客户端IP请求时,直接请求本地内核service ip,根据iptables的规则直接将请求转发到到各pod上,因为使用iptable NAT来完成转发,也存在不可忽视的性能损耗。另外,如果集群中存在上万的Service/Endpoint,那么Node上的iptables rules将会非常庞大,性能还会再打折扣。
ipvs代理模式:
客户端IP请求时到达内核空间时,根据ipvs的规则直接分发到各pod上。kube-proxy会监视Kubernetes Service
对象和Endpoints
,调用netlink
接口以相应地创建ipvs规则并定期与Kubernetes Service
对象和Endpoints
对象同步ipvs规则,以确保ipvs状态与期望一致。访问服务时,流量将被重定向到其中一个后端Pod。
service类型
-
ClusterIP
:通过集群的内部 IP 暴露服务,选择该值,服务只能够在集群内部可以访问,这也是默认的ServiceType
。 -
NodePort
:通过每个 Node 上的 IP 和静态端口(NodePort
)暴露服务。NodePort
服务会路由到ClusterIP
服务,这个ClusterIP
服务会自动创建。通过请求<NodeIP>:<NodePort>
,可以从集群的外部访问一个NodePort
服务。 -
LoadBalancer
:使用云提供商的负载均衡器,可以向外部暴露服务。外部的负载均衡器可以路由到NodePort
服务和ClusterIP
服务。
ClusterIP
[root@k8s-master1 nginx]# vim nginx-service.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-service
labels:
app: nginx
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
selector:
app: nginx
[root@k8s-master1 nginx]# kubectl apply -f nginx-service.yaml
service/nginx-service created
[root@k8s-master1 nginx]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 6d15h
nginx-service ClusterIP 10.0.0.6 <none> 80/TCP 14s
service不会直接到pod,service是直接到endpoint资源,就是地址加端口,再由endpoint再关联到pod。
[root@k8s-master1 nginx]# kubectl get pod -l app=nginx
NAME READY STATUS RESTARTS AGE
nginx-deployment-5fc86c987f-jdpkv 1/1 Running 0 21m
nginx-deployment-5fc86c987f-scns6 1/1 Running 0 21m
nginx-deployment-5fc86c987f-wwvlx 1/1 Running 0 21m
[root@k8s-master1 nginx]# kubectl get ep
NAME ENDPOINTS AGE
kubernetes 192.168.0.123:6443,192.168.0.124:6443 6d15h
nginx-service 172.17.32.3:80,172.17.73.3:80,172.17.73.4:80 76s
service只要创建完,就会在dns中添加一个资源记录进行解析,添加完成即可进行解析。
NodePort
[root@k8s-master1 ~]# kubectl get pod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
myapp-9b4987d5-hk5n9 1/1 Running 0 82s pod-template-hash=9b4987d5,run=myapp
myapp-9b4987d5-ngvbk 1/1 Running 0 82s pod-template-hash=9b4987d5,run=myapp
myapp-9b4987d5-r7q49 1/1 Running 0 82s pod-template-hash=9b4987d5,run=myapp
[root@k8s-master1 ~]# vim myapp-service.yaml
apiVersion: v1
kind: Service
metadata:
name: myapp
namespace: default
spec:
selector:
app: myapp
release: canary
type: NodePort
ports:
- port: 80
targetPort: 80
nodePort: 37695
[root@k8s-master1 ~]# kubectl create -f myapp-service.yaml
service/myapp created
[root@k8s-master1 ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 6d16h
myapp NodePort 10.0.0.214 <none> 80:37695/TCP 8m14s
通过NodePort方式已经实现了从集群外部端口进行访问
[root@k8s-master1 ~]# while true;do curl http://192.168.0.125:37695/hostname.html;sleep 1;done
myapp-9b4987d5-ngvbk
myapp-9b4987d5-hk5n9
myapp-9b4987d5-r7q49
myapp-9b4987d5-ngvbk
myapp-9b4987d5-hk5n9
myapp-9b4987d5-r7q49
myapp-9b4987d5-ngvbk
会话保持
[root@k8s-master1 ~]# vim myapp-service.yaml
apiVersion: v1
kind: Service
metadata:
name: myapp
namespace: default
spec:
selector:
app: myapp
release: canary
sessionAffinity: ClientIP
type: NodePort
ports:
- port: 80
targetPort: 80
nodePort: 37695
[root@k8s-master1 ~]# kubectl create -f myapp-service.yaml
service/myapp created
[root@k8s-master1 ~]# while true;do curl http://192.168.0.125:37695/hostname.html;sleep 1;done
myapp-9b4987d5-hk5n9
myapp-9b4987d5-hk5n9
myapp-9b4987d5-hk5n9
Headless Service
有时不需要或不想要负载均衡,以及单独的 Service IP。 遇到这种情况,可以通过指定 Cluster IP(spec.clusterIP
)的值为 "None"
来创建 Headless
Service。
这个选项允许开发人员自由寻找他们自己的方式,从而降低与 Kubernetes 系统的耦合性。 应用仍然可以使用一种自注册的模式和适配器,对其它需要发现机制的系统能够很容易地基于这个 API 来构建。
对这类 Service
并不会分配 Cluster IP,kube-proxy 不会处理它们,而且平台也不会为它们进行负载均衡和路由。 DNS 如何实现自动配置,依赖于 Service
是否定义了 selector。
headless service做dns解析是直接解析到pod的,而servcie是解析到ClusterIP的
[root@k8s-master1 ~]# vim myapp.svc.yaml
apiVersion: v1
kind: Service
metadata:
name: myapp
namespace: default
spec:
selector:
app: myapp
release: canary
clusterIP: "None"
ports:
- port: 80
targetPort: 80
[root@k8s-master1 ~]# kubectl apply -f myapp-svc.yaml
service/myapp created
[root@k8s-master1 ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 6d17h
myapp ClusterIP None <none> 80/TCP 6m27s
- 【直播】我的基因组48:我可能测了一个假的全基因组
- 【直播】我的基因组47:测序深度和GC含量的关系
- 【直播】我的基因组47:测序深度和GC含量的关系
- SNV突变(96种)频谱的制作
- Golang语言社区--go语言执行cmd命令关机、重启等
- 【直播】我的基因组 45:SNV突变(6种)频谱的制作
- 【直播】我的基因组 44:比对文件画profile和heatmap图
- 做过1000遍RNA-seq的老司机告诉你如何翻车
- 【直播】我的基因组 43:简单粗糙的WGS数据分析流程
- 用谷歌搜索来使用ggplot2做可视化(下)
- 如何通过Google来使用ggplot2可视化
- 【直播】我的基因组54:把我的variation跟dbSNP数据库相比较
- 【翻译】MongoDB指南/引言
- TensorFlow从0到1 | 第十二章:TensorFlow构建3层NN玩转MNIST
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法