精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

說說 Kubernetes 是怎么實現服務發現的

云計算
我們來說說 Kubernetes 的服務發現。那么首先這個大前提是同主機通信以及跨主機通信都是 ok 的,即同一 Kubernetes 集群中各個 Pod 都是互通的。這點是由更底層的方案實現,包括 docker0/CNI 網橋、Flannel vxlan/host-gw 模式等,在此篇就不展開講了。

我們來說說 Kubernetes 的服務發現。那么首先這個大前提是同主機通信以及跨主機通信都是 ok 的,即同一 Kubernetes 集群中各個 Pod 都是互通的。這點是由更底層的方案實現,包括 docker0/CNI 網橋、Flannel vxlan/host-gw 模式等,在此篇就不展開講了。

[[422281]]

在各 Pod 都互通的前提下,我們可以通過訪問 podIP 來調用 Pod 上的資源,那么離服務發現還有多少距離呢?首先 Pod 的 IP 不是固定的,另一方面我們訪問一組 Pod 實例的時候往往會有負載均衡的需求,那么 Service 對象就是用來解決此類問題的。

集群內通信

Endpoints

Service 首先解決的是集群內通信的需求,首先我們編寫一個普通的 deployment: 

  1. apiVersion: apps/v1 
  2. kind: Deployment 
  3. metadata: 
  4. name: hostnames 
  5. spec: 
  6. selector: 
  7. matchLabels: 
  8.   app: hostnames 
  9. replicas: 3 
  10. template: 
  11. metadata: 
  12.   labels: 
  13.     app: hostnames 
  14. spec: 
  15.   containers: 
  16.     - name: hostnames 
  17.       image: mirrorgooglecontainers/serve_hostname 
  18.       ports: 
  19.         - containerPort: 9376 
  20.           protocol: TCP 

這個應用干的事兒就是訪問它是返回自己的 hostname,并且每個 Pod 都帶上了 APP 為 hostnames 的標簽。

那么我們為這些 pod 編寫一個普通的 Service: 

  1. apiVersion: v1 
  2. kind: Service 
  3. metadata: 
  4. name: hostnames 
  5. spec: 
  6. selector: 
  7. app: hostnames 
  8. ports: 
  9. namedefault 
  10.   protocol: TCP 
  11.   port: 80 
  12.   targetPort: 9376 

可以看到 Service 通過 selector 選擇 了帶相應的標簽 Pod,而這些被選中的 Pod,成為 Endpoints,我們可以試一下: 

  1. ~/cloud/k8s kubectl get ep hostnames 
  2. NAME        ENDPOINTS 
  3. hostnames   172.28.21.66:9376,172.28.29.52:9376,172.28.70.13:9376 

當某一個 Pod 出現問題,不處于 running 狀態或者 readinessProbe 未通過時,Endpoints 列表會將其摘除。

ClusterIP

以上我們有了 Service 和 Endpoints,而默認創建 Service 的類型是 ClusterIP 類型,我們查看一下之前創建的 Service: 

  1. ~ kubectl get svc hostnames 
  2. NAME        TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE 
  3. hostnames   ClusterIP   10.212.8.127   <none>        80/TCP    8m2s 

我們看到 ClusterIP 是 10.212.8.127,那么我們此時可以在 Kubernetes 集群內通過這個地址訪問到 Endpoints 列表里的任意 Pod: 

  1. sh-4.2# curl 10.212.8.127 
  2. hostnames-8548b869d7-9qk6b 
  3. sh-4.2# curl 10.212.8.127 
  4. hostnames-8548b869d7-wzksp 
  5. sh-4.2# curl 10.212.8.127 
  6. hostnames-8548b869d7-bvlw8 

訪問了三次 ClusterIP 地址,返回了三個不同的 hostname,我們意識到 ClusterIP 模式的 Service 自動對請求做了 round robin 形式的負載均衡。

對于此時 ClusterIP 模式 Serivice 來說,它有一個 A 記錄是 service-name.namespace-name.svc.cluster.local,指向 ClusterIP 地址: 

  1. sh-4.2# nslookup hostnames.coops-dev.svc.cluster.local 
  2. Server:     10.212.0.2 
  3. Address:    10.212.0.2#53 
  4.  
  5. Name:   hostnames.coops-dev.svc.cluster.local 
  6. Address: 10.212.8.127 

理所當然我們通過此 A 記錄去訪問得到的效果一樣: 

  1. sh-4.2# curl hostnames.coops-dev.svc.cluster.local 
  2. hostnames-8548b869d7-wzksp 

那對 Pod 來說它的 A 記錄是啥呢,我們可以看一下: 

  1. sh-4.2# nslookup 172.28.21.66  
  2. 66.21.28.172.in-addr.arpa name = 172-28-21-66.hostnames.coops-dev.svc.cluster.local

Headless service

Service 的 CluserIP 默認是 Kubernetes 自動分配的,當然也可以自己設置,當我們將 CluserIP 設置成 None 的時候,它就變成了 Headless service。

Headless service 一般配合 StatefulSet 使用。StatefulSet 是一種有狀態應用的容器編排方式,其核心思想是給予 Pod 指定的編號名稱,從而讓 Pod 有一個不變的唯一網絡標識碼。那這么說來,使用 CluserIP 負載均衡訪問 Pod 的方式顯然是行不通了,因為我們渴望通過某個標識直接訪問到 Pod 本身,而不是一個虛擬 vip。

這個時候我們其實可以借助 DNS,每個 Pod 都會有一條 A 記錄 pod-name.service-name.namespace-name.svc.cluster.local 指向 podIP,我們可以通過這條 A 記錄直接訪問到 Pod。

我們編寫相應的 StatefulSet 和 Service 來看一下: 

  1. --- 
  2. apiVersion: apps/v1 
  3. kind: StatefulSet 
  4. metadata: 
  5. name: hostnames 
  6. spec: 
  7. serviceName: "hostnames" 
  8. selector: 
  9. matchLabels: 
  10.   app: hostnames 
  11. replicas: 3 
  12. template: 
  13. metadata: 
  14.   labels: 
  15.     app: hostnames 
  16. spec: 
  17.   containers: 
  18.     - name: hostnames 
  19.       image: mirrorgooglecontainers/serve_hostname 
  20.       ports: 
  21.         - containerPort: 9376 
  22.           protocol: TCP 
  23.  
  24. --- 
  25. apiVersion: v1 
  26. kind: Service 
  27. metadata: 
  28. name: hostnames 
  29. spec: 
  30. selector: 
  31. app: hostnames 
  32. clusterIP: None 
  33. ports: 
  34. namedefault 
  35.   protocol: TCP 
  36.   port: 80 
  37.   targetPort: 9376 

如上,StatefulSet 和 deployment 并沒有什么不同,多了一個字段 spec.serviceName,這個字段的作用就是告訴 StatefulSet controller,在邏輯處理時使用 hostnames 這個 Service 來保證 Pod 的唯一可解析性。

當你執行 apply 之后,一會你就可以看到生成了對應的 Pod: 

  1. ~ kubectl get pods -w -l app=hostnames 
  2. NAME          READY   STATUS    RESTARTS   AGE 
  3. hostnames-0   1/1     Running   0          9m54s 
  4. hostnames-1   1/1     Running   0          9m28s 
  5. hostnames-2   1/1     Running   0          9m24s 

如意料之中,這里對 Pod 名稱進行了遞增編號,并不重復,同時這些 Pod 的創建過程也是按照編號依次串行進行的。我們知道,使用 deployment 部署的 Pod 名稱會加上 replicaSet 名稱和隨機數,重啟后是不斷變化的。而這邊使用 StatefulSet 部署的 Pod,雖然 podIP 仍然會變化,但名稱是一直不會變的,基于此我們得以通過固定的 DNS A 記錄來訪問到每個 Pod。

那么此時,我們來看一下 Pod 的 A 記錄: 

  1. sh-4.2# nslookup hostnames-0.hostnames 
  2. Server:     10.212.0.2 
  3. Address:    10.212.0.2#53 
  4.  
  5. Name:   hostnames-0.hostnames.coops-dev.svc.cluster.local 
  6. Address: 172.28.3.57 
  7.  
  8. sh-4.2# nslookup hostnames-1.hostnames 
  9. Server:     10.212.0.2 
  10. Address:    10.212.0.2#53 
  11.  
  12. Name:   hostnames-1.hostnames.coops-dev.svc.cluster.local 
  13. Address: 172.28.29.31 
  14.  
  15. sh-4.2# nslookup hostnames-2.hostnames 
  16. Server:     10.212.0.2 
  17. Address:    10.212.0.2#53 
  18.  
  19. Name:   hostnames-2.hostnames.coops-dev.svc.cluster.local 
  20. Address: 172.28.23.31 

和之前的推論一致,我們可以通過 pod-name.service-name.namespace-name.svc.cluster.local 這條 A 記錄訪問到 podIP,在同一個 namespace 中,我們可以簡化為 pod-name.service-name。

而這個時候,Service 的 A 記錄是什么呢: 

  1. sh-4.2# nslookup hostnames 
  2. Server:     10.212.0.2 
  3. Address:    10.212.0.2#53 
  4.  
  5. Name:   hostnames.coops-dev.svc.cluster.local 
  6. Address: 172.28.29.31 
  7. Name:   hostnames.coops-dev.svc.cluster.local 
  8. Address: 172.28.3.57 
  9. Name:   hostnames.coops-dev.svc.cluster.local 
  10. Address: 172.28.23.31 

原來是 Endpoints 列表里的一組 podIP,也就是說此時你依然可以通過service-name.namespace-name.svc.cluster.local這條 A 記錄來負載均衡地訪問到后端 Pod。

iptables

或多或少我們知道 Kubernetes 里面的 Service 是基于 kube-proxy 和 iptables 工作的。Service 創建之后可以被 kube-proxy 感知到,那么它會為此在宿主機上創建對應的 iptables 規則。

以 CluserIP 模式的 Service 為例,首先它會創建一條 KUBE-SERVICES 規則作為入口:

  1. -A KUBE-SERVICES -d 10.212.8.127/32 -p tcp -m comment --comment "default/hostnames: cluster IP" -m tcp --dport 80 -j KUBE-SVC-NWV5X2332I4OT4T3 

這條記錄的意思是:所有目的地址是 10.212.8.127 這條 CluserIP 的,都將跳轉到 KUBE-SVC iptables 鏈處理。

那么我們來看 KUBE-SVC 鏈都是什么: 

  1. -A KUBE-SVC-NWV5X2332I4OT4T3 -m comment --comment "default/hostnames:" -m statistic --mode random --probability 0.33332999982 -j KUBE-SEP-WNBA2IHDGP2BOBGZ 
  2. -A KUBE-SVC-NWV5X2332I4OT4T3 -m comment --comment "default/hostnames:" -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-X3P2623AGDH6CDF3 
  3. -A KUBE-SVC-NWV5X2332I4OT4T3 -m comment --comment "default/hostnames:" -j KUBE-SEP-57KPRZ3JQVENLNBR 

這組規則其實是用于負載均衡的,我們看到了--probability 依次是 1/3、1/2、1,由于 iptables 規則是自上而下匹配的,所以設置這些值能保證每條鏈匹配到的幾率一樣。處理完負載均衡的邏輯后,又分別將請求轉發到了另外三條規則,我們來看一下: 

  1. -A KUBE-SEP-57KPRZ3JQVENLNBR -s 172.28.21.66/32 -m comment --comment "default/hostnames:" -j MARK --set-xmark 0x00004000/0x00004000  
  2. -A KUBE-SEP-57KPRZ3JQVENLNBR -p tcp -m comment --comment "default/hostnames:" -m tcp -j DNAT --to-destination 172.28.21.66:9376 
  3.  
  4. -A KUBE-SEP-WNBA2IHDGP2BOBGZ -s 172.28.29.52/32 -m comment --comment "default/hostnames:" -j MARK --set-xmark 0x00004000/0x00004000  
  5. -A KUBE-SEP-WNBA2IHDGP2BOBGZ -p tcp -m comment --comment "default/hostnames:" -m tcp -j DNAT --to-destination 172.28.29.52:9376 
  6.  
  7. -A KUBE-SEP-X3P2623AGDH6CDF3 -s 172.28.70.13/32 -m comment --comment "default/hostnames:" -j MARK --set-xmark 0x00004000/0x00004000  
  8. -A KUBE-SEP-X3P2623AGDH6CDF3 -p tcp -m comment --comment "default/hostnames:" -m tcp -j DNAT --to-destination 172.28.70.13:9376 

可以看到 KUBE-SEP 鏈就是三條 DNAT 規則,并在 DNAT 之前設置了一個 0x00004000 的標志。DNAT 規則就是在 PREROUTING,即路由作用之前,將請求的目的地址和端口改為 --to-destination 指定的 podIP 和端口。這樣一來,我們起先訪問 10.212.8.127 這個 CluserIP 的請求,就會被負載均衡到各個 Pod 上。

那么 Pod 重啟了,podIP 變了怎么辦?自然是 kube-proxy 負責監聽 Pod 變化以及更新維護 iptables 規則了。

而對于 Headless service 來說,我們直接通過固定的 A 記錄訪問到了 Pod,自然不需要這些 iptables 規則了。

iptables 理解起來比較簡單,但實際上性能并不好。可以想象,當我們的 Pod 非常多時,成千上萬的 iptables 規則將被創建出來,并不斷刷新,會占用宿主機大量的 CPU 資源。一個行之有效的方案是基于 IPVS 模式的 Service,IPVS 不需要為每個 Pod 都設置 iptables 規則,而是將這些規則都放到了內核態,極大降低了維護這些規則的成本。

集群間通信

外界訪問 Service

以上我們講了請求怎么在 Kubernetes 集群內互通,主要基于 kube-dns 生成的 DNS 記錄以及 kube-proxy 維護的 iptables 規則。而這些信息都是作用在集群內的,那么自然我們從集群外訪問不到一個具體的 Service 或者 Pod 了。

Service 除了默認的 CluserIP 模式外,還提供了很多其他的模式,比如 nodePort 模式,就是用于解決該問題的。 

  1. apiVersion: v1 
  2. kind: Service 
  3. metadata: 
  4. name: hostnames 
  5. spec: 
  6. selector: 
  7. app: hostnames 
  8. type: NodePort 
  9. ports: 
  10. - nodePort: 8477 
  11.   protocol: TCP 
  12.   port: 80 
  13.   targetPort: 9376 

我們編寫了一個 NodePort 模式的 Service,并且設置 NodePort 為 8477,那么意味著我們可以通過任意一臺宿主機的 8477 端口訪問到 hostnames 這個 Service。 

  1. sh-4.2# curl 10.1.6.25:8477 
  2. hostnames-8548b869d7-j5lj9 
  3. sh-4.2# curl 10.1.6.25:8477 
  4. hostnames-8548b869d7-66vnv 
  5. sh-4.2# curl 10.1.6.25:8477 
  6. hostnames-8548b869d7-szz4f 

我們隨便找了一臺 Node 地址去訪問,得到了相同的返回配方。

那么這個時候它的 iptables 規則是怎么作用的呢:

  1. -A KUBE-NODEPORTS -p tcp -m comment --comment "default/hostnames: nodePort" -m tcp --dport 8477 -j KUBE-SVC-67RL4FN6JRUPOJYM 

kube-proxy 在每臺宿主機上都生成了如上的 iptables 規則,通過 --dport 指定了端口,訪問該端口的請求都會跳轉到 KUBE-SVC 鏈上,KUBE-SVC 鏈和之前 CluserIP Service 的配方一樣,接下來就和訪問 CluserIP Service 沒什么區別了。

不過還需要注意的是,在請求離開當前宿主機發往其他 Node 時會對其做一次 SNAT 操作:

  1. -A KUBE-POSTROUTING -m comment --comment "kubernetes service traffic requiring SNAT" -m mark --mark 0x4000/0x4000 -j MASQUERADE 

可以看到這條 postrouting 規則給即將離開主機的請求進行了一次 SNAT,判斷條件為帶有 0x4000 標志,這就是之前 DNAT 帶的標志,從而判斷請求是從 Service 轉發出來的,而不是普通請求。

需要做 SNAT 的原因很簡單,首先這是一個外部的未經 Kubernetes 處理的請求,如果它訪問 node1,node1 的負載均衡將其轉發給 node2 上的某個 Pod,這沒什么問題,而這個 Pod 處理完后直接返回給外部 client,那么外部 client 就很疑惑,明明自己訪問的是 node1,給自己返回的確是 node2,這時往往會報錯。

SNAT 的作用與 DNAT 相反,就是在請求從 node1 離開發往 node2 時,將源地址改為 node1 的地址,那么當 node2 上的 Pod 返回時,會返回給 node1,然后再讓 node1 返回給 client。 

  1. client 
  2.             | ^ 
  3.             | | 
  4.             v | 
  5. node 2 <--- node 1 
  6. | ^   SNAT 
  7. | |   ---> 
  8. v | 
  9. endpoints 

Service 還有另外 2 種通過外界訪問的方式。適用于公有云的 LoadBalancer 模式的 service,公有云 Kubernetes 會調用 CloudProvider 在公有云上為你創建一個負載均衡服務,并且把被代理的 Pod 的 IP 地址配置給負載均衡服務做后端。另外一種是 ExternalName 模式,可以通過在 spec.externalName 來指定你想要的外部訪問域名,例如 hostnames.example.com,那么你訪問該域名和訪問 service-name.namespace-name.svc.cluser.local 效果是一樣的,這時候你應該知道,其實 kube-dns 為你添加了一條 CNAME 記錄。

Ingress

Service 有一種類型叫作 LoadBalancer,不過如果每個 Service 對外都配置一個負載均衡服務,成本很高而且浪費。一般來說我們希望有一個全局的負載均衡器,通過訪問不同 url,轉發到不同 Service 上,而這就是 Ingress 的功能,Ingress 可以看做是 Service 的 Service。

Ingress 其實是對反向代理的一種抽象,相信大家已經感覺到,這玩意兒和 Nginx 十分相似,實際上 Ingress 是抽象層,而其實現層其中之一就支持 Nginx。

我們可以部署一個 nginx ingress controller:

  1. $ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/mandatory.yaml 

mandatory.yaml是官方維護的 ingress controller,我們看一下: 

  1. kind: ConfigMap 
  2. apiVersion: v1 
  3. metadata: 
  4. name: nginx-configuration 
  5. namespace: ingress-nginx 
  6. labels: 
  7. app.kubernetes.io/name: ingress-nginx 
  8. app.kubernetes.io/part-of: ingress-nginx 
  9. --- 
  10. apiVersion: extensions/v1beta1 
  11. kind: Deployment 
  12. metadata: 
  13. name: nginx-ingress-controller 
  14. namespace: ingress-nginx 
  15. labels: 
  16. app.kubernetes.io/name: ingress-nginx 
  17. app.kubernetes.io/part-of: ingress-nginx 
  18. spec: 
  19. replicas: 1 
  20. selector: 
  21. matchLabels: 
  22.   app.kubernetes.io/name: ingress-nginx 
  23.   app.kubernetes.io/part-of: ingress-nginx 
  24. template: 
  25. metadata: 
  26.   labels: 
  27.     app.kubernetes.io/name: ingress-nginx 
  28.     app.kubernetes.io/part-of: ingress-nginx 
  29.   annotations: 
  30.     ... 
  31. spec: 
  32.   serviceAccountName: nginx-ingress-serviceaccount 
  33.   containers: 
  34.     - name: nginx-ingress-controller 
  35.       image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.20.0 
  36.       args: 
  37.         - /nginx-ingress-controller 
  38.         - --configmap=$(POD_NAMESPACE)/nginx-configuration 
  39.         - --publish-service=$(POD_NAMESPACE)/ingress-nginx 
  40.         - --annotations-prefix=nginx.ingress.kubernetes.io 
  41.       securityContext: 
  42.         capabilities: 
  43.           drop
  44.             - ALL 
  45.           add
  46.             - NET_BIND_SERVICE 
  47.         # www-data -> 33 
  48.         runAsUser: 33 
  49.       env: 
  50.         - name: POD_NAME 
  51.           valueFrom: 
  52.             fieldRef: 
  53.               fieldPath: metadata.name 
  54.         - name: POD_NAMESPACE 
  55.         - name: http 
  56.           valueFrom: 
  57.             fieldRef: 
  58.               fieldPath: metadata.namespace 
  59.       ports: 
  60.         - name: http 
  61.           containerPort: 80 
  62.         - name: https 
  63.           containerPort: 443 

總的來說,我們定義了一個基于 nginx-ingress-controller 鏡像的 Pod,而這個 Pod 自身,是一個監聽 Ingress 對象及其代理后端 Service 變化的控制器。

當一個 Ingress 對象被創建時,nginx-ingress-controller 就會根據 Ingress 對象里的內容,生成一份 Nginx 配置文件(nginx.conf),并依此啟動一個 Nginx 服務。

當 Ingress 對象被更新時,nginx-ingress-controller 就會更新這個配置文件。nginx-ingress-controller 還通過 Nginx Lua 方案實現了 nginx upstream 的動態配置。

為了讓外界可以訪問到這個 Nginx,我們還得給它創建一個 Service 來把 Nginx 暴露出去:

  1. $ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/provider/baremetal/service-nodeport.yaml 

這里面的內容描述了一個 NodePort 類型的 Service: 

  1. apiVersion: v1 
  2. kind: Service 
  3. metadata: 
  4. name: ingress-nginx 
  5. namespace: ingress-nginx 
  6. labels: 
  7. app.kubernetes.io/name: ingress-nginx 
  8. app.kubernetes.io/part-of: ingress-nginx 
  9. spec: 
  10. type: NodePort 
  11. ports: 
  12. name: http 
  13.   port: 80 
  14.   targetPort: 80 
  15.   protocol: TCP 
  16. name: https 
  17.   port: 443 
  18.   targetPort: 443 
  19.   protocol: TCP 
  20. selector: 
  21. app.kubernetes.io/name: ingress-nginx 
  22. app.kubernetes.io/part-of: ingress-nginx 

可以看到這個 Service 僅僅是把 Nginx Pod 的 80/443 端口暴露出去,完了你就可以通過宿主機 IP 和 NodePort 端口訪問到 Nginx 了。

接下來我們來看 Ingress 對象一般是如何編寫的,我們可以參考一個例子。 

  1. apiVersion: extensions/v1beta1 
  2. kind: Ingress 
  3. metadata: 
  4. name: cafe-ingress 
  5. spec: 
  6. tls: 
  7. - hosts: 
  8. - cafe.example.com 
  9. secretName: cafe-secret 
  10. rules: 
  11. - host: cafe.example.com 
  12. http: 
  13.   paths: 
  14.   - path: /tea 
  15.     backend: 
  16.       serviceName: tea-svc 
  17.       servicePort: 80 
  18.   - path: /coffee 
  19.     backend: 
  20.       serviceName: coffee-svc 
  21.       servicePort: 80 

這個 Ingress 表明我們整體的域名是 cafe.example.com,希望通過 cafe.example.com/tea 訪問 tea-svc 這個 Service,通過 cafe.example.com/coffee 訪問 coffee-svc 這個 Service。這里我們通過關鍵字段 spec.rules 來編寫轉發規則。

我們可以查看到 Ingress 對象的詳細信息: 

  1. $ kubectl get ingress 
  2. NAME           HOSTS              ADDRESS   PORTS     AGE 
  3. cafe-ingress   cafe.example.com             80, 443   2h 
  4.  
  5. $ kubectl describe ingress cafe-ingress 
  6. Name:             cafe-ingress 
  7. Namespace:        default 
  8. Address: 
  9. Default backend:  default-http-backend:80 (<none>) 
  10. TLS: 
  11. cafe-secret terminates cafe.example.com 
  12. Rules: 
  13. Host              Path  Backends 
  14. ----              ----  -------- 
  15. cafe.example.com 
  16.                 /tea      tea-svc:80 (<none>) 
  17.                 /coffee   coffee-svc:80 (<none>) 
  18. Annotations: 
  19. Events: 
  20. Type    Reason  Age   From                      Message 
  21. ----    ------  ----  ----                      ------- 
  22. Normal  CREATE  4m    nginx-ingress-controller  Ingress default/cafe-ingress 

我們之前講了我們通過 NodePort 的方式將 nginx-ingress 暴露出去了,而這時候我們 Ingress 配置又希望通過 cafe.example.com 來訪問到后端 Pod,那么首先 cafe.example.com 這個域名得指到任意一臺宿主機 Ip:nodePort上,請求到達 nginx-ingress 之后再轉發到各個后端 Service 上。當然,暴露 nginx-ingress 的方式有很多種,除了 NodePort 外還包括 LoadBalancer、hostNetwork 方式等等。

我們最后來試一下請求: 

  1. $ curl cafe.example.com/coffee 
  2. Server name: coffee-7dbb5795f6-vglbv 
  3. $ curl cafe.example.com/tea 
  4. Server name: tea-7d57856c44-lwbnp 

可以看到 Nginx Ingress controller 已經為我們成功將請求轉發到了對應的后端 Service。而當請求沒有匹配到任何一條 ingress rule 的時候,理所當然我們會得到一個 404。

至此,Kubernetes 的容器網絡是怎么實現服務發現的已經講完了,而服務發現正是微服務架構中最核心的問題,解決了這個問題,那么使用 Kubernetes 來實現微服務架構也就實現了一大半。

 

責任編輯:未麗燕 來源: fredal的博客
相關推薦

2019-12-24 09:39:06

Kubernetes工具微服務

2021-11-17 09:00:00

Kubernetes集群容器

2023-11-29 16:21:30

Kubernetes服務注冊

2022-04-26 05:36:42

服務治理模式

2019-06-09 09:13:14

Istio負載均衡架構

2021-03-16 11:01:02

KubernetesCLI技術

2024-03-06 15:38:06

Spring微服務架構擴展組件

2019-07-12 14:41:31

微服務Kubernetes容器

2022-03-28 11:27:17

Kubernetes運維服務發現

2023-03-06 00:24:05

Kubernetes項目開源

2019-10-30 21:19:42

技術數據結構設計

2024-05-31 09:31:00

2018-07-30 11:53:04

Kubernetes無服務器容器

2022-02-09 07:03:01

SpringNacos服務注冊

2025-11-19 01:00:00

2022-08-14 07:04:44

微服務架構設計模式

2021-09-30 08:54:58

prometheus監控遠端服務

2025-04-08 00:00:00

@AsyncSpring異步

2009-02-17 18:52:06

網絡虛擬化路由系統數據中心

2024-09-18 13:49:42

點贊
收藏

51CTO技術棧公眾號

成年人二级毛片| 亚洲一级免费观看| 欧美女优在线| 美女性感视频久久| 国模视频一区二区| 91资源在线播放| 91精品尤物| 欧洲人成人精品| 国产一区二区三区小说| 国产精品久久久久久久龚玥菲 | 国产在线青青草| 在线观看免费黄视频| 成人性视频免费网站| 国产精品电影观看| 国产在线视频二区| 97精品一区| 亚洲人成在线观看| 亚洲精品无码一区二区| 日韩av懂色| 日本道在线观看一区二区| 免费网站永久免费观看| 在线免费观看的av网站| 91在线观看地址| 懂色一区二区三区av片| 在线免费a视频| 老司机一区二区三区| 久久99热精品这里久久精品| 久久久久人妻一区精品色| 日韩福利视频一区| 亚洲成人黄色网| 毛片毛片毛片毛片毛| 欧美色片在线观看| 色婷婷av一区二区| 日本福利视频在线| heyzo中文字幕在线| 亚洲柠檬福利资源导航| 亚洲精品国产精品国自产| 水中色av综合| 99久久免费精品| 国产精品久久久久久久久婷婷 | 亚洲第一页中文字幕| 久久精品一卡二卡| 91精品一区| 在线不卡一区二区| 色www免费视频| 成人在线高清| 欧美日韩激情一区| 中文字幕天天干| 精品肉辣文txt下载| 在线视频你懂得一区二区三区| 久久久久免费看黄a片app| 男女视频在线| 亚洲夂夂婷婷色拍ww47| 欧美久久在线观看| 亚洲精品一区二区毛豆| 国产精品国产三级国产aⅴ| 蜜臀av性久久久久蜜臀av麻豆| 国产精品久久久久不卡| 国产精品xxxxxx| 奇米影视一区二区三区小说| 国产精品伦子伦免费视频| 波多野结衣在线观看视频| 国际av在线| 精品在线亚洲视频| 91免费精品视频| 国产黄色一级大片| 亚洲精品乱码久久久久久动漫| 国产精品国产福利国产秒拍 | 久久久久网址| 九九99玖玖| 三级黄色在线视频| 国产日韩免费| 中文字幕av一区| 国产黄色网址在线观看| 日本欧美三级| 亚洲精品美女网站| 美女网站免费观看视频| 高清在线一区| 日韩三级.com| xxxx黄色片| 欧美欧美黄在线二区| 中文字幕亚洲综合久久| 希岛爱理中文字幕| 精品福利电影| 欧美在线一级va免费观看| 奴色虐av一区二区三区| 精品一区二区三区影院在线午夜 | 真人做人试看60分钟免费| xxxx视频在线| 日本乱人伦一区| 无码人妻少妇色欲av一区二区| 成人自拍在线| 这里只有精品在线观看| 久久免费在线观看视频| 奇米影视一区二区三区| 国产精品视频在线免费观看| 国产在线日本| 一区二区激情视频| 制服国产精品| 在线播放免费视频| 欧美日韩五码| 亚洲第一二三四五区| 五月天精品在线| 亚洲午夜精品久久久久久app| 国产国语刺激对白av不卡| 精品久久无码中文字幕| 国产亚洲综合av| 全黄性性激高免费视频| 免费日韩成人| 亚洲欧美日韩一区二区三区在线| 欧美日韩大片在线观看| 美女一区二区视频| 欧美精品v日韩精品v国产精品| 午夜羞羞小视频在线观看| 91精品福利在线| 国产一卡二卡三卡四卡| 久久久久久久久丰满| 国产成人精品一区二区三区| 日本xxxxwww| 亚洲精品免费播放| 污视频免费在线观看网站| 精品国内亚洲2022精品成人| 久热精品视频在线观看| 成人一二三四区| 91麻豆免费观看| 日韩av中文字幕第一页| 久久伊人精品| 日韩在线观看精品| 国产一级片毛片| aaa欧美色吧激情视频| 国产在线无码精品| 99综合久久| 日韩有码在线观看| 这里只有精品6| 中文字幕二三区不卡| 一本久道中文无码字幕av| 日韩欧美影院| 欧美性视频精品| 日本一二三区在线视频| 欧美色xxxx| 日本xxx在线播放| 国产婷婷精品| 久久久久久九九| av综合电影网站| 亚洲人成绝费网站色www| 国产www在线| 在线播放日本| 91国偷自产一区二区三区观看| 好吊日免费视频| 午夜影院日韩| 欧洲精品码一区二区三区免费看| 成人性教育av免费网址| 亚洲欧洲高清在线| 国产真人无遮挡作爱免费视频| 久久久久99精品一区| 久久综合久久色| 成人精品电影| 成人久久一区二区| 成人在线视频亚洲| 欧美大胆人体bbbb| 国产香蕉在线视频| 92国产精品观看| 18岁视频在线观看| 日韩免费久久| 亚洲影院色无极综合| 日本精品600av| 亚洲高清福利视频| 神马久久久久久久| 日韩理论片一区二区| 欧美体内she精高潮| 亚洲第一区色| 日本一区二区三区免费看| 国产一区二区色噜噜| 美女扒开尿口让男人操亚洲视频网站| 国产美女自慰在线观看| 亚洲精品精品亚洲| 超碰97在线资源站| 蜜臀av一区二区在线免费观看| 亚洲第一综合网站| 久久久久影视| 国产精品视频在线观看| av网站导航在线观看免费| 亚洲成人免费在线视频| 九九热最新视频| 亚洲精品免费一二三区| 免费看污片网站| 精品一区二区三区日韩| 极品美女扒开粉嫩小泬| 清纯唯美日韩| 国产精品一区二区三区四区五区| 欧美黑人疯狂性受xxxxx野外| zzijzzij亚洲日本成熟少妇| 日本精品久久久久久| 欧美三级电影一区| 欧美亚洲天堂网| 中文字幕一区二区三区在线不卡 | 福利视频一区| 97国产精品人人爽人人做| jizz在线观看中文| 亚洲级视频在线观看免费1级| 中文字幕一区二区久久人妻| 亚洲午夜电影在线| 日本裸体美女视频| 久久综合精品国产一区二区三区| 免费观看黄网站| 奇米影视一区二区三区| 男女激情无遮挡| 女人色偷偷aa久久天堂| 先锋在线资源一区二区三区| 精品欧美午夜寂寞影院| 91在线观看欧美日韩| 欧美理论影院| 97精品欧美一区二区三区| 精产国品自在线www| 国产亚洲一级高清| 天天色综合av| 欧美videos中文字幕| 91精品国产乱码久久| 色婷婷综合久久久中文字幕| 国产亚洲欧美久久久久| 亚洲日本在线a| 少妇愉情理伦三级| 久久精品亚洲麻豆av一区二区| 中文字幕在线国产| 国产乱淫av一区二区三区| 日本在线观看免费视频| 久久中文在线| 国产日韩一区二区在线| 99精品国产99久久久久久福利| 日本a级片在线播放| 婷婷综合激情| 在线一区亚洲| 97偷自拍亚洲综合二区| 亚洲一区二区三区精品动漫| 红桃成人av在线播放| 日本一区不卡| 成人影视亚洲图片在线| 日本公妇乱淫免费视频一区三区| 香蕉久久夜色精品国产更新时间| 精品国产乱码久久久久久郑州公司 | 青青青免费视频在线2| 欧美精品一区二区久久婷婷| а√中文在线资源库| 欧美一区二区精品久久911| 国产伦理吴梦梦伦理| 欧美精选午夜久久久乱码6080| 怡红院男人天堂| 欧美日韩dvd在线观看| 中文字幕日韩三级| 欧美日韩国产不卡| 91精品国自产| 日韩无一区二区| 亚洲精品久久久久avwww潮水| 欧美不卡视频一区| 黄色av中文字幕| 日韩精品免费在线视频| 免费福利在线观看| 中日韩美女免费视频网站在线观看 | 日韩不卡在线| 成人午夜一级二级三级| 亚洲精品a区| 久久精品综合一区| 少妇精品久久久一区二区| 亚洲精品中文字幕在线| 久久五月天小说| 免费cad大片在线观看| 在线观看日韩av电影| 免费成人午夜视频| 日本中文字幕一区二区有限公司| 日韩中文字幕a| 国产精品一二一区| www.超碰97| 日韩欧国产精品一区综合无码| 久久人人爽人人| 亚洲欧美一区二区三区| 国产精品中文久久久久久久| 电影一区二区三区久久免费观看| 国产a一区二区| 久久av网址| 400部精品国偷自产在线观看| 精品动漫3d一区二区三区免费| 男人透女人免费视频| 国产老肥熟一区二区三区| 在线视频 日韩| 国产精品视频看| 国产在线视频二区| 欧美偷拍一区二区| 人妻精品一区二区三区| 国产午夜精品全部视频在线播放 | 亚洲视频免费观看| 国产手机在线视频| 欧美日本高清视频在线观看| 人妻精品一区一区三区蜜桃91| 国产午夜精品全部视频在线播放| 日本高清在线观看| 国产精品大片wwwwww| 狠狠一区二区三区| 亚洲一区二区三区乱码 | 97国产一区二区精品久久呦| 日本精品在线中文字幕| 97se在线视频| 成人在线免费观看91| 国产手机免费视频| 久久91精品国产91久久小草| 黄色性生活一级片| 亚洲人吸女人奶水| 波多野结衣家庭主妇| 精品国产乱码久久久久久闺蜜| av大片在线看| 欧美在线一区二区三区四| 日韩视频一区二区三区四区| 少妇特黄a一区二区三区| 一本色道久久综合亚洲精品高清| 黄色小视频免费网站| 国产日产欧产精品推荐色| 日本一二三区不卡| 日韩欧美国产小视频| 日本黄色片在线观看| 国产999精品| 欧美三级午夜理伦三级小说| 欧美在线观看视频免费| 久久99国产精品久久| 五月激情四射婷婷| 色嗨嗨av一区二区三区| 视频一区二区在线播放| 97在线视频免费播放| 欧美日韩黄色| 亚洲午夜久久久| 91ts人妖另类精品系列| 91久久精品一区二区三| 日韩一二三四| 97久久精品在线| 91夜夜蜜桃臀一区二区三区| 精品少妇人妻av一区二区| 美女国产一区二区三区| 中文字幕人妻一区二区三区在线视频| 黑人精品xxx一区一二区| 亚洲精品久久久蜜桃动漫| 欧美成人精品激情在线观看| 欧美黄色一级| 久久久久久久久久久久久国产| 国产一区中文字幕| 尤物在线免费视频| 日韩欧美一二三四区| 天堂av中文在线| 国产精品久久久久久久久久久久冷 | 99久久精品99国产精品| 国产无遮挡aaa片爽爽| 亚洲第一精品久久忘忧草社区| 国产精品186在线观看在线播放| 国产成人精品自拍| 雨宫琴音一区二区在线| 亚洲熟女乱综合一区二区三区| 亚洲3atv精品一区二区三区| 色婷婷在线视频| 欧美在线视频免费| 欧美一级淫片| 中文字幕成人免费视频| 尤物视频一区二区| 欧美 日韩 国产 成人 在线| 97国产精品免费视频| 深爱激情久久| 亚洲这里只有精品| 亚洲精品成人悠悠色影视| 东京干手机福利视频| 69久久夜色精品国产7777| 国产欧美日韩精品一区二区免费 | 欧美激情一区不卡| 91精品中文字幕| 欧美精品久久久久久久免费观看 | 日韩欧美一区二区三区免费观看| 日韩理论片在线观看| 狠狠色综合日日| 日本一级黄色大片| 亚洲人午夜色婷婷| 91精品视频一区二区| av网站手机在线观看| 久久久久久久久蜜桃| 国产精品一区二区av白丝下载| 久久免费成人精品视频| 欧美猛男同性videos| 中文字幕第22页| 欧美性生活大片免费观看网址| 在线观看免费版| 国产一区二区自拍| 蜜桃精品视频在线| 国产乡下妇女做爰| 中文字幕日韩欧美在线| 91蝌蚪精品视频| 欧美日韩在线免费播放| 一区二区三区四区精品在线视频| 免费黄网站在线观看| 亚洲mm色国产网站| 久久九九国产| 免费人成视频在线| 国产一区二区三区在线视频| 亚洲精品一二三**| 亚洲成人福利在线| 欧美日韩人人澡狠狠躁视频| 五月天婷婷在线视频|