主頁 > 作業系統 > Kubernetes K8S之Service服務詳解與示例

Kubernetes K8S之Service服務詳解與示例

2020-09-17 01:54:02 作業系統

 

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 輪詢?

原因如下:

  • 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=https://www.cnblogs.com/zhanglianghhh/p/"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=https://www.cnblogs.com/zhanglianghhh/p/"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=https://www.cnblogs.com/zhanglianghhh/p/"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=https://www.cnblogs.com/zhanglianghhh/p/"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=https://www.cnblogs.com/zhanglianghhh/p/"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=https://www.cnblogs.com/zhanglianghhh/p/"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=https://www.cnblogs.com/zhanglianghhh/p/"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=https://www.cnblogs.com/zhanglianghhh/p/"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^-) !

 

轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/60919.html

標籤:Linux

上一篇:分布式檔案系統之MogileFS的安裝使用

下一篇:適合基于 x64 的系統 (KB4512508) - 錯誤 0x800f0

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • CA和證書

    1、在 CentOS7 中使用 gpg 創建 RSA 非對稱密鑰對 gpg --gen-key #Centos上生成公鑰/密鑰對(存放在家目錄.gnupg/) 2、將 CentOS7 匯出的公鑰,拷貝到 CentOS8 中,在 CentOS8 中使用 CentOS7 的公鑰加密一個檔案 gpg -a ......

    uj5u.com 2020-09-10 00:09:53 more
  • Kubernetes K8S之資源控制器Job和CronJob詳解

    Kubernetes的資源控制器Job和CronJob詳解與示例 ......

    uj5u.com 2020-09-10 00:10:45 more
  • VMware下安裝CentOS

    VMware下安裝CentOS 一、軟硬體準備 1 Centos鏡像準備 1.1 CentOS鏡像下載地址 下載地址 1.2 CentOS鏡像下載程序 點擊下載地址進入如下圖的網站,選擇需要下載的版本,這里選擇的是Centos8,點擊如圖所示。 決定選擇Centos8后,選擇想要的鏡像源進行下載,此 ......

    uj5u.com 2020-09-10 00:12:10 more
  • 如何使用Grep命令查找多個字串

    如何使用Grep 命令查找多個字串 大家好,我是良許! 今天向大家介紹一個非常有用的技巧,那就是使用 grep 命令查找多個字串。 簡單介紹一下,grep 命令可以理解為是一個功能強大的命令列工具,可以用它在一個或多個輸入檔案中搜索與正則運算式相匹配的文本,然后再將每個匹配的文本用標準輸出的格式 ......

    uj5u.com 2020-09-10 00:12:28 more
  • git配置http代理

    git配置http代理 經常遇到克隆 github 慢的問題,這里記錄一下幾種配置 git 代理的方法,解決 clone github 過慢。 目錄 git配置代理 git單獨配置github代理 git配置全域代理 配置終端環境變數 git配置代理 主要使用 git config 命令 git單獨 ......

    uj5u.com 2020-09-10 00:12:33 more
  • Linux npm install 裝包時提示Error EACCES permission denied解

    npm install 裝包時提示Error EACCES permission denied解決辦法 ......

    uj5u.com 2020-09-10 00:12:53 more
  • Centos 7下安裝nginx,使用yum install nginx,提示沒有可用的軟體包

    Centos 7下安裝nginx,使用yum install nginx,提示沒有可用的軟體包。 18 (flaskApi) [root@67 flaskDemo]# yum -y install nginx 19 已加載插件:fastestmirror, langpacks 20 Loading ......

    uj5u.com 2020-09-10 00:13:13 more
  • Linux查看服務器暴力破解ssh IP

    在公網的服務器上經常遇到別人爆破你服務器的22埠,用來挖礦或者干其他嘿嘿嘿的事情~ 這種情況下正確的做法是: 修改默認ssh的22埠 使用設定密鑰登錄或者白名單ip登錄 建議服務器密碼為復雜密碼 創建普通用戶登錄服務器(root權限過大) 建立堡壘機,實作統一管理服務器 統計爆破IP [root ......

    uj5u.com 2020-09-10 00:13:17 more
  • CentOS 7系統常見快捷鍵操作方式

    Linux系統中一些常見的快捷方式,可有效提高操作效率,在某些時刻也能避免操作失誤帶來的問題。 ......

    uj5u.com 2020-09-10 00:13:31 more
  • CentOS 7作業系統目錄結構介紹

    作業系統存在著大量的資料檔案資訊,相應檔案資訊會存在于系統相應目錄中,為了更好的管理資料資訊,會將系統進行一些目錄規劃,不同目錄存放不同的資源。 ......

    uj5u.com 2020-09-10 00:13:35 more
最新发布
  • vim的常用命令

    Vim的6種基本模式 1. 普通模式在普通模式中,用的編輯器命令,比如移動游標,洗掉文本等等。這也是Vim啟動后的默認模式。這正好和許多新用戶期待的操作方式相反(大多數編輯器默認模式為插入模式)。 2. 插入模式在這個模式中,大多數按鍵都會向文本緩沖中插入文本。大多數新用戶希望文本編輯器編輯程序中一 ......

    uj5u.com 2023-04-20 08:43:21 more
  • vim的常用命令

    Vim的6種基本模式 1. 普通模式在普通模式中,用的編輯器命令,比如移動游標,洗掉文本等等。這也是Vim啟動后的默認模式。這正好和許多新用戶期待的操作方式相反(大多數編輯器默認模式為插入模式)。 2. 插入模式在這個模式中,大多數按鍵都會向文本緩沖中插入文本。大多數新用戶希望文本編輯器編輯程序中一 ......

    uj5u.com 2023-04-20 08:42:36 more
  • docker學習

    ###Docker概述 真實專案部署環境可能非常復雜,傳統發布專案一個只需要一個jar包,運行環境需要單獨部署。而通過Docker可將jar包和相關環境(如jdk,redis,Hadoop...)等打包到docker鏡像里,將鏡像發布到Docker倉庫,部署時下載發布的鏡像,直接運行發布的鏡像即可。 ......

    uj5u.com 2023-04-19 09:26:53 more
  • 設定Windows主機的瀏覽器為wls2的默認瀏覽器

    這里以Chrome為例。 1. 準備作業 wsl是可以使用Windows主機上安裝的exe程式,出于安全考慮,默認情況下改功能是無法使用。要使用的話,終端需要以管理員權限啟動。 我這里以Windows Terminal為例,介紹如何默認使用管理員權限打開終端,具體操作如下圖所示: 2. 操作 wsl ......

    uj5u.com 2023-04-19 09:25:49 more
  • docker學習

    ###Docker概述 真實專案部署環境可能非常復雜,傳統發布專案一個只需要一個jar包,運行環境需要單獨部署。而通過Docker可將jar包和相關環境(如jdk,redis,Hadoop...)等打包到docker鏡像里,將鏡像發布到Docker倉庫,部署時下載發布的鏡像,直接運行發布的鏡像即可。 ......

    uj5u.com 2023-04-19 09:19:04 more
  • Linux學習筆記

    IP地址和主機名 IP地址 ifconfig可以用來查詢本機的IP地址,如果不能使用,可以通過install net-tools安裝。 Centos系統下ens33表示主網卡;inet后表示IP地址;lo表示本地回環網卡; 127.0.0.1表示代指本機;0.0.0.0可以用于代指本機,同時在放行設 ......

    uj5u.com 2023-04-18 06:52:01 more
  • 解決linux系統的kdump服務無法啟動的問題

    問題:專案麒麟系統服務器的kdump服務無法啟動,沒有相關日志無法定位問題。 1、查看服務狀態是關閉的,重啟系統也無法啟動 systemctl status kdump 2、修改grub引數,修改“crashkernel”為“512M(有的機器數值太大太小都會導致報錯,建議從128M開始試,或者加個 ......

    uj5u.com 2023-04-12 09:59:50 more
  • 解決linux系統的kdump服務無法啟動的問題

    問題:專案麒麟系統服務器的kdump服務無法啟動,沒有相關日志無法定位問題。 1、查看服務狀態是關閉的,重啟系統也無法啟動 systemctl status kdump 2、修改grub引數,修改“crashkernel”為“512M(有的機器數值太大太小都會導致報錯,建議從128M開始試,或者加個 ......

    uj5u.com 2023-04-12 09:59:01 more
  • 你是不是暴露了?

    作者:袁首京 原創文章,轉載時請保留此宣告,并給出原文連接。 如果您是計算機相關從業人員,那么應該經歷不止一次網路安全專項檢查了,你肯定是收到過資訊系統技術檢測報告,要求你加強風險監測,確保你提供的系統服務堅實可靠了。 沒檢測到問題還好,檢測到問題的話,有些處理起來還是挺麻煩的,尤其是線上正在運行的 ......

    uj5u.com 2023-04-05 16:52:56 more
  • 細節拉滿,80 張圖帶你一步一步推演 slab 記憶體池的設計與實作

    1. 前文回顧 在之前的幾篇記憶體管理系列文章中,筆者帶大家從宏觀角度完整地梳理了一遍 Linux 記憶體分配的整個鏈路,本文的主題依然是記憶體分配,這一次我們會從微觀的角度來探秘一下 Linux 內核中用于零散小記憶體塊分配的記憶體池 —— slab 分配器。 在本小節中,筆者還是按照以往的風格先帶大家簡單 ......

    uj5u.com 2023-04-05 16:44:11 more