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