Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Documentation for Windows GMSA feature #12936

Merged
merged 17 commits into from
Mar 16, 2019
Merged
Show file tree
Hide file tree
Changes from 8 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
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ different Kubernetes components.
| `VolumeSnapshotDataSource` | `false` | Alpha | 1.12 | - |
| `ScheduleDaemonSetPods` | `false` | Alpha | 1.11 | 1.11 |
| `ScheduleDaemonSetPods` | `true` | Beta | 1.12 | |
| `WindowsGMSA` | `false` | Alpha | 1.14 | |

## Using a Feature

Expand Down Expand Up @@ -311,5 +312,6 @@ Each feature gate is designed for enabling/disabling a specific feature:
type when used together with the `PersistentLocalVolumes` feature gate.
- `VolumeSnapshotDataSource`: Enable volume snapshot data source support.
- `VolumeSubpathEnvExpansion`: Enable `subPathExpr` field for expanding environment variables into a `subPath`.
- `WindowsGMSA`: Enables passing of GMSA credential specs from pods to container runtimes.

{{% /capture %}}
302 changes: 302 additions & 0 deletions content/en/docs/tasks/configure-pod-container/configure-gmsa.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,302 @@
---
title: Configure GMSA for Windows pods and containers
content_template: templates/task
weight: 20
---

{{% capture overview %}}

{{< feature-state for_k8s_version="v1.14" state="alpha" >}}

This page shows how to configure [Group Managed Service Accounts](https://docs.microsoft.com/en-us/windows-server/security/group-managed-service-accounts/group-managed-service-accounts-overview) (GMSA) for pods and containers that will run on Windows nodes. Group Managed Service Accounts are a specific type of Active Directory account that provides automatic password management, simplified service principal name (SPN) management, and the ability to delegate the management to other administrators across multiple servers.

In Kubernetes, GMSA credential specs are configured at a Kubernetes cluster-wide scope as custom resources. Windows pods, as well as individual containers within a pod, can be configured to use a GMSA for domain based functions (e.g. Kerberos authentication) when interacting with other Windows services. As of v1.14, the only container runtime interface that supports GMSA for Windows workloads is Dockershim. Implementation of GMSA through CRI and other runtimes is planned for the future.

{{< note >}}
Currently this feature is in alpha state. While the overall goals and functionality will not change, the way in which the GMSA credspec references are specified in pod specs may change from annotations to a API fields. Please take this into consideration when testing or adopting this feature.
{{< /note >}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to a API fields has an extra "a"


{{% /capture %}}

{{% capture body %}}

## Setup and configuration for GMSA
Configuring GMSA credential specs in the cluster and configuring individual pods and containers to be able to use them requires several steps described in details below:
1. Enable the `WindowsGMSA` feature gate on kubelet on Windows nodes.
2. Install the GMSACredentialSpec CRD
3. Create GMSA credential spec resources
4. Install webhooks to expand and validate references to GMSA credential spec resources from pod specs
5. Create cluster roles to allow service accounts to use specific GMSA credential spec resources
6. Bind roles to specific service accounts to allow them to use GMSA credential spec resources
7. Configure pods to use GMSA credential specs along with a service account authorized to use the GMSA credential specs
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be nice to point out that steps 1, 2 and 4 are one-time operations, whereas the other ones have to be repeated for every deployment using GMSAs?

And actually, since it does say "must be taken in order", might it be worth separating:

To enable GMSA support on your cluster, there are 3 one-time steps to perform:
1. Enable the `WindowsGMSA` feature gate on kubelet on the Windows nodes you'll use to run GMSA-dependent workloads.
2. Install the GMSACredentialSpec Custom Resource Definition (aka CRD).
3. Install the GMSA admission webhooks.

Then, for each deployment using GMSA credentials, you'll need to:
1. Create the relevant GMSA credential spec resource
2. Create an RBAC role to allow your deployment's service account to `use` that GMSA resource, and bind your deployment's service account to that role 
3. Configure pods to use that GMSA credential spec

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with this. I will make a PR tonight to address this.


Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

details should be "described in detail below"

### Enable the WindowsGMSA feature gate
In the alpha state, the `WindowsGMSA` feature gate needs to be enabled on kubelet on Windows nodes. This is required to pass down the GMSA credential specs from the cluster scoped configurations to the container runtime. See [Feature Gates](https://kubernetes.io/docs/reference/command-line-tools-reference/feature-gates/) for an explanation of enabling feature gates. Please make sure `--feature-gates=WindowsGMSA=true` parameter exists in the kubelet.exe command line.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be worth mentioning that if they use Microsoft's SDN repo (which I suspect is the "canonical" way to use k8s on win as of now?), then they can now pass a -KubeletFeatureGates flag to the start.ps1 script from there.

Copy link
Member Author

@ddebroy ddebroy Mar 14, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May be a section can be added to the docs for https://github.com/Microsoft/SDN to make users aware of WindowsGMSA and point to the docs here for further details? I would prefer not to point to external repos/specific external tools that are in completely separate orgs beyond Kubernetes/Kubernetes-sigs from here if possible.

I think cluster admins deploying Kubernetes should be able to use the deployment tools of their choice and map Kubernetes concepts like feature gates to the published mechanism for specifying the same for their deployment tools/scripts.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍


### Install the GMSACredentialSpec CRD
A [CustomResourceDefinition](https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/) (CRD) for GMSA credential spec resources needs to be configured on the cluster to define the custom resource type `GMSACredentialSpec`. Download the GMSA CRD [YAML](https://github.com/kubernetes-sigs/windows-gmsa/blob/master/admission-webhook/deploy/gmsa-webhook.yml.tpl#L131-L148) and save it as gmsa-crd.yaml.
Next, install the CRD with `kubectl apply -f gmsa-crd.yaml`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


### Create GMSA credspec resources
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment above, but I really do think it would be good to cleanly separate "one-time" operations from steps needed for each GMSA deployment afterwards (this would belong to the latter).

With the GMSACredentialSpec CRD installed, GMSA credspec custom resources can now be configured. The GMSA credential spec does not contain secret or sensitive data. It is information that a container runtime can use to describe the desired GMSA of a container to Windows. The GMSA credspec resources can be generated in JSON format with a utility [PowerShell][] script. Following are the steps for generating a GMSA credspec YAML based on the JSON:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[PowerShell][] script => link missing?

1. Import the CredentialSpec module: `ipmo CredentialSpec.psm1`
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be worth reminding readers where to get that one? And also to add their worker nodes to the right GMSA groups?

2. Create a credential spec in JSON format using `New-CredentialSpec`. To create a GMSA credspec named WebApp1: `New-CredentialSpec -Name WebApp1 -AccountName WebApp1 -Domain $(Get-ADDomain -Current LocalComputer)`
3. Use `Get-CredentialSpec` to show the path of the JSON file.
4. Convert the credspec file from JSON to YAML format and apply the necessary header fields `apiVersion`, `kind`, `metadata` and `credspec` to make it a GMSACredentialSpec custom resource. An example based on a GMSA credspec named WebApp1 is below:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could package that in a nice powershell script, or even better add it to the CredentialSpec.psm1 module. Happy to do it if you think that's a good idea?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree it would be good to have that PS module give you the option of YAML output.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Definitely a good idea @wk8 . Can you add it to https://github.com/kubernetes-sigs/windows-gmsa?


```
apiVersion: windows.k8s.io/v1alpha1
kind: GMSACredentialSpec
metadata:
name: gmsa-WebApp1 #This is an arbitrary name but it will be used as a reference
credspec:
ActiveDirectoryConfig:
GroupManagedServiceAccounts:
- Name: WebApp1 #Username of the GMSA account
Scope: CONTOSO #NETBIOS Domain Name
- Name: WebApp1 #Username of the GMSA account
Scope: contoso.com #DNS Domain Name
CmsPlugins:
- ActiveDirectory
DomainJoinConfig:
DnsName: contoso.com #DNS Domain Name
DnsTreeName: contoso.com #DNS Domain Name Root
Guid: 244818ae-87ac-4fcd-92ec-e79e5252348a #GUID
MachineAccountName: WebApp1 #Username of the GMSA account
NetBiosName: CONTOSO #NETBIOS Domain Name
Sid: S-1-5-21-2126449477-2524075714-3094792973 #SID of GMSA
```

5. Deploy the credential spec resource: `kubectl apply -f gmsa-Webapp1-credspec.yml`

[PowerShell]: https://github.com/MicrosoftDocs/Virtualization-Documentation/blob/live/windows-server-container-tools/ServiceAccounts/CredentialSpec.psm1

### Install Webhooks for GMSA
Two webhooks need to be configured on the Kubernetes cluster to populate and validate GMSA credential spec references at the pod or container level. The mutating webhook expands references to GMSAs (by name from a pod specification) into the full credential spec in JSON form within the pod spec. The validating webhook ensures all references to GMSAs are authorized to be used by the pod service account.

Installing the webhooks require several steps:
1. Create a certificate key pair (that will be used to allow the webhook container to communicate to the cluster)
2. Install a secret with the certificate from above.
3. Create a deployment for the core webhook logic.
4. Create the validating and mutating webhook configurations referring to the deployment.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be worth mentioning that they can choose to do all that with a single command, as explained briefly in https://github.com/kubernetes-sigs/windows-gmsa/tree/master/admission-webhook#how-to-deploy (and that the --dry-run flag in that script would let them examine the k8s manifests before applying any chance); but that they can also choose to do this manually with the steps below?


The YAML file below can be used to configure the webhooks and the associated deployment and secret. Replace the values in curly braces {} with desired values, save it as `gmsa-webhooks.yml` and apply using `kubectl apply -f gmsa-webhooks.yml`

```
apiVersion: v1
kind: Secret
metadata:
name: ${DEPLOYMENT_NAME}
namespace: ${NAMESPACE}
data:
tls_private_key: ${TLS_PRIVATE_KEY}
tls_certificate: ${TLS_CERTIFICATE}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: ${DEPLOYMENT_NAME}
namespace: ${NAMESPACE}
spec:
replicas: 1
selector:
matchLabels:
app: ${DEPLOYMENT_NAME}
template:
metadata:
labels:
app: ${DEPLOYMENT_NAME}
spec:
containers:
- name: ${DEPLOYMENT_NAME}
image: k8ssigwindows/gmsa-admission-webhook
imagePullPolicy: IfNotPresent
ports:
- containerPort: 443
volumeMounts:
- name: tls
mountPath: "/tls"
readOnly: true
env:
- name: TLS_KEY
value: /tls/key
- name: TLS_CRT
value: /tls/crt
volumes:
- name: tls
secret:
secretName: ${DEPLOYMENT_NAME}
items:
- key: tls_private_key
path: key
- key: tls_certificate
path: crt
---
apiVersion: v1
kind: Service
metadata:
name: ${DEPLOYMENT_NAME}
namespace: ${NAMESPACE}
spec:
ports:
- port: 443
targetPort: 443
selector:
app: ${DEPLOYMENT_NAME}
---
# add a label to the deployment's namespace so that we can exclude it
apiVersion: v1
kind: Namespace
metadata:
name: ${NAMESPACE}
labels:
gmsa-webhook: disabled
---
apiVersion: admissionregistration.k8s.io/v1beta1
kind: ValidatingWebhookConfiguration
metadata:
name: ${DEPLOYMENT_NAME}
webhooks:
- name: k8s-gmsa-admission-webhook.sig-windows.k8s.io
clientConfig:
service:
name: ${DEPLOYMENT_NAME}
namespace: ${NAMESPACE}
path: "/validate"
caBundle: ${CA_BUNDLE}
rules:
- operations: ["CREATE", "UPDATE"]
apiGroups: [""]
apiVersions: ["*"]
resources: ["pods"]
failurePolicy: Fail
# don't run on ${NAMESPACE}
namespaceSelector:
matchExpressions:
- key: gmsa-webhook
operator: NotIn
values: [disabled]
---
apiVersion: admissionregistration.k8s.io/v1beta1
kind: MutatingWebhookConfiguration
metadata:
name: ${DEPLOYMENT_NAME}
webhooks:
- name: k8s-gmsa-admission-webhook.sig-windows.k8s.io
clientConfig:
service:
name: ${DEPLOYMENT_NAME}
namespace: ${NAMESPACE}
path: "/mutate"
caBundle: ${CA_BUNDLE}
rules:
- operations: ["CREATE"]
apiGroups: [""]
apiVersions: ["*"]
resources: ["pods"]
failurePolicy: Fail
# don't run on ${NAMESPACE}
namespaceSelector:
matchExpressions:
- key: gmsa-webhook
operator: NotIn
values: [disabled]
```
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is missing a few bits and pieces, notably the RBAC roles for the webhook service itself. See the latest version at https://github.com/kubernetes-sigs/windows-gmsa/blob/master/admission-webhook/deploy/gmsa-webhook.yml.tpl (and might be worth adding a link to that here, too?)


### Configure cluster role to enable RBAC on specific GMSA credential specs
A cluster role needs to be defined for each GMSA that authorizes the `use` verb on a specific GMSA resource by a subject such as a service account. The following shows an example of a cluster role that authorizes usage of gmsa-WebApp1 credspec from above. Save the file as gmsa-webapp1-role.yaml and apply using `kubectl apply -f gmsa-webapp1-role.yaml`

```
#Create the Role to read the credspec
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: my-rbac-reader
rules:
- apiGroups: ["windows.k8s.io"]
resources: ["gmsacredentialspecs"]
verbs: ["use"]
resourceNames: ["gmsa-WebApp1"]
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be worth highlighting that this is the name of the GMSA cred spec resource created earlier, and that you want to expose to your deployment?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

```

### Assign role to service accounts to use specific GMSA credspecs
A service account that a pod is configured with needs to be bound to the role to `use` the desired GMSA credential spec resources so that a pod's containers can be configured to use the GMSA. The following demonstrates the default service account being bound to a role to use a GMSA credential spec from above.

```
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: allow-default-svc-account-read-on-gmsa-WebApp1
namespace: default
subjects:
- kind: ServiceAccount
name: default
namespace: default
roleRef:
kind: ClusterRole
name: my-rbac-reader
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my-rbac-reader is incorrect :) it should say webapp1-role

apiGroup: rbac.authorization.k8s.io
```

### Configure GMSA credential spec reference in pod spec
In the alpha stage of the feature, the annotation `pod.alpha.windows.kubernetes.io/gmsa-credential-spec-name` is used to specify references to desired GMSA credential spec custom resources from pod specs. This configures all containers in the podspec to use the specified GMSA. A sample pod spec with the annotation populated:

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

from pod specs should be in pod specs

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

podspec should be pod spec

```
apiVersion: apps/v1beta1
kind: Deployment
metadata:
labels:
run: with-creds
name: with-creds
namespace: default
spec:
replicas: 1
selector:
matchLabels:
run: with-creds
template:
metadata:
labels:
run: with-creds
annotations:
pod.alpha.windows.kubernetes.io/gmsa-credential-spec-name: gmsa-WebApp1
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be worth highlighting that this is the name of the GMSA cred spec resource created earlier?

spec:
containers:
- image: mcr.microsoft.com/windows/servercore/iis:windowsservercore-ltsc2019
imagePullPolicy: Always
name: iis
nodeSelector:
beta.kubernetes.io/os: windows
```

Individual containers in a pod spec can also specify the desired GMSA credspec using annotation `<containerName>.container.alpha.windows.kubernetes.io/gmsa-credential-spec`. For example:

```
apiVersion: apps/v1beta1
kind: Deployment
metadata:
labels:
run: with-creds
name: with-creds
namespace: default
spec:
replicas: 1
selector:
matchLabels:
run: with-creds
template:
metadata:
labels:
run: with-creds
annotations:
iis.container.alpha.windows.kubernetes.io/gmsa-credential-spec-name: gmsa-WebApp1
spec:
containers:
- image: mcr.microsoft.com/windows/servercore/iis:windowsservercore-ltsc2019
imagePullPolicy: Always
name: iis
nodeSelector:
beta.kubernetes.io/os: windows
```

{{% /capture %}}