zoukankan      html  css  js  c++  java
  • Kubernetes 第九章 Service

    Service

    Kubernetes 在设计之初就充分考虑了针对容器的服务发现与负载均衡机制,提供了 Service 资源,对于内部容器资源提供负载均衡机制,对外提供统一访问入口。
    

    Service 是对一组提供相同功能的 Pods 的抽象,并为它们提供一个统一的入口。借助 Service,应用可以方便的实现服务发现与负载均衡,并实现应用的零宕机升级。Service 通过标签来选取服务后端,一般配合 Replication Controller 或者 Deployment 来保证后端容器的正常运行。这些匹配标签的 Pod IP 和端口列表组成 endpoints,由 kube-proxy 负责将服务 IP 负载均衡到这些 endpoints 上。
    #通过标签选择对应的pod
    Service 有四种类型:
    
    ClusterIP:默认类型,自动分配一个仅 cluster 内部可以访问的虚拟 IP
    NodePort:在 ClusterIP 基础上为 Service 在每台机器上绑定一个端口,这样就可以通过 <NodeIP>:NodePort 来访问该服务。如果 kube-proxy 设置了 --nodeport-addresses=10.240.0.0/16(v1.10 支持),那么仅该 NodePort 仅对设置在范围内的 IP 有效。
    LoadBalancer:在 NodePort 的基础上,借助 cloud provider 创建一个外部的负载均衡器,并将请求转发到 <NodeIP>:NodePort,依赖与云环境
    ExternalName:将服务通过 DNS CNAME 记录方式转发到指定的域名(通过 spec.externlName 设定)。需要 kube-dns 版本在 1.7 以上。
    另外,也可以将已有的服务以 Service 的形式加入到 Kubernetes 集群中来,只需要在创建 Service 的时候不指定 Label selector,而是在 Service 创建好后手动为其添加 endpoint。

    Service 定义

    ClusterIP
    [root@kube test]# cat nginx-svc.yaml 
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-service
      namespace: default
    spec:
    #默认ClusterIP 类型 ports:
    - port: 80 protocol: TCP targetPort: 80 selector: app: nginx type: ClusterIP [root@kube test]# kubectl apply -f nginx-svc.yaml [root@kube test]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 38d nginx-service ClusterIP 10.107.27.48 <none> 80/TCP 8s php-apache ClusterIP 10.97.196.195 <none> 80/TCP 86m [root@kube test]#

    查看pods 标签

    root@kube test]# kubectl get pods --show-labels
    NAME                                READY   STATUS             RESTARTS   AGE     LABELS
    liveness-exec                       0/1     CrashLoopBackOff   8923       24d     test=liveness
    liveness-http                       1/1     Running            16         24d     test=liveness
    nginx-deployment-5754944d6c-c797m   1/1     Running            0          3d22h   app=nginx,pod-templ
    nginx-deployment-5754944d6c-jspst   1/1     Running            0          3d22h   app=nginx,pod-templ
    nginx-deployment-5754944d6c-kkvx5   1/1     Running            0          3d22h   app=nginx,pod-templ
    php-apache-d89b5f47b-dllcg          0/1     ImagePullBackOff   0          4h44m   pod-template-hash=d
    pod-test                            1/1     Running            0          31d     app=myapp,tier=fron
    [root@kube test]# 

      

    NodePort:

    [root@kube test]# cat nginx-svc-nodeport.yaml 
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-service-nodeport
      namespace: default
    spec:
      ports:
      - port: 80
        protocol: TCP
        targetPort: 80
        nodePort: 30080
    //指定node 对外映射端口,确认没有被占用
    selector: app: nginx type: NodePort [root@kube test]# kubectl get service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 38d nginx-service ClusterIP 10.107.27.48 <none> 80/TCP 3h46m nginx-service-nodeport NodePort 10.109.241.119 <none> 80:30080/TCP 14m php-apache ClusterIP 10.97.196.195 <none> 80/TCP 5h12m [root@kube test]# curl http://10.2.61.22:30080 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html> [root@kube test]#
    [root@kube test]# kubectl describe service nginx-service-nodeport
    Name:                     nginx-service-nodeport
    Namespace:                default
    Labels:                   <none>
    Annotations:              kubectl.kubernetes.io/last-applied-configuration:
                                {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"nginx-service-nodeport","namespace":"default"},"spec":{"ports":[{...
    Selector:                 app=nginx
    Type:                     NodePort
    IP:                       10.109.241.119
    Port:                     <unset>  80/TCP
    TargetPort:               80/TCP
    NodePort:                 <unset>  30080/TCP
    Endpoints:                10.244.1.7:80,10.244.2.28:80,10.244.2.29:80
    Session Affinity:         None
    External Traffic Policy:  Cluster
    Events:                   <none>
    [root@kube test]# 
    

      

    不指定 Selectors 的服务

    在创建 Service 的时候,也可以不指定 Selectors,用来将 service 转发到 kubernetes 集群外部的服务(而不是 Pod)。目前支持两种方法

    (1)自定义 endpoint,即创建同名的 service 和 endpoint,在 endpoint 中设置外部服务的 IP 和端口

    [root@kube test]# cat endpoint_demo.yaml 
    kind: Service
    apiVersion: v1
    metadata:
      name: my-service-end
    spec:
      ports:
        - protocol: TCP
          port: 80
          targetPort: 8080
    ---
    kind: Endpoints
    apiVersion: v1
    metadata:
      name: my-service-end
    subsets:
      - addresses:
          - ip: 10.1.255.156
        ports:
          - port: 8080
    [root@kube test]# curl  -I http://10.100.60.230
    HTTP/1.1 403 Forbidden
    Server: nginx
    Date: Tue, 20 Aug 2019 08:49:01 GMT
    Content-Type: text/html; charset=utf-8
    Connection: keep-alive
    Vary: Accept-Encoding
    
    [root@kube test]# 

      

        

    Headless 服务

    Headless 服务即不需要 Cluster IP 的服务,即在创建服务的时候指定 spec.clusterIP=None。包括两种类型

    • 不指定 Selectors,但设置 externalName,即上面的(2),通过 CNAME 记录处理
    • 指定 Selectors,通过 DNS A 记录设置后端 endpoint 列表

    CNAME 方式

    保留源 IP

    各种类型的 Service 对源 IP 的处理方法不同:

    • ClusterIP Service:使用 iptables 模式,集群内部的源 IP 会保留(不做 SNAT)。如果 client 和 server pod 在同一个 Node 上,那源 IP 就是 client pod 的 IP 地址;如果在不同的 Node 上,源 IP 则取决于网络插件是如何处理的,比如使用 flannel 时,源 IP 是 node flannel IP 地址。
    • NodePort Service:默认情况下,源 IP 会做 SNAT,server pod 看到的源 IP 是 Node IP。为了避免这种情况,可以给 service 设置 spec.ExternalTrafficPolicy=Local (1.6-1.7 版本设置 Annotation service.beta.kubernetes.io/external-traffic=OnlyLocal),让 service 只代理本地 endpoint 的请求(如果没有本地 endpoint 则直接丢包),从而保留源 IP。
    • LoadBalancer Service:默认情况下,源 IP 会做 SNAT,server pod 看到的源 IP 是 Node IP。设置 service.spec.ExternalTrafficPolicy=Local 后可以自动从云平台负载均衡器中删除没有本地 endpoint 的 Node,从而保留源 IP。

    工作原理

    kube-proxy 负责将 service 负载均衡到后端 Pod 中,如下图所示

     

     

  • 相关阅读:
    windows中administrator 和 administrators两个账户的区别
    如何去掉打印网页时自带的网址以及页码等内容
    Oracle左连接,右连接
    oracle服务器本地能够登录但是局域网内其他机器不能访问的解决方法
    错误Name node is in safe mode的解决方法
    oracle数据库中对varchar类型求max的解决方法
    JBoss中配置数据源出现错误:“Failed to register driver for: com.mysql.jdbc.Driver”的解决方法
    学习junit和hamcrest的使用
    Ubuntu10.10如何给用户添加sudo权限
    ORACLE 9i卸载并重新安装
  • 原文地址:https://www.cnblogs.com/zy09/p/11375624.html
Copyright © 2011-2022 走看看