本篇将说明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. 在WinDbg中显示和搜索std::vector内容

    WinDbg从来都不擅长可视化.尽管Visual Studio一直都有autoexp.dat,而且最近还出现了本机调试器可视化工具,但WinDbg用户不得不满足于转储内存区域和搜索内存来识别模式.另一 ...

  2. Singer 修改tap-s3-csv 支持minio 连接

    singer 团队官方处了一个tap-s3-csv 的tap,对于没有使用aws 的人来说并不是很方便了,所以简单修改了 下源码,可以支持通用的s3 csv 文件的处理,同时发布到了官方pip 仓库中 ...

  3. Unicode-objects must be encoded before hashing 错误解决办法

    提交注册用户数据后出来这个,错误原因是update()必须指定要加密的字符串的字符编码 #encryptions1 = sha1()s1.update(upwd.encode("utf8&q ...

  4. 【题解】洛谷 P1080 国王游戏

    目录 题目 思路 \(Code\) 题目 P1080 国王游戏 思路 贪心+高精度.按\(a \times b\)从小到大排序就可以了. \(Code\) #include<bits/stdc+ ...

  5. 第03组 Alpha冲刺(3/4)

    队名:不等式方程组 组长博客 作业博客 团队项目进度 组员一:张逸杰(组长) 过去两天完成的任务: 文字/口头描述: 制定了初步的项目计划,并开始学习一些推荐.搜索类算法 GitHub签入纪录: 暂无 ...

  6. Android Studio 之 SharedPrefences 数据持久性保存

    SharedPreferences 会在应用包目录中生成一个xml文件,将数据保存在里面 可以实现数据持久性保存. 创建的数据,保存在 Data -> Data -> 包名 -> s ...

  7. AttributeError: 'builtin_function_or_method' object has no attribute 'reshape'

    AttributeError: 'builtin_function_or_method' object has no attribute 'reshape' 读取.mat文件时,copy没加括号

  8. Oracle 导出表结构

    Oracle导出表结构 select A.Table_Name 表名 , -- A.column_name 字段名 A.column_name 字段名, A.data_type 数据类型, A.dat ...

  9. dd命令笔记

    dd命令 用指定大小的块拷贝一个文件,并在拷贝的同时进行指定的转换 参数 if=FILE 指定输入源文件, 缺省为标准输入, < if=input file > iflag=FLAGS 指 ...

  10. C#-DllImport 路径问题

    原文:C# DllImport 相对路径无法找到dll DllImport DLL查找顺序:1.应用程序所在目录2.Windows目录和Windows\System32目录3.环境变量目录 只需要你把 ...