Merge pull request #20782 from nickschuch/readonly_container_2

Auto commit by PR queue bot
This commit is contained in:
k8s-merge-robot 2016-02-14 13:18:24 -08:00
commit 44d12a1389
18 changed files with 427 additions and 101 deletions

View File

@ -5635,6 +5635,10 @@
"runAsNonRoot": {
"type": "boolean",
"description": "Indicates that the container must run as a non-root user. If true, the Kubelet will validate the image at runtime to ensure that it does not run as UID 0 (root) and fail to start the container if it does. If unset or false, no such validation will be performed. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence."
},
"readOnlyRootFilesystem": {
"type": "boolean",
"description": "Whether this container has a read-only root filesystem. Default is false."
}
}
},

View File

@ -16030,6 +16030,10 @@
"runAsNonRoot": {
"type": "boolean",
"description": "Indicates that the container must run as a non-root user. If true, the Kubelet will validate the image at runtime to ensure that it does not run as UID 0 (root) and fail to start the container if it does. If unset or false, no such validation will be performed. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence."
},
"readOnlyRootFilesystem": {
"type": "boolean",
"description": "Whether this container has a read-only root filesystem. Default is false."
}
}
},

View File

@ -3114,6 +3114,13 @@ Populated by the system when a graceful deletion is requested. Read-only. More i
<td class="tableblock halign-left valign-top"><p class="tableblock">boolean</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">readOnlyRootFilesystem</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Whether this container has a read-only root filesystem. Default is false.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">boolean</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
</tr>
</tbody>
</table>
@ -5266,7 +5273,7 @@ Populated by the system when a graceful deletion is requested. Read-only. More i
</div>
<div id="footer">
<div id="footer-text">
Last updated 2016-02-14 04:20:10 UTC
Last updated 2016-02-14 05:38:57 UTC
</div>
</div>
</body>

View File

@ -5904,6 +5904,13 @@ The resulting set of endpoints can be viewed as:<br>
<td class="tableblock halign-left valign-top"><p class="tableblock">boolean</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">readOnlyRootFilesystem</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Whether this container has a read-only root filesystem. Default is false.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">boolean</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
</tr>
</tbody>
</table>
@ -7378,7 +7385,7 @@ The resulting set of endpoints can be viewed as:<br>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2016-02-14 04:20:03 UTC
Last updated 2016-02-14 05:38:48 UTC
</div>
</div>
</body>

View File

@ -2597,6 +2597,13 @@ func DeepCopy_api_SecurityContext(in SecurityContext, out *SecurityContext, c *c
} else {
out.RunAsNonRoot = nil
}
if in.ReadOnlyRootFilesystem != nil {
in, out := in.ReadOnlyRootFilesystem, &out.ReadOnlyRootFilesystem
*out = new(bool)
**out = *in
} else {
out.ReadOnlyRootFilesystem = nil
}
return nil
}

View File

@ -46664,7 +46664,7 @@ func (x *SecurityContext) CodecEncodeSelf(e *codec1978.Encoder) {
} else {
yysep2 := !z.EncBinary()
yy2arr2 := z.EncBasicHandle().StructToArray
var yyq2 [5]bool
var yyq2 [6]bool
_, _, _ = yysep2, yyq2, yy2arr2
const yyr2 bool = false
yyq2[0] = x.Capabilities != nil
@ -46672,9 +46672,10 @@ func (x *SecurityContext) CodecEncodeSelf(e *codec1978.Encoder) {
yyq2[2] = x.SELinuxOptions != nil
yyq2[3] = x.RunAsUser != nil
yyq2[4] = x.RunAsNonRoot != nil
yyq2[5] = x.ReadOnlyRootFilesystem != nil
var yynn2 int
if yyr2 || yy2arr2 {
r.EncodeArrayStart(5)
r.EncodeArrayStart(6)
} else {
yynn2 = 0
for _, b := range yyq2 {
@ -46836,6 +46837,41 @@ func (x *SecurityContext) CodecEncodeSelf(e *codec1978.Encoder) {
}
}
}
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayElem1234)
if yyq2[5] {
if x.ReadOnlyRootFilesystem == nil {
r.EncodeNil()
} else {
yy25 := *x.ReadOnlyRootFilesystem
yym26 := z.EncBinary()
_ = yym26
if false {
} else {
r.EncodeBool(bool(yy25))
}
}
} else {
r.EncodeNil()
}
} else {
if yyq2[5] {
z.EncSendContainerState(codecSelfer_containerMapKey1234)
r.EncodeString(codecSelferC_UTF81234, string("readOnlyRootFilesystem"))
z.EncSendContainerState(codecSelfer_containerMapValue1234)
if x.ReadOnlyRootFilesystem == nil {
r.EncodeNil()
} else {
yy27 := *x.ReadOnlyRootFilesystem
yym28 := z.EncBinary()
_ = yym28
if false {
} else {
r.EncodeBool(bool(yy27))
}
}
}
}
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayEnd1234)
} else {
@ -46967,6 +47003,22 @@ func (x *SecurityContext) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
*((*bool)(x.RunAsNonRoot)) = r.DecodeBool()
}
}
case "readOnlyRootFilesystem":
if r.TryDecodeAsNil() {
if x.ReadOnlyRootFilesystem != nil {
x.ReadOnlyRootFilesystem = nil
}
} else {
if x.ReadOnlyRootFilesystem == nil {
x.ReadOnlyRootFilesystem = new(bool)
}
yym13 := z.DecBinary()
_ = yym13
if false {
} else {
*((*bool)(x.ReadOnlyRootFilesystem)) = r.DecodeBool()
}
}
default:
z.DecStructFieldNotFound(-1, yys3)
} // end switch yys3
@ -46978,16 +47030,16 @@ func (x *SecurityContext) codecDecodeSelfFromArray(l int, d *codec1978.Decoder)
var h codecSelfer1234
z, r := codec1978.GenHelperDecoder(d)
_, _, _ = h, z, r
var yyj12 int
var yyb12 bool
var yyhl12 bool = l >= 0
yyj12++
if yyhl12 {
yyb12 = yyj12 > l
var yyj14 int
var yyb14 bool
var yyhl14 bool = l >= 0
yyj14++
if yyhl14 {
yyb14 = yyj14 > l
} else {
yyb12 = r.CheckBreak()
yyb14 = r.CheckBreak()
}
if yyb12 {
if yyb14 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
@ -47002,13 +47054,13 @@ func (x *SecurityContext) codecDecodeSelfFromArray(l int, d *codec1978.Decoder)
}
x.Capabilities.CodecDecodeSelf(d)
}
yyj12++
if yyhl12 {
yyb12 = yyj12 > l
yyj14++
if yyhl14 {
yyb14 = yyj14 > l
} else {
yyb12 = r.CheckBreak()
yyb14 = r.CheckBreak()
}
if yyb12 {
if yyb14 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
@ -47021,20 +47073,20 @@ func (x *SecurityContext) codecDecodeSelfFromArray(l int, d *codec1978.Decoder)
if x.Privileged == nil {
x.Privileged = new(bool)
}
yym15 := z.DecBinary()
_ = yym15
yym17 := z.DecBinary()
_ = yym17
if false {
} else {
*((*bool)(x.Privileged)) = r.DecodeBool()
}
}
yyj12++
if yyhl12 {
yyb12 = yyj12 > l
yyj14++
if yyhl14 {
yyb14 = yyj14 > l
} else {
yyb12 = r.CheckBreak()
yyb14 = r.CheckBreak()
}
if yyb12 {
if yyb14 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
@ -47049,13 +47101,13 @@ func (x *SecurityContext) codecDecodeSelfFromArray(l int, d *codec1978.Decoder)
}
x.SELinuxOptions.CodecDecodeSelf(d)
}
yyj12++
if yyhl12 {
yyb12 = yyj12 > l
yyj14++
if yyhl14 {
yyb14 = yyj14 > l
} else {
yyb12 = r.CheckBreak()
yyb14 = r.CheckBreak()
}
if yyb12 {
if yyb14 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
@ -47068,20 +47120,20 @@ func (x *SecurityContext) codecDecodeSelfFromArray(l int, d *codec1978.Decoder)
if x.RunAsUser == nil {
x.RunAsUser = new(int64)
}
yym18 := z.DecBinary()
_ = yym18
yym20 := z.DecBinary()
_ = yym20
if false {
} else {
*((*int64)(x.RunAsUser)) = int64(r.DecodeInt(64))
}
}
yyj12++
if yyhl12 {
yyb12 = yyj12 > l
yyj14++
if yyhl14 {
yyb14 = yyj14 > l
} else {
yyb12 = r.CheckBreak()
yyb14 = r.CheckBreak()
}
if yyb12 {
if yyb14 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
@ -47094,25 +47146,51 @@ func (x *SecurityContext) codecDecodeSelfFromArray(l int, d *codec1978.Decoder)
if x.RunAsNonRoot == nil {
x.RunAsNonRoot = new(bool)
}
yym20 := z.DecBinary()
_ = yym20
yym22 := z.DecBinary()
_ = yym22
if false {
} else {
*((*bool)(x.RunAsNonRoot)) = r.DecodeBool()
}
}
for {
yyj12++
if yyhl12 {
yyb12 = yyj12 > l
} else {
yyb12 = r.CheckBreak()
yyj14++
if yyhl14 {
yyb14 = yyj14 > l
} else {
yyb14 = r.CheckBreak()
}
if yyb14 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
if r.TryDecodeAsNil() {
if x.ReadOnlyRootFilesystem != nil {
x.ReadOnlyRootFilesystem = nil
}
if yyb12 {
} else {
if x.ReadOnlyRootFilesystem == nil {
x.ReadOnlyRootFilesystem = new(bool)
}
yym24 := z.DecBinary()
_ = yym24
if false {
} else {
*((*bool)(x.ReadOnlyRootFilesystem)) = r.DecodeBool()
}
}
for {
yyj14++
if yyhl14 {
yyb14 = yyj14 > l
} else {
yyb14 = r.CheckBreak()
}
if yyb14 {
break
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
z.DecStructFieldNotFound(yyj12-1, "")
z.DecStructFieldNotFound(yyj14-1, "")
}
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
}

View File

@ -2412,6 +2412,9 @@ type SecurityContext struct {
// May also be set in PodSecurityContext. If set in both SecurityContext and
// PodSecurityContext, the value specified in SecurityContext takes precedence.
RunAsNonRoot *bool `json:"runAsNonRoot,omitempty"`
// The read-only root filesystem allows you to restrict the locations that an application can write
// files to, ensuring the persistent data can only be written to mounts.
ReadOnlyRootFilesystem *bool `json:"readOnlyRootFilesystem,omitempty"`
}
// SELinuxOptions are the labels to be applied to the container.

View File

@ -2827,6 +2827,12 @@ func autoConvert_api_SecurityContext_To_v1_SecurityContext(in *api.SecurityConte
} else {
out.RunAsNonRoot = nil
}
if in.ReadOnlyRootFilesystem != nil {
out.ReadOnlyRootFilesystem = new(bool)
*out.ReadOnlyRootFilesystem = *in.ReadOnlyRootFilesystem
} else {
out.ReadOnlyRootFilesystem = nil
}
return nil
}
@ -5936,6 +5942,12 @@ func autoConvert_v1_SecurityContext_To_api_SecurityContext(in *SecurityContext,
} else {
out.RunAsNonRoot = nil
}
if in.ReadOnlyRootFilesystem != nil {
out.ReadOnlyRootFilesystem = new(bool)
*out.ReadOnlyRootFilesystem = *in.ReadOnlyRootFilesystem
} else {
out.ReadOnlyRootFilesystem = nil
}
return nil
}

View File

@ -2211,6 +2211,12 @@ func deepCopy_v1_SecurityContext(in SecurityContext, out *SecurityContext, c *co
} else {
out.RunAsNonRoot = nil
}
if in.ReadOnlyRootFilesystem != nil {
out.ReadOnlyRootFilesystem = new(bool)
*out.ReadOnlyRootFilesystem = *in.ReadOnlyRootFilesystem
} else {
out.ReadOnlyRootFilesystem = nil
}
return nil
}

View File

@ -46815,7 +46815,7 @@ func (x *SecurityContext) CodecEncodeSelf(e *codec1978.Encoder) {
} else {
yysep2 := !z.EncBinary()
yy2arr2 := z.EncBasicHandle().StructToArray
var yyq2 [5]bool
var yyq2 [6]bool
_, _, _ = yysep2, yyq2, yy2arr2
const yyr2 bool = false
yyq2[0] = x.Capabilities != nil
@ -46823,9 +46823,10 @@ func (x *SecurityContext) CodecEncodeSelf(e *codec1978.Encoder) {
yyq2[2] = x.SELinuxOptions != nil
yyq2[3] = x.RunAsUser != nil
yyq2[4] = x.RunAsNonRoot != nil
yyq2[5] = x.ReadOnlyRootFilesystem != nil
var yynn2 int
if yyr2 || yy2arr2 {
r.EncodeArrayStart(5)
r.EncodeArrayStart(6)
} else {
yynn2 = 0
for _, b := range yyq2 {
@ -46987,6 +46988,41 @@ func (x *SecurityContext) CodecEncodeSelf(e *codec1978.Encoder) {
}
}
}
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayElem1234)
if yyq2[5] {
if x.ReadOnlyRootFilesystem == nil {
r.EncodeNil()
} else {
yy25 := *x.ReadOnlyRootFilesystem
yym26 := z.EncBinary()
_ = yym26
if false {
} else {
r.EncodeBool(bool(yy25))
}
}
} else {
r.EncodeNil()
}
} else {
if yyq2[5] {
z.EncSendContainerState(codecSelfer_containerMapKey1234)
r.EncodeString(codecSelferC_UTF81234, string("readOnlyRootFilesystem"))
z.EncSendContainerState(codecSelfer_containerMapValue1234)
if x.ReadOnlyRootFilesystem == nil {
r.EncodeNil()
} else {
yy27 := *x.ReadOnlyRootFilesystem
yym28 := z.EncBinary()
_ = yym28
if false {
} else {
r.EncodeBool(bool(yy27))
}
}
}
}
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayEnd1234)
} else {
@ -47118,6 +47154,22 @@ func (x *SecurityContext) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
*((*bool)(x.RunAsNonRoot)) = r.DecodeBool()
}
}
case "readOnlyRootFilesystem":
if r.TryDecodeAsNil() {
if x.ReadOnlyRootFilesystem != nil {
x.ReadOnlyRootFilesystem = nil
}
} else {
if x.ReadOnlyRootFilesystem == nil {
x.ReadOnlyRootFilesystem = new(bool)
}
yym13 := z.DecBinary()
_ = yym13
if false {
} else {
*((*bool)(x.ReadOnlyRootFilesystem)) = r.DecodeBool()
}
}
default:
z.DecStructFieldNotFound(-1, yys3)
} // end switch yys3
@ -47129,16 +47181,16 @@ func (x *SecurityContext) codecDecodeSelfFromArray(l int, d *codec1978.Decoder)
var h codecSelfer1234
z, r := codec1978.GenHelperDecoder(d)
_, _, _ = h, z, r
var yyj12 int
var yyb12 bool
var yyhl12 bool = l >= 0
yyj12++
if yyhl12 {
yyb12 = yyj12 > l
var yyj14 int
var yyb14 bool
var yyhl14 bool = l >= 0
yyj14++
if yyhl14 {
yyb14 = yyj14 > l
} else {
yyb12 = r.CheckBreak()
yyb14 = r.CheckBreak()
}
if yyb12 {
if yyb14 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
@ -47153,13 +47205,13 @@ func (x *SecurityContext) codecDecodeSelfFromArray(l int, d *codec1978.Decoder)
}
x.Capabilities.CodecDecodeSelf(d)
}
yyj12++
if yyhl12 {
yyb12 = yyj12 > l
yyj14++
if yyhl14 {
yyb14 = yyj14 > l
} else {
yyb12 = r.CheckBreak()
yyb14 = r.CheckBreak()
}
if yyb12 {
if yyb14 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
@ -47172,20 +47224,20 @@ func (x *SecurityContext) codecDecodeSelfFromArray(l int, d *codec1978.Decoder)
if x.Privileged == nil {
x.Privileged = new(bool)
}
yym15 := z.DecBinary()
_ = yym15
yym17 := z.DecBinary()
_ = yym17
if false {
} else {
*((*bool)(x.Privileged)) = r.DecodeBool()
}
}
yyj12++
if yyhl12 {
yyb12 = yyj12 > l
yyj14++
if yyhl14 {
yyb14 = yyj14 > l
} else {
yyb12 = r.CheckBreak()
yyb14 = r.CheckBreak()
}
if yyb12 {
if yyb14 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
@ -47200,13 +47252,13 @@ func (x *SecurityContext) codecDecodeSelfFromArray(l int, d *codec1978.Decoder)
}
x.SELinuxOptions.CodecDecodeSelf(d)
}
yyj12++
if yyhl12 {
yyb12 = yyj12 > l
yyj14++
if yyhl14 {
yyb14 = yyj14 > l
} else {
yyb12 = r.CheckBreak()
yyb14 = r.CheckBreak()
}
if yyb12 {
if yyb14 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
@ -47219,20 +47271,20 @@ func (x *SecurityContext) codecDecodeSelfFromArray(l int, d *codec1978.Decoder)
if x.RunAsUser == nil {
x.RunAsUser = new(int64)
}
yym18 := z.DecBinary()
_ = yym18
yym20 := z.DecBinary()
_ = yym20
if false {
} else {
*((*int64)(x.RunAsUser)) = int64(r.DecodeInt(64))
}
}
yyj12++
if yyhl12 {
yyb12 = yyj12 > l
yyj14++
if yyhl14 {
yyb14 = yyj14 > l
} else {
yyb12 = r.CheckBreak()
yyb14 = r.CheckBreak()
}
if yyb12 {
if yyb14 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
@ -47245,25 +47297,51 @@ func (x *SecurityContext) codecDecodeSelfFromArray(l int, d *codec1978.Decoder)
if x.RunAsNonRoot == nil {
x.RunAsNonRoot = new(bool)
}
yym20 := z.DecBinary()
_ = yym20
yym22 := z.DecBinary()
_ = yym22
if false {
} else {
*((*bool)(x.RunAsNonRoot)) = r.DecodeBool()
}
}
for {
yyj12++
if yyhl12 {
yyb12 = yyj12 > l
} else {
yyb12 = r.CheckBreak()
yyj14++
if yyhl14 {
yyb14 = yyj14 > l
} else {
yyb14 = r.CheckBreak()
}
if yyb14 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
if r.TryDecodeAsNil() {
if x.ReadOnlyRootFilesystem != nil {
x.ReadOnlyRootFilesystem = nil
}
if yyb12 {
} else {
if x.ReadOnlyRootFilesystem == nil {
x.ReadOnlyRootFilesystem = new(bool)
}
yym24 := z.DecBinary()
_ = yym24
if false {
} else {
*((*bool)(x.ReadOnlyRootFilesystem)) = r.DecodeBool()
}
}
for {
yyj14++
if yyhl14 {
yyb14 = yyj14 > l
} else {
yyb14 = r.CheckBreak()
}
if yyb14 {
break
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
z.DecStructFieldNotFound(yyj12-1, "")
z.DecStructFieldNotFound(yyj14-1, "")
}
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
}

View File

@ -2844,6 +2844,9 @@ type SecurityContext struct {
// May also be set in PodSecurityContext. If set in both SecurityContext and
// PodSecurityContext, the value specified in SecurityContext takes precedence.
RunAsNonRoot *bool `json:"runAsNonRoot,omitempty"`
// Whether this container has a read-only root filesystem.
// Default is false.
ReadOnlyRootFilesystem *bool `json:"readOnlyRootFilesystem,omitempty"`
}
// SELinuxOptions are the labels to be applied to the container

View File

@ -1404,12 +1404,13 @@ func (SecretVolumeSource) SwaggerDoc() map[string]string {
}
var map_SecurityContext = map[string]string{
"": "SecurityContext holds security configuration that will be applied to a container. Some fields are present in both SecurityContext and PodSecurityContext. When both are set, the values in SecurityContext take precedence.",
"capabilities": "The capabilities to add/drop when running containers. Defaults to the default set of capabilities granted by the container runtime.",
"privileged": "Run container in privileged mode. Processes in privileged containers are essentially equivalent to root on the host. Defaults to false.",
"seLinuxOptions": "The SELinux context to be applied to the container. If unspecified, the container runtime will allocate a random SELinux context for each container. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence.",
"runAsUser": "The UID to run the entrypoint of the container process. Defaults to user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence.",
"runAsNonRoot": "Indicates that the container must run as a non-root user. If true, the Kubelet will validate the image at runtime to ensure that it does not run as UID 0 (root) and fail to start the container if it does. If unset or false, no such validation will be performed. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence.",
"": "SecurityContext holds security configuration that will be applied to a container. Some fields are present in both SecurityContext and PodSecurityContext. When both are set, the values in SecurityContext take precedence.",
"capabilities": "The capabilities to add/drop when running containers. Defaults to the default set of capabilities granted by the container runtime.",
"privileged": "Run container in privileged mode. Processes in privileged containers are essentially equivalent to root on the host. Defaults to false.",
"seLinuxOptions": "The SELinux context to be applied to the container. If unspecified, the container runtime will allocate a random SELinux context for each container. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence.",
"runAsUser": "The UID to run the entrypoint of the container process. Defaults to user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence.",
"runAsNonRoot": "Indicates that the container must run as a non-root user. If true, the Kubelet will validate the image at runtime to ensure that it does not run as UID 0 (root) and fail to start the container if it does. If unset or false, no such validation will be performed. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence.",
"readOnlyRootFilesystem": "Whether this container has a read-only root filesystem. Default is false.",
}
func (SecurityContext) SwaggerDoc() map[string]string {

View File

@ -1064,6 +1064,12 @@ func autoConvert_api_SecurityContext_To_v1_SecurityContext(in *api.SecurityConte
} else {
out.RunAsNonRoot = nil
}
if in.ReadOnlyRootFilesystem != nil {
out.ReadOnlyRootFilesystem = new(bool)
*out.ReadOnlyRootFilesystem = *in.ReadOnlyRootFilesystem
} else {
out.ReadOnlyRootFilesystem = nil
}
return nil
}
@ -2348,6 +2354,12 @@ func autoConvert_v1_SecurityContext_To_api_SecurityContext(in *v1.SecurityContex
} else {
out.RunAsNonRoot = nil
}
if in.ReadOnlyRootFilesystem != nil {
out.ReadOnlyRootFilesystem = new(bool)
*out.ReadOnlyRootFilesystem = *in.ReadOnlyRootFilesystem
} else {
out.ReadOnlyRootFilesystem = nil
}
return nil
}

View File

@ -809,6 +809,12 @@ func deepCopy_v1_SecurityContext(in v1.SecurityContext, out *v1.SecurityContext,
} else {
out.RunAsNonRoot = nil
}
if in.ReadOnlyRootFilesystem != nil {
out.ReadOnlyRootFilesystem = new(bool)
*out.ReadOnlyRootFilesystem = *in.ReadOnlyRootFilesystem
} else {
out.ReadOnlyRootFilesystem = nil
}
return nil
}

View File

@ -354,6 +354,8 @@ type RunContainerOptions struct {
DNSSearch []string
// The parent cgroup to pass to Docker
CgroupParent string
// The type of container rootfs
ReadOnly bool
}
// VolumeInfo contains information about the volume.

View File

@ -544,11 +544,12 @@ func (dm *DockerManager) runContainer(
}
hc := &docker.HostConfig{
Binds: binds,
NetworkMode: netMode,
IpcMode: ipcMode,
UTSMode: utsMode,
PidMode: pidMode,
Binds: binds,
NetworkMode: netMode,
IpcMode: ipcMode,
UTSMode: utsMode,
PidMode: pidMode,
ReadonlyRootfs: readOnlyRootFilesystem(container),
// Memory and CPU are set here for newer versions of Docker (1.6+).
Memory: memoryLimit,
MemorySwap: -1,
@ -815,6 +816,11 @@ func usesHostNetwork(pod *api.Pod) bool {
return pod.Spec.SecurityContext != nil && pod.Spec.SecurityContext.HostNetwork
}
// determine if the container root should be a read only filesystem.
func readOnlyRootFilesystem(container *api.Container) bool {
return container.SecurityContext != nil && container.SecurityContext.ReadOnlyRootFilesystem != nil && *container.SecurityContext.ReadOnlyRootFilesystem
}
// dockerVersion implementes kubecontainer.Version interface by implementing
// Compare() and String() (which is implemented by the underlying semver.Version)
// TODO: this code is the same as rktVersion and may make sense to be moved to

View File

@ -85,6 +85,53 @@ var _ = Describe("Kubelet", func() {
Expect(err).To(BeNil(), fmt.Sprintf("Error creating Pod %v", err))
})
})
Context("when scheduling a read only busybox container", func() {
It("it should return success", func() {
pod := &api.Pod{
ObjectMeta: api.ObjectMeta{
Name: "busybox",
Namespace: api.NamespaceDefault,
},
Spec: api.PodSpec{
// Force the Pod to schedule to the node without a scheduler running
NodeName: *nodeName,
// Don't restart the Pod since it is expected to exit
RestartPolicy: api.RestartPolicyNever,
Containers: []api.Container{
{
Image: "gcr.io/google_containers/busybox",
Name: "busybox",
Command: []string{"sh", "-c", "echo test > /file"},
SecurityContext: &api.SecurityContext{
ReadOnlyRootFilesystem: &isReadOnly,
},
},
},
},
}
_, err := cl.Pods(api.NamespaceDefault).Create(pod)
Expect(err).To(BeNil(), fmt.Sprintf("Error creating Pod %v", err))
})
It("it should not write to the root filesystem", func() {
Eventually(func() string {
rc, err := cl.Pods(api.NamespaceDefault).GetLogs("busybox", &api.PodLogOptions{}).Stream()
if err != nil {
return ""
}
defer rc.Close()
buf := new(bytes.Buffer)
buf.ReadFrom(rc)
return buf.String()
}, time.Second*30, time.Second*4).Should(Equal("sh: can't create /file: Read-only file system"))
})
It("it should be possible to delete", func() {
err := cl.Pods(api.NamespaceDefault).Delete("busybox", &api.DeleteOptions{})
Expect(err).To(BeNil(), fmt.Sprintf("Error creating Pod %v", err))
})
})
})
Describe("metrics api", func() {

View File

@ -161,3 +161,46 @@ func TestPodUpdateActiveDeadlineSeconds(t *testing.T) {
deletePodOrErrorf(t, client, ns, pod.Name)
}
}
func TestPodReadOnlyFilesystem(t *testing.T) {
var m *master.Master
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
m.Handler.ServeHTTP(w, req)
}))
// TODO: Uncomment when fix #19254
// defer s.Close()
isReadOnly := true
ns := "pod-readonly-root"
masterConfig := framework.NewIntegrationTestMasterConfig()
m, err := master.New(masterConfig)
if err != nil {
t.Fatalf("Error in bringing up the master: %v", err)
}
framework.DeleteAllEtcdKeys()
client := client.NewOrDie(&client.Config{Host: s.URL, ContentConfig: client.ContentConfig{GroupVersion: testapi.Default.GroupVersion()}})
pod := &api.Pod{
ObjectMeta: api.ObjectMeta{
Name: "XXX",
},
Spec: api.PodSpec{
Containers: []api.Container{
{
Name: "fake-name",
Image: "fakeimage",
SecurityContext: &api.SecurityContext{
ReadOnlyRootFilesystem: &isReadOnly,
},
},
},
},
}
if _, err := client.Pods(ns).Create(pod); err != nil {
t.Errorf("Failed to create pod: %v", err)
}
deletePodOrErrorf(t, client, ns, pod.Name)
}