k8s-service

1、service简介前端

  1. 我的理解:service相似于一个前端代理,全部的访问经过代理分发,不管后端怎么变化,用户的访问方式始终保持不变
  2. service是一种为一组功能相同的pod提供单一不变的接入点的资源(如何保证service的高可用?service自己是否会成为瓶颈?) 
  3. service也经过标签选择器来选择对应的pod
  4. service能够将特定客户端的请求每次都指向同一个pod(使用次属性须要考虑负载均衡的影响)
  5. service工做在TCP与UDP层,所以没法基于cookie来绑定pod
  6. service的服务发现:
    1)全部的service都以环境变量的形式存放在pod中,pod经过环境变量获取service的IP和端口
    2)DNS发现服务:
       a、k8s自身在kubesystem命名空间有运行dns服务
       b、其余全部在同一集群的pod都配置成使用该dns(k8s经过修改每一个容器的/etc/resolv.conf文件实现)
       c、pod是否使用dns由pod中sepcd dnsPolicy属性决定
       d、客户端pod在知道service的名称的状况下能够经过FQDN(全局限定域名)访问
          访问格式:web-test.default.svc.cluster.local   #service名称.命名空间名称.集群本地服务名称中使用的可配置的集群域后缀
                  在同一namespace的pod能够省略集群域后缀及命名空间,即只须要service_name
       e、端口号依旧使用环境变量获取
  7. service的IP是没法ping的,由于service的clusterIP只是一个虚拟的IP,只有与service的port结合使用时才有意义
  8. 经过service访问服务没法记录客户端IP,因为node对数据包执行了SNAT(源网络地址转换),所以数据包的源IP会发生改变

 

2、endpoint(kubectl get svc svc_name  #能够查看到endpoint)node

  1. Endpoint就是暴露一个服务的IP地址和端口的列表
  2. service的标签选择器是用与构建endpoint的IP、端口列表,而后存入endpoint资源中
  3. 手动建立endpoint(用于给没有标签选择器的service建立endpoint)
  4. 手动建立的endpoint须要与对应的service具备相同的名称,并包含该服务的目标IP和端口列表
  5. 建立完整的service后删除seletor选择器,service将不会自动更新endpoint列表,能够人为控制endpoint

 

 

3、使用service连接外部服务 web

  1. 使用endpoint写入外部服务器的IP和端口连接外部服务(默认服务发现只能连接集群内部的服务)
  2. 建立ExternalName类型的服务,经过externalname属性和ports属性指定外部服务器的IP和端口
  3. 经过service访问外部服务能够直接连接外部服务,隐藏了外部服务的名称、端口等信息

 

4、将服务暴露给外部客户端 后端

  1. 建立NodePort类型的service:每一个节0点都会打开一个相同的随机端口,用于将流量重定向到节点上的pod,外部经过node_ip:port访问(缺点:pod更换node节点会改变访问方式,或弄得节点故障从而致使服务不可访问)
  2. 建立LoadBalancer类型的service:经过一个专用的负载均衡器访问,客户端经过负载均衡器的IP链接到服务
    (云服务商的k8s集群一般支撑从云基础架构自动提供负载均衡器,用户仅需将类型修改成LoadBalance模式便可,以后根据查看到的负载均衡IP访问服务)
    实现须要负载均衡器+独有的公网IP
  3. 建立一个Ingress资源,经过一个IP地址公布多个service 
    一、Ingress须要一个公网IP
    二、Ingress根据请求的主机名和路劲决定请求转发的服务
    三、Ingress在网络栈(HTTP)的应用层操做,能够实现基于cookie的回话亲和性
    四、只有Ingress控制器在集群中运行,Ingress资源才能正常工做
    五、云供应商的Ingress控制器(例如:GKE)要求Ingress指向一个NodePort服务
    六、ingress工做原理:客户端——》DNS——》返回ingress_IP——》客户端发出HTTP请求,并在Host头中指定域名——》控制器经过域名肯定客户端访问的服务——》经过该服务的Endpoint查看pod IP——》并将客户端的请求转发给其中一个pod(一般状况ingress只经过service选择pod,而不是转发给service)
    七、一个Ingress能够暴露多个服务:经过不一样的域名指向不一样的service,所以在实际应用场景中,须要将Ingress用到的域名在Ingress所在的node上所有解析
  4. 小结:
    1)Ingress决定访问的service(选择须要访问的服务)
    2)service选择响应用户请求的pod
    3)建立ingress的pod时注意使用replicas机制,(使用DNS解析到多个对应的Ingress节点,以避免当pod或node故障时,经过ingress的访问所有失效:仅我的理解)

 

 

 

 

2、service的yaml示例api

apiVersion: v1服务器

kind: Servicecookie

metadata:网络

  name: svc-testsession

spec:架构

  #type: ExternalName

  #externalname: www.example.com #在externalname模式是的属性,指定外部服务器的FQDN,同时也须要指定ports属性

  sessionAffinity: ClientIp #次属性用于使同一客户端的请求每次都指向同一个pod(有none和client两中选择,默认为none) 

  externalTrafficPolicy: local #负载均衡器——》service——》node——》pod(选择了node的时候可能响应的pod不在该node上(默认随机),此选即开启:接受到请求的node直接使用本地的pod直接响应;缺点,若此node上无pod响应,则该请求将被直接挂起,且node上的pod数量不一致的状况下,可能致使pod的负载不均衡 

  selector:

    app: web 

  ports:

  - name: http  #映射多个端口时须要指定name属性,只须要映射一个端口时能够省略

    port: 8080 #映射的端口

    targetPort: 80 #pod端口

    #nodePort: 30080 #节点端口,使用nodeport模式时能够指定的属性(不指定则自动生成随机端口) 

  - name: http

    port: 8443

    targetPort: 443  #pod端口在pod的yaml文件中也定义有name属性,此处能够直接引用,这样即便pod的端口发生变化,此处也无需修改

 

 

Ingress的yaml文件

apiVersion: extensions/v1beta1

kind: Ingress

metadata:

  name: ingress-test

spec:

  tls: #使用HTTPS方式访问,将证书建立为secret资源使用

  - hosts:

    - test.example.com #使用HTTPS访问的域名

    secretName: tls-secret  #建立的secret名称

  rules:

  - host: test.example.com #对外暴露的域名

    http:

    paths:

    - path: /web1 #访问的文件路径

      backend:

        service:Name: test-svc #service的名称

        servicePort: 80  #service的端口

    http: 

    paths:

    - path: /web2 #在同一host下的不一样路径

      backend:

        service:Name: test-svc2

        servicePort: 80 

  - host: test2.example.com

    http:

    paths:

    - path: /web1

      backend:

        service:Name: test2-svc

        servicePort: 80 

本站公众号
   欢迎关注本站公众号,获取更多信息