mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-10 12:32:03 +00:00
Implement mount propagation in docker shim
This commit is contained in:
parent
9a7465a4e2
commit
0c767355d8
@ -124,29 +124,40 @@ func extractLabels(input map[string]string) (map[string]string, map[string]strin
|
|||||||
|
|
||||||
// generateMountBindings converts the mount list to a list of strings that
|
// generateMountBindings converts the mount list to a list of strings that
|
||||||
// can be understood by docker.
|
// can be understood by docker.
|
||||||
// Each element in the string is in the form of:
|
// '<HostPath>:<ContainerPath>[:options]', where 'options'
|
||||||
// '<HostPath>:<ContainerPath>', or
|
// is a comma-separated list of the following strings:
|
||||||
// '<HostPath>:<ContainerPath>:ro', if the path is read only, or
|
// 'ro', if the path is read only
|
||||||
// '<HostPath>:<ContainerPath>:Z', if the volume requires SELinux
|
// 'Z', if the volume requires SELinux relabeling
|
||||||
// relabeling and the pod provides an SELinux label
|
// propagation mode such as 'rslave'
|
||||||
func generateMountBindings(mounts []*runtimeapi.Mount) []string {
|
func generateMountBindings(mounts []*runtimeapi.Mount) []string {
|
||||||
result := make([]string, 0, len(mounts))
|
result := make([]string, 0, len(mounts))
|
||||||
for _, m := range mounts {
|
for _, m := range mounts {
|
||||||
bind := fmt.Sprintf("%s:%s", m.HostPath, m.ContainerPath)
|
bind := fmt.Sprintf("%s:%s", m.HostPath, m.ContainerPath)
|
||||||
readOnly := m.Readonly
|
var attrs []string
|
||||||
if readOnly {
|
if m.Readonly {
|
||||||
bind += ":ro"
|
attrs = append(attrs, "ro")
|
||||||
}
|
}
|
||||||
// Only request relabeling if the pod provides an SELinux context. If the pod
|
// Only request relabeling if the pod provides an SELinux context. If the pod
|
||||||
// does not provide an SELinux context relabeling will label the volume with
|
// does not provide an SELinux context relabeling will label the volume with
|
||||||
// the container's randomly allocated MCS label. This would restrict access
|
// the container's randomly allocated MCS label. This would restrict access
|
||||||
// to the volume to the container which mounts it first.
|
// to the volume to the container which mounts it first.
|
||||||
if m.SelinuxRelabel {
|
if m.SelinuxRelabel {
|
||||||
if readOnly {
|
attrs = append(attrs, "Z")
|
||||||
bind += ",Z"
|
}
|
||||||
} else {
|
switch m.Propagation {
|
||||||
bind += ":Z"
|
case runtimeapi.MountPropagation_PROPAGATION_PRIVATE:
|
||||||
}
|
// noop, private is default
|
||||||
|
case runtimeapi.MountPropagation_PROPAGATION_BIDIRECTIONAL:
|
||||||
|
attrs = append(attrs, "rshared")
|
||||||
|
case runtimeapi.MountPropagation_PROPAGATION_HOST_TO_CONTAINER:
|
||||||
|
attrs = append(attrs, "rslave")
|
||||||
|
default:
|
||||||
|
glog.Warningf("unknown propagation mode for hostPath %q", m.HostPath)
|
||||||
|
// Falls back to "private"
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(attrs) > 0 {
|
||||||
|
bind = fmt.Sprintf("%s:%s", bind, strings.Join(attrs, ","))
|
||||||
}
|
}
|
||||||
result = append(result, bind)
|
result = append(result, bind)
|
||||||
}
|
}
|
||||||
|
@ -323,3 +323,70 @@ func TestMakePortsAndBindings(t *testing.T) {
|
|||||||
assert.Equal(t, test.portmappings, actualPortMappings)
|
assert.Equal(t, test.portmappings, actualPortMappings)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGenerateMountBindings(t *testing.T) {
|
||||||
|
mounts := []*runtimeapi.Mount{
|
||||||
|
// everything default
|
||||||
|
{
|
||||||
|
HostPath: "/mnt/1",
|
||||||
|
ContainerPath: "/var/lib/mysql/1",
|
||||||
|
},
|
||||||
|
// readOnly
|
||||||
|
{
|
||||||
|
HostPath: "/mnt/2",
|
||||||
|
ContainerPath: "/var/lib/mysql/2",
|
||||||
|
Readonly: true,
|
||||||
|
},
|
||||||
|
// SELinux
|
||||||
|
{
|
||||||
|
HostPath: "/mnt/3",
|
||||||
|
ContainerPath: "/var/lib/mysql/3",
|
||||||
|
SelinuxRelabel: true,
|
||||||
|
},
|
||||||
|
// Propagation private
|
||||||
|
{
|
||||||
|
HostPath: "/mnt/4",
|
||||||
|
ContainerPath: "/var/lib/mysql/4",
|
||||||
|
Propagation: runtimeapi.MountPropagation_PROPAGATION_PRIVATE,
|
||||||
|
},
|
||||||
|
// Propagation rslave
|
||||||
|
{
|
||||||
|
HostPath: "/mnt/5",
|
||||||
|
ContainerPath: "/var/lib/mysql/5",
|
||||||
|
Propagation: runtimeapi.MountPropagation_PROPAGATION_HOST_TO_CONTAINER,
|
||||||
|
},
|
||||||
|
// Propagation rshared
|
||||||
|
{
|
||||||
|
HostPath: "/mnt/6",
|
||||||
|
ContainerPath: "/var/lib/mysql/6",
|
||||||
|
Propagation: runtimeapi.MountPropagation_PROPAGATION_BIDIRECTIONAL,
|
||||||
|
},
|
||||||
|
// Propagation unknown (falls back to private)
|
||||||
|
{
|
||||||
|
HostPath: "/mnt/7",
|
||||||
|
ContainerPath: "/var/lib/mysql/7",
|
||||||
|
Propagation: runtimeapi.MountPropagation(42),
|
||||||
|
},
|
||||||
|
// Everything
|
||||||
|
{
|
||||||
|
HostPath: "/mnt/8",
|
||||||
|
ContainerPath: "/var/lib/mysql/8",
|
||||||
|
Readonly: true,
|
||||||
|
SelinuxRelabel: true,
|
||||||
|
Propagation: runtimeapi.MountPropagation_PROPAGATION_BIDIRECTIONAL,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
expectedResult := []string{
|
||||||
|
"/mnt/1:/var/lib/mysql/1",
|
||||||
|
"/mnt/2:/var/lib/mysql/2:ro",
|
||||||
|
"/mnt/3:/var/lib/mysql/3:Z",
|
||||||
|
"/mnt/4:/var/lib/mysql/4",
|
||||||
|
"/mnt/5:/var/lib/mysql/5:rslave",
|
||||||
|
"/mnt/6:/var/lib/mysql/6:rshared",
|
||||||
|
"/mnt/7:/var/lib/mysql/7",
|
||||||
|
"/mnt/8:/var/lib/mysql/8:ro,Z,rshared",
|
||||||
|
}
|
||||||
|
result := generateMountBindings(mounts)
|
||||||
|
|
||||||
|
assert.Equal(t, result, expectedResult)
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user