Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions docs/volumes.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,24 @@ A process in a Container sees a filesystem view composed from two sources: a sin

Kubernetes currently supports two types of Volumes, but more may be added in the future.

### EmptyDirectory
### EmptyDir

An EmptyDirectory volume is created when a Pod is bound to a Node. It is initially empty, when the first Container command starts. Containers in the same pod can all read and write the same files in the EmptyDirectory. When a Pod is unbound, the data in the EmptyDirectory is deleted forever.
An EmptyDir volume is created when a Pod is bound to a Node. It is initially empty, when the first Container command starts. Containers in the same pod can all read and write the same files in the EmptyDir. When a Pod is unbound, the data in the EmptyDir is deleted forever.

Some uses for an EmptyDirectory are:
Some uses for an EmptyDir are:
- scratch space, such as for a disk-based mergesort or checkpointing a long computation.
- a directory that a content-manager container fills with data while a webserver container serves the data.

Currently, the user cannot control what kind of media is used for an EmptyDirectory. If the Kubelet is configured to use a disk drive, then all EmptyDirectories will be created on that disk drive. In the future, it is expected that Pods can control whether the EmptyDirectory is on a disk drive, SSD, or tmpfs.
Currently, the user cannot control what kind of media is used for an EmptyDir. If the Kubelet is configured to use a disk drive, then all EmptyDirectories will be created on that disk drive. In the future, it is expected that Pods can control whether the EmptyDir is on a disk drive, SSD, or tmpfs.

### HostDirectory
A Volume with a HostDirectory property allows access to files on the current node.
### HostDir
A Volume with a HostDir property allows access to files on the current node.

Some uses for a HostDirectory are:
- running a container that needs access to Docker internals; use a HostDirectory of /var/lib/docker.
- running cAdvisor in a container; use a HostDirectory of /dev/cgroups.
Some uses for a HostDir are:
- running a container that needs access to Docker internals; use a HostDir of /var/lib/docker.
- running cAdvisor in a container; use a HostDir of /dev/cgroups.

Watch out when using this type of volume, because:
- pods with identical configuration (such as created from a podTemplate) may behave differently on different nodes due to different files on different nodes.
- When Kubernetes adds resource-aware scheduling, as is planned, it will not be able to account for resources used by a HostDirectory.
- When Kubernetes adds resource-aware scheduling, as is planned, it will not be able to account for resources used by a HostDir.

14 changes: 7 additions & 7 deletions pkg/api/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,22 +85,22 @@ type Volume struct {

type VolumeSource struct {
// Only one of the following sources may be specified
// HostDirectory represents a pre-existing directory on the host machine that is directly
// HostDir represents a pre-existing directory on the host machine that is directly
// exposed to the container. This is generally used for system agents or other privileged
// things that are allowed to see the host machine. Most containers will NOT need this.
// TODO(jonesdl) We need to restrict who can use host directory mounts and
// who can/can not mount host directories as read/write.
HostDirectory *HostDirectory `yaml:"hostDir" json:"hostDir"`
// EmptyDirectory represents a temporary directory that shares a pod's lifetime.
EmptyDirectory *EmptyDirectory `yaml:"emptyDir" json:"emptyDir"`
HostDir *HostDir `yaml:"hostDir" json:"hostDir"`
// EmptyDir represents a temporary directory that shares a pod's lifetime.
EmptyDir *EmptyDir `yaml:"emptyDir" json:"emptyDir"`
}

// HostDirectory represents bare host directory volume.
type HostDirectory struct {
// HostDir represents bare host directory volume.
type HostDir struct {
Path string `yaml:"path" json:"path"`
}

type EmptyDirectory struct{}
type EmptyDir struct{}

// Protocol defines network protocols supported for things like conatiner ports.
type Protocol string
Expand Down
14 changes: 7 additions & 7 deletions pkg/api/v1beta1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,22 +83,22 @@ type Volume struct {

type VolumeSource struct {
// Only one of the following sources may be specified
// HostDirectory represents a pre-existing directory on the host machine that is directly
// HostDir represents a pre-existing directory on the host machine that is directly
// exposed to the container. This is generally used for system agents or other privileged
// things that are allowed to see the host machine. Most containers will NOT need this.
// TODO(jonesdl) We need to restrict who can use host directory mounts and
// who can/can not mount host directories as read/write.
HostDirectory *HostDirectory `yaml:"hostDir" json:"hostDir"`
// EmptyDirectory represents a temporary directory that shares a pod's lifetime.
EmptyDirectory *EmptyDirectory `yaml:"emptyDir" json:"emptyDir"`
HostDir *HostDir `yaml:"hostDir" json:"hostDir"`
// EmptyDir represents a temporary directory that shares a pod's lifetime.
EmptyDir *EmptyDir `yaml:"emptyDir" json:"emptyDir"`
}

// HostDirectory represents bare host directory volume.
type HostDirectory struct {
// HostDir represents bare host directory volume.
type HostDir struct {
Path string `yaml:"path" json:"path"`
}

type EmptyDirectory struct{}
type EmptyDir struct{}

// Protocol defines network protocols supported for things like conatiner ports.
type Protocol string
Expand Down
14 changes: 7 additions & 7 deletions pkg/api/v1beta2/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,22 +83,22 @@ type Volume struct {

type VolumeSource struct {
// Only one of the following sources may be specified
// HostDirectory represents a pre-existing directory on the host machine that is directly
// HostDir represents a pre-existing directory on the host machine that is directly
// exposed to the container. This is generally used for system agents or other privileged
// things that are allowed to see the host machine. Most containers will NOT need this.
// TODO(jonesdl) We need to restrict who can use host directory mounts and
// who can/can not mount host directories as read/write.
HostDirectory *HostDirectory `yaml:"hostDir" json:"hostDir"`
// EmptyDirectory represents a temporary directory that shares a pod's lifetime.
EmptyDirectory *EmptyDirectory `yaml:"emptyDir" json:"emptyDir"`
HostDir *HostDir `yaml:"hostDir" json:"hostDir"`
// EmptyDir represents a temporary directory that shares a pod's lifetime.
EmptyDir *EmptyDir `yaml:"emptyDir" json:"emptyDir"`
}

// HostDirectory represents bare host directory volume.
type HostDirectory struct {
// HostDir represents bare host directory volume.
type HostDir struct {
Path string `yaml:"path" json:"path"`
}

type EmptyDirectory struct{}
type EmptyDir struct{}

// Protocol defines network protocols supported for things like conatiner ports.
type Protocol string
Expand Down
14 changes: 7 additions & 7 deletions pkg/api/v1beta3/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,22 +126,22 @@ type Volume struct {

type VolumeSource struct {
// Only one of the following sources may be specified
// HostDirectory represents a pre-existing directory on the host machine that is directly
// HostDir represents a pre-existing directory on the host machine that is directly
// exposed to the container. This is generally used for system agents or other privileged
// things that are allowed to see the host machine. Most containers will NOT need this.
// TODO(jonesdl) We need to restrict who can use host directory mounts and who can/can not
// mount host directories as read/write.
HostDirectory *HostDirectory `json:"hostDir" yaml:"hostDir"`
// EmptyDirectory represents a temporary directory that shares a pod's lifetime.
EmptyDirectory *EmptyDirectory `json:"emptyDir" yaml:"emptyDir"`
HostDir *HostDir `json:"hostDir" yaml:"hostDir"`
// EmptyDir represents a temporary directory that shares a pod's lifetime.
EmptyDir *EmptyDir `json:"emptyDir" yaml:"emptyDir"`
}

// HostDirectory represents bare host directory volume.
type HostDirectory struct {
// HostDir represents bare host directory volume.
type HostDir struct {
Path string `json:"path" yaml:"path"`
}

type EmptyDirectory struct{}
type EmptyDir struct{}

// Protocol defines network protocols supported for things like conatiner ports.
type Protocol string
Expand Down
8 changes: 4 additions & 4 deletions pkg/api/validation/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,11 @@ func validateVolumes(volumes []api.Volume) (util.StringSet, errs.ErrorList) {
func validateSource(source *api.VolumeSource) errs.ErrorList {
numVolumes := 0
allErrs := errs.ErrorList{}
if source.HostDirectory != nil {
if source.HostDir != nil {
numVolumes++
allErrs = append(allErrs, validateHostDir(source.HostDirectory).Prefix("hostDirectory")...)
allErrs = append(allErrs, validateHostDir(source.HostDir).Prefix("hostDirectory")...)
}
if source.EmptyDirectory != nil {
if source.EmptyDir != nil {
numVolumes++
//EmptyDirs have nothing to validate
}
Expand All @@ -70,7 +70,7 @@ func validateSource(source *api.VolumeSource) errs.ErrorList {
return allErrs
}

func validateHostDir(hostDir *api.HostDirectory) errs.ErrorList {
func validateHostDir(hostDir *api.HostDir) errs.ErrorList {
allErrs := errs.ErrorList{}
if hostDir.Path == "" {
allErrs = append(allErrs, errs.NewNotFound("path", hostDir.Path))
Expand Down
10 changes: 5 additions & 5 deletions pkg/api/validation/validation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ func expectPrefix(t *testing.T, prefix string, errs errors.ErrorList) {
func TestValidateVolumes(t *testing.T) {
successCase := []api.Volume{
{Name: "abc"},
{Name: "123", Source: &api.VolumeSource{HostDirectory: &api.HostDirectory{"/mnt/path2"}}},
{Name: "abc-123", Source: &api.VolumeSource{HostDirectory: &api.HostDirectory{"/mnt/path3"}}},
{Name: "empty", Source: &api.VolumeSource{EmptyDirectory: &api.EmptyDirectory{}}},
{Name: "123", Source: &api.VolumeSource{HostDir: &api.HostDir{"/mnt/path2"}}},
{Name: "abc-123", Source: &api.VolumeSource{HostDir: &api.HostDir{"/mnt/path3"}}},
{Name: "empty", Source: &api.VolumeSource{EmptyDir: &api.EmptyDir{}}},
}
names, errs := validateVolumes(successCase)
if len(errs) != 0 {
Expand Down Expand Up @@ -309,8 +309,8 @@ func TestValidateManifest(t *testing.T) {
{
Version: "v1beta1",
ID: "abc",
Volumes: []api.Volume{{Name: "vol1", Source: &api.VolumeSource{HostDirectory: &api.HostDirectory{"/mnt/vol1"}}},
{Name: "vol2", Source: &api.VolumeSource{HostDirectory: &api.HostDirectory{"/mnt/vol2"}}}},
Volumes: []api.Volume{{Name: "vol1", Source: &api.VolumeSource{HostDir: &api.HostDir{"/mnt/vol1"}}},
{Name: "vol2", Source: &api.VolumeSource{HostDir: &api.HostDir{"/mnt/vol2"}}}},
Containers: []api.Container{
{
Name: "abc",
Expand Down
10 changes: 5 additions & 5 deletions pkg/kubelet/kubelet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -581,14 +581,14 @@ func TestMountExternalVolumes(t *testing.T) {
{
Name: "host-dir",
Source: &api.VolumeSource{
HostDirectory: &api.HostDirectory{"/dir/path"},
HostDir: &api.HostDir{"/dir/path"},
},
},
},
}
podVolumes, _ := kubelet.mountExternalVolumes(&manifest)
expectedPodVolumes := make(volumeMap)
expectedPodVolumes["host-dir"] = &volume.HostDirectory{"/dir/path"}
expectedPodVolumes["host-dir"] = &volume.HostDir{"/dir/path"}
if len(expectedPodVolumes) != len(podVolumes) {
t.Errorf("Unexpected volumes. Expected %#v got %#v. Manifest was: %#v", expectedPodVolumes, podVolumes, manifest)
}
Expand Down Expand Up @@ -631,9 +631,9 @@ func TestMakeVolumesAndBinds(t *testing.T) {
}

podVolumes := volumeMap{
"disk": &volume.HostDirectory{"/mnt/disk"},
"disk4": &volume.HostDirectory{"/mnt/host"},
"disk5": &volume.EmptyDirectory{"disk5", "podID", "/var/lib/kubelet"},
"disk": &volume.HostDir{"/mnt/disk"},
"disk4": &volume.HostDir{"/mnt/host"},
"disk5": &volume.EmptyDir{"disk5", "podID", "/var/lib/kubelet"},
}

binds := makeBinds(&pod, &container, podVolumes)
Expand Down
42 changes: 21 additions & 21 deletions pkg/volume/volume.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,32 +49,32 @@ type Cleaner interface {
TearDown() error
}

// HostDirectory volumes represent a bare host directory mount.
// HostDir volumes represent a bare host directory mount.
// The directory in Path will be directly exposed to the container.
type HostDirectory struct {
type HostDir struct {
Path string
}

// SetUp implements interface definitions, even though host directory
// mounts don't require any setup or cleanup.
func (hostVol *HostDirectory) SetUp() error {
func (hostVol *HostDir) SetUp() error {
return nil
}

func (hostVol *HostDirectory) GetPath() string {
func (hostVol *HostDir) GetPath() string {
return hostVol.Path
}

// EmptyDirectory volumes are temporary directories exposed to the pod.
// EmptyDir volumes are temporary directories exposed to the pod.
// These do not persist beyond the lifetime of a pod.
type EmptyDirectory struct {
type EmptyDir struct {
Name string
PodID string
RootDir string
}

// SetUp creates new directory.
func (emptyDir *EmptyDirectory) SetUp() error {
func (emptyDir *EmptyDir) SetUp() error {
path := emptyDir.GetPath()
err := os.MkdirAll(path, 0750)
if err != nil {
Expand All @@ -83,11 +83,11 @@ func (emptyDir *EmptyDirectory) SetUp() error {
return nil
}

func (emptyDir *EmptyDirectory) GetPath() string {
func (emptyDir *EmptyDir) GetPath() string {
return path.Join(emptyDir.RootDir, emptyDir.PodID, "volumes", "empty", emptyDir.Name)
}

func (emptyDir *EmptyDirectory) renameDirectory() (string, error) {
func (emptyDir *EmptyDir) renameDirectory() (string, error) {
oldPath := emptyDir.GetPath()
newPath, err := ioutil.TempDir(path.Dir(oldPath), emptyDir.Name+".deleting~")
if err != nil {
Expand All @@ -101,7 +101,7 @@ func (emptyDir *EmptyDirectory) renameDirectory() (string, error) {
}

// TearDown simply deletes everything in the directory.
func (emptyDir *EmptyDirectory) TearDown() error {
func (emptyDir *EmptyDir) TearDown() error {
tmpDir, err := emptyDir.renameDirectory()
if err != nil {
return err
Expand All @@ -113,14 +113,14 @@ func (emptyDir *EmptyDirectory) TearDown() error {
return nil
}

// createHostDirectory interprets API volume as a HostDirectory.
func createHostDirectory(volume *api.Volume) *HostDirectory {
return &HostDirectory{volume.Source.HostDirectory.Path}
// createHostDir interprets API volume as a HostDir.
func createHostDir(volume *api.Volume) *HostDir {
return &HostDir{volume.Source.HostDir.Path}
}

// createEmptyDirectory interprets API volume as an EmptyDirectory.
func createEmptyDirectory(volume *api.Volume, podID string, rootDir string) *EmptyDirectory {
return &EmptyDirectory{volume.Name, podID, rootDir}
// createEmptyDir interprets API volume as an EmptyDir.
func createEmptyDir(volume *api.Volume, podID string, rootDir string) *EmptyDir {
return &EmptyDir{volume.Name, podID, rootDir}
}

// CreateVolumeBuilder returns a Builder capable of mounting a volume described by an
Expand All @@ -135,10 +135,10 @@ func CreateVolumeBuilder(volume *api.Volume, podID string, rootDir string) (Buil
var vol Builder
// TODO(jonesdl) We should probably not check every pointer and directly
// resolve these types instead.
if source.HostDirectory != nil {
vol = createHostDirectory(volume)
} else if source.EmptyDirectory != nil {
vol = createEmptyDirectory(volume, podID, rootDir)
if source.HostDir != nil {
vol = createHostDir(volume)
} else if source.EmptyDir != nil {
vol = createEmptyDir(volume, podID, rootDir)
} else {
return nil, ErrUnsupportedVolumeType
}
Expand All @@ -149,7 +149,7 @@ func CreateVolumeBuilder(volume *api.Volume, podID string, rootDir string) (Buil
func CreateVolumeCleaner(kind string, name string, podID string, rootDir string) (Cleaner, error) {
switch kind {
case "empty":
return &EmptyDirectory{name, podID, rootDir}, nil
return &EmptyDir{name, podID, rootDir}, nil
default:
return nil, ErrUnsupportedVolumeType
}
Expand Down
6 changes: 3 additions & 3 deletions pkg/volume/volume_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func TestCreateVolumeBuilders(t *testing.T) {
api.Volume{
Name: "host-dir",
Source: &api.VolumeSource{
HostDirectory: &api.HostDirectory{"/dir/path"},
HostDir: &api.HostDir{"/dir/path"},
},
},
"/dir/path",
Expand All @@ -52,7 +52,7 @@ func TestCreateVolumeBuilders(t *testing.T) {
api.Volume{
Name: "empty-dir",
Source: &api.VolumeSource{
EmptyDirectory: &api.EmptyDirectory{},
EmptyDir: &api.EmptyDir{},
},
},
path.Join(tempDir, "/my-id/volumes/empty/empty-dir"),
Expand All @@ -79,7 +79,7 @@ func TestCreateVolumeBuilders(t *testing.T) {
}
continue
}
if tt.volume.Source.HostDirectory == nil && tt.volume.Source.EmptyDirectory == nil {
if tt.volume.Source.HostDir == nil && tt.volume.Source.EmptyDir == nil {
if err != ErrUnsupportedVolumeType {
t.Errorf("Unexpected error: %v", err)
}
Expand Down