精品欧美一区二区三区在线观看 _久久久久国色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技術棧公眾號

欧美国产中文高清| 9191在线| 亚洲男女自偷自拍| 一区二区三区高清国产| 天天操天天干天天做| 国产黄大片在线观看画质优化| 国产高清在线观看免费不卡| 66m—66摸成人免费视频| 在线观看免费黄色网址| 日本一区精品视频| 色噜噜狠狠色综合欧洲selulu| 亚洲一区二区三区四区中文| 亚洲国产精品国自产拍久久| 久久久久国内| 欧美日本亚洲视频| 熟女高潮一区二区三区| 另类视频一区二区三区| 色综合久久天天| 亚洲国产精品影视| 免费一级毛片在线观看| 国产精品一区久久久久| 日本精品性网站在线观看| 久久福利免费视频| 先锋资源av在线| 一区二区视频播放| 日韩一级欧洲| 久久久精品国产| 丝袜美腿中文字幕| eeuss国产一区二区三区四区| 色婷婷综合久久久中文一区二区 | 无码人妻精品一区二区三区不卡| 99re久久最新地址获取| 日韩精品在线免费| 国产精久久久久| 国产亚洲高清一区| 欧美三级蜜桃2在线观看| 男人靠女人免费视频网站| 亚洲欧美成人影院| 亚洲人成7777| 亚洲视频欧美在线| av资源种子在线观看| 91网站最新网址| 99re6在线| 国产视频手机在线观看| 久久99精品国产.久久久久久| 国产999精品久久久| 亚洲精品视频在线观看免费视频| 欧美激情综合| 久久精品视频va| 中文字幕91视频| 欧美日韩亚洲在线观看| 国产亚洲视频在线| 国产成人无码精品久久二区三| 久久国产精品免费精品3p| 精品伦理精品一区| 最新国产精品自拍| 国产成人一二片| 精品久久久久久亚洲综合网| 三级黄色片免费看| 国产精久久久| 日韩天堂在线观看| 免费观看一区二区三区| 第四色在线一区二区| 亚洲第一福利视频| 天天插天天射天天干| 日本欧美三级| 国产视频一区在线| 国产美女免费网站| 色999国产精品| 精品国产一区二区三区久久久狼| 日韩在线一卡二卡| 在线中文一区| 韩国福利视频一区| 天天操天天操天天操天天| 性色一区二区| 国产精品久久久久秋霞鲁丝| 国产又大又粗又硬| 丁香网亚洲国际| 国语精品免费视频| 国产高清一级毛片在线不卡| 中文字幕二三区不卡| 午夜久久久久久久久久久| 1stkiss在线漫画| 午夜av一区二区| 国产视频在线视频| 亚洲欧美在线综合| 亚洲第一偷拍网| 久久美女免费视频| 先锋资源久久| 992tv在线成人免费观看| 国产精品777777| 蜜芽一区二区三区| 国产精品久久久久久久天堂第1集| 天天射,天天干| 国产蜜臀97一区二区三区| 性做爰过程免费播放| free性欧美| 91国产精品成人| 在线观看日本www| 另类图片第一页| www.久久久久久.com| 久久精品国产av一区二区三区| 亚洲欧美日韩综合国产aⅴ| 国产精品久久久久久av福利软件| 国产区精品在线| 2021中文字幕一区亚洲| 国产精品波多野结衣| 久久男人av资源站| 51精品国自产在线| av网页在线观看| 国产精品久久久久9999赢消| 97精品视频在线| 懂色av蜜臀av粉嫩av喷吹| 国产福利一区二区| 五月天国产一区| 老色鬼在线视频| 欧美一区二区三区在线视频| 成人在线手机视频| 日韩午夜av| 1区1区3区4区产品乱码芒果精品| 国际av在线| 精品日本高清在线播放 | 久久视频免费看| 日本美女一区二区| 蜜桃成人在线| 男人天堂亚洲天堂| 51久久夜色精品国产麻豆| 人妻少妇无码精品视频区| 亚洲三级国产| 高清一区二区三区视频| www.黄在线观看| 色哟哟欧美精品| 在线观看日韩精品视频| 精久久久久久| 成人黄色片视频网站| 免费av在线播放| 欧美色老头old∨ideo| 37p粉嫩大胆色噜噜噜| 99精品国产福利在线观看免费| 亚洲自拍高清视频网站| 欧美成人三区| 欧美日本不卡视频| 精品丰满少妇一区二区三区| 久久青草久久| 欧美激情一区二区三区在线视频 | 一区二区三区成人在线视频| 九色porny自拍| 久久神马影院| 成人高h视频在线| 免费黄色网址在线观看| 欧美伦理视频网站| 夫妻性生活毛片| 精品写真视频在线观看| 宅男av一区二区三区| 91成人在线| 中文字幕日韩视频| 一区二区三区播放| 日韩理论在线观看| 中文字幕一区二区在线观看视频 | 亚洲图片小说区| 视频在线观看一区二区| 国产一区二区三区三州| 日韩美女视频一区| 女人扒开双腿让男人捅| 国产综合亚洲精品一区二| 国产成人免费观看| 国产伦理精品| 亚洲精品有码在线| 最新中文字幕免费| 日韩毛片一二三区| 性生交大片免费看l| 亚洲一级影院| 欧美xxxx黑人又粗又长精品| 久久久人成影片一区二区三区在哪下载| 在线视频精品一| 亚洲香蕉在线视频| 一区二区免费看| 黄色录像a级片| 热久久免费视频| 成人手机在线播放| 欧洲亚洲视频| 国产精品日日摸夜夜添夜夜av| 欧美激情二区| 日韩成人av在线播放| 午夜一级黄色片| 樱花影视一区二区| 久久午夜夜伦鲁鲁片| 日本不卡的三区四区五区| 性生活免费观看视频| 美女扒开腿让男人桶爽久久动漫| 日本欧美在线视频| 操你啦视频在线| 精品一区二区三区三区| 国产精品久久久久久免费免熟| 亚洲天堂精品视频| 黄色国产在线观看| 韩国欧美国产一区| 日韩av片在线看| 91精品99| 品久久久久久久久久96高清| 精品麻豆剧传媒av国产九九九| 2018日韩中文字幕| 成人黄视频在线观看| 亚洲精品在线视频| 99热这里只有精品在线| 狠狠色噜噜狠狠狠狠97| 中文字幕电影av| 国产午夜亚洲精品午夜鲁丝片| 伊人影院在线观看视频| 人人爽香蕉精品| 久久久噜噜噜www成人网| 91精品动漫在线观看| 日韩一本精品| 欧美三级午夜理伦三级小说| 91美女片黄在线观| 日韩脚交footjobhd| 欧美精品在线观看| av网站无病毒在线| 亚洲欧美日韩一区二区在线 | 日韩欧美在线观看强乱免费| 99国产精品久久一区二区三区| 国产精品视频一区二区高潮| 漫画在线观看av| 欧美日韩福利在线观看| 日本综合在线| 在线精品国产成人综合| 全部免费毛片在线播放网站| 精品久久国产老人久久综合| 一级黄色短视频| 色av一区二区| 久久久久久久久久久久久av| 亚洲五码中文字幕| 麻豆亚洲av成人无码久久精品| 国产精品高潮久久久久无| 在线观看日本中文字幕| 97se亚洲国产综合自在线| 国产乱淫av麻豆国产免费| 国产精品一二三在| www,av在线| 国产麻豆午夜三级精品| 三年中文在线观看免费大全中国| 久久精品久久99精品久久| 一区二区三区入口| 欧美aⅴ一区二区三区视频| 熟妇人妻va精品中文字幕 | 18涩涩午夜精品.www| 四虎影视1304t| 国产精品乱码人人做人人爱| 91狠狠综合久久久久久| 欧美经典三级视频一区二区三区| 实拍女处破www免费看| 久久精品人人做人人爽97 | 亚洲精品日产精品乱码不卡| 久久精品亚洲a| 亚洲男人的天堂网| 欧美成欧美va| 亚洲成人动漫精品| 天堂网av手机版| 日韩欧美在线一区| 五月激情丁香网| 欧美日韩国产高清一区二区| 国产精品国产av| 日韩欧美不卡一区| 丁香花免费高清完整在线播放| 欧美精品一区二区三区很污很色的 | 91视频网页| 99re6热只有精品免费观看| 国产伦精品一区| 亚洲丝袜美腿一区| 无码免费一区二区三区免费播放| 国产精品麻豆久久| 欧美在线观看黄| 国产亚洲一区在线| 色婷婷狠狠18| 国产精品99久久久久久有的能看 | 2024国产精品视频| 精品人伦一区二区三电影| 国产精品久久久一区麻豆最新章节| 久久福利免费视频| 午夜精品成人在线视频| 免费无码国产精品| 欧美一卡二卡三卡| 视频在线观看你懂的| 伊人激情综合网| 日本伦理一区二区| 日韩免费在线免费观看| 玖玖精品一区| 欧美精品123| 午夜激情久久| 成人av一级片| 精品一区二区在线视频| 2一3sex性hd| 中文字幕亚洲不卡| 男人的天堂一区| 88在线观看91蜜桃国自产| 香蕉av一区二区三区| 中文字幕亚洲自拍| 涩涩av在线| 成人一区二区电影| 亚洲+变态+欧美+另类+精品| 中文字幕一区二区三区精彩视频 | 免费成人高清在线视频theav| 在线国产伦理一区| 免费亚洲婷婷| 在线观看你懂的视频| 欧美国产综合一区二区| 日韩av片在线播放| 欧美日韩国产首页在线观看| 天天干天天舔天天射| 欧美精品在线免费观看| 亚洲日本在线观看视频| 国产一区二区三区四区五区在线 | 欧美一区二区激情| 免费黄网站欧美| 国产特黄级aaaaa片免| 亚洲精品日日夜夜| 一炮成瘾1v1高h| 亚洲女人天堂视频| 草草视频在线观看| 99久热re在线精品视频| 日韩精品免费一区二区在线观看 | 精品无人区卡一卡二卡三乱码免费卡| 日韩少妇一区二区| 亚洲综合视频网| 国产丝袜视频在线观看| 在线视频欧美日韩精品| 校园春色亚洲色图| 精品欧美日韩| 亚洲精品字幕| av天堂一区二区| 一区二区三区日韩精品视频| 一区二区精品视频在线观看| 一区二区三区国产视频| 欧美无毛视频| 欧美日韩天天操| 国产一区二区三区久久久久久久久 | 亚洲最新无码中文字幕久久| 国产精品一 二 三| 尹人成人综合网| 最新版天堂资源在线| 亚洲一区精品在线| 亚洲高清视频网站| 久久久久国产视频| 丁香婷婷成人| aa视频在线播放| 91在线一区二区三区| 97超碰人人干| 日韩成人在线电影网| 性欧美18~19sex高清播放| 激情伦成人综合小说| 国产日韩亚洲| 强伦人妻一区二区三区| 色综合久久精品| av在线免费观看网站| 国产精品偷伦视频免费观看国产| 色综合色综合| 久久久久久久久久毛片| 亚洲乱码一区二区三区在线观看| 精品美女www爽爽爽视频| 欧美激情久久久| 你懂的在线观看一区二区| 国产亚洲精品网站| 久久精品亚洲国产奇米99| 成人黄色免费网| 久久久av一区| 成人香蕉社区| 国产男女激情视频| 国产精品久久久久影院老司| 99久久久国产精品无码免费| 久久99国产综合精品女同| 国产一区在线电影| 麻豆传传媒久久久爱| 中文在线一区二区| www.成人精品| 日本国产精品视频| 久久影院100000精品| 欧美熟妇精品一区二区| 欧美色道久久88综合亚洲精品| 成人亚洲性情网站www在线观看| 成人网欧美在线视频| 尤物在线精品| 影音先锋制服丝袜| 日韩三级免费观看| xxx欧美xxx| 四虎永久免费网站| 97久久人人超碰| 一二三区在线播放| 久久久这里只有精品视频| 色综合中文网| 国产精品日日摸夜夜爽| 色婷婷精品久久二区二区蜜臀av| 精品美女在线观看视频在线观看| 国内一区二区在线视频观看| 免费成人小视频| 日韩精品一区二区不卡| 在线看福利67194| 嫩草国产精品入口| 午夜视频在线观| 色综合天天性综合| 青青草视频在线免费直播|