That’s a common question, what kind of workloads can you run on Windows clusters? In this post we are going to check the possibilities and how to build and run these services on a Windows cluster. There’s a plenty of examples on all languages and build process spread over the Internet. This document intends to enumerate and list them for a quick review and reference.
To do your choice a few topics that can compare both technologies. Use .NET for your server application when:
Use .NET Framework for your server application when:
MS announced .NET in 2000, being the platform for Windows API development. In this architecture at the time .NET framework was the first platform for development, the last released version is 4.8 and the project was discontinued in 2022. The most common case of usage is to run your current application that was no migrated aka legacy workloads. A few technologies like ASP.NET Web Forms Applications are supported only in .NET framework.
Apps are written in C#, F# or Visual Basic and compiled for Common Intermediary Language (CIL). The main resources are the Common Lanuage Runtime (CRL) and the .NET framework class library. The program only runs on Windows machines. Lets start with the examples. If you notice only the WindowsServerCore SDK and Runtime are available, meaning the final container OCI image will have 4Gb of size, so be patient in the downloading.
The first step is to build the image from a Dockerfile, check its split on 2 phase containers, the first part builds the binary with the SDK, the second one is responsible to run your ASP.NET application.
FROM mcr.microsoft.com/dotnet/framework/sdk:4.8 AS build
WORKDIR /app
# copy csproj and restore as distinct layers
COPY *.sln .
COPY aspnetapp/*.csproj ./aspnetapp/
COPY aspnetapp/*.config ./aspnetapp/
RUN nuget restore
# copy everything else and build app
COPY aspnetapp/. ./aspnetapp/
WORKDIR /app/aspnetapp
RUN msbuild /p:Configuration=Release -r:False
FROM mcr.microsoft.com/dotnet/framework/aspnet:4.8 AS runtime
WORKDIR /inetpub/wwwroot
COPY --from=build /app/aspnetapp/. ./
First thing to notice is you need a Windows machine with Docker to build the image for windows/amd64 architecture, with these images I could not build using buildx, but probably there’s a way. Expose the service and port 8000:80 will be available for requests.
apiVersion: apps/v1
kind: Deployment
metadata:
name: aspdotnet
labels:
app: aspdotnet
spec:
replicas: 1
selector:
matchLabels:
app: aspdotnet
template:
metadata:
labels:
app: aspdotnet
spec:
nodeSelector:
kubernetes.io/os: windows
containers:
- name: aspdotnet
image: mcr.microsoft.com/dotnet/framework/samples:aspnetapp
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: aspdotnet
labels:
app: aspdotnet
spec:
ports:
- port: 8000
targetPort: 80
selector:
app: aspdotnet
Its a free, cross-platform, open source developer platform for builiding many kinds of apps. Its divided in two parts:
Again the SDK is used to build the image and the runtime to run your workload. The steps are different though in the sample:
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
WORKDIR /source
# copy csproj and restore as distinct layers
COPY aspnetapp/*.csproj .
RUN dotnet restore --use-current-runtime
# copy everything else and build app
COPY aspnetapp/. .
RUN dotnet publish -c Release -o /app --use-current-runtime --self-contained false --no-restore
# final stage/image
FROM mcr.microsoft.com/dotnet/aspnet:7.0
WORKDIR /app
COPY --from=build /app .
ENTRYPOINT ["dotnet", "aspnetapp.dll"]
The dotnet
CLI is available to build the project and run the final .dll. With the SqlConnection
is possible to connect on a MSSQL server, the cool part is that it can run on Windows.
It’s possible to compile a Golang app and run on Windows as well, you need two things:
FROM mcr.microsoft.com/windows/nanoserver:1809
Copy the binary and run it. The one can test for example the connection to a MSSQL database with this example code:
func main() {
// Build connection string
connString := fmt.Sprintf("server=%s;user id=%s;password=%s;port=%d;database=%s;", server, user, password, port, database)
var err error
// Create connection pool
db, err = sql.Open("mssql", connString)
if err != nil {
log.Fatal("Error creating connection pool: ", err.Error())
}
ctx, stop := context.WithCancel(context.Background())
defer stop()
appSignal := make(chan os.Signal, 3)
signal.Notify(appSignal, os.Interrupt)
go func() {
<-appSignal
stop()
}()
Ping(ctx)
}
.NET workload is a very specialized one, and the framework is deprecated, still there’s a lot of legacy workload and only Windows nodes can run it. For new apps is encouraged to use .NET or a more modern platform that can be used cross OS.