Skip to content

Commit cee6c71

Browse files
authored
Merge pull request #30366 from aravindhp/windows-projected-volume
storage: document Windows projected volume limitations
2 parents 490e286 + 4c296c6 commit cee6c71

File tree

5 files changed

+207
-137
lines changed

5 files changed

+207
-137
lines changed
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
---
2+
reviewers:
3+
- sftim
4+
- marosset
5+
- jsturtevant
6+
- zshihang
7+
title: Projected Volumes
8+
content_type: concept
9+
---
10+
11+
<!-- overview -->
12+
13+
This document describes the current state of _projected volumes_ in Kubernetes. Familiarity with [volumes](/docs/concepts/storage/volumes/) is suggested.
14+
15+
<!-- body -->
16+
17+
## Introduction
18+
19+
A `projected` volume maps several existing volume sources into the same directory.
20+
21+
Currently, the following types of volume sources can be projected:
22+
23+
* [`secret`](/docs/concepts/storage/volumes/#secret)
24+
* [`downwardAPI`](/docs/concepts/storage/volumes/#downwardapi)
25+
* [`configMap`](/docs/concepts/storage/volumes/#configmap)
26+
* `serviceAccountToken`
27+
28+
All sources are required to be in the same namespace as the Pod. For more details,
29+
see the [all-in-one volume design document](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/node/all-in-one-volume.md).
30+
31+
### Example configuration with a secret, a downwardAPI, and a configMap {#example-configuration-secret-downwardapi-configmap}
32+
33+
{{< codenew file="pods/storage/projected-secret-downwardapi-configmap.yaml" >}}
34+
35+
### Example configuration: secrets with a non-default permission mode set {#example-configuration-secrets-nondefault-permission-mode}
36+
37+
{{< codenew file="pods/storage/projected-secrets-nondefault-permission-mode.yaml" >}}
38+
39+
Each projected volume source is listed in the spec under `sources`. The
40+
parameters are nearly the same with two exceptions:
41+
42+
* For secrets, the `secretName` field has been changed to `name` to be consistent
43+
with ConfigMap naming.
44+
* The `defaultMode` can only be specified at the projected level and not for each
45+
volume source. However, as illustrated above, you can explicitly set the `mode`
46+
for each individual projection.
47+
48+
When the `TokenRequestProjection` feature is enabled, you can inject the token
49+
for the current [service account](/docs/reference/access-authn-authz/authentication/#service-account-tokens)
50+
into a Pod at a specified path. For example:
51+
52+
{{< codenew file="pods/storage/projected-service-account-token.yaml" >}}
53+
54+
The example Pod has a projected volume containing the injected service account
55+
token. This token can be used by a Pod's containers to access the Kubernetes API
56+
server. The `audience` field contains the intended audience of the
57+
token. A recipient of the token must identify itself with an identifier specified
58+
in the audience of the token, and otherwise should reject the token. This field
59+
is optional and it defaults to the identifier of the API server.
60+
61+
The `expirationSeconds` is the expected duration of validity of the service account
62+
token. It defaults to 1 hour and must be at least 10 minutes (600 seconds). An administrator
63+
can also limit its maximum value by specifying the `--service-account-max-token-expiration`
64+
option for the API server. The `path` field specifies a relative path to the mount point
65+
of the projected volume.
66+
67+
{{< note >}}
68+
A container using a projected volume source as a [`subPath`](/docs/concepts/storage/volumes/#using-subpath)
69+
volume mount will not receive updates for those volume sources.
70+
{{< /note >}}
71+
72+
## SecurityContext interactions
73+
74+
The [proposal for file permission handling in projected service account volume](https://github.com/kubernetes/enhancements/pull/1598)
75+
enhancement introduced the projected files having the the correct owner
76+
permissions set.
77+
78+
### Linux
79+
80+
In Linux pods that have a projected volume and `RunAsUser` set in the Pod
81+
[`SecurityContext`](/docs/reference/kubernetes-api/workload-resources/pod-v1/#security-context),
82+
the projected files have the correct ownership set including container user
83+
ownership.
84+
85+
### Windows
86+
87+
In Windows pods that have a projected volume and `RunAsUsername` set in the
88+
Pod `SecurityContext`, the ownership is not enforced due to the way user
89+
accounts are managed in Windows. Windows stores and manages local user and group
90+
accounts in a database file called Security Account Manager (SAM). Each
91+
container maintains its own instance of the SAM database, to which the host has
92+
no visibility into while the container is running. Windows containers are
93+
designed to run the user mode portion of the OS in isolation from the host,
94+
hence the maintenance of a virtual SAM database. As a result, the kubelet running
95+
on the host does not have the ability to dynamically configure host file
96+
ownership for virtualized container accounts. It is recommended that if files on
97+
the host machine are to be shared with the container then they should be placed
98+
into their own volume mount outside of `C:\`.
99+
100+
By default, the projected files will have the following ownership as shown for
101+
an example projected volume file:
102+
```powershell
103+
Path : Microsoft.PowerShell.Core\FileSystem::C:\var\run\secrets\kubernetes.io\serviceaccount\..2021_08_31_22_22_18.318230061\ca.crt
104+
Owner : BUILTIN\Administrators
105+
Group : NT AUTHORITY\SYSTEM
106+
Access : NT AUTHORITY\SYSTEM Allow FullControl
107+
BUILTIN\Administrators Allow FullControl
108+
BUILTIN\Users Allow ReadAndExecute, Synchronize
109+
Audit :
110+
Sddl : O:BAG:SYD:AI(A;ID;FA;;;SY)(A;ID;FA;;;BA)(A;ID;0x1200a9;;;BU)
111+
```
112+
This implies all administrator users like `ContainerAdministrator` will have
113+
read, write and execute access while, non-administrator users will have read and
114+
execute access.
115+
116+
{{< note >}}
117+
In general, granting the container access to the host is discouraged as it can
118+
open the door for potential security exploits.
119+
120+
Creating a Windows Pod with `RunAsUser` in it's `SecurityContext` will result in
121+
the Pod being stuck at `ContainerCreating` forever. So it is advised to not use
122+
the Linux only `RunAsUser` option with Windows Pods.
123+
{{< /note >}}

content/en/docs/concepts/storage/volumes.md

Lines changed: 2 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -810,143 +810,8 @@ For more details, see the [Portworx volume](https://github.com/kubernetes/exampl
810810

811811
### projected
812812

813-
A `projected` volume maps several existing volume sources into the same directory.
814-
815-
Currently, the following types of volume sources can be projected:
816-
817-
* [`secret`](#secret)
818-
* [`downwardAPI`](#downwardapi)
819-
* [`configMap`](#configmap)
820-
* `serviceAccountToken`
821-
822-
All sources are required to be in the same namespace as the Pod. For more details,
823-
see the [all-in-one volume design document](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/node/all-in-one-volume.md).
824-
825-
#### Example configuration with a secret, a downwardAPI, and a configMap {#example-configuration-secret-downwardapi-configmap}
826-
827-
```yaml
828-
apiVersion: v1
829-
kind: Pod
830-
metadata:
831-
name: volume-test
832-
spec:
833-
containers:
834-
- name: container-test
835-
image: busybox
836-
volumeMounts:
837-
- name: all-in-one
838-
mountPath: "/projected-volume"
839-
readOnly: true
840-
volumes:
841-
- name: all-in-one
842-
projected:
843-
sources:
844-
- secret:
845-
name: mysecret
846-
items:
847-
- key: username
848-
path: my-group/my-username
849-
- downwardAPI:
850-
items:
851-
- path: "labels"
852-
fieldRef:
853-
fieldPath: metadata.labels
854-
- path: "cpu_limit"
855-
resourceFieldRef:
856-
containerName: container-test
857-
resource: limits.cpu
858-
- configMap:
859-
name: myconfigmap
860-
items:
861-
- key: config
862-
path: my-group/my-config
863-
```
864-
865-
#### Example configuration: secrets with a non-default permission mode set {#example-configuration-secrets-nondefault-permission-mode}
866-
867-
```yaml
868-
apiVersion: v1
869-
kind: Pod
870-
metadata:
871-
name: volume-test
872-
spec:
873-
containers:
874-
- name: container-test
875-
image: busybox
876-
volumeMounts:
877-
- name: all-in-one
878-
mountPath: "/projected-volume"
879-
readOnly: true
880-
volumes:
881-
- name: all-in-one
882-
projected:
883-
sources:
884-
- secret:
885-
name: mysecret
886-
items:
887-
- key: username
888-
path: my-group/my-username
889-
- secret:
890-
name: mysecret2
891-
items:
892-
- key: password
893-
path: my-group/my-password
894-
mode: 511
895-
```
896-
897-
Each projected volume source is listed in the spec under `sources`. The
898-
parameters are nearly the same with two exceptions:
899-
900-
* For secrets, the `secretName` field has been changed to `name` to be consistent
901-
with ConfigMap naming.
902-
* The `defaultMode` can only be specified at the projected level and not for each
903-
volume source. However, as illustrated above, you can explicitly set the `mode`
904-
for each individual projection.
905-
906-
When the `TokenRequestProjection` feature is enabled, you can inject the token
907-
for the current [service account](/docs/reference/access-authn-authz/authentication/#service-account-tokens)
908-
into a Pod at a specified path. For example:
909-
910-
```yaml
911-
apiVersion: v1
912-
kind: Pod
913-
metadata:
914-
name: sa-token-test
915-
spec:
916-
containers:
917-
- name: container-test
918-
image: busybox
919-
volumeMounts:
920-
- name: token-vol
921-
mountPath: "/service-account"
922-
readOnly: true
923-
volumes:
924-
- name: token-vol
925-
projected:
926-
sources:
927-
- serviceAccountToken:
928-
audience: api
929-
expirationSeconds: 3600
930-
path: token
931-
```
932-
933-
The example Pod has a projected volume containing the injected service account
934-
token. This token can be used by a Pod's containers to access the Kubernetes API
935-
server. The `audience` field contains the intended audience of the
936-
token. A recipient of the token must identify itself with an identifier specified
937-
in the audience of the token, and otherwise should reject the token. This field
938-
is optional and it defaults to the identifier of the API server.
939-
940-
The `expirationSeconds` is the expected duration of validity of the service account
941-
token. It defaults to 1 hour and must be at least 10 minutes (600 seconds). An administrator
942-
can also limit its maximum value by specifying the `--service-account-max-token-expiration`
943-
option for the API server. The `path` field specifies a relative path to the mount point
944-
of the projected volume.
945-
946-
{{< note >}}
947-
A container using a projected volume source as a [`subPath`](#using-subpath) volume mount will not
948-
receive updates for those volume sources.
949-
{{< /note >}}
813+
A projected volume maps several existing volume sources into the same
814+
directory. For more details, see [projected volumes](/docs/concepts/storage/projected-volumes/)
950815

951816
### quobyte (deprecated) {#quobyte}
952817

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
apiVersion: v1
2+
kind: Pod
3+
metadata:
4+
name: volume-test
5+
spec:
6+
containers:
7+
- name: container-test
8+
image: busybox
9+
volumeMounts:
10+
- name: all-in-one
11+
mountPath: "/projected-volume"
12+
readOnly: true
13+
volumes:
14+
- name: all-in-one
15+
projected:
16+
sources:
17+
- secret:
18+
name: mysecret
19+
items:
20+
- key: username
21+
path: my-group/my-username
22+
- downwardAPI:
23+
items:
24+
- path: "labels"
25+
fieldRef:
26+
fieldPath: metadata.labels
27+
- path: "cpu_limit"
28+
resourceFieldRef:
29+
containerName: container-test
30+
resource: limits.cpu
31+
- configMap:
32+
name: myconfigmap
33+
items:
34+
- key: config
35+
path: my-group/my-config
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
apiVersion: v1
2+
kind: Pod
3+
metadata:
4+
name: volume-test
5+
spec:
6+
containers:
7+
- name: container-test
8+
image: busybox
9+
volumeMounts:
10+
- name: all-in-one
11+
mountPath: "/projected-volume"
12+
readOnly: true
13+
volumes:
14+
- name: all-in-one
15+
projected:
16+
sources:
17+
- secret:
18+
name: mysecret
19+
items:
20+
- key: username
21+
path: my-group/my-username
22+
- secret:
23+
name: mysecret2
24+
items:
25+
- key: password
26+
path: my-group/my-password
27+
mode: 511
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
apiVersion: v1
2+
kind: Pod
3+
metadata:
4+
name: sa-token-test
5+
spec:
6+
containers:
7+
- name: container-test
8+
image: busybox
9+
volumeMounts:
10+
- name: token-vol
11+
mountPath: "/service-account"
12+
readOnly: true
13+
volumes:
14+
- name: token-vol
15+
projected:
16+
sources:
17+
- serviceAccountToken:
18+
audience: api
19+
expirationSeconds: 3600
20+
path: token

0 commit comments

Comments
 (0)