【kubernetes】Service 介绍和应用

一,Service介绍

  • 四层代理是基于传输层(第四层)工作的代理,主要在传输层(如TCP、UDP协议)上转发和管理数据流

  • 七层代理是基于应用层(第七层)工作的代理,能够对应用层协议(如HTTP、SMTP)进行解析和处理。

Service是四层代理网络,基于IP和端口对数据进行转发和负载均衡

1,概述

因为Pod重启,重建时,它的IP很有可能会发生变化。因此在kubernetes中定义了service资源对象,Service 定义了一个服务访问的入口,客户端通过这个入口即可访问服务背后的应用集群实例。

Service是一个固定接入层,客户端可以通过访问service的ip和端口,访问到service关联的后端pod,这个service工作依赖于在kubernetes集群之上部署的一个附件,就是kubernetes的dns服务

(不同kubernetes版本的dns默认使用的也是不一样的,1.11之前的版本使用的是kubeDNs,较新的版本使用的是coredns),

service的名称解析是依赖于dns附件的,因此在部署完k8s之后,需要再部署dns附件,kubernetes要想给客户端提供网络功能,需要依赖第三方的网络插件(flannel,calico等)。

每个K8s节点上都有一个组件叫做kube-proxy,kube-proxy这个组件将始终监视着apiserver中有关service资源的变动信息,需要跟master之上的apiserver交互,随时连接到apiserver上获取任何一个与service资源相关的资源变动状态,这种是通过kubernetes中固有的一种请求方法watch(监视)来实现的,一旦有service资源的内容发生变动(如创建,删除),kube-proxy都会将它转化成当前节点之上的能够实现service资源调度,把我们请求调度到后端特定的pod资源之上的规则,这个规则可能是iptables,也可能是ipvs,取决于service的实现方式。

2,工作原理

k8s在创建Service时,会根据标签选择器selector(lable selector)来查找Pod,据此创建与Service同名的endpoint对象,当Pod 地址发生变化时,endpoint也会随之发生变化,service接收前端client请求的时候,就会通过endpoint,找到转发到哪个Pod进行访问的地址。(至于转发到哪个节点的Pod,由负载均衡kube-proxy决定)

3,k8s中有三类IP地址

  • 1、Node Network(节点网络):物理节点或者虚拟节点的网络,如ens33接口上的网路地址。
  • 2、Pod network(pod 网络),创建的Pod具有的IP地址。
  • 3、Cluster Network(集群地址,也称为service network),这个地址是虚拟的地址(virtual ip),没有配置在某个接口上,只是出现在service的规则当中。

4,常用字段介绍

kubectl explain Service[svc]
# kubectl explain service

apiVersion	<string>      #service资源使用的api组[版本]
kind	    <string>      #创建的资源类型
metadata	<Object>      #定义元数据
spec	    <Object>     
# kubectl explain service.spec

clusterIP	<string>      # 动态分配的地址,也可以自己在创建的时候指定,创建之后就改不了了
ports	    <[]Object>    # 定义service端口,用来和后端pod建立联系
selector	<map[string]string>   # 通过标签选择器选择关联的pod有哪些
sessionAffinityConfig	<Object>
# service在实现负载均衡的时候还支持sessionAffinity,
# sessionAffinity什么意思?会话联系,默认是none,随机调度的(基于iptables规则调度的)。如果我们定义sessionAffinity的client ip,那就表示把来自同一客户端的IP请求调度到同一个pod上。
type	    <string>       # 定义service的类型 ExternalName, ClusterIP(默认), NodePort, LoadBalancer.
# kubectl explain service.spec.type

ExternalName
ClusterIP
NodePort
LoadBalancer # 下面详细介绍
# kubectl explain service.spec.ports

name	    <string>    # 定义端口的名字
nodePort	<integer>   # service在物理机映射的端口,默认在 30000-32767 之间
port	    <integer> -required-  #service的端口,这个是k8s集群内部服务可访问的端口
targetPort	<string>    # targetPort是pod上的端口,从port和nodePort上来的流量,经过kube-proxy流入到后端pod的targetPort上,最后进入容器。 

二,Service四种类型

1,ClusterIP类型

通过集群的内部 IP 公开 Service,选择该值时 Service 只能够在集群内部访问。 这也是你没有为 Service 指定 type 时使用的默认值
你可以使用 Ingress 或者 Gateway API 向公共互联网公开服务。
创建的pod生成的ip地址,被关联的service生成的endpoints资源管理
创建的pod生成的ip地址,被关联的service生成的endpoints资源管理。

说明:

  • k8s集群内的机器或pod,都能访问此service代理的ip或域名;机器外部是不能访问的。
  • 域名格式:[service名.命名空间名.svc.cluster.local]

2,NodePort类型

通过每个节点上的 IP 和静态端口(NodePort)公开 Service。 为了让 Service 可通过节点端口访问,Kubernetes 会为 Service 配置集群 IP 地址, 相当于你请求了 type: ClusterIP 的 Service。
service.yaml

宿主机(物理机)的ip+ 映射端口(30380) 可以直接访问到集群内部pod内容。
在这里插入图片描述
客户端请求http://192.168.40.180:30380 - > docker0虚拟网卡:172.17.0.1:30380 -> 10.244.186.236:80,10.244.140.90:80

3,ExternalName类型

将服务映射到 externalName 字段的内容(例如,映射到主机名 api.foo.bar.example)。 该映射将集群的 DNS 服务器配置为返回具有该外部主机名值的 CNAME 记录。 集群不会为之创建任何类型代理。

应用场景:**跨名称空间访问**。 例如:default名称空间下的client 服务,去访问nginx-ns名称空间下的nginx-svc服务。

在这里插入图片描述

4,LoadBalancer类型

使用云平台的负载均衡器向外部公开 Service。Kubernetes 不直接提供负载均衡组件; 你必须提供一个,或者将你的 Kubernetes 集群与某个云平台集成。

三,Service案例参考

场景:k8s集群引用外部的mysql数据库

【理解】:

Service 在创建时,通过定义“spec.selector”选择器,选择指定标签的pod,从而生成对应的Endpoints资源,来管理选择的pod的ip地址。

现在,我们生成service的时候,不定义“spec.selector”选择器,而是通过定义Endpoints的yaml资源,指定名称和Service名称相同,即可实现关联。与此同时,定义“subsets.addresses.ip和ports”为外部机器的ip和端口,即可实现k8s集群引用外部的服务(如:mysql数据库等)

【操作】

第一步:在node02上安装mysql数据库:

yum install mariadb-server.x86_64 -y
systemctl start mariadb
# 安装完后,直接输入 mysql 进入终端

第二步:在master上,创建service:

因为没定义“spec.selector”选择器,没有选择pod,所以Endpoint 值为none

#cat mysql_service.yaml 

apiVersion: v1
kind: Service
metadata:
  name: mysql
spec:
  type: ClusterIP
  ports:
  - port: 3306

在这里插入图片描述
通过命令,再次验证没有创建对应的Endpoints资源:

kubectl get  ep[Endpoints]

第三步:在master上,直接创建Endpoint资源:

metadata.name的名字,必须对应特定关联的Service的名称相同。

# cat endpoint.yaml 

apiVersion: v1
kind: Endpoints
metadata:
  name: mysql    # 必须对应特定关联的Service的名称
subsets:
- addresses:
  - ip: 192.168.40.182   # 注册的ip地址
  ports:
  - port: 3306    # 注册的端口

在这里插入图片描述
此时,集群可以直接访问外部node02的集群外部服务。

四,CoreDNS

DNS全称是Domain Name System:域名系统,是整个互联网的电话簿。
其实就是一个 DNS 服务,“ 可被人理解的域名 ”翻译成“ 可被机器理解IP地址 ”。

在k8s中创建service之后,service默认的FQDN是:
<service name>.<name space>.svc.cluster.local

  • 14
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值