k8s service的四种体位

Headless Service

有时不需要或不想要负载均衡,以及单独的 Service IP 。遇到这种情况,可以通过指定 Cluster

IP(spec.clusterIP) 的值为 “None” 来创建 Headless Service 。这类 Service 并不会分配 Cluster IP, kube-proxy 不会处理它们,而且平台也不会为它们进行负载均衡和路由

1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: v1
kind: Service
metadata:
name: myapp
namespace: default
spec:
selector:
app: myapp
clusterIP:"None"
ports:
- name: http
port: 80
targetPort: 80

svc一旦创建成功后,会被写入到 coredns 中

他的写入的格式体是:svc名称 + 当前命名空间 + 当前集群的域名(集群域名我没没改过,默认就是svc.cluser.local. ) 通过我们当前的coredns的地址进行解析出一个域名

1
2
3
dig -t A myapp-headservice.default.svc.cluster.local. @10.244.0.34
dig命令需要安装
yum -y install bind-utils

NodePort

nodePort 的原理在于在 node 上开了一个端口,将向该端口的流量导入到 kube-proxy,然后由 kube-proxy 进

一步到给对应的 pod。(能够将内部服务暴露给外部的一种方式)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
apiVersion: v1
kind: Service
metadata:
name: myapp
namespace: default
spec:
type: NodePort #svc类型 就算不指定默认也是ClusterIP
selector: #匹配如下标签的pod来进行访问,匹配不到是访问不了的 这里起作用的就是selector(选择器)
app: myapp
release: stabel
ports:
- name: http
port: 80 #前端访问端口
targetPort: 80 #后端真实服务使用端口

LoadBalancer

loadBalancer 和 nodePort 其实是同一种方式。都是向外部暴露一个端口,以提供访问,区别在于 loadBalancer 比 nodePort 多了一步,就是可以调用

cloud provider 去创建 LB 来向节点导流,通俗说就是前面端口访问加了负载均衡

LoadBalancer(收费服务,负载均衡需要收费)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
apiVersion: v1
kind: Service
metadata:
name: nginx-out
namespace: sentry
annotations:
service.beta.kubernetes.io/alicloud-loadbalancer-id: lb-bp1v02eppysi5z40u6fxp #根据厂商注释可以将svc加入到slb虚拟服务组
spec:
ports:
- name: sentry
protocol: TCP
port: 20008
targetPort: 80
nodePort: 30700
selector:
app: web
clusterIP: 172.24.11.183
type: LoadBalancer
sessionAffinity: None
externalTrafficPolicy: Cluster

ExternalName

这种类型的 Service 通过返回 CNAME 和它的值,可以将服务映射到 externalName 字段的内容( 例如:hub.cctv.com )。ExternalName Service 是 Service 的特例,它没有 selector,也没有定义任何的端口和Endpoint。相反的,对于运行在集群外部的服务,它通过返回该外部服务的别名这种方式来提供服务

1
2
3
4
5
6
7
8
kind: Service
apiVersion: v1
metadata:
name: my-service-1
namespace: default
spec:
type: ExternalName
externalName: hub.cctv.com #尽量不使用ip

说明: ExternalName 接受 IPv4 地址字符串,但作为包含数字的 DNS 名称,而不是 IP 地址。 类似于 IPv4 地址的外部名称不能由 CoreDNS 或 ingress-nginx 解析,因为外部名称旨在指定规范的 DNS 名称。 要对 IP 地址进行硬编码,请考虑使用 headless Services

当查询主机 my-service.defalut.svc.cluster.local ( SVC_NAME.NAMESPACE.svc.cluster.local )时,集群的 DNS 服务将返回一个值 my.database.example.com 的 CNAME 记录。访问这个服务的工作方式和其他的相 同,唯一不同的是重定向发生在 DNS 层,而且不会进行代理或转发

自定义endpoint

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

---
apiVersion: v1
kind: Endpoints
metadata:
name: xinhua-news-server
namespace: nbugs-online
subsets:
- addresses:
- ip: 172.16.108.118
ports:
- name: xinhua-news-server
port: 28080
protocol: TCP

---
apiVersion: v1
kind: Service
metadata:
name: xinhua-news-server
namespace: nbugs-online
spec:
ports:
- name: xinhua-news-server # 要和Endpoints端口名称一样
protocol: TCP
port: 28080 #后端代理端口是什么,这里就写什么(不要写其他的端口)
targetPort: 28080
clusterIP: None
type: ClusterIP
sessionAffinity: None