内容简介:最近在玩这个玩意儿,准备在此之上开发自己的容器编排系统我是使用ArchLinux,因此可以直接安装:
最近在玩这个玩意儿,准备在此之上开发自己的容器编排系统 huang 。这里简单看一下containerd 的使用。containerd是从 Docker 分离出来的一个用于容器、镜像增删改查的程序,这是它的架构图:
安装
我是使用ArchLinux,因此可以直接安装:
$ sudo pacman -S containerd resolving dependencies... looking for conflicting packages... Packages (2) runc-1.0.0rc6-1 containerd-1.2.0-3 Total Installed Size: 108.18 MiB :: Proceed with installation? [Y/n] (2/2) checking keys in keyring [##############################################################] 100% (2/2) checking package integrity [##############################################################] 100% (2/2) loading package files [##############################################################] 100% (2/2) checking for file conflicts [##############################################################] 100% (2/2) checking available disk space [##############################################################] 100% :: Processing package changes... (1/2) installing runc [##############################################################] 100% (2/2) installing containerd [##############################################################] 100% :: Running post-transaction hooks... (1/2) Reloading system manager configuration... (2/2) Arming ConditionNeedsUpdate...
也可以自己下载二进制包,也可以把二进制文件放到 $PATH
里包含的文件夹之一例如 /usr/local/bin
中,然后把对应的 systemd service文件也拷贝到对应的位置。
使用默认配置:
# containerd config default > /etc/containerd/config.toml
使用containerd
我们使用这段代码来连接containerd并且拉取一个 redis 镜像:
package main import ( "context" "log" "github.com/containerd/containerd" "github.com/containerd/containerd/namespaces" "github.com/containerd/containerd/oci" ) func main() { if err := redisExample(); err != nil { log.Fatal(err) } } func redisExample() error { client, err := containerd.New("/run/containerd/containerd.sock") // 连接到containerd默认监听的地址 if err != nil { return err } defer client.Close() ctx := namespaces.WithNamespace(context.Background(), "example") // 使用一个独立的namespace防止冲突 image, err := client.Pull(ctx, "docker.io/library/redis:alpine", containerd.WithPullUnpack) if err != nil { return err } log.Printf("Successfully pulled %s image\n", image.Name()) // 创建一额容器 container, err := client.NewContainer( ctx, "redis-server", containerd.WithNewSnapshot("redis-server-snapshot", image), containerd.WithNewSpec(oci.WithImageConfig(image)), ) if err != nil { return err } defer container.Delete(ctx, containerd.WithSnapshotCleanup) // 记得把容器删了 log.Printf("Successfully created container with ID %s and snapshot with ID redis-server-snapshot", container.ID()) return nil }
执行一下:
$ go build main.go $ sudo ./main [sudo] password for jiajun: 2019/02/27 23:44:40 Successfully pulled docker.io/library/redis:alpine image 2019/02/27 23:44:40 Successfully created container with ID redis-server and snapshot with ID redis-server-snapshot
检查一下镜像是否拉下来了:
$ sudo ctr -n example images ls REF TYPE DIGEST SIZE PLATFORMS LABELS docker.io/library/redis:alpine application/vnd.docker.distribution.manifest.list.v2+json sha256:3fa51e0b90b42ed2dd9bd87620fe7c45c43eb4e1f81c83813a78474cbe2f7457 16.9 MiB linux/386,linux/amd64,linux/arm/v6,linux/arm64/v8,linux/ppc64le,linux/s390x -
注意其中的 -n example
,因为代码中,我们就使用了 example
这个namespace,如果不加这一行我们是看不到结果的,因为默认的namespace 是 default
。
Task
Container是永驻的,Task相当于一条临时命令,例如执行 docker exec -it
的时候。这个例子可以看得出来:
package main import ( "context" "fmt" "log" "syscall" "time" "github.com/containerd/containerd" "github.com/containerd/containerd/cio" "github.com/containerd/containerd/namespaces" "github.com/containerd/containerd/oci" ) 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") // 连接containerd默认地址 if err != nil { return err } defer client.Close() // create a new context with an "example" namespace ctx := namespaces.WithNamespace(context.Background(), "example") // 使用example命名空间 // pull the redis image from DockerHub image, err := client.Pull(ctx, "docker.io/library/redis:alpine", containerd.WithPullUnpack) // 拉镜像 if err != nil { return err } // 创建容器 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) // 连上容器的stdio 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 }
执行一下:
$ sudo ./main 1:C 27 Feb 2019 23:52:08.999 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo 1:C 27 Feb 2019 23:52:08.999 # Redis version=5.0.3, bits=64, commit=00000000, modified=0, pid=1, just started 1:C 27 Feb 2019 23:52:08.999 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf 1:M 27 Feb 2019 23:52:09.002 # You requested maxclients of 10000 requiring at least 10032 max file descriptors. 1:M 27 Feb 2019 23:52:09.002 # Server can't set maximum open files to 10032 because of OS error: Operation not permitted. 1:M 27 Feb 2019 23:52:09.002 # Current maximum open files is 1024. maxclients has been reduced to 992 to compensate for low ulimit. If you need higher maxclients increase 'ulimit -n'. 1:M 27 Feb 2019 23:52:09.003 * Running mode=standalone, port=6379. 1:M 27 Feb 2019 23:52:09.003 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128. 1:M 27 Feb 2019 23:52:09.003 # Server initialized 1:M 27 Feb 2019 23:52:09.003 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect. 1:M 27 Feb 2019 23:52:09.003 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled. 1:M 27 Feb 2019 23:52:09.003 * Ready to accept connections 1:signal-handler (1551325932) Received SIGTERM scheduling shutdown... 1:M 27 Feb 2019 23:52:12.113 # User requested shutdown... 1:M 27 Feb 2019 23:52:12.113 * Saving the final RDB snapshot before exiting. 1:M 27 Feb 2019 23:52:12.127 * DB saved on disk 1:M 27 Feb 2019 23:52:12.127 # Redis is now ready to exit, bye bye... redis-server exited with status: 0
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
微信小程序(开发入门及案例详解)
李骏、边思 / 机械工业出版社 / 2017-3-1 / 59.0
本书可分为3部分,第一部分作为基础章节,介绍了第一个小程序的搭建流程,让大家能快速上手;同时对小程序框架原理进行了详细介绍,为后面学习组件、API打下基础。 第二部分对小程序组件、API进行介绍,对组件、API的使用、注意事项进行详细讲解,并给出示例代码。 最后一部分精选5个由浅入深的案例,对小程序研发进行实战讲解,涵盖了实际项目中可能涉及的技术方案和使用方法,具备很强的实战意义。 ......一起来看看 《微信小程序(开发入门及案例详解)》 这本书的介绍吧!