k8s service

定义Service

一个Service在k8s中是一个rest对象,和pod类似,像所有的rest对象一样,Servvice定义可以基于post方式,请求apiserver创建的新的实例,例如,假如有一组pod,他们对外暴露了80端口,同时还被打上了app=Myapp的标签

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: Myapp
  ports:
    - portocol: TCP
      port: 80
      targetPort: 9376

上诉配置将要创建一个名称为my-service的service对象,他会将请求代理到使用TCP端口的9376,并且具有标签"app=Myapp"的pod上,这个service将指派一个ip地址(通常称为Cluster IP),他会被服务端代理使用,该service的selector将会持续评估,处理结果将被post到一个名称为my-service的Endpoints对象上

定义一个没有selector的Service

service抽象了该如何访问k8s pod,但也能够抽象其他类型backend,如:

  • 希望在生产环境中访问外部的数据库集群
  • 希望service指向另一个Namespace中或其他集群中的服务。
  • 正在将工作负载转移到k8s集群,和运行在k8s集群之的backend

在任意这些场景中,都能定义没有selector的service:

kind: Service
apiVersion: v1
metadata:
  name: my-service
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376

由于这个service没有selector,就不会创建相关的endpoints对象,可以手动将service映射到指定的endpoints:

kind: Endpoints
apiVersion: v1
metadata:
  name: my-service
subsets:
  - addresses:
      - ip: 1.2.3.4
    ports:
      - port: 9376

注意:endpoint IP地址不能是loopback(127.0.0.0/8).link-local(169.254.0.0/16)或者link-local多播地址(224.0.0.0/24)

访问没有selector的service与有selector的service的原理相同,请求将被路由到用户定义的endpoint,上图示例为1.2.3.4:9376

extemalname service是service的特例,它没有selector也没有定义任何端口和endpoint,他通过返回该外部服务的别名来提供服务。比如当查询主机my-service.prod.svc时,集群的DNS服务将放回一个值为my.database.example.com的CNAME记录:

kind: Service
apiVersion: v1
metadata:
  name: my-service
  namespace: prod
spec:
  type: ExternalName
  externalName: my.database.example.com

多端口的service

在很多情况下,service可能需要暴露多个端口,对应这种情况k8s支持service定义多个端口,但使用多个端口时,必须提供所有端口的名称,如:

kind: Service
apiVersion: v1
metadata:
  name: my-service
spec:
  selector:
    app: MyApp
  ports:
  - name: http  #名称
    protocol: TCP
    port: 80
    targetPort: 9376
  - name: https  #名称
    protocol: TCP
    port: 443
    targetPort: 9377

service类型

k8s service type(服务类型)注意包括以下几种:

  • ClusterIP:在集群内部使用,默认值,中能在集群中访问
  • NodePort:在所有安装kube-proxy的节点上打开一个端口,此端口可以代理值后端pod,可以通过NodePort从集群外部访问集群内的服务,格式为NodePort:NodePort
  • loadBalancer:使用云提供商的负载均衡器公开服务,成本较高
  • externalName:通过返回定义的CNAME别名,没有设置任何类型的代理,需要1.7或更高版本kube-dns支持

NodePort类型

如果将service的type字段设置为NodePort,则k8s将从--service-node-port-range参数指定的范围(默认30000-32767)中自动分配端口,也可以手动指定NodePort,创建该Service后,集群每一个节点都将暴露一个端口,通过某个宿主机的IP+端口即访问到后端的应用。

定义一个NodePort类型的service:

kind: Service
apiVersion: v1
metadata:
 labels:
 k8s-app: kubernetes-dashboard
 name: kubernetes-dashboard
 namespace: kube-system
spec:
 type: NodePort
 ports:
 - port: 443
 targetPort: 8443
 nodePort: 30000
 selector:
 k8s-app: kubernetes-dashboard

使用service代理k8s外部服务

使用场景:

  • 希望在生产环境中使用某个固定的名称,而非IP访问外部的中间件服务
  • 希望service指向一个nsmespace中或集群中的服务
  • 将正在工作负载的转移到k8s集群,但是一部分服务仍运行在k8s集群之外的backend
# cat nginx-svc-external.yaml 
apiVersion: v1
kind: Service
metadata:
  labels:
   app: nginx-svc-external
  name: nginx-svc-external
spec:
  ports:
  - name: http
    port: 80 
  protocol: TCP
  targetPort: 80
  sessionAffinity: None
  type: ClusterIP
# cat nginx-ep-external.yaml 
apiVersion: v1
kind: Endpoints
metadata:
  labels:
    app: nginx-svc-external
  name: nginx-svc-external
subsets:
- addresses:
   - ip: 140.205.94.189 
   ports:
     - name: http
       port: 80
   protocol: TCP

 

posted @ 2023-02-26 01:16  百因必有果  阅读(52)  评论(0编辑  收藏  举报