注:本文整理自網絡
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上的能力
kubernetes發布tomcat服務,通過deployment,service布署
service及deployment的yaml文件
[root@k8s-master ~]# pwd /root [root@k8s-master ~]# cat deployment-hello.yaml apiVersion: extensions/v1beta1 kind: Deployment metadata: name: hello spec: 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: v1 kind: Service metadata: name: service-hello labels: name: service-hello spec: 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 services NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 4h24m service-hello NodePort 10.98.166.242 <none> 80:31111/TCP 42s [root@k8s-master ~]# root@k8s-master ~]# kubectl get services -o wide NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 4h25m <none> service-hello NodePort 10.98.166.242 <none> 80:31111/TCP 104s run=hello [root@k8s-master ~]# kubectl describe service service-hello Name: service-hello Namespace: default Labels: <none> Annotations: <none> Selector: run=hello Type: NodePort IP: 10.98.166.242 Port: <unset> 80/TCP TargetPort: 8080/TCP NodePort: <unset> 31111/TCP Endpoints: 10.244.1.22:8080,10.244.1.23:8080,10.244.1.24:8080 + 1 more... Session Affinity: None External Traffic Policy: Cluster Events: <none> [root@k8s-master ~]#
endpoints
[root@k8s-master ~]# kubectl get endpoints NAME ENDPOINTS AGE kubernetes 192.168.111.130:6443 20h service-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-hello error: the server doesn't have a resource type "endpoint" [root@k8s-master ~]# kubectl describe endpoints service-hello Name: service-hello Namespace: default Labels: <none> Annotations: endpoints.kubernetes.io/last-change-trigger-time: 2019-04-03T02:18:57Z Subsets: Addresses: 10.244.1.22,10.244.1.23,10.244.1.24,10.244.1.25 NotReadyAddresses: <none> Ports: Name Port Protocol ---- ---- -------- <unset> 8080 TCP Events: 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 ~]#