从扩展与 Kubernetes 交互

Extensions SDK 没有提供任何 API 方法来直接与 Docker Desktop 管理的 Kubernetes 集群或使用 KinD 等其他工具创建的集群交互。但是,本页面提供了一种方法,让您可以利用其他 SDK API 从扩展间接与 Kubernetes 集群交互。

要请求一个能直接与 Docker Desktop 管理的 Kubernetes 交互的 API,您可以在 Extensions SDK GitHub 仓库中为此问题点赞

前提条件

开启 Kubernetes

您可以使用 Docker Desktop 内置的 Kubernetes 来启动一个 Kubernetes 单节点集群。kubeconfig 文件用于配合 kubectl 命令行工具或其他客户端配置对 Kubernetes 的访问。Docker Desktop 便利地在用户主目录下为用户提供了本地预配置的 kubeconfig 文件和 kubectl 命令。这对于那些希望从 Docker Desktop 利用 Kubernetes 的用户来说,是一种快速获得访问权限的便捷方式。

kubectl 作为扩展的一部分分发

如果您的扩展需要与 Kubernetes 集群交互,建议您将 kubectl 命令行工具作为扩展的一部分包含进来。通过这样做,安装您的扩展的用户将在其主机上安装 kubectl。

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

示例

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

检查 Kubernetes API 服务器是否可达

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

您可以使用 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");
页面选项