如何在智能告警平台CA触发测试告警
835
2022-10-12
[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
查看Service
[root@aliyun168-37 nginx]# kubectl describe svc/nginx-svc -n testName: nginx-svcNamespace: testLabels:
查看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
随便登录一台主机,查看端口监听情况
集群外访问测试:
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
获取集群内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:
访问:
--结束。
发表评论
暂时没有评论,来抢沙发吧~