01 引言
至此,service的相关知识已经讲解完了,下面是相关文章的详情总结:
- 《k8s教程(service篇)-资源定义详解》
- 《k8s教程(service篇)-概念和原理》
- 《k8s教程(service篇)-DNS服务搭建和配置》
- 《k8s教程(service篇)-Node本地DNS缓存》
- 《k8s教程(service篇)-pod的dns域名》
- 《k8s教程(service篇)-ingress 7层路由机制》
02 内容整理
先贴上整理的脑图:
2.1 资源定义
详情参考: 《k8s教程(service篇)-资源定义详解》
Service是Kubernetes实现微服务架构的核心概念,通过创建Service,可以为一组具有相同功能的容器应用提供一个统一的入口地址,并且将请求负载分发到后端的各个容器应用上,下面对Service的资源定义进行详细说明。
Service的YAML格式的定义文件的完整内容如下:
apiVersion: v1
kind: Service
metadata:
name: string
namespace: string
labels:
- name: string
annotations:
- name: string
spec:
selector:[]
type: string
clusterIP: string
sessionAffinity:string
ports:
- name: string
protocol: string
port: int
targetPort: int
nodePort: int
status:
loadBalancer:
ingress:
ip: string
hostname: string
属性说明:
属性名称 | 取值类型 | 必选 | 取值说明 |
---|---|---|---|
version | String | 是 | V1 |
kind | String | 是 | Service |
metadata | Object | 是 | 元数据 |
metadata.name | String | 是 | Service名称,需符合RFC 1035规范 |
metadata.namespace | String | 是 | 命名空间,不指定系统时将使用名称为default的命名空间 |
metadata.labels[] | list | 自定义标签属性列表 | |
metadata.annotation[] | list | 自定义注解属性列表 | |
spec | Object | 是 | 详细描述 |
spec.selector[] | list | 是 | Label Selector配置,将选择具有指定Label标签的Pod作为管理范围 |
spec.type | String | 是 | Service的类型,指定Service的访问方式,默认值为ClusterIP。 ClusterIP:虚拟服务IP地址,该地址用于Kubernetes 集群内部的Pod访问,在Node上kube-proxy通过设置的 iptables规则进行转发. NodePort:使用宿主机的端口,使能够访问各Node的外 部客户端通过Node的P地址和端口号就能访问服务. LoadBalancer:使用外接负载均衡器完成到服务的负载分发,需要在spec.status.loadBalancer字段指定外部负载均 衡器的P地址,同时定义nodePort和clusterIP,用于公有 云环境 |
spec.clusterIP | String | 虚拟服务的P地址,当type=ClusterIP时,如果不指定,则系统进行自动分配,也可以手工指定;当type=LoadBalancer 时,需要指定 | |
spec.sessionAffinity | String | 是否支持Session,可选值为ClientIP,默认值为None。 ClientIP:表示将同一个客户端(根据客户端的IP地址决定) 的访问请求都转发到同一个后端Pod | |
spec.ports[] | list | Service端口列表 | |
spec.ports[].name | String | 端口名称 | |
spec.ports[].protocol | String | 端口协议,支持TCP和UDP,默认值为TCP | |
spec.ports[].port | int | 服务监听的端口号 | |
spec.ports[].targetPort | int | 需要转发到后端Pod的端口号 | |
spec.ports[].nodePort | int | 当spec.type=NodePort时,指定映射到宿主机的端口号 | |
Status | Object | 当spec.type=LoadBalancer时,设置外部负载均衡器的地址,用于公有云环境 | |
status.loadBalancer | Object | 外部负载均衡器 | |
status.loadBalancer.ingress | Object | 外部负载均衡器 | |
status.loadBalancer.ingress.ip | String | 外部负载均衡器的IP地址 | |
status.loadBalancer.ingress.hostname | String | 外部负载均衡器的主机名 |
2.2 概念和原理
详情参考: 《k8s教程(service篇)-概念和原理》
Service实现的是微服务架构中的几个核心功能:全自动的服务注册、服务发现、 服务负载均衡等。
2.2.1 创建service的方式
① 使用kubectl expose命令创建:
kubectl expose deployment webapp
service/webapp exposed
查看新创建的Service,可以看到系统为它分配了一个虚拟IP
地址(ClusterIP
地址),Service的端口号则从Pod中的containerPort复制而来:
通过curl 169.169.140.242:8080 也是可以访问的。访问时,会被自动负载分发到了后端两个Pod之一:10.0.95.22:8080或10.0.95.23:8080。
② 资源文件的方式创建:
除了使用命令,还可以使用yaml资源文件的方式来创建:
apiVersion: v1
kind: Service
metadata:
name: webapp
spec:
ports:
- protocol: TCP
port: 8080
targetPort: 8080
selector:
app: webapp
Service定义中的关键字段是ports和selector:
- ports:定义部分指定了Service本身的端口号为8080;
- targetPort:指定后端Pod的容器端口号;
- selector:定义部分设置的是后端Pod所拥有的
label:app=webapp
。
使用kubectl create
命令创建后,能看到和使用kubectl expose
命令创建Service的效果一样。
2.2.2 endpoint
一个Service对应的 “后端” 由Pod的IP和容器端口号组成,这在k8s系统中称为Endpoint。
可以通过kubectl descirbe svc
命令查看Endpoint列表,如:
2.2.3 负载均衡机制
从服务IP到后端Pod的负载均衡机制,则是由每个Node上的kube-proxy负责实现的。
通过Service的负载均衡机制,Kubernetes实现了一种分布式应用的统一入口,免去了客户端应用获知后端服务实例列表和变化的复杂度。
2.2.3.1 kube-proxy的代理模式
目前kube-proxy提供了以下代理模式(通过启动参数--proxy-mode
设置):
模式 | 描述 |
---|---|
userspace模式 | 用户空间模式,由kube-proxy完成代理的实现,效率最低,不再推荐使用 |
iptables模式 | kube-proxy通过设置Linux Kernel的iptablesi规则,实现从Service到后端Endpoint列表的负载分发规则,效率很高。<br/>——————————<br/>但是,如果某个后端Endpoint在转发时不可用,此次客户端请求就会得到失败的响应,相对于 userspace模式来说更不可靠,此时应该通过为Pod设置readinessprobe(服务可用性健康检查)来保证只有达到ready状态的Endpoint才会被设置为Service的后端Endpoint。 |
ipvs模式 | 在Kubernetes1.11版本中达到Stable阶段,kube-proxy通过设置Linux Kernel的netlink接口设置IPVS规则,转发效率和支持的吞吐率都是最高的。<br/><br/>ipvs模式要求Linux Kernel启用IPVS模块,如果操作系统未启用IPVS内核模块,kube-proxy则会自动切换至iptables模式。同时ipvs模式支持更多的负载均衡策略,如下所述:<br/>——————————<br/>rr(round-robin):轮询;<br/>lc(least connection):最小连接数;<br/>dh(destination hashing):目的地址哈希;<br/>sh(source hashing):源地址哈希;<br/>sed(shortest expected delay):最短期望延时;<br/>nq(never queue):永不排队。 |
kernelspace模式 | Windows Server上的代理模式 |
2.2.3.2 会话保持模式
Service支持通过设置sessionAffinity实现基于客户端IP的会话保持机制,即:首次将某个客户端来源IP发起的请求转发到后端的某个Pod上,之后从相同的客户端 IP发起的请求都将被转发到相同的后端Pod上。
配置参数为 service.spec.sessionAffinity
,也可以设置会话保持的最长时间(service.spec.sessionAffinityConfig.clientIP.timeoutSeconds
),例如下面的服务将会话保持时间设置为10800s(3h):
apiVersion: v1
kind: Service
metadata:
name: webapp
spec:
sessionAffinity: ClientIP
sessionAffinityConfig:
clientIP:
timeoutSecondes: 10080
ports:
- protocol: TCP
port: 8080
targetPort: 8080
selector:
app: webapp
2.2.4 多端口设置
在下面的例子中,Service设置了两个端口号来分别提供不同的服务,如web服务
和management服务
(下面为每个端口号都进行了命名,以便区分):
apiversion: v1
kind: Service
metadata:
name: webapp
spec:
ports:
- port: 8080
targetPort: 8080
name: web
- port: 8005
targetPort: 8005
name: management
selector:
app: webapp
2.2.5 外部服务定义为service
普通的Service通过Label Selector对后端Endpoint列表进行了一次抽象,如果后端的Endpoint
不是由Pod副本集
提供的,则Service
还可以抽象定义任意其他服务,将一个Kubernetes集群外部的已知服务
定义为Kubernetes内的一个Service
, 供集群内的其他应用访问。
举例:(用户在创建Service
资源对象时不设置Label Selector
(后端Pod
也不存在),同时再定义一个与Service
关联的Endpoint
资源对象,在Endpoint
中设置外部服务的IP
地址和端口号):
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
ports:
- protocol: TCP
port: 80
targetPort: 80
-----------
apiversion: v1
kind: Endpoints
metadata:
name: my-service
subsets:
- addresses:
- IP: 1.2.3.4
ports:
- port: 80
2.2.6 service暴露给外部集群
可以通过Service资源对象的类型字段“type”进行设置。
目前Service的类型如下:
类型 | 描述 |
---|---|
ClusterIP | Kubernetes默认会自动设置Service的虚拟IP地址,仅可被集群内部的客户端应用访问。当然,用户也可手工指定一个ClusterIP地址,不过需要确保该IP在Kubernetes集群设置的ClusterIP地址范围内(通过kube-apiserver 服务的启动参数-service-cluster--ip-range设置),并且没有被其他Service使用 |
NodePort | 将Service的端口号映射到每个Node的一个端口号上,这样集群中的任意Node都可以作为Service的访问入口地址,即NodeIP:NodePort |
LoadBalancer | 将Service映射到一个已存在的负载均衡器的IP地址上, 通常在公有云环境中使用 |
ExternalName | 将Service映射为一个外部域名地址,通过externalName字段进行设置 |
2.2.6.1 NodePort类型
apiVersion: v1
kind: Service
metadata:
name: webapp
spec:
type: NodePort
ports:
- port: 8080
targetPort: 8080
nodePort: 8081
selector:
app: webapp
使用kubectl create
创建了Service之后,就可以通过任意一个Node的IP地址+ NodePort 8081端口号 访问服务了。
2.2.6.2 LoadBalancer类型
通常在公有云环境中设置Service
的类型为 “LoadBalancer‘” ,可以将Service
映射到公有云提供的某个负载均衡器的IP
地址上,客户端通过负载均衡器的IP
和Service
的端口号就可以访问到具体的服务,无须再通过kube-proxy
提供的负载均衡机制进行流量转发。公有云提供的LoadBalancer可以直接将流量转发到后端Pod上,而负载分发机制依赖于公有云服务商的具体实现。
举例:
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: LoadBalancer
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
clusterIP: 10.0.171.239
在服务创建成功之后,云服务商会在Service
的定义中补充LoadBalancer
的IP
地址(status字段):
status:
loadBalancer:
ingress:
- ip:192.0.2.127
2.2.6.3 ExternalName类型
ExternalName类型的服务用于将集群外的服务定义为Kubernetes
的集群的Service
,并且通过externalName
字段指定外部服务的地址,可以使用域名或IP
格式,集群内的客户端应用通过访问这个Service
就能访问外部服务了。
这种类型的Service没有后端Pod,所以无须设置Label Selector。例如:
apiVersion: v1
kind: Service
metadata:
name: my-service
namespace: prod
spec:
type: ExternalName
externalName: my.database.example.com
在本例中设置的服务名为my-service,所在namespace为prod,客户端访问服务地址my-service.prod.svc.cluster.local
时,系统将自动指向外部域名my.database.example.com
。
2.2.7 Service支持的网络协议
目前Service支持的网络协议如下.
类型 | 描述 |
---|---|
TCP | Service的默认网络协议,可用于所有类型的Service |
UDP | 可用于大多数类型的Service,LoadBalancer类型取决于云服务商对UDP的支持 |
HTTP | 取决于云服务商是否支持HTTP和实现机制 |
PROXY | 取决于云服务商是否支持HTTP和实现机制 |
SCTP | 从Kubernetes1.12版本引入,到1.19版本时达到Beta阶段,默认启用,如需关闭该特性,则需要设置kube-apiserver的启动参数--feature- gates=-SCTPSupport=-false进行关闭 |
2.2.8 k8s的服务发现机制
2.2.8.1 环境变量的方式
在一个Pod运行起来的时候,系统会自动为其容器运行环境注入所有集群中有效Service的信息。
Service的相关信息包括服务IP、服务端口号、各端口号相关的协议等,通过{SVCNAME_SERVICE_HOST}
和{SVCNAME_SERVICE_PORT}
格式进行设置。
以webapp服务为例:
apiVersion: v1
kind: Service
metadata:
name: webapp
spec:
ports:
- protocol: TCP
port: 8080
targetPort: 8080
selector:
app: webapp
在一个新创建的Pod(客户端应用)中,可以看到系统自动设置的环境变量如下:
WEBAPP_SERVICE_HOST=169.169.81.175
WEBAPP_SERVICE_PORT=8080
WEBAPP_P0RT=tcp://169.169.81.175:8080
WEBAPP_P0RT_8080_TCP=tcp://169.169.81.175:8080
WEBAPP_PORT_8080_TCP_PROTO=tcp
WEBAPP_PORT_8080_TCP_PORT=8080
WEBAPP_PORT_8080_TCP_ADDR=169.169.81.175
然后,客户端应用就能够根据Service
相关环境变量的命名规则,从环境变量中获取需要访问的目标服务的地址了,例如:
curl http://${WEBAPP_SERVICE_HOST}:${WEBAPP_SERVICE_HOST}
2.2.8.2 DNS的方式
Service在Kubernetes系统中遵循DNS命名规范,Service的DNS域名表示方法为<servicename>.<namespace>.svc.<clusterdomain>
,其中:
字段 | 解析 |
---|---|
servicename | 服务的名称 |
namespace | 所在namespace的名称 |
clusterdomain | Kubernetes集群设置的域名后缀(例如cluster.local),服务名称的命名规则遵循RFC 1123规范的要求 |
以webapp
服务为例,将其端口号命名为“http
”:
apiversion: v1
kind: Service
metadata:
name: webapp
spec:
ports:
- protocol: TCP
port: 8080
targetPort: 8080
name: http
selector:
app: webapp
解析名为 "http" 端口的DNS SRV
记录
"_http._tcp.webapp.default.svc.cluster.local'
",可以查询到其端口号的值为8080
。
2.2.9 headless service
在某些应用场景中,客户端应用不需要通过Kubernetes内置Service实现的负载均衡功能,需要自行完成对服务后端各实例的服务发现机制,或者需要自行实现负载均衡功能,此时可以通过创建一种特殊的名为 “Headless‘”的服务来实现。
服务名(DNS
域名)的解析机制取决于该Headless Service
是否设置了Label Selector
。
2.2.9.1 已设置Label Selector
如果Headless Service设置了Label Selector,Kubernetes
则将根据Label Selector
查询后端Pod
列表,自动创建Endpoint
列表,将服务名(DNS
域名)的解析机制设置为:当客户端访问该服务名时,得到的是全部Endpoint
列表(而不是一个确定的IP
地址)。
以下面的Headless Service为例,其设置了Label Selector:
apiversion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
clusterIP: None
selector:
app: nginx
使用kubectl create
命令创建完之后,可以查看该Headless Service
的详细信息,可以看到后端的Endpoint
列表:
当客户端通过DNS
服务名 " nginx"和服务端口号访问该Headless服务(URL=nginx:80)时,将得到Service后端Endpoint列表"10.0.95.12:80,10.0.9513:80,10.0.95.14:80
",然后 由客户端程序自行决定如何操作,例如:通过轮询机制访问各个Endpoint。
2.2.9.2 未设置Label Selector
如果headless Service没有设置Label Selector,则Kubernetes将不会自动创建对应的Endpoint列表。
DNS系统会根据下列条件尝试对该服务名设置DNS记录:
- 如果Service的类型为ExternalName,则对服务名的访问将直接被DNS系统转换为Service设置的外部名称(externalName);
- 如果系统中存在与Service同名的Endpoint定义,则服务名将被解析为Endpoint定义中的列表,适用于非ExternalName类型的Service。
2.2.10 端点分片和服务拓扑
2.2.10.1 端点分片
EndpointSlice通过对Endpoint进行分片管理来实现降低Master和各Node之间的网络传输数据量及提高整体性能的目标。对于Deployment的滚动升级,可以实现仅更新部分Node上的Endpoint信息,Master与Node之间的数据传输量可以减少100倍左右,能够大大提高管理效率。
EndpointSlice根据Endpoint
所在Node
的拓扑信息进行分片管理,如图所示:
Endpoint Slices
要实现的第2个目标是为基于Node拓扑的服务路由提供支持,这需要与服务拓扑(Service Topology)机制共同实现。
2.2.10.2 服务拓扑
在默认情况下,发送到一个Service的流量会被均匀转发到每个后端Endpoint,但无法根据更复杂的拓扑信息设置复杂的路由策略。服务拓扑机制的引入就是为了实现基于Node拓扑的服务路由,允许Service创建者根据来源Node和目标Node的标签来定义流量路由策略。
通过对来源Node和目标Node标签的匹配,用户可以根据业务需求对Node进行分组,设置有意义的指标值来标识 “较近” 或者 “较远” 的属性:
例如:对于公有云环境来说,通常有区域(Zone或Region)的划分,云平台倾向于把服务流量限制在同一个区域内,这通常是因为跨区域网络流量会收取额外的费用。另一个例子是把流量路由到由DaemonSet管理的当前Node的Pod 上。又如希望把流量保持在相同机架内的Node上,以获得更低的网络延时。
2.3 dns服务搭建和配置
详情参考: 《k8s教程(service篇)-DNS服务搭建和配置》
2.3.1 dns在k8s服务的发展
发展: SkyDNS => KubeDNS =>CoreDNS
CoreDNS架构图如下:
描述:
- 它是由go语言实现的一套高性能、插件式,易于扩展的DNS服务端;
- 解决了KubeDNS的一些问题, 例如dnsmasq的安全漏洞、externalName不能使用stubDomains进行设置等等;
- 支持自定义DNS记录及配置upstream DNS Server,可以统一管理Kubernetes基于服务的内部DNS和数据中心的物理DNS;
- 它没有使用多个容器的架构,只用一个容器便实现了KubeDNS内3个容器的全部功能。
2.3.2 coredns搭建
① 修改每个Node上kubelet的启动参数,在其中加上以下两个参数:
--cluster-dns=169.169.0.100
:为DNS服务的ClusterIP地址。--cluster-domain=cluster.local
:为在DNS服务中设置的域名。
② 重启kubelet服务
③ 部署:需要创建3个资源对象:1个ConfigMap、1个Deployment和1个Service。
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
labels:
addonmanager.kubernetes.io/mode: EnsureExists
data:
Corefile: |
cluster.local{
errors
health{
lameduck 5s
}
ready
kubernetes cluster.local 169.169.0.0/16{
fallthrough in-addr.arpa ip6.arpa
}
prometheus: 9153
forward ./etc/resolv.conf
cache 30
loop
reload
loadbalance
}
. {
cache 30
loadbalance
forward /etc/resolv.conf
}
---
apiversion: apps/v1
kind: Deployment
metadata:
name: coredns
namespace: kube-system
labels:
k8s-app: kube-dns
kubernetes.io/name: "CoreDNS"
spec:
replicas: 1
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
selector:
matchLabels:
k8s-app: kube-dns
template:
metadata:
labels:
k8s-app: kube-dns
spec:
priorityClassName: system-cluster-critical
tolerations:
- key: "CriticalAddonsonly"
operator: "Exists"
nodeSelector:
kubernetes.io/os: linux
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: k8s-app
operator: In
values: ["kube-dns"]
topologyKey: kubernetes.io/hostname
containers:
- name: coredns
image: coredns/coredns:1.7.0
imagePullPolicy: IfNotPresent
resources:
limits:
memory: 170Mi
requests:
cpu: 100m
memory: 70Mi
args: ["-conf","/etc/coredns/Corefile" ]
volumeMounts:
- name: config-volume
mountPath: /etc/coredns
readOnly: true
ports:
- containerPort: 53
name: dns
protocol: UDP
- containerPort: 53
name: dns-tcp
protocol: TCP
- containerPort: 9153
name: metrics
protocol: TCP
securityContext:
allowPrivilegeEscalation: false
capabilities:
add:
- NET_BIND_SERVICE
drop:
- a11
readOnlyRootFilesystem: true
livenessProbe:
httpGet:
path: /health
port: 8080
scheme: HTTP
initialDelaySeconds: 60
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 5
readinessProbe:
httpGet:
path: /ready
port: 8181
scheme: HTTP
dnsPolicy: Default
volumes:
- name: config-volume
configMap:
name: coredns
items:
- key: Corefile
path: Corefile
---
apiVersion: v1
kind: Service
metadata:
name: kube-dns
namespace: kube-system
annotations:
prometheus.io/port: "9153"
prometheus.io/scrape: "true"
labels:
k8s-app: kube-dns
kubernetes.io/cluster-service: "true"
kubernetes.io/name: "CoreDNS"
spec:
selector:
k8s-app: kube-dns
clusterIP: 169.169.0.100
ports:
- name: dns
port: 53
protocol: UDP
- name: dns-tcp
port: 53
protocol: TCP
- name: metrics
port: 9153
protocol: TCP
使用kubectl create
命令依次把资源对象创建,然后可以看到创建成功:
2.3.3 配置解析
CoreDNS的主要功能是通过插件系统实现的,CoreDNS实现了一种链式插件结构,将DNS的逻辑抽象成了一个个插件,能够灵活组合使用。常用的插件如下:
插件 | 描述 |
---|---|
loadbalance | 提供基于DNS的负载均衡功能 |
loop | 检测在DNS解析过程中出现的简单循环问题 |
cache | 提供前端缓存功能 |
health | 对Endpoint进行健康检查 |
kubernetes | 从Kubernetes中读取zone数据 |
etcd | 从etcd中读取zone数据,可用于自定义域名记录 |
file | 从RFC 1035格式文件中读取zone数据 |
hosts | 使用/etc/hosts文件或者其他文件读取zone数据,可用于自定义域名记录 |
auto | 从磁盘中自动加载区域文件 |
reload | 定时自动重新加载Corefile配置文件的内容 |
forward | 转发域名查询到上游DNS服务器上 |
prometheus | 为Prometheus系统提供采集性能指标数据的URL |
pprof | 在URL路径/debug/pprof下提供运行时的性能数据 |
log | 对DNS查询进行日志记录 |
errors | 对错误信息进行日志记录 |
2.3.4 举例(自定义域名)
etcd和hosts插件都可以用于用户自定义域名记录。
下面是使用etcd
插件的配置示例,将以“.com
”结尾的域名记录配置为从etcd中获取,并将域名记录保存在/skydns
路径下:
{
etcd com{
path /skydns
endpoint http://192.168.18.3:2379
upstream /etc/resolv.conf
}
cache 160 com
loadbalance
proxy /etc/resolv.conf
}
如果用户在etcd中插入一条“10.1.1.1 mycompany” DNS记录:
$ ETCDCTL_API=3 etcdctl put "/skydns/com/mycompany" '["host":"10.1.1.","ttl":60]'
客户端应用就能访问域名"mycompany.com"了:
$ nslookup mycompany.com
Server: 169.169.0.100
Address: 169.169.0.100#53
Name: mycompany.com
Address: 10.1.1.1
2.4 node本地dns缓存
详情参考: 《k8s教程(service篇)-Node本地DNS缓存》
Node本地DNS缓存(NodeLocal DNSCache)的工作流程如图所示,客户端Pod首先会通过本地DNS缓存进行域名解析,当缓存中不存在域名时,会将请求转发到集群DS服务进行解析。
部署Node本地DNS缓存工具,主要包括 ServiceAccount、Daemonset、ConfigMap和Service 几个资源对象,详情看原文。
2.5 pod的dns域名
详情参考: 《k8s教程(service篇)-pod的dns域名》
对Pod来说,Kubernetes会为其设置一个<pod-ip>.<namespace>.pod.<cluster-domain>
格式的DNS域名,其中Pod IP部分需要用 “-
” 替换 “.
” 符号,例如下面Pod的IP地址为10.0.95.63
:
系统为这个Pod设置的DNS域名为10-0-95-63.default.pod.cluster.local
,用 nslookup
进行验证,便可以成功解析该域名的IP地址为10.0.95.63
:
其它与Service差不多,详情参考原文。
2.6 ingress 7层路由机制
详情参考: 《k8s教程(service篇)-ingress 7层路由机制》
Kubernetes 使用了一个Ingress策略定义和一个具体提供转发服务的Ingress Controller,两者结合,实现了基于灵活Ingress策略定义的服务路由功能。
如果是对Kubernetes集群外部的客户端提供服务,那么Ingress Controller实现的是类似于边缘路由器(Edge Router)的功能。
需要注意的是,Ingress
只能以HTTP
和 HTTPS
提供服务,对于使用其他网络协议的服务,可以通过设置Service
的类型 type
为NodePort
或LoadBalancer
对集群外部的客户端提供服务。
举例:使用Ingress进行服务路由时,Ingress Controller基于Ingress规则将客户端请求直接转发到Service对应的后端Endpoint(Pod)上,这样会跳过kube-proxy设置的路由转发规则,以提高网络转发效率,下图是一个典型的HTTP层路由的例子:
主要流程:部署ingress controller -> 创建ingress策略 -> 客户端通过ingress controller访问后端web-app服务。
关系图大致如下:(图片来自:https://www.cnblogs.com/rancherlabs/p/12034075.html)
03 疑问
如果还是对service的一些概念不清晰,比如:kube-proxy与ingress的关系,可以参考阅读:《Using a Network Load Balancer (NLB) to Expose an Application Outside the Kubernetes Cluster》。
暴露k8s的服务的三种方式:
- NodePort
- Network Load Balancer (NLB)
- Ingress (application load balancer, ALB)
原理图如下,以便于理解:
04 文末
本文主要总结k8s关于Service的一些学习笔记,以便后续的回顾,谢谢大家的阅读,本文完!