k8s中pod获取宿主机IP地址

xxsdnol / 2024-08-31 / 原文

在 Pod 内部的 Java 环境中,你可以通过 Kubernetes API 或 Kubernetes Downward API 来获取节点的 IP 地址。以下是几种方法来实现这一点:

个人使用的第一种

方法 1: 使用 Kubernetes Downward API
如果你已经在 Pod 配置中使用了 Downward API,将节点的 IP 地址注入到环境变量中,你可以在 Java 程序中读取该环境变量。

1.1 配置 Pod 的 YAML 文件
首先,在 Pod 的 YAML 文件中配置 Downward API,如下所示:

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: my-container
    image: my-image
    env:
    - name: NODE_IP
      valueFrom:
        fieldRef:
          fieldPath: status.hostIP

1.2 在 Java 中读取环境变量
在 Java 程序中,你可以通过 System.getenv() 方法读取环境变量:

public class Main {
    public static void main(String[] args) {
        String nodeIp = System.getenv("NODE_IP");
        System.out.println("Node IP: " + nodeIp);
    }
}

方法 2: 通过 Kubernetes API 查询节点信息
如果你没有使用 Downward API,你可以通过 Kubernetes API 直接在 Java 中查询节点的 IP 地址。这需要你使用 Kubernetes 客户端库(如 kubernetes-client)来访问 Kubernetes API。

2.1 添加 Kubernetes 客户端依赖
首先,添加 Kubernetes 客户端依赖到你的 pom.xml 中:

<dependency>
    <groupId>io.kubernetes</groupId>
    <artifactId>client-java</artifactId>
    <version>15.0.0</version> <!-- 使用最新版本 -->
</dependency>
2.2 使用 Kubernetes 客户端库查询节点信息
以下是一个示例代码,展示如何使用 Kubernetes 客户端库查询节点 IP 地址:
import io.kubernetes.client.openapi.ApiClient;
import io.kubernetes.client.openapi.Configuration;
import io.kubernetes.client.openapi.auth.ApiKeyAuth;
import io.kubernetes.client.openapi.models.V1Node;
import io.kubernetes.client.openapi.models.V1NodeList;
import io.kubernetes.client.openapi.apis.CoreV1Api;
import io.kubernetes.client.util.Config;

public class Main {
    public static void main(String[] args) {
        try {
            // Initialize the Kubernetes API client
            ApiClient client = Config.defaultClient();
            Configuration.setDefaultApiClient(client);
            CoreV1Api api = new CoreV1Api();

            // Get the node list
            V1NodeList nodeList = api.listNode(null, null, null, null, null, null, null, null, null);
            
            // Print node IP addresses
            for (V1Node node : nodeList.getItems()) {
                String nodeName = node.getMetadata().getName();
                String nodeIp = node.getStatus().getAddresses().stream()
                                   .filter(address -> "InternalIP".equals(address.getType()))
                                   .map(address -> address.getAddress())
                                   .findFirst().orElse("Unknown");
                System.out.println("Node Name: " + nodeName + ", Node IP: " + nodeIp);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

方法 3: 直接从 Pod 中获取信息
如果你的 Pod 已经配置了 Kubernetes API 权限,你可以使用 HTTP 请求直接从 Kubernetes API 服务器获取节点的 IP 地址。以下是一个使用 HttpURLConnection 的示例:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class Main {
    public static void main(String[] args) {
        try {
            String url = "http://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT/api/v1/nodes/$(hostname)/status";
            URL obj = new URL(url);
            HttpURLConnection con = (HttpURLConnection) obj.openConnection();
            con.setRequestMethod("GET");
            con.setRequestProperty("Authorization", "Bearer " + System.getenv("TOKEN"));
            con.setRequestProperty("Accept", "application/json");
            
            BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
            String inputLine;
            StringBuilder response = new StringBuilder();
            
            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
            in.close();
            
            // Print the response
            System.out.println(response.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

在这个示例中,$KUBERNETES_SERVICE_HOST 和 $KUBERNETES_SERVICE_PORT 是 Kubernetes API 的服务地址和端口,TOKEN 是从 /var/run/secrets/kubernetes.io/serviceaccount/token 文件中读取的服务账户令牌。

总结
使用 Downward API 是最简单的方法,可以将节点 IP 地址作为环境变量注入到 Pod 中。
Kubernetes API 客户端 提供了更灵活的方式来查询节点信息,但需要配置和权限。
直接使用 HTTP 请求 也是一种方法,但需要处理身份验证和 API 访问。