在 K8S 上的 Web 服務該怎麼做域名解析呢?

我們這個系列的文章一直都在學習和掌握 K8S 各種組成部分在集羣裏的角色、作用和使用場景,那麼針對今天這個主題任務「給 K8S 上的 Web 服務做域名解析」你覺得應該使用什麼組件來完成呢?

如果你看過我上一篇文章你知道 K8S 暴露服務的方式有哪些嗎? 應該能猜到是使用Ingress,那麼有人會問爲啥不能用NodePort這種方式呢?今天的文章我們就來詳細探討一下這些相關的問題:

爲什麼 NodePort 不適合做域名解析

NodePort 類型的Service 是向集羣外暴露服務的最原始方式,也是最好讓人理解的。NodePort,顧名思義,會在所有節點(宿主機或者是 VM)上打開一個特定的端口,發送到這個端口的任何流量都會轉發給Service

NodePort Service 的原理可以用下面這個圖表示:

NodePort Service 的原理圖

上圖我們順着流量的流向箭頭從下往上看,流量通過NodeIP+NodePort的方式進入集羣,上圖三個節點的 30001 上的流量都會轉發給 Service,再由 Service 給到後端端點Pod

NodePort Service 的優點是簡單,好理解,通過 IP + 端口的方式就能訪問,但是它的缺點也很明顯,比如:

怎麼使用 Ingress 暴露 Web 服務

在 K8S 的這些組件中Ingress 不是一種Service。相反,它位於多個Service的前端,給這些Service充當 “智能路由代理” 或集羣的入口點(entrypoint)。

Service前面加上Ingress,集羣中需要有Ingress-Controller纔行。如果是自建 K8S 集羣,通常使用nginx-ingress作爲控制器,它使用NGINX服務器作爲反向代理來把流量路由給後面的Service

通過Ingress可以對後端Service進行基於域名和 URL 路徑的路由。例如,您可以將 foo.yourdomain.com 上的所有內容發送到 foo Service,將 yourdomain.com/bar/ 路徑下的所有內容發送到 bar Service。

Ingress 運行原理

我們可以把這張圖和上面 NodePort 原理圖做一個比較,看看兩者的區別。上面這個示意圖對應的 Ingress 資源聲明文件差不多應該長這個樣子:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: my-ingress
spec:
  backend: // 哪個都不匹配時,走這個兜底的Service
    serviceName: other
    servicePort: 8080
  rules:
  - host: foo.mydomain.com
    http:
      paths:
      - backend:
          serviceName: foo
          servicePort: 8080
  - host: mydomain.com
    http:
      paths:
      - path: /bar/
        backend:
          serviceName: bar
          servicePort: 8080

在本地實踐 Ingress

上面說了很多理論,下面我們可以通過一個簡單的 Demo 進行演示,我本地使用的是Docker Desktop自帶的 K8S 集羣,至於爲啥用它,沒別的就是簡單。

要使用Ingress,那麼集羣裏就得先有個Ingress-Controller,我們先來安裝一個Nginx-Ingress-Controller (其本質上就是一個 Nginx Server):

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.0.0/deploy/static/provider/cloud/deploy.yaml

執行上述命令後,其實會在本地集羣的ingress-nginx命名空間裏,安裝三個創建nginx-controllerPod:

➜  ~ kubectl get pods -n ingress-nginx
NAME                                        READY   STATUS      RESTARTS   AGE
ingress-nginx-admission-create-n59dn        0/1     Completed   2          49d
ingress-nginx-admission-patch-hft52         0/1     Completed   3          49d
ingress-nginx-controller-68649d49b8-nlch7   1/1     Running     77         49d

前兩個admission相關的Pod是給nignx controller做配置用的,執行完就退出,第三個纔是運行着nginx-controlelrPod

我之前幾次在本地試驗Ingress沒有成功,就是因爲這個nignx-controller沒有正常啓動起來。一個常見的錯誤是nginx controller 這個Pod拉取鏡像k8s.gcr.io/ingress-nginx/controller:v0.46.0@sha256:.... 的速度非常慢,所以我們最好是在安裝控制器前先通過docker pull命令把這個鏡像拉到本地。

在本地安裝完 Ingress 控制器後,爲了演示方便,之前本地搭建Nacos時做過一個ServiceNacos是阿里巴巴出的一個可以做自動配置和服務註冊的組件,自帶 Web 管理界面,正好可以拿它來演示。

下面我想能通過dev.nacos.com訪問nacos-service,最終讓nacos-service把流量路由給後端安裝了Nacos服務的Pod,這個Ingress可以這麼聲明

//ingress.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: nacos-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
    - host: dev.nacos.com
      http:
        paths:
          - path: /
            backend:
              serviceName: nacos-service
              servicePort: 8848

在集羣裏應用這個Ingress

# 執行下面兩個命令
# kubectl apply -f nacos-ingress.yaml
# kubectl get ingress
➜  ~ kubectl get ingress
NAME            CLASS    HOSTS           ADDRESS     PORTS   AGE
nacos-ingress   <none>   dev.nacos.com   localhost   80      54d

再在本地 hosts 文件裏綁定上

127.0.0.1 dev.nacos.com # 本地K8S集羣的IP是127.0.0.1

就能通過域名訪問到Nacos服務的管理界面

Nacos 的 Web 界面

爲了不影響閱讀,Service、Deployment 這些聲明文件,我放在了 GitHub 倉庫裏,鏈接如下:

https://github.com/kevinyan815/LearningKubernetes

如果有啥疑問可以通過留言或者加微信號 fsg1233210 與我討論。

生產集羣Ingress怎麼做高可用

上面我們聊了Ingress怎麼暴露服務,以及在本地怎麼實踐演練用Ingress暴露服務,那麼有的人肯定會好奇,在生產集羣裏Ingress是怎麼做高可用的呢?域名解析應該怎麼綁定呢?

正常的生產環境,因爲Ingress是公網的流量入口,所以壓力比較大肯定需要多機部署。一般會在集羣裏單獨出幾臺Node,只用來跑Ingress-Controller,可以使用deamonSet的讓節點創建時就安裝上Ingress-Controller,在這些 Node 上層再做一層負載均衡,把域名的 DNS 解析到負載均衡 IP 上。

考慮到多業務線服務相互不影響的話,還需要讓不同的業務線的轉發規則注入到不同的Ingress裏,這個通過我們上面聲明 Ingress 時的註解annotations:kubernetes.io/ingress.class就能實現。

其實每家公司的方案肯定不一樣,尤其是解析鏈路里加上高防 Waf 的話,會更復雜,由於我不是專業運維,也只是知道一些大概的思路,如果有專業的大佬歡迎留言,讓我們共同進步一下。

最後

其實這個主題我一直想寫,之前斷斷續續嘗試了兩三次纔在本地把Ingress這套跑通,搞明白。希望今天的文章能幫大家進行一下Ingress知識的分析,如果想自己掌握、想明白,還是需要把文章好好看看,親自實踐一下演示的例子,以及多複習複習前面關於 Service 的知識才行。

如果你喜歡文章的內容,請關注我的公衆號(微信搜:網管叨 bi 叨),點贊在看分享給更多人吧。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/ZU61NIMxh_UOo-chNvkPXA