使用ambassador容器

使用ambassador容器,即在Pod中的另一个容器中使用kubectl客户端生成代理,主容器中访问该代理,由于同一个Pod中的所有容器是共享同一个网络命名空间的,因此它们之间可以直接通过环回口通信,因此主容器可以间接与API服务器交互。

它们之间的通信架构如下图所示:

将加密、授权、服务器验证工作交给ambassador容器中的代理
  1. kubernetes是集群中后端为API服务器Podkube-apiserver的Service实例;

  2. ambassador容器生成代理时所需的配置信息来自于默认Secret卷

创建ambassador容器

由于ambassador容器需要使用kubectl客户端生成代理,因此需要下载客户端。

使用客户端时,需要添加验证性的文件才可以正常使用,因此还需要从默认Secret卷中获取相关的验证文件。

下面展示创建ambassador容器的Dockerfile:

FROM alpine
RUN apk update && apk add curl && curl -L -O https://dl.k8s.io/v1.8.0/kubernetes-client-linux-amd64.tar.gz && tar zvxf kubernetes-client-linux-amd64.tar.gz kubernetes/client/bin/kubectl && mv kubernetes/client/bin/kubectl / && rm -rf kubernetes && rm -f kubernetes-client-linux-amd64.tar.gz
ADD kubectl-proxy.sh /kubectl-proxy.sh
ENTRYPOINT /kubectl-proxy.sh

从上述内容可以看出,在ambassador容器中下载了kubectl客户端,并且将kubectl-proxy.sh添加至根目录,并且设置为默认启动进程。

其中,kubectl-proxy.sh的内容如下:

#!/bin/sh

API_SERVER="https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT"
CA_CRT="/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
TOKEN="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)"

/kubectl proxy --server="$API_SERVER" --certificate-authority="$CA_CRT" --token="$TOKEN" --accept-paths='^.*'

从上述内容中可以看出,首先通过环境变量KUBECTL_SERVICE_HOSTKUBERNETES_SERVICE_PORT确认了后端Pod为API服务器的名为kubernetes的Service的位置;接着从默认的Secret卷中,读取了用于验证API服务器真假的CA证书/var/run/secrets/kubernetes.io/serviceaccount/ca.crt,以及用于获取API服务器授权的凭证/var/run/secrets/kubernetes.io/serviceaccount/token;最后利用kubectl客户端生成代理,此时代理会在Pod的8001端口开始监听请求。

创建Pod

下面直接展示创建的Pod的配置文件案例:

apiVersion: v1
kind: Pod
metadata:
  name: curl-with-ambassador
spec:
  containers:
  - name: main    # 主容器,在该容器中向代理发送请求,间接的与API服务器交互
    image: tutum/curl
    command: ["sleep", "9999999"]
  - name: ambassador    # ambassador容器
    image: luksa/kubectl-proxy:1.6.2

创建完成后,只需要在主容器,即名为main的容器中,使用如下命令即可与API服务器间接交互,省去了每次请求都需要自行使用验证数据的麻烦:

curl localhost:8001

Last updated

Was this helpful?