124 lines
5.3 KiB
Markdown
124 lines
5.3 KiB
Markdown
---
|
||
layout: LearningLayout
|
||
description: 本文描述了 Kubernetes StatefulSet 的基本信息:Components、Pod Selector、Pod Identity
|
||
---
|
||
|
||
# StatefulSet 的基本信息
|
||
|
||
[返回 StatefulSet](./)
|
||
|
||
## 创建 StatefulSet
|
||
|
||
下面是一个 StatefulSet 的例子,由如下内容组成:
|
||
* 一个名为 nginx 的 [Headless Service](https://kubernetes.io/docs/concepts/services-networking/service/#headless-service),用于控制网络域
|
||
* 一个名为 web 的StatefulSet,副本数为 3
|
||
* volumeClaimTemplates 提供稳定的存储(每一个 Pod ID 对应自己的存储卷,且 Pod 重建后,仍然能找到对应的存储卷)
|
||
|
||
``` yaml
|
||
apiVersion: v1
|
||
kind: Service
|
||
metadata:
|
||
name: nginx
|
||
labels:
|
||
app: nginx
|
||
spec:
|
||
ports:
|
||
- port: 80
|
||
name: web
|
||
clusterIP: None
|
||
selector:
|
||
app: nginx
|
||
---
|
||
apiVersion: apps/v1
|
||
kind: StatefulSet
|
||
metadata:
|
||
name: web
|
||
spec:
|
||
selector:
|
||
matchLabels:
|
||
app: nginx # has to match .spec.template.metadata.labels
|
||
serviceName: "nginx"
|
||
replicas: 3 # by default is 1
|
||
template:
|
||
metadata:
|
||
labels:
|
||
app: nginx # has to match .spec.selector.matchLabels
|
||
spec:
|
||
terminationGracePeriodSeconds: 10
|
||
containers:
|
||
- name: nginx
|
||
image: nginx:1.7.9
|
||
ports:
|
||
- containerPort: 80
|
||
name: web
|
||
volumeMounts:
|
||
- name: www
|
||
mountPath: /usr/share/nginx/html
|
||
volumeClaimTemplates:
|
||
- metadata:
|
||
name: www
|
||
spec:
|
||
accessModes: [ "ReadWriteOnce" ]
|
||
storageClassName: "my-storage-class"
|
||
resources:
|
||
requests:
|
||
storage: 1Gi
|
||
```
|
||
|
||
## Pod 的标识
|
||
|
||
StatefulSet 中的 Pod 具备一个唯一标识,该标识由以下几部分组成:
|
||
* 序号
|
||
* 稳定的网络标识
|
||
* 稳定的存储
|
||
|
||
该标识始终与 Pod 绑定,无论该 Pod 被调度(重新调度)到哪一个节点上。
|
||
|
||
### 序号
|
||
|
||
假设一个 StatefulSet 的副本数为 N,其中的每一个 Pod 都会被分配一个序号,序号的取值范围从 0 到 N - 1,并且该序号在 StatefulSet 内部是唯一的。
|
||
|
||
### 稳定的网络 ID
|
||
|
||
* StatefulSet 中 Pod 的 hostname 格式为 $(StatefulSet name)-$(Pod 序号)。上面的例子将要创建三个 Pod,其名称分别为: web-0,web-1,web-2。
|
||
* StatefulSet 可以使用 Headless Service 来控制其 Pod 所在的域。该域(domain)的格式为 $(service name).$(namespace).svc.cluster.local,其中 “cluster.local” 是集群的域。
|
||
* StatefulSet 中每一个 Pod 将被分配一个 dnsName,格式为: $(podName).$(所在域名)
|
||
|
||
::: tip
|
||
您需要自行为 StatefulSet 创建 Headless Service。
|
||
:::
|
||
|
||
下表列出了不同的 集群域、Service name、StatefulSet name 的情况下,对应的 StatefulSet 中 Pod 的 DNS 名字:
|
||
|
||
|
||
|
||
| 字段名 | 组合一 | 组合二 | 组合三 |
|
||
| --------------------- | -------------------------------------------- | ---------------------------------------- | ------------------------------------- |
|
||
| **集群域 Cluster Domain** | cluster.local | cluster.local | cluster.local |
|
||
| **Service name** | default/nginx | foo/nginx | foo/nginx |
|
||
| **StatefulSet name** | default/web | foo/web | foo/web |
|
||
| **StatefulSet Domain** | nginx.default.svc.cluster.local | nginx.foo.svc.cluster.local | nginx.foo.svc.kube.local |
|
||
| **Pod DNS** | web-{0..N-1}.nginx.default.svc.cluster.local | web-{0..N-1}.nginx.foo.svc.cluster.local | web-{0..N-1}.nginx.foo.svc.kube.local |
|
||
| **Pod name** | web-{0..N-1} | web-{0..N-1} | web-{0..N-1} |
|
||
|
||
### 稳定的存储
|
||
|
||
Kubernetes 为每一个 VolumeClaimTemplate 创建一份 PersistentVolume(存储卷)。在上面的例子中,每一个 Pod 都将由 StorageClass(存储类)`my-storage-class` 为其创建一个 1Gib 大小的 PersistentVolume(存储卷)。当 Pod 被调度(或重新调度)到一个节点上,其挂载点将挂载该存储卷声明(关联到该 PersistentVolume)。
|
||
|
||
::: tip
|
||
* 当 Pod 或 StatefulSet 被删除时,其关联的 PersistentVolumeClaim(存储卷声明)以及其背后的 PersistentVolume(存储卷)仍然存在。
|
||
* 如果相同的 Pod 或 StatefulSet 被再次创建,则,新建的名为 web-0 的 Pod 仍将挂载到原来名为 web-0 的 Pod 所挂载的存储卷声明及存储卷。
|
||
* 这确保了 web-0、web-1、web-2 等,不管被删除重建多少次,都将 “稳定” 的使用各自所对应的存储内容
|
||
:::
|
||
|
||
### Pod name 标签
|
||
|
||
当 StatefulSet 控制器创建一个 Pod 时,会为 Pod 添加一个标签(label) `statefulset.kubernetes.io/pod-name` 且该标签的值为 Pod 的名字。您可以利用此名字,StatefulSet 中的某一个特定的 Pod 关联一个 Service。
|
||
|
||
::: tip
|
||
实际操作中,您无需为 StatefulSet 中的一个特定 Pod 关联 Service,因为您可以直接通过该 Pod 的 DNS Name 访问到 Pod。
|
||
:::
|
||
|
||
|
||
[返回 StatefulSet](./)
|