使用ambassador容器,即在Pod中的另一个容器中使用kubectl
客户端生成代理,主容器中访问该代理,由于同一个Pod中的所有容器是共享同一个网络命名空间的,因此它们之间可以直接通过环回口通信,因此主容器可以间接与API服务器交互。
它们之间的通信架构如下图所示:
创建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_HOST
和KUBERNETES_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服务器间接交互,省去了每次请求都需要自行使用验证数据的麻烦: