从扩展与 Kubernetes 交互

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

要请求直接与 Docker Desktop 管理的 Kubernetes 交互的 API,您可以在扩展 SDK GitHub 存储库中为此问题 点赞。

先决条件

启用 Kubernetes

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

kubectl作为扩展的一部分交付

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

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

示例

以下代码片段已在Kubernetes 示例扩展中组合在一起。它展示了如何通过交付kubectl 命令行工具来与 Kubernetes 集群交互。

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

一旦kubectl 命令行工具添加到Dockerfile 中的扩展镜像中,并在metadata.json中定义,扩展框架就会在安装扩展时将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");