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.