标签:ddr 缓存 balance 解析 访问 路由规则 app 不可 href
在kubernetes中每个Pod都存在生命周期;当一个Pod出现故障,极有可能被Pod控制器销毁并新建一个同类Pod取代(Pod控制器对Pod进行扩容也会新建Pod)。因此每个新建的Pod的都会重新获取IP,因此可以说通过IP获取Pod的服务是不可靠的。
service是一个有固定域名作为访问入口的服务,接受用户的访问请求,通过算法代理至后端的Pods上。Pods创建和销毁都会及时关联至service上。
工作原理简介
各Node节点上的kubelet关注各自节点上的pod,如有变动会及时通知master上的kube-apiserver。
各节点上的kube-proxy又实时监测着kube-apiserver上关于pod的变动,获取变动信息后及时修改本地的iptables(或ipvs),生成新的代理规则。
根据创建Service的type类型不同,可分成4种(externalname模式此处不做总结)模式:
1.ClusterIP: 默认方式。根据是否生成ClusterIP又可分为普通Service和Headless Service两类:
a.普通Service:通过为Kubernetes的Service分配一个集群内部可访问的固定虚拟IP(Cluster IP),实现集群内的访问。为最常见的方式。
b.Headless Service:该服务不会分配Cluster IP,也不通过kube-proxy做反向代理和负载均衡。而是通过DNS提供稳定的网络ID来访问,DNS会将headless service的后端直接解析为podIP列表。主要供StatefulSet使用。
2.NodePort:
NodePort服务是外部访问服务的最基本方式,顾名思义,NodePort就是在所有节点或者虚拟机上开放特点的端口,该端口的流量将被转发到对应的服务
我们来分析一下上图要表达的意思,当集群外部的客户想要访问ServiceA时,它可以访问Host1-10.10.1.2的31600端口,也可以访问Host2-10.10.1.3的31600端口。这两个访问地址最终都会连接到ServiceA上,并且集群内部的Pod还是可以通过访问192.168.1.22这个集群地址来访问到ServiceA
可总结如下:
在具有集群内部IP的基础上,在集群的每个节点上的端口(每个节点上的相同端口)上公开服务。用户可以在任何< Node IP >:NodePort地址上访问
NodePort方式的缺点主要有:
1)每个服务占用一个端口
2)可以使用的范围端口为30000~32767
3)如果节点/虚拟机IP地址发生更改,需要进行相关处理
3.LoadBalancer:和nodePort类似,不过除了使用一个Cluster IP和nodePort之外,还会向所使用的公有云申请一个负载均衡器(负载均衡器后端映射到各节点的nodePort),实现从集群外通过LB访问服务。
前3种模式,定义服务的时候通过selector指定服务对应的pods,根据pods的地址创建出endpoints作为服务后端;Endpoints Controller会watch Service以及pod的变化,维护对应的Endpoint信息。kube-proxy根据Service和Endpoint来维护本地的路由规则。当Endpoint发生变化,即Service以及关联的pod发生变化,kube-proxy都会在每个节点上更新iptables,实现一层负载均衡。
Service中主要涉及三种Port: * `port` 这里的port表示service暴露在clusterIP上的端口,clusterIP:Port 是提供给集群内部访问kubernetes服务的入口。
containerPort,targetPort是pod上的端口,从port和nodePort上到来的数据最终经过kube-proxy流入到后端pod的targetPort上进入容器。
nodeIP:nodePort 是提供给从集群外部访问kubernetes服务的入口。
总的来说,port和nodePort都是service的端口,前者暴露给从集群内访问服务,后者暴露给从集群外访问服务。从这两个端口到来的数据都需要经过反向代理kube-proxy流入后端具体pod的targetPort,从而进入到pod上的容器内。
使用Service服务还会涉及到几种IP:
Pod IP 地址是实际存在于某个网卡(可以是虚拟设备)上的,但clusterIP就不一样了,没有网络设备承载这个地址。它是一个虚拟地址,由kube-proxy使用iptables规则重新定向到其本地端口,再均衡到后端Pod。当kube-proxy发现一个新的service后,它会在本地节点打开一个任意端口,创建相应的iptables规则,重定向服务的clusterIP和port到这个新建的端口,开始接受到达这个服务的连接。
Pod的IP,每个Pod启动时,会自动创建一个镜像为gcr.io/google_containers/pause的容器,Pod内部其他容器的网络模式使用container模式,并指定为pause容器的ID,即:network_mode: "container:pause容器ID",使得Pod内所有容器共享pause容器的网络,与外部的通信经由此容器代理,pause容器的IP也可以称为Pod IP。
Node-IP,service对象在Cluster IP range池中分配到的IP只能在内部访问,如果服务作为一个应用程序内部的层次,还是很合适的。如果这个service作为前端服务,准备为集群外的客户提供业务,我们就需要给这个服务提供公共IP了。指定service的spec.type=NodePort,这个类型的service,系统会给它在集群的各个代理节点上分配一个节点级别的端口,能访问到代理节点的客户端都能访问这个端口,从而访问到服务。
kube-proxy是一个简单的网络代理和负载均衡器,它的作用主要是负载Service的实现,实现从Pod到Service,以及从NodePort到Service的访问
一.kube-proxy实现方式
1.usersapce方式:通过kube-proxy实现LB的代理服务,是kube0proxy的最初版本,较为稳定,但是效率不高
2.iptables方式:采用iptables来实现LB,是当前kube-proxy的默认方式
kube-proxy监视Kubernetes主服务器对服务/端点对象的各种增,删,改等操作。对于每个服务,它配置iptables规则,捕获Service的ClusterIP和端口的流量,并将流量重定向到服务的后端之一。对于每个Endpoint对象,它选择后端Pod的iptables规则
默认情况下,后端的选择是随机的。可通过Service.spec.sessionAffinity设置为“ClientIP”来选择基于客户端IP的会话关联
在Kubernetes系统中,当Pod需要访问其他Service时,可以通过两种方式来发现服务,即环境变量和DNS方式。前者有非常大的局限性,所以实际我们一般都选用第二种DNS方式来实现服务的注册和发现
kube-dns用来为Service分配子域名,以便集群中的Pod可通过域名获取Service的访问地址,通常kube-dns会为Service赋予一个名为“service_name.namespace_name.svc.cluster_domain”的记录,用来解析Service的Cluster_IP。Kubernetes v1.4版本之后,其主要由Kubedns,Dnsmasq,Exechealthz三个组件构成
Kubedns通过Kubernetes API监视Service资源变化并更新DNS记录,主要为Dnsmasq提供查询服务,服务端口是10053
Dnsmasq是一款小巧的DNS配置工具,其在kube-dns插件中的作用是:通过kube-dns容器获取DNS规则,在集群中提供DNS查询服务,提供DNS缓存,提高查询性能,降低kube-dns容器的压力
Exechealthz主要提供监控检查功能
Cluster类型的Service
目前k8s集群中已经有一组Pod
新建一个service作为他们的代理(通过label selector)
service的定义清单如下
kind: Service apiVersion: v1 metadata: name: ngx-service spec: selector: app: ngx ##选择label为app:ngx的pod建立代理关系 ports: - protocol: TCP ##代理的协议,可选TCP或者UDP port: 80 ##service对外服务端口 targetPort: 80 ##Pod上的服务端口
依据清单创建service并观察代理情况
[root@k8s-master k8s-yaml]# kubectl apply -f ngx-service.yaml service/ngx-service created [root@k8s-master k8s-yaml]# kubectl get services NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7d ngx-service ClusterIP 10.105.184.128 <none> 80/TCP 43s [root@k8s-master k8s-yaml]# curl 10.105.184.128/hostname.html ngx-deployment-58d847f49c-9tbwh [root@k8s-master k8s-yaml]# curl 10.105.184.128/hostname.html ngx-deployment-58d847f49c-vvnrj
docker 镜像事先构建好,提供nginx服务并/hostname.html显示docker主机名。
代理多服务的cluster类型
定义清单如下
kind: Service apiVersion: v1 metadata: name: ngx-service spec: selector: app: ngx ##选择label为app:ngx的pod建立代理关系 ports: - name: http protocol: TCP ##代理的协议,可选TCP或者UDP port: 80 ##service对外服务端口 targetPort: 80 ##Pod上的服务端口 - name: https protocol: TCP ##代理的协议,可选TCP或者UDP port: 443 ##service对外服务端口 targetPort: 443 ##Pod上的服务端口
NodePort类型的Service
定义清单如下
kind: Service apiVersion: v1 metadata: name: ngx-sr-nodeport spec: type: NodePort ##虽然为NodePort但仍会为其分配一个ClusterIP selector: app: ngx ports: - protocol: TCP port: 80 ##供集群内部使用CluserIP+port访问服务 targetPort: 80 ##Pod上的服务端口 nodePort: 30080 ##供集群外部使用node的IP+nodeport访问服务
依据清单创建service并观察代理情况
`仍会生成clusterIP,也能提供服务` [root@k8s-master k8s-yaml]# kubectl get services NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7d ngx-sr-nodeport NodePort 10.106.74.134 <none> 80:30080/TCP 6s [root@k8s-master k8s-yaml]# curl 10.106.74.134/hostname.html ngx-deployment-58d847f49c-9tbwh [root@k8s-master k8s-yaml]# curl 10.106.74.134/hostname.html ngx-deployment-58d847f49c-vvnrj
`从集群外的主机访问服务` [root@192-168-80-121 ~]# curl 192.168.80.147:30080/hostname.html ngx-deployment-58d847f49c-9tbwh [root@192-168-80-121 ~]# curl 192.168.80.147:30080/hostname.html ngx-deployment-58d847f49c-vvnrj [root@192-168-80-121 ~]# curl 192.168.80.147:30080/hostname.html ngx-deployment-58d847f49c-9tbwh
外部Service
实现访问集群外(或另一个k8s集群或同个集群中的另一个namespace)的服务。需要自建service使用Endpoint,service不需要使用spec.selector。为了将Endpoint和service绑定,需要定义Endpoint的name与service相同。
service清单
kind: Service apiVersion: v1 metadata: name: ngx-service spec: ports: - protocol: TCP ##代理的协议,可选TCP或者UDP port: 80 ##service对外服务端口 targetPort: 80 ##Pod上的服务端口
自建Endpoint清单
kind: Service apiVersion: v1 metadata: name: ngx-service subsets: - address: - IP:1.2.3.4 ports: - port:80
Headless Service
不为Service设置ClusterIP(即clusterIP:none),同个spec.selector将后端的Pod列表直接返回给用户,尤其自行负载调度。
kind: Service apiVersion: v1 metadata: name: ngx-service spec: selector: app: ngx ##选择label为app:ngx的pod建立代理关系 clusterIP: None ports: - name: http protocol: TCP ##代理的协议,可选TCP或者UDP port: 80 ##service对外服务端口 targetPort: 80 ##Pod上的服务端口
原文:
https://blog.csdn.net/liukuan73/article/details/82585732
https://blog.csdn.net/flat0809/article/details/103275026
标签:ddr 缓存 balance 解析 访问 路由规则 app 不可 href
原文地址:https://www.cnblogs.com/sucretan2010/p/14743300.html