Containers

How to Run EKS Windows containers with group Managed Service Accounts (gMSA)

Windows-based networks commonly use Active Directory to facilitate authentication and authorization between users, computers, and other computer network resources. Traditionally, enterprise applications running on Windows platforms use either service accounts or Managed Service Accounts (MSA) for authentication and authorization. The use of service accounts brings with it the overhead of service account password management. In contrast, Managed Service Accounts don’t have any password management overhead. They are limited to a single computer account; they can’t be used on more than one computer. Group Managed Service Account (gMSA) is a special type of service account; its identity can be shared across multiple computers without needing to know the password. Computers should be part of an Active Directory domain, which manages these service accounts to make use of them. Although Windows containers cannot join a domain like an instance, they can still use gMSA identity for authentication and authorization.

EKS recently announced official support for Windows in all 1.14 and above clusters, and the focus of this blog post is to show you how to deploy a Windows Pod with gMSA credentials to an EKS cluster. Though the main focus is on deploying to EKS, I will also show you how to set up an AWS managed Active Directory with a gMSA account, and enable an EC2 Auto Scaling group to automatically join newly launched EKS Windows instances to a target domain.

Prerequisites and assumptions

  • You have properly installed and configured the AWS CLI and PowerShell core on your computer.
  • This blog post applies to EKS Windows instances only.
  • This blog post talks about managed Active Directory, but it should also work with other Active Directory scenarios as long as the EKS Windows instances can join the domain.
  • Configuring instances to join a domain and creating an Active Directory security group require Active Directory credentials, and this blog post uses SSM Parameter Store to store Active Directory related information.
  • You have cloned the artifacts from this repo.
  • I chose to use the AWS CLI for these steps, so that end-to-end workflow can be demonstrated, but you can use AWS Management Console as well.
  • gMSA is an alpha feature in Kubernetes 1.14 and thus not officially supported by EKS. You will need to explicitly enable the Windows gMSA feature gate in the bootstrap arguments to your EKS worker node.
  • You have an EKS Cluster setup with Linux worker nodes. If you already have Windows worker nodes running, you need to relaunch them using the bootstrap arguments.

I’ve divided this blog post into three parts. The first part discusses required infrastructure setup, the second part talks about EKS deployment, and the last part discusses a sample two-tier application deployment that uses a gMSA credential spec.

Part 1: Infrastructure set up

Follow the instructions in GitHub to complete the infrastructure setup up, such as setting up AWS managed Active Directory, SSM documents to join domain, and to generate new gMSA account. If you’ve an existing Active Directory, update SSM parameters to use your Active Directory information.

Please note that the blog assumes that Active Directory is created in the same VPC as your EKS Worker VPC. Otherwise you should have established the cross VPC Active Directory communication.

Part 2: launch EKS Windows worker nodes

GMSA feature is an alpha feature in Kubernetes 1.14. Hence, we need to specify the additional bootstrap arguments while launching EKS Windows instances. You can follow the steps in AWS documentation to launch EKS Windows worker nodes.

BootstrapArguments: --feature-gates="WindowsGMSA=true"

In addition to that, we also need to make the EKS Windows instances join the Active Directory domain to allow gMSA authentication and authorization. There are different ways to make an EKS instance to join Active Directory. One of them is to attach SSM document to Auto Scaling group. Follow the instructions in GitHub to attach a SSM document that will join the instance to the domain and give required IAM policies for the node instance role. Once the SSM document is attached, the instances will start executing the document once and whenever the Auto Scaling group launches a new instance.

At this point, we should have an Active Directory setup, and EKS instances running that have joined the Active Directory and are associated with an Active Directory security group. The next section will talk about the gMSA account setup and EKS deployments.

Part 3: gMSA account setup and EKS deployments

gMSA resources in Kubernetes

A gMSA credential spec is a JSON file generated by Active Directory PowerShell module, which is deployed as a custom resource to the EKS cluster. The file contains metadata about one more gMSA accounts intended to be used with containers. In alpha state, this custom resource name is referenced in the pod specifications under pod annotations, whereas in beta, this has been changed to a field “securityContext.windowsOptions.gmsaCredentialSpecName.” A mutating webhook then expands this reference 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. For more details refer Kubernetes documentation.

CoreDNS Configmap

CoreDNS is the DNS server for Kubernetes services deployed in an EKS cluster. For resolving external services, it forwards the DNS traffic to upstream DNS servers configured in the instances. In your EKS cluster, CoreDNS is running on Linux instances and they are not domain joined. So, we must update the CoreDNS config map to route the Active Directory related DNS queries to Active Directory DNS servers.

The instructions in GitHub will deploy EKS artifacts, create gMSA account in Active Directory, and patch the coredns configmap to include Active Directory DNS servers.

After it’s patched, your CoreDNS configmap will have an additional section as shown below:

Part 4: sample application deployment

A sample two-tier application is developed to demonstrate the gMSA authentication. The ASP .NET Core web application authenticates with the backend SQL Server bookstore database using the gMSA account. The application performs basic add, edit, list, and delete operations. Both the front end and database applications are running in containers and deployed with gMSA credential specifications.

The steps in GitHub will create the container images and deploy the sample applications with gMSA credentialspec to EKS cluster.

To show the difference between SQL authentication and gMSA authentication, I’ve included a CreatedBy column in the list. The initial ones are populated by SQL account (sa) during database setup. If you add a new book, it is created by gMSA account.

You can switch between SQL and gMSA authentication by changing the connectionstring environment variable in application definition and then redeploy the application.

SQL authentication snippet.

      containers:
      - image: containermvc-web:latest
        imagePullPolicy: Always
        name: containermvc-web
        env:
          - name: connectionstring
            value: 'Server=containersql-bookstore-service; Database = Bookstore; User Id=sa; Password = <<PASSWORD>>;'
      nodeSelector:
        beta.kubernetes.io/os: windows

Conclusion

In this blog post, I showed you how to deploy a Windows pod with gMSA credential spec to an EKS cluster. I also explained how EKS Windows instances in Auto Scaling groups can be automatically joined to an Active Directory domain upon launch.

If you have comments about this blog post, submit them in the “Comments” section below. If you have questions, please start a new forum thread on the EC2 forum.