Merge pull request #1546 from smarterclayton/allow_configurable_net_image

Allow configurable Kubelet net image for isolated networks
pull/6/head
Tim Hockin 2014-10-02 17:11:32 -07:00
commit f7db0bc674
4 changed files with 118 additions and 41 deletions

View File

@ -57,6 +57,7 @@ var (
address = flag.String("address", "127.0.0.1", "The address for the info server to serve on (set to 0.0.0.0 or \"\" for all interfaces)")
port = flag.Uint("port", master.KubeletPort, "The port for the info server to serve on")
hostnameOverride = flag.String("hostname_override", "", "If non-empty, will use this string as identification instead of the actual hostname.")
networkContainerImage = flag.String("network_container_image", kubelet.NetworkContainerImage, "The image that network containers in each pod will use.")
dockerEndpoint = flag.String("docker_endpoint", "", "If non-empty, use this for the docker endpoint to communicate with")
etcdServerList util.StringList
rootDirectory = flag.String("root_dir", defaultRootDir, "Directory path for managing kubelet files (volume mounts,etc).")
@ -159,6 +160,7 @@ func main() {
cadvisorClient,
etcdClient,
*rootDirectory,
*networkContainerImage,
*syncFrequency,
float32(*registryPullQPS),
*registryBurst)

View File

@ -81,7 +81,7 @@ func (f *FakeDockerClient) CreateContainer(c docker.CreateContainerOptions) (*do
// This is not a very good fake. We'll just add this container's name to the list.
// Docker likes to add a '/', so copy that behavior.
name := "/" + c.Name
f.ContainerList = append(f.ContainerList, docker.APIContainers{ID: name, Names: []string{name}})
f.ContainerList = append(f.ContainerList, docker.APIContainers{ID: name, Names: []string{name}, Image: c.Config.Image})
return &docker.Container{ID: name}, nil
}
@ -138,6 +138,7 @@ func (f *FakeDockerClient) InspectImage(name string) (*docker.Image, error) {
type FakeDockerPuller struct {
sync.Mutex
HasImages []string
ImagesPulled []string
// Every pull will return the first error here, and then reslice
@ -159,5 +160,15 @@ func (f *FakeDockerPuller) Pull(image string) (err error) {
}
func (f *FakeDockerPuller) IsImagePresent(name string) (bool, error) {
f.Lock()
defer f.Unlock()
if f.HasImages == nil {
return true, nil
}
for _, s := range f.HasImages {
if s == name {
return true, nil
}
}
return false, nil
}

View File

@ -67,6 +67,7 @@ func NewMainKubelet(
cc CadvisorInterface,
ec tools.EtcdClient,
rd string,
ni string,
ri time.Duration,
pullQPS float32,
pullBurst int) *Kubelet {
@ -77,6 +78,7 @@ func NewMainKubelet(
etcdClient: ec,
rootDirectory: rd,
resyncInterval: ri,
networkContainerImage: ni,
podWorkers: newPodWorkers(),
runner: dockertools.NewDockerContainerCommandRunner(),
httpClient: &http.Client{},
@ -92,6 +94,7 @@ func NewIntegrationTestKubelet(hn string, dc dockertools.DockerInterface) *Kubel
hostname: hn,
dockerClient: dc,
dockerPuller: &dockertools.FakeDockerPuller{},
networkContainerImage: NetworkContainerImage,
resyncInterval: 3 * time.Second,
podWorkers: newPodWorkers(),
}
@ -106,6 +109,7 @@ type Kubelet struct {
hostname string
dockerClient dockertools.DockerInterface
rootDirectory string
networkContainerImage string
podWorkers podWorkers
resyncInterval time.Duration
@ -368,7 +372,7 @@ func (kl *Kubelet) killContainerByID(ID, name string) error {
const (
networkContainerName = "net"
networkContainerImage = "kubernetes/pause:latest"
NetworkContainerImage = "kubernetes/pause:latest"
)
// createNetworkContainer starts the network container for a pod. Returns the docker container ID of the newly created container.
@ -381,12 +385,19 @@ func (kl *Kubelet) createNetworkContainer(pod *Pod) (dockertools.DockerID, error
}
container := &api.Container{
Name: networkContainerName,
Image: networkContainerImage,
Image: kl.networkContainerImage,
Ports: ports,
}
if err := kl.dockerPuller.Pull(networkContainerImage); err != nil {
// TODO: make this a TTL based pull (if image older than X policy, pull)
ok, err := kl.dockerPuller.IsImagePresent(container.Image)
if err != nil {
return "", err
}
if !ok {
if err := kl.dockerPuller.Pull(container.Image); err != nil {
return "", err
}
}
return kl.runContainer(pod, container, nil, "")
}

View File

@ -22,6 +22,7 @@ import (
"reflect"
"regexp"
"strconv"
"strings"
"sync"
"testing"
"time"
@ -206,6 +207,7 @@ func matchString(t *testing.T, pattern, str string) bool {
func TestSyncPodsCreatesNetAndContainer(t *testing.T) {
kubelet, _, fakeDocker := newTestKubelet(t)
kubelet.networkContainerImage = "custom_image_name"
fakeDocker.ContainerList = []docker.APIContainers{}
err := kubelet.SyncPods([]Pod{
{
@ -228,6 +230,57 @@ func TestSyncPodsCreatesNetAndContainer(t *testing.T) {
"list", "list", "create", "start", "list", "inspect", "list", "create", "start"})
fakeDocker.Lock()
found := false
for _, c := range fakeDocker.ContainerList {
if c.Image == "custom_image_name" && strings.HasPrefix(c.Names[0], "/k8s_net") {
found = true
}
}
if !found {
t.Errorf("Custom net container not found: %v", fakeDocker.ContainerList)
}
if len(fakeDocker.Created) != 2 ||
!matchString(t, "k8s_net\\.[a-f0-9]+_foo.test_", fakeDocker.Created[0]) ||
!matchString(t, "k8s_bar\\.[a-f0-9]+_foo.test_", fakeDocker.Created[1]) {
t.Errorf("Unexpected containers created %v", fakeDocker.Created)
}
fakeDocker.Unlock()
}
func TestSyncPodsCreatesNetAndContainerPullsImage(t *testing.T) {
kubelet, _, fakeDocker := newTestKubelet(t)
puller := kubelet.dockerPuller.(*dockertools.FakeDockerPuller)
puller.HasImages = []string{}
kubelet.networkContainerImage = "custom_image_name"
fakeDocker.ContainerList = []docker.APIContainers{}
err := kubelet.SyncPods([]Pod{
{
Name: "foo",
Namespace: "test",
Manifest: api.ContainerManifest{
ID: "foo",
Containers: []api.Container{
{Name: "bar"},
},
},
},
})
if err != nil {
t.Errorf("unexpected error: %v", err)
}
kubelet.drainWorkers()
verifyCalls(t, fakeDocker, []string{
"list", "list", "create", "start", "list", "inspect", "list", "create", "start"})
fakeDocker.Lock()
if !reflect.DeepEqual(puller.ImagesPulled, []string{"custom_image_name", ""}) {
t.Errorf("Unexpected pulled containers: %v", puller.ImagesPulled)
}
if len(fakeDocker.Created) != 2 ||
!matchString(t, "k8s_net\\.[a-f0-9]+_foo.test_", fakeDocker.Created[0]) ||
!matchString(t, "k8s_bar\\.[a-f0-9]+_foo.test_", fakeDocker.Created[1]) {