[kubernetes] Endpoint 和 Service介绍与应用

网友投稿 835 2022-10-12

本站部分文章、图片属于网络上可搜索到的公开信息,均用于学习和交流用途,不能代表睿象云的观点、立场或意见。我们接受网民的监督,如发现任何违法内容或侵犯了您的权益,请第一时间联系小编邮箱jiasou666@gmail.com 处理。

[kubernetes] Endpoint 和 Service介绍与应用

0x01 介绍

每个Pod都有独有的IP地址,而每次Pod重建后IP地址都会发生变化,那我们如何长期对一个Pod进行访问呢?答案就是Service,Servcie可以理解为一组Pod的四层代理,Service作为kubernets一种标准的资源,它可以通过节点的kube-proxy从apiserver中获取每个Pod的地址,从而实现代理功能。由下图可见,每一个Service资源都有一个endpoints,endpoints主要记录了每个pod的IP地址信息,当Pod的IP发生变化时,endpoints会进行更新。

Service常见的代理模式有两种,一种是IPVS,一种是iptables;还有比较新的cni:ebpf、nftables。本篇使用的是IPVS,启用IPVS可以通过以下方式进行设置:

1、使用kubeadm安装的集群配置

# kubectl edit configmap kube-proxy -n kube-system ... mode: “ipvs“ ...、 # kubectl delete pod kube-proxy-btz4p -n kube-system 注:1、kube-proxy配置文件以configmap方式存储 2、如果让所有节点生效,需要重建所有节点kube-proxy pod

2、二进制安装的集群配置

# vi kube-proxy-config.ymlmode: ipvsipvs:scheduler: "rr“# systemctl restart kube-proxy注:参考不同资料,文件名可能不同。

值得注意的是:当 kube-proxy 以 IPVS 代理模式启动时,它将验证 IPVS 内核模块是否可用。如果未检测到 IPVS 内核模块,则 kube-proxy 将退回到以 iptables 代理模式运行。

0x02 Service快速入门

定义一个deployment资源

[root@aliyun168-37 nginx]# cat dp.yaml apiVersion: apps/v1kind: Deploymentmetadata: name: nginx labels: app: nginx namespace: testspec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - image: nginx name: nginx ports:        - containerPort: 80

定义一个service资源

[root@aliyun168-37 nginx]# cat svc.yaml apiVersion: v1kind: Servicemetadata: name: nginx-svc namespace: testspec: selector:    app: nginx   # 选择的pod ports:  - port: 8080 # service端口 targetPort: 80 # container端口    protocol: TCP  # 协议类型

应用:

kubectl apply -f dp.yamlkubectl apply -f svc.yaml

至此一个Service资源就创建好了,Service的endpoint为labels app:nginx的pod.

查看Pod

[root@aliyun168-37 nginx]# kubectl get pod -n test -o wideNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATESnginx-7848d4b86f-mdql8 1/1 Running 0 6m45s 10.244.4.140 wokayou nginx-7848d4b86f-t5zmt 1/1 Running 0 6m45s 10.244.4.139 wokayou nginx-7848d4b86f-zt7jj 1/1 Running 0 6m45s 10.244.4.141 wokayou

查看Service

[root@aliyun168-37 nginx]# kubectl describe svc/nginx-svc -n testName: nginx-svcNamespace: testLabels: Annotations: Selector: app=nginxType: ClusterIPIP: 10.109.58.23Port:                8080/TCP  # 代理后的端口TargetPort:        80/TCP  # Container的端口Endpoints: 10.244.4.139:80,10.244.4.140:80,10.244.4.141:80Session Affinity: NoneEvents:

查看Endpoints(创建Service后会自动创建一个同名的endpoints)

[root@aliyun168-37 nginx]# kubectl get endpoints nginx-svc -n testNAME ENDPOINTS AGEnginx-svc 10.244.4.139:80,10.244.4.140:80,10.244.4.141:80 18m

访问:

查看IPVS规则:

0x03 Service类型和应用

Service支持4种类型:

ClusterIP(默认模式)NodePort:主机端口模式Headless ClusterIP:无头模式LoadBalancer:使用外部负载均衡ExternalName:将外部服务引入集群内部

0x03.1 ClusterIP

不指定Service类型时,默认类型为ClusterIP,而这个ClusterIP的地址段在安装集群的时已经配置好了,ClusterIP一般只能在集群内访问,集群外是无法访问的。

配置位置:

cat kube-controller-manager.yaml ...    - --service-cluster-ip-range=10.96.0.0/12...

ClusterIP类型使用:

[root@aliyun168-37 nginx]# cat svc.yaml apiVersion: v1kind: Servicemetadata: name: nginx-svc namespace: testspec: selector: app: nginx ports: - port: 8080 # service端口    targetPort: 80 # container Port protocol: TCP type: ClusterIP

也可以指定ClusterIP

...spec:... type: ClusterIP clusterIP: 10.100.100.100...

0x03.2 NodePort

NodePort类型的Service应用后,每个Node都会监听该端口。我们可以通过任意一个NodeIP:Port来访问。

创建一个NodePort类型的Service

...spec:... ports: - port: 80 protocol: TCP type: NodePort...

查看Service,可以看到已经将80端口映射为31321端口了

[root@aliyun168-37 nginx]# kubectl get svc -n testNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEnginx-svc NodePort 10.104.215.99 80:31321/TCP 3m23s

随便登录一台主机,查看端口监听情况

集群外访问测试:

NodePort类型的Service在不指定Port的情况下,将随机分配一个Port,而分配的访问默认为30000-32767,可以通过以下配置文件进行修改:

vim kube-apiserver.yaml增加:- --service-node-port-range=1-65535

也可以指定NodePort

...spec:... ports: - port: 80 protocol: TCP    nodePort: 1023 type: NodePort...

0x03.3 Headless ClusterIP无头服务

无头服务是一种特殊ClusterIP类型的Service,但是没有ClusterIP,只能通过域名进行访问,无头服务一般在StatfulSet中使用。

定义一个Headless ClusterIP资源

apiVersion: v1kind: Servicemetadata: name: nginx-svc namespace: testspec: selector: app: nginx ports:  - port: 80 protocol: TCP  clusterIP: "None"  # 此处定义为Node,即为Headless

查看Service

[root@aliyun168-37 nginx]# kubectl get svc -n testNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEnginx-svc ClusterIP None 80/TCP 48s

获取集群内DNS地址

解析地址,域名组成为servicename.namespace.svc.cluster.local:

[root@aliyun168-37 nginx]# nslookup nginx-svc.test.svc.cluster.local 10.96.0.10Server: 10.96.0.10Address: 10.96.0.10#53Name: nginx-svc.test.svc.cluster.localAddress: 10.244.4.140Name: nginx-svc.test.svc.cluster.localAddress: 10.244.4.141Name: nginx-svc.test.svc.cluster.localAddress: 10.244.4.139

集群内访问:

0x03.4 ExternalName 将外部流量引入集群内部

ExternalName类型的Service通过CNAME和它的值,可以将服务映射到externalName字段的内容引入外部服务到内部流量,即使用DNS CNAME机制把自己CNAME到你指定的另外一个域名上。

定义一个externalName类型Service:

[root@aliyun168-37 nginx]# cat svc3.yaml apiVersion: v1kind: Servicemetadata: name: mysql namespace: testspec: type: ExternalName externalName: mysql.51yunwei.top

pod使用mysql进行访问

0x03.5 LoadBalancer使用外部负载均衡

LoadBalancer需要使用外部Balancer(负载均衡器)来实现,我的环境无法演示。

0x04 使用endpoint代理集群外部服务

通过上面的例子,我们知道service是依靠endpoint实现的,而这个endpoint也是一种kuberntes资源,支持自定义,这就意味着我们也可以使用service实现集群外部的资源代理访问。

定义endpoints:

apiVersion: v1kind: Endpointsmetadata: name: mysql-svc namespace: testsubsets: - addresses:     - ip: 1.1.1.1 ports: - port: 3306

定义service(名字和endpoints一样就可以自动关联起来了):

apiVersion: v1kind: Servicemetadata: name: mysql-svc namespace: testspec: ports: - port: 3306 targetPort: 3306    protocol: TCP

查看:

[root@aliyun168-37 nginx]# kubectl describe svc mysql-svc -n test Name: mysql-svcNamespace: testLabels: Annotations: Selector: Type: ClusterIPIP: 10.103.36.61Port: 3306/TCPTargetPort: 3306/TCPEndpoints: 1.1.1.1:3306Session Affinity: NoneEvents: [root@aliyun168-37 nginx]#

访问:

--结束。

上一篇:win10怎么打开cmd命令窗口
下一篇:[kubernetes] POD健康检测和自愈
相关文章

 发表评论

暂时没有评论,来抢沙发吧~