k8s - Service ExternalName


類型ExternalName

類型為 ExternalName 的服務將服務映射到 DNS 名稱,而不是典型的選擇器,例如 my-service 或者 cassandra。 您可以使用 spec.externalName 參數指定這些服務。

例如,以下 Service 定義將 prod 名稱空間中的 my-service 服務映射到 my.database.example.com

apiVersion: v1
kind: Service
metadata:
  name: my-service
  namespace: prod
spec:
  type: ExternalName
  externalName: my.database.example.com
說明: ExternalName 接受 IPv4 地址字符串,但作為包含數字的 DNS 名稱,而不是 IP 地址。 類似於 IPv4 地址的外部名稱不能由 CoreDNS 或 ingress-nginx 解析,因為外部名稱旨在指定規范的 DNS 名稱。 要對 IP 地址進行硬編碼,請考慮使用 [headless Services](#headless-services)。

當查找主機 my-service.prod.svc.cluster.local 時,群集DNS服務返回 CNAME 記錄,其值為 my.database.example.com。 訪問 my-service 的方式與其他服務的方式相同,但主要區別在於重定向發生在 DNS 級別,而不是通過代理或轉發。 如果以后您決定將數據庫移到群集中,則可以啟動其 Pod,添加適當的選擇器或端點以及更改服務的類型

 

以下文章引用: https://www.qedev.com/cloud/244937.html

ExternalName 介紹

記得很多年前大陸流行音樂剛開始流行,李春波的一首《小芳》風靡大街小巷,正處於青春懵懂期的少男,頃刻間就被它的旋律捕獲了,於是小芳就是初戀,初戀就是小芳.

后來上了大學,讀了計算機系,學到了很多基於控制台的命令,但是不知道為什么,每當我敲打 ln 命令的時候,都會想起小芳,那時我天真地認為,只要找到了小芳,我就可以找到幸福,於是我向一個情場老手討教全年級最好記的女生姓名叫什么?他想都沒想,脫口而出——“殷靜”、“史珍香”。

        后來學了 k8s,知道了常用的 k8s service 類型—— ClusterIP、NodePort、LoadBalancer,唯獨對 externalName 置若罔聞,直到有一天在學習 Istio Sidecar 這種 API 資源的時候,才突然領悟了 ExternalName 這種 k8s service 類型是使用場景。

 ExternalName 這種 service 類型的作用類似軟鏈或者快捷方式。下面舉一個具體的例子。

 

 該樣例目的是讓處於 default 命名空間下的 httpd-pod 訪問到處於 nginx-ns 命名空間下的 nginx-svc,不像以往 svc-name.ns-name.svc.cluster.local 方式跨命名空間訪問的方式,這里我們使用 ExternalName 方式。

 jiuxi-client.yaml

 

 

 jiuxi-client-svc.yaml

 

 關鍵點就在這個文件,該文件中指定了到 nginx-svc 的軟鏈,這么做的好處是對使用者做到了透明,讓使用者感覺就好像調用自己命名空間的服務一樣。

 

jiuxi-nginx.yaml

 

 

 

jiuxi-nginx-svc.yaml

 

 

jiuxi-ns.yaml

 

 

自此整個樣例代碼編寫完畢。

首先創建 jiuxi-ns.yaml 命名空間,然后再應用其他資源文件,如下命令所示:

kubectl apply -f jiuxi-ns.yaml

kubectl apply -f jiuxi-client.yaml

kubectl apply -f jiuxi-client-svc.yaml

kubectl apply -f jiuxi-nginx.yaml

kubectl apply -f jiuxi-nginx-svc.yaml

     

驗證樣例

所有 pod 都爭取運行之后,登錄 client,然后執行如下語句:

wget -q -O - http://jiuxi-client-svc

wget -q -O - http://jiuxi-nginx-svc.nginx-ns.svc.cluster.local

        發現兩種方式都可以正常訪問。

 

擴展閱讀 

K8S 最佳實踐-映射外部服務

場景 1:具有 IP 地址的集群外數據庫

其中一個常見場景是在集群外部托管自己的數據庫,例如在 Google 計算引擎實例中。如果您在 Kubernetes 內部和外部分別運行一些服務,或者需要在 Kubernetes 允許的基礎上獲得更多定制或控制,通常可采用上述這種方式。

希望未來某個時候您可以將所有服務都移入集群內,但在此之前將是“內外混用”的狀態。幸運的是,您可以使用靜態 Kubernetes 服務來緩解上述痛點。

在本例中,我使用 Cloud Launcher 創建了一個 MongoDB 服務器。由於此服務器在與 Kubernetes 集群相同的網絡(或 VPC)中創建,因此可以使用高性能的內部 IP 地址訪問。在 Google Cloud 中,這是默認設置,因此無需進行任何特殊配置。

現在我們有了 IP 地址,那么第一步就是創建服務:

kind: Service

apiVersion: v1

metadata:

name: mongo

Spec:

type: ClusterIP

ports:

– port: 27017

targetPort: 27017

您可能會注意到此服務沒有 Pod 選擇器。此操作將創建一個服務,但它不知道往哪里發送流量。這樣一來,您可以手動創建一個將從此服務接收流量的 Endpoints 對象。

kind: Endpoints

apiVersion: v1

metadata:

name: mongo

subsets:

– addresses:

– ip: 10.240.0.4

ports:

– port: 27017

您可以看到 Endpoints 手動定義了數據庫的 IP 地址,並且使用的名稱與服務名稱相同。Kubernetes 將 Endpoints 中定義的所有 IP 地址視為與常規 Kubernetes Pod 一樣。現在您可以用一個簡單的連接字符串訪問數據庫:

mongodb://mongo

> 根本不需要在代碼中使用 IP 地址!如果以后 IP 地址發生變化,您可以為端點更新 IP 地址,而應用無需進行任何更改。

場景 2:具有 URI 的遠程托管數據庫

如果您使用的是來自第三方的托管數據庫服務,它們可能會為您提供可用於連接的統一資源標識符 (URI)。如果它們為您提供 IP 地址,則可以使用場景 1 中的方法。

在本例中,我在 mLab 上托管了兩個 MongoDB 數據庫。一個是我的開發數據庫,另一個是生產數據庫。

這些數據庫的連接字符串如下所示:

mongodb://<dbuser>:<dbpassword>@ds149763.mlab.com:49763/devmongodb://<dbuser>:<dbpassword>@ds145868.mlab.com:45868/prodmLab

為您提供了動態 URI 和動態端口,您可以看到兩者都不同。我們來使用 Kubernetes 基於這些差異創建一個抽象層。在本例中,我們將連接開發數據庫。

您可以創建一個 “ExternalName” Kubernetes 服務,此服務為您提供將流量重定向到外部服務的靜態 Kubernetes 服務。此服務在內核級別執行簡單的 CNAME 重定向,因此對性能的影響非常小。

服務的 YAML 如下所示:

kind: Service

apiVersion: v1

metadata:

name: mongo

spec:

type: ExternalName

externalName: ds149763.mlab.com

現在,您可以使用更簡化的連接字符串:

mongodb://<dbuser>:<dbpassword>@mongo:<port>/dev

由於 “ExternalName” 使用 CNAME 重定向,因此無法執行端口重映射。對於使用靜態端口的服務來說,這可能不成問題,然而本例中使用的是動態端口。mLab 免費版為您提供了動態端口號,並且不允許更改。這意味着您需要對開發和生產數據庫使用其他連接字符串。

但如果您可以獲取 IP 地址,就可以執行端口重映射,關於此內容,我將在下一部分進行介紹。

場景 3:具有 URI 和端口重映射功能的遠程托管數據庫

CNAME 重定向對於每個環境均使用相同端口的服務非常有效,但如果每個環境的不同端點使用不同的端口,CNAME 重定向就略顯不足。幸運的是我們可以使用一些基本工具來解決這個問題。

第一步是從 URI 獲取 IP 地址。

對 URI 運行 nslookup、hostname 或 ping 命令即可獲取數據庫的 IP 地址。

您現在可以創建一個重新映射 mLab 端口的服務,並為此 IP 地址創建端點。

kind: Service

apiVersion: v1

metadata:

name: mongo

spec:

ports:

– port: 27017

targetPort: 49763

kind: Endpoints

apiVersion: v1

metadata:

name: mongo

subsets:

– addresses:

– ip: 35.188.8.12

ports:

– port: 49763

注:URI 可以使用 DNS 在多個 IP 地址之間進行負載平衡,因此,如果 IP 地址發生變化,這個方法可能會有風險!如果您通過上述命令獲取多個 IP 地址,則可以將所有這些地址都包含在 Endpoints YAML 中,並且 Kubernetes 會在所有 IP 地址之間進行流量的負載平衡。

通過這種方式,您無需指定端口即可連接到遠程數據庫。Kubernetes 服務重映射端口的過程完全透明!

mongodb://<dbuser>:<dbpassword>@mongo/dev

結論

將外部服務映射到內部服務可讓您未來靈活地將這些服務納入集群,同時最大限度地減少重構工作。即使您今天不打算將服務加入集群,以后可能也會這樣做!而且,這樣一來,您可以更輕松地管理和了解組織所使用的外部服務。

如果外部服務具有有效域名,並且您不需要重新映射端口,那么使用 “ExternalName” 服務類型將外部服務映射到內部服務十分簡便、快捷。如果您沒有域名或需要執行端口重映射,只需將 IP 地址添加到端點並使用即可。

實例 

ExternalName
apiVersion: v1
kind: Service
metadata:
  name: "baiducom" # 設置 IP 14.215.177.39和www.baidu.com 錯誤,不允許'.'
spec:
  type: ExternalName
  externalName: "www.baidu.com" # 設置 IP 14.215.177.39 無效

# 所以 externalName 的意義就是為域名設置一個別名,如上 為 www.baidu.com 設置別名 baiducom,以便 pod 內容器使用
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: busybox
  labels:
    app: busybox
spec:
  replicas: 1
  selector:
    matchLabels:
      app: busybox
  template:
    metadata:
      labels:
        app: busybox
    spec:
      containers:
        - name: busybox
          image: busybox
          command: ["/bin/sh", "-c", "sleep 3600"]

- 外部 IP 鏈接

ip.yaml 外部訪問:

182.254.186.198:81
apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    run: nginx
spec:
  type: NodePort
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
      name: http
      nodePort: 81
  selector:
    run: nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  selector:
    matchLabels:
      run: nginx
  replicas: 1
  template:
    metadata:
      labels:
        run: nginx
    spec:
      containers:
        - name: nginx
          image: nginx
          ports:
            - containerPort: 80

kubectl apply -f ip.yaml

創建服務 ips.yaml

apiVersion: v1
kind: Service
metadata:
  name: nginx-ip
spec:
  ports:
    - protocol: TCP
      port: 88
      targetPort: 81
---
apiVersion: v1
kind: Endpoints
metadata:
  name: nginx-ip
subsets:
  - addresses:
      - ip: 182.254.186.198
    ports:
      - port: 81 # IP相關的端口,可以是外部連接端口,也可以是內部容器連接端口

kubectl apply -f ips.yaml

 

 -

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM