Skip to content

Instantly share code, notes, and snippets.

@jschwinger233
Last active May 13, 2020 11:16
Show Gist options
  • Save jschwinger233/26b231ded56989044f022408e9f3e569 to your computer and use it in GitHub Desktop.
Save jschwinger233/26b231ded56989044f022408e9f3e569 to your computer and use it in GitHub Desktop.

WHO NEEDS CONTAINERD

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

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

  1. 安装 runc, calico, etcd, 创建 calico ippool:
- apiVersion: projectcalico.org/v3
  kind: IPPool
  metadata:
    name: $POOL_NAME
  spec:
    natOutgoing: true
    cidr: $POOL_CIDR
  1. 安装 calico CNI:

  2. 准备 CNI 配置到 /etc/cni/net.d/

{
    "name": "calico-cni",
    "cniVersion": "0.3.1",
    "type": "calico",
    "etcd_endpoints": "http://127.0.0.1:2379",
    "log_level": "info",
    "ipam": {
        "type": "calico-ipam",
        "ipv4_pools": ["$POOL_NAME"]
    }
}

当然要改成自己的 pool name.

  1. 然后 runc 走起来

    • mkdir rootfs
    • docker export $(docker create busybox) | tar -C rootfs -xvf -
    • runc spec
  2. 骚的来了, 在 config.json 里加入 hook 调用 CNI:

  "hooks": {
    "prestart": [
      {
        "env": ["PATH=/opt/cni/bin/:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin", "CNI_PATH=/opt/cni/bin"],
        "path": "/root/cni-master/scripts/exec-plugins.sh",
        "args": [
          "/root/cni-master/scripts/exec-plugins.sh",
          "add",
          "zzc",
          "/run/netns/zzc"
        ]
      }
    ]
  }

对了要先安装 cnitool, 我是直接下载 github.com/containernetworking/cni; 然后也要手动创建 netns zzc (智障川)

  1. runc run zzc, 可以看到容器是成功集成到 calico SDN.

正好借这贴说下 docker 和 Kubernetes 的创建流程.

docker 的流程是:

  1. start container 的第一步, 调用 containerd 之前, 先把 CNM 流程走了, 请求 IP, 创建内部 endpoint 对象
  2. 然后 containerd NewContainer 时候在 OCI spec 里塞上 prestart hook, 类似 libnetwork-setkey $CONT_ID $CONTROL_ID
  3. 然后在 runc 启动容器前运行这个 hook, 会通过 controller id 绑定的一个 unix socket 给 dockerd 发请求, 然后 dockerd 会给容器创建好的 netns 设置上申请好的 IP 和 veth

Kubernetes:

  1. CRI 先创建好 pause 容器(呕
  2. 直接调用 CNI 申请 IP + 绑定到 pause 容器 netns 一步完成
  3. 然后 OCI spec 里指定 network namespace path 完事儿

可以看到两个的做法作风是完全不同的

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment