• k8s 组件介绍-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接口(GETLISTWATCH方法)来实现,从而实现各模块之间的信息交互。

    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-address HTTPS 安全接口的监听地址 0.0.0.0
    –secure-port HTTPS 安全接口的监听端口 6443
    –cert-dir TLS 证书的存放目录 /var/run/kubernetes
    –etcd-prefix 信息存放在 etcd 中地址的前缀 “/registry”
    –etcd-servers 逗号分割的 etcd server 地址 []
    –insecure-bind-address HTTP 访问的地址 127.0.0.1
    –insecure-port HTTP 访问的端口 8080
    –log-dir 日志存放的目录  
    –service-cluster-ip-range service 要使用的网段,使用 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

  • 相关阅读:
    CodeForces
    4.15随笔
    oracle新建用户并赋予权限等
    catch时,获取异常信息
    ORACLE 判断是否为数字类型
    UNION ALL用法
    2019.11.7随笔
    oracle 查询锁表和解锁
    2019.11.1随笔
    oracle拼接子查询返回的多个结果
  • 原文地址:https://www.cnblogs.com/Su-per-man/p/10942783.html
Copyright © 2020-2023  润新知