Windows authentication in Docker containers is kind of a tricky subject and while containers in general are gaining momentum every day, containers on Windows are having a somewhat less steep increase and Windows authentication in that context is the niche in a niche. Still, that topic matters if you have users depending on Windows authentication that you want to bring to a containerized environment, so it is very good to see Microsoft making very nice improvements in that area.
If you want to use Windows authentication in Docker containers you need something called a group Managed Service Account or gMSA to handle the communication with your Active Directory. Until now there was a restriction that the name of the gMSA and the container needed to be the exact same. That meant that you had to create a gMSA for every new container and also that you had to remove the gMSA again after you removed the container. For a number of reasons that was bad, mostly because it prevented any meaningful dynamic scaling efforts through compose, Swarm1 or Kubernetes because you will end up with dynamic container names there and it meant that you couldn’t use standard tooling like portainer for those cases. With the latest Windows Server 2019 Insider Preview Microsoft announced that this restriction is no longer in place. I had to create a NAV/BC container image based on a matching Windows Server base image but because of Freddy Kristiansen’s excellent work this is quite easy now2. In the end I have verified that this indeed does work as advertised, you are free to name the gMSA however you want and you can reuse it between containers!
Microsoft’s release notes are actually quite clear on this topic but I have to admit that I completely missed that part and only was made aware of it when @marknitek was kind enough to politely tell me that I was wrong after I had3 said that I was quite sure I was right. A very good reminder that even in areas where I spent a lot of time and in this case did a lot of banging my head against a wall, there is always something new to learn… Anyways, the main point is that Microsoft announced that we no longer need the same name for the gMSA and the container:
Group Managed Service Accounts
We’ve improved the scalability and reliability of containers that use group managed service accounts (gMSA) to access network resources. You should see fewer authentication errors when using a single gMSA with multiple container instances. Additionally, you no longer need to set the container’s host name to be the same as the gMSA. We also fixed a bug that prevented you from using gMSAs with Hyper-V isolated containers.
I simply had to try that, so I went straight to the Insiders download page, got the ISO and as I needed full AD integration, asked my colleagues from Axians IT Solutions who are managing our base internal IT to provide a VM with that Insider version of Windows Server 2019. Running Windows containers with process isolation which I very much prefer requires the same base version for the container and the host, so I had to build my own NAV/BC image as we currently only have official images for 2016 LTSC. But that is quite easily done:
docker pull mcr.microsoft.com/windowsservercore-insider:10.0.17738.1000
docker build -t microsoft/dotnet-framework:4.7.2-runtime-windowsservercore-insider-10.0.17738.1000 .
to get my base image.$registry = "" $tag = "0.0.6.1-adjusted" $latest = $true "insider-10.0.17738.1000" | % {
compared to the original found here. I also changed the Dockerfile to reference my base image instead of the 2016ltsc one (first line now is FROM microsoft/dotnet-framework:4.7.2-runtime-windowsservercore-insider-10.0.17738.1000
)
FROM dynamics-nav:generic-insider-10.0.17738.1000 COPY NAVDVD c:/navdvd RUN PowerShell .\Run\buildimage.ps1 ENV DatabaseServer localhost ENV DatabaseName CRONUS
With docker build -t dynamics-nav:2018-cu8-w1-insider .
and a bit of patience I had my NAV 2018 Docker image based on Windows Server 2019 Insider Preview. Not a five minute job but also really not terribly complicated.
With that in place, the rest was a breeze: I created two containers, one named tstme2 and one tstme35, both using a gMSA named tst19 and both using Windows auth:
docker run --name tstme2 --hostname tstme2 --security-opt "credentialspec=file://tst19.json" --network MyTransparentNetwork -e auth=Windows -e usessl=n -e accept_eula=y dynamics-nav:2018-cu8-w1-insider docker run --name tstme3 --hostname tstme3 --security-opt "credentialspec=file://tst19.json" --network MyTransparentNetwork -e auth=Windows -e usessl=n -e accept_eula=y dynamics-nav:2018-cu8-w1-insider
To make sure that I didn’t get access through the old “first user in the database always gets in” mechanism, I created my own Windows user and that of a colleague as users in NAV and still SSO worked perfectly.
I have to say I was somewhat surprised to see Microsoft making that progress as I really hadn’t seen anything at all in that area despite a couple of Github issues and support cases. But it is a very pleasant surprise as this will drastically decrease complexity for running Windows Containers with Windows authentication and enable a couple of new scenarios, especially around dynamic scaling. More to follow…