服务发布
对内用service,对外用ingress。
Service可以简单的理解为逻辑上的一组Pod。一种可以访问Pod的策略,而且其他Pod可以通过这个Service访问到这个Service代理的Pod。相对于Pod而言,它会有一个固定的名称,一旦创建就固定不变。
一般用于东西流量。
一、什么是service
每个Pod都会获取到它自己的IP地址,但是这些IP地址不总是稳定和可依赖的,这样就会导致一个问题在Kubernetes集群中,如果一组Pod(比如后端的Pod)为其他Pod(比如前端的Pod)提供服务,那么如果它们之间使用Pod的IP地址进行通信,在Pod重建后,将无法再进行连接。
于是Kubernetes引用了Service这样一种抽象概念:逻辑上的一组Pod,即一种可以访问Pod的策略。这一组Pod能够被Service通过标签选择器访问到,之后就可以使用Service进行通信。
创建service的同时,会创建同名的endpoint,endpoint里面记录了pod的ip地址。
# 查看DNS 地址
[root@k8s-master01 practice]#kubectl get po -A -owide |grep -i dns
kube-system coredns-788958459b-5qsq2 1/1 Running 2 (6d22h ago) 30d 172.16.58.240 k8s-node02 <none> <none>
kube-system coredns-788958459b-778xw 1/1 Running 2 (6d22h ago) 112d 172.16.122.184 k8s-master02 <none> <none># 查看对应的service
[root@k8s-master01 practice]#kubectl get svc -A
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
...
kube-system kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 112d
...# 查看对应的endpoint
[root@k8s-master01 practice]#kubectl get ep -A
NAMESPACE NAME ENDPOINTS AGE
......
kube-system kube-dns 172.16.122.184:53,172.16.58.240:53,172.16.122.184:53 + 3 more... 112d
...... # 查看endpoint的内容, 两个 dns的地址记录在endpoint内。
[root@k8s-master01 practice]#kubectl get ep kube-dns -oyaml -n kube-system
apiVersion: v1
kind: Endpoints
metadata:annotations:endpoints.kubernetes.io/last-change-trigger-time: "2023-09-25T16:50:41Z"creationTimestamp: "2023-09-25T16:50:42Z"labels:app.kubernetes.io/name: corednsk8s-app: kube-dnskubernetes.io/cluster-service: "true"kubernetes.io/name: CoreDNSname: kube-dnsnamespace: kube-systemresourceVersion: "23835901"uid: 38a64d71-ad91-48ef-a27e-125400f0193f
subsets:
- addresses:- ip: 172.16.122.184nodeName: k8s-master02targetRef:kind: Podname: coredns-788958459b-778xwnamespace: kube-systemuid: 33c128c1-8bd1-4c30-a5c8-2c3250b57ab5- ip: 172.16.58.240nodeName: k8s-node02targetRef:kind: Podname: coredns-788958459b-5qsq2namespace: kube-systemuid: 47e5bee1-d677-438f-868e-dee81b3e14faports:- name: dns-tcpport: 53protocol: TCP- name: dnsport: 53protocol: UDP- name: metricsport: 9153protocol: TCP
二、什么是endpoints
在 Kubernetes 中,Endpoints (端点)是一个对象,它会动态地记录 Pod 的 IP 地址和端口号。当你创建一个 Service 对象时,Kubernetes 会自动创建一个相应的 Endpoints 对象来帮助 Service 将请求转发到后端 Pod 上。
Endpoints 对象存储了一组 Pod 的网络地址,它们都能够提供相同的服务。你可以通过在 Service 对象中设置一个标签选择器,来指定连接这些 Pod 的方式。这就可以让你通过 Service IP,以负载均衡的方式访问到这些 Pod。
当新的 Pod 准备好提供服务时,它将会跟 Endpoints API 通信,并告知 API 它自己的 IP 地址和端口号。Endpoints API 会负责将这些信息更新到 Endpoints 对象中,Service 对象也会自动得到更新。由于 Endpoints 对象是动态更新的,这就意味着你可以随时将 Pod 添加或删除,而不会影响到正在使用 Service 的应用程序。
A. 查看命令
要查看 Kubernetes 中的 Endpoints,你可以使用以下命令:
- 使用 kubectl 命令:运行
kubectl get endpoints
命令,将显示当前集群中所有可用的 Endpoints。
kubectl get endpoints
- 指定特定的 Service:要查看特定 Service 的 Endpoints,可以运行
kubectl describe endpoints <service-name>
命令。
kubectl describe endpoints <service-name>#请将 `<service-name>` 替换为你要查看的 Service 的名称。
这些命令将显示与指定的 Service 相关联的所有 Endpoints 的详细信息,包括 IP 地址和端口号。你还可以通过添加其他标志选项来进行过滤和排序,以获取更精确的结果。运行 kubectl get endpoints --help
命令可以查看更多可用选项的详细信息。
另外,还可以使用 Kubernetes Dashboard 或其他第三方集群管理工具来查看 Endpoints。这些工具通常提供了更友好的用户界面,可以方便地查看和管理集群中的各种资源。
B. 使用场景
你可以在以下场景中使用 Kubernetes 的 Endpoints:
-
Service:Endpoints 用于将请求从 Service 转发到后端 Pod。当你创建一个 Service 对象时,Kubernetes 会自动创建一个相应的 Endpoints 对象。Endpoints 会记录与该 Service 相关联的所有可用的 Pod 的网络地址和端口号。这样,通过使用 Service IP,你可以以负载均衡的方式访问这些 Pod。
-
集群内部通信:如果你希望在集群内部的各个组件之间进行通信,可以使用 Endpoints。通过创建一个代表服务的 Service 对象,并将其与后端 Pod 相关联,Kubernetes 会为该 Service 创建相应的 Endpoints 对象,并在其中记录与该 Service 相关的 Pod 的网络地址和端口号。然后,你可以使用 Service IP 和端口号来与后端 Pod 进行通信。
-
特定服务的发现:通过查询 Endpoints,你可以获取到某个特定 Service 的所有可用的后端 Pod 的网络地址和端口号。这对于一些需要在运行时发现和访问特定服务的应用程序很有用。
总之,Endpoints 是用来记录与一个特定服务相关的所有可用的 Pod 的网络地址和端口号,以便于负载均衡和服务发现。使用 Endpoints,你可以轻松地将请求转发到后端的 Pod,并确保在 Pod 动态变化时仍然能够正常访问到服务。
三、定义Service
定义Service的yaml文件如下:
[root@k8s-master01 practice] # vim service.yamlkind: Service
apiVersion: v1
metadata:name: my-servicelabels: app: nginx-svc ### 这是service的标签
spec:selector:app: nginx ### 可以代理到哪些pod的标签,注意是pod的标签ports:- protocol: TCP # 协议port: 80 ### Service 他自己的端口号 也就是说svc的80代理pod的80端口 service--> 80端口,可以直接http://service, 其他后面还要加端口,不是的写法http://service:8080targetPort: 80 ### 容器的端口号,后端应用端口
创建Deployment服务:
[root@k8s-master01 practice] # vim nginx-deploy.yamlapiVersion: apps/v1
kind: Deployment
metadata:name: nginx-deploymentlabels:app: nginx
spec:replicas: 3selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginx:1.15.12ports:- containerPort: 80
该示例为 my-service:80 即可访问到具有 app=nginx 标签的 Pod 的 80 端口上。
需要注意的是,Service 能够将一个接收端口映射到任意的 targetPort,如果 targetPort 为空,targetPort 将被设置为与 Port 字段相同的值。targetPort 可以设置为一个字符串,引用 backend Pod 的一个端口的名称,这样的话即使更改了 Pod 的端口,也不会对 Service 的访问造成影响。
Kubernetes Service 能够支持 TCP、UDP、SCTP 等协议,默认为 TCP 协议。
小技巧:
可以在容器的端口下面加个name,这样在service里面的targetPort就可以写名字了
service必须和pod在同