Kubernetes在Pod中获取NodePort映射

时间:2018-10-31 06:03:30

标签: kubernetes

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

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

现在,我想让应用程序知道由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

1 个答案:

答案 0 :(得分:5)

这可以通过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: {}