【问题标题】:Kubernetes get nodeport mappings in a podKubernetes 在 pod 中获取节点端口映射
【发布时间】:2018-11-01 01:33:57
【问题描述】:

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

一个解决方案是在服务中将众所周知的端口定义为(静态)nodePorts,但我不希望这样,因为它会限制节点的可用性:如果另一个服务已经启动并且偶然采用了其中一个应用程序将无法启动的已知端口。另外,由于 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

【问题讨论】:

    标签: kubernetes


    【解决方案1】:

    这可以通过一个 initContainer 来完成。

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

    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: {}
    

    【讨论】:

    • 我无法使用来自/var/run/secrets/kubernetes.io/serviceaccount/token 的令牌访问网址。此令牌未经授权。如果我使用从管理员那里获得的另一个令牌,我可以生成端口文件。一种解决方法:awk 脚本应该是:awk 'NR>1{print $2}'
    • 好的,您应该使用 RBAC 为您的应用的 serviceaccount 授予权限。
    猜你喜欢
    • 2017-07-30
    • 1970-01-01
    • 1970-01-01
    • 2022-11-30
    • 1970-01-01
    • 1970-01-01
    • 2016-11-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多