我正在使用statefulset,并且启动了多个Pod,但它们不是彼此的副本。我想设置Pod的主机名,并将这些主机名作为env变量传递给所有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
答案 0 :(得分:0)
Kuberenetes已加入service discovery,因此您不必这样做。您可以为StatefulSet设置一个headless service,以让其他应用程序与之通信。
使用StatefulSets创建的Pod顺序排序和设置。因此,后缀整数值。您可以在here上阅读更多内容。
答案 1 :(得分:0)
根据文档:
StatefulSet是用于管理有状态应用程序的工作负载API对象。
管理一组Pod的部署和扩展,并保证这些Pod的顺序和唯一性。
StatefulSet对于需要以下一项或多项操作的应用程序很有价值:
Statefulset Limitations:
StatefulSet当前需要无头服务来负责Pod的网络标识。您负责创建此服务。
StatefulSet Pod具有一个唯一的身份,该身份由序数,稳定的网络身份和稳定的存储组成。无论将身份(安排在哪个节点上),身份都将固定在Pod上。 对于具有N个副本的StatefulSet,将为StatefulSet中的每个Pod分配一个从0到N-1的整数序数,该序数在Set上是唯一的。
StatefulSet中的每个Pod都从StatefulSet的名称和Pod的序数派生其主机名。 构造的主机名的模式为$(状态集名称)-$(普通)。 上面的示例将创建三个名为web-0,web-1,web-2的Pod。 StatefulSet可以使用无头服务来控制其Pod的域。此服务管理的域的格式为:$(服务名称)。$(名称空间).svc.cluster.local,其中“ cluster.local”是群集域。创建每个Pod时,它将获得一个匹配的DNS子域,格式为:$ {podname)。$ {governing service domain},其中控制服务由StatefulSet上的serviceName字段定义。
注意:
您负责创建负责Pod的网络标识的Headless服务。
因此,如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。您可以找到here的棘手方法。 利用Statefulset的上述优势:
构造的主机名的模式为$(状态集名称)-$(普通)。上面的示例将创建三个名为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
将为您做到这一点。
希望获得帮助。