从扩展程序与 Kubernetes 交互

扩展 SDK 未提供任何 API 方法以直接与 Docker Desktop 管理的 Kubernetes 集群或使用其他工具(如 KinD)创建的其他 Kubernetes 集群进行交互。然而,本页介绍了一种方法,可让您通过 SDK 的其他 API 间接从您的扩展与 Kubernetes 集群进行交互。

要请求一个可直接与Docker Desktop管理的Kubernetes进行交互的API,您可以为以下问题点赞:
该问题(位于Extensions SDK的GitHub仓库中)。

前提条件

启用 Kubernetes

您可以使用 Docker Desktop 中内置的 Kubernetes 启动一个单节点 Kubernetes 集群。 当与 kubectl 命令行工具或其他客户端配合使用时,kubeconfig 文件用于配置对 Kubernetes 的访问。 Docker Desktop 方便地为用户提供了一个位于用户主目录下的预配置 kubeconfig 文件和 kubectl 命令。这是那些希望从 Docker Desktop 快速开始使用 Kubernetes 的用户的便捷途径。

kubectl 作为扩展的一部分进行部署

如果您的插件需要与 Kubernetes 集群进行交互,建议将 kubectl 命令行工具包含在您的插件中。通过这样做,安装您插件的用户将在其主机上自动安装 kubectl

要了解如何将 kubectl 命令行工具作为您 Docker 扩展镜像的一部分部署到多个平台,请参阅 构建多架构扩展

示例

以下代码片段已整合到Kubernetes 示例扩展中。该示例展示了如何通过分发kubectl命令行工具与Kubernetes集群进行交互。

检查 Kubernetes API 服务器是否可访问

kubectl命令行工具被添加到Dockerfile中的扩展镜像,并在metadata.json中定义后,Extensions框架会在扩展安装时将其部署到用户的主机上。

您可以使用 JS API ddClient.extension.host?.cli.exec 向容器平台发出 kubectl 命令,例如,在给定特定上下文的情况下检查 Kubernetes API 服务器是否可访问:

const output = await ddClient.extension.host?.cli.exec("kubectl", [
  "cluster-info",
  "--request-timeout",
  "2s",
  "--context",
  "docker-desktop",
]);

列出 Kubernetes 上下文

const output = await ddClient.extension.host?.cli.exec("kubectl", [
  "config",
  "view",
  "-o",
  "jsonpath='{.contexts}'",
]);

列出 Kubernetes 命名空间

const output = await ddClient.extension.host?.cli.exec("kubectl", [
  "get",
  "namespaces",
  "--no-headers",
  "-o",
  'custom-columns=":metadata.name"',
  "--context",
  "docker-desktop",
]);

持久化 kubeconfig 文件

下面提供了多种方式,用于从宿主机文件系统中持久化和读取 kubeconfig 文件。用户可随时向 kubeconfig 文件中添加、编辑或删除 Kubernetes 上下文。

警告

kubeconfig 文件非常敏感,若被发现,攻击者可借此获得对 Kubernetes 集群的管理员权限。

扩展的后端容器

如果您需要在扩展读取 kubeconfig 文件后仍保留该文件,可以使用一个后端容器,该容器提供一个 HTTP POST 接口,用于将文件内容存储在内存中或容器文件系统的某个位置。这样,当用户离开扩展跳转到 Docker Desktop 的其他部分,然后再返回时,您无需再次读取 kubeconfig 文件。

export const updateKubeconfig = async () => {
  const kubeConfig = await ddClient.extension.host?.cli.exec("kubectl", [
    "config",
    "view",
    "--raw",
    "--minify",
    "--context",
    "docker-desktop",
  ]);
  if (kubeConfig?.stderr) {
    console.log("error", kubeConfig?.stderr);
    return false;
  }

  // call backend container to store the kubeconfig retrieved into the container's memory or filesystem
  try {
    await ddClient.extension.vm?.service?.post("/store-kube-config", {
      data: kubeConfig?.stdout,
    });
  } catch (err) {
    console.log("error", JSON.stringify(err));
  }
};

Docker 卷

数据卷是持久化由 Docker 容器生成和使用的数据的首选机制。您可以利用数据卷来持久化 kubeconfig 文件。 通过将 kubeconfig 持久化到数据卷中,当扩展面板关闭时,您无需再次读取 kubeconfig 文件。这使其成为在从扩展导航至 Docker Desktop 其他部分时持久化数据的理想选择。

const kubeConfig = await ddClient.extension.host?.cli.exec("kubectl", [
  "config",
  "view",
  "--raw",
  "--minify",
  "--context",
  "docker-desktop",
]);
if (kubeConfig?.stderr) {
  console.log("error", kubeConfig?.stderr);
  return false;
}

await ddClient.docker.cli.exec("run", [
  "--rm",
  "-v",
  "my-vol:/tmp",
  "alpine",
  "/bin/sh",
  "-c",
  `"touch /tmp/.kube/config && echo '${kubeConfig?.stdout}' > /tmp/.kube/config"`,
]);

扩展的 localStorage

localStorage 是浏览器 Web 存储机制之一。它允许用户将数据以键值对的形式保存在浏览器中,供后续使用。 localStorage 在浏览器(或扩展面板)关闭时不会清除数据。这使其非常适合在从扩展程序跳转到 Docker Desktop 其他部分时持久化保存数据。

localStorage.setItem("kubeconfig", kubeConfig);
localStorage.getItem("kubeconfig");