使用 Kubernetes API 访问集群

本页面介绍如何使用 Kubernetes API 访问集群。

准备工作

你需要拥有一个 Kubernetes 集群,并且 kubectl 命令行工具已配置为与你的集群通信。建议在至少有两个不是控制平面主机的节点上运行本教程。如果你还没有集群,可以使用 minikube 创建一个,或者使用这些 Kubernetes 操场之一。

要检查版本,请输入 kubectl version

访问 Kubernetes API

首次使用 kubectl 访问

首次访问 Kubernetes API 时,请使用 Kubernetes 命令行工具 kubectl

要访问集群,你需要知道集群的位置并拥有访问它的凭据。通常,当你完成 入门指南 时,这会自动设置,或者其他人设置了集群并为你提供了凭据和位置。

使用以下命令检查 kubectl 知道的位置和凭据:

kubectl config view

许多 示例 提供了使用 kubectl 的介绍。完整的文档可以在 kubectl 手册 中找到。

直接访问 REST API

kubectl 负责定位 API 服务器并进行身份验证。如果你想使用 HTTP 客户端(如 curlwget,或浏览器)直接访问 REST API,有多种方法可以定位 API 服务器并进行身份验证。

  1. 以代理模式运行 kubectl(推荐)。此方法被推荐,因为它使用存储的 API 服务器位置并通过自签名证书验证 API 服务器的身份。使用此方法不可能发生中间人 (MITM) 攻击。
  2. 或者,你可以直接向 HTTP 客户端提供位置和凭据。这适用于被代理混淆的客户端代码。为了防范中间人攻击,你需要将根证书导入到浏览器中。

使用 Go 或 Python 客户端库提供以代理模式访问 kubectl。

使用 kubectl proxy

以下命令以反向代理模式运行 kubectl。它负责定位 API 服务器并进行身份验证。

像这样运行它:

kubectl proxy --port=8080 &

有关更多详细信息,请参阅 kubectl proxy

然后,你可以使用 curl、wget 或浏览器探索 API,如下所示:

curl https://:8080/api/

输出类似于:

{
  "versions": [
    "v1"
  ],
  "serverAddressByClientCIDRs": [
    {
      "clientCIDR": "0.0.0.0/0",
      "serverAddress": "10.0.1.149:443"
    }
  ]
}

不使用 kubectl 代理

可以通过直接将身份验证令牌传递给 API 服务器来避免使用 kubectl 代理,如下所示:

使用 grep/cut 方法

# Check all possible clusters, as your .KUBECONFIG may have multiple contexts:
kubectl config view -o jsonpath='{"Cluster name\tServer\n"}{range .clusters[*]}{.name}{"\t"}{.cluster.server}{"\n"}{end}'

# Select name of cluster you want to interact with from above output:
export CLUSTER_NAME="some_server_name"

# Point to the API server referring the cluster name
APISERVER=$(kubectl config view -o jsonpath="{.clusters[?(@.name==\"$CLUSTER_NAME\")].cluster.server}")

# Create a secret to hold a token for the default service account
kubectl apply -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
  name: default-token
  annotations:
    kubernetes.io/service-account.name: default
type: kubernetes.io/service-account-token
EOF

# Wait for the token controller to populate the secret with a token:
while ! kubectl describe secret default-token | grep -E '^token' >/dev/null; do
  echo "waiting for token..." >&2
  sleep 1
done

# Get the token value
TOKEN=$(kubectl get secret default-token -o jsonpath='{.data.token}' | base64 --decode)

# Explore the API with TOKEN
curl -X GET $APISERVER/api --header "Authorization: Bearer $TOKEN" --insecure

输出类似于:

{
  "kind": "APIVersions",
  "versions": [
    "v1"
  ],
  "serverAddressByClientCIDRs": [
    {
      "clientCIDR": "0.0.0.0/0",
      "serverAddress": "10.0.1.149:443"
    }
  ]
}

上面的示例使用了 --insecure 标志。这使其容易受到中间人攻击。当 kubectl 访问集群时,它使用存储的根证书和客户端证书来访问服务器。(这些安装在 ~/.kube 目录中)。由于集群证书通常是自签名的,因此可能需要特殊配置才能使你的 HTTP 客户端使用根证书。

在某些集群上,API 服务器不需要身份验证;它可能在 localhost 上提供服务,或者受到防火墙保护。对此没有标准。控制对 Kubernetes API 的访问 描述了作为集群管理员如何配置此项。

对 API 的程序化访问

Kubernetes 官方支持 GoPythonJavadotnetJavaScriptHaskell 的客户端库。还有其他由其作者而非 Kubernetes 团队提供和维护的客户端库。有关从其他语言访问 API 以及它们如何进行身份验证的信息,请参阅 客户端库

Go 客户端

  • 要获取该库,请运行以下命令:go get k8s.io/client-go@kubernetes-<kubernetes-version-number> 请参阅 https://github.com/kubernetes/client-go/releases 以查看支持的版本。
  • 在 client-go 客户端之上编写应用程序。

Go 客户端可以使用与 kubectl CLI 相同的 kubeconfig 文件 来定位 API 服务器并进行身份验证。请参阅此 示例

package main

import (
  "context"
  "fmt"
  "k8s.io/apimachinery/pkg/apis/meta/v1"
  "k8s.io/client-go/kubernetes"
  "k8s.io/client-go/tools/clientcmd"
)

func main() {
  // uses the current context in kubeconfig
  // path-to-kubeconfig -- for example, /root/.kube/config
  config, _ := clientcmd.BuildConfigFromFlags("", "<path-to-kubeconfig>")
  // creates the clientset
  clientset, _ := kubernetes.NewForConfig(config)
  // access the API to list pods
  pods, _ := clientset.CoreV1().Pods("").List(context.TODO(), v1.ListOptions{})
  fmt.Printf("There are %d pods in the cluster\n", len(pods.Items))
}

如果应用程序作为 Pod 部署在集群中,请参阅 从 Pod 内部访问 API

Python 客户端

要使用 Python 客户端,请运行以下命令:pip install kubernetes。有关更多安装选项,请参阅 Python 客户端库页面

Python 客户端可以使用与 kubectl CLI 相同的 kubeconfig 文件 来定位 API 服务器并进行身份验证。请参阅此 示例

from kubernetes import client, config

config.load_kube_config()

v1=client.CoreV1Api()
print("Listing pods with their IPs:")
ret = v1.list_pod_for_all_namespaces(watch=False)
for i in ret.items:
    print("%s\t%s\t%s" % (i.status.pod_ip, i.metadata.namespace, i.metadata.name))

Java 客户端

要安装 Java 客户端,请运行

# Clone java library
git clone --recursive https://github.com/kubernetes-client/java

# Installing project artifacts, POM etc:
cd java
mvn install

请参阅 https://github.com/kubernetes-client/java/releases 以查看支持的版本。

Java 客户端可以使用与 kubectl CLI 相同的 kubeconfig 文件 来定位 API 服务器并进行身份验证。请参阅此 示例

package io.kubernetes.client.examples;

import io.kubernetes.client.ApiClient;
import io.kubernetes.client.ApiException;
import io.kubernetes.client.Configuration;
import io.kubernetes.client.apis.CoreV1Api;
import io.kubernetes.client.models.V1Pod;
import io.kubernetes.client.models.V1PodList;
import io.kubernetes.client.util.ClientBuilder;
import io.kubernetes.client.util.KubeConfig;
import java.io.FileReader;
import java.io.IOException;

/**
 * A simple example of how to use the Java API from an application outside a kubernetes cluster
 *
 * <p>Easiest way to run this: mvn exec:java
 * -Dexec.mainClass="io.kubernetes.client.examples.KubeConfigFileClientExample"
 *
 */
public class KubeConfigFileClientExample {
  public static void main(String[] args) throws IOException, ApiException {

    // file path to your KubeConfig
    String kubeConfigPath = "~/.kube/config";

    // loading the out-of-cluster config, a kubeconfig from file-system
    ApiClient client =
        ClientBuilder.kubeconfig(KubeConfig.loadKubeConfig(new FileReader(kubeConfigPath))).build();

    // set the global default api-client to the in-cluster one from above
    Configuration.setDefaultApiClient(client);

    // the CoreV1Api loads default api-client from global configuration.
    CoreV1Api api = new CoreV1Api();

    // invokes the CoreV1Api client
    V1PodList list = api.listPodForAllNamespaces(null, null, null, null, null, null, null, null, null);
    System.out.println("Listing all pods: ");
    for (V1Pod item : list.getItems()) {
      System.out.println(item.getMetadata().getName());
    }
  }
}

dotnet 客户端

要使用 dotnet 客户端,请运行以下命令:dotnet add package KubernetesClient --version 1.6.1。有关更多安装选项,请参阅 dotnet 客户端库页面。请参阅 https://github.com/kubernetes-client/csharp/releases 以查看支持的版本。

dotnet 客户端可以使用与 kubectl CLI 相同的 kubeconfig 文件 来定位 API 服务器并进行身份验证。请参阅此 示例

using System;
using k8s;

namespace simple
{
    internal class PodList
    {
        private static void Main(string[] args)
        {
            var config = KubernetesClientConfiguration.BuildDefaultConfig();
            IKubernetes client = new Kubernetes(config);
            Console.WriteLine("Starting Request!");

            var list = client.ListNamespacedPod("default");
            foreach (var item in list.Items)
            {
                Console.WriteLine(item.Metadata.Name);
            }
            if (list.Items.Count == 0)
            {
                Console.WriteLine("Empty!");
            }
        }
    }
}

JavaScript 客户端

要安装 JavaScript 客户端,请运行以下命令:npm install @kubernetes/client-node。请参阅 https://github.com/kubernetes-client/javascript/releases 以查看支持的版本。

JavaScript 客户端可以使用与 kubectl CLI 相同的 kubeconfig 文件 来定位 API 服务器并进行身份验证。请参阅此 示例

const k8s = require('@kubernetes/client-node');

const kc = new k8s.KubeConfig();
kc.loadFromDefault();

const k8sApi = kc.makeApiClient(k8s.CoreV1Api);

k8sApi.listNamespacedPod({ namespace: 'default' }).then((res) => {
    console.log(res);
});

Haskell 客户端

请参阅 https://github.com/kubernetes-client/haskell/releases 以查看支持的版本。

Haskell 客户端 可以使用与 kubectl CLI 相同的 kubeconfig 文件 来定位 API 服务器并进行身份验证。请参阅此 示例

exampleWithKubeConfig :: IO ()
exampleWithKubeConfig = do
    oidcCache <- atomically $ newTVar $ Map.fromList []
    (mgr, kcfg) <- mkKubeClientConfig oidcCache $ KubeConfigFile "/path/to/kubeconfig"
    dispatchMime
            mgr
            kcfg
            (CoreV1.listPodForAllNamespaces (Accept MimeJSON))
        >>= print

下一步

上次修改时间:2025 年 5 月 13 日太平洋标准时间上午 11:27:修复 JavaScript 客户端示例中 listNamespacedPod 的不正确用法 (7edfd2dfbc)