• Service


    一.pod存在的意义

    kubernetes中一个应用服务会有一个或多个示例(Pod,PodK可以通过rs进行多副本建立),每个实例的ip地址由网络插件动态随机分配(pod重启ip地址会改变)。
    为屏蔽这些后端实例的动态变化和对多实例的负载均衡,引入了Service这个资源对象
    • 防止pod失联,准备找到提供同一个服务的pod,即服务发现
    • 定义一组pod的访问策略(负载均衡)

    二.Pod与Service的关系

    • Service通过标签关联一组pod
    • Service使用iptables或者ipvs为一组pod提供负载均衡的能力

    三.Service的定义与创建 

    创建service:
        kubectl apply -f service.yaml
    查看service:
        kubectl get service
    apiVersion: v1
    kind: Service
    metadata:
      name: web-nginx    # service的name
      namespace: web     # 所属哪个命名空间,一般和pod放在一个同一个命名空间下
    spec:
      ports:
      - port: 8080       # service端口
        protocol: TCP  # 协议
        targetPort: 80 # 容器端口
      selector:        # 标签选择器
        app: nginx      # 指定关联Pod的标签
      type: ClusterIP  # 服务类型

    # selector:指定关联的pod标签
    标签获取方式:  
      通过yaml文件获取
      kubectl get svc --show-labels

    四.Service三种常用类型

    1.ClusterIP

    默认类型,分配一个稳定的ip地址,即VIP。只能在集群内部访问
    spec:
      ports:
      - port: 8080       # service端口
        protocol: TCP  # 协议
        targetPort: 80 # 容器端口
      selector:        # 标签选择器
        app: nginx      # 指定关联Pod的标签
      type: ClusterIP  # 服务类型
    #########################################################

    [root@k8s-master yaml]# kubectl get svc -o wide -n web
    NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
    web-nginx ClusterIP 10.107.185.146 <none> 8080/TCP 13m app=nginx

    # 此service只能通过10.107.185.146:8080来访问

    2.NodePort

    在每个节点启用一个端口来暴露服务,可以在集群外部访问。也会分配一个稳定的集群ip地址
    
    外部访问:任意nodeip:NodePort
    端口范围:30000-32767
    apiVersion: v1
    kind: Service
    metadata:
      name: web-nginx    # service的name
      namespace: web     # 所属哪个命名空间,一般和pod放在一个同一个命名空间下
    spec:
      ports:
      - port: 8080       # service端口
        protocol: TCP   # 协议
        targetPort: 80  # 容器端口
        nodePort: 30008 # NodePort的端口 
      selector:        # 标签选择器
        app: nginx      # 指定关联Pod的标签
      type: NodePort  # 服务类型

    ###########################################################################################

    [root@k8s-master yaml]# kubectl get svc -n web -o wide
    NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
    web-nginx NodePort 10.107.185.146 <none> 8080:30008/TCP 25m app=nginx

    集群外部可以通过nodeip:30008来访问

    [root@k8s-master yaml]# curl -I http://192.168.11.134:30008
    HTTP/1.1 200 OK

    3.LoadBalancer

    LoadBalancer:与NodePort类似,在每个节点上启用一个端口来暴
    露服务。除此之外,Kubernetes会请求底层云平台(例如阿里云、腾
    讯云、AWS等)上的负载均衡器,将每个Node
    ([NodeIP]:[NodePort])作为后端添加进去。

    五.Service代理模式之iptables实现

    集群外部访问service的30008端口,iptables是怎么实现的

    以集群中的一个node分析
    1.入口规则匹配
    -A KUBE-NODEPORTS -p tcp -m comment --comment "web/web-nginx" -m tcp --dport 30008 -j KUBE-SVC-DGUGPUBGLFKE4V6A  # 进入30008的数据包被重定向到KUBE-SVC-DGUGPUBGLFKE4V6A这个链

    2. 实现负载均衡器(一组规则,有几个pod就创建几条)

      A KUBE-SVC-DGUGPUBGLFKE4V6A -m comment --comment "web/web-nginx" -m statistic --mode random --probability 0.33333333349 -j KUBE-SEP-4Q7O3SKSDAWOI3U5
      -A KUBE-SVC-DGUGPUBGLFKE4V6A -m comment --comment "web/web-nginx" -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-L4IK2ED63YY2WA7E
      -A KUBE-SVC-DGUGPUBGLFKE4V6A -m comment --comment "web/web-nginx" -j KUBE-SEP-Q42CSEQQKNK3LVBU

    ### --probability 顺序匹配,有33%的概率进入到KUBE-SEP-4Q7O3SKSDAWOI3U5链,有50%的概率进入到KUBE-SEP-L4IK2ED63YY2WA7E链,100%的概率进入到KUBE-SEP-Q42CSEQQKNK3LVBU链,实现了类似轮训的机制  每个链对应一个pod

      3.使用DNAT转发到具体的pod上 

      -A KUBE-SEP-4Q7O3SKSDAWOI3U5 -p tcp -m comment --comment "web/web-nginx" -m tcp -j DNAT --to-destination 10.244.169.186:80
      -A KUBE-SEP-L4IK2ED63YY2WA7E -p tcp -m comment --comment "web/web-nginx" -m tcp -j DNAT --to-destination 10.244.36.95:80
      -A KUBE-SEP-Q42CSEQQKNK3LVBU -p tcp -m comment --comment "web/web-nginx" -m tcp -j DNAT --to-destination 10.244.36.99:80

      4.由具体的pod将数据原路返回客户端

    集群内部通过ClusterIP的方式8080请求pod资源,iptables怎么实现的

    1.入口匹配
    -A KUBE-SERVICES -d 10.100.184.209/32 -p tcp -m comment --comment "web/web-nginx cluster IP" -m tcp --dport 8080 -j KUBE-SVC-DGUGPUBGLFKE4V6A  #转发到KUBE-SVC-DGUGPUBGLFKE4V6A链
    
    2.负载均衡实现和nodeport一样
    -A KUBE-SVC-DGUGPUBGLFKE4V6A -m comment --comment "web/web-nginx" -m statistic --mode random --probability 0.33333333349 -j KUBE-SEP-4Q7O3SKSDAWOI3U5
    -A KUBE-SVC-DGUGPUBGLFKE4V6A -m comment --comment "web/web-nginx" -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-L4IK2ED63YY2WA7E
    -A KUBE-SVC-DGUGPUBGLFKE4V6A -m comment --comment "web/web-nginx" -j KUBE-SEP-Q42CSEQQKNK3LVBU
    
    3. DNAT转发到对应pod上
    -A KUBE-SEP-4Q7O3SKSDAWOI3U5 -p tcp -m comment --comment "web/web-nginx" -m tcp -j DNAT --to-destination 10.244.169.186:80
    -A KUBE-SEP-L4IK2ED63YY2WA7E -p tcp -m comment --comment "web/web-nginx" -m tcp -j DNAT --to-destination 10.244.36.95:80
    -A KUBE-SEP-Q42CSEQQKNK3LVBU -p tcp -m comment --comment "web/web-nginx" -m tcp -j DNAT --to-destination 10.244.36.99:80
    4.由pod将资源原路返回给客户端

    六.Service代理模式之ipvs实现

    kubeadm方式修改ipvs模式:
    [root@k8s-master yaml]# kubectl get configmap -n kube-system 
    NAME                                 DATA   AGE
    calico-config                        4      12d
    coredns                              1      12d
    extension-apiserver-authentication   6      12d
    kube-proxy                           2      12d
    kubeadm-config                       2      12d
    kubelet-config-1.19                  1      12d
    
    kubectl edit configmap kube-proxy -n kube-system
    ...
       mode: “ipvs“
    ...
    
    ####
        1.kube-proxy配置文件是以configmap方式存储
        2.如果让所有节点生效,需要重建所有节点的kube-proxy pod
    3.ipvs默认调度算法是rr
    二进制方式修改ipvs模式:
    # vi kube-proxy-config.yml
        mode: ipvs
        ipvs:
        scheduler: "rr“
    # systemctl restart kube-proxy
    注:参考不同资料,文件名可能不同。
    ipvs修改已生效
    [root@k8s-master yaml]# kubectl logs kube-proxy-ww79n Error from server (NotFound): pods "kube-proxy-ww79n" not found [root@k8s-master yaml]# kubectl logs kube-proxy-ww79n -n kube-system I1130 09:46:32.359435 1 node.go:136] Successfully retrieved node IP: 192.168.11.134 I1130 09:46:32.359667 1 server_others.go:111] kube-proxy node IP is an IPv4 address (192.168.11.134), assume IPv4 operation I1130 09:46:32.435474 1 server_others.go:259] Using ipvs Proxier.

    节点上查看ipvs规则,需要安装:yum install ipvsadm -y

    [root@k8s-node1 ~]# ipvsadm -L 
    IP Virtual Server version 1.2.1 (size=4096)
    Prot LocalAddress:Port Scheduler Flags
      -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
    TCP  k8s-node1:30008 rr
      -> 10.244.36.95:http            Masq    1      0          0         
      -> 10.244.36.99:http            Masq    1      0          0         
      -> 10.244.169.186:http          Masq    1      0          0         
    TCP  k8s-node1:pago-services1 rr
      -> 10.244.36.109:pcsync-https   Masq    1      0          0         
    TCP  k8s-node1:30008 rr
      -> 10.244.36.95:http            Masq    1      1          0         
      -> 10.244.36.99:http            Masq    1      1          0         
      -> 10.244.169.186:http          Masq    1      1          0  
    .............

    service代理流程图解

    七.总结:ipvs和iptables模式的独领风骚

    iptables:
        灵活,功能强大
        规则遍历匹配更新,呈线性时延
        缺点:集群中service pod量大时,规则成千上万条时,性能瓶颈就会凸显
    
    
    ipvs:
        工作在内核态,有更好的性能
        丰富的调度算法:rr  wrr lc wlc [ip hash]等等

    八.Service DNS名称

    用busybox起一个pod,进行验证
    [root@k8s-master yaml]# kubectl run -it dns-test --image=busybox:1.28.4 -- sh
    
    同一命名空间解析:
    [root@k8s-master ~]# kubectl get svc
    NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
    kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   12d
    
    / # nslookup kubernetes
    Server:    10.96.0.10
    Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
    
    Name:      kubernetes
    Address 1: 10.96.0.1 kubernetes.default.svc.cluster.local
    
    不同命名空间需要加对应的namespace-name
    [root@k8s-master ~]# kubectl get svc -n web 
    NAME        TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)           AGE
    redis-app   NodePort   10.106.73.85     <none>        63790:30010/TCP   14h
    web-nginx   NodePort   10.101.144.136   <none>        8080:30008/TCP    16h
    
    / # nslookup web-nginx.web 
    Server:    10.96.0.10
    Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
    
    Name:      web-nginx.web
    Address 1: 10.101.144.136 web-nginx.web.svc.cluster.local
    / # nslookup redis-app.web 
    Server:    10.96.0.10
    Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
  • 相关阅读:
    新服务器上迁移项目遇到的问题
    xftp传输文件失败
    记录一些mysql常用命令
    微信APP支付
    状态码(更新中&#183;&#183;&#183;)
    yii ActiveRecord
    MySQL命令行自动补全——mycli安装
    MySQL优化总结
    MySQL读写分离架构——Atlas
    MySQL日志
  • 原文地址:https://www.cnblogs.com/lichunke/p/14062717.html
Copyright © 2020-2023  润新知