注:本文整理自网络
endpoint
endpoint是k8s集群中的一个资源对象,存储在etcd中,用来记录一个service对应的所有pod的访问地址。service配置selector,endpoint controller才会自动创建对应的endpoint对象;否则,不会生成endpoint对象.
例如,k8s集群中创建一个名为hello的service,就会生成一个同名的endpoint对象,ENDPOINTS就是service关联的pod的ip地址和端口。
一个 Service 由一组 backend Pod 组成。这些 Pod 通过 endpoints
暴露出来。 Service Selector 将持续评估,结果被 POST 到一个名称为 Service-hello 的 Endpoint 对象上。 当 Pod 终止后,它会自动从 Endpoint 中移除,新的能够匹配上 Service Selector 的 Pod 将自动地被添加到 Endpoint 中。 检查该 Endpoint,注意到 IP 地址与创建的 Pod 是相同的。现在,能够从集群中任意节点上使用 curl 命令请求 hello Service <CLUSTER-IP>:<PORT>
。 注意 Service IP 完全是虚拟的,它从来没有走过网络,如果对它如何工作的原理感到好奇,可以阅读更多关于 的内容。
Endpoints是实现实际服务的端点集合。
Kubernetes在创建Service时,根据Service的标签选择器(Label Selector)来查找Pod,据此创建与Service同名的EndPoints对象。当Pod的地址发生变化时,EndPoints也随之变化。Service接收到请求时,就能通过EndPoints找到请求转发的目标地址。
Service不仅可以代理Pod,还可以代理任意其他后端,比如运行在Kubernetes外部Mysql、Oracle等。这是通过定义两个同名的service和endPoints来实现的。
在实际的生产环境使用中,通过分布式存储来实现的磁盘在mysql这种IO密集性应用中,性能问题会显得非常突出。所以在实际应用中,一般不会把mysql这种应用直接放入kubernetes中管理,而是使用专用的服务器来独立部署。而像web这种无状态应用依然会运行在kubernetes当中,这个时候web服务器要连接kubernetes管理之外的数据库,有两种方式:一是直接连接数据库所在物理服务器IP,另一种方式就是借助kubernetes的Endpoints直接将外部服务器映射为kubernetes内部的一个服务。
简单认为:动态存储pod名字与pod ip对应关系的list,并提供将请求转发到实际pod上的能力
service及deployment的yaml文件
[root@k8s-master ~]# pwd/root[root@k8s-master ~]# cat deployment-hello.yaml apiVersion: extensions/v1beta1kind: Deploymentmetadata: name: hellospec: replicas: 4 template: metadata: labels: run: hello spec: containers: - name: hello image: tomcat:8 #确保node节点上有该镜像且可正常运行,注意是node节点机器上,不是master机器 imagePullPolicy: IfNotPresent ##Always,IfNotPresent,Never ports: - name: http containerPort: 8080
[root@k8s-master ~]# cat service-hello.yaml apiVersion: v1kind: Servicemetadata: name: service-hello labels: name: service-hellospec: type: NodePort #这里代表是NodePort类型的,另外还有ingress,LoadBalancer ports: - port: 80 #这里的端口和clusterIP(kubectl describe service service-hello中的IP的port)对应,即在集群中所有机器上curl 10.98.166.242:80可访问发布的应用服务。 targetPort: 8080 #端口一定要和container暴露出来的端口对应,nodejs暴露出来的端口是8081,所以这里也应是8081 protocol: TCP nodePort: 31111 # 所有的节点都会开放此端口30000--32767,此端口供外部调用。 selector: run: hello #这里选择器一定要选择容器的标签,之前写name:kube-node是错的。[root@k8s-master ~]# pwd/root[root@k8s-master ~]#
创建service
[root@k8s-master ~]# kubectl create -f service-hello.yaml service/service-hello created[root@k8s-master ~]# kubectl get servicesNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEkubernetes ClusterIP 10.96.0.1443/TCP 4h24mservice-hello NodePort 10.98.166.242 80:31111/TCP 42s[root@k8s-master ~]#root@k8s-master ~]# kubectl get services -o wideNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTORkubernetes ClusterIP 10.96.0.1 443/TCP 4h25m service-hello NodePort 10.98.166.242 80:31111/TCP 104s run=hello[root@k8s-master ~]# kubectl describe service service-helloName: service-helloNamespace: defaultLabels: Annotations: Selector: run=helloType: NodePortIP: 10.98.166.242Port: 80/TCPTargetPort: 8080/TCPNodePort: 31111/TCPEndpoints: 10.244.1.22:8080,10.244.1.23:8080,10.244.1.24:8080 + 1 more...Session Affinity: NoneExternal Traffic Policy: ClusterEvents: [root@k8s-master ~]#
[root@k8s-master ~]# kubectl get endpointsNAME ENDPOINTS AGEkubernetes 192.168.111.130:6443 20hservice-hello 10.244.1.22:8080,10.244.1.23:8080,10.244.1.24:8080 + 1 more... 15h[root@k8s-master ~]# kubectl describe endpoint service-helloerror: the server doesn't have a resource type "endpoint"[root@k8s-master ~]# kubectl describe endpoints service-helloName: service-helloNamespace: defaultLabels:Annotations: endpoints.kubernetes.io/last-change-trigger-time: 2019-04-03T02:18:57ZSubsets: Addresses: 10.244.1.22,10.244.1.23,10.244.1.24,10.244.1.25 NotReadyAddresses: Ports: Name Port Protocol ---- ---- -------- 8080 TCPEvents: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedToUpdateEndpoint 48m (x2 over 69m) endpoint-controller Failed to update endpoint default/service-hello: Operation cannot be fulfilled on endpoints "service-hello": the object has been modified; please apply your changes to the latest version and try again[root@k8s-master ~]#