使用 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 服务器并进行身份验证。如果您想使用 curlwget 等 HTTP 客户端,或者使用浏览器直接访问 REST API,可以通过多种方式定位并验证 API 服务器。

  1. 以代理模式运行 kubectl(推荐)。推荐使用此方法,因为它利用存储的 API 服务器位置,并使用自签名证书验证 API 服务器的身份。使用此方法可以避免中间人(MITM)攻击。
  2. 或者,您可以直接将位置和凭据提供给 HTTP 客户端。这适用于对代理感到困惑的客户端代码。为了防止中间人攻击,您需要将根证书导入到浏览器中。

使用 Go 或 Python 客户端库可以实现以代理模式访问 kubectl。

使用 kubectl 代理

以下命令将 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 proxy

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

使用 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 客户端

说明

client-go 定义了它自己的 API 对象,因此如果需要,请从 client-go 导入 API 定义,而不是从主仓库导入。例如,import "k8s.io/client-go/kubernetes" 是正确的。

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 (PST):修复 JavaScript 客户端示例中 listNamespacedPod 的错误用法 (7edfd2dfbc)