- 根据文档:
StatefulSet 是用于管理有状态应用程序的工作负载 API 对象。
管理一组 Pod 的部署和扩展,并提供有关这些 Pod 的顺序和唯一性的保证。
StatefulSet 对于需要以下一项或多项的应用程序非常有价值:
-
稳定、唯一的网络标识符.
- 稳定、持久的存储。
- 有序、优雅的部署和扩展。
- 有序、自动滚动更新。
- 有状态集局限性 https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#limitations:
StatefulSet 目前需要 Headless Service 来负责 Pod 的网络身份。您负责创建此服务。
- Pod 身份 https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#pod-identity
StatefulSet Pod 具有唯一的身份,由序数、稳定的网络身份和稳定的存储组成。无论 Pod 被(重新)调度到哪个节点,身份都会保留在 Pod 上。对于具有 N 个副本的 StatefulSet,StatefulSet 中的每个 Pod 都将被分配一个从 0 到 N-1 的整数序数,该序数在 Set 中是唯一的.
- 稳定的网络ID https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#stable-network-id
StatefulSet 中的每个 Pod 都从 StatefulSet 的名称和 Pod 的序号中派生出其主机名。构造的主机名的模式是 $(statefulset name)-$(ordinal). 上面的示例将创建三个名为 web-0、web-1、web-2 的 Pod。 StatefulSet 可以使用 Headless Service 来控制其 Pod 的域。此服务管理的域采用以下形式:$(服务名称).$(命名空间).svc.cluster.local,其中“cluster.local”是集群域。创建每个 Pod 时,它都会获得一个匹配的 DNS 子域,格式为:$(podname).$(governing service domain),其中管理服务由 StatefulSet 上的 serviceName 字段定义。
Note:
您负责创建负责 Pod 网络身份的 Headless Service。
正如所描述的vjdhama https://stackoverflow.com/a/58669371/11207414请使用 Headless Service 创建您的 Statefulset。
您可以在文档中找到此示例:
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" # has to match headless Service metadata.name
replicas: 3 # by default is 1
template:
metadata:
labels:
app: nginx # has to match .spec.selector.matchLabels
spec:
terminationGracePeriodSeconds: 10
containers:
- name: nginx
image: k8s.gcr.io/nginx-slim:0.8
ports:
- containerPort: 80
在这种情况下,Pod DNS 和 Pod 主机名应分别为:
Pod DNS
web-{0..N-1}.nginx.default.svc.cluster.local
Pod Hostname
web-{0..N-1}
NAME READY STATUS RESTARTS AGE IP
pod/web-0 1/1 Running 0 5m 192.168.148.78
pod/web-1 1/1 Running 0 4m53s 192.168.148.79
pod/web-2 1/1 Running 0 4m51s 192.168.148.80
从 Pod 角度来看:
root@web-2:# nslookup nginx
Server: 10.96.0.10
Address: 10.96.0.10#53
Name: nginx.default.svc.cluster.local
Address: 192.168.148.80
Name: nginx.default.svc.cluster.local
Address: 192.168.148.78
Name: nginx.default.svc.cluster.local
Address: 192.168.148.79
因此,您可以使用 Pod DNS 调用每个相应的 Pod,例如:
web-0.nginx.default.svc.cluster.local
Update:
从 StatefulSet 公开单个 pod。
Pod 名称标签
StatefulSet控制器创建Pod时,会添加一个标签,statefulset.kubernetes.io/pod-name
,设置为 Pod 的名称。该标签允许您将 Service 附加到 StatefulSet 中的特定 Pod。
https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#pod-name-label https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#pod-name-label
你可以找到here https://itnext.io/exposing-statefulsets-in-kubernetes-698730fb92a1棘手的方式。
使用上述 Statefulset 的优点:
构造的主机名的模式是 $(statefulset name)-$(ordinal)。上面的示例将创建三个名为 web-0、web-1、web-2 的 Pod。
举个例子:
apiVersion: v1
kind: Service
metadata:
name: app-0
spec:
type: LoadBalancer
selector:
statefulset.kubernetes.io/pod-name: web-0
ports:
- protocol: TCP
port: 80
targetPort: 80
将为您做这件事。
希望这有帮助。