Kubernetes权威指南三——Service

1、Service概念:

   Service主要用于提供网络服务,通过Service的定义,能够为客户端应用提供稳定的访问地址(域名或IP地址)和负载均衡,以及能够屏蔽后端的Endpoint的变化,是Kubernetes实现微服务的核心资源。

创建Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: webapps
spec:
  replicas: 3
  selector:
    matchLabels:
      app: webapps
  template:
    metadata:
      labels:  
        app: webapps
    spec:
      containers:
      - name: web
        image: tomcat
        ports:
        - containerPort: 8080

2、用expose创建Service

[root@master01 service]# kubectl expose deployment webapps
service/webapps exposed

查看Service:

[root@master01 service]# kubectl get service
webapps        ClusterIP   10.99.10.229    <none>        8080/TCP         104s

访问服务:

[root@master01 service]# curl 10.99.10.229:8080
<!doctype html><html lang="en"><head><title>HTTP Status 404 – Not Found</title><style type="text/css">body {font-family:Tahoma,Arial,sans-serif;} h1, h2, h3, b {color:white;background-color:#525D76;} h1 {font-size:22px;} h2 {font-size:16px;} h3 {font-size:14px;} p {font-size:12px;} a {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTP Status 404 – Not Found</h1><hr class="line" /><p><b>Type</b> Status Report</p><p><b>Description</b> The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.</p><hr class="line" /><h3>Apache Tomcat/10.0.14</h3></body></html>[root@master01 service]# 

3、用yaml创建Service

apiVersion: v1
kind: Service
metadata:
  name: webapp
spec:
  ports:
  - protocol: TCP
    port: 8080   #Service本身的端口号
    targetPort: 8080   #后端Pod容器端口号
  selector:
    app: webapp

 

 

 查看Service后端的容器

[root@master01 service]# kubectl describe svc webapps
Name:              webapps
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          app=webapps
Type:              ClusterIP
IP:                10.99.10.229
Port:              <unset>  8080/TCP
TargetPort:        8080/TCP
Endpoints:         10.244.75.100:8080,10.244.75.88:8080,10.244.75.99:8080
Session Affinity:  None
Events:            <none>

 4、Service的负载均衡机制

 从服务IP到后端Pod的负载均衡机制,则是由每个Node上的kube-proxy负责实现的。

4.1 kube-proxy的代理模式:

iptables模式:kube-proxy通过设置Linux Kernel 的iptables规则,实现从Service到后端EndPoint列表的负载分发规则。

ipvs模式: kube-proxy通过设置Linux Kernel的netlink接口设置IPVS规则,转发率和吞吐率都是最高的。ipvs模式要求Linux Kernel启用IPVS模块,如果操作系统未启用IPVS模块,则kube-proxy会自动切换至iptables。

4.2 kube-proxy

 kubbe-proxy支持更多的负载均衡策略

 

 4.3会话保持机制

Service通过设置sessionAffinity实现基于客户端IP的会话保持机制,即首次将某个客户端来源IP发起的请求转发到某个Pod上,之后从相同的客户端IP发起的请求都被转发到相同的后端Pod上,同时还可以设置会话保持的最长时间,

apiVersion: v1
kind: Service
metadata:
  name: affinity
spec:
  sessionAffinity: ClientIP
  sessionAffinityConfig:
    clientIP:
      timeoutSeconds: 10800
  ports:
  - protocol: TCP
    port: 8080
    targetPort: 8080
  selector:
    app: webapp

4.3Service的多端口设置

一个容器应用可以提供多个端口的服务,在Service的定义中也可以相应的设置多个端口号。同一个端口号,可以使用不同的协议,

apiVersion: v1
kind: Service
metadata:
  name: webapp
  namespace: kube-system
  labels:
    k8s-app: kube-dns
    kubernetes.io/cluster-service: "true"
    kubernetes.io/name: "kubeDNS"
spec:
  selector:
    k8s-app: kube-dns
  clusterIP: 10.96.0.100
  ports:
  - name: dns
    port: 53
    protocol: UDP
  - name: dns-tcp
    port: 53
    protocol: TCP

4.4 将外部协议定义为Service

普通的Service通过Label Selector对后端EndPoint 列表进行了一次抽象,如果后端的EndPoint 不是有Pod副本提供的,则Service还可以抽象定义任意其他服务。

对于这种场景,用户在创建Service的时候不设置Label  Selector(后端Pod也不存在),同时在定义一个与Service关联的EndPoint的资源对象,在EndPoint中设置外部服务的IP地址和端口号:

apiVersion: v1
kind: Service
metadata:
  name: nopod
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

---
apiVersion: v1
kind: Endpoints
metadata:
  name: my-service
subsets:
- addresses:
  - ip: 10.96.0.99
  ports:
  - port: 80

4.5 将Service暴露到集群外部

Kubernetes为Service创建的ClusterIP地址是对后端Pod列表的一层抽象,对于集群外部来说没有意义,但又许多Service是需要对集群外部提供服务的,Kubernetes提供了多种机制将Service暴露出去,供集群外部的客户端访问,这可以通过Service资源类型字段“type”进行设置。

目前Service的类型如下:

  • ClusterIP:Kubernetes默认会自动设置Service的虚拟IP地址,仅可以被集群内部的客户端访问,当然也可以手动指定。
  • NodePort:将Service的端口号映射到每个Node的一个端口号上,这样在集群中任意Node都可以最为Service的访问入口地址,即NodeIP:NodePort
  • LoadBalancer:将Service映射到一个已经存在的负载均衡器的IP地址上,通常在公有云环境上使用。
  • ExternalName: 将Service映射为一个外部域名地址。

4.5.1 NodePort 类型

apiVersion: v1
kind: Service
metadata: 
  name: nodeport
spec:
  type: NodePort
  ports:
  - port: 8080
    targetPort: 8080
    nodePort: 30080
  selector:
    app: webapp

4.5.2 LoadBalancer类型

apiVersion: v1
kind: Service
metadata:
  name: loadbal
spec:
  type: LoadBalancer
  selector:
    app: webapp
  ports:
  - protocol: TCP
    port: 80
    targetPort: 9376
  clusterIP: 10.96.10.10

4.5.3 ExternalName

 ExternalName类型的服务用于将集群外部的服务定义为Kubernetes的集群的Service。

apiVersion: v1
kind: Service
metadata:
  name: extra
  namespace: default
spec:
  type: ExternalName
  externalName: my.databas.example.com

5、Kubernetes的服务发现机制

服务发现机制是指客户端应用在一个Kubernetes集群中如何获取后端服务的访问地址。

5.1 环境变量方式

      在一个Pod运行起来的时候,系统会自动为其容器运行环境注入所有进去中有效Service的信息。Service的相关信息包括服务IP、端口号各种端口协议。

5.2 DNS

   <servicename>.<namespace>.sve.<clusterdomain>

6、Headless Service的概念和应用

  在某些应用场景中,客户端应用不需要通过Kubernetes内置Service实现的负载均衡功能。

   Headless Service的概念是这种服务没有入口访问地址(无ClusterIP地址),kube-proxy不会为其创建负载均衡转发规则。

 

posted @ 2023-04-30 20:48  中仕  阅读(16)  评论(0)    收藏  举报