如何读取容器应用中分配给nodePort端口的Kubernetes Service“随机”值?

91zkwejq  于 2023-08-03  发布在  Kubernetes
关注(0)|答案(1)|浏览(104)

我有一个使用Apache Ignite胖客户端的容器化应用程序。这使用与Kubernetes外部的Ignite集群的双向通信。当它连接到Ignite时,它会通告它是Ignite的IP和端口。Ignite连接回胖客户端以执行发现/统计和其他管理任务。
显然,使用默认配置和部署,容器将通告其内部信息。
在我之前的容器env DC/OS中,我能够读取主机i.p和外部随机端口(Kubernetes中节点端口的“随机”nodePort端口)作为环境变量,Ignite集群能够通过公开发布的i.p和端口连接。如果应用程序被移动到另一个节点上重新部署,它只会得到新的主机和新的随机端口,Ignite只会重新连接新的信息。
我能够解决的主机i.p:

env:
- name: HOST_IP
  valueFrom:
    fieldRef:
      fieldPath: status.hostIP

字符串
我希望服务节点端口会暴露目标端口,但可用的环境变量仍然只有内部变量。
我得到的服务环境变量:

MY_SERVICE_PORT_18080_TCP_PORT: 123456
MY_SERVICE_SERVICE_PORT: 123456


使用Kubectl,我可以获得:

kubectl get svc my-service

my-service   NodePort   xxx.xxx.xxx.xxx   <none>        123456:30086/TCP   2m46s


那么,有没有办法让容器应用程序知道30086端口呢?
我告诉自己快速解决这个问题的一种方法是在服务定义中硬编码targetPort,并在应用程序配置中硬编码相同的端口。但这只有在你有2-3个应用程序连接到Ignite时才有效,更不用说跟踪你为此保留了哪些端口了。
-- Update表示由服务分配的随机nodePort

qq24tv8q

qq24tv8q1#

正如Chris所指出的,init containers是实现这一点的唯一方法。尽管Service API将其公开为env var会更好。

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    run: my-app
  name: my-app
spec:
  replicas: 1
  selector:
    matchLabels:
      run: my-app
  template:
    metadata:
      labels:
        run: my-app
    spec:
      containers:
        - name: private
          image: foo/bar
          volumeMounts:
            - name: config-data
              mountPath: /config
          ports:
            - containerPort: 18080
          env:
      initContainers:
        - name: config-data
          image: curlimages/curl
          command: ["sh", "-c", "TOKEN=`cat /var/run/secrets/kubernetes.io/serviceaccount/token`; curl -k -H \"Authorization: Bearer $TOKEN\" https://kubernetes.default:443/api/v1/namespaces/default/services/my-app >> /config/service.json"]
          volumeMounts:
            - name: config-data
              mountPath: /config
      volumes:
        - name: config-data
          emptyDir: {}

字符串
对于init容器,我使用curlimages/curl image作为提供curl命令的容器。
在上面的命令部分,如果使用另一个命名空间,请确保将defaultmy-app替换为您的应用程序的名称。另外,出于我的目的,我选择只将完整的JSON输出写入文件。由于我的应用程序已经解析了JSON配置,并有一个JSON库作为依赖项,我可以按原样读取JSON。
您还需要为default服务帐户或您可能正在使用的服务帐户给予“查看”访问权限,以便它可以在init容器中调用curl API。

kubectl create rolebinding default-view \
  --clusterrole=view \
  --serviceaccount=default:default \
  --namespace=default

相关问题