Kubernetes K8S之Service服務詳解與示例
K8S之Service概述與代理說明,並詳解所有的service服務類型與示例
主機配置規劃
伺服器名稱(hostname) | 系統版本 | 配置 | 內網IP | 外網IP(模擬) |
---|---|---|---|---|
k8s-master | CentOS7.7 | 2C/4G/20G | 172.16.1.110 | 10.0.0.110 |
k8s-node01 | CentOS7.7 | 2C/4G/20G | 172.16.1.111 | 10.0.0.111 |
k8s-node02 | CentOS7.7 | 2C/4G/20G | 172.16.1.112 | 10.0.0.112 |
Service概述
Kubernetes Service定義了這樣一種抽象:邏輯上的一組 Pod,一種可以訪問它們的策略 —— 通常被稱為微服務。這一組 Pod 能夠被 Service 訪問到,通常是通過 selector實現的。
舉例:考慮一個圖片處理 backend,它運行了3個副本。這些副本是可互換的 —— frontend 不需要關心它們調用了哪個 backend 副本。 然而組成這一組 backend 程式的 Pod 實際上可能會發生變化,frontend 客戶端不應該也沒必要知道,而且也不需要跟蹤這一組 backend 的狀態。Service 定義的抽象能夠解耦這種關聯。
Service可以提供負載均衡的能力,但是使用上存在如下限制:
- 只能提供4層負載均衡能力,而沒有7層功能。有時我們可能需要更多的匹配規則來轉發請求,這點上4層負載均衡是不支援的、
如web訪問的service服務示例圖:
VIP和Service代理
在 Kubernetes 集群中,每個 Node 運行一個 kube-proxy 進程。kube-proxy 負責為 Service 實現了一種 VIP(虛擬 IP)的形式,而不是 ExternalName 的形式。
從Kubernetes v1.0開始,已經可以使用 userspace代理模式。Kubernetes v1.1添加了 iptables 代理模式,在 Kubernetes v1.2 中kube-proxy 的 iptables 模式成為默認設置。Kubernetes v1.8添加了 ipvs 代理模式。
原因如下:
- DNS 實現的歷史由來已久,它不遵守記錄 TTL,並且在名稱查找到結果後會對其進行快取。
- 有些應用程式僅執行一次 DNS 查找,並無限期地快取結果。
- 即使應用和庫進行了適當的重新解析,DNS 記錄上的 TTL 值低或為零也可能會給 DNS 帶來高負載,從而使管理變得困難。
總之就是因為有快取,因此不合適。
userspace代理模式
這種模式,kube-proxy 會監視 Kubernetes master 對 Service 對象和 Endpoints 對象的添加和移除。 對每個 Service,它會在本地 Node 上打開一個埠(隨機選擇)。 任何連接到「代理埠」的請求,都會被代理到 Service 的backend Pods 中的某個上面(如 Endpoints 所報告的一樣)。 使用哪個 backend Pod,是 kube-proxy 基於 SessionAffinity 來確定的。
最後,它配置 iptables 規則,捕獲到達該 Service 的 clusterIP(是虛擬 IP)和 Port 的請求,並重定向到代理埠,代理埠再代理請求到 backend Pod。
默認情況下,userspace模式下的kube-proxy通過循環演算法選擇後端。
默認的策略是,通過 round-robin 演算法來選擇 backend Pod。
iptables 代理模式
這種模式,kube-proxy 會監視 Kubernetes 控制節點對 Service 對象和 Endpoints 對象的添加和移除。 對每個 Service,它會配置 iptables 規則,從而捕獲到達該 Service 的 clusterIP 和埠的請求,進而將請求重定向到 Service 的一組 backend 中的某個上面。對於每個 Endpoints 對象,它也會配置 iptables 規則,這個規則會選擇一個 backend 組合。
默認的策略是,kube-proxy 在 iptables 模式下隨機選擇一個 backend。
使用 iptables 處理流量具有較低的系統開銷,因為流量由 Linux netfilter 處理,而無需在用戶空間和內核空間之間切換。 這種方法也可能更可靠。
如果 kube-proxy 在 iptables模式下運行,並且所選的第一個 Pod 沒有響應,則連接失敗。 這與userspace模式不同:在這種情況下,kube-proxy 將檢測到與第一個 Pod 的連接已失敗,並會自動使用其他後端 Pod 重試。
我們可以使用 Pod readiness 探測器 驗證後端 Pod 是否可以正常工作,以便 iptables 模式下的 kube-proxy 僅看到測試正常的後端。這樣做意味著可以避免將流量通過 kube-proxy 發送到已知已失敗的Pod。
IPVS 代理模式
在 ipvs 模式下,kube-proxy監視Kubernetes服務(Service)和端點(Endpoints),調用 netlink 介面相應地創建 IPVS 規則, 並定期將 IPVS 規則與 Kubernetes服務(Service)和端點(Endpoints)同步。該控制循環可確保 IPVS 狀態與所需狀態匹配。訪問服務(Service)時,IPVS 將流量定向到後端Pod之一。
IPVS代理模式基於類似於 iptables 模式的 netfilter 掛鉤函數,但是使用哈希表作為基礎數據結構,並且在內核空間中工作。 這意味著,與 iptables 模式下的 kube-proxy 相比,IPVS 模式下的 kube-proxy 重定向通訊的延遲要短,並且在同步代理規則時具有更好的性能。與其他代理模式相比,IPVS 模式還支援更高的網路流量吞吐量。
IPVS提供了更多選項來平衡後端Pod的流量。這些是:
- rr: round-robin
- lc: least connection (smallest number of open connections)
- dh: destination hashing
- sh: source hashing
- sed: shortest expected delay
- nq: never queue
注意:要在 IPVS 模式下運行 kube-proxy,必須在啟動 kube-proxy 之前使 IPVS Linux 在節點上可用。 當 kube-proxy 以 IPVS 代理模式啟動時,它將驗證 IPVS 內核模組是否可用。 如果未檢測到 IPVS 內核模組,則 kube-proxy 將退回到以 iptables 代理模式運行。
Service服務類型
Kubernetes 中Service有以下4中類型:
- ClusterIP:默認類型,自動分配一個僅Cluster內部可以訪問的虛擬IP
- NodePort:通過每個 Node 上的 IP 和靜態埠(NodePort)暴露服務。以ClusterIP為基礎,NodePort 服務會路由到 ClusterIP 服務。通過請求
<NodeIP>:<NodePort>
,可以從集群的外部訪問一個集群內部的 NodePort 服務。 - LoadBalancer:使用雲提供商的負載均衡器,可以向外部暴露服務。外部的負載均衡器可以路由到 NodePort 服務和 ClusterIP 服務。
- ExternalName:通過返回 CNAME 和它的值,可以將服務映射到 externalName 欄位的內容(例如,foo.bar.example.com)。沒有任何類型代理被創建。
需要注意的是:Service 能夠將一個接收 port 映射到任意的 targetPort。默認情況下,targetPort 將被設置為與 port 欄位相同的值。
Service域名格式:$(service name).$(namespace).svc.cluster.local
,其中 cluster.local 為指定的集群的域名
Deployment的yaml資訊
yaml文件
1 [root@k8s-master service]# pwd 2 /root/k8s_practice/service 3 [root@k8s-master service]# cat myapp-deploy.yaml 4 apiVersion: apps/v1 5 kind: Deployment 6 metadata: 7 name: myapp-deploy 8 namespace: default 9 spec: 10 replicas: 3 11 selector: 12 matchLabels: 13 app: myapp 14 release: v1 15 template: 16 metadata: 17 labels: 18 app: myapp 19 release: v1 20 env: test 21 spec: 22 containers: 23 - name: myapp 24 image: registry.cn-beijing.aliyuncs.com/google_registry/myapp:v1 25 imagePullPolicy: IfNotPresent 26 ports: 27 - name: http 28 containerPort: 80
啟動Deployment並查看狀態
1 [root@k8s-master service]# kubectl apply -f myapp-deploy.yaml 2 deployment.apps/myapp-deploy created 3 [root@k8s-master service]# 4 [root@k8s-master service]# kubectl get deploy -o wide 5 NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR 6 myapp-deploy 3/3 3 3 31h myapp registry.cn-beijing.aliyuncs.com/google_registry/myapp:v1 app=myapp,release=v1 7 [root@k8s-master service]# 8 [root@k8s-master service]# kubectl get rs -o wide 9 NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR 10 myapp-deploy-5695bb5658 3 3 3 31h myapp registry.cn-beijing.aliyuncs.com/google_registry/myapp:v1 app=myapp,pod-template-hash=5695bb5658,release=v1 11 [root@k8s-master service]# 12 [root@k8s-master service]# kubectl get pod -o wide --show-labels 13 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES LABELS 14 myapp-deploy-5695bb5658-2866m 1/1 Running 2 31h 10.244.2.116 k8s-node02 <none> <none> app=myapp,env=test,pod-template-hash=5695bb5658,release=v1 15 myapp-deploy-5695bb5658-dcfw7 1/1 Running 2 31h 10.244.4.105 k8s-node01 <none> <none> app=myapp,env=test,pod-template-hash=5695bb5658,release=v1 16 myapp-deploy-5695bb5658-n2b5w 1/1 Running 2 31h 10.244.2.115 k8s-node02 <none> <none> app=myapp,env=test,pod-template-hash=5695bb5658,release=v1
curl訪問
1 [root@k8s-master service]# curl 10.244.2.116 2 Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a> 3 [root@k8s-master service]# 4 [root@k8s-master service]# curl 10.244.2.116/hostname.html 5 myapp-deploy-5695bb5658-2866m 6 [root@k8s-master service]# 7 [root@k8s-master service]# curl 10.244.4.105 8 Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a> 9 [root@k8s-master service]# 10 [root@k8s-master service]# curl 10.244.4.105/hostname.html 11 myapp-deploy-5695bb5658-dcfw7 12 [root@k8s-master service]# 13 [root@k8s-master service]# curl 10.244.2.115 14 Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a> 15 [root@k8s-master service]# 16 [root@k8s-master service]# curl 10.244.2.115/hostname.html 17 myapp-deploy-5695bb5658-n2b5w
ClusterIP類型示例
yaml文件
1 [root@k8s-master service]# pwd 2 /root/k8s_practice/service 3 [root@k8s-master service]# cat myapp-svc-ClusterIP.yaml 4 apiVersion: v1 5 kind: Service 6 metadata: 7 name: myapp-clusterip 8 namespace: default 9 spec: 10 type: ClusterIP # 可以不寫,為默認類型 11 selector: 12 app: myapp 13 release: v1 14 ports: 15 - name: http 16 port: 80 17 targetPort: 80
啟動Service並查看狀態
1 [root@k8s-master service]# kubectl apply -f myapp-svc-ClusterIP.yaml 2 service/myapp-clusterip created 3 [root@k8s-master service]# 4 [root@k8s-master service]# kubectl get svc -o wide 5 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR 6 kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 22d <none> 7 myapp-clusterip ClusterIP 10.106.66.120 <none> 80/TCP 15s app=myapp,release=v1
查看pod資訊
1 [root@k8s-master service]# kubectl get pod -o wide --show-labels 2 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES LABELS 3 myapp-deploy-5695bb5658-2866m 1/1 Running 2 31h 10.244.2.116 k8s-node02 <none> <none> app=myapp,env=test,pod-template-hash=5695bb5658,release=v1 4 myapp-deploy-5695bb5658-dcfw7 1/1 Running 2 31h 10.244.4.105 k8s-node01 <none> <none> app=myapp,env=test,pod-template-hash=5695bb5658,release=v1 5 myapp-deploy-5695bb5658-n2b5w 1/1 Running 2 31h 10.244.2.115 k8s-node02 <none> <none> app=myapp,env=test,pod-template-hash=5695bb5658,release=v1
查看ipvs資訊
1 [root@k8s-master service]# ipvsadm -Ln 2 IP Virtual Server version 1.2.1 (size=4096) 3 Prot LocalAddress:Port Scheduler Flags 4 -> RemoteAddress:Port Forward Weight ActiveConn InActConn 5 ……………… 6 TCP 10.106.66.120:80 rr 7 -> 10.244.2.115:80 Masq 1 0 0 8 -> 10.244.2.116:80 Masq 1 0 0 9 -> 10.244.4.105:80 Masq 1 0 0
curl訪問
1 [root@k8s-master service]# curl 10.106.66.120 2 Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a> 3 [root@k8s-master service]# 4 [root@k8s-master service]# curl 10.106.66.120/hostname.html 5 myapp-deploy-5695bb5658-2866m 6 [root@k8s-master service]# 7 [root@k8s-master service]# curl 10.106.66.120/hostname.html 8 myapp-deploy-5695bb5658-n2b5w 9 [root@k8s-master service]# 10 [root@k8s-master service]# curl 10.106.66.120/hostname.html 11 myapp-deploy-5695bb5658-dcfw7 12 [root@k8s-master service]# 13 [root@k8s-master service]# curl 10.106.66.120/hostname.html 14 myapp-deploy-5695bb5658-2866m
備註:如果訪問失敗,請參考如下文章:
「Kubernetes K8S在IPVS代理模式下svc服務的ClusterIP類型訪問失敗處理」
Headless Services
有時不需要或不想要負載均衡,以及單獨的 Service IP。遇到這種情況,可以通過指定 Cluster IP(spec.clusterIP)的值為 「None」 來創建 Headless Service。
這對headless Service 並不會分配 Cluster IP,kube-proxy 不會處理它們,而且平台也不會為它們進行負載均衡和路由。
- 第一種:自主選擇權,有時候client想自己來決定使用哪個Real Server,可以通過查詢DNS來獲取Real Server的資訊。
- 第二種:Headless Services還有一個用處(PS:也就是我們需要的那個特性)。Headless Service對應的每一個Endpoints,即每一個Pod,都會有對應的DNS域名;這樣Pod之間就可以互相訪問。【結合statefulset有狀態服務使用,如Web、MySQL集群】
yaml文件
1 [root@k8s-master service]# pwd 2 /root/k8s_practice/service 3 [root@k8s-master service]# cat myapp-svc-headless.yaml 4 apiVersion: v1 5 kind: Service 6 metadata: 7 name: myapp-headless 8 namespace: default 9 spec: 10 selector: 11 app: myapp 12 release: v1 13 clusterIP: "None" 14 ports: 15 - port: 80 16 targetPort: 80
啟動Service並查看狀態和詳情
1 [root@k8s-master service]# kubectl apply -f myapp-svc-headless.yaml 2 service/myapp-headless created 3 [root@k8s-master service]# 4 [root@k8s-master service]# kubectl get svc -o wide 5 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR 6 kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 22d <none> 7 myapp-headless ClusterIP None <none> 80/TCP 6s app=myapp,release=v1 8 [root@k8s-master service]# 9 [root@k8s-master service]# kubectl describe svc/myapp-headless 10 Name: myapp-headless 11 Namespace: default 12 Labels: <none> 13 Annotations: kubectl.kubernetes.io/last-applied-configuration: 14 {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"myapp-headless","namespace":"default"},"spec":{"clusterIP":"None"... 15 Selector: app=myapp,release=v1 16 Type: ClusterIP 17 IP: None 18 Port: <unset> 80/TCP 19 TargetPort: 80/TCP 20 Endpoints: 10.244.2.115:80,10.244.2.116:80,10.244.4.105:80 # 後端的Pod資訊 21 Session Affinity: None 22 Events: <none>
service只要創建成功就會寫入到coredns。我們得到coredns IP的命令如下:
1 [root@k8s-master service]# kubectl get pod -o wide -A | grep 'coredns' 2 kube-system coredns-6955765f44-c9zfh 1/1 Running 29 22d 10.244.0.62 k8s-master <none> <none> 3 kube-system coredns-6955765f44-lrz5q 1/1 Running 29 22d 10.244.0.61 k8s-master <none> <none>
在宿主機安裝nslookup、dig命令安裝
yum install -y bind-utils
coredns記錄資訊如下
1 # 其中 10.244.0.61 為 coredns IP 2 # myapp-headless.default.svc.cluster.local 為Headless Service域名。格式為:$(service name).$(namespace).svc.cluster.local,其中 cluster.local 指定的集群的域名 3 [root@k8s-master service]# nslookup myapp-headless.default.svc.cluster.local 10.244.0.61 4 Server: 10.244.0.61 5 Address: 10.244.0.61#53 6 7 Name: myapp-headless.default.svc.cluster.local 8 Address: 10.244.2.116 9 Name: myapp-headless.default.svc.cluster.local 10 Address: 10.244.4.105 11 Name: myapp-headless.default.svc.cluster.local 12 Address: 10.244.2.115 13 14 [root@k8s-master service]# 15 ### 或使用如下命令 16 [root@k8s-master service]# dig -t A myapp-headless.default.svc.cluster.local. @10.244.0.61 17 18 ; <<>> DiG 9.11.4-P2-RedHat-9.11.4-16.P2.el7_8.6 <<>> -t A myapp-headless.default.svc.cluster.local. @10.244.0.61 19 ;; global options: +cmd 20 ;; Got answer: 21 ;; WARNING: .local is reserved for Multicast DNS 22 ;; You are currently testing what happens when an mDNS query is leaked to DNS 23 ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 7089 24 ;; flags: qr aa rd; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1 25 ;; WARNING: recursion requested but not available 26 27 ;; OPT PSEUDOSECTION: 28 ; EDNS: version: 0, flags:; udp: 4096 29 ;; QUESTION SECTION: 30 ;myapp-headless.default.svc.cluster.local. IN A 31 32 ;; ANSWER SECTION: 33 myapp-headless.default.svc.cluster.local. 14 IN A 10.244.2.116 34 myapp-headless.default.svc.cluster.local. 14 IN A 10.244.4.105 35 myapp-headless.default.svc.cluster.local. 14 IN A 10.244.2.115 36 37 ;; Query time: 0 msec 38 ;; SERVER: 10.244.0.61#53(10.244.0.61) 39 ;; WHEN: Wed Jun 03 22:34:46 CST 2020 40 ;; MSG SIZE rcvd: 237
NodePort類型示例
如果將 type 欄位設置為 NodePort,則 Kubernetes 控制層面將在 –service-node-port-range 標誌指定的範圍內分配埠(默認值:30000-32767)。
yaml文件
1 [root@k8s-master service]# pwd 2 /root/k8s_practice/service 3 [root@k8s-master service]# cat myapp-svc-NodePort.yaml 4 apiVersion: v1 5 kind: Service 6 metadata: 7 name: myapp-nodeport 8 namespace: default 9 spec: 10 type: NodePort 11 selector: 12 app: myapp 13 release: v1 14 ports: 15 - name: http 16 # 默認情況下,為了方便起見,`targetPort` 被設置為與 `port` 欄位相同的值。 17 port: 80 # Service對外提供服務埠 18 targetPort: 80 # 請求轉發後端Pod使用的埠 19 nodePort: 31682 # 可選欄位,默認情況下,為了方便起見,Kubernetes 控制層面會從某個範圍內分配一個埠號(默認:30000-32767)
啟動Service並查看狀態
1 [root@k8s-master service]# kubectl apply -f myapp-svc-NodePort.yaml 2 service/myapp-nodeport created 3 [root@k8s-master service]# 4 [root@k8s-master service]# kubectl get svc -o wide 5 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR 6 kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 22d <none> 7 myapp-nodeport NodePort 10.99.50.81 <none> 80:31682/TCP 6s app=myapp,release=v1
由上可見,類型變為了NodePort
查看ipvs資訊
1 [root@k8s-master service]# ipvsadm -Ln 2 IP Virtual Server version 1.2.1 (size=4096) 3 Prot LocalAddress:Port Scheduler Flags 4 -> RemoteAddress:Port Forward Weight ActiveConn InActConn 5 ……………… 6 TCP 10.99.50.81:80 rr 7 -> 10.244.2.115:80 Masq 1 0 0 8 -> 10.244.2.116:80 Masq 1 0 0 9 -> 10.244.4.105:80 Masq 1 0 0
埠查看,可見在本地宿主機監聽了相應的埠(備註:集群所有機器都監聽了該埠)
1 # 集群所有機器都可以執行查看 2 [root@k8s-master service]# netstat -lntp | grep '31682' 3 tcp6 0 0 :::31682 :::* LISTEN 3961/kube-proxy
curl通過ClusterIP訪問
1 # 通過ClusterIP訪問 2 [root@k8s-master service]# curl 10.99.50.81 3 Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a> 4 [root@k8s-master service]# 5 [root@k8s-master service]# curl 10.99.50.81/hostname.html 6 myapp-deploy-5695bb5658-2866m 7 [root@k8s-master service]# 8 [root@k8s-master service]# curl 10.99.50.81/hostname.html 9 myapp-deploy-5695bb5658-n2b5w 10 [root@k8s-master service]# 11 [root@k8s-master service]# curl 10.99.50.81/hostname.html 12 myapp-deploy-5695bb5658-dcfw7
curl通過節點IP訪問
1 # 通過集群節點IP訪問 2 [root@k8s-master service]# curl 172.16.1.110:31682 3 Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a> 4 [root@k8s-master service]# 5 [root@k8s-master service]# curl 172.16.1.110:31682/hostname.html 6 myapp-deploy-5695bb5658-2866m 7 [root@k8s-master service]# 8 [root@k8s-master service]# curl 172.16.1.110:31682/hostname.html 9 myapp-deploy-5695bb5658-n2b5w 10 [root@k8s-master service]# 11 [root@k8s-master service]# curl 172.16.1.110:31682/hostname.html 12 myapp-deploy-5695bb5658-dcfw7 13 # 訪問集群其他節點。每台機器都有LVS,和相關調度 14 [root@k8s-master service]# curl 172.16.1.111:31682/hostname.html 15 myapp-deploy-5695bb5658-dcfw7 16 [root@k8s-master service]# 17 [root@k8s-master service]# curl 172.16.1.112:31682/hostname.html 18 myapp-deploy-5695bb5658-dcfw7
訪問日誌查看
kubectl logs -f svc/myapp-nodeport
LoadBalancer類型示例
需要相關雲廠商服務支援,這裡就不表述了。
ExternalName類型示例
這種類型的Service通過返回CNAME和它的值,可以將服務映射到externalName欄位的內容(例如:my.k8s.example.com;可以實現跨namespace名稱空間訪問)。ExternalName Service是Service的特例,它沒有selector,也沒有定義任何的埠和Endpoint。相反的,對於運行在集群外部的服務,它通過返回該外部服務的別名這種方式提供服務。
具體使用參見:「Kubernetes K8S之Pod跨namespace名稱空間訪問Service服務」
yaml文件
1 [root@k8s-master service]# pwd 2 /root/k8s_practice/service 3 [root@k8s-master service]# cat myapp-svc-ExternalName.yaml 4 apiVersion: v1 5 kind: Service 6 metadata: 7 name: myapp-externalname 8 namespace: default 9 spec: 10 type: ExternalName 11 externalName: my.k8s.example.com
啟動Service並查看狀態
1 [root@k8s-master service]# kubectl apply -f myapp-svc-ExternalName.yaml 2 service/myapp-externalname created 3 [root@k8s-master service]# 4 [root@k8s-master service]# kubectl get svc -o wide 5 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR 6 kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 21d <none> 7 myapp-externalname ExternalName <none> my.k8s.example.com <none> 21s <none>
由上可見,類型變為了ExternalName
宿主機dig命令安裝
yum install -y bind-utils
coredns記錄資訊如下
1 # 其中 10.244.0.61 為 coredns IP 2 # myapp-externalname.default.svc.cluster.local 為Service域名。格式為:$(service name).$(namespace).svc.cluster.local,其中 cluster.local 指定的集群的域名 3 ##### 通過 nslookup 訪問 4 [root@k8s-master service]# nslookup myapp-externalname.default.svc.cluster.local 10.244.0.61 5 Server: 10.244.0.61 6 Address: 10.244.0.61#53 7 8 myapp-externalname.default.svc.cluster.local canonical name = my.k8s.example.com. 9 ** server can't find my.k8s.example.com: NXDOMAIN 10 11 [root@k8s-master service]# 12 ##### 通過 dig 訪問 13 [root@k8s-master service]# dig -t A myapp-externalname.default.svc.cluster.local. @10.244.0.61 14 15 ; <<>> DiG 9.11.4-P2-RedHat-9.11.4-16.P2.el7_8.6 <<>> -t A myapp-externalname.default.svc.cluster.local. @10.244.0.61 16 ;; global options: +cmd 17 ;; Got answer: 18 ;; WARNING: .local is reserved for Multicast DNS 19 ;; You are currently testing what happens when an mDNS query is leaked to DNS 20 ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 39541 21 ;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 22 ;; WARNING: recursion requested but not available 23 24 ;; OPT PSEUDOSECTION: 25 ; EDNS: version: 0, flags:; udp: 4096 26 ;; QUESTION SECTION: 27 ;myapp-externalname.default.svc.cluster.local. IN A 28 29 ;; ANSWER SECTION: 30 myapp-externalname.default.svc.cluster.local. 30 IN CNAME my.k8s.example.com. 31 32 ;; Query time: 2072 msec 33 ;; SERVER: 10.244.0.61#53(10.244.0.61) 34 ;; WHEN: Wed Jun 03 23:15:47 CST 2020 35 ;; MSG SIZE rcvd: 149
ExternalIP示例
如果外部的 IP 路由到集群中一個或多個 Node 上,Kubernetes Service 會被暴露給這些 externalIPs。通過外部 IP(作為目的 IP 地址)進入到集群,打到 Service 埠上的流量,將會被路由到 Service 的 Endpoint 上。
externalIPs 不會被 Kubernetes 管理,它屬於集群管理員的職責範疇。
根據 Service 的規定,externalIPs 可以同任意的 ServiceType 來一起指定。在下面的例子中,my-service 可以在【模擬外網IP】「10.0.0.240」(externalIP:port) 上被客戶端訪問。
yaml文件
1 [root@k8s-master service]# pwd 2 /root/k8s_practice/service 3 [root@k8s-master service]# cat myapp-svc-externalIP.yaml 4 apiVersion: v1 5 kind: Service 6 metadata: 7 name: myapp-externalip 8 namespace: default 9 spec: 10 selector: 11 app: myapp 12 release: v1 13 ports: 14 - name: http 15 port: 80 16 targetPort: 80 17 externalIPs: 18 - 10.0.0.240
啟動Service並查看狀態
1 [root@k8s-master service]# kubectl apply -f myapp-svc-externalIP.yaml 2 service/myapp-externalip created 3 [root@k8s-master service]# 4 [root@k8s-master service]# kubectl get svc -o wide 5 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR 6 kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 22d <none> 7 myapp-externalip ClusterIP 10.107.186.167 10.0.0.240 80/TCP 8s app=myapp,release=v1
查看ipvs資訊
1 [root@k8s-master service]# ipvsadm -Ln 2 IP Virtual Server version 1.2.1 (size=4096) 3 Prot LocalAddress:Port Scheduler Flags 4 -> RemoteAddress:Port Forward Weight ActiveConn InActConn 5 ……………… 6 TCP 10.107.186.167:80 rr 7 -> 10.244.2.115:80 Masq 1 0 0 8 -> 10.244.2.116:80 Masq 1 0 0 9 -> 10.244.4.105:80 Masq 1 0 0 10 ……………… 11 TCP 10.0.0.240:80 rr 12 -> 10.244.2.115:80 Masq 1 0 0 13 -> 10.244.2.116:80 Masq 1 0 0 14 -> 10.244.4.105:80 Masq 1 0 0
curl訪問,通過ClusterIP
1 [root@k8s-master service]# curl 10.107.186.167 2 Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a> 3 [root@k8s-master service]# 4 [root@k8s-master service]# curl 10.107.186.167/hostname.html 5 myapp-deploy-5695bb5658-n2b5w 6 [root@k8s-master service]# 7 [root@k8s-master service]# curl 10.107.186.167/hostname.html 8 myapp-deploy-5695bb5658-2866m 9 [root@k8s-master service]# 10 [root@k8s-master service]# curl 10.107.186.167/hostname.html 11 myapp-deploy-5695bb5658-dcfw7
curl訪問,通過ExternalIP
1 [root@k8s-master service]# curl 10.0.0.240 2 Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a> 3 [root@k8s-master service]# 4 [root@k8s-master service]# curl 10.0.0.240/hostname.html 5 myapp-deploy-5695bb5658-2866m 6 [root@k8s-master service]# 7 [root@k8s-master service]# curl 10.0.0.240/hostname.html 8 myapp-deploy-5695bb5658-dcfw7 9 [root@k8s-master service]# 10 [root@k8s-master service]# curl 10.0.0.240/hostname.html 11 myapp-deploy-5695bb5658-n2b5w
相關閱讀
1、Kubernetes K8S在IPVS代理模式下svc服務的ClusterIP類型訪問失敗處理
2、Kubernetes K8S之Pod跨namespace名稱空間訪問Service服務
3、kubernetes學習Service之headless和statefulSet結合
4、linuxea:kubernetes Headless Service無頭服務
———END———
如果覺得不錯就關注下唄 (-^O^-) !