Running Workflows on windows with Jenkins pipeline and Kubernetes
As a DevOps engineer I am building a new CI/CD pipeline based on Kubernetes and Jenkins. Recently working on one of the workflows I was in need to build artifacts (executables) on windows, and you can run pods(containers) with windows based images only on windows worker nodes. I will share my experience in this post about how to add windows worker nodes to your EKS cluster and then run windows workflows on the top of it.
Let’s start.
What is Jenkins?
Jenkins is a self-contained, open source automation server which can be used to automate all sorts of tasks related to building, testing, and delivering or deploying software.
What is Jenkins Pipeline?
Jenkins Pipeline (or simply “Pipeline” with a capital “P”) is a suite of plugins which supports implementing and integrating continuous delivery pipelines into Jenkins.
What is the Kubernetes plugin for Jenkins?
Jenkins plugin to run dynamic agents in a Kubernetes cluster. The plugin creates a Kubernetes Pod for each agent started, defined by the Docker image to run, and stops it after each build.
What is Amazon EKS?
Amazon Elastic Kubernetes Service (Amazon EKS) is a managed service that makes it easy for you to run Kubernetes on AWS without needing to stand up or maintain your own Kubernetes control plane. Kubernetes is an open-source system for automating the deployment, scaling, and management of containerized applications.
Add windows worker nodes to existing EKS cluster with linux nodes only
Create a new node group (AWS autoscaling group) with windows nodes using eksctl utility directly, without the use of config
The most important parameter here is node-ami-family: WindowsServer2019FullContainer
Create a node group with windows nodes from config file and using the eksctl utility
eks_cluster_config.yaml
You may have also a more advanced configuration, for example running the windows nodes on spot instances
In this case, I am using the cluster Cluster Autoscaler to automatically adjusts the size of the Kubernetes cluster
Also, read the Consideration, which has important info like Amazon EC2 instance types C3, C4, D2, I2, M4 (excluding m4.16xlarge), and R3 instances are not supported for Windows workloads.
Installing VPC Resource Controller and VPC Admission Webhook into the cluster
These components run on Linux nodes and are responsible for enabling networking for incoming pods on Windows nodes. To use the tool we run the following command.
Deploy a Windows sample application
https://docs.aws.amazon.com/eks/latest/userguide/windows-support.html#windows-sample-application
I encourage you to deploy a windows sample application to validate your cluster configured properly.
Setting properly Node Selectors in your application
So the cluster is configured and able to run windows workflows, now you must specify node selectors on your applications so that the pods land on a node with the appropriate operating system.
Targeting Windows
Targeting Linux
This is the most important part based on my experience, because if you using labels you created to select the needed nodes and not attaching ‘beta.kubernetes.io/os: windows’ selector like recommended to your app, you might get into trouble, and your pod may stuck in pending state with the error similar to this one: Failed create pod sandbox: rpc error: code = Unknown desc = [failed to set up sandbox container “…” network for pod “…”: NetworkPlugin cni failed to set up pod “…” network: failed to parse Kubernetes args: pod does not have label vpc.amazonaws.com/PrivateIPv4Address…
Check you set node Selectors properly in this case, also if you have some problems you can read this
Running the workflows on windows with Jenkins pipeline
In this example, I am using the ‘windows server core’ image and PowerShell to create a sample file and upload it to the s3 bucket, which you need to define.
I also store credentials for AWS in the ‘Vault’, I described in the previous post how to read Vault’s secrets in Jenkins pipeline
Please subscribe to my YT channel
Please follow me on Twitter (@warolv)