Update cri plugin to v1.0.0-rc.1.

Signed-off-by: Lantao Liu <lantaol@google.com>
This commit is contained in:
Lantao Liu 2018-04-03 21:11:38 +00:00
parent d1b3ea4061
commit 89d74986cc
20 changed files with 103 additions and 99 deletions

View File

@ -43,7 +43,7 @@ github.com/gotestyourself/gotestyourself 44dbf532bbf5767611f6f2a61bded572e337010
github.com/google/go-cmp v0.1.0
# cri dependencies
github.com/containerd/cri v1.0.0-rc.0
github.com/containerd/cri v1.0.0-rc.1
github.com/containerd/go-cni f2d7272f12d045b16ed924f50e91f9f9cecc55a7
github.com/blang/semver v3.1.0
github.com/containernetworking/cni v0.6.0
@ -68,11 +68,11 @@ golang.org/x/crypto 49796115aa4b964c318aad4f3084fdb41e9aa067
golang.org/x/time f51c12702a4d776e4c1fa9b0fabab841babae631
gopkg.in/inf.v0 3887ee99ecf07df5b447e9b00d9c0b2adaa9f3e4
gopkg.in/yaml.v2 53feefa2559fb8dfa8d81baad31be332c97d6c77
k8s.io/api 5584376ceeffeb13a2e98b5e9f0e9dab37de4bab
k8s.io/api 7e796de92438aede7cb5d6bcf6c10f4fa65db560
k8s.io/apimachinery fcb9a12f7875d01f8390b28faedc37dcf2e713b9
k8s.io/apiserver 837069aa36757a586e4a8165f1ff5ca06170aa4a
k8s.io/client-go 484f27892430b961df38fe6715cc396409207d9f
k8s.io/kubernetes v1.10.0-rc.1
k8s.io/apiserver 4a8377c547bbff4576a35b5b5bf4026d9b5aa763
k8s.io/client-go b9a0cf870f239c4a4ecfd3feb075a50e7cbe1473
k8s.io/kubernetes v1.10.0
k8s.io/utils 258e2a2fa64568210fbd6267cf1d8fd87c3cb86e
# zfs dependencies

View File

@ -66,7 +66,6 @@ specifications as appropriate.
* **libseccomp development library.** Required by `cri` and runc seccomp support. `libseccomp-dev` (Ubuntu, Debian) / `libseccomp-devel`
(Fedora, CentOS, RHEL). On releases of Ubuntu <=Trusty and Debian <=jessie a
backport version of `libseccomp-dev` is required. See [travis.yml](.travis.yml) for an example on trusty.
* **libapparmor development library.** Required by `cri` and runc apparmor support. To use apparmor on Debian, Ubuntu, and related distributions the installation of `libapparmor-dev` is required.
* **btrfs development library.** Required by containerd btrfs support. `btrfs-tools`(Ubuntu, Debian) / `btrfs-progs-devel`(Fedora, CentOS, RHEL)
2. Install other dependencies:
* **`nsenter`**: Required by portforward.
@ -102,7 +101,7 @@ make BUILD_TAGS='seccomp apparmor'
|-----------|------------------------------------|---------------------------------|
| seccomp | syscall filtering | libseccomp development library |
| selinux | selinux process and mount labeling | <none> |
| apparmor | apparmor profile support | libapparmor development library |
| apparmor | apparmor profile support | <none> |
### Validate Your `cri` Setup
A Kubernetes incubator project called [cri-tools](https://github.com/kubernetes-incubator/cri-tools)
includes programs for exercising CRI implementations such as the `cri` plugin.

View File

@ -83,6 +83,8 @@ type PluginConfig struct {
StatsCollectPeriod int `toml:"stats_collect_period" json:"statsCollectPeriod"`
// SystemdCgroup enables systemd cgroup support.
SystemdCgroup bool `toml:"systemd_cgroup" json:"systemdCgroup"`
// EnableTLSStreaming indicates to enable the TLS streaming support.
EnableTLSStreaming bool `toml:"enable_tls_streaming" json:"enableTLSStreaming"`
}
// Config contains all configurations for cri server.
@ -118,6 +120,7 @@ func DefaultConfig() PluginConfig {
StreamServerAddress: "",
StreamServerPort: "10010",
EnableSelinux: false,
EnableTLSStreaming: false,
SandboxImage: "k8s.gcr.io/pause:3.1",
StatsCollectPeriod: 10,
SystemdCgroup: false,

View File

@ -19,6 +19,7 @@ package server
import (
"os"
"path/filepath"
"strconv"
"strings"
"time"
@ -219,11 +220,16 @@ func (c *criService) CreateContainer(ctx context.Context, r *runtime.CreateConta
// Set container username. This could only be done by containerd, because it needs
// access to the container rootfs. Pass user name to containerd, and let it overwrite
// the spec for us.
if uid := securityContext.GetRunAsUser(); uid != nil {
specOpts = append(specOpts, oci.WithUserID(uint32(uid.GetValue())))
userstr, err := generateUserString(
securityContext.GetRunAsUsername(),
securityContext.GetRunAsUser(),
securityContext.GetRunAsGroup(),
)
if err != nil {
return nil, errors.Wrap(err, "failed to generate user string")
}
if username := securityContext.GetRunAsUsername(); username != "" {
specOpts = append(specOpts, oci.WithUsername(username))
if userstr != "" {
specOpts = append(specOpts, oci.WithUser(userstr))
}
apparmorSpecOpts, err := generateApparmorSpecOpts(
@ -884,3 +890,28 @@ func ensureSharedOrSlave(path string, lookupMount func(string) (mount.Info, erro
}
return errors.Errorf("path %q is mounted on %q but it is not a shared or slave mount", path, mountInfo.Mountpoint)
}
// generateUserString generates valid user string based on OCI Image Spec v1.0.0.
// TODO(random-liu): Add group name support in CRI.
func generateUserString(username string, uid, gid *runtime.Int64Value) (string, error) {
var userstr, groupstr string
if uid != nil {
userstr = strconv.FormatInt(uid.GetValue(), 10)
}
if username != "" {
userstr = username
}
if gid != nil {
groupstr = strconv.FormatInt(gid.GetValue(), 10)
}
if userstr == "" {
if groupstr != "" {
return "", errors.Errorf("user group %q is specified without user", groupstr)
}
return "", nil
}
if groupstr != "" {
userstr = userstr + ":" + groupstr
}
return userstr, nil
}

View File

@ -17,6 +17,7 @@ limitations under the License.
package server
import (
"sync"
"time"
eventtypes "github.com/containerd/containerd/api/events"
@ -57,6 +58,8 @@ type eventMonitor struct {
type backOff struct {
queuePool map[string]*backOffQueue
// tickerMu is mutex used to protect the ticker.
tickerMu sync.Mutex
ticker *time.Ticker
minDuration time.Duration
maxDuration time.Duration
@ -120,8 +123,8 @@ func (em *eventMonitor) start() (<-chan struct{}, error) {
return nil, errors.New("event channel is nil")
}
closeCh := make(chan struct{})
go func() {
backOffCheckCh := em.backOff.start()
go func() {
for {
select {
case e := <-em.ch:
@ -366,13 +369,19 @@ func (b *backOff) reBackOff(key string, events []interface{}, oldDuration time.D
}
func (b *backOff) start() <-chan time.Time {
b.tickerMu.Lock()
defer b.tickerMu.Unlock()
b.ticker = time.NewTicker(b.checkDuration)
return b.ticker.C
}
func (b *backOff) stop() {
b.tickerMu.Lock()
defer b.tickerMu.Unlock()
if b.ticker != nil {
b.ticker.Stop()
}
}
func newBackOffQueue(events []interface{}, init time.Duration, c clock.Clock) *backOffQueue {
return &backOffQueue{

View File

@ -102,7 +102,7 @@ func (c *criService) portForward(id string, port int32, stream io.ReadWriteClose
logrus.WithError(err).Errorf("Failed to copy port forward input for %q port %d", id, port)
}
in.Close()
logrus.Debugf("Finish copy port forward input for %q port %d: %v", id, port)
logrus.Debugf("Finish copy port forward input for %q port %d", id, port)
}()
if err := cmd.Run(); err != nil {

View File

@ -145,8 +145,16 @@ func (c *criService) RunPodSandbox(ctx context.Context, r *runtime.RunPodSandbox
logrus.Debugf("Sandbox container spec: %+v", spec)
var specOpts []oci.SpecOpts
if uid := securityContext.GetRunAsUser(); uid != nil {
specOpts = append(specOpts, oci.WithUserID(uint32(uid.GetValue())))
userstr, err := generateUserString(
"",
securityContext.GetRunAsUser(),
securityContext.GetRunAsGroup(),
)
if err != nil {
return nil, errors.Wrap(err, "failed to generate user string")
}
if userstr != "" {
specOpts = append(specOpts, oci.WithUser(userstr))
}
seccompSpecOpts, err := generateSeccompSpecOpts(

View File

@ -17,19 +17,11 @@ limitations under the License.
package server
import (
"crypto/rand"
"crypto/rsa"
"crypto/tls"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"fmt"
"io"
"math"
"math/big"
"net"
"os"
"time"
"github.com/pkg/errors"
k8snet "k8s.io/apimachinery/pkg/util/net"
@ -42,13 +34,6 @@ import (
ctrdutil "github.com/containerd/cri/pkg/containerd/util"
)
const (
// certOrganizationName is the name of this organization, used for certificates etc.
certOrganizationName = "containerd"
// certCommonName is the common name of the CRI plugin
certCommonName = "cri"
)
func newStreamServer(c *criService, addr, port string) (streaming.Server, error) {
if addr == "" {
a, err := k8snet.ChooseBindAddress(nil)
@ -60,6 +45,7 @@ func newStreamServer(c *criService, addr, port string) (streaming.Server, error)
config := streaming.DefaultConfig
config.Addr = net.JoinHostPort(addr, port)
runtime := newStreamRuntime(c)
if c.config.EnableTLSStreaming {
tlsCert, err := newTLSCert()
if err != nil {
return nil, errors.Wrap(err, "failed to generate tls certificate for stream server")
@ -68,6 +54,7 @@ func newStreamServer(c *criService, addr, port string) (streaming.Server, error)
Certificates: []tls.Certificate{tlsCert},
InsecureSkipVerify: true,
}
}
return streaming.NewServer(config, runtime)
}
@ -139,54 +126,26 @@ func handleResizing(resize <-chan remotecommand.TerminalSize, resizeFunc func(si
}()
}
// newTLSCert returns a tls.certificate loaded from a newly generated
// x509certificate from a newly generated rsa public/private key pair. The
// x509certificate is self signed.
// newTLSCert returns a self CA signed tls.certificate.
// TODO (mikebrow): replace / rewrite this function to support using CA
// signing of the cetificate. Requires a security plan for kubernetes regarding
// CRI connections / streaming, etc. For example, kubernetes could configure or
// require a CA service and pass a configuration down through CRI.
func newTLSCert() (tls.Certificate, error) {
fail := func(err error) (tls.Certificate, error) { return tls.Certificate{}, err }
var years = 1 // duration of certificate
// Generate new private key
privKey, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
return fail(errors.Wrap(err, "private key cannot be created"))
}
// Generate pem block using the private key
keyPem := pem.EncodeToMemory(&pem.Block{
Type: k8scert.RSAPrivateKeyBlockType,
Bytes: x509.MarshalPKCS1PrivateKey(privKey),
})
// Generate a new random serial number for certificate
serialNumber, err := rand.Int(rand.Reader, new(big.Int).Lsh(big.NewInt(1), 128))
if err != nil {
return fail(errors.Wrap(err, "failed to generate serial number"))
}
hostName, err := os.Hostname()
if err != nil {
return fail(errors.Wrap(err, "failed to get hostname"))
}
addrs, err := net.InterfaceAddrs()
if err != nil {
return fail(errors.Wrap(err, "failed to get host IP addresses"))
}
// Configure and create new certificate
tml := x509.Certificate{
NotBefore: time.Now(),
NotAfter: time.Now().AddDate(years, 0, 0),
SerialNumber: serialNumber,
Subject: pkix.Name{
CommonName: fmt.Sprintf("%s:%s:%s", certOrganizationName, certCommonName, hostName),
Organization: []string{certOrganizationName},
},
BasicConstraintsValid: true,
}
var alternateIPs []net.IP
var alternateDNS []string
for _, addr := range addrs {
var ip net.IP
@ -199,21 +158,16 @@ func newTLSCert() (tls.Certificate, error) {
continue
}
tml.IPAddresses = append(tml.IPAddresses, ip)
tml.DNSNames = append(tml.DNSNames, ip.String())
alternateIPs = append(alternateIPs, ip)
alternateDNS = append(alternateDNS, ip.String())
}
cert, err := x509.CreateCertificate(rand.Reader, &tml, &tml, &privKey.PublicKey, privKey)
// Generate a self signed certificate key (CA is self)
certPem, keyPem, err := k8scert.GenerateSelfSignedCertKey(hostName, alternateIPs, alternateDNS)
if err != nil {
return fail(errors.Wrap(err, "certificate cannot be created"))
return fail(errors.Wrap(err, "certificate key could not be created"))
}
// Generate a pem block with the certificate
certPem := pem.EncodeToMemory(&pem.Block{
Type: k8scert.CertificateBlockType,
Bytes: cert,
})
// Load the tls certificate
tlsCert, err := tls.X509KeyPair(certPem, keyPem)
if err != nil {

View File

@ -4,7 +4,7 @@ github.com/boltdb/bolt e9cf4fae01b5a8ff89d0ec6b32f0d9c9f79aefdd
github.com/BurntSushi/toml a368813c5e648fee92e5f6c30e3944ff9d5e8895
github.com/containerd/cgroups fe281dd265766145e943a034aa41086474ea6130
github.com/containerd/console cb7008ab3d8359b78c5f464cb7cf160107ad5925
github.com/containerd/containerd 8a7e17ef96678507a4b23d2bc66e5bbe5b50ad37
github.com/containerd/containerd d1b3ea406130fdb7284f14a8754b2272f2537c4c
github.com/containerd/continuity 3e8f2ea4b190484acb976a5b378d373429639a1a
github.com/containerd/fifo 3d5202aec260678c48179c56f40e6f38a095738c
github.com/containerd/go-runc bcb223a061a3dd7de1a89c0b402a60f4dd9bd307
@ -64,9 +64,9 @@ google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944
google.golang.org/grpc v1.7.4
gopkg.in/inf.v0 3887ee99ecf07df5b447e9b00d9c0b2adaa9f3e4
gopkg.in/yaml.v2 53feefa2559fb8dfa8d81baad31be332c97d6c77
k8s.io/api 5584376ceeffeb13a2e98b5e9f0e9dab37de4bab
k8s.io/api 7e796de92438aede7cb5d6bcf6c10f4fa65db560
k8s.io/apimachinery fcb9a12f7875d01f8390b28faedc37dcf2e713b9
k8s.io/apiserver 837069aa36757a586e4a8165f1ff5ca06170aa4a
k8s.io/client-go 484f27892430b961df38fe6715cc396409207d9f
k8s.io/kubernetes v1.10.0-rc.1
k8s.io/apiserver 4a8377c547bbff4576a35b5b5bf4026d9b5aa763
k8s.io/client-go b9a0cf870f239c4a4ecfd3feb075a50e7cbe1473
k8s.io/kubernetes v1.10.0
k8s.io/utils 258e2a2fa64568210fbd6267cf1d8fd87c3cb86e

View File

@ -1,5 +1,5 @@
/*
Copyright 2018 The Kubernetes Authors.
Copyright 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.

View File

@ -1,5 +1,5 @@
/*
Copyright 2018 The Kubernetes Authors.
Copyright 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.

View File

@ -1,5 +1,5 @@
/*
Copyright 2016 The Kubernetes Authors.
Copyright 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.
@ -26,7 +26,7 @@ package v1
//
// Those methods can be generated by using hack/update-generated-swagger-docs.sh
// AUTO-GENERATED FUNCTIONS START HERE
// AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT.
var map_AWSElasticBlockStoreVolumeSource = map[string]string{
"": "Represents a Persistent Disk resource in AWS.\n\nAn AWS EBS disk must exist before mounting to a container. The disk must also be in the same AWS zone as the kubelet. An AWS EBS disk can only be mounted as read/write once. AWS EBS volumes support ownership management and SELinux relabeling.",
"volumeID": "Unique ID of the persistent disk resource in AWS (Amazon EBS volume). More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore",

View File

@ -1,7 +1,7 @@
// +build !ignore_autogenerated
/*
Copyright 2018 The Kubernetes Authors.
Copyright 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.

View File

@ -1,7 +1,7 @@
// +build !ignore_autogenerated
/*
Copyright 2018 The Kubernetes Authors.
Copyright 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.

View File

@ -1,7 +1,7 @@
// +build !ignore_autogenerated
/*
Copyright 2018 The Kubernetes Authors.
Copyright 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.

View File

@ -1,7 +1,7 @@
// +build !ignore_autogenerated
/*
Copyright 2018 The Kubernetes Authors.
Copyright 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.

View File

@ -1,7 +1,7 @@
// +build !ignore_autogenerated
/*
Copyright 2018 The Kubernetes Authors.
Copyright 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.

View File

@ -1,7 +1,7 @@
// +build !ignore_autogenerated
/*
Copyright 2018 The Kubernetes Authors.
Copyright 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.

View File

@ -1,7 +1,7 @@
// +build !ignore_autogenerated
/*
Copyright 2018 The Kubernetes Authors.
Copyright 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.

View File

@ -331,11 +331,11 @@ func (r *requestInfo) toCurl() string {
headers := ""
for key, values := range r.RequestHeaders {
for _, value := range values {
headers += fmt.Sprintf(` -H %q`, fmt.Sprintf("%s: %s", key, value))
headers += fmt.Sprintf(` -H %q`, fmt.Sprintf("%s: '%s'", key, value))
}
}
return fmt.Sprintf("curl -k -v -X%s %s %s", r.RequestVerb, headers, r.RequestURL)
return fmt.Sprintf("curl -k -v -X%s %s '%s'", r.RequestVerb, headers, r.RequestURL)
}
// debuggingRoundTripper will display information about the requests passing