![](/img/trans.png)
[英]How does StatefulSet assigns hostname to containers in Kubernetes
[英]How to set hostname for kubernetes pod in statefulset
我正在使用 statefulset 并且我启动了多个 pod,但它们不是彼此的副本。 我想设置 pod 的主机名并将这些主机名作为环境变量传递给所有 pod,以便它们可以相互通信。
我尝试在 pod 规范下使用主机名,但主机名永远不会设置为指定的主机名。 但是,它被设置为主机名作为 podname-0。
# Source: testrep/templates/statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: orbiting-butterfly-testrep
labels:
app.kubernetes.io/name: testrep
helm.sh/chart: testrep-0.1.0
app.kubernetes.io/instance: orbiting-butterfly
app.kubernetes.io/managed-by: Tiller
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: testrep
app.kubernetes.io/instance: orbiting-butterfly
strategy:
type: Recreate
template:
metadata:
labels:
app.kubernetes.io/name: testrep
app.kubernetes.io/instance: orbiting-butterfly
spec:
nodeSelector:
testol: ad3
hostname: test1
containers:
- name: testrep
image: "test/database:v1"
imagePullPolicy: IfNotPresent
env:
- name: DB_HOSTS
value: test1,test2,test3
根据文档:
StatefulSet 是用于管理有状态应用程序的工作负载 API object。
管理一组 Pod 的部署和扩展,并保证这些 Pod 的顺序和唯一性。
StatefulSets 对于需要以下一项或多项的应用程序很有价值:
状态集限制:
StatefulSets 目前需要一个 Headless Service 来负责 Pod 的网络身份。 您负责创建此服务。
StatefulSet Pod 具有唯一的身份,由序数、稳定的网络身份和稳定的存储组成。 身份坚持到 Pod,无论它(重新)调度在哪个节点上。 对于具有 N 个副本的 StatefulSet,StatefulSet 中的每个 Pod 将被分配一个 integer 序数,从 0 到 N-1,这在 Set 中是唯一的。
StatefulSet 中的每个 Pod 都从 StatefulSet 的名称和 Pod 的序号派生其主机名。 构造主机名的模式是 $(statefulset name)-$(ordinal) 。 上面的示例将创建三个名为 web-0,web-1,web-2 的 Pod 。 StatefulSet 可以使用 Headless Service 来控制其 Pod 的域。 此 Service 管理的域采用以下形式:$(service name).$(namespace).svc.cluster.local,其中“cluster.local”是集群域。 在创建每个 Pod 时,它会获得一个匹配的 DNS 子域,格式为:$(podname).$(governing service domain),其中管理服务由 StatefulSet 上的 serviceName 字段定义。
注意:
您负责创建负责 Pod 网络身份的 Headless Service。
因此,如vjdhama所述,请使用无头服务创建您的 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"
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
更新:
从 StatefulSet 暴露单个 pod。 你可以在这里找到棘手的方法。 使用 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
会为你做这件事。
希望这有帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.