kubernetes实践之四十五:API Server原理分析

一:简介
k8s API Server提供了k8s各类资源对象(pod,RC,Service等)的增删改查及watch等HTTP Rest接口,是整个系统的数据总线和数据中心。功能特性:
1.是集群管理的API入口
2.是资源配额控制的入口
3.提供了完善的集群安全机制


二:概述
通常可以通过命令行工具Kubectl来与API Server交互,它们之间的接口是REST调用,同时也可以使用curl命令行工具进行快速验证。通过配置参数KUBE_MASTER="--master=http://10.116.137.196:8080" 客户获得API Server的访问路径。

1.获取 API的版本信息
curl 10.116.137.196:8080/api

点击(此处)折叠或打开

  1. {
  2.   "kind": "APIVersions",
  3.   "versions": [
  4.     "v1"
  5.   ],
  6.   "serverAddressByClientCIDRs": [
  7.     {
  8.       "clientCIDR": "0.0.0.0/0",
  9.       "serverAddress": "10.116.137.196:6443"
  10.     }
  11.   ]
  12. }
2.获取目前所支持的资源对象的种类
curl 10.116.137.196:8080/api/v1
  1. {
  2.   "kind": "APIResourceList",
  3.   "groupVersion": "v1",
  4.   "resources": [
  5.     {
  6.       "name": "bindings",
  7.       "singularName": "",
  8.       "namespaced": true,
  9.       "kind": "Binding",
  10.       "verbs": [
  11.         "create"
  12.       ]
  13.     },
  14.     {
  15.       "name": "componentstatuses",
  16.       "singularName": "",
  17.       "namespaced": false,
  18.       "kind": "ComponentStatus",
  19.       "verbs": [
  20.         "get",
  21.         "list"
  22.       ],
  23.       "shortNames": [
  24.         "cs"
  25.       ]
  26.     },
  27.     {
  28.       "name": "configmaps",
  29.       "singularName": "",
  30.       "namespaced": true,
  31.       "kind": "ConfigMap",
  32.       "verbs": [
  33.         "create",
  34.         "delete",
  35.         "deletecollection",
  36.         "get",
  37.         "list",
  38.         "patch",
  39.         "update",
  40.         "watch"
  41.       ],
  42.       "shortNames": [
  43.         "cm"
  44.       ]
  45.     },
  46.     {
  47.       "name": "endpoints",
  48.       "singularName": "",
  49.       "namespaced": true,
  50.       "kind": "Endpoints",
  51.       "verbs": [
  52.         "create",
  53.         "delete",
  54.         "deletecollection",
  55.         "get",
  56.         "list",
  57.         "patch",
  58.         "update",
  59.         "watch"
  60.       ],
  61.       "shortNames": [
  62.         "ep"
  63.       ]
  64.     },
  65.     {
  66.       "name": "events",
  67.       "singularName": "",
  68.       "namespaced": true,
  69.       "kind": "Event",
  70.       "verbs": [
  71.         "create",
  72.         "delete",
  73.         "deletecollection",
  74.         "get",
  75.         "list",
  76.         "patch",
  77.         "update",
  78.         "watch"
  79.       ],
  80.       "shortNames": [
  81.         "ev"
  82.       ]
  83.     },
  84.     {
  85.       "name": "limitranges",
  86.       "singularName": "",
  87.       "namespaced": true,
  88.       "kind": "LimitRange",
  89.       "verbs": [
  90.         "create",
  91.         "delete",
  92.         "deletecollection",
  93.         "get",
  94.         "list",
  95.         "patch",
  96.         "update",
  97.         "watch"
  98.       ],
  99.       "shortNames": [
  100.         "limits"
  101.       ]
  102.     },
  103.     {
  104.       "name": "namespaces",
  105.       "singularName": "",
  106.       "namespaced": false,
  107.       "kind": "Namespace",
  108.       "verbs": [
  109.         "create",
  110.         "delete",
  111.         "get",
  112.         "list",
  113.         "patch",
  114.         "update",
  115.         "watch"
  116.       ],
  117.       "shortNames": [
  118.         "ns"
  119.       ]
  120.     },
  121.     {
  122.       "name": "namespaces/finalize",
  123.       "singularName": "",
  124.       "namespaced": false,
  125.       "kind": "Namespace",
  126.       "verbs": [
  127.         "update"
  128.       ]
  129.     },
  130.     {
  131.       "name": "namespaces/status",
  132.       "singularName": "",
  133.       "namespaced": false,
  134.       "kind": "Namespace",
  135.       "verbs": [
  136.         "get",
  137.         "patch",
  138.         "update"
  139.       ]
  140.     },
  141.     {
  142.       "name": "nodes",
  143.       "singularName": "",
  144.       "namespaced": false,
  145.       "kind": "Node",
  146.       "verbs": [
  147.         "create",
  148.         "delete",
  149.         "deletecollection",
  150.         "get",
  151.         "list",
  152.         "patch",
  153.         "proxy",
  154.         "update",
  155.         "watch"
  156.       ],
  157.       "shortNames": [
  158.         "no"
  159.       ]
  160.     },
  161.     {
  162.       "name": "nodes/proxy",
  163.       "singularName": "",
  164.       "namespaced": false,
  165.       "kind": "Node",
  166.       "verbs": []
  167.     },
  168.     {
  169.       "name": "nodes/status",
  170.       "singularName": "",
  171.       "namespaced": false,
  172.       "kind": "Node",
  173.       "verbs": [
  174.         "get",
  175.         "patch",
  176.         "update"
  177.       ]
  178.     },
  179.     {
  180.       "name": "persistentvolumeclaims",
  181.       "singularName": "",
  182.       "namespaced": true,
  183.       "kind": "PersistentVolumeClaim",
  184.       "verbs": [
  185.         "create",
  186.         "delete",
  187.         "deletecollection",
  188.         "get",
  189.         "list",
  190.         "patch",
  191.         "update",
  192.         "watch"
  193.       ],
  194.       "shortNames": [
  195.         "pvc"
  196.       ]
  197.     },
  198.     {
  199.       "name": "persistentvolumeclaims/status",
  200.       "singularName": "",
  201.       "namespaced": true,
  202.       "kind": "PersistentVolumeClaim",
  203.       "verbs": [
  204.         "get",
  205.         "patch",
  206.         "update"
  207.       ]
  208.     },
  209.     {
  210.       "name": "persistentvolumes",
  211.       "singularName": "",
  212.       "namespaced": false,
  213.       "kind": "PersistentVolume",
  214.       "verbs": [
  215.         "create",
  216.         "delete",
  217.         "deletecollection",
  218.         "get",
  219.         "list",
  220.         "patch",
  221.         "update",
  222.         "watch"
  223.       ],
  224.       "shortNames": [
  225.         "pv"
  226.       ]
  227.     },
  228.     {
  229.       "name": "persistentvolumes/status",
  230.       "singularName": "",
  231.       "namespaced": false,
  232.       "kind": "PersistentVolume",
  233.       "verbs": [
  234.         "get",
  235.         "patch",
  236.         "update"
  237.       ]
  238.     },
  239.     {
  240.       "name": "pods",
  241.       "singularName": "",
  242.       "namespaced": true,
  243.       "kind": "Pod",
  244.       "verbs": [
  245.         "create",
  246.         "delete",
  247.         "deletecollection",
  248.         "get",
  249.         "list",
  250.         "patch",
  251.         "proxy",
  252.         "update",
  253.         "watch"
  254.       ],
  255.       "shortNames": [
  256.         "po"
  257.       ],
  258.       "categories": [
  259.         "all"
  260.       ]
  261.     },
  262.     {
  263.       "name": "pods/attach",
  264.       "singularName": "",
  265.       "namespaced": true,
  266.       "kind": "Pod",
  267.       "verbs": []
  268.     },
  269.     {
  270.       "name": "pods/binding",
  271.       "singularName": "",
  272.       "namespaced": true,
  273.       "kind": "Binding",
  274.       "verbs": [
  275.         "create"
  276.       ]
  277.     },
  278.     {
  279.       "name": "pods/eviction",
  280.       "singularName": "",
  281.       "namespaced": true,
  282.       "group": "policy",
  283.       "version": "v1beta1",
  284.       "kind": "Eviction",
  285.       "verbs": [
  286.         "create"
  287.       ]
  288.     },
  289.     {
  290.       "name": "pods/exec",
  291.       "singularName": "",
  292.       "namespaced": true,
  293.       "kind": "Pod",
  294.       "verbs": []
  295.     },
  296.     {
  297.       "name": "pods/log",
  298.       "singularName": "",
  299.       "namespaced": true,
  300.       "kind": "Pod",
  301.       "verbs": [
  302.         "get"
  303.       ]
  304.     },
  305.     {
  306.       "name": "pods/portforward",
  307.       "singularName": "",
  308.       "namespaced": true,
  309.       "kind": "Pod",
  310.       "verbs": []
  311.     },
  312.     {
  313.       "name": "pods/proxy",
  314.       "singularName": "",
  315.       "namespaced": true,
  316.       "kind": "Pod",
  317.       "verbs": []
  318.     },
  319.     {
  320.       "name": "pods/status",
  321.       "singularName": "",
  322.       "namespaced": true,
  323.       "kind": "Pod",
  324.       "verbs": [
  325.         "get",
  326.         "patch",
  327.         "update"
  328.       ]
  329.     },
  330.     {
  331.       "name": "podtemplates",
  332.       "singularName": "",
  333.       "namespaced": true,
  334.       "kind": "PodTemplate",
  335.       "verbs": [
  336.         "create",
  337.         "delete",
  338.         "deletecollection",
  339.         "get",
  340.         "list",
  341.         "patch",
  342.         "update",
  343.         "watch"
  344.       ]
  345.     },
  346.     {
  347.       "name": "replicationcontrollers",
  348.       "singularName": "",
  349.       "namespaced": true,
  350.       "kind": "ReplicationController",
  351.       "verbs": [
  352.         "create",
  353.         "delete",
  354.         "deletecollection",
  355.         "get",
  356.         "list",
  357.         "patch",
  358.         "update",
  359.         "watch"
  360.       ],
  361.       "shortNames": [
  362.         "rc"
  363.       ],
  364.       "categories": [
  365.         "all"
  366.       ]
  367.     },
  368.     {
  369.       "name": "replicationcontrollers/scale",
  370.       "singularName": "",
  371.       "namespaced": true,
  372.       "group": "autoscaling",
  373.       "version": "v1",
  374.       "kind": "Scale",
  375.       "verbs": [
  376.         "get",
  377.         "patch",
  378.         "update"
  379.       ]
  380.     },
  381.     {
  382.       "name": "replicationcontrollers/status",
  383.       "singularName": "",
  384.       "namespaced": true,
  385.       "kind": "ReplicationController",
  386.       "verbs": [
  387.         "get",
  388.         "patch",
  389.         "update"
  390.       ]
  391.     },
  392.     {
  393.       "name": "resourcequotas",
  394.       "singularName": "",
  395.       "namespaced": true,
  396.       "kind": "ResourceQuota",
  397.       "verbs": [
  398.         "create",
  399.         "delete",
  400.         "deletecollection",
  401.         "get",
  402.         "list",
  403.         "patch",
  404.         "update",
  405.         "watch"
  406.       ],
  407.       "shortNames": [
  408.         "quota"
  409.       ]
  410.     },
  411.     {
  412.       "name": "resourcequotas/status",
  413.       "singularName": "",
  414.       "namespaced": true,
  415.       "kind": "ResourceQuota",
  416.       "verbs": [
  417.         "get",
  418.         "patch",
  419.         "update"
  420.       ]
  421.     },
  422.     {
  423.       "name": "secrets",
  424.       "singularName": "",
  425.       "namespaced": true,
  426.       "kind": "Secret",
  427.       "verbs": [
  428.         "create",
  429.         "delete",
  430.         "deletecollection",
  431.         "get",
  432.         "list",
  433.         "patch",
  434.         "update",
  435.         "watch"
  436.       ]
  437.     },
  438.     {
  439.       "name": "serviceaccounts",
  440.       "singularName": "",
  441.       "namespaced": true,
  442.       "kind": "ServiceAccount",
  443.       "verbs": [
  444.         "create",
  445.         "delete",
  446.         "deletecollection",
  447.         "get",
  448.         "list",
  449.         "patch",
  450.         "update",
  451.         "watch"
  452.       ],
  453.       "shortNames": [
  454.         "sa"
  455.       ]
  456.     },
  457.     {
  458.       "name": "services",
  459.       "singularName": "",
  460.       "namespaced": true,
  461.       "kind": "Service",
  462.       "verbs": [
  463.         "create",
  464.         "delete",
  465.         "get",
  466.         "list",
  467.         "patch",
  468.         "proxy",
  469.         "update",
  470.         "watch"
  471.       ],
  472.       "shortNames": [
  473.         "svc"
  474.       ],
  475.       "categories": [
  476.         "all"
  477.       ]
  478.     },
  479.     {
  480.       "name": "services/proxy",
  481.       "singularName": "",
  482.       "namespaced": true,
  483.       "kind": "Service",
  484.       "verbs": []
  485.     },
  486.     {
  487.       "name": "services/status",
  488.       "singularName": "",
  489.       "namespaced": true,
  490.       "kind": "Service",
  491.       "verbs": [
  492.         "get",
  493.         "patch",
  494.         "update"
  495.       ]
  496.     }
  497.   ]
  498. }
3.如果只想对外暴露部分REST服务,则可以在Master或其他任何节点上通过运行kubectl proxy进程启动一个内部代理来实现
kubectl proxy --port=8001

三:Kubernetes Proxy API接口

 API Server最主要的REST接口是资源对象的增删改查,另外还有一类特殊的REST接口--Kubernetes  Proxy API接口,这类接口的作用是代理REST请求,即kubernetes API Server把收到的REST请求转发到某个Node上的kubelet守护进程的REST端口上,由该kubelet进程负责响应。

1.Node
相关的接口

点击(此处)折叠或打开

  1. /api/v1/proxy/nodes/{name}/pods/ #列出指定节点内所有Pod的信息

  2. /api/v1/proxy/nodes/{name}/stats/ #列出指定节点内物理资源的统计信息

  3. /api/v1/prxoy/nodes/{name}/spec/ #列出指定节点的概要信息
这里获取的Pod信息来自Node而非etcd数据库,两者时间点可能存在偏差。

2.Pod 相关的接口

点击(此处)折叠或打开

  1. /api/v1/proxy/namespaces/{namespace}/pods/{name}/{path:*} #访问pod的某个服务接口

  2. /api/v1/proxy/namespaces/{namespace}/pods/{name} #访问Pod

  3. #以下写法不同,功能一样

  4. /api/v1/namespaces/{namespace}/pods/{name}/proxy/{path:*} #访问pod的某个服务接口

  5. /api/v1/namespaces/{namespace}/pods/{name}/proxy #访问Pod
Pod的proxy接口的作用:在kubernetes集群之外访问某个pod容器的服务(HTTP服务),可以用Proxy API实现,这种场景多用于管理目的,比如逐一排查Service的Pod副本,检查哪些Pod的服务存在异常问题。

3.Service 相关的接口

点击(此处)折叠或打开

  1. /api/v1/proxy/namespaces/{namespace}/services/{name}

四:集群功能模块之间的通信
kubernetes API Server作为集群的核心,负责集群各功能模块之间的通信,集群内各个功能模块通过API Server将信息存入etcd,当需要获取和操作这些数据时,通过API Server提供的REST接口(GET\LIST\WATCH方法)来实现,从而实现各模块之间的信息交互。

1. kubelet与API SERVER交互
每个Node节点上的kubelet定期就会调用API Server的REST接口报告自身状态,API Server接收这些信息后,将节点状态信息更新到etcd中。kubelet也通过API Server的Watch接口监听Pod信息,从而对Node机器上的POD进行管理。

2. kube-controller-manager与API SERVER交互
kube-controller-manager中的Node Controller模块通过API Server提供的Watch接口,实时监控Node的信息,并做相应处理。

3.kube-scheduler与API SERVER交互
Scheduler通过API Server的Watch接口监听到新建Pod副本的信息后,它会检索所有符合该Pod要求的Node列表,开始执行Pod调度逻辑。调度成功后将Pod绑定到目标节点上。

五: 说明
为了缓解各模块对API Server的访问压力,各功能模块都采用缓存机制来缓存数据,各功能模块定时从API Server获取指定的资源对象信息(LIST/WATCH方法),然后将信息保存到本地缓存,功能模块在某些情况下不直接访问API Server,而是通过访问缓存数据来间接访问API Server。
请使用浏览器的分享功能分享到微信等