日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關咨詢
選擇下列產品馬上在線溝通
服務時間:8:30-17:00
你可能遇到了下面的問題
關閉右側工具欄

新聞中心

這里有您想知道的互聯網營銷解決方案
創(chuàng)新互聯kubernetes教程:Kubernetes使用源IP

使用源 IP

運行在 Kubernetes 集群中的應用程序通過 Service 抽象發(fā)現彼此并相互通信,它們也用 Service 與外部世界通信。 本文解釋了發(fā)送到不同類型 Service 的數據包的源 IP 會發(fā)生什么情況,以及如何根據需要切換此行為。

創(chuàng)新互聯公司長期為近1000家客戶提供的網站建設服務,團隊從業(yè)經驗10年,關注不同地域、不同群體,并針對不同對象提供差異化的產品和服務;打造開放共贏平臺,與合作伙伴共同營造健康的互聯網生態(tài)環(huán)境。為潤州企業(yè)提供專業(yè)的成都網站設計、成都做網站,潤州網站改版等技術服務。擁有十年豐富建站經驗和眾多成功案例,為您定制開發(fā)。

術語表

本文使用了下列術語:

  • NAT
  • 網絡地址轉換

  • Source NAT
  • 替換數據包上的源 IP;在本頁面中,這通常意味著替換為節(jié)點的 IP 地址

  • Destination NAT
  • 替換數據包上的目標 IP;在本頁面中,這通常意味著替換為 Pod 的 IP 地址

  • VIP
  • 一個虛擬 IP 地址,例如分配給 Kubernetes 中每個 Service 的 IP 地址

  • Kube-proxy
  • 一個網絡守護程序,在每個節(jié)點上協(xié)調 Service VIP 管理

在開始之前

你必須擁有一個 Kubernetes 的集群,同時你的 Kubernetes 集群必須帶有 kubectl 命令行工具。 建議在至少有兩個節(jié)點的集群上運行本教程,且這些節(jié)點不作為控制平面主機。 如果你還沒有集群,你可以通過 Minikube 構建一個你自己的集群,或者你可以使用下面任意一個 Kubernetes 工具構建:

  • Katacoda
  • 玩轉 Kubernetes

示例使用一個小型 nginx Web 服務器,服務器通過 HTTP 標頭返回它接收到的請求的源 IP。 你可以按如下方式創(chuàng)建它:

kubectl create deployment source-ip-app --image=K8S.gcr.io/echoserver:1.4

輸出為:

deployment.apps/source-ip-app created

教程目標

  • 通過多種類型的 Service 暴露一個簡單應用
  • 了解每種 Service 類型如何處理源 IP NAT
  • 了解保留源 IP 所涉及的權衡

Type=ClusterIP 類型 Service 的源 IP 

如果你在 iptables 模式(默認)下運行 kube-proxy,則從集群內發(fā)送到 ClusterIP 的數據包永遠不會進行源 NAT。 你可以通過在運行 kube-proxy 的節(jié)點上獲取 ?http://localhost:10249/proxyMode? 來查詢 kube-proxy 模式。

kubectl get nodes

輸出類似于:

NAME                   STATUS     ROLES    AGE     VERSION
kubernetes-node-6jst   Ready         2h      v1.13.0
kubernetes-node-cx31   Ready         2h      v1.13.0
kubernetes-node-jj1t   Ready         2h      v1.13.0

在其中一個節(jié)點上獲取代理模式(kube-proxy 監(jiān)聽 10249 端口):

# 在要查詢的節(jié)點上的 shell 中運行
curl http://localhost:10249/proxyMode

輸出為:

iptables

你可以通過在源 IP 應用程序上創(chuàng)建 Service 來測試源 IP 保留:

kubectl expose deployment source-ip-app --name=clusterip --port=80 --target-port=8080

輸出為:

service/clusterip exposed
kubectl get svc clusterip

輸出類似于:

NAME         TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE
clusterip    ClusterIP   10.0.170.92           80/TCP    51s

并從同一集群中的 Pod 中訪問 ?ClusterIP?:

kubectl run busybox -it --image=busybox:1.28 --restart=Never --rm

輸出類似于:

Waiting for pod default/busybox to be running, status is Pending, pod ready: false
If you don't see a command prompt, try pressing enter.

然后,你可以在該 Pod 中運行命令:

# 從 “kubectl run” 的終端中運行
ip addr
1: lo:  mtu 65536 qdisc noqueue
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
3: eth0:  mtu 1460 qdisc noqueue
    link/ether 0a:58:0a:f4:03:08 brd ff:ff:ff:ff:ff:ff
    inet 10.244.3.8/24 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::188a:84ff:feb0:26a5/64 scope link
       valid_lft forever preferred_lft forever

然后使用 ?wget ?查詢本地 Web 服務器:

# 將 “10.0.170.92” 替換為 Service 中名為 “clusterip” 的 IPv4 地址
wget -qO - 10.0.170.92
CLIENT VALUES:
client_address=10.244.3.8
command=GET
...

?client_address? 始終是客戶端 Pod 的 IP 地址,不管客戶端 Pod 和服務器 Pod 位于同一節(jié)點還是不同節(jié)點。

Type=NodePort 類型 Service 的源 IP

默認情況下,發(fā)送到 ?Type=NodePort? 的 Service 的數據包會經過源 NAT 處理。你可以通過創(chuàng)建一個 ?NodePort ?的 Service 來測試這點:

kubectl expose deployment source-ip-app --name=nodeport --port=80 --target-port=8080 --type=NodePort

輸出為:

service/nodeport exposed
NODEPORT=$(kubectl get -o jsonpath="{.spec.ports[0].nodePort}" services nodeport)
NODES=$(kubectl get nodes -o jsonpath='{ $.items[*].status.addresses[?(@.type=="InternalIP")].address }')

如果你在云供應商上運行,你可能需要為上面報告的 ?nodes:nodeport ?打開防火墻規(guī)則。 現在你可以嘗試通過上面分配的節(jié)點端口從集群外部訪問 Service。

for node in $NODES; do curl -s $node:$NODEPORT | grep -i client_address; done

輸出類似于:

client_address=10.180.1.1
client_address=10.240.0.5
client_address=10.240.0.3

請注意,這些并不是正確的客戶端 IP,它們是集群的內部 IP。這是所發(fā)生的事情:

  • 客戶端發(fā)送數據包到 ?node2:nodePort ?
  • ?node2 ?使用它自己的 IP 地址替換數據包的源 IP 地址(SNAT)
  • ?node2 ?將數據包上的目標 IP 替換為 Pod IP
  • 數據包被路由到 node1,然后到端點
  • Pod 的回復被路由回 node2
  • Pod 的回復被發(fā)送回給客戶端

用圖表示:

如圖。使用 SNAT 的源 IP(Type=NodePort)

為避免這種情況,Kubernetes 有一個特性可以保留客戶端源 IP。 如果將 ?service.spec.externalTrafficPolicy? 設置為 ?Local?, kube-proxy 只會將代理請求代理到本地端點,而不會將流量轉發(fā)到其他節(jié)點。 這種方法保留了原始源 IP 地址。如果沒有本地端點,則發(fā)送到該節(jié)點的數據包將被丟棄, 因此你可以在任何數據包處理規(guī)則中依賴正確的源 IP,你可能會應用一個數據包使其通過該端點。

設置 ?service.spec.externalTrafficPolicy? 字段如下:

kubectl patch svc nodeport -p '{"spec":{"externalTrafficPolicy":"Local"}}'

輸出為:

service/nodeport patched

現在,重新運行測試:

for node in $NODES; do curl --connect-timeout 1 -s $node:$NODEPORT | grep -i client_address; done

輸出類似于:

client_address=198.51.100.79

請注意,你只從運行端點 Pod 的節(jié)點得到了回復,這個回復有正確的客戶端 IP。

這是發(fā)生的事情:

  • 客戶端將數據包發(fā)送到沒有任何端點的? node2:nodePort ?
  • 數據包被丟棄
  • 客戶端發(fā)送數據包到 ?node1:nodePort?,它確實有端點
  • node1 使用正確的源 IP 地址將數據包路由到端點

用圖表示:

如圖。源 IP(Type=NodePort)保存客戶端源 IP 地址

Type=LoadBalancer 類型 Service 的 Source IP

默認情況下,發(fā)送到 ?Type=LoadBalancer? 的 Service 的數據包經過源 NAT處理,因為所有處于 ?Ready ?狀態(tài)的可調度 Kubernetes 節(jié)點對于負載均衡的流量都是符合條件的。 因此,如果數據包到達一個沒有端點的節(jié)點,系統(tǒng)會將其代理到一個帶有端點的節(jié)點,用該節(jié)點的 IP 替換數據包上的源 IP(如上一節(jié)所述)。

你可以通過負載均衡器上暴露 source-ip-app 進行測試:

kubectl expose deployment source-ip-app --name=loadbalancer --port=80 --target-port=8080 --type=LoadBalancer

輸出為:

service/loadbalancer exposed

打印 Service 的 IP 地址:

kubectl get svc loadbalancer

輸出類似于:

NAME           TYPE           CLUSTER-IP    EXTERNAL-IP       PORT(S)   AGE
loadbalancer   LoadBalancer   10.0.65.118   203.0.113.140     80/TCP    5m

接下來,發(fā)送請求到 Service 的 的外部IP(External-IP):

curl 203.0.113.140

輸出類似于:

CLIENT VALUES:
client_address=10.240.0.5
...

然而,如果你在 Google Kubernetes Engine/GCE 上運行, 將相同的 ?service.spec.externalTrafficPolicy? 字段設置為 ?Local?, 故意導致健康檢查失敗,從而強制沒有端點的節(jié)點把自己從負載均衡流量的可選節(jié)點列表中刪除。

用圖表示:

你可以通過設置注解進行測試:

kubectl patch svc loadbalancer -p '{"spec":{"externalTrafficPolicy":"Local"}}'

你應該能夠立即看到 Kubernetes 分配的 ?service.spec.healthCheckNodePort? 字段:

kubectl get svc loadbalancer -o yaml | grep -i healthCheckNodePort

輸出類似于:

  healthCheckNodePort: 32122

?service.spec.healthCheckNodePort? 字段指向每個在 ?/healthz? 路徑上提供健康檢查的節(jié)點的端口。你可以這樣測試:

kubectl get pod -o wide -l run=source-ip-app

輸出類似于:

NAME                            READY     STATUS    RESTARTS   AGE       IP             NODE
source-ip-app-826191075-qehz4   1/1       Running   0          20h       10.180.1.136   kubernetes-node-6jst

使用 ?curl ?獲取各個節(jié)點上的 ?/healthz? 端點:

# 在你選擇的節(jié)點上本地運行
curl localhost:32122/healthz
1 Service Endpoints found

在不同的節(jié)點上,你可能會得到不同的結果:

# 在你選擇的節(jié)點上本地運行
curl localhost:32122/healthz
No Service Endpoints Found

在控制平面上運行的控制器負責分配云負載均衡器。 同一個控制器還在每個節(jié)點上分配指向此端口/路徑的 HTTP 健康檢查。 等待大約 10 秒,讓 2 個沒有端點的節(jié)點健康檢查失敗,然后使用 ?curl ?查詢負載均衡器的 IPv4 地址:

curl 203.0.113.140

輸出類似于:

CLIENT VALUES:
client_address=198.51.100.79
...

跨平臺支持

只有部分云提供商為 ?Type=LoadBalancer? 的 Service 提供保存源 IP 的支持。 你正在運行的云提供商可能會以幾種不同的方式滿足對負載均衡器的請求:

  1. 使用終止客戶端連接并打開到你的節(jié)點/端點的新連接的代理。 在這種情況下,源 IP 將始終是云 LB 的源 IP,而不是客戶端的源 IP。
  2. 使用數據包轉發(fā)器,這樣客戶端發(fā)送到負載均衡器 VIP 的請求最終會到達具有客戶端源 IP 的節(jié)點,而不是中間代理。

第一類負載均衡器必須使用負載均衡器和后端之間商定的協(xié)議來傳達真實的客戶端 IP, 例如 HTTP 轉發(fā)或 X-FORWARDED-FOR 表頭,或代理協(xié)議。 第二類負載均衡器可以通過創(chuàng)建指向存儲在 Service 上的 ?service.spec.healthCheckNodePort? 字段中的端口的 HTTP 健康檢查來利用上述功能。

清理

刪除 Service:

$ kubectl delete svc -l app=source-ip-app

刪除 Deployment、ReplicaSet 和 Pod:

$ kubectl delete deployment source-ip-app

本文題目:創(chuàng)新互聯kubernetes教程:Kubernetes使用源IP
URL地址:http://www.5511xx.com/article/cdsieoe.html