Skip to main content

Accessing VM Host (localhost) from minikube

Time to time I need to access resources outside of your Kubernetes cluster. It can be some .net framework app that I can`t put in linux container or shared db, like SQL server.

We can easily access resources in kube via kubefwd or ingress\exposed port. However, that doesn't work backwards. Services in k8s cluster can`t just access your machine, they need to know VM`s host IP.

The main point here is finding an ip of the host machine:
$ route -n | grep ^0.0.0.0 | awk "{ print \$2 }"
172.17.8.1

In order to run in from powershell we need to escape quotes:
minikube ssh 'route -n | grep ^0.0.0.0 | awk \"{ print \$2 }\"'
172.17.8.1

What can it be use it for?
I can setup that ip in PODS connection string but I don’t want to update every pod when my ip changes (a typical problem with hyberV).
It would be much better to reference resources by dns name and let dns service decide how to resolve that resource.

So let’s make a ‘dns-service’ that will redirect us to host.

What we`ll need is:
  1. grab new ip
  2. update service.yaml
  3. deploy it
1) We know how to do it already

2)Make a template of a service:
# creates fake dns minikube-host to actual host Ip 
apiVersionv1
kindService
metadata:
  namemasterhost
  namespaceshared
spec:
    typeExternalName
    # externalName should be dns name, not ip, so as a workaround we use http://xip.io 
    externalName: {IP}.xip.io


Xip.io provides wildcard dns to ip. Yes its public and runs outside so if you want security- deploy your own wildcard proxy into cluster.

We don’t want to change ip manually, a simple replace should work (or convert it to helm)

(Get-Content $PSScriptRoot'\masterhost.template.yaml').replace('{IP}'$hostIp) | Set-Content $PSScriptRoot'\masterhost.yaml'

3) kubectl apply -f minikube-host.yaml

All together in one script:
$hostIp = minikube ssh 'route -n | grep ^0.0.0.0 | awk \"{ print \$2 }\"'

(Get-Content $PSScriptRoot'\masterhost.template.yaml').replace('{IP}'$hostIp) | Set-Content $PSScriptRoot'\masterhost.yaml'

kubectl apply -f $PSScriptRoot'\masterhost.yaml'


In my connection string I can use masterhost.shared and if ip changes update just masterhost service.

Troubleshooting access to host from pod (SQL Server as an example)

1) Make sure your service is binding to all ips and you can access server just by ip\machine name.  For SQL: Run SQLServerManager12.msc (For SQL 2014) and follow steps https://stackoverflow.com/a/11921896/603622 (don’t forget to restart server)

2) Check your firewall and if necessary create an inbound rule for port 1433

3) Verify you can connect to host IP from minikube
minikube ssh
$ route -n | grep ^0.0.0.0 | awk \"{ print \$2 }\"
172.17.8.1 1433
$ telnet 172.17.8.1 1433
4) Verify you can connect to host by IP or masterhost.shared from some running pod. SSH to pod
$ apt-get install telnet
$ telnet 172.17.8.1 1433
$ telnet masterhost.shared 1433

Comments

Popular posts from this blog

Using MinIO as on premises object storage with .NET and S3 SDK

Ever tried to find a blob store that can work on-premises as well as in a cloud, support meta-data, scale well and have .NET client libraries? I did and stopped on MinIO . Well, honestly to my surprise I was quite limited in my choice. It's free, it's open-source, it can work on-premises and has helm charts for k8s. The best thing is that its S3 compatible, so if one day you move to the cloud the only thing you`ll need to change in your code is a connection string. The easiest way to start is by starting a docker image. Pull the image: docker pull minio/minio start for testing (data will be part of the container, so after a restart, all files will be gone docker run -p 9000:9000 minio/minio server /data Or start with a mapped image in windows: docker run -p 9000:9000 --name minio1 \ -v C:\data:/data \ minio/minio server /data When the server is up you can access it by http://127.0.0.1:9000/minio/login default user/password: minioadmin/minioadmin Working wi...

Avoiding distributed transactions (DTC) with SQL Server and async code

Wrapping async code in transaction scope is not as straightforward as sync one. Let's say we have some simple code: await using (var connection = new SqlConnection(connectionString)) { await using var command = new SqlCommand("select 1", connection); await connection.OpenAsync(); await command.ExecuteScalarAsync(); } We can wrap it in transaction scope and test that it still works: using var ts = new TransactionScope(); await using (var connection = new SqlConnection(connectionString)) { await using var command = new SqlCommand("select 1", connection); await connection.OpenAsync(); await command.ExecuteScalarAsync(); } ts.Complete(); But if you try to run this code you will get: "A TransactionScope must be disposed on the same thread that it was created" exception.  The fix is easy: we need to add TransactionScopeAsyncFlowOption.Enabled option to the constructor: var options = new TransactionOptions { IsolationLevel = IsolationLevel.ReadCom...

Fluent-Bit and Kibana in Kubernetes cluster or minikube

Agenda I`ll show how to setup a centralized logging solution running in k8s cluster that works beyond hello world examples.I`ll use local minikube but the same charts with adjustments could be used for normal k8s cluster (the real diff usually comes with usage of persistent storage). What you need to be installed: K8s Cluster (as I said, I use minikube ) Helm ( https://helm.sh/docs/intro/install/ ) Code: https://github.com/Vfialkin/vf-observability A bit of theory first: Let’s start with how logging works by default in Docker and Kubernetes. application log appender should forward logs to standard output, this way it will be passed to Docker container.  default container logging driver will forward them to Pod where logs are stored as JSON files (see: configure logging drivers ). There are other options for log drivers like  syslog, fluentd or splunk , but for now, I’ll limit scenario to default driver. at the end all those files will end-up in a node folde...