My Github runner is running only unittests right now. But I also have a test set that are sort of integration tests that need MS Sql server to run. Of course I also want to run this on my 3 node K8s cluster. Luckily for me MS Sql server is running on Linux for a while now, and Microsoft is even providing container images for it. My tests create their own database if it doesn't exist, so I don't even need persistent storage for this.  If this pod fails this will create a new pod and this will have no databases (because no persistent volume), but for this use-case this is no problem.

To start off I created this deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mssql-integration-test
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mssql
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: mssql
    spec:
      containers:
      - name: mssql
        image: 'mcr.microsoft.com/mssql/server'
        ports:
        - containerPort: 1433
        env:
        - name: ACCEPT_EULA
          value: "Y"
        - name: MSSQL_PID
          value: "Developer"
        - name: SA_PASSWORD
          value: mysqlpassword

Now this will give you one running container with MS Sql in it, but with this configuration there is no way to access it. Based on my (still limited) understanding of K8s networking, the way to do this in this case is create a nodePort for it. This way:

apiVersion: v1
kind: Service
metadata:
  name: mssql-integration-test
spec:
  type: NodePort
  selector:
    app: mssql
  ports:
  - port: 1433
    nodePort: 31433

Now you should be able to access the server via port 31433 on every node in the cluster.

My tests use a connection string that is stored in a appsettings.json this way:

{
  "ConnectionStrings": {
    "Database": "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=testsdb;Integrated Security=True;"
  }
}

This will not work when the tests execute inside the Github runner. To get this to work I've added this setting to the environment of the Github runner (this way overriding the value from the appsettings.json):

apiVersion: apps/v1
kind: Deployment
metadata:
  name: github-runner
  labels:
    app: github-runner
spec:
  replicas: 3
  selector:
    matchLabels:
      app: github-runner
  template:
    metadata:
      labels:
        app: github-runner
    spec:
      containers:
      - name: github-runner
        image: myoung34/github-runner:latest
        env:
        - name: ACCESS_TOKEN
          value: mytoken
        - name: REPO_URL
          value: https://github.com/floreseken/myrepo
        - name: ConnectionStrings__Database
              value: >-
                Server=node1.home,31433;Database=testdb;User
                Id=sa;Password=mysqlpassword;

Where the password should be the same one you used for the SQL server config. Now I'm pretty sure there is a better way to store these secrets, I will solve that in a follow-up post. For now this works.

Note that I've included the portnummer 31433 in this connection string.

Also note that for the Pods to be able to resolve node1.home servername (which is one of the cluster nodes), you need to enable MicroK8s dns and set an internal forwarder for it (that holds these records). Eventually I want some sort of loadbalancer for this (so I don't need the node1.home reference), but this is also something for another post.

Hope this helps.