什么时候需要kubectl代理?

Ste*_*hen 6 kubernetes

我正在阅读Kubernetes教程的第二个模块,我对何时kubectl proxy需要它感到困惑。

我感到困惑的原因是,在本教程中,有可能kubectl run kubernetes-bootcamp --image=gcr.io/google-samples/kubernetes-bootcamp:v1 --port=8080在设置代理之前使用命令创建Deployment(即,将Docker映像作为容器放置在Pod中)。部署映像似乎需要访问节点。

该教程说:“默认情况下,[pod,即容器组]在同一kubernetes群集中的其他Pod和服务中可见,但在该网络外部不可见。” 出于这个原因,它指示我们kubectl proxycurl直接尝试使用Pod 之前(例如使用curl http://localhost:8001/api/v1/namespaces/default/pods/$POD_NAME/proxy/)设置代理。但是我们已经能够在没有代理的情况下部署这些Pod。我们可以部署它们但不能查询它们,这似乎很奇怪。

同样,本教程还让我们在尝试使用带有Kubernetes API的版本curl http://localhost:8001/version(我相信localhost:8001是代理)之前设置了代理。但是,之前我们可以使用而不使用代理查询版本,该代理kubectl version返回主节点上Kubernetes kubectl Kubernetes 的版本。

有人能阐明这些明显的矛盾吗?

Ami*_*pta 6

在运行kubectl命令时,CLI会确定Kubernetes API服务器的地址,CA以验证服务器证书所依据的地址(以确保您正在与受信任的服务器通信,而不是中间人),以及您的来自kubeconfig文件的客户端凭据(用于使用mTLS与服务器建立加密的,经过身份验证的连接),~/.kube/config默认情况下处于此状态。您可以cat在教程中查看该文件的内容:

$ cat ~/.kube/config
apiVersion: v1
clusters:
- cluster:
    certificate-authority: /root/.minikube/ca.crt
    server: https://172.17.0.26:8443
  name: minikube
contexts:
- context:
    cluster: minikube
    user: minikube
  name: minikube
current-context: minikube
kind: Config
preferences: {}
users:
- name: minikube
  user:
    client-certificate: /root/.minikube/client.crt
    client-key: /root/.minikube/client.key
Run Code Online (Sandbox Code Playgroud)

您可以在没有代理的情况下等效于本教程中发生的事情,如下所示:

$ curl \
    --cacert /root/.minikube/ca.crt \
    --cert /root/.minikube/client.crt \
    --key /root/.minikube/client.key \
    https://172.17.0.26:8443/api/v1/namespaces/default/pods/$POD_NAME/proxy/
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-6bf84cb898-5gzp5 | v=1
Run Code Online (Sandbox Code Playgroud)

您可以看到,在运行proxy命令之后,需要运行的结果curl命令更加简单和方便:

curl http://localhost:8001/api/v1/namespaces/default/pods/$POD_NAME/proxy/
Run Code Online (Sandbox Code Playgroud)

您无需费心弄清楚API服务器的地址或处理所有这些证书和密钥,只需连接到本地主机,然后在本地主机上运行的本地代理即可处理与API的安全且经过身份验证的连接,并代理来自API服务器返回给您。


现在,您需要与Kubernetes API进行的大多数交互都可以直接通过kubectl命令完成,很少需要直接与该API交互curl。发出kubectl runor kubectl version命令时,您会看到此信息。实际上,您观察到您后来通过a找到了版本信息curl,但实际上并不需要这样做,因为您可以直接运行kubectl version

因此,您可能只kubectl proxy在需要curl直接使用Kubernetes API 时才使用,因为没有本机kubectl命令可以让您执行所需的操作,并且当您希望不使用curl带有所有cert标志的更复杂的命令等便利时。


好的,但是什么时候真正需要curl直接使用API​​?同样,通常永远不会。但是,除了作为用于创建和删除Kubernetes资源(pod,部署,服务,pvc等)的RESTful API之外,API所做的一件事是它还充当了内部容器网络的代理。现成的,除了通过位于Kubernetes API提供的代理端点之外,无法将流量发送到您在本教程中运行的容器/api/v1/namespaces/default/pods/$POD_NAME/proxy/

您在问题的注释中链接到的StackOverflow问题具有可接受的答案,该答案说明了将流量发送到正在运行的容器的其他几种方法。对于实际应用程序,您可能想使用Kubernetes API服务器本身上的代理端点之外的其他东西,但是代理端点是通过网络与部署的容器进行交互的一种快速简便的方法,因此它在设置更健壮和复杂的基础结构以处理到您的容器的入口流量之前,您可能想在开发生命周期的早期阶段做些事情。


因此,将它们放在一起:将Web应用程序部署到Kubernetes 希望向其发送请求时您(现在)还不想建立一些更复杂但更可靠的方法来将入口流量获取到您的容器,您可以使用/api/v1/namespaces/default/pods/$POD_NAME/proxy/Kubernetes API服务器上的容器网络代理API 。没有kubectl命令会为您命中该端点,因此您必须直接卷曲它(或在浏览器中打开它)。 如果您想curl直接连接到任何Kuberentes服务器API端点并且不想将一堆标志传递给curl命令,那么运行kubectl proxy可以使您运行起来更简单curl 针对该本地代理的命令,该命令会将您的请求代理到Kubernetes API。


最后一点,这里有两个完全不同的代理。一种是本地代理,将您的请求代理到Kuberentes API服务器的任何端点。Kubernetes API服务器拥有的一个这样的(类型)端点本身就是部署容器的内部网络的代理。(此外,容器网络内部存在一些代理,这些代理使事物在后台运行,但为了简单起见,无需在此答案中进行讨论)。不要混淆这两个代理。