Signed-off-by: Lantao Liu <lantaol@google.com>
This commit is contained in:
Lantao Liu
2019-08-05 11:22:41 -07:00
parent cb46663725
commit c99961c6c0
158 changed files with 8322 additions and 5290 deletions

View File

@@ -15,7 +15,7 @@ for information about the standalone version of `cri-containerd`.*
[![Build Status](https://api.travis-ci.org/containerd/cri.svg?style=flat-square)](https://travis-ci.org/containerd/cri)
[![Go Report Card](https://goreportcard.com/badge/github.com/containerd/cri)](https://goreportcard.com/report/github.com/containerd/cri)
`cri` is a [containerd](https://containerd.io/) plugin implementation of Kubernetes [container runtime interface (CRI)](https://github.com/kubernetes/kubernetes/blob/master/pkg/kubelet/apis/cri/runtime/v1alpha2/api.proto).
`cri` is a [containerd](https://containerd.io/) plugin implementation of Kubernetes [container runtime interface (CRI)](https://github.com/kubernetes/cri-api/blob/master/pkg/apis/runtime/v1alpha2/api.proto).
With it, you could run Kubernetes using containerd as the container runtime.
![cri](./docs/cri.png)
@@ -162,7 +162,7 @@ For sync communication we have a community slack with a #containerd channel that
everyone is welcome to join and chat about development.
**Slack:** Catch us in the #containerd and #containerd-dev channels on dockercommunity.slack.com.
[Click here for an invite to docker community slack.](https://join.slack.com/t/dockercommunity/shared_invite/enQtNDY4MDc1Mzc0MzIwLTgxZDBlMmM4ZGEyNDc1N2FkMzlhODJkYmE1YTVkYjM1MDE3ZjAwZjBkOGFlOTJkZjRmZGYzNjYyY2M3ZTUxYzQ)
[Click here for an invite to docker community slack.](https://dockr.ly/slack)
## Other Communications
As this project is tightly coupled to CRI and CRI-Tools and they are Kubernetes

View File

@@ -1,78 +0,0 @@
/*
Copyright 2018 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 cli
import (
gocontext "context"
"fmt"
"path/filepath"
api "github.com/containerd/cri/pkg/api/v1"
"github.com/containerd/cri/pkg/client"
"github.com/pkg/errors"
"github.com/urfave/cli"
)
// Command is the cli command for cri plugin.
var Command = cli.Command{
Name: "cri",
Usage: "interact with cri plugin",
Subcommands: cli.Commands{
loadCommand,
},
}
var loadCommand = cli.Command{
Name: "load",
Usage: "load one or more images from tar archives.",
ArgsUsage: "[flags] TAR [TAR, ...]",
Description: "load one or more images from tar archives.",
Flags: []cli.Flag{},
Action: func(context *cli.Context) error {
var (
ctx = gocontext.Background()
address = context.GlobalString("address")
timeout = context.GlobalDuration("timeout")
cancel gocontext.CancelFunc
)
if timeout > 0 {
ctx, cancel = gocontext.WithTimeout(gocontext.Background(), timeout)
} else {
ctx, cancel = gocontext.WithCancel(ctx)
}
defer cancel()
cl, err := client.NewCRIPluginClient(ctx, address)
if err != nil {
return errors.Wrap(err, "failed to create grpc client")
}
for _, path := range context.Args() {
absPath, err := filepath.Abs(path)
if err != nil {
return errors.Wrap(err, "failed to get absolute path")
}
res, err := cl.LoadImage(ctx, &api.LoadImageRequest{FilePath: absPath})
if err != nil {
return errors.Wrap(err, "failed to load image")
}
images := res.GetImages()
for _, image := range images {
fmt.Println("Loaded image:", image)
}
}
return nil
},
}

View File

@@ -1,5 +1,5 @@
/*
Copyright 2018 The Containerd Authors.
Copyright 2018 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.
@@ -141,6 +141,28 @@ func validateConfig(ctx context.Context, c *criconfig.Config) error {
return errors.New("no corresponding runtime configured in `runtimes` for `default_runtime_name`")
}
// Validation for deprecated runtime options.
if c.SystemdCgroup {
if c.ContainerdConfig.Runtimes[c.ContainerdConfig.DefaultRuntimeName].Type != plugin.RuntimeLinuxV1 {
return errors.Errorf("`systemd_cgroup` only works for runtime %s", plugin.RuntimeLinuxV1)
}
log.G(ctx).Warning("`systemd_cgroup` is deprecated, please use runtime `options` instead")
}
for _, r := range c.ContainerdConfig.Runtimes {
if r.Engine != "" {
if r.Type != plugin.RuntimeLinuxV1 {
return errors.Errorf("`runtime_engine` only works for runtime %s", plugin.RuntimeLinuxV1)
}
log.G(ctx).Warning("`runtime_engine` is deprecated, please use runtime `options` instead")
}
if r.Root != "" {
if r.Type != plugin.RuntimeLinuxV1 {
return errors.Errorf("`runtime_root` only works for runtime %s", plugin.RuntimeLinuxV1)
}
log.G(ctx).Warning("`runtime_root` is deprecated, please use runtime `options` instead")
}
}
// Validation for stream_idle_timeout
if c.StreamIdleTimeout != "" {
if _, err := time.ParseDuration(c.StreamIdleTimeout); err != nil {

View File

@@ -1,578 +0,0 @@
/*
Copyright 2019 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.
*/
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: api.proto
/*
Package api_v1 is a generated protocol buffer package.
It is generated from these files:
api.proto
It has these top-level messages:
LoadImageRequest
LoadImageResponse
*/
package api_v1
import proto "github.com/gogo/protobuf/proto"
import fmt "fmt"
import math "math"
import _ "github.com/gogo/protobuf/gogoproto"
import (
context "golang.org/x/net/context"
grpc "google.golang.org/grpc"
)
import strings "strings"
import reflect "reflect"
import io "io"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
type LoadImageRequest struct {
// FilePath is the absolute path of docker image tarball.
FilePath string `protobuf:"bytes,1,opt,name=FilePath,proto3" json:"FilePath,omitempty"`
}
func (m *LoadImageRequest) Reset() { *m = LoadImageRequest{} }
func (*LoadImageRequest) ProtoMessage() {}
func (*LoadImageRequest) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{0} }
func (m *LoadImageRequest) GetFilePath() string {
if m != nil {
return m.FilePath
}
return ""
}
type LoadImageResponse struct {
// Images have been loaded.
Images []string `protobuf:"bytes,1,rep,name=Images" json:"Images,omitempty"`
}
func (m *LoadImageResponse) Reset() { *m = LoadImageResponse{} }
func (*LoadImageResponse) ProtoMessage() {}
func (*LoadImageResponse) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{1} }
func (m *LoadImageResponse) GetImages() []string {
if m != nil {
return m.Images
}
return nil
}
func init() {
proto.RegisterType((*LoadImageRequest)(nil), "api.v1.LoadImageRequest")
proto.RegisterType((*LoadImageResponse)(nil), "api.v1.LoadImageResponse")
}
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion4
// Client API for CRIPluginService service
type CRIPluginServiceClient interface {
// LoadImage loads a image into containerd.
LoadImage(ctx context.Context, in *LoadImageRequest, opts ...grpc.CallOption) (*LoadImageResponse, error)
}
type cRIPluginServiceClient struct {
cc *grpc.ClientConn
}
func NewCRIPluginServiceClient(cc *grpc.ClientConn) CRIPluginServiceClient {
return &cRIPluginServiceClient{cc}
}
func (c *cRIPluginServiceClient) LoadImage(ctx context.Context, in *LoadImageRequest, opts ...grpc.CallOption) (*LoadImageResponse, error) {
out := new(LoadImageResponse)
err := grpc.Invoke(ctx, "/api.v1.CRIPluginService/LoadImage", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Server API for CRIPluginService service
type CRIPluginServiceServer interface {
// LoadImage loads a image into containerd.
LoadImage(context.Context, *LoadImageRequest) (*LoadImageResponse, error)
}
func RegisterCRIPluginServiceServer(s *grpc.Server, srv CRIPluginServiceServer) {
s.RegisterService(&_CRIPluginService_serviceDesc, srv)
}
func _CRIPluginService_LoadImage_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(LoadImageRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(CRIPluginServiceServer).LoadImage(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/api.v1.CRIPluginService/LoadImage",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(CRIPluginServiceServer).LoadImage(ctx, req.(*LoadImageRequest))
}
return interceptor(ctx, in, info, handler)
}
var _CRIPluginService_serviceDesc = grpc.ServiceDesc{
ServiceName: "api.v1.CRIPluginService",
HandlerType: (*CRIPluginServiceServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "LoadImage",
Handler: _CRIPluginService_LoadImage_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "api.proto",
}
func (m *LoadImageRequest) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA)
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *LoadImageRequest) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
if len(m.FilePath) > 0 {
dAtA[i] = 0xa
i++
i = encodeVarintApi(dAtA, i, uint64(len(m.FilePath)))
i += copy(dAtA[i:], m.FilePath)
}
return i, nil
}
func (m *LoadImageResponse) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA)
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *LoadImageResponse) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
if len(m.Images) > 0 {
for _, s := range m.Images {
dAtA[i] = 0xa
i++
l = len(s)
for l >= 1<<7 {
dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
l >>= 7
i++
}
dAtA[i] = uint8(l)
i++
i += copy(dAtA[i:], s)
}
}
return i, nil
}
func encodeVarintApi(dAtA []byte, offset int, v uint64) int {
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return offset + 1
}
func (m *LoadImageRequest) Size() (n int) {
var l int
_ = l
l = len(m.FilePath)
if l > 0 {
n += 1 + l + sovApi(uint64(l))
}
return n
}
func (m *LoadImageResponse) Size() (n int) {
var l int
_ = l
if len(m.Images) > 0 {
for _, s := range m.Images {
l = len(s)
n += 1 + l + sovApi(uint64(l))
}
}
return n
}
func sovApi(x uint64) (n int) {
for {
n++
x >>= 7
if x == 0 {
break
}
}
return n
}
func sozApi(x uint64) (n int) {
return sovApi(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (this *LoadImageRequest) String() string {
if this == nil {
return "nil"
}
s := strings.Join([]string{`&LoadImageRequest{`,
`FilePath:` + fmt.Sprintf("%v", this.FilePath) + `,`,
`}`,
}, "")
return s
}
func (this *LoadImageResponse) String() string {
if this == nil {
return "nil"
}
s := strings.Join([]string{`&LoadImageResponse{`,
`Images:` + fmt.Sprintf("%v", this.Images) + `,`,
`}`,
}, "")
return s
}
func valueToStringApi(v interface{}) string {
rv := reflect.ValueOf(v)
if rv.IsNil() {
return "nil"
}
pv := reflect.Indirect(rv).Interface()
return fmt.Sprintf("*%v", pv)
}
func (m *LoadImageRequest) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowApi
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: LoadImageRequest: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: LoadImageRequest: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field FilePath", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowApi
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthApi
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.FilePath = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipApi(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthApi
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *LoadImageResponse) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowApi
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: LoadImageResponse: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: LoadImageResponse: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Images", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowApi
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthApi
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Images = append(m.Images, string(dAtA[iNdEx:postIndex]))
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipApi(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthApi
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipApi(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowApi
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowApi
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
return iNdEx, nil
case 1:
iNdEx += 8
return iNdEx, nil
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowApi
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
iNdEx += length
if length < 0 {
return 0, ErrInvalidLengthApi
}
return iNdEx, nil
case 3:
for {
var innerWire uint64
var start int = iNdEx
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowApi
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
innerWire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
innerWireType := int(innerWire & 0x7)
if innerWireType == 4 {
break
}
next, err := skipApi(dAtA[start:])
if err != nil {
return 0, err
}
iNdEx = start + next
}
return iNdEx, nil
case 4:
return iNdEx, nil
case 5:
iNdEx += 4
return iNdEx, nil
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
}
panic("unreachable")
}
var (
ErrInvalidLengthApi = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowApi = fmt.Errorf("proto: integer overflow")
)
func init() { proto.RegisterFile("api.proto", fileDescriptorApi) }
var fileDescriptorApi = []byte{
// 219 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x4c, 0x2c, 0xc8, 0xd4,
0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x03, 0x31, 0xcb, 0x0c, 0xa5, 0x74, 0xd3, 0x33, 0x4b,
0x32, 0x4a, 0x93, 0xf4, 0x92, 0xf3, 0x73, 0xf5, 0xd3, 0xf3, 0xd3, 0xf3, 0xf5, 0xc1, 0xd2, 0x49,
0xa5, 0x69, 0x60, 0x1e, 0x98, 0x03, 0x66, 0x41, 0xb4, 0x29, 0xe9, 0x71, 0x09, 0xf8, 0xe4, 0x27,
0xa6, 0x78, 0xe6, 0x26, 0xa6, 0xa7, 0x06, 0xa5, 0x16, 0x96, 0xa6, 0x16, 0x97, 0x08, 0x49, 0x71,
0x71, 0xb8, 0x65, 0xe6, 0xa4, 0x06, 0x24, 0x96, 0x64, 0x48, 0x30, 0x2a, 0x30, 0x6a, 0x70, 0x06,
0xc1, 0xf9, 0x4a, 0xda, 0x5c, 0x82, 0x48, 0xea, 0x8b, 0x0b, 0xf2, 0xf3, 0x8a, 0x53, 0x85, 0xc4,
0xb8, 0xd8, 0xc0, 0x02, 0xc5, 0x12, 0x8c, 0x0a, 0xcc, 0x1a, 0x9c, 0x41, 0x50, 0x9e, 0x51, 0x18,
0x97, 0x80, 0x73, 0x90, 0x67, 0x40, 0x4e, 0x69, 0x7a, 0x66, 0x5e, 0x70, 0x6a, 0x51, 0x59, 0x66,
0x72, 0xaa, 0x90, 0x13, 0x17, 0x27, 0xdc, 0x00, 0x21, 0x09, 0x3d, 0x88, 0xab, 0xf5, 0xd0, 0xdd,
0x20, 0x25, 0x89, 0x45, 0x06, 0x62, 0x9b, 0x12, 0x83, 0x93, 0xcc, 0x89, 0x87, 0x72, 0x8c, 0x37,
0x1e, 0xca, 0x31, 0x34, 0x3c, 0x92, 0x63, 0x3c, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, 0x39, 0xc6,
0x07, 0x8f, 0xe4, 0x18, 0x27, 0x3c, 0x96, 0x63, 0x48, 0x62, 0x03, 0xfb, 0xcc, 0x18, 0x10, 0x00,
0x00, 0xff, 0xff, 0xfc, 0x6f, 0xec, 0xf4, 0x1d, 0x01, 0x00, 0x00,
}

View File

@@ -1,30 +0,0 @@
// To regenerate api.pb.go run `make proto`
syntax = 'proto3';
package api.v1;
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
option (gogoproto.goproto_stringer_all) = false;
option (gogoproto.stringer_all) = true;
option (gogoproto.goproto_getters_all) = true;
option (gogoproto.marshaler_all) = true;
option (gogoproto.sizer_all) = true;
option (gogoproto.unmarshaler_all) = true;
option (gogoproto.goproto_unrecognized_all) = false;
// CRIPluginService defines non-CRI APIs for cri plugin.
service CRIPluginService{
// LoadImage loads a image into containerd.
rpc LoadImage(LoadImageRequest) returns (LoadImageResponse) {}
}
message LoadImageRequest {
// FilePath is the absolute path of docker image tarball.
string FilePath = 1;
}
message LoadImageResponse {
// Images have been loaded.
repeated string Images = 1;
}

View File

@@ -1,45 +0,0 @@
/*
Copyright 2017 The Kubernetes 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 client
import (
"context"
"github.com/pkg/errors"
"google.golang.org/grpc"
"k8s.io/kubernetes/pkg/kubelet/util"
api "github.com/containerd/cri/pkg/api/v1"
)
// NewCRIPluginClient creates grpc client of cri plugin
// TODO(random-liu): Wrap grpc functions.
func NewCRIPluginClient(ctx context.Context, endpoint string) (api.CRIPluginServiceClient, error) {
addr, dialer, err := util.GetAddressAndDialer(endpoint)
if err != nil {
return nil, errors.Wrap(err, "failed to get dialer")
}
conn, err := grpc.DialContext(ctx, addr,
grpc.WithBlock(),
grpc.WithInsecure(),
grpc.WithDialer(dialer),
)
if err != nil {
return nil, errors.Wrap(err, "failed to dial")
}
return api.NewCRIPluginServiceClient(conn), nil
}

View File

@@ -71,6 +71,10 @@ type CniConfig struct {
NetworkPluginBinDir string `toml:"bin_dir" json:"binDir"`
// NetworkPluginConfDir is the directory in which the admin places a CNI conf.
NetworkPluginConfDir string `toml:"conf_dir" json:"confDir"`
// NetworkPluginMaxConfNum is the max number of plugin config files that will
// be loaded from the cni config directory by go-cni. Set the value to 0 to
// load all config files (no arbitrary limit). The legacy default value is 1.
NetworkPluginMaxConfNum int `toml:"max_conf_num" json:"maxConfNum"`
// NetworkPluginConfTemplate is the file path of golang template used to generate
// cni config.
// When it is set, containerd will get cidr from kubelet to replace {{.PodCIDR}} in
@@ -106,6 +110,13 @@ type AuthConfig struct {
IdentityToken string `toml:"identitytoken" json:"identitytoken"`
}
// TLSConfig contains the CA/Cert/Key used for a registry
type TLSConfig struct {
CAFile string `toml:"ca_file" json:"caFile"`
CertFile string `toml:"cert_file" json:"certFile"`
KeyFile string `toml:"key_file" json:"keyFile"`
}
// Registry is registry settings configured
type Registry struct {
// Mirrors are namespace to mirror mapping for all namespaces.
@@ -113,6 +124,9 @@ type Registry struct {
// Auths are registry endpoint to auth config mapping. The registry endpoint must
// be a valid url with host specified.
Auths map[string]AuthConfig `toml:"auths" json:"auths"`
// TLSConfigs are pairs of CA/Cert/Key which then are used when creating the transport
// that communicates with the registry.
TLSConfigs map[string]TLSConfig `toml:"tls_configs" json:"tlsConfigs"`
}
// PluginConfig contains toml config related to CRI plugin,
@@ -124,6 +138,8 @@ type PluginConfig struct {
CniConfig `toml:"cni" json:"cni"`
// Registry contains config related to the registry
Registry Registry `toml:"registry" json:"registry"`
// DisableTCPService disables serving CRI on the TCP server.
DisableTCPService bool `toml:"disable_tcp_service" json:"disableTCPService"`
// StreamServerAddress is the ip address streaming server is listening on.
StreamServerAddress string `toml:"stream_server_address" json:"streamServerAddress"`
// StreamServerPort is the port streaming server is listening on.
@@ -161,6 +177,11 @@ type PluginConfig struct {
// current OOMScoreADj.
// This is useful when the containerd does not have permission to decrease OOMScoreAdj.
RestrictOOMScoreAdj bool `toml:"restrict_oom_score_adj" json:"restrictOOMScoreAdj"`
// MaxConcurrentDownloads restricts the number of concurrent downloads for each image.
MaxConcurrentDownloads int `toml:"max_concurrent_downloads" json:"maxConcurrentDownloads"`
// DisableProcMount disables Kubernetes ProcMount support. This MUST be set to `true`
// when using containerd with Kubernetes <=1.11.
DisableProcMount bool `toml:"disable_proc_mount" json:"disableProcMount"`
}
// X509KeyPairStreaming contains the x509 configuration for streaming
@@ -192,6 +213,7 @@ func DefaultConfig() PluginConfig {
CniConfig: CniConfig{
NetworkPluginBinDir: "/opt/cni/bin",
NetworkPluginConfDir: "/etc/cni/net.d",
NetworkPluginMaxConfNum: 1, // only one CNI plugin config file will be loaded
NetworkPluginConfTemplate: "",
},
ContainerdConfig: ContainerdConfig{
@@ -204,6 +226,7 @@ func DefaultConfig() PluginConfig {
},
},
},
DisableTCPService: true,
StreamServerAddress: "127.0.0.1",
StreamServerPort: "0",
StreamIdleTimeout: streaming.DefaultConfig.StreamIdleTimeout.String(), // 4 hour
@@ -224,6 +247,8 @@ func DefaultConfig() PluginConfig {
},
},
},
MaxConcurrentDownloads: 3,
DisableProcMount: false,
}
}

View File

@@ -1,356 +0,0 @@
/*
Copyright 2017 The Kubernetes 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 importer
import (
"archive/tar"
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"strings"
"github.com/containerd/containerd"
"github.com/containerd/containerd/content"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/images"
"github.com/containerd/containerd/leases"
"github.com/containerd/containerd/log"
"github.com/docker/distribution/reference"
"github.com/opencontainers/go-digest"
"github.com/opencontainers/image-spec/specs-go"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
ctrdutil "github.com/containerd/cri/pkg/containerd/util"
)
// This code reuses the docker import code from containerd/containerd#1602.
// It has been simplified a bit and garbage collection support was added.
// If a library/helper is added to containerd in the future, we should switch to it.
// manifestDotJSON is an entry in manifest.json.
type manifestDotJSON struct {
Config string
RepoTags []string
Layers []string
// Parent is unsupported
Parent string
}
// isLayerTar returns true if name is like "foobar/layer.tar"
func isLayerTar(name string) bool {
slashes := len(strings.Split(name, "/"))
return slashes == 2 && strings.HasSuffix(name, "/layer.tar")
}
// followSymlinkLayer returns actual layer name of the symlink layer.
// It returns "foobar/layer.tar" if the name is like
// "../foobar/layer.tar", and returns error if the name
// is not in "../foobar/layer.tar" format.
func followSymlinkLayer(name string) (string, error) {
parts := strings.Split(name, "/")
if len(parts) != 3 || parts[0] != ".." {
return "", errors.New("invalid symlink layer")
}
name = strings.TrimPrefix(name, "../")
if !isLayerTar(name) {
return "", errors.New("invalid layer tar")
}
return name, nil
}
// isDotJSON returns true if name is like "foobar.json"
func isDotJSON(name string) bool {
slashes := len(strings.Split(name, "/"))
return slashes == 1 && strings.HasSuffix(name, ".json")
}
type imageConfig struct {
desc ocispec.Descriptor
img ocispec.Image
}
type importConfig struct {
unpack bool
snapshotter string
}
// ImportOption configures import behavior.
type ImportOption func(*importConfig)
// WithUnpack is used to unpack image after import.
func WithUnpack(snapshotter string) ImportOption {
return func(c *importConfig) {
c.unpack = true
c.snapshotter = snapshotter
}
}
// Import implements Docker Image Spec v1.1.
// An image MUST have `manifest.json`.
// `repositories` file in Docker Image Spec v1.0 is not supported (yet).
// Also, the current implementation assumes the implicit file name convention,
// which is not explicitly documented in the spec. (e.g. foobar/layer.tar)
// It returns a group of image references successfully loaded.
func Import(ctx context.Context, client *containerd.Client, reader io.Reader, opts ...ImportOption) (_ []string, retErr error) {
c := &importConfig{}
for _, o := range opts {
o(c)
}
ctx, done, err := client.WithLease(ctx)
if err != nil {
return nil, err
}
defer func() {
deferCtx, deferCancel := ctrdutil.DeferContext()
defer deferCancel()
if err := done(deferCtx); err != nil {
// Get lease id from context still works after context is done.
leaseID, _ := leases.FromContext(ctx)
log.G(ctx).WithError(err).Errorf("Failed to release lease %q", leaseID)
}
}()
cs := client.ContentStore()
is := client.ImageService()
tr := tar.NewReader(reader)
var (
mfsts []manifestDotJSON
symlinkLayers = make(map[string]string) // key: filename (foobar/layer.tar), value: linkname (targetlayerid/layer.tar)
layers = make(map[string]ocispec.Descriptor) // key: filename (foobar/layer.tar)
configs = make(map[string]imageConfig) // key: filename (foobar.json)
)
for {
hdr, err := tr.Next()
if err == io.EOF {
break
}
if err != nil {
return nil, errors.Wrap(err, "get next file")
}
if hdr.Typeflag == tar.TypeSymlink && isLayerTar(hdr.Name) {
linkname, err := followSymlinkLayer(hdr.Linkname)
if err != nil {
return nil, errors.Wrapf(err, "follow symlink layer from %q to %q", hdr.Name, hdr.Linkname)
}
symlinkLayers[hdr.Name] = linkname
continue
}
if hdr.Typeflag != tar.TypeReg && hdr.Typeflag != tar.TypeRegA {
continue
}
if hdr.Name == "manifest.json" {
mfsts, err = onUntarManifestJSON(tr)
if err != nil {
return nil, errors.Wrapf(err, "untar manifest %q", hdr.Name)
}
continue
}
if isLayerTar(hdr.Name) {
desc, err := onUntarLayerTar(ctx, tr, cs, hdr.Name, hdr.Size)
if err != nil {
return nil, errors.Wrapf(err, "untar layer %q", hdr.Name)
}
layers[hdr.Name] = *desc
continue
}
if isDotJSON(hdr.Name) {
c, err := onUntarDotJSON(ctx, tr, cs, hdr.Name, hdr.Size)
if err != nil {
return nil, errors.Wrapf(err, "untar config %q", hdr.Name)
}
configs[hdr.Name] = *c
continue
}
}
for name, linkname := range symlinkLayers {
desc, ok := layers[linkname]
if !ok {
return nil, errors.Errorf("no target for symlink layer from %q to %q", name, linkname)
}
layers[name] = desc
}
var refs []string
defer func() {
if retErr == nil {
return
}
// TODO(random-liu): Consider whether we should keep images already imported
// even when there is an error.
for _, ref := range refs {
func() {
deferCtx, deferCancel := ctrdutil.DeferContext()
defer deferCancel()
if err := is.Delete(deferCtx, ref); err != nil {
log.G(ctx).WithError(err).Errorf("Failed to remove image %q", ref)
}
}()
}
}()
for _, mfst := range mfsts {
config, ok := configs[mfst.Config]
if !ok {
return refs, errors.Errorf("image config %q not found", mfst.Config)
}
schema2Manifest, err := makeDockerSchema2Manifest(mfst, config, layers)
if err != nil {
return refs, errors.Wrap(err, "create docker manifest")
}
desc, err := writeDockerSchema2Manifest(ctx, cs, *schema2Manifest, config.img.Architecture, config.img.OS)
if err != nil {
return refs, errors.Wrap(err, "write docker manifest")
}
for _, ref := range mfst.RepoTags {
normalized, err := reference.ParseDockerRef(ref)
if err != nil {
return refs, errors.Wrapf(err, "normalize image ref %q", ref)
}
ref = normalized.String()
imgrec := images.Image{
Name: ref,
Target: *desc,
}
if c.unpack {
img := containerd.NewImage(client, imgrec)
if err := img.Unpack(ctx, c.snapshotter); err != nil {
return refs, errors.Wrapf(err, "unpack image %q", ref)
}
}
if _, err := is.Create(ctx, imgrec); err != nil {
if !errdefs.IsAlreadyExists(err) {
return refs, errors.Wrapf(err, "create image ref %+v", imgrec)
}
_, err := is.Update(ctx, imgrec)
if err != nil {
return refs, errors.Wrapf(err, "update image ref %+v", imgrec)
}
}
refs = append(refs, ref)
}
}
return refs, nil
}
func makeDockerSchema2Manifest(mfst manifestDotJSON, config imageConfig, layers map[string]ocispec.Descriptor) (*ocispec.Manifest, error) {
manifest := ocispec.Manifest{
Versioned: specs.Versioned{
SchemaVersion: 2,
},
Config: config.desc,
}
for _, f := range mfst.Layers {
desc, ok := layers[f]
if !ok {
return nil, errors.Errorf("layer %q not found", f)
}
manifest.Layers = append(manifest.Layers, desc)
}
return &manifest, nil
}
func writeDockerSchema2Manifest(ctx context.Context, cs content.Ingester, manifest ocispec.Manifest, arch, os string) (*ocispec.Descriptor, error) {
manifestBytes, err := json.Marshal(manifest)
if err != nil {
return nil, err
}
manifestBytesR := bytes.NewReader(manifestBytes)
manifestDigest := digest.FromBytes(manifestBytes)
labels := map[string]string{}
labels["containerd.io/gc.ref.content.0"] = manifest.Config.Digest.String()
for i, ch := range manifest.Layers {
labels[fmt.Sprintf("containerd.io/gc.ref.content.%d", i+1)] = ch.Digest.String()
}
desc := ocispec.Descriptor{
MediaType: images.MediaTypeDockerSchema2Manifest,
Digest: manifestDigest,
Size: int64(len(manifestBytes)),
}
if err := content.WriteBlob(ctx, cs, "manifest-"+manifestDigest.String(), manifestBytesR,
desc, content.WithLabels(labels)); err != nil {
return nil, err
}
if arch != "" || os != "" {
desc.Platform = &ocispec.Platform{
Architecture: arch,
OS: os,
}
}
return &desc, nil
}
func onUntarManifestJSON(r io.Reader) ([]manifestDotJSON, error) {
// name: "manifest.json"
b, err := ioutil.ReadAll(r)
if err != nil {
return nil, err
}
var mfsts []manifestDotJSON
if err := json.Unmarshal(b, &mfsts); err != nil {
return nil, err
}
return mfsts, nil
}
func onUntarLayerTar(ctx context.Context, r io.Reader, cs content.Ingester, name string, size int64) (*ocispec.Descriptor, error) {
// name is like "foobar/layer.tar" ( guaranteed by isLayerTar() )
split := strings.Split(name, "/")
// note: split[0] is not expected digest here
cw, err := cs.Writer(ctx, content.WithRef("layer-"+split[0]), content.WithDescriptor(ocispec.Descriptor{Size: size}))
if err != nil {
return nil, err
}
defer cw.Close()
if err := content.Copy(ctx, cw, r, size, ""); err != nil {
return nil, err
}
return &ocispec.Descriptor{
MediaType: images.MediaTypeDockerSchema2Layer,
Size: size,
Digest: cw.Digest(),
}, nil
}
func onUntarDotJSON(ctx context.Context, r io.Reader, cs content.Ingester, name string, size int64) (*imageConfig, error) {
config := imageConfig{}
config.desc.MediaType = images.MediaTypeDockerSchema2Config
config.desc.Size = size
// name is like "foobar.json" ( guaranteed by is DotJSON() )
split := strings.Split(name, ".")
cw, err := cs.Writer(ctx, content.WithRef("config-"+split[0]), content.WithDescriptor(ocispec.Descriptor{Size: size}))
if err != nil {
return nil, err
}
defer cw.Close()
var buf bytes.Buffer
tr := io.TeeReader(r, &buf)
if err := content.Copy(ctx, cw, tr, size, ""); err != nil {
return nil, err
}
config.desc.Digest = cw.Digest()
if err := json.Unmarshal(buf.Bytes(), &config.img); err != nil {
return nil, err
}
return &config, nil
}

View File

@@ -38,7 +38,7 @@ import (
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
)
const (
@@ -83,9 +83,9 @@ func mergeGids(gids1, gids2 []uint32) []uint32 {
func WithoutRunMount(_ context.Context, _ oci.Client, c *containers.Container, s *runtimespec.Spec) error {
var (
mounts []runtimespec.Mount
currnet = s.Mounts
current = s.Mounts
)
for _, m := range currnet {
for _, m := range current {
if filepath.Clean(m.Destination) == "/run" {
continue
}

View File

@@ -24,7 +24,7 @@ import (
"github.com/sirupsen/logrus"
"golang.org/x/net/context"
"k8s.io/client-go/tools/remotecommand"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
cio "github.com/containerd/cri/pkg/server/io"
)

View File

@@ -34,7 +34,7 @@ import (
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/net/context"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
"github.com/containerd/cri/pkg/annotations"
customopts "github.com/containerd/cri/pkg/containerd/opts"
@@ -114,6 +114,10 @@ func (c *criService) CreateContainer(ctx context.Context, r *runtime.CreateConta
if err != nil {
return nil, errors.Wrapf(err, "failed to resolve image %q", config.GetImage().GetImage())
}
containerdImage, err := c.toContainerdImage(ctx, image)
if err != nil {
return nil, errors.Wrapf(err, "failed to get image from containerd %q", image.ID)
}
// Run container using the same runtime with sandbox.
sandboxInfo, err := sandbox.Container.Info(ctx)
@@ -179,7 +183,7 @@ func (c *criService) CreateContainer(ctx context.Context, r *runtime.CreateConta
// the runtime (runc) a chance to modify (e.g. to create mount
// points corresponding to spec.Mounts) before making the
// rootfs readonly (requested by spec.Root.Readonly).
customopts.WithNewSnapshot(id, image.Image),
customopts.WithNewSnapshot(id, containerdImage),
}
if len(volumeMounts) > 0 {
@@ -192,9 +196,14 @@ func (c *criService) CreateContainer(ctx context.Context, r *runtime.CreateConta
meta.ImageRef = image.ID
meta.StopSignal = image.ImageSpec.Config.StopSignal
// Get container log path.
if config.GetLogPath() != "" {
// Validate log paths and compose full container log path.
if sandboxConfig.GetLogDirectory() != "" && config.GetLogPath() != "" {
meta.LogPath = filepath.Join(sandboxConfig.GetLogDirectory(), config.GetLogPath())
logrus.Debugf("Composed container full log path %q using sandbox log dir %q and container log path %q",
meta.LogPath, sandboxConfig.GetLogDirectory(), config.GetLogPath())
} else {
logrus.Infof("Logging will be disabled due to empty log paths for sandbox (%q) or container (%q)",
sandboxConfig.GetLogDirectory(), config.GetLogPath())
}
containerIO, err := cio.NewContainerIO(id,
@@ -357,20 +366,14 @@ func (c *criService) generateContainerSpec(id string, sandboxID string, sandboxP
}
specOpts = append(specOpts, customopts.WithMounts(c.os, config, extraMounts, mountLabel))
// Apply masked paths if specified.
// When `MaskedPaths` is not specified, keep runtime default for backward compatibility;
// When `MaskedPaths` is specified, but length is zero, clear masked path list.
// Note: If the container is privileged, then we clear any masked paths later on in the call to setOCIPrivileged()
if maskedPaths := securityContext.GetMaskedPaths(); maskedPaths != nil {
specOpts = append(specOpts, oci.WithMaskedPaths(maskedPaths))
}
if !c.config.DisableProcMount {
// Apply masked paths if specified.
// Note: If the container is privileged, then we clear any masked paths later on in the call to setOCIPrivileged()
specOpts = append(specOpts, oci.WithMaskedPaths(securityContext.GetMaskedPaths()))
// Apply readonly paths if specified.
// Note: If the container is privileged, then we clear any readonly paths later on in the call to setOCIPrivileged()
// Apply readonly paths if specified.
if roPaths := securityContext.GetReadonlyPaths(); roPaths != nil {
specOpts = append(specOpts, oci.WithReadonlyPaths(roPaths))
// Apply readonly paths if specified.
// Note: If the container is privileged, then we clear any readonly paths later on in the call to setOCIPrivileged()
specOpts = append(specOpts, oci.WithReadonlyPaths(securityContext.GetReadonlyPaths()))
}
if securityContext.GetPrivileged() {

View File

@@ -19,7 +19,7 @@ package server
import (
"github.com/pkg/errors"
"golang.org/x/net/context"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
)
// Exec prepares a streaming endpoint to execute a command in the container, and returns the address.

View File

@@ -19,6 +19,7 @@ package server
import (
"bytes"
"io"
"syscall"
"time"
"github.com/containerd/containerd"
@@ -28,9 +29,8 @@ import (
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/net/context"
"golang.org/x/sys/unix"
"k8s.io/client-go/tools/remotecommand"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
ctrdutil "github.com/containerd/cri/pkg/containerd/util"
cioutil "github.com/containerd/cri/pkg/ioutil"
@@ -134,7 +134,7 @@ func (c *criService) execInContainer(ctx context.Context, id string, opts execOp
defer func() {
deferCtx, deferCancel := ctrdutil.DeferContext()
defer deferCancel()
if _, err := process.Delete(deferCtx); err != nil {
if _, err := process.Delete(deferCtx, containerd.WithProcessKill); err != nil {
logrus.WithError(err).Errorf("Failed to delete exec process %q for container %q", execID, id)
}
}()
@@ -164,18 +164,17 @@ func (c *criService) execInContainer(ctx context.Context, id string, opts execOp
},
})
var timeoutCh <-chan time.Time
if opts.timeout == 0 {
// Do not set timeout if it's 0.
timeoutCh = make(chan time.Time)
} else {
timeoutCh = time.After(opts.timeout)
execCtx := ctx
if opts.timeout > 0 {
var execCtxCancel context.CancelFunc
execCtx, execCtxCancel = context.WithTimeout(ctx, opts.timeout)
defer execCtxCancel()
}
select {
case <-timeoutCh:
//TODO(Abhi) Use context.WithDeadline instead of timeout.
case <-execCtx.Done():
// Ignore the not found error because the process may exit itself before killing.
if err := process.Kill(ctx, unix.SIGKILL); err != nil && !errdefs.IsNotFound(err) {
if err := process.Kill(ctx, syscall.SIGKILL); err != nil && !errdefs.IsNotFound(err) {
return nil, errors.Wrapf(err, "failed to kill exec %q", execID)
}
// Wait for the process to be killed.
@@ -184,7 +183,7 @@ func (c *criService) execInContainer(ctx context.Context, id string, opts execOp
execID, exitRes.ExitCode(), exitRes.Error())
<-attachDone
logrus.Debugf("Stream pipe for exec process %q done", execID)
return nil, errors.Errorf("timeout %v exceeded", opts.timeout)
return nil, errors.Wrapf(execCtx.Err(), "timeout %v exceeded", opts.timeout)
case exitRes := <-exitCh:
code, _, err := exitRes.Result()
logrus.Infof("Exec process %q exits with exit code %d and error %v", execID, code, err)

View File

@@ -19,7 +19,7 @@ package server
import (
"golang.org/x/net/context"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
containerstore "github.com/containerd/cri/pkg/store/container"
)

View File

@@ -20,7 +20,7 @@ import (
"github.com/pkg/errors"
"golang.org/x/net/context"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
)
// ReopenContainerLog asks the cri plugin to reopen the stdout/stderr log file for the container.

View File

@@ -23,7 +23,7 @@ import (
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/net/context"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
"github.com/containerd/cri/pkg/log"
"github.com/containerd/cri/pkg/store"

View File

@@ -24,10 +24,11 @@ import (
"github.com/containerd/containerd"
containerdio "github.com/containerd/containerd/cio"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/plugin"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/net/context"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
ctrdutil "github.com/containerd/cri/pkg/containerd/util"
cioutil "github.com/containerd/cri/pkg/ioutil"
@@ -99,7 +100,7 @@ func (c *criService) StartContainer(ctx context.Context, r *runtime.StartContain
var taskOpts []containerd.NewTaskOpts
// TODO(random-liu): Remove this after shim v1 is deprecated.
if c.config.NoPivot && ctrInfo.Runtime.Name == linuxRuntime {
if c.config.NoPivot && ctrInfo.Runtime.Name == plugin.RuntimeLinuxV1 {
taskOpts = append(taskOpts, containerd.WithNoPivotRoot)
}
task, err := container.NewTask(ctx, ioCreation, taskOpts...)

View File

@@ -20,7 +20,7 @@ import (
tasks "github.com/containerd/containerd/api/services/tasks/v1"
"github.com/pkg/errors"
"golang.org/x/net/context"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
)
// ContainerStats returns stats of the container. If the container does not

View File

@@ -23,7 +23,7 @@ import (
"github.com/containerd/typeurl"
"github.com/pkg/errors"
"golang.org/x/net/context"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
containerstore "github.com/containerd/cri/pkg/store/container"
)

View File

@@ -22,7 +22,7 @@ import (
runtimespec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
"golang.org/x/net/context"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
"github.com/containerd/cri/pkg/store"
containerstore "github.com/containerd/cri/pkg/store/container"

View File

@@ -17,6 +17,7 @@ limitations under the License.
package server
import (
"syscall"
"time"
"github.com/containerd/containerd"
@@ -25,21 +26,13 @@ import (
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/net/context"
"golang.org/x/sys/unix"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
ctrdutil "github.com/containerd/cri/pkg/containerd/util"
"github.com/containerd/cri/pkg/store"
containerstore "github.com/containerd/cri/pkg/store/container"
)
// killContainerTimeout is the timeout that we wait for the container to
// be SIGKILLed.
// The timeout is set to 1 min, because the default CRI operation timeout
// for StopContainer is (2 min + stop timeout). Set to 1 min, so that we
// have enough time for kill(all=true) and kill(all=false).
const killContainerTimeout = 1 * time.Minute
// StopContainer stops a running container with a grace period (i.e., timeout).
func (c *criService) StopContainer(ctx context.Context, r *runtime.StopContainerRequest) (*runtime.StopContainerResponse, error) {
// Get container config from container store.
@@ -141,34 +134,40 @@ func (c *criService) stopContainer(ctx context.Context, container containerstore
return errors.Wrapf(err, "failed to stop container %q", id)
}
if err = c.waitContainerStop(ctx, container, timeout); err == nil || errors.Cause(err) == ctx.Err() {
// Do not SIGKILL container if the context is cancelled.
return err
sigTermCtx, sigTermCtxCancel := context.WithTimeout(ctx, timeout)
defer sigTermCtxCancel()
err = c.waitContainerStop(sigTermCtx, container)
if err == nil {
// Container stopped on first signal no need for SIGKILL
return nil
}
logrus.WithError(err).Errorf("An error occurs during waiting for container %q to be stopped", id)
// If the parent context was cancelled or exceeded return immediately
if ctx.Err() != nil {
return ctx.Err()
}
// sigTermCtx was exceeded. Send SIGKILL
logrus.Debugf("Stop container %q with signal %v timed out", id, sig)
}
logrus.Infof("Kill container %q", id)
if err = task.Kill(ctx, unix.SIGKILL); err != nil && !errdefs.IsNotFound(err) {
if err = task.Kill(ctx, syscall.SIGKILL); err != nil && !errdefs.IsNotFound(err) {
return errors.Wrapf(err, "failed to kill container %q", id)
}
// Wait for a fixed timeout until container stop is observed by event monitor.
if err = c.waitContainerStop(ctx, container, killContainerTimeout); err == nil {
return nil
err = c.waitContainerStop(ctx, container)
if err != nil {
return errors.Wrapf(err, "an error occurs during waiting for container %q to be killed", id)
}
return errors.Wrapf(err, "an error occurs during waiting for container %q to be killed", id)
return nil
}
// waitContainerStop waits for container to be stopped until timeout exceeds or context is cancelled.
func (c *criService) waitContainerStop(ctx context.Context, container containerstore.Container, timeout time.Duration) error {
timeoutTimer := time.NewTimer(timeout)
defer timeoutTimer.Stop()
// waitContainerStop waits for container to be stopped until context is
// cancelled or the context deadline is exceeded.
func (c *criService) waitContainerStop(ctx context.Context, container containerstore.Container) error {
select {
case <-ctx.Done():
return errors.Wrapf(ctx.Err(), "wait container %q is cancelled", container.ID)
case <-timeoutTimer.C:
return errors.Errorf("wait container %q stop timeout", container.ID)
return errors.Wrapf(ctx.Err(), "wait container %q", container.ID)
case <-container.Stopped():
return nil
}

View File

@@ -27,7 +27,7 @@ import (
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/net/context"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
"github.com/containerd/cri/pkg/containerd/opts"
ctrdutil "github.com/containerd/cri/pkg/containerd/util"

View File

@@ -25,7 +25,9 @@ import (
"strings"
"github.com/BurntSushi/toml"
"github.com/containerd/containerd"
"github.com/containerd/containerd/containers"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/runtime/linux/runctypes"
runcoptions "github.com/containerd/containerd/runtime/v2/runc/options"
"github.com/containerd/typeurl"
@@ -34,7 +36,7 @@ import (
"github.com/opencontainers/selinux/go-selinux/label"
"github.com/pkg/errors"
"golang.org/x/net/context"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
runtimeoptions "github.com/containerd/cri/pkg/api/runtimeoptions/v1"
criconfig "github.com/containerd/cri/pkg/config"
@@ -115,16 +117,6 @@ const (
networkAttachCount = 2
)
// Runtime type strings for various runtimes.
const (
// linuxRuntime is the legacy linux runtime for shim v1.
linuxRuntime = "io.containerd.runtime.v1.linux"
// runcRuntimeV1 is the runc v1 runtime for shim v2.
runcRuntimeV1 = "io.containerd.runc.v1"
// runcRuntimeV2 is the runc v2 runtime for shim v2.
runcRuntimeV2 = "io.containerd.runc.v2"
)
// makeSandboxName generates sandbox name from sandbox metadata. The name
// generated is unique as long as sandbox metadata is unique.
func makeSandboxName(s *runtime.PodSandboxMetadata) string {
@@ -254,6 +246,15 @@ func (c *criService) localResolve(refOrID string) (imagestore.Image, error) {
return c.imageStore.Get(imageID)
}
// toContainerdImage converts an image object in image store to containerd image handler.
func (c *criService) toContainerdImage(ctx context.Context, image imagestore.Image) (containerd.Image, error) {
// image should always have at least one reference.
if len(image.References) == 0 {
return nil, errors.Errorf("invalid image with no reference %q", image.ID)
}
return c.client.GetImage(ctx, image.References[0])
}
// getUserFromImage gets uid or user name of the image user.
// If user is numeric, it will be treated as uid; or else, it is treated as user name.
func getUserFromImage(user string) (*int64, string) {
@@ -275,7 +276,7 @@ func getUserFromImage(user string) (*int64, string) {
// ensureImageExists returns corresponding metadata of the image reference, if image is not
// pulled yet, the function will pull the image.
func (c *criService) ensureImageExists(ctx context.Context, ref string) (*imagestore.Image, error) {
func (c *criService) ensureImageExists(ctx context.Context, ref string, config *runtime.PodSandboxConfig) (*imagestore.Image, error) {
image, err := c.localResolve(ref)
if err != nil && err != store.ErrNotExist {
return nil, errors.Wrapf(err, "failed to get image %q", ref)
@@ -284,7 +285,7 @@ func (c *criService) ensureImageExists(ctx context.Context, ref string) (*images
return &image, nil
}
// Pull image to ensure the image exists
resp, err := c.PullImage(ctx, &runtime.PullImageRequest{Image: &runtime.ImageSpec{Image: ref}})
resp, err := c.PullImage(ctx, &runtime.PullImageRequest{Image: &runtime.ImageSpec{Image: ref}, SandboxConfig: config})
if err != nil {
return nil, errors.Wrapf(err, "failed to pull image %q", ref)
}
@@ -406,7 +407,7 @@ func parseImageReferences(refs []string) ([]string, []string) {
// generateRuntimeOptions generates runtime options from cri plugin config.
func generateRuntimeOptions(r criconfig.Runtime, c criconfig.Config) (interface{}, error) {
if r.Options == nil {
if r.Type != linuxRuntime {
if r.Type != plugin.RuntimeLinuxV1 {
return nil, nil
}
// This is a legacy config, generate runctypes.RuncOptions.
@@ -426,11 +427,11 @@ func generateRuntimeOptions(r criconfig.Runtime, c criconfig.Config) (interface{
// getRuntimeOptionsType gets empty runtime options by the runtime type name.
func getRuntimeOptionsType(t string) interface{} {
switch t {
case runcRuntimeV1:
case plugin.RuntimeRuncV1:
fallthrough
case runcRuntimeV2:
case plugin.RuntimeRuncV2:
return &runcoptions.Options{}
case linuxRuntime:
case plugin.RuntimeLinuxV1:
return &runctypes.RuncOptions{}
default:
return &runtimeoptions.Options{}

View File

@@ -18,7 +18,7 @@ package server
import (
"golang.org/x/net/context"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
)
// ListImages lists existing images.

View File

@@ -1,56 +0,0 @@
/*
Copyright 2017 The Kubernetes 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 server
import (
"os"
"path/filepath"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/net/context"
api "github.com/containerd/cri/pkg/api/v1"
"github.com/containerd/cri/pkg/containerd/importer"
)
// LoadImage loads a image into containerd.
func (c *criService) LoadImage(ctx context.Context, r *api.LoadImageRequest) (*api.LoadImageResponse, error) {
path := r.GetFilePath()
if !filepath.IsAbs(path) {
return nil, errors.Errorf("path %q is not an absolute path", path)
}
f, err := os.Open(path)
if err != nil {
return nil, errors.Wrap(err, "failed to open file")
}
repoTags, err := importer.Import(ctx, c.client, f, importer.WithUnpack(c.config.ContainerdConfig.Snapshotter))
if err != nil {
return nil, errors.Wrap(err, "failed to import image")
}
for _, repoTag := range repoTags {
// Update image store to reflect the newest state in containerd.
// Image imported by importer.Import is not treated as managed
// by the cri plugin, call `updateImage` to make it managed.
// TODO(random-liu): Replace this with the containerd library (issue #909).
if err := c.updateImage(ctx, repoTag); err != nil {
return nil, errors.Wrapf(err, "update image store %q", repoTag)
}
logrus.Debugf("Imported image %q", repoTag)
}
return &api.LoadImageResponse{Images: repoTags}, nil
}

View File

@@ -17,10 +17,15 @@ limitations under the License.
package server
import (
"crypto/tls"
"crypto/x509"
"encoding/base64"
"io/ioutil"
"net"
"net/http"
"net/url"
"strings"
"time"
"github.com/containerd/containerd"
"github.com/containerd/containerd/errdefs"
@@ -28,12 +33,13 @@ import (
"github.com/containerd/containerd/reference"
"github.com/containerd/containerd/remotes"
"github.com/containerd/containerd/remotes/docker"
"github.com/containerd/cri/pkg/config"
distribution "github.com/docker/distribution/reference"
imagespec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/net/context"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
)
// For image management:
@@ -101,6 +107,8 @@ func (c *criService) PullImage(ctx context.Context, r *runtime.PullImageRequest)
containerd.WithResolver(resolver),
containerd.WithPullSnapshotter(c.config.ContainerdConfig.Snapshotter),
containerd.WithPullUnpack,
containerd.WithPullLabel(imageLabelKey, imageLabelValue),
containerd.WithMaxConcurrentDownloads(c.config.MaxConcurrentDownloads),
)
if err != nil {
return nil, errors.Wrapf(err, "failed to pull and unpack image %q", ref)
@@ -246,6 +254,31 @@ func (c *criService) credentials(auth *runtime.AuthConfig) func(string) (string,
}
}
// getTLSConfig returns a TLSConfig configured with a CA/Cert/Key specified by registryTLSConfig
func (c *criService) getTLSConfig(registryTLSConfig config.TLSConfig) (*tls.Config, error) {
cert, err := tls.LoadX509KeyPair(registryTLSConfig.CertFile, registryTLSConfig.KeyFile)
if err != nil {
return nil, errors.Wrap(err, "failed to load cert file")
}
caCertPool, err := x509.SystemCertPool()
if err != nil {
return nil, errors.Wrap(err, "failed to get system cert pool")
}
caCert, err := ioutil.ReadFile(registryTLSConfig.CAFile)
if err != nil {
return nil, errors.Wrap(err, "failed to load CA file")
}
caCertPool.AppendCertsFromPEM(caCert)
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{cert},
RootCAs: caCertPool,
}
tlsConfig.BuildNameToCertificate()
return tlsConfig, nil
}
// getResolver tries registry mirrors and the default registry, and returns the resolver and descriptor
// from the first working registry.
func (c *criService) getResolver(ctx context.Context, ref string, cred func(string) (string, string, error)) (remotes.Resolver, imagespec.Descriptor, error) {
@@ -253,15 +286,29 @@ func (c *criService) getResolver(ctx context.Context, ref string, cred func(stri
if err != nil {
return nil, imagespec.Descriptor{}, errors.Wrap(err, "parse image reference")
}
var (
transport = newTransport()
httpClient = &http.Client{Transport: transport}
)
// Try mirrors in order first, and then try default host name.
for _, e := range c.config.Registry.Mirrors[refspec.Hostname()].Endpoints {
u, err := url.Parse(e)
if err != nil {
return nil, imagespec.Descriptor{}, errors.Wrapf(err, "parse registry endpoint %q", e)
}
if registryTLSConfig, ok := c.config.Registry.TLSConfigs[u.Host]; ok {
transport.TLSClientConfig, err = c.getTLSConfig(registryTLSConfig)
if err != nil {
return nil, imagespec.Descriptor{}, errors.Wrapf(err, "get TLSConfig for registry %q", refspec.Hostname())
}
}
resolver := docker.NewResolver(docker.ResolverOptions{
Authorizer: docker.NewAuthorizer(http.DefaultClient, cred),
Client: http.DefaultClient,
Authorizer: docker.NewAuthorizer(httpClient, cred),
Client: httpClient,
Host: func(string) (string, error) { return u.Host, nil },
// By default use "https".
PlainHTTP: u.Scheme == "http",
@@ -270,11 +317,24 @@ func (c *criService) getResolver(ctx context.Context, ref string, cred func(stri
if err == nil {
return resolver, desc, nil
}
logrus.WithError(err).Debugf("Tried registry mirror %q but failed", e)
// Continue to try next endpoint
}
hostname, err := docker.DefaultHost(refspec.Hostname())
if err != nil {
return nil, imagespec.Descriptor{}, errors.Wrapf(err, "get host for refspec %q", refspec.Hostname())
}
if registryTLSConfig, ok := c.config.Registry.TLSConfigs[hostname]; ok {
transport.TLSClientConfig, err = c.getTLSConfig(registryTLSConfig)
if err != nil {
return nil, imagespec.Descriptor{}, errors.Wrapf(err, "get TLSConfig for registry %q", refspec.Hostname())
}
}
resolver := docker.NewResolver(docker.ResolverOptions{
Credentials: cred,
Client: http.DefaultClient,
Client: httpClient,
})
_, desc, err := resolver.Resolve(ctx, ref)
if err != nil {
@@ -282,3 +342,20 @@ func (c *criService) getResolver(ctx context.Context, ref string, cred func(stri
}
return resolver, desc, nil
}
// newTransport returns a new HTTP transport used to pull image.
// TODO(random-liu): Create a library and share this code with `ctr`.
func newTransport() *http.Transport {
return &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
DualStack: true,
}).DialContext,
MaxIdleConns: 10,
IdleConnTimeout: 30 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 5 * time.Second,
}
}

View File

@@ -21,7 +21,7 @@ import (
"github.com/containerd/containerd/images"
"github.com/pkg/errors"
"golang.org/x/net/context"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
"github.com/containerd/cri/pkg/store"
)

View File

@@ -22,7 +22,7 @@ import (
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/net/context"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
"github.com/containerd/cri/pkg/store"
imagestore "github.com/containerd/cri/pkg/store/image"

View File

@@ -21,7 +21,7 @@ import (
"golang.org/x/net/context"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
)
// ImageFsInfo returns information of the filesystem that is used to store images.

View File

@@ -21,9 +21,9 @@ import (
"github.com/sirupsen/logrus"
"golang.org/x/net/context"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
api "github.com/containerd/cri/pkg/api/v1"
"github.com/containerd/containerd/errdefs"
ctrdutil "github.com/containerd/cri/pkg/containerd/util"
"github.com/containerd/cri/pkg/log"
)
@@ -60,7 +60,8 @@ func (in *instrumentedService) RunPodSandbox(ctx context.Context, r *runtime.Run
logrus.Infof("RunPodSandbox for %+v returns sandbox id %q", r.GetConfig().GetMetadata(), res.GetPodSandboxId())
}
}()
return in.c.RunPodSandbox(ctrdutil.WithNamespace(ctx), r)
res, err = in.c.RunPodSandbox(ctrdutil.WithNamespace(ctx), r)
return res, errdefs.ToGRPC(err)
}
func (in *instrumentedService) ListPodSandbox(ctx context.Context, r *runtime.ListPodSandboxRequest) (res *runtime.ListPodSandboxResponse, err error) {
@@ -75,7 +76,8 @@ func (in *instrumentedService) ListPodSandbox(ctx context.Context, r *runtime.Li
log.Tracef("ListPodSandbox returns pod sandboxes %+v", res.GetItems())
}
}()
return in.c.ListPodSandbox(ctrdutil.WithNamespace(ctx), r)
res, err = in.c.ListPodSandbox(ctrdutil.WithNamespace(ctx), r)
return res, errdefs.ToGRPC(err)
}
func (in *instrumentedService) PodSandboxStatus(ctx context.Context, r *runtime.PodSandboxStatusRequest) (res *runtime.PodSandboxStatusResponse, err error) {
@@ -90,7 +92,8 @@ func (in *instrumentedService) PodSandboxStatus(ctx context.Context, r *runtime.
log.Tracef("PodSandboxStatus for %q returns status %+v", r.GetPodSandboxId(), res.GetStatus())
}
}()
return in.c.PodSandboxStatus(ctrdutil.WithNamespace(ctx), r)
res, err = in.c.PodSandboxStatus(ctrdutil.WithNamespace(ctx), r)
return res, errdefs.ToGRPC(err)
}
func (in *instrumentedService) StopPodSandbox(ctx context.Context, r *runtime.StopPodSandboxRequest) (_ *runtime.StopPodSandboxResponse, err error) {
@@ -105,7 +108,8 @@ func (in *instrumentedService) StopPodSandbox(ctx context.Context, r *runtime.St
logrus.Infof("StopPodSandbox for %q returns successfully", r.GetPodSandboxId())
}
}()
return in.c.StopPodSandbox(ctrdutil.WithNamespace(ctx), r)
res, err := in.c.StopPodSandbox(ctrdutil.WithNamespace(ctx), r)
return res, errdefs.ToGRPC(err)
}
func (in *instrumentedService) RemovePodSandbox(ctx context.Context, r *runtime.RemovePodSandboxRequest) (_ *runtime.RemovePodSandboxResponse, err error) {
@@ -120,7 +124,8 @@ func (in *instrumentedService) RemovePodSandbox(ctx context.Context, r *runtime.
logrus.Infof("RemovePodSandbox %q returns successfully", r.GetPodSandboxId())
}
}()
return in.c.RemovePodSandbox(ctrdutil.WithNamespace(ctx), r)
res, err := in.c.RemovePodSandbox(ctrdutil.WithNamespace(ctx), r)
return res, errdefs.ToGRPC(err)
}
func (in *instrumentedService) PortForward(ctx context.Context, r *runtime.PortForwardRequest) (res *runtime.PortForwardResponse, err error) {
@@ -135,7 +140,8 @@ func (in *instrumentedService) PortForward(ctx context.Context, r *runtime.PortF
logrus.Infof("Portforward for %q returns URL %q", r.GetPodSandboxId(), res.GetUrl())
}
}()
return in.c.PortForward(ctrdutil.WithNamespace(ctx), r)
res, err = in.c.PortForward(ctrdutil.WithNamespace(ctx), r)
return res, errdefs.ToGRPC(err)
}
func (in *instrumentedService) CreateContainer(ctx context.Context, r *runtime.CreateContainerRequest) (res *runtime.CreateContainerResponse, err error) {
@@ -153,7 +159,8 @@ func (in *instrumentedService) CreateContainer(ctx context.Context, r *runtime.C
r.GetPodSandboxId(), r.GetConfig().GetMetadata(), res.GetContainerId())
}
}()
return in.c.CreateContainer(ctrdutil.WithNamespace(ctx), r)
res, err = in.c.CreateContainer(ctrdutil.WithNamespace(ctx), r)
return res, errdefs.ToGRPC(err)
}
func (in *instrumentedService) StartContainer(ctx context.Context, r *runtime.StartContainerRequest) (_ *runtime.StartContainerResponse, err error) {
@@ -168,7 +175,8 @@ func (in *instrumentedService) StartContainer(ctx context.Context, r *runtime.St
logrus.Infof("StartContainer for %q returns successfully", r.GetContainerId())
}
}()
return in.c.StartContainer(ctrdutil.WithNamespace(ctx), r)
res, err := in.c.StartContainer(ctrdutil.WithNamespace(ctx), r)
return res, errdefs.ToGRPC(err)
}
func (in *instrumentedService) ListContainers(ctx context.Context, r *runtime.ListContainersRequest) (res *runtime.ListContainersResponse, err error) {
@@ -184,7 +192,8 @@ func (in *instrumentedService) ListContainers(ctx context.Context, r *runtime.Li
r.GetFilter(), res.GetContainers())
}
}()
return in.c.ListContainers(ctrdutil.WithNamespace(ctx), r)
res, err = in.c.ListContainers(ctrdutil.WithNamespace(ctx), r)
return res, errdefs.ToGRPC(err)
}
func (in *instrumentedService) ContainerStatus(ctx context.Context, r *runtime.ContainerStatusRequest) (res *runtime.ContainerStatusResponse, err error) {
@@ -199,7 +208,8 @@ func (in *instrumentedService) ContainerStatus(ctx context.Context, r *runtime.C
log.Tracef("ContainerStatus for %q returns status %+v", r.GetContainerId(), res.GetStatus())
}
}()
return in.c.ContainerStatus(ctrdutil.WithNamespace(ctx), r)
res, err = in.c.ContainerStatus(ctrdutil.WithNamespace(ctx), r)
return res, errdefs.ToGRPC(err)
}
func (in *instrumentedService) StopContainer(ctx context.Context, r *runtime.StopContainerRequest) (res *runtime.StopContainerResponse, err error) {
@@ -214,7 +224,8 @@ func (in *instrumentedService) StopContainer(ctx context.Context, r *runtime.Sto
logrus.Infof("StopContainer for %q returns successfully", r.GetContainerId())
}
}()
return in.c.StopContainer(ctrdutil.WithNamespace(ctx), r)
res, err = in.c.StopContainer(ctrdutil.WithNamespace(ctx), r)
return res, errdefs.ToGRPC(err)
}
func (in *instrumentedService) RemoveContainer(ctx context.Context, r *runtime.RemoveContainerRequest) (res *runtime.RemoveContainerResponse, err error) {
@@ -229,7 +240,8 @@ func (in *instrumentedService) RemoveContainer(ctx context.Context, r *runtime.R
logrus.Infof("RemoveContainer for %q returns successfully", r.GetContainerId())
}
}()
return in.c.RemoveContainer(ctrdutil.WithNamespace(ctx), r)
res, err = in.c.RemoveContainer(ctrdutil.WithNamespace(ctx), r)
return res, errdefs.ToGRPC(err)
}
func (in *instrumentedService) ExecSync(ctx context.Context, r *runtime.ExecSyncRequest) (res *runtime.ExecSyncResponse, err error) {
@@ -246,7 +258,8 @@ func (in *instrumentedService) ExecSync(ctx context.Context, r *runtime.ExecSync
res.GetStdout(), res.GetStderr())
}
}()
return in.c.ExecSync(ctrdutil.WithNamespace(ctx), r)
res, err = in.c.ExecSync(ctrdutil.WithNamespace(ctx), r)
return res, errdefs.ToGRPC(err)
}
func (in *instrumentedService) Exec(ctx context.Context, r *runtime.ExecRequest) (res *runtime.ExecResponse, err error) {
@@ -262,7 +275,8 @@ func (in *instrumentedService) Exec(ctx context.Context, r *runtime.ExecRequest)
logrus.Infof("Exec for %q returns URL %q", r.GetContainerId(), res.GetUrl())
}
}()
return in.c.Exec(ctrdutil.WithNamespace(ctx), r)
res, err = in.c.Exec(ctrdutil.WithNamespace(ctx), r)
return res, errdefs.ToGRPC(err)
}
func (in *instrumentedService) Attach(ctx context.Context, r *runtime.AttachRequest) (res *runtime.AttachResponse, err error) {
@@ -277,7 +291,8 @@ func (in *instrumentedService) Attach(ctx context.Context, r *runtime.AttachRequ
logrus.Infof("Attach for %q returns URL %q", r.GetContainerId(), res.Url)
}
}()
return in.c.Attach(ctrdutil.WithNamespace(ctx), r)
res, err = in.c.Attach(ctrdutil.WithNamespace(ctx), r)
return res, errdefs.ToGRPC(err)
}
func (in *instrumentedService) UpdateContainerResources(ctx context.Context, r *runtime.UpdateContainerResourcesRequest) (res *runtime.UpdateContainerResourcesResponse, err error) {
@@ -292,7 +307,8 @@ func (in *instrumentedService) UpdateContainerResources(ctx context.Context, r *
logrus.Infof("UpdateContainerResources for %q returns successfully", r.GetContainerId())
}
}()
return in.c.UpdateContainerResources(ctrdutil.WithNamespace(ctx), r)
res, err = in.c.UpdateContainerResources(ctrdutil.WithNamespace(ctx), r)
return res, errdefs.ToGRPC(err)
}
func (in *instrumentedService) PullImage(ctx context.Context, r *runtime.PullImageRequest) (res *runtime.PullImageResponse, err error) {
@@ -308,7 +324,8 @@ func (in *instrumentedService) PullImage(ctx context.Context, r *runtime.PullIma
r.GetImage().GetImage(), res.GetImageRef())
}
}()
return in.c.PullImage(ctrdutil.WithNamespace(ctx), r)
res, err = in.c.PullImage(ctrdutil.WithNamespace(ctx), r)
return res, errdefs.ToGRPC(err)
}
func (in *instrumentedService) ListImages(ctx context.Context, r *runtime.ListImagesRequest) (res *runtime.ListImagesResponse, err error) {
@@ -324,7 +341,8 @@ func (in *instrumentedService) ListImages(ctx context.Context, r *runtime.ListIm
r.GetFilter(), res.GetImages())
}
}()
return in.c.ListImages(ctrdutil.WithNamespace(ctx), r)
res, err = in.c.ListImages(ctrdutil.WithNamespace(ctx), r)
return res, errdefs.ToGRPC(err)
}
func (in *instrumentedService) ImageStatus(ctx context.Context, r *runtime.ImageStatusRequest) (res *runtime.ImageStatusResponse, err error) {
@@ -340,7 +358,8 @@ func (in *instrumentedService) ImageStatus(ctx context.Context, r *runtime.Image
r.GetImage().GetImage(), res.GetImage())
}
}()
return in.c.ImageStatus(ctrdutil.WithNamespace(ctx), r)
res, err = in.c.ImageStatus(ctrdutil.WithNamespace(ctx), r)
return res, errdefs.ToGRPC(err)
}
func (in *instrumentedService) RemoveImage(ctx context.Context, r *runtime.RemoveImageRequest) (_ *runtime.RemoveImageResponse, err error) {
@@ -355,7 +374,8 @@ func (in *instrumentedService) RemoveImage(ctx context.Context, r *runtime.Remov
logrus.Infof("RemoveImage %q returns successfully", r.GetImage().GetImage())
}
}()
return in.c.RemoveImage(ctrdutil.WithNamespace(ctx), r)
res, err := in.c.RemoveImage(ctrdutil.WithNamespace(ctx), r)
return res, errdefs.ToGRPC(err)
}
func (in *instrumentedService) ImageFsInfo(ctx context.Context, r *runtime.ImageFsInfoRequest) (res *runtime.ImageFsInfoResponse, err error) {
@@ -370,7 +390,8 @@ func (in *instrumentedService) ImageFsInfo(ctx context.Context, r *runtime.Image
logrus.Debugf("ImageFsInfo returns filesystem info %+v", res.ImageFilesystems)
}
}()
return in.c.ImageFsInfo(ctrdutil.WithNamespace(ctx), r)
res, err = in.c.ImageFsInfo(ctrdutil.WithNamespace(ctx), r)
return res, errdefs.ToGRPC(err)
}
func (in *instrumentedService) ContainerStats(ctx context.Context, r *runtime.ContainerStatsRequest) (res *runtime.ContainerStatsResponse, err error) {
@@ -385,7 +406,8 @@ func (in *instrumentedService) ContainerStats(ctx context.Context, r *runtime.Co
logrus.Debugf("ContainerStats for %q returns stats %+v", r.GetContainerId(), res.GetStats())
}
}()
return in.c.ContainerStats(ctrdutil.WithNamespace(ctx), r)
res, err = in.c.ContainerStats(ctrdutil.WithNamespace(ctx), r)
return res, errdefs.ToGRPC(err)
}
func (in *instrumentedService) ListContainerStats(ctx context.Context, r *runtime.ListContainerStatsRequest) (res *runtime.ListContainerStatsResponse, err error) {
@@ -400,7 +422,8 @@ func (in *instrumentedService) ListContainerStats(ctx context.Context, r *runtim
log.Tracef("ListContainerStats returns stats %+v", res.GetStats())
}
}()
return in.c.ListContainerStats(ctrdutil.WithNamespace(ctx), r)
res, err = in.c.ListContainerStats(ctrdutil.WithNamespace(ctx), r)
return res, errdefs.ToGRPC(err)
}
func (in *instrumentedService) Status(ctx context.Context, r *runtime.StatusRequest) (res *runtime.StatusResponse, err error) {
@@ -415,7 +438,8 @@ func (in *instrumentedService) Status(ctx context.Context, r *runtime.StatusRequ
log.Tracef("Status returns status %+v", res.GetStatus())
}
}()
return in.c.Status(ctrdutil.WithNamespace(ctx), r)
res, err = in.c.Status(ctrdutil.WithNamespace(ctx), r)
return res, errdefs.ToGRPC(err)
}
func (in *instrumentedService) Version(ctx context.Context, r *runtime.VersionRequest) (res *runtime.VersionResponse, err error) {
@@ -430,7 +454,8 @@ func (in *instrumentedService) Version(ctx context.Context, r *runtime.VersionRe
log.Tracef("Version returns %+v", res)
}
}()
return in.c.Version(ctrdutil.WithNamespace(ctx), r)
res, err = in.c.Version(ctrdutil.WithNamespace(ctx), r)
return res, errdefs.ToGRPC(err)
}
func (in *instrumentedService) UpdateRuntimeConfig(ctx context.Context, r *runtime.UpdateRuntimeConfigRequest) (res *runtime.UpdateRuntimeConfigResponse, err error) {
@@ -445,22 +470,8 @@ func (in *instrumentedService) UpdateRuntimeConfig(ctx context.Context, r *runti
logrus.Debug("UpdateRuntimeConfig returns returns successfully")
}
}()
return in.c.UpdateRuntimeConfig(ctrdutil.WithNamespace(ctx), r)
}
func (in *instrumentedService) LoadImage(ctx context.Context, r *api.LoadImageRequest) (res *api.LoadImageResponse, err error) {
if err := in.checkInitialized(); err != nil {
return nil, err
}
logrus.Debugf("LoadImage from file %q", r.GetFilePath())
defer func() {
if err != nil {
logrus.WithError(err).Error("LoadImage failed")
} else {
logrus.Debugf("LoadImage returns images %+v", res.GetImages())
}
}()
return in.c.LoadImage(ctrdutil.WithNamespace(ctx), r)
res, err = in.c.UpdateRuntimeConfig(ctrdutil.WithNamespace(ctx), r)
return res, errdefs.ToGRPC(err)
}
func (in *instrumentedService) ReopenContainerLog(ctx context.Context, r *runtime.ReopenContainerLogRequest) (res *runtime.ReopenContainerLogResponse, err error) {
@@ -475,5 +486,6 @@ func (in *instrumentedService) ReopenContainerLog(ctx context.Context, r *runtim
logrus.Debugf("ReopenContainerLog for %q returns successfully", r.GetContainerId())
}
}()
return in.c.ReopenContainerLog(ctrdutil.WithNamespace(ctx), r)
res, err = in.c.ReopenContainerLog(ctrdutil.WithNamespace(ctx), r)
return res, errdefs.ToGRPC(err)
}

View File

@@ -26,7 +26,7 @@ import (
"github.com/containerd/containerd/cio"
"github.com/containerd/fifo"
"golang.org/x/net/context"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
)
// AttachOptions specifies how to attach to a container.

View File

@@ -25,7 +25,7 @@ import (
"time"
"github.com/sirupsen/logrus"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
cioutil "github.com/containerd/cri/pkg/ioutil"
)

View File

@@ -32,7 +32,7 @@ import (
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/net/context"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
ctrdutil "github.com/containerd/cri/pkg/containerd/util"
"github.com/containerd/cri/pkg/netns"

View File

@@ -18,7 +18,7 @@ package server
import (
"golang.org/x/net/context"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
sandboxstore "github.com/containerd/cri/pkg/store/sandbox"
)

View File

@@ -27,7 +27,7 @@ import (
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/net/context"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
sandboxstore "github.com/containerd/cri/pkg/store/sandbox"
)

View File

@@ -22,7 +22,7 @@ import (
"github.com/docker/docker/pkg/system"
"github.com/pkg/errors"
"golang.org/x/net/context"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
"github.com/containerd/cri/pkg/log"
"github.com/containerd/cri/pkg/store"

View File

@@ -19,6 +19,7 @@ package server
import (
"encoding/json"
"fmt"
"math"
"os"
"strings"
@@ -26,6 +27,7 @@ import (
containerdio "github.com/containerd/containerd/cio"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/oci"
"github.com/containerd/containerd/plugin"
cni "github.com/containerd/go-cni"
"github.com/containerd/typeurl"
"github.com/davecgh/go-spew/spew"
@@ -35,7 +37,8 @@ import (
"github.com/sirupsen/logrus"
"golang.org/x/net/context"
"golang.org/x/sys/unix"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
"k8s.io/kubernetes/pkg/util/bandwidth"
"github.com/containerd/cri/pkg/annotations"
criconfig "github.com/containerd/cri/pkg/config"
@@ -92,10 +95,14 @@ func (c *criService) RunPodSandbox(ctx context.Context, r *runtime.RunPodSandbox
)
// Ensure sandbox container image snapshot.
image, err := c.ensureImageExists(ctx, c.config.SandboxImage)
image, err := c.ensureImageExists(ctx, c.config.SandboxImage, config)
if err != nil {
return nil, errors.Wrapf(err, "failed to get sandbox image %q", c.config.SandboxImage)
}
containerdImage, err := c.toContainerdImage(ctx, *image)
if err != nil {
return nil, errors.Wrapf(err, "failed to get image from containerd %q", image.ID)
}
ociRuntime, err := c.getSandboxRuntime(config, r.GetRuntimeHandler())
if err != nil {
@@ -185,7 +192,7 @@ func (c *criService) RunPodSandbox(ctx context.Context, r *runtime.RunPodSandbox
}
opts := []containerd.NewContainerOpts{
containerd.WithSnapshotter(c.config.ContainerdConfig.Snapshotter),
customopts.WithNewSnapshot(id, image.Image),
customopts.WithNewSnapshot(id, containerdImage),
containerd.WithSpec(spec, specOpts...),
containerd.WithContainerLabels(sandboxLabels),
containerd.WithContainerExtension(sandboxMetadataExtension, &sandbox.Metadata),
@@ -260,7 +267,7 @@ func (c *criService) RunPodSandbox(ctx context.Context, r *runtime.RunPodSandbox
var taskOpts []containerd.NewTaskOpts
// TODO(random-liu): Remove this after shim v1 is deprecated.
if c.config.NoPivot && ociRuntime.Type == linuxRuntime {
if c.config.NoPivot && ociRuntime.Type == plugin.RuntimeRuncV1 {
taskOpts = append(taskOpts, containerd.WithNoPivotRoot)
}
// We don't need stdio for sandbox container.
@@ -500,7 +507,7 @@ func parseDNSOptions(servers, searches, options []string) (string, error) {
resolvContent := ""
if len(searches) > maxDNSSearches {
return "", errors.New("DNSOption.Searches has more than 6 domains")
return "", errors.Errorf("DNSOption.Searches has more than %d domains", maxDNSSearches)
}
if len(searches) > 0 {
@@ -540,10 +547,21 @@ func (c *criService) setupPod(id string, path string, config *runtime.PodSandbox
}
labels := getPodCNILabels(id, config)
// Will return an error if the bandwidth limitation has the wrong unit
// or an unreasonable valure see validateBandwidthIsReasonable()
bandWidth, err := toCNIBandWidth(config.Annotations)
if err != nil {
return "", nil, errors.Wrap(err, "failed to get bandwidth info from annotations")
}
result, err := c.netPlugin.Setup(id,
path,
cni.WithLabels(labels),
cni.WithCapabilityPortMap(toCNIPortMappings(config.GetPortMappings())))
cni.WithCapabilityPortMap(toCNIPortMappings(config.GetPortMappings())),
cni.WithCapabilityBandWidth(*bandWidth),
)
if err != nil {
return "", nil, err
}
@@ -559,6 +577,28 @@ func (c *criService) setupPod(id string, path string, config *runtime.PodSandbox
return "", result, errors.Errorf("failed to find network info for sandbox %q", id)
}
// toCNIBandWidth converts CRI annotations to CNI bandwidth.
func toCNIBandWidth(annotations map[string]string) (*cni.BandWidth, error) {
ingress, egress, err := bandwidth.ExtractPodBandwidthResources(annotations)
if err != nil {
return nil, errors.Errorf("reading pod bandwidth annotations: %v", err)
}
bandWidth := &cni.BandWidth{}
if ingress != nil {
bandWidth.IngressRate = uint64(ingress.Value())
bandWidth.IngressBurst = math.MaxUint32
}
if egress != nil {
bandWidth.EgressRate = uint64(egress.Value())
bandWidth.EgressBurst = math.MaxUint32
}
return bandWidth, nil
}
// toCNIPortMappings converts CRI port mappings to CNI.
func toCNIPortMappings(criPortMappings []*runtime.PortMapping) []cni.PortMapping {
var portMappings []cni.PortMapping

View File

@@ -25,7 +25,7 @@ import (
runtimespec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
"golang.org/x/net/context"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
sandboxstore "github.com/containerd/cri/pkg/store/sandbox"
)

View File

@@ -17,6 +17,7 @@ limitations under the License.
package server
import (
"syscall"
"time"
eventtypes "github.com/containerd/containerd/api/events"
@@ -25,8 +26,7 @@ import (
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/net/context"
"golang.org/x/sys/unix"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
ctrdutil "github.com/containerd/cri/pkg/containerd/util"
sandboxstore "github.com/containerd/cri/pkg/store/sandbox"
@@ -138,22 +138,19 @@ func (c *criService) stopSandboxContainer(ctx context.Context, sandbox sandboxst
}
// Kill the sandbox container.
if err = task.Kill(ctx, unix.SIGKILL); err != nil && !errdefs.IsNotFound(err) {
if err = task.Kill(ctx, syscall.SIGKILL); err != nil && !errdefs.IsNotFound(err) {
return errors.Wrap(err, "failed to kill sandbox container")
}
return c.waitSandboxStop(ctx, sandbox, killContainerTimeout)
return c.waitSandboxStop(ctx, sandbox)
}
// waitSandboxStop waits for sandbox to be stopped until timeout exceeds or context is cancelled.
func (c *criService) waitSandboxStop(ctx context.Context, sandbox sandboxstore.Sandbox, timeout time.Duration) error {
timeoutTimer := time.NewTimer(timeout)
defer timeoutTimer.Stop()
// waitSandboxStop waits for sandbox to be stopped until context is cancelled or
// the context deadline is exceeded.
func (c *criService) waitSandboxStop(ctx context.Context, sandbox sandboxstore.Sandbox) error {
select {
case <-ctx.Done():
return errors.Wrapf(ctx.Err(), "wait sandbox container %q is cancelled", sandbox.ID)
case <-timeoutTimer.C:
return errors.Errorf("wait sandbox container %q stop timeout", sandbox.ID)
return errors.Wrapf(ctx.Err(), "wait sandbox container %q", sandbox.ID)
case <-sandbox.Stopped():
return nil
}

View File

@@ -33,10 +33,9 @@ import (
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"google.golang.org/grpc"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
"k8s.io/kubernetes/pkg/kubelet/server/streaming"
api "github.com/containerd/cri/pkg/api/v1"
"github.com/containerd/cri/pkg/atomic"
criconfig "github.com/containerd/cri/pkg/config"
ctrdutil "github.com/containerd/cri/pkg/containerd/util"
@@ -52,7 +51,6 @@ import (
type grpcServices interface {
runtime.RuntimeServiceServer
runtime.ImageServiceServer
api.CRIPluginServiceServer
}
// CRIService is the interface implement CRI remote service server.
@@ -148,6 +146,7 @@ func NewCRIService(config criconfig.Config, client *containerd.Client) (CRIServi
// of the default network interface as the pod IP.
c.netPlugin, err = cni.New(cni.WithMinNetworkCount(networkAttachCount),
cni.WithPluginConfDir(config.NetworkPluginConfDir),
cni.WithPluginMaxConfNum(config.NetworkPluginMaxConfNum),
cni.WithPluginDir([]string{config.NetworkPluginBinDir}))
if err != nil {
return nil, errors.Wrap(err, "failed to initialize cni")
@@ -172,10 +171,15 @@ func NewCRIService(config criconfig.Config, client *containerd.Client) (CRIServi
// Register registers all required services onto a specific grpc server.
// This is used by containerd cri plugin.
func (c *criService) Register(s *grpc.Server) error {
instrumented := newInstrumentedService(c)
runtime.RegisterRuntimeServiceServer(s, instrumented)
runtime.RegisterImageServiceServer(s, instrumented)
api.RegisterCRIPluginServiceServer(s, instrumented)
return c.register(s)
}
// RegisterTCP register all required services onto a GRPC server on TCP.
// This is used by containerd CRI plugin.
func (c *criService) RegisterTCP(s *grpc.Server) error {
if !c.config.DisableTCPService {
return c.register(s)
}
return nil
}
@@ -269,6 +273,13 @@ func (c *criService) Close() error {
return nil
}
func (c *criService) register(s *grpc.Server) error {
instrumented := newInstrumentedService(c)
runtime.RegisterRuntimeServiceServer(s, instrumented)
runtime.RegisterImageServiceServer(s, instrumented)
return nil
}
// imageFSPath returns containerd image filesystem path.
// Note that if containerd changes directory layout, we also needs to change this.
func imageFSPath(rootDir, snapshotter string) string {

View File

@@ -24,7 +24,7 @@ import (
cni "github.com/containerd/go-cni"
"github.com/sirupsen/logrus"
"golang.org/x/net/context"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
)
// networkNotReadyReason is the reason reported when network is not ready.
@@ -72,6 +72,12 @@ func (c *criService) Status(ctx context.Context, r *runtime.StatusRequest) (*run
return nil, err
}
resp.Info["golang"] = string(versionByt)
cniConfig, err := json.Marshal(c.netPlugin.GetConfig())
if err != nil {
logrus.WithError(err).Errorf("Failed to marshal CNI config %v", err)
}
resp.Info["cniconfig"] = string(cniConfig)
}
return resp, nil
}

View File

@@ -25,7 +25,7 @@ import (
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/net/context"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
)
// cniConfigTemplate contains the values containerd will overwrite

View File

@@ -19,7 +19,7 @@ package server
import (
"github.com/containerd/containerd/version"
"golang.org/x/net/context"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
"github.com/containerd/cri/pkg/constants"
)

View File

@@ -21,7 +21,7 @@ import (
"github.com/containerd/containerd"
"github.com/docker/docker/pkg/truncindex"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
cio "github.com/containerd/cri/pkg/server/io"
"github.com/containerd/cri/pkg/store"

View File

@@ -20,7 +20,7 @@ import (
"encoding/json"
"github.com/pkg/errors"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
)
// NOTE(random-liu):

View File

@@ -25,7 +25,7 @@ import (
"github.com/containerd/continuity"
"github.com/pkg/errors"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
)
// The container state machine in the CRI plugin:
@@ -90,7 +90,6 @@ type Status struct {
Message string
// Starting indicates that the container is in starting state.
// This field doesn't need to be checkpointed.
// TODO(now): Add unit test.
Starting bool `json:"-"`
// Removing indicates that the container is in removing state.
// This field doesn't need to be checkpointed.

View File

@@ -47,8 +47,6 @@ type Image struct {
Size int64
// ImageSpec is the oci image structure which describes basic information about the image.
ImageSpec imagespec.Image
// Containerd image reference
Image containerd.Image
}
// Store stores all images.
@@ -152,7 +150,6 @@ func getImage(ctx context.Context, i containerd.Image) (*Image, error) {
ChainID: chainID.String(),
Size: size,
ImageSpec: ociimage,
Image: i,
}, nil
}

View File

@@ -21,7 +21,7 @@ import (
cni "github.com/containerd/go-cni"
"github.com/pkg/errors"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
)
// NOTE(random-liu):
@@ -57,7 +57,7 @@ type Metadata struct {
IP string
// RuntimeHandler is the runtime handler name of the pod.
RuntimeHandler string
// CNI result
// CNIresult resulting configuration for attached network namespace interfaces
CNIResult *cni.CNIResult
}

View File

@@ -1,13 +1,13 @@
github.com/beorn7/perks 4c0e84591b9aa9e6dcfdf3e020114cd81f89d5f9
github.com/BurntSushi/toml v0.3.1
github.com/containerd/cgroups 4994991857f9b0ae8dc439551e8bebdbb4bf66c1
github.com/containerd/console c12b1e7919c14469339a5d38f2f8ed9b64a9de23
github.com/containerd/containerd 32e788a8be3ab4418265693d9e742c30495fdd4c
github.com/containerd/cgroups db272301ab8449d05f062e6db6f13d8a6aaff466
github.com/containerd/console 0650fd9eeb50bab4fc99dceb9f2e14cf58f36e7f
github.com/containerd/containerd 31afff294400b5a69bdb3ec387ecdf5bad57a038
github.com/containerd/continuity bd77b46c8352f74eb12c85bdc01f4b90f69d66b4
github.com/containerd/fifo 3d5202aec260678c48179c56f40e6f38a095738c
github.com/containerd/go-cni 891c2a41e18144b2d7921f971d6c9789a68046b2
github.com/containerd/go-cni 22460c018b64cf8bf4151b3ff9c4d077e6a88cbf
github.com/containerd/go-runc 5a6d9f37cfa36b15efba46dc7ea349fa9b7143c3
github.com/containerd/ttrpc f02858b1457c5ca3aaec3a0803eb0d59f96e41d6
github.com/containerd/ttrpc a5bd8ce9e40bc7c065a11c6936f4d032ce6bfa2b
github.com/containerd/typeurl a93fcdb778cd272c6e9b3028b2f42d813e785d40
github.com/containernetworking/cni v0.6.0
github.com/containernetworking/plugins v0.7.5
@@ -17,7 +17,7 @@ github.com/docker/distribution 0d3efadf0154c2b8a4e7b6621fff9809655cc580
github.com/docker/docker 86f080cff0914e9694068ed78d503701667c4c00
github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9
github.com/docker/go-metrics 4ea375f7759c82740c893fc030bc37088d2ec098
github.com/docker/go-units v0.3.1
github.com/docker/go-units v0.4.0
github.com/docker/spdystream 449fdfce4d962303d702fec724ef0ad181c92528
github.com/emicklei/go-restful v2.2.1
github.com/godbus/dbus v3
@@ -28,44 +28,45 @@ github.com/google/gofuzz 44d81051d367757e1c7c6a5a86423ece9afcf63c
github.com/grpc-ecosystem/go-grpc-prometheus v1.1
github.com/json-iterator/go 1.1.5
github.com/matttproud/golang_protobuf_extensions v1.0.1
github.com/Microsoft/go-winio c599b533b43b1363d7d7c6cfda5ede70ed73ff13
github.com/Microsoft/go-winio 84b4ab48a50763fe7b3abcef38e5205c12027fac
github.com/Microsoft/hcsshim 8abdbb8205e4192c68b5f84c31197156f31be517
github.com/modern-go/concurrent 1.0.3
github.com/modern-go/reflect2 1.0.1
github.com/opencontainers/go-digest c9281466c8b2f606084ac71339773efd177436e7
github.com/opencontainers/image-spec v1.0.1
github.com/opencontainers/runc 029124da7af7360afa781a0234d1b083550f797c
github.com/opencontainers/runc v1.0.0-rc8
github.com/opencontainers/runtime-spec 29686dbc5559d93fb1ef402eeda3e35c38d75af4
github.com/opencontainers/selinux v1.2.1
github.com/opencontainers/selinux v1.2.2
github.com/pkg/errors v0.8.1
github.com/pmezard/go-difflib v1.0.0
github.com/prometheus/client_golang f4fb1b73fb099f396a7f0036bf86aa8def4ed823
github.com/prometheus/client_model 99fa1f4be8e564e8a6b613da7fa6f46c9edafc6c
github.com/prometheus/common 89604d197083d4781071d3c65855d24ecfb0a563
github.com/prometheus/procfs cb4147076ac75738c9a7d279075a253c0cc5acbd
github.com/seccomp/libseccomp-golang 32f571b70023028bd57d9288c20efbcb237f3ce0
github.com/seccomp/libseccomp-golang v0.9.1
github.com/sirupsen/logrus v1.4.1
github.com/stretchr/testify v1.1.4
github.com/syndtr/gocapability db04d3cc01c8b54962a58ec7e491717d06cfcc16
github.com/syndtr/gocapability d98352740cb2c55f81556b63d4a1ec64c5a319c2
github.com/tchap/go-patricia v2.2.6
github.com/urfave/cli 7bc6a0acffa589f415f88aca16cc1de5ffd66f9c
go.etcd.io/bbolt v1.3.2
golang.org/x/crypto 49796115aa4b964c318aad4f3084fdb41e9aa067
golang.org/x/net b3756b4b77d7b13260a0a2ec658753cf48922eac
go.etcd.io/bbolt 2eb7227adea1d5cf85f0bc2a82b7059b13c2fa68
golang.org/x/crypto 88737f569e3a9c7ab309cdc09a07fe7fc87233c3
golang.org/x/net f3200d17e092c607f615320ecaad13d87ad9a2b3
golang.org/x/oauth2 a6bd8cefa1811bd24b86f8902872e4e8225f74c4
golang.org/x/sync 42b317875d0fa942474b76e1b46a6060d720ae6e
golang.org/x/sys d455e41777fca6e8a5a79e34a14b8368bc11d9ba https://github.com/golang/sys
golang.org/x/sys 4c4f7f33c9ed00de01c4c741d2177abfcfe19307 https://github.com/golang/sys
golang.org/x/text 19e51611da83d6be54ddafce4a4af510cb3e9ea4
golang.org/x/time f51c12702a4d776e4c1fa9b0fabab841babae631
google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944
google.golang.org/grpc v1.12.0
google.golang.org/grpc 25c4f928eaa6d96443009bd842389fb4fa48664e
gopkg.in/inf.v0 3887ee99ecf07df5b447e9b00d9c0b2adaa9f3e4
gopkg.in/yaml.v2 v2.2.1
k8s.io/api kubernetes-1.15.0-alpha.0
k8s.io/apimachinery kubernetes-1.15.0-alpha.0
k8s.io/apiserver kubernetes-1.15.0-alpha.0
k8s.io/client-go kubernetes-1.15.0-alpha.0
k8s.io/klog 8145543d67ada0bd556af97faeeb8a65a2651c98
k8s.io/kubernetes v1.15.0-alpha.0
k8s.io/api kubernetes-1.15.0
k8s.io/apimachinery kubernetes-1.15.0
k8s.io/apiserver kubernetes-1.15.0
k8s.io/cri-api kubernetes-1.15.0
k8s.io/client-go kubernetes-1.15.0
k8s.io/klog v0.3.1
k8s.io/kubernetes v1.15.0
k8s.io/utils c2654d5206da6b7b6ace12841e8f359bb89b443c
sigs.k8s.io/yaml v1.1.0

View File

@@ -41,10 +41,11 @@ type CNI interface {
}
type ConfigResult struct {
PluginDirs []string
PluginConfDir string
Prefix string
Networks []*ConfNetwork
PluginDirs []string
PluginConfDir string
PluginMaxConfNum int
Prefix string
Networks []*ConfNetwork
}
type ConfNetwork struct {
@@ -78,9 +79,10 @@ type libcni struct {
func defaultCNIConfig() *libcni {
return &libcni{
config: config{
pluginDirs: []string{DefaultCNIDir},
pluginConfDir: DefaultNetDir,
prefix: DefaultPrefix,
pluginDirs: []string{DefaultCNIDir},
pluginConfDir: DefaultNetDir,
pluginMaxConfNum: DefaultMaxConfNum,
prefix: DefaultPrefix,
},
cniConfig: &cnilibrary.CNIConfig{
Path: []string{DefaultCNIDir},
@@ -187,9 +189,10 @@ func (c *libcni) GetConfig() *ConfigResult {
c.RLock()
defer c.RUnlock()
r := &ConfigResult{
PluginDirs: c.config.pluginDirs,
PluginConfDir: c.config.pluginConfDir,
Prefix: c.config.prefix,
PluginDirs: c.config.pluginDirs,
PluginConfDir: c.config.pluginConfDir,
PluginMaxConfNum: c.config.pluginMaxConfNum,
Prefix: c.config.prefix,
}
for _, network := range c.networks {
conf := &NetworkConfList{

View File

@@ -33,6 +33,15 @@ func WithCapabilityIPRanges(ipRanges []IPRanges) NamespaceOpts {
}
}
// WithCapabilityBandWitdh adds support for traffic shaping:
// https://github.com/heptio/cni-plugins/tree/master/plugins/meta/bandwidth
func WithCapabilityBandWidth(bandWidth BandWidth) NamespaceOpts {
return func(c *Namespace) error {
c.capabilityArgs["bandwidth"] = bandWidth
return nil
}
}
func WithCapability(name string, capability interface{}) NamespaceOpts {
return func(c *Namespace) error {
c.capabilityArgs[name] = capability

View File

@@ -54,6 +54,15 @@ func WithPluginConfDir(dir string) CNIOpt {
}
}
// WithPluginMaxConfNum can be used to configure the
// max cni plugin config file num.
func WithPluginMaxConfNum(max int) CNIOpt {
return func(c *libcni) error {
c.pluginMaxConfNum = max
return nil
}
}
// WithMinNetworkCount can be used to configure the
// minimum networks to be configured and initialized
// for the status to report success. By default its 1.
@@ -86,6 +95,12 @@ func WithLoNetwork(c *libcni) error {
// WithConf can be used to load config directly
// from byte.
func WithConf(bytes []byte) CNIOpt {
return WithConfIndex(bytes, 0)
}
// WithConfIndex can be used to load config directly
// from byte and set the interface name's index.
func WithConfIndex(bytes []byte, index int) CNIOpt {
return func(c *libcni) error {
conf, err := cnilibrary.ConfFromBytes(bytes)
if err != nil {
@@ -98,7 +113,7 @@ func WithConf(bytes []byte) CNIOpt {
c.networks = append(c.networks, &Network{
cni: c.cniConfig,
config: confList,
ifName: getIfName(c.prefix, 0),
ifName: getIfName(c.prefix, index),
})
return nil
}
@@ -153,7 +168,7 @@ func WithConfListFile(fileName string) CNIOpt {
// the convention chosen is - the first network configuration in the sorted
// list of network conf files as the default network.
func WithDefaultConf(c *libcni) error {
return loadFromConfDir(c, 1)
return loadFromConfDir(c, c.pluginMaxConfNum)
}
// WithAllConf can be used to detect all network config

View File

@@ -20,14 +20,16 @@ const (
CNIPluginName = "cni"
DefaultNetDir = "/etc/cni/net.d"
DefaultCNIDir = "/opt/cni/bin"
DefaultMaxConfNum = 1
VendorCNIDirTemplate = "%s/opt/%s/bin"
DefaultPrefix = "eth"
)
type config struct {
pluginDirs []string
pluginConfDir string
prefix string
pluginDirs []string
pluginConfDir string
pluginMaxConfNum int
prefix string
}
type PortMapping struct {
@@ -43,3 +45,11 @@ type IPRanges struct {
RangeEnd string
Gateway string
}
// BandWidth defines the ingress/egress rate and burst limits
type BandWidth struct {
IngressRate uint64
IngressBurst uint64
EgressRate uint64
EgressBurst uint64
}