# StatefulSet
StatefulSet 作為 Controller 為 Pod 提供唯一的標識。它可以保證部署和 scale 的順序。
使用案例參考:[kubernetes contrib - statefulsets](https://github.com/kubernetes/contrib/tree/master/statefulsets),其中包含zookeeper和kakfa的statefulset設置和使用說明。
StatefulSet是為了解決有狀態服務的問題(對應Deployments和ReplicaSets是為無狀態服務而設計),其應用場景包括:
- 穩定的持久化存儲,即Pod重新調度后還是能訪問到相同的持久化數據,基于PVC來實現
- 穩定的網絡標志,即Pod重新調度后其PodName和HostName不變,基于Headless Service(即沒有Cluster IP的Service)來實現
- 有序部署,有序擴展,即Pod是有順序的,在部署或者擴展的時候要依據定義的順序依次依次進行(即從0到N-1,在下一個Pod運行之前所有之前的Pod必須都是Running和Ready狀態),基于init containers來實現
- 有序收縮,有序刪除(即從N-1到0)
從上面的應用場景可以發現,StatefulSet由以下幾個部分組成:
- 用于定義網絡標志(DNS domain)的Headless Service
- 用于創建PersistentVolumes的volumeClaimTemplates
- 定義具體應用的StatefulSet
StatefulSet中每個Pod的DNS格式為`statefulSetName-{0..N-1}.serviceName.namespace.svc.cluster.local`,其中
- `serviceName`為Headless Service的名字
- `0..N-1`為Pod所在的序號,從0開始到N-1
- `statefulSetName`為StatefulSet的名字
- `namespace`為服務所在的namespace,Headless Servic和StatefulSet必須在相同的namespace
- `.cluster.local`為Cluster Domain
## 使用 StatefulSet
StatefulSet 適用于有以下某個或多個需求的應用:
- 穩定,唯一的網絡標志。
- 穩定,持久化存儲。
- 有序,優雅地部署和 scale。
- 有序,優雅地刪除和終止。
- 有序,自動的滾動升級。
在上文中,穩定是 Pod (重新)調度中持久性的代名詞。 如果應用程序不需要任何穩定的標識符、有序部署、刪除和 scale,則應該使用提供一組無狀態副本的 controller 來部署應用程序,例如 [Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment) 或 [ReplicaSet](https://kubernetes.io/docs/concepts/workloads/controllers/replicaset) 可能更適合您的無狀態需求。
## 限制
- StatefulSet 是 beta 資源,Kubernetes 1.5 以前版本不支持。
- 對于所有的 alpha/beta 的資源,您都可以通過在 apiserver 中設置 `--runtime-config` 選項來禁用。
- 給定 Pod 的存儲必須由 PersistentVolume Provisioner 根據請求的 `storage class` 進行配置,或由管理員預先配置。
- 刪除或 scale StatefulSet 將_不會_刪除與 StatefulSet 相關聯的 volume。 這樣做是為了確保數據安全性,這通常比自動清除所有相關 StatefulSet 資源更有價值。
- StatefulSets 目前要求 [Headless Service](https://kubernetes.io/docs/concepts/services-networking/service/#headless-services) 負責 Pod 的網絡身份。 您有責任創建此服務。
## 組件
下面的示例中描述了 StatefulSet 中的組件。
- 一個名為 nginx 的 headless service,用于控制網絡域。
- 一個名為 web 的 StatefulSet,它的 Spec 中指定在有 3 個運行 nginx 容器的 Pod。
- volumeClaimTemplates 使用 PersistentVolume Provisioner 提供的 [PersistentVolumes](https://kubernetes.io/docs/concepts/storage/volumes) 作為穩定存儲。
```yaml
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
---
apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "nginx"
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
terminationGracePeriodSeconds: 10
containers:
- name: nginx
image: gcr.io/google_containers/nginx-slim:0.8
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
annotations:
volume.beta.kubernetes.io/storage-class: anything
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 1Gi
```
## Pod 身份
StatefulSet Pod 具有唯一的身份,包括序數,穩定的網絡身份和穩定的存儲。 身份綁定到 Pod 上,不管它(重新)調度到哪個節點上。
### 序數
對于一個有 N 個副本的 StatefulSet,每個副本都會被指定一個整數序數,在 [0,N)之間,且唯一。
## 穩定的網絡 ID
StatefulSet 中的每個 Pod 從 StatefulSet 的名稱和 Pod 的序數派生其主機名。構造的主機名的模式是`$(statefulset名稱)-$(序數)`。 上面的例子將創建三個名為`web-0,web-1,web-2`的 Pod。
StatefulSet 可以使用 [Headless Service](https://kubernetes.io/docs/concepts/services-networking/service/#headless-services) 來控制其 Pod 的域。此服務管理的域的格式為:`$(服務名稱).$(namespace).svc.cluster.local`,其中 “cluster.local” 是集群域。
在創建每個Pod時,它將獲取一個匹配的 DNS 子域,采用以下形式:`$(pod 名稱).$(管理服務域)`,其中管理服務由 StatefulSet 上的 `serviceName` 字段定義。
以下是 Cluster Domain,服務名稱,StatefulSet 名稱以及如何影響 StatefulSet 的 Pod 的 DNS 名稱的一些示例。
| Cluster Domain | Service (ns/name) | StatefulSet (ns/name) | StatefulSet Domain | Pod DNS | Pod Hostname |
| -------------- | ----------------- | --------------------- | ------------------------------- | ---------------------------------------- | ------------ |
| cluster.local | default/nginx | default/web | nginx.default.svc.cluster.local | web-{0..N-1}.nginx.default.svc.cluster.local | web-{0..N-1} |
| cluster.local | foo/nginx | foo/web | nginx.foo.svc.cluster.local | web-{0..N-1}.nginx.foo.svc.cluster.local | web-{0..N-1} |
| kube.local | foo/nginx | foo/web | nginx.foo.svc.kube.local | web-{0..N-1}.nginx.foo.svc.kube.local | web-{0..N-1} |
注意 Cluster Domain 將被設置成 `cluster.local` 除非進行了其他配置。
### 穩定存儲
Kubernetes 為每個 VolumeClaimTemplate 創建一個 [PersistentVolume](https://kubernetes.io/docs/concepts/storage/volumes)。上面的 nginx 的例子中,每個 Pod 將具有一個由 `anything` 存儲類創建的 1 GB 存儲的 PersistentVolume。當該 Pod (重新)調度到節點上,`volumeMounts` 將掛載與 PersistentVolume Claim 相關聯的 PersistentVolume。請注意,與 PersistentVolume Claim 相關聯的 PersistentVolume 在 產出 Pod 或 StatefulSet 的時候不會被刪除。這必須手動完成。
## 部署和 Scale 保證
- 對于有 N 個副本的 StatefulSet,Pod 將按照 {0..N-1} 的順序被創建和部署。
- 當 刪除 Pod 的時候,將按照逆序來終結,從{N-1..0}
- 對 Pod 執行 scale 操作之前,它所有的前任必須處于 Running 和 Ready 狀態。
- 在終止 Pod 前,它所有的繼任者必須處于完全關閉狀態。
不應該將 StatefulSet 的 `pod.Spec.TerminationGracePeriodSeconds` 設置為 0。這樣是不安全的且強烈不建議您這樣做。進一步解釋,請參閱 [強制刪除 StatefulSet Pod](https://kubernetes.io/docs/tasks/run-application/force-delete-stateful-set-pod)。
上面的 nginx 示例創建后,3 個 Pod 將按照如下順序創建 web-0,web-1,web-2。在 web-0 處于 [運行并就緒](https://kubernetes.io/docs/user-guide/pod-states) 狀態之前,web-1 將不會被部署,同樣當 web-1 處于運行并就緒狀態之前 web-2也不會被部署。如果在 web-1 運行并就緒后,web-2 啟動之前, web-0 失敗了,web-2 將不會啟動,直到 web-0 成功重啟并處于運行并就緒狀態。
如果用戶通過修補 StatefulSet 來 scale 部署的示例,以使 `replicas=1`,則 web-2 將首先被終止。 在 web-2 完全關閉和刪除之前,web-1 不會被終止。 如果 web-0 在 web-2 終止并且完全關閉之后,但是在 web-1 終止之前失敗,則 web-1 將不會終止,除非 web-0 正在運行并準備就緒。
### Pod 管理策略
在 Kubernetes 1.7 和之后版本,StatefulSet 允許您放開順序保證,同時通過 `.spec.podManagementPolicy` 字段保證身份的唯一性。
#### OrderedReady Pod 管理
StatefulSet 中默認使用的是 `OrderedReady` pod 管理。它實現了 [如上](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset.md#deployment-and-scaling-guarantees) 所述的行為。
#### 并行 Pod 管理
`Parallel` pod 管理告訴 StatefulSet controller 并行的啟動和終止 Pod,在啟動和終止其他 Pod 之前不會等待 Pod 變成 運行并就緒或完全終止狀態。
## 更新策略
在 kubernetes 1.7 和以上版本中,StatefulSet 的 `.spec.updateStrategy` 字段允許您配置和禁用 StatefulSet 中的容器、label、resource request/limit、annotation 的滾動更新。
### 刪除
`OnDelete` 更新策略實現了遺留(1.6和以前)的行為。 當 `spec.updateStrategy` 未指定時,這是默認策略。 當StatefulSet 的 `.spec.updateStrategy.type` 設置為 `OnDelete` 時,StatefulSet 控制器將不會自動更新 `StatefulSet` 中的 Pod。 用戶必須手動刪除 Pod 以使控制器創建新的 Pod,以反映對StatefulSet的 `.spec.template` 進行的修改。
### 滾動更新
`RollingUpdate` 更新策略在 StatefulSet 中實現 Pod 的自動滾動更新。 當StatefulSet的 `.spec.updateStrategy.type` 設置為 `RollingUpdate` 時,StatefulSet 控制器將在 StatefulSet 中刪除并重新創建每個 Pod。 它將以與 Pod 終止相同的順序進行(從最大的序數到最小的序數),每次更新一個 Pod。 在更新其前身之前,它將等待正在更新的 Pod 狀態變成正在運行并就緒。
#### 分區
可以通過指定 `.spec.updateStrategy.rollingUpdate.partition` 來對 `RollingUpdate` 更新策略進行分區。如果指定了分區,則當 StatefulSet 的 `.spec.template` 更新時,具有大于或等于分區序數的所有 Pod 將被更新。具有小于分區的序數的所有 Pod 將不會被更新,即使刪除它們也將被重新創建。如果 StatefulSet 的 `.spec.updateStrategy.rollingUpdate.partition` 大于其 `.spec.replicas`,則其 `.spec.template` 的更新將不會傳播到 Pod。
在大多數情況下,您不需要使用分區,但如果您想要進行分階段更新,使用金絲雀發布或執行分階段發布,它們將非常有用。
## 簡單示例
以一個簡單的nginx服務[web.yaml](https://github.com/rootsongjc/kubernetes-handbook/blob/master/manifests/test/web.yaml)為例:
```yaml
---
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
---
apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "nginx"
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: gcr.io/google_containers/nginx-slim:0.8
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
annotations:
volume.alpha.kubernetes.io/storage-class: anything
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 1Gi
```
```sh
$ kubectl create -f web.yaml
service "nginx" created
statefulset "web" created
# 查看創建的headless service和statefulset
$ kubectl get service nginx
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx None <none> 80/TCP 1m
$ kubectl get statefulset web
NAME DESIRED CURRENT AGE
web 2 2 2m
# 根據volumeClaimTemplates自動創建PVC(在GCE中會自動創建kubernetes.io/gce-pd類型的volume)
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESSMODES AGE
www-web-0 Bound pvc-d064a004-d8d4-11e6-b521-42010a800002 1Gi RWO 16s
www-web-1 Bound pvc-d06a3946-d8d4-11e6-b521-42010a800002 1Gi RWO 16s
# 查看創建的Pod,他們都是有序的
$ kubectl get pods -l app=nginx
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 5m
web-1 1/1 Running 0 4m
# 使用nslookup查看這些Pod的DNS
$ kubectl run -i --tty --image busybox dns-test --restart=Never --rm /bin/sh
/ # nslookup web-0.nginx
Server: 10.0.0.10
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
Name: web-0.nginx
Address 1: 10.244.2.10
/ # nslookup web-1.nginx
Server: 10.0.0.10
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
Name: web-1.nginx
Address 1: 10.244.3.12
/ # nslookup web-0.nginx.default.svc.cluster.local
Server: 10.0.0.10
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
Name: web-0.nginx.default.svc.cluster.local
Address 1: 10.244.2.10
```
還可以進行其他的操作
```sh
# 擴容
$ kubectl scale statefulset web --replicas=5
# 縮容
$ kubectl patch statefulset web -p '{"spec":{"replicas":3}}'
# 鏡像更新(目前還不支持直接更新image,需要patch來間接實現)
$ kubectl patch statefulset web --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"gcr.io/google_containers/nginx-slim:0.7"}]'
# 刪除StatefulSet和Headless Service
$ kubectl delete statefulset web
$ kubectl delete service nginx
# StatefulSet刪除后PVC還會保留著,數據不再使用的話也需要刪除
$ kubectl delete pvc www-web-0 www-web-1
```
## zookeeper
另外一個更能說明StatefulSet強大功能的示例為[zookeeper.yaml](https://github.com/rootsongjc/kubernetes-handbook/blob/master/manifests/test/zookeeper.yaml),這個例子僅為講解,實際可用的配置請使用 https://github.com/kubernetes/contrib/tree/master/statefulsets 中的配置。
```yaml
---
apiVersion: v1
kind: Service
metadata:
name: zk-headless
labels:
app: zk-headless
spec:
ports:
- port: 2888
name: server
- port: 3888
name: leader-election
clusterIP: None
selector:
app: zk
---
apiVersion: v1
kind: ConfigMap
metadata:
name: zk-config
data:
ensemble: "zk-0;zk-1;zk-2"
jvm.heap: "2G"
tick: "2000"
init: "10"
sync: "5"
client.cnxns: "60"
snap.retain: "3"
purge.interval: "1"
---
apiVersion: policy/v1beta1
kind: PodDisruptionBudget
metadata:
name: zk-budget
spec:
selector:
matchLabels:
app: zk
minAvailable: 2
---
apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
name: zk
spec:
serviceName: zk-headless
replicas: 3
template:
metadata:
labels:
app: zk
annotations:
pod.alpha.kubernetes.io/initialized: "true"
scheduler.alpha.kubernetes.io/affinity: >
{
"podAntiAffinity": {
"requiredDuringSchedulingRequiredDuringExecution": [{
"labelSelector": {
"matchExpressions": [{
"key": "app",
"operator": "In",
"values": ["zk-headless"]
}]
},
"topologyKey": "kubernetes.io/hostname"
}]
}
}
spec:
containers:
- name: k8szk
imagePullPolicy: Always
image: gcr.io/google_samples/k8szk:v1
resources:
requests:
memory: "4Gi"
cpu: "1"
ports:
- containerPort: 2181
name: client
- containerPort: 2888
name: server
- containerPort: 3888
name: leader-election
env:
- name : ZK_ENSEMBLE
valueFrom:
configMapKeyRef:
name: zk-config
key: ensemble
- name : ZK_HEAP_SIZE
valueFrom:
configMapKeyRef:
name: zk-config
key: jvm.heap
- name : ZK_TICK_TIME
valueFrom:
configMapKeyRef:
name: zk-config
key: tick
- name : ZK_INIT_LIMIT
valueFrom:
configMapKeyRef:
name: zk-config
key: init
- name : ZK_SYNC_LIMIT
valueFrom:
configMapKeyRef:
name: zk-config
key: tick
- name : ZK_MAX_CLIENT_CNXNS
valueFrom:
configMapKeyRef:
name: zk-config
key: client.cnxns
- name: ZK_SNAP_RETAIN_COUNT
valueFrom:
configMapKeyRef:
name: zk-config
key: snap.retain
- name: ZK_PURGE_INTERVAL
valueFrom:
configMapKeyRef:
name: zk-config
key: purge.interval
- name: ZK_CLIENT_PORT
value: "2181"
- name: ZK_SERVER_PORT
value: "2888"
- name: ZK_ELECTION_PORT
value: "3888"
command:
- sh
- -c
- zkGenConfig.sh && zkServer.sh start-foreground
readinessProbe:
exec:
command:
- "zkOk.sh"
initialDelaySeconds: 15
timeoutSeconds: 5
livenessProbe:
exec:
command:
- "zkOk.sh"
initialDelaySeconds: 15
timeoutSeconds: 5
volumeMounts:
- name: datadir
mountPath: /var/lib/zookeeper
securityContext:
runAsUser: 1000
fsGroup: 1000
volumeClaimTemplates:
- metadata:
name: datadir
annotations:
volume.alpha.kubernetes.io/storage-class: anything
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 20Gi
```
```sh
kubectl create -f zookeeper.yaml
```
詳細的使用說明見[zookeeper stateful application](https://kubernetes.io/docs/tutorials/stateful-application/zookeeper/)。
關于StatefulSet的更多示例請參閱 [github.com/kubernetes/contrib - statefulsets](https://github.com/kubernetes/contrib/tree/master/statefulsets),其中包括了zookeeper和kafka。
## 集群外部訪問StatefulSet的Pod
我們設想一下這樣的場景:在kubernetes集群外部調試StatefulSet中有序的Pod,那么如何訪問這些的pod呢?
方法是為pod設置label,然后用`kubectl expose`將其以NodePort的方式暴露到集群外部,以上面的zookeeper的例子來說明,下面使用命令的方式來暴露其中的兩個zookeeper節點,也可以寫一個serivce配置yaml文件。
```bash
kubectl label pod zk-0 zkInst=0
kubectl label pod zk-1 zkInst=1
kubectl expose po zk-0 --port=2181 --target-port=2181 --name=zk-0 --selector=zkInst=0 --type=NodePort
kubectl expose po zk-1 --port=2181 --target-port=2181 --name=zk-1 --selector=zkInst=1 --type=NodePort
```
這樣在kubernetes集群外部就可以根據pod所在的主機所映射的端口來訪問了。
查看`zk-0`這個service可以看到如下結果:
```
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
zk-0 10.254.98.14 <nodes> 2181:31693/TCP 5m
```
集群外部就可以使用所有的node中的任何一個IP:31693來訪問這個zookeeper實例。
## 參考
https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/
[kubernetes contrib - statefulsets](https://github.com/kubernetes/contrib/tree/master/statefulsets)
- 序言
- 云原生
- 云原生(Cloud Native)的定義
- CNCF - 云原生計算基金會簡介
- CNCF章程
- 云原生的設計哲學
- Play with Kubernetes
- 快速部署一個云原生本地實驗環境
- Kubernetes與云原生應用概覽
- 云原生應用之路——從Kubernetes到Cloud Native
- 云原生編程語言
- 云原生編程語言Ballerina
- 云原生編程語言Pulumi
- 云原生的未來
- Kubernetes架構
- 設計理念
- Etcd解析
- 開放接口
- CRI - Container Runtime Interface(容器運行時接口)
- CNI - Container Network Interface(容器網絡接口)
- CSI - Container Storage Interface(容器存儲接口)
- Kubernetes中的網絡
- Kubernetes中的網絡解析——以flannel為例
- Kubernetes中的網絡解析——以calico為例
- 具備API感知的網絡和安全性管理開源軟件Cilium
- Cilium架構設計與概念解析
- 資源對象與基本概念解析
- Pod狀態與生命周期管理
- Pod概覽
- Pod解析
- Init容器
- Pause容器
- Pod安全策略
- Pod的生命周期
- Pod Hook
- Pod Preset
- Pod中斷與PDB(Pod中斷預算)
- 集群資源管理
- Node
- Namespace
- Label
- Annotation
- Taint和Toleration(污點和容忍)
- 垃圾收集
- 控制器
- Deployment
- StatefulSet
- DaemonSet
- ReplicationController和ReplicaSet
- Job
- CronJob
- Horizontal Pod Autoscaling
- 自定義指標HPA
- 準入控制器(Admission Controller)
- 服務發現
- Service
- Ingress
- Traefik Ingress Controller
- 身份與權限控制
- ServiceAccount
- RBAC——基于角色的訪問控制
- NetworkPolicy
- 存儲
- Secret
- ConfigMap
- ConfigMap的熱更新
- Volume
- Persistent Volume(持久化卷)
- Storage Class
- 本地持久化存儲
- 集群擴展
- 使用自定義資源擴展API
- 使用CRD擴展Kubernetes API
- Aggregated API Server
- APIService
- Service Catalog
- 資源調度
- QoS(服務質量等級)
- 用戶指南
- 資源對象配置
- 配置Pod的liveness和readiness探針
- 配置Pod的Service Account
- Secret配置
- 管理namespace中的資源配額
- 命令使用
- Docker用戶過度到kubectl命令行指南
- kubectl命令概覽
- kubectl命令技巧大全
- 使用etcdctl訪問kubernetes數據
- 集群安全性管理
- 管理集群中的TLS
- kubelet的認證授權
- TLS bootstrap
- 創建用戶認證授權的kubeconfig文件
- IP偽裝代理
- 使用kubeconfig或token進行用戶身份認證
- Kubernetes中的用戶與身份認證授權
- Kubernetes集群安全性配置最佳實踐
- 訪問Kubernetes集群
- 訪問集群
- 使用kubeconfig文件配置跨集群認證
- 通過端口轉發訪問集群中的應用程序
- 使用service訪問群集中的應用程序
- 從外部訪問Kubernetes中的Pod
- Cabin - Kubernetes手機客戶端
- Kubernetic - Kubernetes桌面客戶端
- Kubernator - 更底層的Kubernetes UI
- 在Kubernetes中開發部署應用
- 適用于kubernetes的應用開發部署流程
- 遷移傳統應用到Kubernetes中——以Hadoop YARN為例
- 最佳實踐概覽
- 在CentOS上部署Kubernetes集群
- 創建TLS證書和秘鑰
- 創建kubeconfig文件
- 創建高可用etcd集群
- 安裝kubectl命令行工具
- 部署master節點
- 安裝flannel網絡插件
- 部署node節點
- 安裝kubedns插件
- 安裝dashboard插件
- 安裝heapster插件
- 安裝EFK插件
- 生產級的Kubernetes簡化管理工具kubeadm
- 使用kubeadm在Ubuntu Server 16.04上快速構建測試集群
- 服務發現與負載均衡
- 安裝Traefik ingress
- 分布式負載測試
- 網絡和集群性能測試
- 邊緣節點配置
- 安裝Nginx ingress
- 安裝配置DNS
- 安裝配置Kube-dns
- 安裝配置CoreDNS
- 運維管理
- Master節點高可用
- 服務滾動升級
- 應用日志收集
- 配置最佳實踐
- 集群及應用監控
- 數據持久化問題
- 管理容器的計算資源
- 集群聯邦
- 存儲管理
- GlusterFS
- 使用GlusterFS做持久化存儲
- 使用Heketi作為Kubernetes的持久存儲GlusterFS的external provisioner
- 在OpenShift中使用GlusterFS做持久化存儲
- GlusterD-2.0
- Ceph
- 用Helm托管安裝Ceph集群并提供后端存儲
- 使用Ceph做持久化存儲
- 使用rbd-provisioner提供rbd持久化存儲
- OpenEBS
- 使用OpenEBS做持久化存儲
- Rook
- NFS
- 利用NFS動態提供Kubernetes后端存儲卷
- 集群與應用監控
- Heapster
- 使用Heapster獲取集群和對象的metric數據
- Prometheus
- 使用Prometheus監控kubernetes集群
- Prometheus查詢語言PromQL使用說明
- 使用Vistio監控Istio服務網格中的流量
- 分布式跟蹤
- OpenTracing
- 服務編排管理
- 使用Helm管理Kubernetes應用
- 構建私有Chart倉庫
- 持續集成與發布
- 使用Jenkins進行持續集成與發布
- 使用Drone進行持續集成與發布
- 更新與升級
- 手動升級Kubernetes集群
- 升級dashboard
- 領域應用概覽
- 微服務架構
- 微服務中的服務發現
- 使用Java構建微服務并發布到Kubernetes平臺
- Spring Boot快速開始指南
- Service Mesh 服務網格
- 企業級服務網格架構
- Service Mesh基礎
- Service Mesh技術對比
- 采納和演進
- 定制和集成
- 總結
- Istio
- 安裝并試用Istio service mesh
- 配置請求的路由規則
- 安裝和拓展Istio service mesh
- 集成虛擬機
- Istio中sidecar的注入規范及示例
- 如何參與Istio社區及注意事項
- Istio教程
- Istio免費學習資源匯總
- 深入理解Istio Service Mesh中的Envoy Sidecar注入與流量劫持
- 深入理解Istio Service Mesh中的Envoy Sidecar代理的路由轉發
- Linkerd
- Linkerd 使用指南
- Conduit
- Condiut概覽
- 安裝Conduit
- Envoy
- Envoy的架構與基本術語
- Envoy作為前端代理
- Envoy mesh教程
- SOFAMesh
- SOFAMesh中的Dubbo on x-protocol
- SOFAMosn
- 使用 SOFAMosn 構建 SOFAMesh
- 大數據
- Spark standalone on Kubernetes
- 運行支持Kubernetes原生調度的Spark程序
- Serverless架構
- 理解Serverless
- FaaS-函數即服務
- OpenFaaS快速入門指南
- 邊緣計算
- 人工智能