Kubernetes在一个pod中获取节点端口映射



我正在将一个应用程序迁移到Docker/Kubernetes。这个应用程序有20多个众所周知的端口需要访问。它需要从kubernetes集群外部访问。为此,应用程序将其公共可访问IP写入数据库,以便外部服务知道如何访问它。IP取自向下的API(status.hostIP(。

一种解决方案是将已知端口定义为服务中的(静态(nodePorts,但我不希望这样做,因为这会限制节点的可用性:如果另一个服务已经启动,并且偶然占用了其中一个已知端口,则应用程序将无法启动。此外,因为Kubernetes打开了集群中所有节点上的端口,所以每个集群只能运行一个应用程序实例。

现在,我想让应用程序了解NodePort服务所做的端口映射。如何做到这一点?因为我在Kubernetes中没有看到ServiceStatefulset对象之间的硬链接。

这是我的(简化的(Kubernetes配置:

apiVersion: v1
kind: Service
metadata:
name: my-app-svc
labels:
app: my-app
spec:
ports:
- port: 6000
targetPort: 6000
protocol: TCP
name: debug-port
- port: 6789
targetPort: 6789
protocol: TCP
name: traffic-port-1
selector:
app: my-app
type: NodePort
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: my-app-sf
spec:
serviceName: my-app-svc
replicas: 1
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: my-repo/myapp/my-app:latest
imagePullPolicy: Always
env:
- name: K8S_ServiceAccountName
valueFrom:
fieldRef:
fieldPath: spec.serviceAccountName
- name: K8S_ServerIP
valueFrom:
fieldRef:
fieldPath: status.hostIP
- name: serverName
valueFrom:
fieldRef:
fieldPath: metadata.name
ports:
- name: debug
containerPort: 6000
- name: traffic1
containerPort: 6789

这可以通过initContainer来完成。

您可以定义一个initContainer来获取节点端口并保存到与容器共享的目录中,然后容器可以稍后从该目录中获取节点端口,一个简单的演示如下:

apiVersion: v1
kind: Pod
metadata:
name: my-app
spec:
containers:
- name: my-app
image: busybox
command: ["sh", "-c", "cat /data/port; while true; do sleep 3600; done"]
volumeMounts:
- name: config-data
mountPath: /data
initContainers:
- name: config-data
image: tutum/curl
command: ["sh", "-c", "TOKEN=`cat /var/run/secrets/kubernetes.io/serviceaccount/token`; curl -kD - -H "Authorization: Bearer $TOKEN" https://kubernetes.default:443/api/v1/namespaces/test/services/app 2>/dev/null | grep nodePort | awk '{print $2}' > /data/port"]
volumeMounts:
- name: config-data
mountPath: /data
volumes:
- name: config-data
emptyDir: {}

最新更新