1. 程式人生 > 實用技巧 >那個執事,騰雲:記一次某大型醫院的同城雙資料中心上雲過程

那個執事,騰雲:記一次某大型醫院的同城雙資料中心上雲過程

摘要

本文介紹了我曾經的一個僱主給全國排行前 5 的某公立醫院上私有云 + 容器雲的過程。包括普通 Web 系統的遷移,也包括商業網路、儲存裝置的納管,以及異構計算(GPU、FPGA)的支援。

醫院及其資訊系統狀況

經過醫院提供的資訊和我們的調查,醫院當時的資訊系統的狀況如下:

一、主要應用

  1. 醫療資訊系統(HIS)(C-S 架構,資料庫為 Oracle 11g RAC);
  2. 電子病歷(資料庫為 Oracle 11g RAC);
  3. 病歷無紙化系統;
  4. PACS;
  5. 移動醫護系統;
  6. 證書頒發(CA);
  7. 臨床決策支援系統;
  8. 手麻系統;
  9. 合理用藥系統;
  10. 院感系統;
  11. 績效管理系統;
  12. 實驗室資訊系統(LIS);
  13. ESB(即古老的企業服務匯流排);
  14. OA;
  15. 各種前置服務系統(醫保、預約掛號、衛建委平臺等)。

二、部署架構

醫院的物理伺服器上安裝 VMware 虛擬化軟體。上述應用均以雙活共享儲存的方式執行在 VM 中。VM 例項數為 80 餘個。

資料中心中有一些商業網路裝置(F5)和商業儲存裝置。

某些應用(如影像系統)需要顯示卡(GPU),某些應用(如基因分析)需要 FPGA。

三、新資料中心問題

新的院區即將建設完畢,需要考慮雙資料中心(每個院區一個數據中心)的容災問題。新老院區在同一個城市。

四、其他

  • 醫院的各個應用均以原始碼(託管到內網 gitlab) + 構建指令碼 + 部署手冊的方式交付,且文件比較完善(很幸運!)
  • 醫院有內網 DNS 伺服器,所有的系統均用內網域名互相訪問(也很幸運!這會極大減少上雲的難度)

醫院的疑問

  1. 是否所有的應用都上容器?
  2. 上雲之後,雙資料中心的容災怎樣實現?
  3. 兩個資料中心的網路如何建設有利於順利上雲?
  4. 上雲之後,醫院的應用改造涉及哪些方面?

上雲思路分析

先挑出不上容器的應用(如 gitlab 伺服器,CA)。

由於醫院已經購買了 VMware 的永久授權,而且版本還比較新,所以將 VMware 作為虛擬機器的後端實現(產品支援兩種虛擬機器:KVM 和 VMware)。

對於上雲的應用,必須進行分類(哪些是普通 Web 軟體,哪些是大記憶體的,哪些是高 CPU 負載的,哪些必須高可用,哪些要執行在 Windows 上,哪些需要特殊硬體),給這些應用規劃標籤(Kubernetes 的 label)。

給節點也要規劃標籤,標識它是否有某種裝置,配置的高低,在哪個資料中心等資訊。

另外,啟用配額管理(產品功能),防止某個應用佔用資源過多把別的應用擠爆。

由於應用中有很多雲原生的反模式,所以要進行一些修改,用 DevOps 的方式部署的雲。

上雲方案和過程

網路建設

這部分與研發關係不大。簡略敘述。

結果是醫院找人在兩個資料中心之間架設了高可用的專線,兩個資料中心在一個區域網中。

(如此一來,不必為每個資料中心部署一個 Kubernetes 叢集,而是隻部署一個叢集,大大簡化了問題;雙資料中心容災也被簡化為相當於一間機房的左、右半邊容災。)

雲的部署

裝置位置調整

在安裝雲之間,要調整機器的位置。把帶 GPU 的機器、帶 FPGA 的機器均分到兩個資料中心,使得兩邊的 GPU、FPGA 數分別相當。

6 臺 F5,其中 2 臺當作 Kubernetes 的 apiserver 的負載均衡(每個資料中心放一個,配相同的內網域名);2 臺有公網 IP,當作訪問入口(每個資料中心放一個,配相同的內網和公網域名);2 臺當作內網訪問的入口(每個資料中心放一個,配相同的內網域名)。

Oracle 使用的商業儲存裝置也移動一下,均分到兩邊。

安裝雲軟體

Kubernetes 叢集的 master 4 個節點;etcd 3 個節點(一個數據中心 2 個,另一個 1 個,這其實是個隱患或缺陷,因為 2 個節點的資料中心被摧毀,etcd 就會壞掉)。

這裡需要指出,有人所說的 Kubernetes 的 master 節點數必須為奇數是錯的,master 的元件中,只有 etcd 是有狀態的,其他元件(如 apiserver)根本無狀態,自然不存在奇偶性的要求。

雲提供了跨資料中心的高可用基礎設定(如 PubSub、映象中心、Redis、雲資料庫),這部分自帶跨資料中心容災。

Kubernetes 裡面的負載不用考慮雙資料中心容災,就算一個負載的 Pod 全部在一個數據中心而這個資料中心被摧毀,Kubernetes 也會再別處(也就是另一資料中心)把 Pod 啟動或恢復。由於兩邊的資源(如 GPU)是對稱的,所以不存在在另一邊無法啟動的情況。

處理不上容器的應用和服務

Gitlab 、CA 放到配置比較高的 VM 上,和原來一樣。

OA 不上容器,因為它的技術棧特別老舊,而且用到了很難上雲的 WebLogic,所以它的 OA 沒有合適的容器化方案。

HIS 整個(包括它的資料庫)還在 VM 上,不上容器。

電子病歷的資料庫部分不上容器。

這是因為 Oracle 上容器的坑太多,業界沒啥好辦法。

Oracle + 商業儲存的雙機熱備有官方的方案,照著配即可。只需要注意把計算節點的多個 VM 副本例項分到不同的資料中心。

標籤規劃

節點標籤:

x-has-vgpu: [yes|no] # 是否有 vGPU
x-has-vfpga: [yes|no] # 是否有 vFPGA

(注:在我們的雲軟體中,GPU 是通過虛擬化技術虛擬出多個 vGPU 分別給多個 VM,然後容器獨佔 vGPU 的方式,而且讓容器共享 GPU。FPGA 類似。)

需要相應資源的負載要設定 nodeSelector

nodeSelector:
    x-has-vfpga: yes

值得注意的是,Kubernetes 會在每個節點上自動增加

kubernetes.io/os: [windows|linux]

的標籤。

由於 Windows 容器只能在 Windows 上執行,而 Linux 容器只能在 Linux 上執行,所以需要給 Windows 節點抹上汙點 os=windows:NoSchedule

所有需要執行在 Windows 上的負載均加上 nodeSelector 和汙點容忍:

nodeSelector:
    kubernetes.io/os: windows
tolerations:
    - key: "os"
      operator: "Equal"
      value: "windows"
      effect: "NoSchedule"

應用的雲原生改造

由於醫院現有應用的開發時間遠近不一,多多少少存在著雲原生的反模式。

日誌方面:由輸出到檔案改成到 stdout(會被日誌採集服務自動採走)。所幸原來的開發人員素養還行,沒有把日誌輸出目標寫死。

配置檔案方面:由 ConfigMap 和 Secret 管理。

監控支援:Spring Boot 專案添加了比較完整的 Prometheus 支援,老專案(用 Struts2)捏著鼻子好歹添加了幾個支援 Prometheus 查詢的指標。Django 專案新增 Prometheus 支援。

其他細節:程式配置的資料庫地址從原來的內網域名改為了 Service 名;開關類的配置改為由環境變數獲取。

為應用提供雲的支援

DevOps:在改造程式並準備好雲環境後,就可以將應用通過 DevOps 功能部署到雲。在操作介面新建流水線,編寫構建、部署流程,設定好觸發方式(手動、定時、Gitlab 的 WebHook),應用就被部署到了 Kubernetes 叢集中。

監控與告警:部署完應用之後,就可以在監控介面看到節點、Kubernetes 叢集、負載(各個應用)的各項指標,如 CPU 使用、記憶體佔用、網路佔用、應用的健康程度、排程器的頻率、etcd 的大小與吞吐、資料庫的連線情況等等。然後給部分指標設定了告警,如記憶體佔用超過一定數值就傳送釘釘訊息,JVM 記憶體中物件數突然升高傳送郵件,等等。

日誌支援:雲提供的日誌服務可以方便地查詢、搜尋、篩選日誌,供排查問題用。比看那個黑視窗或日誌文字好用多了。後續(開發中)還會有機器學習日誌分析功能,用來推斷故障出在哪。

結束語

以上便是這家醫院上雲的全過程。對醫院疑問的解答也包含在上述過程中。

上雲過程的難點就是在折騰的過程中要頂一下來自醫院的壓力和質疑。而在醫院看到上雲後物理機使用數減少約 1/3 後,態度則轉變為欣喜和信任。雲的強大功能(監控、日誌、DevOps、微服務與服務網格、中介軟體等)又進一步給產品添彩。