0
点赞
收藏
分享

微信扫一扫

Kubernetes资源对象之Service

进击的铁雾 2022-08-01 阅读 42

Service

Service 介绍

  • Service,能够为客户端应用提供稳定的访问地址(域名或者IP地址)和负载均衡功能,以及屏蔽后端Endpoint的变化,是kubernetes实现微服务的核心资源

Service 访问实现原理

iptables 代理模式

  • kube-proxy 通过设置 Linux 内核的 防火墙规则,实现从Service到后端Endpoint 列表的负载分发规则,效率很高。
  • 原理图
    iptables.png

ipvs 代理模式

  • kube-proxy 通过设置 Linux 内核的netlink接口设置IPVS规则,转发效率和支持的吞吐率都是最高的
  • ipvs模式支持更多的负载均衡策略
    • rr: 轮训
    • lc:最小连接数
    • dh:目的地址哈希
    • sh:源地址哈希
    • sed:最短期望延时
    • nq:永不排队
  • 原理图
    ipvs.png

userspace 代理模式(早期版本)

  • 用户空间模式,由kube-proxy完成代理的实现,效率较低(不在推荐)
  • 原理图userspace.png

kernelspace 模式

  • Windows Server 上的代理模式

会话保持机制

  • Service 支持通过设置 sessionAffinity 实现基于客户端IP的会话保持机制
[root@master nginx]# cat webnginx-service.yaml 
apiVersion: v1
kind: Service
metadata:
  name: webapp
  namespace: test-nginx
spec:
  sessionAffinity: ClientIP #设置会话保持
  sessionAffinityConfig: #设置会话保持的最长时间
    ClientIP:
      timeoutSeconds:18000
  ports:
  - protocol: TCP
    port: 8080 
    targetPort: 80 
  selector: 
    app: webapp

Service 多端口设置

[root@master nginx]# cat webnginx-service.yaml 
apiVersion: v1
kind: Service
metadata:
  name: webapp
  namespace: test-nginx
spec:
  ports:
  - port: 8080  #service 端口
    targetPort: 80 #后端pod的容器端口
    name: web
  - port: 8081  #service 端口
    targetPort: 80 #后端pod的容器端口
    name: apache
  selector: #定义后端Pod所拥有的label
    app: webapp

# 使用不同的协议
[root@master nginx]# cat webnginx-service.yaml 
apiVersion: v1
kind: Service
metadata:
  name: kube-dns
  namespace: kube-system
spec:
  selector:
    k8s-app: kube-dns
  ClientIP: 169.169.0.100
  ports:
  - name: dns
    port: 53
    protocol: TCP
  - name: dns-UDP
    port: 53
    protocol: UDP

Service 对外访问

  • Kubernets 提供了多种机制将Service暴露出去,供集群外部的客户端访问

  • Service 类型如下

    • ClusterIP
    Kubernetes 默认会自动设置Service的虚拟IP地址,仅可被集群内部的客户端应用访问
    • NodePort
    • LoadBalance
    • ExternalName
  • NodePort 类型示例
[root@master nginx]# cat webnginx-service.yaml 
apiVersion: v1
kind: Service
metadata:
  name: webapp
  namespace: test-nginx
spec:
  type: NodePort
  ports:
  - port: 8080
    targetPort: 80 
    nodePort: 8081 #如果不设置nodePort端口号,则kubernets会自动分配一个NodePort范围内的可用端口号
  selector: #定义后端Pod所拥有的label
    app: webapp
  • LoadBalance 类型示例
#客户端通过 负载均衡的IP和Service的端口号就可以访问到具体的服务,无须在通过kube-proxy提供的负载均衡机制进行流量转发

[root@master nginx]# cat webnginx-service.yaml 
apiVersion: v1
kind: Service
metadata:
  name: webapp
  namespace: test-nginx
spec:
  type: LoadBalancer
  ports:
  - protocol: TCP
    port: 80
    targetPort: 9376 
  clusterIP: 10.11.199.247
  selector:
    app: webapp

#Service创建后,Service会补充LoadBalancer的IP地址

  status:
    loadBalancer:
      ingress:
      - ip:1.1.1.1
  • ExternalName 类型示例
#将Service映射为一个外部域名地址,通过ExternalName字段进行设置

[root@master nginx]# cat webnginx-service.yaml 
apiVersion: v1
kind: Service
metadata:
  name: webapp
  namespace: test-nginx
spec:
  type: ExternalName
  externalName: my.date.example.com

Service 支持的网络协议

  • 支持的协议如下:
    • TCP:Service 默认的网络协议
    • UDP:可用于大多数的Service
    • HTTP:取决于云服务商是否支持
    • PROXY:取决于云服务商是否支持
    • STCP:1.12版本之后引入,默认开启

Service服务发现机制

  • 环境变量 方式
在Pod运行时,系统会自动为容器运行环境注入所有集群中有效的Service信息,包含:服务IP,服务端口号等,通过{SVCNAME}_SERVICE_HOST 和 {SVCNAME}_SERVICE_PORT格式进行设置

[root@master nginx]# cat webnginx-service.yaml 
apiVersion: v1
kind: Service
metadata:
  name: webapp
  namespace: test-nginx
spec:
  ports:
  - protocol: TCP
    port: 8080  #service 端口
    targetPort: 80 #后端pod的容器端口
  selector: #定义后端Pod所拥有的label
    app: webapp
#WEBAPP_SERVICE_HOST=10.11.199.247
#WEBAPP_SERVICE_PORT=8080
#WEBAPP_PORT=tcp://1.1.1.1:80
  • DNS 方式
#Service的DNS域名表示方法为<servicename>.<namespace>.svc.<clusterdomain>
$ servicename 为服务的名称
$ namespace 为namespace名称
$ clusterdomain 为kubernetes集群设置的域名后缀

Headless Service 概念

  • 概念:服务没有入口访问地址,kube-proxy不会为其创建负载转发规则,而服务名(DNS域名)的 解析机制取决于该Headless Service是否设置了Label Selector
  • Headless Service
    • 如果设置了Label Selector, Kubernetes会根据 Label Selector 查询后端Pod列表,自动创建Endpoint,将服务名(DNS域名)的解析机制设置为:当客户端访问该服务是,得到的是全部Endpoint列表
    • 如果没有设置Label Selector,Kubernetes 则不会创建Endpoint列表

Ingress 7层路由机制

  • Ingress资源对象,用于将不同URL的访问请求转发到后端不同的Service,以实现HTTP层的业务路由机制
  • Kubernetes使用一个Ingress策略定义和一个具体的Ingress Controller,两者结合并实现了一个完整的Ingress负载均衡器
  • 架构图
    ingress.png

  • 示例
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-nginx
  annotations:
    # use the shared ingress-nginx
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
  - host: a.com #基于域名的访问,客户端请求将作用于指定域名的客户端请求
    http:
      paths: #一组根据路径进行转发的规则设置
      - path: /
        pathType: Prefix
        backend: #目标后端服务,包括服务的名称和端口
          service:
            name: nginx
            port: 
              number: 80
 # 如果一个请求同时被多个URL路径匹配,系统将以最长的匹配路径优先。如果长度相同,则精确匹配类型优先前缀匹配类型

Service简单示例

  • 创建两个nginx pod
#创建namespace
[root@master nginx]# cat nginxnamespace.yaml 
apiVersion: v1
kind: Namespace
metadata:
   name: test-nginx
   labels:
     name: test-nginx

#创建deployment
[root@master nginx]# cat webnginx.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: webapp
  namespace: test-nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: webapp
  template:
    metadata:
      labels:
        app: webapp
    spec:
      containers:
      - name: webapp
        image: nginx:1.22
        ports:
        - containerPort: 80
#创建pod
$kubectl apply -f nginxnamespace.yaml
$kubectl apply -f webnginx.yaml
  • 创建service
#快速创建
$ kubectl expose deployment webapp

#yaml创建
[root@master nginx]# cat webnginx-service.yaml 
apiVersion: v1
kind: Service
metadata:
  name: webapp
  namespace: test-nginx
spec:
  ports:
  - protocol: TCP
    port: 8080  #service 端口
    targetPort: 80 #后端pod的容器端口
  selector: #定义后端Pod所拥有的label
    app: webapp

[root@master nginx]# kubectl get svc -n test-nginx
NAME     TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
webapp   ClusterIP   10.11.199.247   <none>        8080/TCP   3m13

[root@master nginx]# curl -Lvo /dev/null 10.11.199.247:8080
* About to connect() to 10.11.199.247 port 8080 (#0)
*   Trying 10.11.199.247...
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* Connected to 10.11.199.247 (10.11.199.247) port 8080 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: 10.11.199.247:8080
> Accept: */*
> 
< HTTP/1.1 200 OK
< Server: nginx/1.22.0
< Date: Sat, 30 Jul 2022 16:31:33 GMT
< Content-Type: text/html
< Content-Length: 615
< Last-Modified: Mon, 23 May 2022 23:59:19 GMT
< Connection: keep-alive
< ETag: "628c1fd7-267"
< Accept-Ranges: bytes
< 
  • 查看service 详细信息
[root@master nginx]# kubectl describe svc webapp -n test-nginx
Name:              webapp
Namespace:         test-nginx
Labels:            <none>
Annotations:       <none>
Selector:          app=webapp
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.11.199.247
IPs:               10.11.199.247
Port:              <unset>  8080/TCP
TargetPort:        80/TCP
Endpoints:         10.244.104.3:80,10.244.104.4:80
Session Affinity:  None
Events:            <none>
  • Kubernetes 自动创建了与Service关联的Endpoint资源对象,这可以通过查询endpoint对象进行查看
[root@master nginx]# kubectl get endpoints -n test-nginx
NAME     ENDPOINTS                         AGE
webapp   10.244.104.3:80,10.244.104.4:80   8m16s
举报

相关推荐

0 条评论