• k8s之Service


    什么是service?

    将运行在一组 Pods 上的应用程序公开为网络服务的抽象方法

    为什么需要service?

    1. pod的数量、IP都是动态变化的,service可以给该集合的Pod一个固定的IP,无论pod的集合如何改变,都可以通过service的固定IP来访问到应用。

    2. 可以给pod集合提供负载均衡的功能。

    Service类型

    • LoadBalance,使用云提供商的负载均衡器向外部暴露服务。
    • ExternalName,将服务映射到指定的域名,这个域名可以集群内部也可以是外部的。
    • NodePort,提供的服务既可对外部服务通过NodeIp:NodePort访问,也可以对集群内部通过ClusterIp访问
    • ClusterIP,service提供的访问IP仅在集群内部可达

    使用ClusterIP Service

    我们定义service如下,其中selector是用来筛选需要代理的pod,targetPort是目标pod的端口,port是指该service的端口。

    kind: Service 
    apiVersion: v1 
    metadata: 
      name: demoapp-svc 
    spec: 
      selector: 
        app: demoapp 
      ports: 
      - name: http 
        protocol: TCP    
        port: 80
        targetPort: 80
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    使用上面定义的yaml创建service对象,并可以看到SELECTOR的值是app=demoapp,我们需要创建带有该标签的pod,才能够进行代理。

    [root@k8s-worker1 zwf]# kubectl apply -f service.yaml -n zwf
    service/demoapp-svc created
    
    [root@k8s-worker1 zwf]# kubectl get svc -n zwf -o wide
    NAME          TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE   SELECTOR
    demoapp-svc   ClusterIP   10.0.0.74            80/TCP    18s   app=demoapp
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    定义deployment,会创建带有app=demoapp的Pod

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: demoapp
      name: demo-deploy
    
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: demoapp
    
      template:
        metadata:
          labels:
            app: demoapp
        spec:
          containers:
          - image: mirrors.sangfor.com/ikubernetes/demoapp:v1.0
            name: demoapp
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    创建Deployment对象,并且可以看到创建了2个Pod

    [root@k8s-worker1 zwf]# kubectl apply -f deployments_service.yaml -n zwf
    deployment.apps/demo-deploy created
    
    [root@k8s-worker1 zwf]# kubectl get deploy -o wide -n zwf
    NAME          READY   UP-TO-DATE   AVAILABLE   AGE     CONTAINERS   IMAGES                                         SELECTOR
    demo-deploy   2/2     2            2           2m37s   demoapp      mirrors.sangfor.com/ikubernetes/demoapp:v1.0   app=demoapp
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    查看pod的详情,可以看到Labels有一个app=demoapp的标签

    [root@k8s-worker1 zwf]# kubectl get pods -o wide -n zwf
    NAME                           READY   STATUS    RESTARTS   AGE   IP               NODE          NOMINATED NODE   READINESS GATES
    demo-deploy-6c6d588789-h9gmd   1/1     Running   0          32s   10.222.126.1     k8s-worker2              
    demo-deploy-6c6d588789-nhzhl   1/1     Running   0          32s   10.222.194.104   k8s-worker1              
    
    [root@k8s-worker1 zwf]# kubectl describe demo-deploy-6c6d588789-h9gmd -n zwf
    Name:         demo-deploy-6c6d588789-h9gmd
    Namespace:    zwf
    Priority:     0
    Node:         k8s-worker2/10.64.2.153
    Start Time:   Tue, 30 Aug 2022 19:23:22 +0800
    Labels:       app=demoapp
                  pod-template-hash=6c6d588789
    
    ....
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    通过查看service的详情,我们可以看到Endpoints的值是上面创建的两个Pod的IP。

    [root@k8s-worker1 zwf]# kubectl describe svc -n zwf
    Name:              demoapp-svc
    Namespace:         zwf
    Labels:            
    Annotations:       
    Selector:          app=demoapp
    Type:              ClusterIP
    IP Family Policy:  SingleStack
    IP Families:       IPv4
    IP:                10.0.0.74
    IPs:               10.0.0.74
    Port:              http  80/TCP
    TargetPort:        80/TCP
    Endpoints:         10.222.126.1:80,10.222.194.104:80
    Session Affinity:  None
    Events:            
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    Endpoints也是一个资源对象,Service通过筛选标签到的Pod会添加到Endpints中保存

    [root@k8s-worker1 zwf]# kubectl get endpoints -n zwf
    NAME          ENDPOINTS                           AGE
    demoapp-svc   10.222.126.1:80,10.222.194.104:80   15m
    
    • 1
    • 2
    • 3

    这个时候,我们访问service的80端口,会访问到轮询访问到这两个pod中,我们就可以通过访问service来访问pod集合。

    [root@k8s-worker1 zwf]# curl 10.0.0.74
    iKubernetes demoapp v1.0 !! ClientIP: 10.64.2.141, ServerName: demo-deploy-6c6d588789-nhzhl, ServerIP: 10.222.194.104!
    
    [root@k8s-worker1 zwf]# curl 10.0.0.74
    iKubernetes demoapp v1.0 !! ClientIP: 10.64.2.141, ServerName: demo-deploy-6c6d588789-h9gmd, ServerIP: 10.222.126.1!
    
    [root@k8s-worker1 zwf]# curl 10.0.0.74
    iKubernetes demoapp v1.0 !! ClientIP: 10.64.2.141, ServerName: demo-deploy-6c6d588789-nhzhl, ServerIP: 10.222.194.104!
    
    [root@k8s-worker1 zwf]# curl 10.0.0.74
    iKubernetes demoapp v1.0 !! ClientIP: 10.64.2.141, ServerName: demo-deploy-6c6d588789-h9gmd, ServerIP: 10.222.126.1!
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    除了通过ClusterIP访问,在集群中也能通过域名进行访问,访问方式:..svc.cluster.local

    [root@k8s-worker1 zwf]# kubectl exec -it demo-deploy-6c6d588789-h9gmd -n zwf  -- nslookup demoapp-svc.zwf.svc.cluster.local
    Server:         10.0.0.2
    Address:        10.0.0.2#53
    
    Name:   demoapp-svc.zwf.svc.cluster.local
    Address: 10.0.0.74
    
    [root@k8s-worker1 zwf]# kubectl exec -it demo-deploy-6c6d588789-h9gmd -n zwf  -- curl demoapp-svc.zwf.svc.cluster.local
    iKubernetes demoapp v1.0 !! ClientIP: 10.64.2.153, ServerName: demo-deploy-6c6d588789-h9gmd, ServerIP: 10.222.126.1!
    
    [root@k8s-worker1 zwf]# kubectl exec -it demo-deploy-6c6d588789-h9gmd -n zwf  -- curl demoapp-svc.zwf.svc.cluster.local
    iKubernetes demoapp v1.0 !! ClientIP: 10.222.126.1, ServerName: demo-deploy-6c6d588789-nhzhl, ServerIP: 10.222.194.104!
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    使用NodePort Service

    定义NodePort Service如下,和ClusterIP Service比较,新增type: NodePort代表该Service的类型是NodePort,然后nodePort是节点的端口,在每一台Node上都会创建这么一个端口给集群外调用。

    kind: Service
    apiVersion: v1
    metadata:
      name: demoapp-nodeport-svc
    spec:
      selector:
        app: demoapp
      ports:
      - name: http
        protocol: TCP
        port: 80
        targetPort: 80
        nodePort: 31999
      type: NodePort
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    创建该Service,可以看到TYPE是NodePort,PORT是80:31999代表着将80端口映射到节点的31999端口

    [root@k8s-worker1 zwf]# kubectl apply -f service_nodeport.yaml -n zwf
    service/demoapp-nodeport-svc created
    
    [root@k8s-worker1 zwf]# kubectl get svc -n zwf -o wide
    NAME                   TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE   SELECTOR
    demoapp-nodeport-svc   NodePort    10.0.0.144           80:31999/TCP   10s   app=demoapp
    demoapp-svc            ClusterIP   10.0.0.74            80/TCP         47m   app=demoapp
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    我们可以在集群外通过节点的IP:31999端口一样可以访问Pod服务。

    C:\Users\User>curl 10.64.2.141:31999
    iKubernetes demoapp v1.0 !! ClientIP: 10.64.2.141, ServerName: demo-deploy-6c6d588789-nhzhl, ServerIP: 10.222.194.104!
    
    C:\Users\User>curl 10.64.2.141:31999
    iKubernetes demoapp v1.0 !! ClientIP: 10.64.2.141, ServerName: demo-deploy-6c6d588789-h9gmd, ServerIP: 10.222.126.1!
    
    • 1
    • 2
    • 3
    • 4
    • 5

    如何实现的代理?

    每个Node都会有一个kube-proxy进程,该进程会监控Service的创建与EndPoints列表的添加与删除,配置iptables规则,当客户端请求Service的ClusterIP和端口时,会根据规则轮询转发到后端的Pod中。

    欢迎关注,互相学习,共同进步~

    我的个人博客

    我的微信公众号:编程黑洞

  • 相关阅读:
    Iceberg源码学习:flink读iceberg流程二
    【版本发布公告】HMS Core 6.6.0来啦
    为什么apt-get update 要与apt-get install &&在一起
    .net core Elasticsearch 更新文档,updatebyquery
    机器学习期中考试
    DPDK丢包那些事
    Redis实现消息队列
    shell变量
    C++ day2
    vue实现鼠标移入图片播放视频
  • 原文地址:https://blog.csdn.net/qq_22918243/article/details/126668328