任务

任务
管理集群
Debug DNS 方案
Enabling Service Topology (EN)
IP Masquerade Agent 用户指南
Kubernetes 云管理控制器
Safely Drain a Node while Respecting the PodDisruptionBudget (EN)
为 Kubernetes 运行 etcd 集群
为系统守护进程预留计算资源
为节点发布扩展资源
使用 CoreDNS 进行服务发现
使用 KMS 提供商进行数据加密
使用 Kubernetes API 访问集群
关键插件 Pod 的调度保证
启用端点切片
命名空间演练
在 Kubernetes 集群中使用 NodeLocal DNSCache
在 Kubernetes 集群中使用 sysctl
在实时集群上重新配置节点的 Kubelet
声明网络策略
开发云控制器管理器
控制节点上的 CPU 管理策略
控制节点上的拓扑管理策略
搭建高可用的 Kubernetes Masters
改变默认 StorageClass
更改 PersistentVolume 的回收策略
自定义 DNS 服务
访问集群上运行的服务
通过命名空间共享集群
通过配置文件设置 Kubelet 参数
配置 API 对象配额
配置多个调度器
配置资源不足时的处理方式
限制存储消耗
集群 DNS 服务自动伸缩
集群安全
集群管理
静态加密 Secret 数据
用插件扩展 kubectl
管理巨页(HugePages)
调度 GPUs

Edit This Page

访问集群

本文阐述多种与集群交互的方法。

使用 kubectl 完成集群的第一次访问

当您第一次访问 Kubernetes API 的时候,我们建议您使用 Kubernetes CLI,kubectl

访问集群时,您需要知道集群的地址并且拥有访问的凭证。通常,这些在您通过 Getting started guide 安装集群时都是自动安装好的,或者其他人安装时也应该提供了凭证和集群地址。

通过以下命令检查 kubectl 是否知道集群地址及凭证:

$ kubectl config view

有许多 例子 介绍了如何使用 kubectl,可以在 kubectl手册 中找到更完整的文档。

直接访问 REST API

Kubectl 处理 apiserver 的定位和身份验证。 如果要使用 curl 或 wget 等 http 客户端或浏览器直接访问 REST API,可以通过多种方式查找和验证:

  • 以代理模式运行 kubectl。
    • 推荐此方式。
    • 使用已存储的 apiserver 地址。
    • 使用自签名的证书来验证 apiserver 的身份。杜绝 MITM 攻击。
    • 对 apiserver 进行身份验证。
    • 未来可能会实现智能化的客户端负载均衡和故障恢复。
  • 直接向 http 客户端提供位置和凭据。
    • 可选的方案。
    • 适用于代理可能引起混淆的某些客户端类型。
    • 需要引入根证书到您的浏览器以防止 MITM 攻击。

使用 kubectl 代理

以下命令以反向代理的模式运行kubectl。它处理 apiserver 的定位和验证。 像这样运行:

$ kubectl proxy --port=8080 &

参阅 kubectl proxy 获取更多详细信息。

然后,您可以使用 curl、wget 或浏览器访问 API,如果是 IPv6 则用 [::1] 替换 localhost,如下所示:

$ curl http://localhost:8080/api/
{
  "kind": "APIVersions",
  "versions": [
    "v1"
  ],
  "serverAddressByClientCIDRs": [
    {
      "clientCIDR": "0.0.0.0/0",
      "serverAddress": "10.0.1.149:443"
    }
  ]
}

不使用 kubectl 代理

在 Kubernetes 1.3 或更高版本中,kubectl config view 不再显示 token。使用 kubectl describe secret ... 来获取默认服务帐户的 token,如下所示:

grep/cut 方法实现:

$ APISERVER=$(kubectl config view | grep server | cut -f 2- -d ":" | tr -d " ")
$ TOKEN=$(kubectl describe secret $(kubectl get secrets | grep default | cut -f1 -d ' ') | grep -E '^token' | cut -f2 -d':' | tr -d '\t')
$ curl $APISERVER/api --header "Authorization: Bearer $TOKEN" --insecure
{
  "kind": "APIVersions",
  "versions": [
    "v1"
  ],
  "serverAddressByClientCIDRs": [
    {
      "clientCIDR": "0.0.0.0/0",
      "serverAddress": "10.0.1.149:443"
    }
  ]
}

jsonpath 方法实现:

$ APISERVER=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')
$ TOKEN=$(kubectl get secret $(kubectl get serviceaccount default -o jsonpath='{.secrets[0].name}') -o jsonpath='{.data.token}' | base64 --decode )
$ curl $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 客户端使用根证书。

在一些集群中,apiserver 不需要身份验证;它可能只服务于 localhost,或者被防火墙保护,这个没有一定的标准。 配置对 API 的访问 描述了集群管理员如何进行配置。此类方法可能与未来的高可用性支持相冲突。

以编程方式访问 API

Kubernetes 官方提供对 GoPython 的客户端库支持。

Go 客户端

  • 想要获得这个库,请运行命令:go get k8s.io/client-go/<version number>/kubernetes。参阅 https://github.com/kubernetes/client-go 来查看目前支持哪些版本。
  • 基于这个 client-go 客户端库编写应用程序。 请注意,client-go 定义了自己的 API 对象,因此如果需要,请从 client-go 而不是从主存储库导入 API 定义,例如,import "k8s.io/client-go/1.4/pkg/api/v1" 才是对的。

Go 客户端可以像 kubectl CLI 一样使用相同的 kubeconfig 文件 来定位和验证 apiserver。可参阅 示例

如果应用程序以 Pod 的形式部署在集群中,那么请参阅 下一章

Python 客户端

如果想要使用 Python 客户端,请运行命令:pip install kubernetes。参阅 Python Client Library page 以获得更详细的安装参数。

Python 客户端可以像 kubectl CLI 一样使用相同的 kubeconfig 文件 来定位和验证 apiserver,可参阅 示例

其它语言

目前有多个 客户端库 为其它语言提供访问 API 的方法。 参阅其它库的相关文档以获取他们是如何验证的。

从 Pod 中访问 API

当你从 Pod 中访问 API 时,定位和验证 apiserver 会有些许不同。

在 Pod 中定位 apiserver 的推荐方式是通过 kubernetes.default.svc 这个 DNS 名称,该名称将会解析为服务 IP,然后服务 IP 将会路由到 apiserver。

向 apiserver 进行身份验证的推荐方法是使用 服务帐户 凭据。 通过 kube-system,pod 与服务帐户相关联,并且该服务帐户的凭证(token)被放置在该 pod 中每个容器的文件系统中,位于 /var/run/secrets/kubernetes.io/serviceaccount/token

如果可用,则将证书放入每个容器的文件系统中的 /var/run/secrets/kubernetes.io/serviceaccount/ca.crt,并且应该用于验证 apiserver 的服务证书。

最后,命名空间化的 API 操作所使用的默认命名空间将被放置在每个容器的 /var/run/secrets/kubernetes.io/serviceaccount/namespace 文件中。

在 pod 中,建议连接 API 的方法是:

  • 在 pod 的 sidecar 容器中运行 kubectl proxy,或者以后台进程的形式运行。 这将把 Kubernetes API 代理到当前 pod 的 localhost interface,所以 pod 中的所有容器中的进程都能访问它。
  • 使用 Go 客户端库,并使用 rest.InClusterConfig()kubernetes.NewForConfig() 函数创建一个客户端。 他们处理 apiserver 的定位和身份验证。示例

在每种情况下,pod 的凭证都是为了与 apiserver 安全地通信。

访问集群中正在运行的服务

上一节介绍了如何连接 Kubernetes API 服务。本节介绍如何连接到 Kubernetes 集群上运行的其他服务。 在 Kubernetes 中,节点pods服务 都有自己的 IP。 在许多情况下,集群上的节点 IP,pod IP 和某些服务 IP 将无法路由,因此无法从集群外部的计算机(例如桌面计算机)访问它们。

连接的方法

有多种方式可以从集群外部连接节点、pod 和服务:

  • 通过公共 IP 访问服务。
    • 类型为 NodePortLoadBalancer 的服务,集群外部可以访问。 请参阅 服务kubectl expose 文档。
    • 取决于您的集群环境,该服务可能仅暴露给您的公司网络,或者也可能暴露给整个互联网。 请考虑公开该服务是否安全。它是否进行自己的身份验证?
    • 在服务后端放置 pod。要从一组副本中访问一个特定的 pod,例如进行调试,请在 pod 上放置一个唯一的标签,然后创建一个选择此标签的新服务。
    • 在大多数情况下,应用程序开发人员不应该通过其 nodeIP 直接访问节点。
  • 使用 Proxy Verb 访问服务、node 或者 pod。
    • 在访问远程服务之前进行 apiserver 身份验证和授权。 如果服务不能够安全地暴露到互联网,或者服务不能获得节点 IP 端口的访问权限,或者是为了 debug,那么请使用此选项。
    • 代理可能会给一些 web 应用带来问题。
    • 只适用于 HTTP/HTTPS。
    • 更多详细信息在 [这里]。
  • 从集群中的 node 或者 pod 中访问。
    • 运行一个 pod,然后使用 kubectl exec 来连接 pod 里的 shell。 然后从 shell 中连接其它的节点、pod 和服务。
    • 有些集群可能允许您通过 ssh 连接到 node,从那您可能可以访问集群的服务。 这是一个非正式的方式,可能可以运行在个别的集群上。 浏览器和其它一些工具可能没有被安装。集群的 DNS 可能无法使用。

发现内建服务

通常来说,集群中会有 kube-system 创建的一些运行的服务。

通过 kubectl cluster-info 命令获得这些服务列表:

$ kubectl cluster-info

  Kubernetes master is running at https://104.197.5.247
  elasticsearch-logging is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy
  kibana-logging is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/kibana-logging/proxy
  kube-dns is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/kube-dns/proxy
  grafana is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/monitoring-grafana/proxy
  heapster is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/monitoring-heapster/proxy

这展示了访问每个服务的 proxy-verb URL。 例如,如果集群启动了集群级别的日志(使用 Elasticsearch),并且传递合适的凭证,那么可以通过 https://104.197.5.247/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/ 进行访问。日志也能通过 kubectl 代理获取,例如: http://localhost:8080/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/。 (参阅 上面的内容 来获取如何使用 kubectl 代理来传递凭证)

手动构建 apiserver 代理 URL

如上所述,您可以使用 kubectl cluster-info 命令来获得服务的代理 URL。要创建包含服务端点、后缀和参数的代理 URL,只需添加到服务的代理 URL: http://kubernetes_master_address/api/v1/namespaces/namespace_name/services/service_name[:port_name]/proxy

如果尚未为端口指定名称,则不必在 URL 中指定 *port_name*。

默认情况下,API server 使用 http 代理您的服务。要使用 https,请在服务名称前加上 https:http://kubernetes_master_address/api/v1/namespaces/namespace_name/services/https:service_name:[port_name]/proxy

URL 名称段支持的格式为:

  • <service_name> - 使用 http 代理到默认或未命名的端口
  • <service_name>:<port_name> - 使用 http 代理到指定的端口
  • https:<service_name>: - 使用 https 代理到默认或未命名的端口(注意后面的冒号)
  • https:<service_name>:<port_name> - 使用 https 代理到指定的端口
示例
  • 要访问 Elasticsearch 服务端点 _search?q=user:kimchy,您需要使用:http://104.197.5.247/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/_search?q=user:kimchy
  • 要访问 Elasticsearch 集群健康信息 _cluster/health?pretty=true,您需要使用:https://104.197.5.247/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/_cluster/health?pretty=true

    {
    "cluster_name" : "kubernetes_logging",
    "status" : "yellow",
    "timed_out" : false,
    "number_of_nodes" : 1,
    "number_of_data_nodes" : 1,
    "active_primary_shards" : 5,
    "active_shards" : 5,
    "relocating_shards" : 0,
    "initializing_shards" : 0,
    "unassigned_shards" : 5
    }

使用 web 浏览器访问运行在集群上的服务

您可以在浏览器地址栏中输入 apiserver 代理 URL。但是:

  • Web 浏览器通常不能传递 token,因此您可能需要使用基本(密码)身份验证。Apiserver 可以配置为接受基本身份验证,但您的集群可能未进行配置。
  • 某些 Web 应用程序可能无法运行,尤其是那些使用客户端 javascript 以不知道代理路径前缀的方式构建 URL 的应用程序。

请求重定向

已弃用并删除了重定向功能。请改用代理(见下文)。

多种代理

使用 Kubernetes 时可能会遇到几种不同的代理:

  1. kubectl 代理

    • 在用户的桌面或 pod 中运行
    • 代理从本地主机地址到 Kubernetes apiserver
    • 客户端到代理将使用 HTTP
    • 代理到 apiserver 使用 HTTPS
    • 定位 apiserver
    • 添加身份验证 header
  1. apiserver 代理

    • 内置于 apiserver 中
    • 将集群外部的用户连接到集群 IP,否则这些 IP 可能无法访问
    • 运行在 apiserver 进程中
    • 客户端代理使用 HTTPS(也可配置为 http)
    • 代理将根据可用的信息决定使用 HTTP 或者 HTTPS 代理到目标
    • 可用于访问节点、Pod 或服务
    • 在访问服务时进行负载平衡
  1. kube proxy

    • 运行在每个节点上
    • 代理 UDP 和 TCP
    • 不能代理 HTTP
    • 提供负载均衡
    • 只能用来访问服务
  1. 位于 apiserver 之前的 Proxy/Load-balancer:

    • 存在和实现因集群而异(例如 nginx)
    • 位于所有客户和一个或多个 apiserver 之间
    • 如果有多个 apiserver,则充当负载均衡器
  1. 外部服务上的云负载均衡器:

    • 由一些云提供商提供(例如 AWS ELB,Google Cloud Load Balancer)
    • 当 Kubernetes 服务类型为 LoadBalancer 时自动创建
    • 只使用 UDP/TCP
    • 具体实现因云提供商而异。

除了前两种类型之外,Kubernetes 用户通常不需要担心任何其他问题。集群管理员通常会确保后者的正确配置。

反馈