使用 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 proxy

以下命令在 kubectl 充当反向代理的模式下运行 kubectl。 它处理定位 API 服务器和身份验证。

像这样运行它

kubectl proxy --port=8080 &

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

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

curl https://127.0.0.1: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 标志。 这使它容易受到 MITM 攻击。当 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('default').then((res) => {
    console.log(res.body);
});

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

下一步

上次修改时间:2023 年 12 月 06 日 上午 9:05 PST: 清理 change-default-storage-class.md (d1d6eda640)