Add containerd shim v2 support. (#13)

* Update vendors

Signed-off-by: Lantao Liu <lantaol@google.com>

* Add containerd shim v2 support.

Signed-off-by: Lantao Liu <lantaol@google.com>

* Add test and doc for containerd-shim-runsc-v1.

Signed-off-by: Lantao Liu <lantaol@google.com>

* Address comments.
This commit is contained in:
Lantao Liu
2019-01-29 18:51:18 -08:00
committed by GitHub
parent f39907aa5d
commit 35db607dfc
127 changed files with 28611 additions and 122 deletions
+1
View File
@@ -7,6 +7,7 @@ env:
- CONTAINERD_VERSION=1.1.5 RUNSC_VERSION=2018-12-07 TEST=untrusted-workload
- CONTAINERD_VERSION=1.2.1 RUNSC_VERSION=2018-12-07 TEST=untrusted-workload
- CONTAINERD_VERSION=1.2.1 RUNSC_VERSION=2018-12-07 TEST=runtime-handler
- CONTAINERD_VERSION=1.2.1 RUNSC_VERSION=2018-12-07 TEST=runtime-handler-shim-v2
go_import_path: github.com/google/gvisor-containerd-shim
+6
View File
@@ -7,16 +7,22 @@ SOURCES=$(shell find cmd/ pkg/ vendor/ -name '*.go')
DEPLOY_PATH=cri-containerd-staging/gvisor-containerd-shim
VERSION=$(shell git rev-parse HEAD)
all: bin/gvisor-containerd-shim bin/containerd-shim-runsc-v1
bin/gvisor-containerd-shim: $(SOURCES)
CGO_ENABLED=0 go build ${GO_BUILD_FLAGS} -o bin/gvisor-containerd-shim ${SHIM_GO_LDFLAGS} ${GO_TAGS} ./cmd/gvisor-containerd-shim
bin/containerd-shim-runsc-v1: $(SOURCES)
CGO_ENABLED=0 go build ${GO_BUILD_FLAGS} -o bin/containerd-shim-runsc-v1 ${SHIM_GO_LDFLAGS} ${GO_TAGS} ./cmd/containerd-shim-runsc-v1
install: bin/gvisor-containerd-shim
mkdir -p $(DESTDIR)/bin
install bin/gvisor-containerd-shim $(DESTDIR)/bin
install bin/containerd-shim-runsc-v1 $(DESTDIR)/bin
uninstall:
rm -f $(DESTDIR)/bin/gvisor-containerd-shim
rm -f $(DESTDIR)/bin/containerd-shim-runsc-v1
clean:
rm -rf bin/*
+1
View File
@@ -14,6 +14,7 @@ gvisor-containerd-shim is a containerd shim for [gVisor](https://github.com/goog
- [Untrusted Workload Quick Start (containerd >=1.1)](docs/untrusted-workload-quickstart.md)
- [Runtime Handler Quick Start (containerd >=1.2)](docs/runtime-handler-quickstart.md)
- [Runtime Handler Quick Start (shim v2) (containerd >=1.2)](docs/runtime-handler-shim-v2-quickstart.md)
# Contributing
+24
View File
@@ -0,0 +1,24 @@
/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (
"github.com/containerd/containerd/runtime/v2/shim"
runsc "github.com/google/gvisor-containerd-shim/pkg/v2"
)
func main() {
shim.Run("io.containerd.runsc.v1", runsc.New)
}
+1 -1
View File
@@ -48,7 +48,7 @@ import (
"golang.org/x/sys/unix"
runsc "github.com/google/gvisor-containerd-shim/pkg/go-runsc"
"github.com/google/gvisor-containerd-shim/pkg/shim"
"github.com/google/gvisor-containerd-shim/pkg/v1/shim"
)
var (
+1
View File
@@ -4,3 +4,4 @@ Everything you need to know about gvisor-containerd-shim
- [Untrusted Workload Quick Start (containerd >=1.1)](untrusted-workload-quickstart.md)
- [Runtime Handler Quick Start (containerd >=1.2)](runtime-handler-quickstart.md)
- [Runtime Handler Quick Start (shim v2) (containerd >=1.2)](runtime-handler-shim-v2-quickstart.md)
+6 -14
View File
@@ -16,30 +16,22 @@ later.
1. Download the latest release of the `gvisor-containerd-shim`. See the
[releases page](https://github.com/google/gvisor-containerd-shim/releases)
[embedmd]:# (../test/e2e/shim-install.sh shell /{ # Step 1/ /^}/)
[embedmd]:# (../test/e2e/shim-install.sh shell /{ # Step 1\(release\)/ /^}/)
```shell
{ # Step 1: Download gvisor-containerd-shim
{ # Step 1(release): Install gvisor-containerd-shim
LATEST_RELEASE=$(wget -qO - https://api.github.com/repos/google/gvisor-containerd-shim/releases | grep -oP '(?<="browser_download_url": ")https://[^"]*' | head -1)
wget -O gvisor-containerd-shim
chmod +x gvisor-containerd-shim
sudo mv gvisor-containerd-shim /usr/local/bin/gvisor-containerd-shim
}
```
2. Copy the binary to the desired directory:
2. Create the configuration for the gvisor shim in
`/etc/containerd/gvisor-containerd-shim.yaml`:
[embedmd]:# (../test/e2e/shim-install.sh shell /{ # Step 2/ /^}/)
```shell
{ # Step 2: Copy the binary to the desired directory
sudo mv gvisor-containerd-shim-* /usr/local/bin/gvisor-containerd-shim
}
```
3. Create the configuration for the gvisor shim in
`/etc/containerd/gvisor-containerd-shim.yaml`:
[embedmd]:# (../test/e2e/shim-install.sh shell /{ # Step 3/ /^}/)
```shell
{ # Step 3: Create the gvisor-containerd-shim.yaml
{ # Step 2: Create the gvisor-containerd-shim.yaml
cat <<EOF | sudo tee /etc/containerd/gvisor-containerd-shim.yaml
# This is the path to the default runc containerd-shim.
runc_shim = "/usr/local/bin/containerd-shim"
+187
View File
@@ -0,0 +1,187 @@
# Runtime Handler Quickstart (Shim V2)
This document describes how to install and run `containerd-shim-runsc-v1` using
the containerd runtime handler support. This requires containerd 1.2 or later.
## Requirements
- **runsc**: See the [gVisor documentation](https://github.com/google/gvisor) for information on how to install runsc.
- **containerd**: See the [containerd website](https://containerd.io/) for information on how to install containerd.
## Install
### Install containerd-shim-runsc-v1
1. Build and install `containerd-shim-runsc-v1`.
<!-- TODO: Use a release once we have one available. -->
[embedmd]:# (../test/e2e/shim-install.sh shell /{ # Step 1\(dev\)/ /^}/)
```shell
{ # Step 1(dev): Build and install gvisor-containerd-shim and containerd-shim-runsc-v1
make
sudo make install
}
```
### Configure containerd
1. Update `/etc/containerd/config.toml`. Make sure `containerd-shim-runsc-v1` is
in `${PATH}`.
[embedmd]:# (../test/e2e/runtime-handler-shim-v2/install.sh shell /{ # Step 1/ /^}/)
```shell
{ # Step 1: Create containerd config.toml
cat <<EOF | sudo tee /etc/containerd/config.toml
disabled_plugins = ["restart"]
[plugins.linux]
shim_debug = true
[plugins.cri.containerd.runtimes.runsc]
runtime_type = "io.containerd.runsc.v1"
EOF
}
```
2. Restart `containerd`
```shell
sudo systemctl restart containerd
```
## Usage
You can run containers in gVisor via containerd's CRI.
### Install crictl
1. Download and install the crictl binary:
[embedmd]:# (../test/e2e/crictl-install.sh shell /{ # Step 1/ /^}/)
```shell
{ # Step 1: Download crictl
wget https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.13.0/crictl-v1.13.0-linux-amd64.tar.gz
tar xf crictl-v1.13.0-linux-amd64.tar.gz
sudo mv crictl /usr/local/bin
}
```
2. Write the crictl configuration file
[embedmd]:# (../test/e2e/crictl-install.sh shell /{ # Step 2/ /^}/)
```shell
{ # Step 2: Configure crictl
cat <<EOF | sudo tee /etc/crictl.yaml
runtime-endpoint: unix:///run/containerd/containerd.sock
EOF
}
```
### Create the nginx Sandbox in gVisor
1. Pull the nginx image
[embedmd]:# (../test/e2e/runtime-handler/usage.sh shell /{ # Step 1/ /^}/)
```shell
{ # Step 1: Pull the nginx image
sudo crictl pull nginx
}
```
2. Create the sandbox creation request
[embedmd]:# (../test/e2e/runtime-handler/usage.sh shell /{ # Step 2/ /^EOF\n}/)
```shell
{ # Step 2: Create sandbox.json
cat <<EOF | tee sandbox.json
{
"metadata": {
"name": "nginx-sandbox",
"namespace": "default",
"attempt": 1,
"uid": "hdishd83djaidwnduwk28bcsb"
},
"linux": {
},
"log_directory": "/tmp"
}
EOF
}
```
3. Create the pod in gVisor
[embedmd]:# (../test/e2e/runtime-handler/usage.sh shell /{ # Step 3/ /^}/)
```shell
{ # Step 3: Create the sandbox
SANDBOX_ID=$(sudo crictl runp --runtime runsc sandbox.json)
}
```
### Run the nginx Container in the Sandbox
1. Create the nginx container creation request
[embedmd]:# (../test/e2e/run-container.sh shell /{ # Step 1/ /^EOF\n}/)
```shell
{ # Step 1: Create nginx container config
cat <<EOF | tee container.json
{
"metadata": {
"name": "nginx"
},
"image":{
"image": "nginx"
},
"log_path":"nginx.0.log",
"linux": {
}
}
EOF
}
```
2. Create the nginx container
[embedmd]:# (../test/e2e/run-container.sh shell /{ # Step 2/ /^}/)
```shell
{ # Step 2: Create nginx container
CONTAINER_ID=$(sudo crictl create ${SANDBOX_ID} container.json sandbox.json)
}
```
3. Start the nginx container
[embedmd]:# (../test/e2e/run-container.sh shell /{ # Step 3/ /^}/)
```shell
{ # Step 3: Start nginx container
sudo crictl start ${CONTAINER_ID}
}
```
### Validate the container
1. Inspect the created pod
[embedmd]:# (../test/e2e/validate.sh shell /{ # Step 1/ /^}/)
```shell
{ # Step 1: Inspect the pod
sudo crictl inspectp ${SANDBOX_ID}
}
```
2. Inspect the nginx container
[embedmd]:# (../test/e2e/validate.sh shell /{ # Step 2/ /^}/)
```shell
{ # Step 2: Inspect the container
sudo crictl inspect ${CONTAINER_ID}
}
```
3. Verify that nginx is running in gVisor
[embedmd]:# (../test/e2e/validate.sh shell /{ # Step 3/ /^}/)
```shell
{ # Step 3: Check dmesg
sudo crictl exec ${CONTAINER_ID} dmesg | grep -i gvisor
}
```
+6 -14
View File
@@ -13,7 +13,7 @@ are using containerd 1.2, please consider using runtime handler.*
- **containerd**: See the [containerd website](https://containerd.io/) for information on how to install containerd.
## Install
### Install gvisor-containerd-shim
1. Download the latest release of the `gvisor-containerd-shim`. See the
@@ -21,28 +21,20 @@ are using containerd 1.2, please consider using runtime handler.*
[embedmd]:# (../test/e2e/shim-install.sh shell /{ # Step 1/ /^}/)
```shell
{ # Step 1: Download gvisor-containerd-shim
{ # Step 1(release): Install gvisor-containerd-shim
LATEST_RELEASE=$(wget -qO - https://api.github.com/repos/google/gvisor-containerd-shim/releases | grep -oP '(?<="browser_download_url": ")https://[^"]*' | head -1)
wget -O gvisor-containerd-shim
chmod +x gvisor-containerd-shim
sudo mv gvisor-containerd-shim /usr/local/bin/gvisor-containerd-shim
}
```
2. Copy the binary to the desired directory:
2. Create the configuration for the gvisor shim in
`/etc/containerd/gvisor-containerd-shim.yaml`:
[embedmd]:# (../test/e2e/shim-install.sh shell /{ # Step 2/ /^}/)
```shell
{ # Step 2: Copy the binary to the desired directory
sudo mv gvisor-containerd-shim-* /usr/local/bin/gvisor-containerd-shim
}
```
3. Create the configuration for the gvisor shim in
`/etc/containerd/gvisor-containerd-shim.yaml`:
[embedmd]:# (../test/e2e/shim-install.sh shell /{ # Step 3/ /^}/)
```shell
{ # Step 3: Create the gvisor-containerd-shim.yaml
{ # Step 2: Create the gvisor-containerd-shim.yaml
cat <<EOF | sudo tee /etc/containerd/gvisor-containerd-shim.yaml
# This is the path to the default runc containerd-shim.
runc_shim = "/usr/local/bin/containerd-shim"
+5 -10
View File
@@ -30,7 +30,6 @@ import (
"github.com/containerd/console"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/runtime/proc"
"github.com/containerd/containerd/runtime/v1/shim"
"github.com/containerd/fifo"
runc "github.com/containerd/go-runc"
specs "github.com/opencontainers/runtime-spec/specs-go"
@@ -171,11 +170,11 @@ func (e *execProcess) start(ctx context.Context) (err error) {
if socket != nil {
opts.ConsoleSocket = socket
}
eventCh := shim.Default.Subscribe()
eventCh := e.parent.Monitor.Subscribe()
defer func() {
// Unsubscribe if an error is returned.
if err != nil {
shim.Default.Unsubscribe(eventCh)
e.parent.Monitor.Unsubscribe(eventCh)
}
}()
if err := e.parent.runtime.Exec(ctx, e.parent.id, e.spec, opts); err != nil {
@@ -183,7 +182,7 @@ func (e *execProcess) start(ctx context.Context) (err error) {
return e.parent.runtimeError(err, "OCI runtime exec failed")
}
if e.stdio.Stdin != "" {
sc, err := fifo.OpenFifo(ctx, e.stdio.Stdin, syscall.O_WRONLY|syscall.O_NONBLOCK, 0)
sc, err := fifo.OpenFifo(context.Background(), e.stdio.Stdin, syscall.O_WRONLY|syscall.O_NONBLOCK, 0)
if err != nil {
return errors.Wrapf(err, "failed to open stdin fifo %s", e.stdio.Stdin)
}
@@ -192,11 +191,7 @@ func (e *execProcess) start(ctx context.Context) (err error) {
}
var copyWaitGroup sync.WaitGroup
ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
defer func() {
if err != nil {
cancel()
}
}()
defer cancel()
if socket != nil {
console, err := socket.ReceiveMaster()
if err != nil {
@@ -222,7 +217,7 @@ func (e *execProcess) start(ctx context.Context) (err error) {
}
e.internalPid = internalPid
go func() {
defer shim.Default.Unsubscribe(eventCh)
defer e.parent.Monitor.Unsubscribe(eventCh)
for event := range eventCh {
if event.Pid == e.pid {
ExitCh <- Exit{
+3 -6
View File
@@ -75,6 +75,7 @@ type Init struct {
IoGID int
Sandbox bool
UserLog string
Monitor ProcessMonitor
}
// NewRunsc returns a new runsc instance for a process
@@ -138,7 +139,7 @@ func (p *Init) Create(ctx context.Context, r *CreateConfig) (err error) {
return p.runtimeError(err, "OCI runtime create failed")
}
if r.Stdin != "" {
sc, err := fifo.OpenFifo(ctx, r.Stdin, syscall.O_WRONLY|syscall.O_NONBLOCK, 0)
sc, err := fifo.OpenFifo(context.Background(), r.Stdin, syscall.O_WRONLY|syscall.O_NONBLOCK, 0)
if err != nil {
return errors.Wrapf(err, "failed to open stdin fifo %s", r.Stdin)
}
@@ -147,11 +148,7 @@ func (p *Init) Create(ctx context.Context, r *CreateConfig) (err error) {
}
var copyWaitGroup sync.WaitGroup
ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
defer func() {
if err != nil {
cancel()
}
}()
defer cancel()
if socket != nil {
console, err := socket.ReceiveMaster()
if err != nil {
+1 -1
View File
@@ -112,7 +112,7 @@ func copyPipes(ctx context.Context, rio runc.IO, stdin, stdout, stderr string, w
if stdin == "" {
return nil
}
f, err := fifo.OpenFifo(ctx, stdin, syscall.O_RDONLY|syscall.O_NONBLOCK, 0)
f, err := fifo.OpenFifo(context.Background(), stdin, syscall.O_RDONLY|syscall.O_NONBLOCK, 0)
if err != nil {
return fmt.Errorf("gvisor-containerd-shim: opening %s failed: %s", stdin, err)
}
@@ -21,6 +21,8 @@ import (
"time"
google_protobuf "github.com/gogo/protobuf/types"
runc "github.com/containerd/go-runc"
)
// Mount holds filesystem mount configuration
@@ -60,3 +62,11 @@ type Exit struct {
ID string
Status int
}
// ProcessMonitor monitors process exit changes
type ProcessMonitor interface {
// Subscribe to process exit changes
Subscribe() chan runc.Exit
// Unsubscribe to process exit changes
Unsubscribe(c chan runc.Exit)
}
+6 -28
View File
@@ -19,9 +19,7 @@ package shim
import (
"context"
"encoding/json"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"sync"
@@ -37,18 +35,18 @@ import (
"github.com/containerd/containerd/runtime"
"github.com/containerd/containerd/runtime/linux/runctypes"
rproc "github.com/containerd/containerd/runtime/proc"
"github.com/containerd/containerd/runtime/v1/shim"
shimapi "github.com/containerd/containerd/runtime/v1/shim/v1"
"github.com/containerd/cri/pkg/annotations"
"github.com/containerd/typeurl"
ptypes "github.com/gogo/protobuf/types"
specs "github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
runsc "github.com/google/gvisor-containerd-shim/pkg/go-runsc"
"github.com/google/gvisor-containerd-shim/pkg/proc"
"github.com/google/gvisor-containerd-shim/pkg/v1/proc"
"github.com/google/gvisor-containerd-shim/pkg/v1/utils"
)
var (
@@ -549,7 +547,7 @@ func newInit(ctx context.Context, path, workDir, runtimeRoot, namespace string,
options = *v.(*runctypes.CreateOptions)
}
spec, err := readSpec(r.Bundle)
spec, err := utils.ReadSpec(r.Bundle)
if err != nil {
return nil, errors.Wrap(err, "read oci spec")
}
@@ -568,28 +566,8 @@ func newInit(ctx context.Context, path, workDir, runtimeRoot, namespace string,
p.WorkDir = workDir
p.IoUID = int(options.IoUid)
p.IoGID = int(options.IoGid)
p.Sandbox = isSandbox(spec)
p.Sandbox = utils.IsSandbox(spec)
p.UserLog = userLog
p.Monitor = shim.Default
return p, nil
}
func readSpec(bundle string) (*specs.Spec, error) {
f, err := os.Open(filepath.Join(bundle, "config.json"))
if err != nil {
return nil, err
}
b, err := ioutil.ReadAll(f)
if err != nil {
return nil, err
}
var spec specs.Spec
if err := json.Unmarshal(b, &spec); err != nil {
return nil, err
}
return &spec, nil
}
func isSandbox(spec *specs.Spec) bool {
t, ok := spec.Annotations[annotations.ContainerType]
return !ok || t == annotations.ContainerTypeSandbox
}

Some files were not shown because too many files have changed in this diff Show More