前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >containerd了解

containerd了解

作者头像
heidsoft
发布2022-01-13 15:13:03
发布2022-01-13 15:13:03
68000
代码可运行
举报
运行总次数:0
代码可运行

I recently had a need to manually load some container images into a Linux system running containerd (instead of Docker) as the container runtime. I say “manually load some images” because this system was isolated from the Internet, and so simply running a container and having containerd automatically pull the image from an image registry wasn’t going to work. The process for working around the lack of Internet access isn’t difficult, but didn’t seem to be documented anywhere that I could readily find using a general web search. I thought publishing it here may help individuals seeking this information in the future.

For an administrator/operations-minded user, the primary means of interacting with containerd is via the ctr command-line tool. This tool uses a command syntax very similar to Docker, so users familiar with Docker should be able to be productive with ctr pretty easily.

In my specific example, I had a bastion host with Internet access, and a couple of hosts behind the bastion that did not have Internet access. It was the hosts behind the bastion that needed the container images preloaded. So, I used the ctr tool to fetch and prepare the images on the bastion, then transferred the images to the isolated systems and loaded them. Here’s the process I followed:

On the bastion host, first I downloaded (pulled) the image from a public registry using ctr image pull (the example I’ll use here is for the Calico node container image, used by the Calico CNI in Kubernetes clusters):

(Note that sudo may be needed for all these ctr commands; that will depend on your system configuration.)

If you have a system (like your local laptop) running Docker, then you can use docker pull here instead; just note that you may need to adjust the path/URL to the image/image registry.

Still on the bastion host, I exported the pulled images to standalone archives:

The general format for this command looks like this:

If you don’t know what the image name (according to containerd) is, use ctr image ls.

After transferring the standalone archives to the other systems (using whatever means you prefer; I used scp), then load (or import) the images into containerd with this command:

Repeat as needed for additional images. It appears, by the way, that using wildcards in the ctr image import command won’t work; I had to manually specify each individual file for import.

代码语言:javascript
代码运行次数:0
复制
 ctr -n=k8s.io images import <filename-from-previous-step>

Verify that the image(s) are present and recognized by containerd using ctr image ls.

代码语言:javascript
代码运行次数:0
复制
package main

import (
  "context"
  "fmt"
  "log"
  "syscall"
  "time"

  "github.com/containerd/containerd"
  "github.com/containerd/containerd/cio"
  "github.com/containerd/containerd/oci"
  "github.com/containerd/containerd/namespaces"
)

func main() {
  if err := redisExample(); err != nil {
    log.Fatal(err)
  }
}

func redisExample() error {
  // create a new client connected to the default socket path for containerd
  client, err := containerd.New("/run/containerd/containerd.sock")
  if err != nil {
    return err
  }
  defer client.Close()

  // create a new context with an "example" namespace
  ctx := namespaces.WithNamespace(context.Background(), "example")

  // pull the redis image from DockerHub
  image, err := client.Pull(ctx, "docker.io/library/redis:alpine", containerd.WithPullUnpack)
  if err != nil {
    return err
  }

  // create a container
  container, err := client.NewContainer(
    ctx,
    "redis-server",
    containerd.WithImage(image),
    containerd.WithNewSnapshot("redis-server-snapshot", image),
    containerd.WithNewSpec(oci.WithImageConfig(image)),
  )
  if err != nil {
    return err
  }
  defer container.Delete(ctx, containerd.WithSnapshotCleanup)

  // create a task from the container
  task, err := container.NewTask(ctx, cio.NewCreator(cio.WithStdio))
  if err != nil {
    return err
  }
  defer task.Delete(ctx)

  // make sure we wait before calling start
  exitStatusC, err := task.Wait(ctx)
  if err != nil {
    fmt.Println(err)
  }

  // call start on the task to execute the redis server
  if err := task.Start(ctx); err != nil {
    return err
  }

  // sleep for a lil bit to see the logs
  time.Sleep(3 * time.Second)

  // kill the process and get the exit status
  if err := task.Kill(ctx, syscall.SIGTERM); err != nil {
    return err
  }

  // wait for the process to fully exit and print out the exit status

  status := <-exitStatusC
  code, _, err := status.Result()
  if err != nil {
    return err
  }
  fmt.Printf("redis-server exited with status: %d\n", code)

  return nil
}
  • https://github.com/containerd/cri/blob/master/docs/crictl.md
  • https://sweetcode.io/getting-started-with-containerd/
  • https://docs.quay.io/solution/getting-started.html
  • https://access.redhat.com/documentation/en-us/red_hat_quay/3/html/manage_red_hat_quay/repo-mirroring-in-red-hat-quay
  • https://docs.docker.com/network/proxy/
  • https://support.huaweicloud.com/usermanual-mcp/mcp_01_0055.html
  • https://github.com/baidu/EasyFaaS
  • https://github.com/polarismesh/polaris/blob/main/README-zh.md
  • https://containerd.io/docs/getting-started/
  • https://cloud.google.com/architecture/best-practices-for-building-containers
  • https://www.infoq.cn/article/2017/02/docker-containerd-runc
  • https://github.com/opencontainers/runc
  • https://www.tutorialworks.com/difference-docker-containerd-runc-crio-oci/
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-09-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 云数智圈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档