当前位置:   article > 正文

kubernetes-Service服务发现_headless svc

headless svc

目录

一、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 <none> 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 <none> <none>
  13. httpd-7cd5646885-9rkwj 1/1 Running 0 32m 172.16.126.7 k8s-worker2 <none> <none>
  14. httpd-7cd5646885-jzd5z 1/1 Running 0 32m 172.16.194.102 k8s-worker1 <none> <none>
  15. httpd-7cd5646885-n6t7s 1/1 Running 0 32m 172.16.194.103 k8s-worker1 <none> <none>

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

  1. $ curl 10.100.160.205:8080
  2. <html><body><h1>It works!</h1></body></html>

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

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

  1. $ kubectl describe service httpd-svc
  2. Name: httpd-svc
  3. Namespace: default
  4. Labels: <none>
  5. Annotations: <none>
  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: <none>

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 <none> 8080:30144/TCP 18h
  4. kiosk@k8s-master:~$ curl k8s-worker1:30144
  5. <html><body><h1>It works!</h1></body></html>
  6. kiosk@k8s-master:~$ curl k8s-worker2:30144
  7. <html><body><h1>It works!</h1></body></html>

参考文档: 服务(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 <none> <none>
  6. coredns-74586cf9b6-wfbn4 1/1 Running 13 (27h ago) 25d 172.16.235.234 k8s-master <none> <none>
  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 <none> 8080:30144/TCP 23h
  4. kubernetes ClusterIP 10.96.0.1 <none> 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. <html><body><h1>It works!</h1></body></html>

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

3、DNS记录

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

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

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

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

3.ClientPod访问服务时,可以使用<服务名称>.<namespace>便携抵达服务、甚至在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 <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,只是做了转发功能

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/685006
推荐阅读
相关标签
  

闽ICP备14008679号