问题描述
有两个Pod,他的应用程序基于一个集群,即应用程序与另一个Pod同步以使其上线。假设在这个例子中,用户使用的是appod1和appod2,同步端口是8080。
用户希望DNS服务能解析这些Pod的主机名,但希望阻止外部流量访问appod1和appod2。
用户可以使用就绪探针,但是服务没有端点,无法解析第二个Pod的IP。如果无法从pod1解析第二个pod的IP,则无法完成这些pod的配置。
例如:
app1_sts.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
labels:
cluster: appcluster
name: app1
namespace: app
spec:
selector:
matchLabels:
cluster: appcluster
serviceName: app1cluster
template:
metadata:
labels:
cluster: appcluster
spec:
containers:
- name: app1-0
image: localhost/linux:8
imagePullPolicy: Always
securityContext:
privileged: false
command: [/usr/sbin/init]
ports:
- containerPort: 8080
name: appport
readinessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 120
periodSeconds: 30
failureThreshold: 20
env:
- name: container
value: "true"
- name: applist
value: "app2-0"
app2_sts.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
labels:
cluster: appcluster
name: app2
namespace: app
spec:
selector:
matchLabels:
cluster: appcluster
serviceName: app2cluster
template:
metadata:
labels:
cluster: appcluster
spec:
containers:
- name: app2-0
image: localhost/linux:8
imagePullPolicy: Always
securityContext:
privileged: false
command: [/usr/sbin/init]
ports:
- containerPort: 8080
name: appport
readinessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 120
periodSeconds: 30
failureThreshold: 20
env:
- name: container
value: "true"
- name: applist
value: "app1-0"
检查StatefulSet
[root@oper01 onprem]# kubectl get all -n app
NAME READY STATUS RESTARTS AGE
pod/app1-0 0/1 Running 0 8s
pod/app2-0 0/1 Running 0 22s
NAME READY AGE
statefulset.apps/app1 0/1 49s
statefulset.apps/app2 0/1 22s
kubectl exec -i -t app1-0 /bin/bash -n app
[root@app1-0 ~]# nslookup app2-0
Server: 10.96.0.10
Address: 10.96.0.10#53
** server can't find app2-0: NXDOMAIN
[root@app1-0 ~]# nslookup app1-0
Server: 10.96.0.10
Address: 10.96.0.10#53
** server can't find app1-0: NXDOMAIN
[root@app1-0 ~]#
用户理解就绪探针的行为,并使用它来确保服务在端口8080关闭时不会解析到app pods。然而,用户无法弄清楚如何完成配置,因为app pods需要相互解析,它们需要它们的主机名和IP来进行配置。只有在服务具有端点后,才能进行DNS解析。有没有更好的方法来处理这种情况?
解决方案
请注意以下操作注意版本差异及修改前做好备份。
方案1
您可以使用两个服务来解决这个问题。
其中一个服务应该设置一些spec.publishNotReadyAddresses: true
。您可以将其用于内部通信,在Pod还没有准备好的情况下初始化您的集群。
另一个服务将暴露您的集群给其客户端,并观察默认的就绪状态。
例如,对于Redis,您可以使用以下配置:
apiVersion: v1
kind: Service
metadata:
name: redis-kube
spec:
clusterIP: None
ports:
- name: tcp-6379
port: 6379
protocol: TCP
targetPort: 6379
- name: tcp-26379
port: 26379
protocol: TCP
targetPort: 26379
publishNotReadyAddresses: true
selector:
name: redis-kube
sessionAffinity: None
type: ClusterIP
另外,当尝试解析集群中其他容器的名称时,可以尝试使用nslookup <statefulset-pod-name>.<statefulset-spec.serviceName>.<statefulset.namespace>
,而不是nslookup app-0
。
例如,要解析app1-0,您可以使用nslookup app1-0.app1cluster.app
或nslookup app1-0.app1cluster.app.svc.cluster.local
。