K8s如何實現服務發現與配置管理

這是我參與更文挑戰的第24天,活動詳情查看:更文挑戰web

K8s如何實現服務註冊與發現

  咱們一直在說K8s具有服務發現以及配置管理的能力,K8s是如何實現服務的註冊與發現,而後如何作到服務的轉發、實現負載均衡的。spring

  其實服務在K8s中,也定義了一種資源:Service,Service,顧名思義是一個服務,什麼樣的服務呢?它是定義了一個服務的多種 pod 的邏輯合集以及一種訪問 pod 的策略。ubuntu

service 的類型有四種:後端

  • ExternalName:建立一個 DNS 別名指向 service name,這樣能夠防止 service name 發生變化,但須要配合 DNS 插件使用。
  • NodePort:基於 ClusterIp,用於爲集羣外部訪問 Service 後面 Pod 提供訪問接入端口。
  • LoadBalancer:它是基於 NodePort。
  • ClusterIP:默認的類型,用於爲集羣內 Pod 訪問時,提供的固定訪問地址,默認是自動分配地址,可以使用 ClusterIP 關鍵字指定固定 IP。

從上面講的 Service,咱們能夠看到一種場景:全部的微服務在一個局域網內,或者說在一個 K8s 集羣下,那麼能夠經過 Service 用於集羣內 Pod 的訪問,這就是 Service 默認的一種類型 ClusterIP,ClusterIP 這種的默認會自動分配地址。api

  那麼問題來了,既然能夠經過上面的 ClusterIp 來實現集羣內部的服務訪問,那麼如何註冊服務呢?其實 K8s 並無引入任何的註冊中心,使用的就是 K8s 的 kube-dns 組件。而後 K8s 將 Service 的名稱當作域名註冊到 kube-dns 中,每個Service在kube-dns中都有一條DNS記錄,同時,若是有服務的ip更換,kube-dns自動會同步,對服務來講是不須要改動的。經過 Service 的名稱就能夠訪問其提供的服務。那麼問題又來了,若是一個服務的 pod 對應有多個,那麼如何實現 LB?其實,最終經過 kube-proxy,實現負載均衡。也就是說kube-dns經過 servicename 找到指定 clusterIP,kube-proxy完成經過 clusterIP 到 PodIP 的過程。markdown

說到這,咱們來看下 Service 的服務發現與負載均衡的策略,Service 負載分發策略有兩種:app

  • RoundRobin:輪詢模式,即輪詢將請求轉發到後端的各個 pod 上,其爲默認模式。
  • SessionAffinity:基於客戶端 IP 地址進行會話保持的模式,相似 IP Hash 的方式,來實現服務的負載均衡。

下面寫一個很簡單的例子:負載均衡

apiVersion: v1
kind: Service
metadata:
  name: cas-server-service
  namespace: default
spec:
  ports:
  - name: cas-server01
    port: 2000
    targetPort: cas-server01
  selector:
    app: cas-server
複製代碼

能夠看到執行 kubectl apply -f service.yaml 後:微服務

root@ubuntu:~$ kubectl get svc
NAME                          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)              AGE
admin-web-service             ClusterIP   10.16.129.24    <none>        2001/TCP              84d
cas-server-service            ClusterIP   10.16.230.167   <none>        2000/TCP               67d
cloud-admin-service-service   ClusterIP   10.16.25.178    <none>        1001/TCP         190d
複製代碼

這樣,咱們能夠看到默認的類型是 ClusterIP,用於爲集羣內 Pod 訪問時,能夠先經過域名來解析到多個服務地址信息,而後再經過 LB 策略來選擇其中一個做爲請求的對象。oop

K8s 如何處理微服務中經常使用的配置

  接下來咱們看看微服務中場景的居多配置該如何來利用K8s實現統一管理。其實,在K8s中,定義了一種資源:ConfigMap,咱們來看看這種資源。

  ConfigMap,看到這個名字能夠理解:它是用於保存配置信息的鍵值對,能夠用來保存單個屬性,也能夠保存配置文件。對於一些非敏感的信息,好比應用的配置信息,則可使用 ConfigMap。

建立一個 ConfigMap 有多種方式以下。

  1. key-value 字符串建立
kubectl create configmap test-config --from-literal=baseDir=/usr
複製代碼

  上面的命令建立了一個名爲 test-config,擁有一條 key 爲 baseDir,value 爲 "/usr" 的鍵值對數據。

  1. 根據 yml 描述文件建立
apiVersion: v1
kind: ConfigMap
metadata:
  name: test-config
data:
  baseDir: /usr
複製代碼

也能夠這樣,建立一個 yml 文件,選擇不一樣的環境配置不一樣的信息:

kind: ConfigMap
apiVersion: v1
metadata:
  name: cas-server
data:
  application.yaml: |-
    greeting:
      message: Say Hello to the World
    ---
    spring:
      profiles: dev
    greeting:
      message: Say Hello to the Dev
    spring:
      profiles: test
    greeting:
      message: Say Hello to the Test
    spring:
      profiles: prod
    greeting:
      message: Say Hello to the Prod
複製代碼

注意點:

  • ConfigMap 必須在 Pod 使用其以前建立。
  • Pod 只能使用同一個命名空間的 ConfigMap。

  固然,還有其餘更多用途,具體能夠參考官網(kubernetes.io/zh/docs/con…

前面講述了幾種建立ConfigMap的方式,其中有一種在 Java 中經常用到:經過建立 yml 文件來實現配置管理。好比:

kind: ConfigMap
apiVersion: v1
metadata:
  name: cas-server
data:
  application.yaml: |-
    greeting:
      message: Say Hello to the World
    ---
    spring:
      profiles: dev
    greeting:
      message: Say Hello to the Dev
    spring:
      profiles: test
    greeting:
      message: Say Hello to the Test
    spring:
      profiles: prod
    greeting:
      message: Say Hello to the Prod
複製代碼

  這樣,當咱們啓動容器時,經過 --spring.profiles.active=dev 來指定當前容器的活躍環境,便可獲取 ConfigMap 中對應的配置。是否是感受跟 Java 中的 Config 配置多個環境的配置有點相似呢?可是,咱們不用那麼複雜,這些通通能夠交給 K8s 來處理。只須要你啓動這一命令便可,是否是很簡單?

相關文章
相關標籤/搜索