Skip to content

Instantly share code, notes, and snippets.

View jschwinger233's full-sized avatar
😭
On vacation

graymon jschwinger233

😭
On vacation
  • China
View GitHub Profile

同事说, curl -v http://10.22.12.87:2376/version 返回 400, 问我怎么用 curl 访问 dockerd.

我的思路是先想办法通过 sdk 访问 version api, 然后 tcpdump 观察一下 url 就可以了, 所以:

  1. pip install docker, python repl 里 docker.from_env().version()
  2. tcpdump -i any port 2376 却什么都看不到, 怀疑 from_env() 走的 unix socket
  3. lsof -p + ss -xp 果然是在的 unix socket, 那我抓个 unix socket 的包吧
  4. socat TCP-LISTEN:2375,fork UNIX-CONNECT:/var/run/docker.sock, 然后 python repl 里 docker.DockerClient(base_url='tcp://localhost:2375').version()
  5. 这次可以抓到包了, 一个简单的 GET HTTP, curl 却发现报错说没有证书
  6. 没证书会返回 400? 我自己手动试了一次 curl -v http://10.22.12.87:2376/version, 发现并没有 400, 而是直接说 Client sent an HTTP request to an HTTPS server.

安利浏览器插件 https://github.com/tridactyl/tridactyl/blob/master/readme.md

作为 vimium 的长期用户, 这次是瞬间抛弃 chrome, 只为使用 tridactyl.

highlights:

  1. 纠正了若干 vimium 的错误的 key bindings:
    1. vimium <S-^> 是在 latest tab 之间跳转, vim 里明明是 <C-^>, tridactyl 把这个纠正过来了
    2. vimium u / d 的功能是 vim 里的 <C-u> / <C-d> 翻页, tridactyle u 是恢复最近关闭的 tab, d 是关闭当前 tab
  2. 可以在输入框里 edit in vim!

没想到一个 open files limit 都能让我有这么多惊喜.

  1. ulimitrlimit 是一个东西, 有些文章说 ulimit 代表的是 user limit, 限制的是一个 effective user 的总资源, 而 rlimit 限制的是一个进程的资源, 这是错的.
  2. strace -fT ulimit -n 是不行的, 因为 ulimit 是 shell builtins, 所以 strace ulimit 直接报错说找不到命令; 同理 which ulimit 也没有输出(我第一次知道 builtins 是不能 which 的)
  3. man 3 ulimitThis routine is obsolete. Use getrlimit(2), setrlimit(2), and sysconf(3) instead, 有理由相信 ulimit 就是 rlimit
  4. 直接看 bash 源码, 在 builtins/ulimit.def 里可以清楚看到 ulimit 就是调用 rlimit, 第一个问题解决了, 以下讨论 rlimit.
  5. rlimit 是限制用户 / 会话 / 进程组的吗? 只有 RLIMIT_NPROC, RLIMIT_MSGQUEUE, RLIMIT_SIGPENDING 是按照 real user ID 限制的多个进程的, 分别限制的是进程数, POSIX 消息队列字节数, 排队信号数, 其他都是限制单进程.
  6. /proc/$PID/limitulimit 的关系是对应的, 但是如果你在 shell 里 ulimit -a 看到的东西和一个进程的 /proc/$PID/limit 是不一样的, 不要慌, rlimit 是继承的, 所以看看父进程, 看看不同用户的 rlimit 是否不一样, 看看进程自己是否修改了.
  7. docker run --ulimit 是在 docker 层做的! 我意思是, 这不是交给 containerd 和 runc 做的, runc 对此一无所知. 不过具体在哪一步设置的我还不清楚, 我的 docker 解剖计划已经拖延很久了.
  8. 进程出现了 `accept4: too many open files in s

分层和解耦对我的诱惑太大了, 最近写业务有一些想法.

UI -> App

比方说一个服务有两种协议 http 和 grpc, 再加上一个 cli 吧, 算是三种完全不同的 UI 层了, 共享同一个 App 层的函数:

type App interface {
    func CreateInstance(name string, count, memory, cpu int, network, podname string, dns, env []string) *Instance
}

WHO NEEDS CONTAINERD

标题来自 XCOM2 的成就之一 WHO NEEDS TYGAN, 要求在最后一关使用初级科技通关, 简直恶趣味..

总之成功用 runc 调用 CNI 建立了 calico 网络, 流程是这样的:

  1. 安装 runc, calico, etcd, 创建 calico ippool:
- apiVersion: projectcalico.org/v3
 kind: IPPool

手动实现 bridge 网络和 calico 网络

本质上要解决的问题是连通 host 和 netns, 来体会一下两者的不同思路.

Bridge

用变量方便大家阅读, 否则区分不出语法和变量

NS=dock-ns3

KVM 极简入门

一. QEMU

QEMU (Quick Emulator) 提供了硬件和处理器虚拟化, 它跑在用户态, 无需内核.

话不多说, 直接用起来. 我使用的 OS 是 Ubuntu16.

1.1 安装

最近一周一直在查 calico SDN 挂掉的问题, 过程十分艰辛, 回头想了想觉得可以好好反思一下.

优先尝试进行稳定复现

太沉迷使用各种工具, 倒不是坏事, 只不过性价比太低了.

在开始怀疑 是自己 restart 服务导致的 之后, 就应该立刻开始进行集群的复刻和复现测试:

  1. 复刻: 完全相同的机器上, 使用完全相同的配置(除了端口和落盘目录等), 启动几乎等价的集群, 导入完全相同的数据
  2. 简化: 完全复刻客户端需要启动 calico-felix, 想到一台机器部署两个 felix 是需要技巧的, 不如先简单尝试一下 etcdctl 能否复现, 因为成本低, 就算不能也能快速回到正确的轨道进行完全复刻

另外两点想法

  1. gophers 都不会做并发抽象了

没有语言原生支持并发的时候, 大家有 pool, 有 future, 有 actor, 有 pubsub, 有好莱坞风格, 有双分派, 结果到了 go 里面, 全是裸的 channel 满天飞, 一个 switch case <-chan 能写六七个分支每个分支一屏幕的代码, 没有抽象, 只有原生的, 赤裸裸的, channel, 什么开放封闭, gopher 从不在意, 一扩展就加 case, 真是精妙的软件工程.

  1. 我就是想黑一下 rust

天天在 python 群里看人吹 rust, 拜托 rust 界连个能用的 etcdv3 客户端都没有, 求求你们别吹了.