• kubernetes-Service服务发现


    目录

    一、Service基本概念

    1、Pod的特征

      1. Pod等资源的概念

    2.解决pod进行如此多变化时的解决方案

    2、Service

    1. Kubernetes Service 定义了这样一种抽象:

    2. Service的实现类型

    3、Service模型

    4、Endpoint Controller

    5、Kube-proxy  iptables

    6、Kube-proxy IPVS

    二、服务发现

    1、创建后端Deployment

    2、创建Service

    3、整理文件并创建

    4、查看Service

    1. 查看service简明信息,可以获取service提供服务的ip地址和端口

    2.测试service是否正常提供服务

    3. 使用describe命令可以查看service详细信息

    5、创建可供外部访问的Service

    三、集群中的DNS

    1、CoreDNS

    2、查看服务的完整域名

    3、DNS记录

    四、Headless Service(无头服务)

    1、Headless Service

    2、创建Headless Service

    3、使用Headless Service

    1.查看Headless Service的信息,可以看到没有IP地址

    2.使用的时候利用DNS功能,通过访问“Headless-svc”或“headless-svc.default”来访问服务


    一、Service基本概念

    1、Pod的特征

      1. Pod等资源的概念

    ①.Pod有自己独立的IP

    ②.Pod可以被创建,销毁

    ③.当扩容时,pod的数量会发生变更(可以扩、缩容)

    ④.当pod故障时,replicaset会创建新的pod

    20aa679d2757476284d9a7a23858c370.png

    2.解决pod进行如此多变化时的解决方案

    e45011bfd96340aaba7aa147212b004c.png

    一组pod对应一个服务,通过服务访问后端

    2、Service

    1. Kubernetes Service 定义了这样一种抽象:

            逻辑上的一组Pod,一种可以访问它们的策略 — — 通常称为微服务

            这一组Pod能够被Service访问到,通常是通过Label Selector 实现的

    2. Service的实现类型

    ClusterIP提供一个集群内部的虚拟IP地址以供Pod访问(默认模式),只能供内部使用
    NodePort在Node上打开一个端口以供外部访问
    LoadBalancer通过外部的负载均衡器来访问
    官网(如何发布服务): 服务(Service) | Kubernetes

    3、Service模型

    edf81bcf0d0b4c09bbac44dd6085342d.png

    每个节点都有一个Kube-Proxy服务,负责iptables(路由);

    Endpoint Controller负责映射关系,通过其知道内部IP地址,内部IP映射到服务

    最终通过Kube-proxy组件进行工作

    4、Endpoint Controller

    1.负责生成和维护所有endpoint对象的控制器
    2.负责监听service和对应pod的变化
    3.监听到service被删除,则删除和该service同名的endpoint对象

    4.监听到新的service被创建,

        则根据新建service信息获取相关pod列表,然后创建对应endpoint对象

    5.监听到service被更新,

       则根据更新后的service信息获取相关pod列表,然后更新对应endpoint对象

    6.监听到pod事件,则更新对应的service的endpoint对象,将pod IP 记录到endpoint中

        endpoint其实就是个列表

    5、Kube-proxy  iptables

    f964fec1c22f4bab965367f764aee56b.png

    集群内部的Client可以访问服务IP,通过服务IP可以找到集群内部的Pod

    6、Kube-proxy IPVS

            从k8s的1.8版本开始,kube-proxy引入了IPVS模式,IPVS模式与iptables实现方式类似,但是采用的hash表,因此当service数量达到一定规模时,hash查表的速度优势就会显现出来,从而提高service的服务性能

    Service基数15,00020,000
    Rules基数840,000160,000
    增加1条iptables规则50us11min5hour
    增加1条ipvs规则30us50us70us

    二、服务发现

    1、创建后端Deployment

    1. 创建一个deployment,特别注意其中的几个选项要和service匹配

            - Template 选项必须配置labels,示例中配置参数为“app:httpd”,该配置和service匹配

            Pod的属性中Ports选项指定pod对外提供服务的容器端口,图例中为"containerPort:80",该端口需要和service匹配

    1. apiVersion: apps/v1 #版本
    2. kind: Deployment
    3. metadata: #元数据
    4. name: httpd
    5. spec: #描述
    6. replicas: 3 #三副本
    7. selector: #选择器
    8. matchLabels: #匹配标签
    9. app: httpd
    10. template: #模板
    11. metadata: #模板元数据
    12. labels: #模板标签
    13. app: httpd
    14. spec: #针对template的描述
    15. containers: #容器
    16. - name: httpd
    17. image: httpd
    18. ports:
    19. - containerPort: 80

    参考文档: Deployments | Kubernetes

    2、创建Service

    1. 创建一个httpd-service.yaml,在编写时需要注意以下几点:

            - spec参数中添加selector字段,指定一组label的键值对,该值在示例中为"app:httpd",和上一步创建的deployment匹配

            - Port参数中,需要指定两个端口

                    - Ports为该service的端口,客户端访问该服务时使用

                    - targetPort 为后端pod的端口,需要与之前创建的pod提供服务端口一致

    1. apiVersion: v1
    2. kind: Service #类型为service
    3. metadata:
    4. name: httpd-svc
    5. spec:
    6. selector:
    7. app: httpd #要和上一个文件标签要对上
    8. ports:
    9. - protocol: TCP
    10. port: 8080 #对应service端口
    11. targetPort: 80 #对应pod端口

    参考文档: 服务(Service) | Kubernetes

    3、整理文件并创建

    1. $ kubectl apply -f- <<EOF
    2. apiVersion: apps/v1
    3. kind: Deployment
    4. metadata:
    5. name: httpd
    6. spec:
    7. replicas: 3
    8. selector:
    9. matchLabels:
    10. app: httpd
    11. template:
    12. metadata:
    13. labels:
    14. app: httpd
    15. spec:
    16. containers:
    17. - name: httpd
    18. image: httpd
    19. ports:
    20. - containerPort: 80
    21. ---
    22. apiVersion: v1
    23. kind: Service
    24. metadata:
    25. name: httpd-svc
    26. spec:
    27. selector:
    28. app: httpd
    29. ports:
    30. - protocol: TCP
    31. port: 8080
    32. targetPort: 80
    33. EOF

    4、查看Service

    1. 查看service简明信息,可以获取service提供服务的ip地址和端口

    1. $ kubectl get deployments.apps httpd
    2. NAME READY UP-TO-DATE AVAILABLE AGE
    3. httpd 3/3 3 3 76s
    4. $ kubectl get service httpd-svc #查看service,集群类型默认就是Cluster-IP
    5. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
    6. httpd-svc ClusterIP 10.100.160.205 8080/TCP 107s
    7. $ kubectl get endpoints httpd-svc #查看后端对应IP
    8. NAME ENDPOINTS AGE
    9. httpd-svc 172.16.126.7:80,172.16.194.102:80,172.16.194.103:80 16m
    10. $ kubectl get pod -owide #列出pod所在节点,纯文本格式输出,包含所有附加信息
    11. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
    12. k8s-worker2
    13. httpd-7cd5646885-9rkwj 1/1 Running 0 32m 172.16.126.7 k8s-worker2
    14. httpd-7cd5646885-jzd5z 1/1 Running 0 32m 172.16.194.102 k8s-worker1
    15. httpd-7cd5646885-n6t7s 1/1 Running 0 32m 172.16.194.103 k8s-worker1

    2.测试service是否正常提供服务

    1. $ curl 10.100.160.205:8080
    2. It works!

    3. 使用describe命令可以查看service详细信息

    如:endpoints信息,显示service关联pod的地址和服务端口

    1. $ kubectl describe service httpd-svc
    2. Name: httpd-svc
    3. Namespace: default
    4. Labels:
    5. Annotations:
    6. Selector: app=httpd
    7. Type: ClusterIP
    8. IP Family Policy: SingleStack
    9. IP Families: IPv4
    10. IP: 10.100.160.205
    11. IPs: 10.100.160.205
    12. Port: <unset> 8080/TCP
    13. TargetPort: 80/TCP
    14. Endpoints: 172.16.126.7:80,172.16.194.102:80,172.16.194.103:80
    15. Session Affinity: None
    16. Events:

    5、创建可供外部访问的Service

    1.如果需要service可供外部进行访问,可以使用Nodeport的方式

    2.编辑Yaml文件时,添加type(类型)参数

    3.可以在使用nodeport字段指定对外服务端口,如果不进行指定,系统会自动分配空闲端口

    4.访问时通过访问 “节点IP地址:端口” 进行服务使用

    1. $ vim http_service.yml
    2. apiVersion: v1
    3. kind: Service
    4. metadata:
    5. name: httpd-svc
    6. spec:
    7. type: NodePort
    8. selector:
    9. app: httpd
    10. ports:
    11. - protocol: TCP
    12. port: 8080
    13. targetPort: 80
    14. nodePort: 30144 #指明对外节点端口,不指明时随机

    5.测试

    1. $ kubectl get service httpd-svc #查看类型已经变为NodePort,端口号也改变
    2. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
    3. httpd-svc NodePort 10.100.160.205 8080:30144/TCP 18h
    4. kiosk@k8s-master:~$ curl k8s-worker1:30144
    5. It works!

    6. kiosk@k8s-master:~$ curl k8s-worker2:30144
    7. It works!

    参考文档: 服务(Service) | Kubernetes

    三、集群中的DNS

    1、CoreDNS

    1.CoreDNS是一个轻量级的DNS服务器,通过插件的形式在Kubernetes集群内实现,提供服务发现功能,使得用户除了可以用IP访问服务外,也可用域名来访问服务

    2.从1.13版本的Kubernetes开始CoreDNS取代了原有的kubeDNS,成为了kubernetes集群内部的默认DNS组件

    1. $ kubectl get pods -n kube-system | grep dns #查看coredns的pod
    2. coredns-74586cf9b6-fcmv6 1/1 Running 13 (27h ago) 25d
    3. coredns-74586cf9b6-wfbn4 1/1 Running 13 (27h ago) 25d
    4. $ kubectl get pods -o wide -n kube-system | grep dns
    5. coredns-74586cf9b6-fcmv6 1/1 Running 13 (27h ago) 25d 172.16.235.232 k8s-master
    6. coredns-74586cf9b6-wfbn4 1/1 Running 13 (27h ago) 25d 172.16.235.234 k8s-master
    7. $ kubectl get deployments.apps -n kube-system #经过名称反推coredns为deployment创建出来
    8. NAME READY UP-TO-DATE AVAILABLE AGE
    9. calico-kube-controllers 1/1 1 1 25d
    10. coredns 2/2 2 2 25d
    11. metrics-server 1/1 1 1 23d

    2、查看服务的完整域名

    1.创建一个clientpod,用于查看httpd服务的完整名字

    2.在记录总可以看到,服务的IP地址对应的名称是httpd-svc.default.svc.cluster.local

    1. $ kubectl apply -f- <<EOF #创建一个持续运行的Pod
    2. apiVersion: v1
    3. kind: Pod
    4. metadata:
    5. name: clientpod
    6. spec:
    7. containers:
    8. - name: clientpod
    9. image: busybox:1.28.3
    10. args:
    11. - /bin/sh #指定解释器
    12. - -c
    13. - sleep 3h #睡眠时间
    14. EOF

    3.测试

    1. $ kubectl get service #查看集群IP地址
    2. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
    3. httpd-svc NodePort 10.100.160.205 8080:30144/TCP 23h
    4. kubernetes ClusterIP 10.96.0.1 443/TCP 25d #k8s自身的集群
    5. $ nslookup 10.100.160.205 #查询DNS名
    6. ** server can't find 205.160.100.10.in-addr.arpa: NXDOMAIN
    7. 无法解析,要在pod当中查,因为coredns是在集群内部
    8. $ kubectl exec -it clientpod -- /bin/sh #进入pod
    9. / # nslookup 10.100.160.205
    10. Server: 10.96.0.10 #服务器相关信息
    11. Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
    12. Name: 10.100.160.205 #地址dns对应的是谁
    13. Address 1: 10.100.160.205 httpd-svc.default.svc.cluster.local
    14. / # nslookup httpd-svc.default.svc.cluster.local #一样可以解析
    15. Server: 10.96.0.10
    16. Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
    17. Name: httpd-svc.default.svc.cluster.local
    18. Address 1: 10.100.160.205 httpd-svc.default.svc.cluster.local
    19. / # wget httpd-svc.default.svc.cluster.local:8080
    20. Connecting to httpd-svc.default.svc.cluster.local:8080 (10.100.160.205:8080)
    21. index.html 100% |**************************************************| 45 0:00:00 ETA
    22. / # cat index.html #验证可以正常工作
    23. It works!

    参考文档: 为容器设置启动时要执行的命令和参数 | Kubernetes

    3、DNS记录

    1.服务的DNS记录名称为:

            <服务名称>..svc.cluster.local

    2.服务后端的deployment中Pod的DNS记录名称为:

            .<服务名称>..svc.cluster.local

    3.ClientPod访问服务时,可以使用<服务名称>.便携抵达服务、甚至在ClientPod与服务在同一namespace时,直接使用<服务名称>进行访问

    1. / # nslookup 172.16.126.7 #反向解析,查看podIP通过谁来解析
    2. Server: 10.96.0.10
    3. Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
    4. Name: 172.16.126.7
    5. Address 1: 172.16.126.7 172-16-126-7.httpd-svc.default.svc.cluster.local

    四、Headless Service(无头服务)

    1、Headless Service

    1. 有的时候不需要或者不想要负载均衡,以及单独的Service IP,可以通过指定Cluster IP的值为“None” 来创建Headless Service
    2. 对这类Service 并不会分配Cluster IP,kube-proxy不会处理他们,并且平台也不会为他们进行负载均衡和路由
    3. 对定义了selector的Headless Service,意味着后端有一些提供业务的Pod,Endpoint控制器在API中创建了Endpoint记录,当通过域名访问服务时,流量会被直接转发到对应的Pod上

    2、创建Headless Service

    1. 创建一个简单的deployment和Headless Service。(区别多了一条clusterIP:None参数)

    1. $ kubectl apply -f- <<EOF
    2. apiVersion: apps/v1
    3. kind: Deployment
    4. metadata:
    5. name: httpd
    6. spec:
    7. replicas: 3
    8. selector:
    9. matchLabels:
    10. app: httpd
    11. template:
    12. metadata:
    13. labels:
    14. app: httpd
    15. spec:
    16. containers:
    17. - name: httpd
    18. image: httpd
    19. ports:
    20. - containerPort: 80
    21. ---
    22. apiVersion: v1
    23. kind: Service
    24. metadata:
    25. name: headless-svc
    26. spec:
    27. selector:
    28. app: httpd
    29. ports:
    30. - protocol: TCP
    31. port: 80
    32. targetPort: 80
    33. clusterIP: None
    34. EOF

    3、使用Headless Service

    1.查看Headless Service的信息,可以看到没有IP地址

    1. $ kubectl get service
    2. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
    3. headless-svc ClusterIP None 80/TCP 9s
    4. ...
    5. $ kubectl get endpoints
    6. NAME ENDPOINTS AGE
    7. headless-svc 172.16.126.7:80,172.16.194.102:80,172.16.194.103:80 2m38s
    8. ...

    2.使用的时候利用DNS功能,通过访问“Headless-svc”或“headless-svc.default”来访问服务

    观察看出,域名解析到的IP地址其实是Pod的IP地址

    1. $ kubectl exec -it clientpod -- /bin/sh
    2. / # nslookup headless-svc
    3. Server: 10.96.0.10
    4. Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
    5. Name: headless-svc #解析出了3个IP
    6. Address 1: 172.16.126.7 172-16-126-7.httpd-svc.default.svc.cluster.local
    7. Address 2: 172.16.194.102 172-16-194-102.httpd-svc.default.svc.cluster.local
    8. Address 3: 172.16.194.103 172-16-194-103.httpd-svc.default.svc.cluster.local
    9. '解析到了后端Pod的IP,通过名字访问,访问的就是后端的Pod,只是做了转发功能

  • 相关阅读:
    zeromq-01-初学
    Django的可重用HTML模板示例
    异地寄件教程分析
    基于孤立森林的信用卡欺诈 Python 实战案例,最佳参数选择、可视化等
    git init报错:‘git‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件。
    LeetCode 1822. 数组元素积的符号
    团队开发(git的使用及注意事项)
    SaaS系统平台赋能大健康产业互联网变革,助力企业提升市场占有率
    SVG标签 内path标签自适应缩放问题
    同一个线程池执行不同类型的任务
  • 原文地址:https://blog.csdn.net/qq_41619571/article/details/126934929