kubernetes如何解決服務依賴呢?

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
  • 如何知道Pod已經Ready
  • 延遲應用的部署
  • 結論

原文連結在此。寫的比較通俗易懂,做個筆記,有一些是我自己的理解。

在微服務的世界裡,任何應用都需要注意,其所依賴的服務是會中斷的。所以當應用發現某服務(如資料庫)出現了故障,應該每隔一端時間去重試。而上層架構(如k8s)會檢測到服務故障,並嘗試恢複這個服務。

但在現實世界裡,有些舊應用並沒有處理這種情況,但我們還是希望能將他們也跑在微服務架構裡,以期得到微服務的紅利(例如應用程式中斷重啟),所以,需要定義服務依賴關係,從而保障舊應用啟動時,它所依賴的服務已經ready。

解決方案是,微服務架構替應用等待其所依賴的服務(api, database, etc),當服務準備好時,架構才啟動該應用。

如何知道Pod已經Ready

kubernetes提供了Readiness Probe功能,用來探測Pod是否Ready。

Pod在Readiness Probe成功之前,不會接受任何流量;具體以Service來說,在Pod的Readiness Probe成功之前,Kubernetes不會將該Pod作為Serivce的Endpoint(注意,這是下面initContainer的基礎)。Probe是kubernet API提供的功能,服務不需要做任何改變就可以支援。下面是一個readiness Probe的例子:

readinessProbe:  httpGet:    path: /login    port: 3000

延遲應用的部署

我們已經解決了依賴服務是否Ready的問題,但還需要解決應用如何延遲部署;具體來說,如何讓應用感知到其所依賴的服務已經Ready,但不必修改應用,當然還是需要架構來幫忙。

Kubernetes提供了init Container,它會在應用Pod啟動之前啟動,並且在init Container結束之前,應用Pod不會啟動。所以,顧名思義,init Container用來初始化,在這裡主要用來阻塞應用Pod的啟動。(你將會看到在其他例子裡initContainer還有一些其他的用法,例如可以用來修改與應用Pod共用的Volume,從而使相同的鏡像具有不同的行為。initContainer很像開啟了潘多拉的盒子)

annotations:pod.beta.kubernetes.io/init-containers: '[{"name": "wait-for-endpoints","image": "giantswarm/tiny-tools","imagePullPolicy": "IfNotPresent","command": ["fish", "-c", "echo \"waiting for endpoints...\"; while true; set endpoints (curl -s --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt --header \"Authorization: Bearer \"(cat /var/run/secrets/kubernetes.io/serviceaccount/token) https://kubernetes.default.svc/api/v1/namespaces/monitoring/endpoints/grafana); echo $endpoints | jq \".\"; if test (echo $endpoints | jq -r \".subsets[]?.addresses // [] | length\") -gt 0; exit 0; end; echo \"waiting...\";sleep 1; end"],"args": ["monitoring", "grafana"]}]'

上面是initContainer的定義,簡單來說就是每隔1s去問問kubernetes,我依賴的這個服務(namespaces/monitoring/endpoints/grafana),是不是ready了,如果沒有我就再while true一會,如果ready了我initContainer的使命就結束了,應用Pod可以啟動了。

結論

Readiness+initContainer,算是Kubernetes為服務依賴給出的一個解決辦法。但,其實這是一個workaroud,實際上完全可以作為kubernetes的一個feature(回想一下,initContainer的事情完全是k8s系統層面的,跟具體應用無關),那為什麼kubernetes不實現呢?

我理解,這可能是k8s作為一個微服務的架構,不希望引入“服務依賴”,而是希望應用能夠處理這種情況。畢竟,服務依賴帶來一個問題:解決了應用啟動時依賴的問題,那麼應用運行過程中,所依賴的服務又故障了怎麼辦呢?

然而,現實情況沒這麼美。我給mysql叢集前加的keepalived叢集,希望不要老是重啟,使用了上面的這個方法。

建立時的確是可以阻塞keepalived直到mysql叢集ready;但在整叢集重啟的時候,initContainer由於之前已經complete了,所以叢集重啟時並不會再去拉起initContainer,所以也就不存在這個阻塞點了,因此服務依賴失敗。

不過tiny-tools提供了一個fish shell很不錯,可以試試。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.