Operator是指一類基於Kubernetes自定義資源對象(CRD)和控制器(Controller)的雲原生拓展服務,其中CRD定義了每一個operator所建立和管理的自定義資源對象,Controller則包含了管理這些對象所相關的運維邏輯代碼。html
對於普通用戶來講,若是要在k8s集羣中部署一個高可用的etcd集羣,那麼不只要了解其相關的配置,同時又須要特定的etcd專業知識才能完成維護仲裁,從新配置集羣成員,建立備份,處理災難恢復等等繁瑣的事件。git
而在operator這一類拓展服務的協助下,咱們就可使用簡單易懂的YAML文件(同理參考Deployment)來聲明式的配置,建立和管理咱們的etcd集羣,下面咱們就來一同瞭解下etcd-operator這個服務的架構以及它所包含的一些功能。github
瞭解etcd-operator的架構與CRD資源對象數據庫
部署etcd-operatorapi
使用etcd-operator建立etcd cluster架構
基於etcd-operator備份和恢復etcd clusterapp
etcd-operator的設計是基於k8s的API Extension機制來進行拓展的,它爲用戶設計了一個相似於Deployment的Controller,只不過這個Controller是用來專門管理etcd這一服務的。運維
用戶默認仍是經過kubectl或UI來與k8s的API進行交互,只不過在這個k8s集羣中多了一個用戶自定義的控制器(custom controller),operator controller的服務是以Pod的方式運行在k8s集羣中的,同時這個服務也須要配置所需的RBAC權限(好比對Pod,Deployment,Volume等使用到的資源進行增刪改查的操做),下面咱們用一個簡單的架構圖來進行闡述:分佈式
在k8s中,全部自定義的Controller和其自定義的資源對象(CRD)都必須知足k8s API的規範(參考下圖):ide
apiVersion
描述了當前自定義資源對象的版本號
Kind
表示自定義資源對象的名稱,用戶可經過執行kubectl get $KIND_NAME
來獲取所建立的CRD對象
Metadata
繼承了原生k8s的metadata,用於添加標籤,Annotations等元數據
Spec
是用戶可自定義設計的服務配置參數,如鏡像版本號,節點數量,資源配置等等..
Status
包含了當前資源的的相關狀態,每一個operator controller可自定義status所包含的信息,通常會選擇添加如conditions,updateTime和message等一類的信息。
下面先咱們來了解一下etcd-operator所包含的幾個自定義資源對象(CRDs):
一、EtcdCluster: etcdcluster用來描述用戶自定義的etcd集羣,可一鍵式部署和配置一個相關的etcd集羣。
apiVersion: etcd.database.coreos.com/v1beta2 kind: EtcdCluster metadata: name: etcd-cluster spec: size: 3 version: 3.2.25
二、EtcdBackup: etcdbackup用來描述和管理一個etcd集羣的備份,當前支持按期備份到雲端存儲,如AWS s3, Aliyun oss(oss當前需使用quay.io/coreos/etcd-operator:dev
鏡像)。
apiVersion: etcd.database.coreos.com/v1beta2 kind: EtcdBackup metadata: name: etcd-backup spec: etcdEndpoints: [<etcd-cluster-endpoints>] storageType: OSS #options are S3/ABS/GCS/OSS backupPolicy: backupIntervalInSecond: 125 maxBackups: 4 oss: #"<oss-bucket-name>/<path-to-backup-file>" path: <full-oss-path> ossSecret: <oss-secret> # Details about regions and endpoints, see https://www.alibabacloud.com/help/doc-detail/31837.htm endpoint: <endpoint>
三、EtcdRestore:etcdrestore
用來幫助將etcdbackup
服務所建立的備份恢復到一個指定的etcd的集羣。
apiVersion: etcd.database.coreos.com/v1beta2 kind: EtcdRestore metadata: # name must be same to the spec.etcdCluster.name name: example-etcd-cluster spec: etcdCluster: name: example-etcd-cluster backupStorageType: OSS oss: path: <full-oss-path> ossSecret: <oss-secret> endpoint: <endpoint>
一、部署etcd-operator
在Rancher最新的stable v2.3.2 的版本中,用戶可經過應用商店(Catalog)來一鍵式部署 etcd-operator v0.9.0版本,同時原生k8s也可下載rancher/charts到本地後經過helm install的方式進行部署。
1)(可選)部署etcd-operator時可選擇同時建立一個etcd集羣(此集羣在etcd-operator被刪除時會被一同移除),固然用戶也可待etcd-operator部署完成經過kubectl apply -f myetcd.yaml來建立一個新的etcd集羣。
2)部署時,若是用戶選擇啓動Enable Clusterwide of etcd Operator這個選項,那麼這個etcd-operator將做爲集羣層級對象來使用(不然爲namespaced隔離),若是enable這個選項,那麼在建立etcd集羣時需添加如下注釋才能建立建立:
kind: EtcdCluster metadata: name: etcd-cluster # add this annotation when the clusterWide is enabled annotations: etcd.database.coreos.com/scope: clusterwide
二、建立etcd集羣
接下來咱們就可使用上述的CRD自定義資源對象對來建立和管理咱們的etcd集羣了。
2.1 手動建立etcd集羣
cat <<EOF | kubectl apply -f - apiVersion: etcd.database.coreos.com/v1beta2 kind: EtcdCluster metadata: name: "etcd-cluster" spec: size: 3 # 默認etcd節點數 version: "3.2.25" # etcd版本號 EOF
2.2 部署後可經過CRD對象來查看咱們建立的etcd集羣和pod狀態
$ kubectl get etcdcluster NAME AGE etcd-cluster 2m $ kubectl get pod NAME READY STATUS RESTARTS AGE etcd-cluster-g28f552vvx 1/1 Running 0 2m etcd-cluster-lpftgqngl8 1/1 Running 0 2m etcd-cluster-sdpcfrtv99 1/1 Running 0 2m
2.3 能夠往etcd集羣任意的寫入幾條數據驗證etcd集羣是正常工做的(後續也可用來驗證集羣的備份和恢復功能)
$ kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE etcd-cluster ClusterIP None <none> 2379/TCP,2380/TCP 17h etcd-cluster-client ClusterIP 10.43.130.71 <none> 2379/TCP 17h ## write data $ kubectl exec -it any-etcd-pod -- env "ETCDCTL_API=3" etcdctl --endpoints http://etcd-cluster-client:2379 put foo "Hello World" ## get data $ kubectl exec -it any-etcd-pod -- env "ETCDCTL_API=3" etcdctl --endpoints http://etcd-cluster-client:2379 get foo foo Hello World
三、基於operator備份etcd cluster
3.1 確認了etcd集羣正常運行後,做爲devops後面要考慮的就是如何建立etcd集羣的自動化備份,下面以阿里雲的OSS舉例:
cat <<EOF | kubectl apply -f - apiVersion: etcd.database.coreos.com/v1beta2 kind: EtcdBackup metadata: name: example-etcd-cluster-periodic-backup spec: etcdEndpoints: [http://etcd-cluster-client:2379] #內網可以使用svc地址,外網可用NodePort或LB代理地址 storageType: OSS backupPolicy: backupIntervalInSecond: 120 #備份時間間隔 maxBackups: 4 #最大備份數 oss: path: my-bucket/etcd.backup ossSecret: oss-secret #需預先建立oss secret endpoint: oss-cn-hangzhou.aliyuncs.com EOF
3.2 若OSS Secret不存在,用戶可先手動建立,具體配置可參考以下:
cat << EOF | kubectl apply -f - apiVersion: v1 kind: Secret metadata: name: oss-secret type: Opaque stringData: accessKeyID: myAccessKey accessKeySecret: mySecret EOF
3.3 待etcdbackup建立成功後,用戶能夠經過kubectl describe etcdbackup或查看etcd-backup controller日誌來查看備份狀態,如狀態顯示爲Succeeded: true,能夠前往oss查看具體的備分內容。
四、基於operator恢復etcd cluster
最後,假設咱們要將etcd集羣A的備份數據恢復到另外一個新的etcd集羣B,那麼咱們先手動建立一個名爲etcd-cluster2的新集羣(oss備份/恢復當前需使用quay.io/coreos/etcd-operator:dev
鏡像)。
cat <<EOF | kubectl apply -f - apiVersion: etcd.database.coreos.com/v1beta2 kind: EtcdCluster metadata: name: "etcd-cluster2" spec: size: 3 version: "3.2.25" EOF
而後經過建立etcdresotre將備份數據恢復到etcd-cluster2集羣
cat <<EOF | kubectl apply -f - apiVersion: etcd.database.coreos.com/v1beta2 kind: EtcdRestore metadata: # name必須與下面的spec.etcdCluster.name保持一致 name: etcd-cluster2 spec: etcdCluster: name: etcd-cluster2 backupStorageType: OSS oss: path: my-bucket/etcd.backup_v1_2019-08-07-06:44:17 ossSecret: oss-secret endpoint: oss-cn-hangzhou.aliyuncs.com EOF
待etcdresotre對象建立成功後,能夠查看etcd-operator-restore的日誌,大體內容以下:
$ kubectl logs -f etcd-operator-restore ... time="2019-08-07T06:50:26Z" level=info msg="listening on 0.0.0.0:19999" time="2019-08-07T06:50:26Z" level=info msg="starting restore controller" pkg=controller time="2019-08-07T06:56:25Z" level=info msg="serving backup for restore CR etcd-cluster2"
經過kubectl查看pod咱們能夠看到etcd-cluster2
集羣的etcd節點被刪除重建:
NAME READY STATUS RESTARTS AGE etcd-cluster2-5tq2d5bvpf 0/1 Terminating 0 93s etcd-cluster2-kfgvc692pp 1/1 Terminating 0 101s etcd-cluster2-xqkgz8chb8 0/1 Init:1/3 0 6s etcd-cluster2-pf2qxgtg9d 1/1 Running 0 48s etcd-cluster2-x92l9vpx97 1/1 Running 0 40s
最後可經過etcdctl
來驗證以前的數據是否存在(需設置ETCDCTL_API=3
):
$ kubectl exec -it etcd-pod -- env "ETCDCTL_API=3" etcdctl --endpoints http://etcd-cluster2-client:2379 get foo foo Hello World
Etcd做爲當前很是流行的key-value分佈式文件存儲,它自己的強一致性和較優的性能能夠爲許多分佈式計算解決分佈式存儲的需求,若是你的微服務和應用須要用到此類的數據庫,不妨來試試Rancher Catalog應用中的etcd-operator吧,Just do it!
相關資料:
https://github.com/coreos/etcd-operator
https://coreos.com/blog/introducing-the-etcd-operator.html
https://github.com/rancher/charts/tree/master/charts/etcd-operator/v0.9.0