從業務資料的角度看,容器可以分為兩類:無狀态(stateless)容器和有狀态(stateful)容器。
無狀态是指容器在運作過程中不需要儲存資料,每次通路的結果不依賴上一次通路,比如提供靜态頁面的 web 伺服器。
有狀态是指容器需要儲存資料,而且資料會發生變化,通路的結果依賴之前請求的處理結果,最典型的就是資料庫伺服器。
簡單來講,狀态(state)就是資料,如果容器需要處理并存儲資料,它就是有狀态的,反之則無狀态。
對于有狀态的容器,如何儲存資料呢?
前面在 Docker 存儲章節我們學習到 data volume 可以存儲容器的狀态,不過當時讨論的 volume 其本質是 Docker 主機 本地 的目錄。
本地目錄就存在一個隐患:如果 Docker Host 當機了,如何恢複容器?
一個辦法就是定期備份資料,但這種方案還是會丢失從上次備份到當機這段時間的資料。更好的方案是由專門的 storage provider 提供 volume,Docker 從 provider 那裡擷取 volume 并挂載到容器。這樣即使 Host 挂了,也可以立刻在其他可用 Host 上啟動相同鏡像的容器,挂載之前使用的 volume,這樣就不會有資料丢失。
本章将詳細讨論如何實作跨 Docker 主機管理 data volume。
假設有兩個 Dokcer 主機,Host1 運作了一個 MySQL 容器,為了保護資料,data volume 由 storage provider 提供,如下圖所示。

當 Host1 發生故障,我們會在 Host2 上啟動相同的 MySQL 鏡像,并挂載 data volume。
Docker 是如何實作這個跨主機管理 data volume 方案的呢?
答案是 volume driver。
任何一個 data volume 都是由 driver 管理的,建立 volume 時如果不特别指定,将使用 <code>local</code> 類型的 driver,即從 Docker Host 的本地目錄中配置設定存儲空間。如果要支援跨主機的 volume,則需要使用第三方 driver。
我們這裡将選擇 Rex-Ray driver,其原因是:
Rex-Ray 是開源的,而且社群活躍。
支援多種 backend,VirtualBox 的 Virtual Media、Amazon EBS、Ceph RBD、OpenStack Cinder 等。
支援多種作業系統,Ubuntu、CentOS、RHEL 和 CoreOS。
支援多種容器編排引擎,Docker Swarm、Kubernetes 和 Mesos。
Rex-Ray 安裝使用方法非常簡單。
下一節我們開始實踐 Rex-Ray。