1.ClusterIP 類型
2.NodePort 類型
3.LoadBalancer 類型
4.ExternalName 類型
類型為 ExternalName 的 Service 將 Service 映射到 DNS 名稱,而不是典型的選擇算符, 例如 my-service 或者 cassandra。你可以使用 spec.externalName 參數指定這些服務。
例如,以下 Service 定義將 prod 名字空間中的 my-service 服務映射到 my.database.example.com:
apiVersion: v1
kind: Service
metadata:name: my-servicenamespace: prod
spec:type: ExternalNameexternalName: my.database.example.com
說明:
type: ExternalName
的服務接受 IPv4 地址字符串,但將該字符串視為由數字組成的 DNS 名稱, 而不是 IP 地址(然而,互聯網不允許在 DNS 中使用此類名稱)。 類似于 IPv4 地址的外部名稱無法
被 DNS 服務器解析。
如果你想要將服務直接映射到某特定 IP 地址,請考慮使用無頭服務
。
當查找主機 my-service.prod.svc.cluster.local
時,集群 DNS 服務返回 CNAME 記錄, 其值為 my.database.example.com
。訪問 my-service
的方式與訪問其他 Service 的方式相同, 主要區別在于重定向發生在 DNS 級別,而不是通過代理或轉發來完成。 如果后來你決定將數據庫移到集群中,則可以啟動其 Pod,添加適當的選擇算符或端點并更改 Service 的 type
。
注意:
針對 ExternalName 服務使用一些常見的協議,包括 HTTP 和 HTTPS,可能會有問題。 如果你使用 ExternalName 服務,那么集群內客戶端使用的主機名與 ExternalName 引用的名稱不同。對于使用主機名的協議,這一差異可能會導致錯誤或意外響應。 HTTP 請求將具有源服務器無法識別的
Host
: 標頭; TLS 服務器將無法提供與客戶端連接的主機名匹配的證書。
實戰場景1:
假設你在集群外有一個數據庫服務,地址為db.external.com
,端口是3306
(MySQL的默認端口)。你希望在集群內部用一個類似mysql.default.svc.cluster.local
的域名來訪問它。
kubectl apply -f << EOF
apiVersion: v1
kind: Service
metadata: name: mysqlnamespace: default
spec:type: ExternalNameexternalName: db.external.com
EOF
一旦創建完成,在集群內的Pod可以通過DNS名稱mysql.default.svc.cluster.local
或者mysql
來訪問
kubectl run test-pod --rm -it --image=busybox -- /bin/sh
然后訪問:
nslookup mysql
telnet mysql 3306
應該可以看到DNS解析指向db.external.com
實戰場景2:
假如你有一個應用程序AppA部署在命名空間aa中,服務名為servicea。
現在計劃將AppA遷移到新的命名空間bb中,但是你希望在遷移的過程中,其他應用仍然能通過原有的
servicea訪問AppA,以避免服務中斷。
在aa命名空間中創建一個ExternalName的Service,將流量指向新的B命名空間的servicea
步驟:
1.在bb命名空間部署AppA和對應的servicea服務。
2.在aa命令空間創建ExternalName的Service。
kubectl apply -f << EOF
apiVersion: v1
kind: Service
metadata: name: serviceanamespace: aa
spec:type: ExternalNameexternalName: servicea.bb.svc.cluster.local
EOF
總結:
1.端口信息不可配置:ExternalName 類型的服務本身不會定義端口,所以需要你在Pod中直接訪問目標主機的端口。
2.僅支持TCP流量:因為它本質是DNS CNAME映射,所以主要適用TCP協議。
3.安全性: 你仍需要自己處理認證、證書等安全問題。