本篇将说明Kubernetes exec API的运作方式,并以简单范例进行开发在前后端上。虽然Kubernetes提供了不同资源的RESTful API来进行CRUD操作,但是部分API并非单纯的回传一个资料,有些是需要透过SPDY或WebSocket建立长连线串流,这种API以exec,attach为主,目标是对一个Pod执行指定指令,或者进入该Pod进行互动等等。

Exec API端点

首先了解一下Kubernetes exec API端点,由于Kubernetes官方文件并未提供相关资讯,因此这边透过kubectl指令来了解API的结构:

$ cat <<EOF | kubectl create -f -
apiVersion: v1
kind: Pod
metadata:
name: ubuntu
spec:
containers:
- name: ubuntu
image: ubuntu:16.04
command: ['/bin/bash', '-c', 'while :; do echo Hello; sleep 1; done ']
EOF $ kubectl -v = 8 exec -ti ubuntu bash
...
I0625 10:39:33.716271 93099 round_trippers.go:383] POST https://xxx.xxx.xxx.xxx:8443/api/v1/namespaces/default/ pods / ubuntu / exec?command = bash&container = ubuntu&container = ubuntu&stdin = true&stdout = true&tty = true
...

从上述得知exec API结构大致如下图所示:

其中API中的查询又可细分以下资讯:

  • command:将被执行的指令。若指令为ping 8.8.8.8,则API为command=ping&command=8.8.8.8。类型为string值。
  • container:哪个容器将被执行指令。若Pod只有一个容器,一般会用API找出名称塞到该参数中,若多个则选择让人输入名称。类型为string值。
  • stdin:是否开启标准输入,通常由使用者决定是否开启。类型为bool值。
  • stdout:是否开启标准输出,通常是預設開啟。类型为bool值。
  • stderr:是否开启标准错误输出,通常是預設開啟。类型为bool值。
  • tty:是否分配一个终端设备(Pseudo TTY,PTY)。ㄒ为bool值。

协议

执行是利用SPDY与WebSocket协定进行串流沟通的API,其中SPDY在Kubernetes官方的client-go已经有实现(参考远程命令),而kubectl正是使用SPDY,但是是SPDY目前已经规划在未来将被移弃,因此建议选择使用WebSocket来作为串流沟通。但而无论是使用哪一个协定,都要注意请求的Header必须有Connection: UpgradeUpgrade: xxx等,不然API Server会拒绝存取请求。

HTTP标头

除了SPDY与WebSocket所需要的Headers(如升级等)外,使用者与开发者还必须提供两个Headers来确保能够正确授权并沟通:

  • 授权:该Header是用来提供给API Server做认证请求的资讯,通常会是以Authorization: Bearer <token>的形式。
  • 接受:指定客户端能够接收的内容类型,一般为Accept: application/json,若输入不支持的类型将会被API以406 Not Acceptable拒绝请求。

沟通协定

一旦符合上述所有资讯后,WebSocket(或SPDY)就能够建立连线,并且与API服务器进行沟通。而当写入WebSocket时,资料将被传送到标准输入(stdin),而WebSocket的接收将会是标准输出(stdout)与输出错误(stderr).Kubernetes API服务器简单定义了一个协定来复用stdout与stderr。因此可以理解当WebSocket建立连线后,传送资料时需要再缓冲的第一个字元定义为stdin(buf [0] = 0),而接收资料时要判断stdout(buf [0] = 1)与stderr(buf [0] = 2)。其资讯如下:

标准串流
0 标准输入
1 标准输出
2 标准错误

简单下面以发送ls指令为例:

#传送`ls`指令,必须buf [0]自行塞入0字元来表示stdin.buf
= [0 108 115 10] #接收
BUF = [1 108 115 13 10 27 91 48 109 27 91 ...]

最后需要注意Timeout问题,由于可能对WebSocket设置TCP Timeout,因此建议每一段时间发送一个stdin空讯息来保持连线。

透过WebSocket 实现Kubernetes Exec Terminal

一般我们在操作K8S (Kubernetes) 都是透过kubectl 命令,其实kubectl 所有操作都是呼叫K8S 提供的标准WebService API,然而有时候需要进Container Debug 的时候就需要透过exec 功能。有用过K8S Dashboard 应该也知道,管理者可以任意进入某一个Container Terminal,其实就是透过exec sh command 来实现。我一直很好奇K8S Dashboard 要如何在Web 实现这样的功能,查一下果然不出所料有一个WebSocket API 可以使用,于是开始研究如何自己实现像是Dashboard Terminal 这样的功能。

K8S Exec Command API WebSocket 串接

我今天的目的是要在Web做出跟K8S Dashboard Terminal一样的功能,其中必须透过WebSocker API进行串接。这一个Exec API官方说明相当少,其实有一个Kubernetes Project,叫做container-terminal  已经有实做一样的功能,但是我实际测试的时候并不work,因为K8S API呼叫的Token必须透过HTTP Header传递,然而标准的HTML5并没有夹带自订Header的方法,container-terminal所使用在Query String夹带access_token并不是标准作法。

我按下F12 光明正大偷看了K8S Dashboard 的作法,发现是透过Cookie 自行验证WebSocket 权限,看来要透过HTML5 标准来呼叫API 就要自己实做Server 了。

开始以前,我们先看看只有一条IO特性的WebSocket如何处理exec呢?其实exec就是命令呼叫,所有的程式在Linux执行一个程序都是一样的,程序启动时会分配三个档案描述子(File Descriptor),分别是StdIn (标准输入), Std Out (标准输出), Std Error Out (标准错误输出),当我们的WebSocket成功Upgrade为TCP/IP之后,K8S API必须提供一个协定来处理这三种标准描述子的收发工作。区分方法就是在资料最前端加入一个Byte,如下:

Byte 0 : 标准输入

Byte 1 : 标准输出

Byte 2 : 标准错误输出

有了这些资讯我们就可以开始实做了WebSocket 串接了。

透过WebSocket 串接K8S Exec API 实现Terminal

由于刚刚提到HTML5 WebSocket标准并不提供自订的HTTP Header,因此我的想法是在Server端透过NodeJS夹带Token来连线K8S Exec WebSocket API,因为不在Browser的NodeJS就可以自订Request Header好通过K8S的验证机制。然后另外启动一个WebSocket Server提供浏览器进行连线,当然这里的认证机制要自己实做了,可以用Cookie/Session控制即可,这样一来也不需要暴露API Token。总而言之就是一个左手接右手传的机制,这里的终端机介面移植container-terminal用了xterm.js  套件,跑起来的画面如下:

这样一来就可以在浏览器操作你的Container,由于是命令模式并非VM 那种传整个画面的终端机,所以用起来貌似飞快,速度就跟平常使用SSH 差不多速度,满酷炫的。

范例程式码在GitHub 有兴趣请自己玩看看啰。

https://github.com/samejack/web-k8s-exec

此外,上述提到的K8S API WebSocket 协定,其实用在Log API 也是一样的,就可以在Web 做出logs 画面的即时输出,也是很方便。闪电分享结束.......下台一鞠躬~

Kubernetes exec API串接分析的更多相关文章

  1. kubernetes核心原理之API Server原理分析

    kubernetes API Server的核心功能是提供了Kubernetes各类资源对象(Pod,RC,Service等)的增删改查及Watch等HTTP Rest接口,成为集群内各个功能模块之间 ...

  2. Kubernetes client-go DeltaFIFO 源码分析

    概述Queue 接口DeltaFIFO元素增删改 - queueActionLocked()Pop()Replace() 概述 源码版本信息 Project: kubernetes Branch: m ...

  3. 微服务、SOA 和 API对比与分析

    摘要: 对比微服务架构和面向服务的架构(SOA)是一个敏感的话题,常常引起激烈的争论.本文将介绍这些争论的起源,并分析如何以最佳方式解决它们.然后进一步查看这些概念如何与 API 管理概念结合使用,实 ...

  4. 深入了解Kubernetes REST API的工作方式

    关于Kubernetes REST API的工作方式: 在哪里以及如何定义从REST路径到处理REST调用的函数的映射? 与etcd的交互发生在哪里? 从客户端发出请求到保存在etcd中对象的端到端路 ...

  5. 如何用 Python 和 API 收集与分析网络数据?

    摘自 https://www.jianshu.com/p/d52020f0c247 本文以一款阿里云市场历史天气查询产品为例,为你逐步介绍如何用 Python 调用 API 收集.分析与可视化数据.希 ...

  6. kubernetes 的API 介绍

    在API conventions doc中描述了API的全部协议. 在API Reference文档中描述了API的端点.资源类型和示例. 在Controlling API Access doc中讨论 ...

  7. 记一次 .NET 某纺织工厂 MES系统 API 挂死分析

    一:背景 1. 讲故事 这个月中旬,有位朋友加我wx求助他的程序线程占有率很高,寻求如何解决,截图如下: 说实话,和不同行业的程序员聊天还是蛮有意思的,广交朋友,也能扩大自己的圈子,朋友说他因为这个b ...

  8. Qt 事件系统浅析 (用 Windows API 描述,分析了QCoreApplication::exec()和QEventLoop::exec的源码)(比起新号槽,事件机制是更高级的抽象,拥有更多特性,比如 accept/ignore,filter,还是实现状态机等高级 API 的基础)

    事件系统在 Qt 中扮演了十分重要的角色,不仅 GUI 的方方面面需要使用到事件系统,Signals/Slots 技术也离不开事件系统(多线程间).我们本文中暂且不描述 GUI 中的一些特殊情况,来说 ...

  9. Docker系列(十四):Kubernetes API和源码分析

    Kubernetes API入门 Ku8 eye开源项目

随机推荐

  1. LeetCode 491. Increasing Subsequences

    原题链接在这里:https://leetcode.com/problems/increasing-subsequences/ 题目: Given an integer array, your task ...

  2. MongoDB 启动报错

    1.配置MongoDB ls /etc/mongod.conf 可以根据此配置文件启动 或者根据自己需求进行配置文件的变更 重要提醒: 如果变更MongoDB配置文件中:日志与数据文件目录,那么要把这 ...

  3. ubuntu及Cenos国内镜像下载

    打开:https://man.linuxde.net/download/ CentOS 7提供了三种ISO镜像文件的下载: DVD ISO 标准安装版,一般下载这个就可以了(推荐) Everythin ...

  4. kuma kong 团队开发的可视化&&安全的service mesh

    最近service mesh 的开源产品是越来越多了,好多团队都开源了自己的解决方案 maesh 最近kong 团队也开源了自己的service meshkuma 一张参考图 说明 kuma 没有基于 ...

  5. haproxy 2.0 dataplaneapi docker 镜像

    为了方便测试dataplaneapi 基于官方的docker镜像,制作了一个简单的包含dataplaneapi 的镜像 下载dataplaneapi https://github.com/haprox ...

  6. pmm docker-compose 运行试用

    pmm 是一个很不错的mysql.mongo.postgresql 数据库监控平台,基于prometheus.grafana.exporter 算是一个比较完整 的数据库分析平台 参考架构图 环境准备 ...

  7. webpack打包vue单文件组件

    一.vue单文件组件 ①文件扩展名为 .vue 的 就是single-file components(单文件组件) ②参考文档:单文件组件 二.webpack加载第三方包 ①项目中,如果需要用到一些第 ...

  8. bootstrap入门&栅格系统

    一.概述 1. 概念: 一个前端开发的框架,Bootstrap,来自 Twitter,是目前很受欢迎的前端框架.Bootstrap 是基于 HTML.CSS.JavaScript 的,它简洁灵活,使得 ...

  9. kafka部署在云服务器(centOS 6.5),本地远程连接问题

    kafka简介 Apache Kafka发源于LinkedIn,于2011年成为Apache的孵化项目,随后于2012年成为Apache的主要项目之一.Kafka使用Scala和Java进行编写.Ap ...

  10. selenium 基本操作

    #前进 driver.back() #后退 driver.forward() #刷新 driver.refresh() #退出 driver.quit() #获取所有 cookie cookies=d ...