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是否正常提供服务

  1. 使用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

2.解决pod进行如此多变化时的解决方案
一组pod对应一个服务,通过服务访问后端

2、Service 1. Kubernetes Service 定义了这样一种抽象:
逻辑上的一组Pod,一种可以访问它们的策略 — — 通常称为微服务。

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

3、Service模型
每个节点都有一个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
集群内部的Client可以访问服务IP,通过服务IP可以找到集群内部的Pod

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

Service基数 1 5,000 20,000
Rules基数 8 40,000 160,000
增加1条iptables规则 50us 11min 5hour
增加1条ipvs规则 30us 50us 70us
二、服务发现 1、创建后端Deployment

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

     - Template 选项必须配置labels,示例中配置参数为“app:httpd”,该配置和service匹配
    
     - Pod的属性中Ports选项指定pod对外提供服务的容器端口,图例中为"containerPort:80",该端口需要和service匹配
    

apiVersion: apps/v1 #版本
kind: Deployment
metadata: #元数据
name: httpd
spec: #描述
replicas: 3 #三副本
selector: #选择器
matchLabels: #匹配标签
app: httpd
template: #模板
metadata: #模板元数据
labels: #模板标签
app: httpd
spec: #针对template的描述
containers: #容器
- name: httpd
image: httpd
ports:
- containerPort: 80
参考文档: Deployments | Kubernetes

2、创建Service

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

     - spec参数中添加selector字段,指定一组label的键值对,该值在示例中为"app:httpd",和上一步创建的deployment匹配
    
     - Port参数中,需要指定两个端口
    
             - Ports为该service的端口,客户端访问该服务时使用
    
             - targetPort 为后端pod的端口,需要与之前创建的pod提供服务端口一致
    

apiVersion: v1
kind: Service #类型为service
metadata:
name: httpd-svc
spec:
selector:
app: httpd #要和上一个文件标签要对上
ports:
- protocol: TCP
port: 8080 #对应service端口
targetPort: 80 #对应pod端口
参考文档: 服务(Service) | Kubernetes

3、整理文件并创建
$ kubectl apply -f- <<eof apiversion:=“” apps=“” v1=“” kind:=“” deployment=“” metadata:=“” name:=“” httpd=“” spec:=“” replicas:=“” 3=“” selector:=“” matchlabels:=“” app:=“” template:=“” labels:=“” containers:=“” -=“” image:=“” ports:=“” containerport:=“” 80=“” —=“” service=“” httpd-svc=“” protocol:=“” tcp=“” port:=“” 8080=“” targetport:=“” eof<=“” pre=“”>

4、查看Service 1. 查看service简明信息,可以获取service提供服务的ip地址和端口
$ kubectl get deployments.apps httpd
NAME READY UP-TO-DATE AVAILABLE AGE
httpd 3/3 3 3 76s

$ kubectl get service httpd-svc #查看service,集群类型默认就是Cluster-IP
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
httpd-svc ClusterIP 10.100.160.205 8080/TCP 107s

$ kubectl get endpoints httpd-svc #查看后端对应IP
NAME ENDPOINTS AGE
httpd-svc 172.16.126.7:80,172.16.194.102:80,172.16.194.103:80 16m

$ kubectl get pod -owide #列出pod所在节点,纯文本格式输出,包含所有附加信息
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
k8s-worker2
httpd-7cd5646885-9rkwj 1/1 Running 0 32m 172.16.126.7 k8s-worker2
httpd-7cd5646885-jzd5z 1/1 Running 0 32m 172.16.194.102 k8s-worker1
httpd-7cd5646885-n6t7s 1/1 Running 0 32m 172.16.194.103 k8s-worker1
2.测试service是否正常提供服务
$ curl 10.100.160.205:8080
It works!
3. 使用describe命令可以查看service详细信息
如:endpoints信息,显示service关联pod的地址和服务端口

$ kubectl describe service httpd-svc
Name: httpd-svc
Namespace: default
Labels:
Annotations:
Selector: app=httpd
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.100.160.205
IPs: 10.100.160.205
Port: 8080/TCP
TargetPort: 80/TCP
Endpoints: 172.16.126.7:80,172.16.194.102:80,172.16.194.103:80
Session Affinity: None
Events:
5、创建可供外部访问的Service
1.如果需要service可供外部进行访问,可以使用Nodeport的方式

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

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

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

$ vim http_service.yml
apiVersion: v1
kind: Service
metadata:
name: httpd-svc
spec:
type: NodePort
selector:
app: httpd
ports:
- protocol: TCP
port: 8080
targetPort: 80
nodePort: 30144 #指明对外节点端口,不指明时随机
5.测试

$ kubectl get service httpd-svc #查看类型已经变为NodePort,端口号也改变
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
httpd-svc NodePort 10.100.160.205 8080:30144/TCP 18h

kiosk@k8s-master:~$ curl k8s-worker1:30144
It works!

kiosk@k8s-master:~$ curl k8s-worker2:30144
It works!
参考文档: 服务(Service) | Kubernetes

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

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

$ kubectl get pods -n kube-system | grep dns #查看coredns的pod
coredns-74586cf9b6-fcmv6 1/1 Running 13 (27h ago) 25d
coredns-74586cf9b6-wfbn4 1/1 Running 13 (27h ago) 25d

$ kubectl get pods -o wide -n kube-system | grep dns
coredns-74586cf9b6-fcmv6 1/1 Running 13 (27h ago) 25d 172.16.235.232 k8s-master
coredns-74586cf9b6-wfbn4 1/1 Running 13 (27h ago) 25d 172.16.235.234 k8s-master

$ kubectl get deployments.apps -n kube-system #经过名称反推coredns为deployment创建出来
NAME READY UP-TO-DATE AVAILABLE AGE
calico-kube-controllers 1/1 1 1 25d
coredns 2/2 2 2 25d
metrics-server 1/1 1 1 23d
2、查看服务的完整域名
1.创建一个clientpod,用于查看httpd服务的完整名字

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

$ kubectl apply -f- <<eof #创建一个持续运行的pod=“” apiversion:=“” v1=“” kind:=“” pod=“” metadata:=“” name:=“” clientpod=“” spec:=“” containers:=“” -=“” image:=“” busybox:1.28.3=“” args:=“” bin=“” sh=“” #指定解释器=“” -c=“” sleep=“” 3h=“” #睡眠时间=“” eof<=“” pre=“”>

3.测试

$ kubectl get service    #查看集群IP地址
NAME            TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
httpd-svc       NodePort    10.100.160.205           8080:30144/TCP   23h
kubernetes      ClusterIP   10.96.0.1                443/TCP          25d #k8s自身的集群

$ nslookup 10.100.160.205 #查询DNS名
** server can’t find 205.160.100.10.in-addr.arpa: NXDOMAIN
无法解析,要在pod当中查,因为coredns是在集群内部

$ kubectl exec -it clientpod – /bin/sh #进入pod
/ # nslookup 10.100.160.205
Server: 10.96.0.10 #服务器相关信息
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name: 10.100.160.205 #地址dns对应的是谁
Address 1: 10.100.160.205 httpd-svc.default.svc.cluster.local

/ # nslookup httpd-svc.default.svc.cluster.local #一样可以解析
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name: httpd-svc.default.svc.cluster.local
Address 1: 10.100.160.205 httpd-svc.default.svc.cluster.local

/ # wget httpd-svc.default.svc.cluster.local:8080
Connecting to httpd-svc.default.svc.cluster.local:8080 (10.100.160.205:8080)
index.html 100% |**************************************************| 45 0:00:00 ETA
/ # cat index.html #验证可以正常工作
It works!

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

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

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

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

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

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

/ # nslookup 172.16.126.7 #反向解析,查看podIP通过谁来解析
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name: 172.16.126.7
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
  4. 创建一个简单的deployment和Headless Service。(区别多了一条clusterIP:None参数)

$ kubectl apply -f- <<eof apiversion:=“” apps=“” v1=“” kind:=“” deployment=“” metadata:=“” name:=“” httpd=“” spec:=“” replicas:=“” 3=“” selector:=“” matchlabels:=“” app:=“” template:=“” labels:=“” containers:=“” -=“” image:=“” ports:=“” containerport:=“” 80=“” —=“” service=“” headless-svc=“” protocol:=“” tcp=“” port:=“” targetport:=“” clusterip:=“” none=“” eof<=“” pre=“”>

3、使用Headless Service 1.查看Headless Service的信息,可以看到没有IP地址
$ kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
headless-svc ClusterIP None 80/TCP 9s

$ kubectl get endpoints
NAME ENDPOINTS AGE
headless-svc 172.16.126.7:80,172.16.194.102:80,172.16.194.103:80 2m38s


2.使用的时候利用DNS功能,通过访问“Headless-svc”或“headless-svc.default”来访问服务
观察看出,域名解析到的IP地址其实是Pod的IP地址

$ kubectl exec -it clientpod – /bin/sh
/ # nslookup headless-svc
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name: headless-svc #解析出了3个IP
Address 1: 172.16.126.7 172-16-126-7.httpd-svc.default.svc.cluster.local
Address 2: 172.16.194.102 172-16-194-102.httpd-svc.default.svc.cluster.local
Address 3: 172.16.194.103 172-16-194-103.httpd-svc.default.svc.cluster.local
'解析到了后端Pod的IP,通过名字访问,访问的就是后端的Pod,只是做了转发功能

文章转自:kubernetes-Service服务发现_Java-答学网

作者:答学网,转载请注明原文链接:http://www.dxzl8.com/

猜你喜欢

转载自blog.csdn.net/zl5186888/article/details/126987579