k8s 组件介绍-API Server API Server简介

API Server简介

k8s API Server提供了k8s各类资源对象(pod,RC,Service等)的增删改查及watch等HTTP Rest接口,是整个系统的数据总线和数据中心。

kubernetes API Server的功能:

  1. 提供了集群管理的REST API接口(包括认证授权、数据校验以及集群状态变更);
  2. 提供其他模块之间的数据交互和通信的枢纽(其他模块通过API Server查询或修改数据,只有API Server才直接操作etcd);
  3. 是资源配额控制的入口;
  4. 拥有完备的集群安全机制.

kube-apiserver工作原理图

技术图片

如何访问kubernetes API

k8s通过kube-apiserver这个进程提供服务,该进程运行在单个k8s-master节点上。默认有两个端口。

k8s通过kube-apiserver这个进程提供服务,该进程运行在单个k8s-master节点上。默认有两个端口。

1. 本地端口

  1. 该端口用于接收HTTP请求;
  2. 该端口默认值为8080,可以通过API Server的启动参数“--insecure-port”的值来修改默认值;
  3. 默认的IP地址为“localhost”,可以通过启动参数“--insecure-bind-address”的值来修改该IP地址;
  4. 非认证或授权的HTTP请求通过该端口访问API Server。

2.安全端口

  1. 该端口默认值为6443,可通过启动参数“--secure-port”的值来修改默认值;
  2. 默认IP地址为非本地(Non-Localhost)网络端口,通过启动参数“--bind-address”设置该值;
  3. 该端口用于接收HTTPS请求;
  4. 用于基于Tocken文件或客户端证书及HTTP Base的认证;
  5. 用于基于策略的授权;
  6. 默认不启动HTTPS安全访问控制。

kubernetes API访问方式

Kubernetes REST API可参考https://kubernetes.io/docs/api-reference/v1.6/

1. curl

curl localhost:8080/api

curl localhost:8080/api/v1/pods

curl localhost:8080/api/v1/services

curl localhost:8080/api/v1/replicationcontrollers

2. Kubectl Proxy

Kubectl Proxy代理程序既能作为API Server的反向代理,也能作为普通客户端访问API Server的代理。通过master节点的8080端口来启动该代理程序。

kubectl proxy --port=8080 &

具体见kubectl proxy --help

3. kubectl客户端

命令行工具kubectl客户端,通过命令行参数转换为对API Server的REST API调用,并将调用结果输出。

命令格式:kubectl [command] [options]

具体可参考Kubernetes常用命令

4. 编程方式调用

使用场景:

1、运行在Pod里的用户进程调用kubernetes API,通常用来实现分布式集群搭建的目标。

2、开发基于kubernetes的管理平台,比如调用kubernetes API来完成Pod、Service、RC等资源对象的图形化创建和管理界面。可以使用kubernetes提供的Client Library。

具体可参考https://github.com/kubernetes/client-go

通过API Server访问Node、Pod和Service

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

1. Node相关接口

关于Node相关的接口的REST路径为:/api/v1/proxy/nodes/{name},其中{name}为节点的名称或IP地址。

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

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

/api/v1/prxoy/nodes/{name}/spec/    #列出指定节点的概要信息

这里获取的Pod信息来自Node而非etcd数据库,两者时间点可能存在偏差。如果在kubelet进程启动时加--enable-debugging-handles=true参数,那么kubernetes Proxy API还会增加以下接口:

/api/v1/proxy/nodes/{name}/run      #在节点上运行某个容器

/api/v1/proxy/nodes/{name}/exec     #在节点上的某个容器中运行某条命令

/api/v1/proxy/nodes/{name}/attach   #在节点上attach某个容器

/api/v1/proxy/nodes/{name}/portForward   #实现节点上的Pod端口转发

/api/v1/proxy/nodes/{name}/logs     #列出节点的各类日志信息

/api/v1/proxy/nodes/{name}/metrics  #列出和该节点相关的Metrics信息

/api/v1/proxy/nodes/{name}/runningpods  #列出节点内运行中的Pod信息

/api/v1/proxy/nodes/{name}/debug/pprof  #列出节点内当前web服务的状态,包括CPU和内存的使用情况

2. Pod相关接口

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

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

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

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

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

3. Service相关接口

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

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

集群功能模块之间的通信

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进行管理。

监听信息

kubelet动作

备注

新的POD副本被调度绑定到本节点执行POD对应的容器的创建和启动逻辑 
POD对象被删除删除本节点上相应的POD容器 
修改POD信息修改本节点的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 主要是和 etcd 打交道,并且对外提供 HTTP 服务,以及进行安全控制,因此它的命令行提供的参数也主要和这几个方面有关。下面是一些比较重要的参数以及说明(不同版本参数可能会有不同):

参数含义默认值
–advertise-address通过该 ip 地址向集群其他节点公布 api server 的信息,必须能够被其他节点访问nil
–allow-privileged是否允许 privileged 容器运行false
–admission-control准入控制AlwaysAdmit
–authorization-mode授权模式 ,安全接口上的授权AlwaysAllow
–bind-addressHTTPS 安全接口的监听地址0.0.0.0
–secure-portHTTPS 安全接口的监听端口6443
–cert-dirTLS 证书的存放目录/var/run/kubernetes
–etcd-prefix信息存放在 etcd 中地址的前缀“/registry”
–etcd-servers逗号分割的 etcd server 地址[]
–insecure-bind-addressHTTP 访问的地址127.0.0.1
–insecure-portHTTP 访问的端口8080
–log-dir日志存放的目录 
–service-cluster-ip-rangeservice 要使用的网段,使用 CIDR 格式,参考 kubernetes 中 service 的定义 

API Server安装和运行

API Server 是通过提供的 kube-apiserver 二进制文件直接运行的,下面的例子指定了 service 分配的 ip 范围,etcd 的地址,和对外提供服务的 ip 地址:

  1.  
     /usr/bin/kube-apiserver \

  2.  
     
  3.  
    --service-cluster-ip-range=10.20.0.1/24 \

  4.  
     
  5.  
    --etcd-servers=http://127.0.0.1:2379 \

  6.  
     
  7.  
    --advertise-address=192.168.8.100 \

  8.  
     
  9.  
    --bind-address=192.168.8.100 \

  10.  
     
  11.  
    --insecure-bind-address=192.168.8.100 \

  12.  
     
  13.  
    --v=4

直接访问 8080 端口,API Server 会返回它提供了哪些接口:

  1.  
     [root@localhost vagrant]# curl http://192.168.8.100:8080

  2.  
     
  3.  
    {

  4.  
    "paths": [

  5.  
    "/api",

  6.  
    "/api/v1",

  7.  
    "/apis",

  8.  
    "/apis/apps",

  9.  
    "/apis/apps/v1alpha1",

  10.  
    "/apis/autoscaling",

  11.  
    "/apis/autoscaling/v1",

  12.  
    "/apis/batch",

  13.  
    "/apis/batch/v1",

  14.  
    "/apis/batch/v2alpha1",

  15.  
    "/apis/extensions",

  16.  
    "/apis/extensions/v1beta1",

  17.  
    "/apis/policy",

  18.  
    "/apis/policy/v1alpha1",

  19.  
    "/apis/rbac.authorization.k8s.io",

  20.  
    "/apis/rbac.authorization.k8s.io/v1alpha1",

  21.  
    "/healthz",

  22.  
    "/healthz/ping",

  23.  
    "/logs/",

  24.  
    "/metrics",

  25.  
    "/swaggerapi/",

  26.  
    "/ui/",

  27.  
    "/version"

  28.  
    ]

  29.  
    }

而目前最重要的路径是 /api/v1,里面包含了 kubernetes 所有资源的操作,比如下面的 nodes:

  1.  
     ? ~ http http://192.168.8.100:8080/api/v1/nodes

  2.  
     
  3.  
    HTTP/1.1 200 OK

  4.  
     
  5.  
    Content-Length: 112

  6.  
     
  7.  
    Content-Type: application/json

  8.  
     
  9.  
    Date: Thu, 08 Sep 2016 08:14:45 GMT

  10.  
     
  11.  
    {

  12.  
     
  13.  
    "apiVersion": "v1",

  14.  
     
  15.  
    "items": [],

  16.  
     
  17.  
    "kind": "NodeList",

  18.  
     
  19.  
    "metadata": {

  20.  
     
  21.  
    "resourceVersion": "12",

  22.  
     
  23.  
    "selfLink": "/api/v1/nodes"

  24.  
    }

  25.  
    }

 API 以 json 的形式返回,会通过 apiVersion 来说明 API 版本号,kind 说明请求的是什么资源。不过这里面的内容是空的,因为目前还没有任何 kubelet 节点接入到我们的 API Server。对应的,pod 也是空的:

  1.  
     ? ~ http http://192.168.8.100:8080/api/v1/pods

  2.  
     
  3.  
    HTTP/1.1 200 OK

  4.  
     
  5.  
    Content-Length: 110

  6.  
     
  7.  
    Content-Type: application/json

  8.  
     
  9.  
    Date: Thu, 08 Sep 2016 08:18:53 GMT

  10.  
     
  11.  
    {

  12.  
     
  13.  
    "apiVersion": "v1",

  14.  
     
  15.  
    "items": [],

  16.  
     
  17.  
    "kind": "PodList",

  18.  
     
  19.  
    "metadata": {

  20.  
     
  21.  
    "resourceVersion": "12",

  22.  
     
  23.  
    "selfLink": "/api/v1/pods"

  24.  
     
  25.  
    }

  26.  
     
  27.  
    }

添加节点

添加节点也非常简单,启动 kubelet 的时候使用 --api-servers 指定要接入的 API Server 就行。kubelet 启动之后,会把自己注册到指定的 API Server,然后监听 API 对应 pod 的变化,根据 API 中 pod 的实际信息来管理节点上 pod 的生命周期。

现在访问 /api/v1/nodes 就能看到已经添加进来的节点:

  1.  
     ? ~ http http://192.168.8.100:8080/api/v1/nodes

  2.  
    HTTP/1.1 200 OK

  3.  
    Content-Type: application/json

  4.  
    Date: Thu, 08 Sep 2016 08:27:44 GMT

  5.  
    Transfer-Encoding: chunked

  6.  
    {

  7.  
    "apiVersion": "v1",

  8.  
    "items": [

  9.  
    {

  10.  
    "metadata": {

  11.  
    "annotations": {

  12.  
    "volumes.kubernetes.io/controller-managed-attach-detach": "true"

  13.  
    },

  14.  
    "creationTimestamp": "2016-09-08T08:23:01Z",

  15.  
    "labels": {

  16.  
    "beta.kubernetes.io/arch": "amd64",

  17.  
    "beta.kubernetes.io/os": "linux",

  18.  
    "kubernetes.io/hostname": "192.168.8.100"

  19.  
    },

  20.  
    "name": "192.168.8.100",

  21.  
    "resourceVersion": "65",

  22.  
    "selfLink": "/api/v1/nodes/192.168.8.100",

  23.  
    "uid": "74e16eba-759d-11e6-b463-080027c09e5b"

  24.  
    },

  25.  
    "spec": {

  26.  
    "externalID": "192.168.8.100"

  27.  
    },

  28.  
    "status": {

  29.  
    "addresses": [

  30.  
    {

  31.  
    "address": "192.168.8.100",

  32.  
    "type": "LegacyHostIP"

  33.  
    },

  34.  
    {

  35.  
    "address": "192.168.8.100",

  36.  
    "type": "InternalIP"

  37.  
    }

  38.  
    ],

  39.  
    "allocatable": {

  40.  
    "alpha.kubernetes.io/nvidia-gpu": "0",

  41.  
    "cpu": "1",

  42.  
    "memory": "502164Ki",

  43.  
    "pods": "110"

  44.  
    },

  45.  
    "capacity": {

  46.  
    "alpha.kubernetes.io/nvidia-gpu": "0",

  47.  
    "cpu": "1",

  48.  
    "memory": "502164Ki",

  49.  
    "pods": "110"

  50.  
    },

  51.  
    "conditions": [

  52.  
    {

  53.  
    "lastHeartbeatTime": "2016-09-08T08:27:36Z",

  54.  
    "lastTransitionTime": "2016-09-08T08:23:01Z",

  55.  
    "message": "kubelet has sufficient disk space available",

  56.  
    "reason": "KubeletHasSufficientDisk",

  57.  
    "status": "False",

  58.  
    "type": "OutOfDisk"

  59.  
    },

  60.  
    {

  61.  
    "lastHeartbeatTime": "2016-09-08T08:27:36Z",

  62.  
    "lastTransitionTime": "2016-09-08T08:23:01Z",

  63.  
    "message": "kubelet has sufficient memory available",

  64.  
    "reason": "KubeletHasSufficientMemory",

  65.  
    "status": "False",

  66.  
    "type": "MemoryPressure"

  67.  
    },

  68.  
    {

  69.  
    "lastHeartbeatTime": "2016-09-08T08:27:36Z",

  70.  
    "lastTransitionTime": "2016-09-08T08:24:56Z",

  71.  
    "message": "kubelet is posting ready status",

  72.  
    "reason": "KubeletReady",

  73.  
    "status": "True",

  74.  
    "type": "Ready"

  75.  
    }

  76.  
    ],

  77.  
    "daemonEndpoints": {

  78.  
    "kubeletEndpoint": {

  79.  
    "Port": 10250

  80.  
    }

  81.  
    },

  82.  
    "images": [

  83.  
    {

  84.  
    "names": [

  85.  
    "172.16.1.41:5000/nginx:latest"

  86.  
    ],

  87.  
    "sizeBytes": 425626718

  88.  
    },

  89.  
    {

  90.  
    "names": [

  91.  
    "172.16.1.41:5000/hyperkube:v0.18.2"

  92.  
    ],

  93.  
    "sizeBytes": 207121551

  94.  
    },

  95.  
    {

  96.  
    "names": [

  97.  
    "172.16.1.41:5000/etcd:v3.0.4"

  98.  
    ],

  99.  
    "sizeBytes": 43302056

  100.  
    },

  101.  
    {

  102.  
    "names": [

  103.  
    "172.16.1.41:5000/busybox:latest"

  104.  
    ],

  105.  
    "sizeBytes": 1092588

  106.  
    },

  107.  
    {

  108.  
    "names": [

  109.  
    "172.16.1.41:5000/google_containers/pause:0.8.0"

  110.  
    ],

  111.  
    "sizeBytes": 241656

  112.  
    }

  113.  
    ],

  114.  
    "nodeInfo": {

  115.  
    "architecture": "amd64",

  116.  
    "bootID": "48955926-11dd-4ad3-8bb0-2585b1c9215d",

  117.  
    "containerRuntimeVersion": "docker://1.10.3",

  118.  
    "kernelVersion": "3.10.0-123.13.1.el7.x86_64",

  119.  
    "kubeProxyVersion": "v1.3.1-beta.0.6+fbf3f3e5292fb0",

  120.  
    "kubeletVersion": "v1.3.1-beta.0.6+fbf3f3e5292fb0",

  121.  
    "machineID": "b9597c4ae5f24494833d35e806e00b29",

  122.  
    "operatingSystem": "linux",

  123.  
    "osImage": "CentOS Linux 7 (Core)",

  124.  
    "systemUUID": "823EB67A-057E-4EFF-AE7F-A758140CD2F7"

  125.  
    }

  126.  
    }

  127.  
    }

  128.  
    ],

  129.  
    "kind": "NodeList",

  130.  
    "metadata": {

  131.  
    "resourceVersion": "65",

  132.  
    "selfLink": "/api/v1/nodes"

  133.  
    }

  134.  
    }

 我们可以看到,kubelet 收集了很多关于自身节点的信息,这些信息也会不断更新。这些信息里面不仅包含节点的系统信息(系统架构,操作系统版本,内核版本等)、还有镜像信息(节点上有哪些已经下载的 docker 镜像)、资源信息(Memory 和 Disk 的总量和可用量)、以及状态信息(是否正常,可以分配 pod等)。

和 API Server 通信

编写的 yaml 文件转换成 json 格式,保存到文件里。主要注意的是,我们指定了 nodeName 的名字,这个名字必须和之前通过 /api/v1/nodes 得到的结果中 metadata.labels.kubernetes.io/hostname 保持一致:

  1.  
     [root@localhost vagrant]# cat nginx_pod.yml

  2.  
    apiVersion: v1

  3.  
    kind: Pod

  4.  
    metadata:

  5.  
    name: nginx-server

  6.  
    spec:

  7.  
    NodeName: 192.168.8.100

  8.  
    containers:

  9.  
    - name: nginx-server

  10.  
    image: 172.16.1.41:5000/nginx

  11.  
    ports:

  12.  
    - containerPort: 80

  13.  
    volumeMounts:

  14.  
    - mountPath: /var/log/nginx

  15.  
    name: nginx-logs

  16.  
    - name: log-output

  17.  
    image: 172.16.1.41:5000/busybox

  18.  
    command:

  19.  
    - bin/sh

  20.  
    args: [-c, ‘tail -f /logdir/access.log‘]

  21.  
    volumeMounts:

  22.  
    - mountPath: /logdir

  23.  
    name: nginx-logs

  24.  
    volumes:

  25.  
    - name: nginx-logs

  26.  
    emptyDir: {}

 

使用 curl 执行 POST 请求,设置头部内容为 application/json,传过去文件中的 json 值,可以看到应答(其中 status 为 pending,表示以及接收到请求,正在准备处理):

  1.  
    # curl -s -X POST -H "Content-Type: application/json" http://192.168.8.100:8080/api/v1/namespaces/default/pods --data @nginx_pod.json

  2.  
    {

  3.  
    "kind": "Pod",

  4.  
    "apiVersion": "v1",

  5.  
    "metadata": {

  6.  
    "name": "nginx-server",

  7.  
    "namespace": "default",

  8.  
    "selfLink": "/api/v1/namespaces/default/pods/nginx-server",

  9.  
    "uid": "888e95d0-75a9-11e6-b463-080027c09e5b",

  10.  
    "resourceVersion": "573",

  11.  
    "creationTimestamp": "2016-09-08T09:49:28Z"

  12.  
    },

  13.  
    "spec": {

  14.  
    "volumes": [

  15.  
    {

  16.  
    "name": "nginx-logs",

  17.  
    "emptyDir": {}

  18.  
    }

  19.  
    ],

  20.  
    "containers": [

  21.  
    {

  22.  
    "name": "nginx-server",

  23.  
    "image": "172.16.1.41:5000/nginx",

  24.  
    "ports": [

  25.  
    {

  26.  
    "containerPort": 80,

  27.  
    "protocol": "TCP"

  28.  
    }

  29.  
    ],

  30.  
    "resources": {},

  31.  
    "volumeMounts": [

  32.  
    {

  33.  
    "name": "nginx-logs",

  34.  
    "mountPath": "/var/log/nginx"

  35.  
    }

  36.  
    ],

  37.  
    "terminationMessagePath": "/dev/termination-log",

  38.  
    "imagePullPolicy": "Always"

  39.  
    }

  40.  
    ],

  41.  
    "restartPolicy": "Always",

  42.  
    "terminationGracePeriodSeconds": 30,

  43.  
    "dnsPolicy": "ClusterFirst",

  44.  
    "nodeName": "192.168.8.100",

  45.  
    "securityContext": {}

  46.  
    },

  47.  
    "status": {

  48.  
    "phase": "Pending"

  49.  
    }

  50.  
    }

返回中包含了我们提交 pod 的信息,并且添加了 statusmetadata 等额外信息。

等一段时间去查询 pod,就可以看到 pod 的状态已经更新了:

  1.  
     ? http http://192.168.8.100:8080/api/v1/namespaces/default/pods

  2.  
    HTTP/1.1 200 OK

  3.  
    Content-Type: application/json

  4.  
    Date: Thu, 08 Sep 2016 09:51:29 GMT

  5.  
    Transfer-Encoding: chunked

  6.  
    {

  7.  
    "apiVersion": "v1",

  8.  
    "items": [

  9.  
    {

  10.  
    "metadata": {

  11.  
    "creationTimestamp": "2016-09-08T09:49:28Z",

  12.  
    "name": "nginx-server",

  13.  
    "namespace": "default",

  14.  
    "resourceVersion": "592",

  15.  
    "selfLink": "/api/v1/namespaces/default/pods/nginx-server",

  16.  
    "uid": "888e95d0-75a9-11e6-b463-080027c09e5b"

  17.  
    },

  18.  
    "spec": {

  19.  
    "containers": [

  20.  
    {

  21.  
    "image": "172.16.1.41:5000/nginx",

  22.  
    "imagePullPolicy": "Always",

  23.  
    "name": "nginx-server",

  24.  
    "ports": [

  25.  
    {

  26.  
    "containerPort": 80,

  27.  
    "protocol": "TCP"

  28.  
    }

  29.  
    ],

  30.  
    "resources": {},

  31.  
    "terminationMessagePath": "/dev/termination-log",

  32.  
    "volumeMounts": [

  33.  
    {

  34.  
    "mountPath": "/var/log/nginx",

  35.  
    "name": "nginx-logs"

  36.  
    }

  37.  
    ]

  38.  
    },

  39.  
    {

  40.  
    "args": [

  41.  
    "-c",

  42.  
    "tail -f /logdir/access.log"

  43.  
    ],

  44.  
    "command": [

  45.  
    "bin/sh"

  46.  
    ],

  47.  
    "image": "172.16.1.41:5000/busybox",

  48.  
    "imagePullPolicy": "Always",

  49.  
    "name": "log-output",

  50.  
    "resources": {},

  51.  
    "terminationMessagePath": "/dev/termination-log",

  52.  
    "volumeMounts": [

  53.  
    {

  54.  
    "mountPath": "/logdir",

  55.  
    "name": "nginx-logs"

  56.  
    }

  57.  
    ]

  58.  
    }

  59.  
    ],

  60.  
    "dnsPolicy": "ClusterFirst",

  61.  
    "nodeName": "192.168.8.100",

  62.  
    "restartPolicy": "Always",

  63.  
    "securityContext": {},

  64.  
    "terminationGracePeriodSeconds": 30,

  65.  
    "volumes": [

  66.  
    {

  67.  
    "emptyDir": {},

  68.  
    "name": "nginx-logs"

  69.  
    }

  70.  
    ]

  71.  
    },

  72.  
    "status": {

  73.  
    "conditions": [

  74.  
    {

  75.  
    "lastProbeTime": null,

  76.  
    "lastTransitionTime": "2016-09-08T09:49:28Z",

  77.  
    "status": "True",

  78.  
    "type": "Initialized"

  79.  
    },

  80.  
    {

  81.  
    "lastProbeTime": null,

  82.  
    "lastTransitionTime": "2016-09-08T09:49:44Z",

  83.  
    "status": "True",

  84.  
    "type": "Ready"

  85.  
    },

  86.  
    {

  87.  
    "lastProbeTime": null,

  88.  
    "lastTransitionTime": "2016-09-08T09:49:44Z",

  89.  
    "status": "True",

  90.  
    "type": "PodScheduled"

  91.  
    }

  92.  
    ],

  93.  
    "containerStatuses": [

  94.  
    {

  95.  
    "containerID": "docker://8b79eeea60f27b6d3f0a19cbd1b3ee3f83709bcf56574a6e1124c69a6376972d",

  96.  
    "image": "172.16.1.41:5000/busybox",

  97.  
    "imageID": "docker://sha256:8c566faa3abdaebc33d40c1b5e566374c975d17754c69370f78c00c162c1e075",

  98.  
    "lastState": {},

  99.  
    "name": "log-output",

  100.  
    "ready": true,

  101.  
    "restartCount": 0,

  102.  
    "state": {

  103.  
    "running": {

  104.  
    "startedAt": "2016-09-08T09:49:43Z"

  105.  
    }

  106.  
    }

  107.  
    },

  108.  
    {

  109.  
    "containerID": "docker://96e64cdba7b05d4e30710a20e958ff5b8f1f359c8d16d32622b36f0df0cb353c",

  110.  
    "image": "172.16.1.41:5000/nginx",

  111.  
    "imageID": "docker://sha256:51d764c1fd358ce81fd0e728436bd0175ff1f3fd85fc5d1a2f9ba3e7dc6bbaf6",

  112.  
    "lastState": {},

  113.  
    "name": "nginx-server",

  114.  
    "ready": true,

  115.  
    "restartCount": 0,

  116.  
    "state": {

  117.  
    "running": {

  118.  
    "startedAt": "2016-09-08T09:49:36Z"

  119.  
    }

  120.  
    }

  121.  
    }

  122.  
    ],

  123.  
    "hostIP": "192.168.8.100",

  124.  
    "phase": "Running",

  125.  
    "podIP": "172.17.0.2",

  126.  
    "startTime": "2016-09-08T09:49:28Z"

  127.  
    }

  128.  
    }

  129.  
    ],

  130.  
    "kind": "PodList",

  131.  
     
  132.  
    "metadata": {

  133.  
    "resourceVersion": "602",

  134.  
    "selfLink": "/api/v1/namespaces/default/pods"

  135.  
    }

  136.  
    }

可以看到 pod 已经在运行,并且给分配了 ip:172.17.0.2,通过 curl 也可以访问它的服务:

  1.  
    [root@localhost vagrant]# curl -s http://172.17.0.2 | head -n 5

  2.  
    <!DOCTYPE html>

  3.  
    <html>

  4.  
    <head>

  5.  
    <title>Welcome to nginx on Debian!</title>

  6.  
    <style>

kubectl -s http://ip:8080 get pods

相关文章