kubernets与API服务器进行交互

一  为何需要与kubernets集群的API服务器进行交互

 

  1.1  kubernets提供了一种downapi的资源可以将pod的元数据渲染成环境变量或者downward卷的形式挂载到容器的文件系统上面去,但是这种操作只能将很少的数据暴露挂载pod的容器中,如果希望能将更多的数据暴露到容器里面去,需要在容器里面与kubernets的集群API服务器进行交互下面来介绍如何来与API服务器进行交互。

 

二 如何与API服务器进行通信

 

  2.1  第一步获取API服务器的url,通过如下命令获取

[root@node01 ~]# k cluster-info
Kubernetes control plane is running at https://172.16.70.6:6443
KubeDNS is running at https://172.16.70.6:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
  • api的地址是https://172.16.70.6:6443

 

  2.2  从节点通过kubectl proxy与API服务器进行通信

[root@node01 ~]# k proxy
Starting to serve on 127.0.0.1:8001

[root@node01 ~]# curl 127.0.0.1:8001
{
  "paths": [
    "/api",
    "/api/v1",
    "/apis",
    "/apis/",
    "/apis/admissionregistration.k8s.io",
    "/apis/admissionregistration.k8s.io/v1beta1",
    "/apis/apiextensions.k8s.io",
    "/apis/apiextensions.k8s.io/v1beta1",
    "/apis/apiregistration.k8s.io",
    "/apis/apiregistration.k8s.io/v1",
    "/apis/apiregistration.k8s.io/v1beta1",
    "/apis/apps",
    "/apis/apps/v1",
    "/apis/apps/v1beta1",
    "/apis/apps/v1beta2",
    "/apis/authentication.k8s.io",
    "/apis/authentication.k8s.io/v1",
    "/apis/authentication.k8s.io/v1beta1",
    "/apis/authorization.k8s.io",
    "/apis/authorization.k8s.io/v1",
    "/apis/authorization.k8s.io/v1beta1",
    "/apis/autoscaling",
    "/apis/autoscaling/v1",
    "/apis/autoscaling/v2beta1",
    "/apis/autoscaling/v2beta2",
    "/apis/batch",
    "/apis/batch/v1",
    "/apis/batch/v1beta1",
  • 执行k proxy
  • 之后就可以来访问api服务器了
  • 这是因为,k proxy的这个代理里面已经包含了要与api服务器通信的所有必备因素,k proxy接受所有来自节点的http请求,之后将请求转发到proxy,并且将从api服务器接受到的信息返回给节点

 

  2.3 在pod内部与api服务器进行通信

    

    我们已经能够能在节点上与api服务器进行通信,下一步需要的是希望能够在pod内部与api服务器进行通信,但是pod内部没有kuberctl,所以我们只能通过其他的方式来与API服务器进行通信,需要关注一下几件事情

  • 确定API服务器的位置
  • 确定是API服务器而不是其他的冒名顶替的
  • 通过服务器的认证,否则将看不到任何的资源,同时也无法操作任何的资源

    之前提到过,每个pod中都会挂载一个secrets,这个secret中包含了与API服务器通信的所有必要因素,在此之前我们需要先创建一个金丝雀pod用来测试与API服务器进行通信,里面配置很简单,只需要一个主进程保持睡眠,然后使用里面挂载的secrets三要素ca.cert,namespace,token来访问API服务器

[root@node01 Chapter08]# cat curl.yml
apiVersion: v1
kind: Pod
metadata:
  name: curl
spec:
  containers:
  - name: main
    image: tutum/curl
    command: ["sleep", "999999"]

   

  下面我们进入到pod里面执行访问命令API服务命令

export CURL_CA_BUNDLE=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt

TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)

curl -H "Authorization: Bearer $TOKEN" https://kubernetes

  

  如果我们所在的集群基于角色的访问控制(RBAC),我们需要创建以下资源来绕过

k create clusterrolebinding permissive-binding --clusterrole=cluster-admin --group=system:serviceaccounts

 

  2.4 通过ambassador容器简化与API服务器的交互

 

    在运行主容器的同时运行一个ambassador容器,并在其中运行一个kuberctl proxy,主容器在运行的时候需要向API服务器发起请求的时候,会将请求以http的形式发送到ambassador中,ambassador容器将请求以https的形式转发到API服务器,ambassador挂载着secrets,用以提供对API服务器的认证

                 

 

    运行一个带有附加ambassador容器的CURL容器

apiVersion: v1
kind: Pod
metadata:
  name: curl-with-ambassador
spec:
  containers:
  - name: main
    image: tutum/curl
    command: ["sleep", "999999"]
  - name: ambassador
    image: luksa/kubectl-proxy:1.6.2

 

    之后在主容器里面执行访问API服务器的命令

[root@node01 Chapter08]# k exec -it curl-with-ambassador -c main bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.

root@curl-with-ambassador:/# curl localhost:8001
{
  "paths": [
    "/api",
    "/api/v1",
    "/apis",
    "/apis/",

 

    其中的原理如下图所示

       

 

  • 由于同一个pod里面的2个容器共享相同的主机命名空间,所以在该pod里面可以直接curl本机地址加端口将请求转发到kubectl proxy
  • kubectl-proxy接受到请求之后进行一系列的认证,鉴权等,之后将相关请求以https的形式发送到API服务器
  • API服务器响应之后,在将请求的数据转发给主容器,完成一次连接请求
  • 还可以根据各种各样的客户端进行与API服务器的交互

 

posted @ 2021-01-05 21:05  伊铭(netease)  阅读(204)  评论(0编辑  收藏  举报