I have a kubernetes cluster with front end as C# console application written in .NET Core and a backend Mysql db. Both of these applications are deployed as deployments in kubernetes in different pods. I have also created a mysql service to be able to connect with Mysql db. But, I can't seem to connect to mysql server from .NET core console app to kubernetes Mysql service. However, I can pretty much connect with Mysql pod using the IP address from the console app.
I will try my best to describe the situation here.
$ kubectl -n radiomicsapp get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
anonymizer-pod-586548ddd9-kv8cj 2/2 Running 0 21s 10.244.0.187 aks-agentpool-35971152-1
mysql-744bfb878c-scwz9 1/1 Running 0 19h 10.244.1.244 aks-agentpool-35971152-2
$ kubectl -n abcapp get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
mysql ClusterIP 10.0.54.120 <none> 3306/TCP 104d
If I use IP address from the pod (10.244.1.244) to connect with db, it works. However, if I use IP address (10.0.54.120) from mysql service, it throws
Error: Unable to connect to any of the specified MySQL hosts.
Since, the IP address of the mysql pod changes whenever the pod is restarted/recreated, I will have to change the db connection string in my anonymizer console app, I created a mysql service with type ClusterIP as given below:
apiVersion: v1
kind: Service
metadata:
name: mysql
namespace: abcapp
labels:
app: abc
spec:
type: ClusterIP
ports:
- name: mysql
port: 3306
protocol: TCP
targetPort: 3306
selector:
app: abc
Also, my anonymizer pod, mysql pod as well as mysql service are all in the same namespace.
Any help would be much appreciated. Thanks for taking your time.
You have to use the service name on your code and leave kube-dns to handle the IP resolution for you to be sure your code works no matter if the pod is recreated or moved and it takes a different IP address during the process.
From another answer is easy to extrapolate an approximate example
How to connect to MySQL Database?
string connstring = string.Format("Server=mysql; database={0}; UID=UserName; password=your password", databaseName);
connection = new MySqlConnection(connstring);
Notice that only need to put on the Server mysql
Related
I have created a single node ScyllaDB in docker, which is up and running, and below is my docker-compose commands:
version: "3"
services:
scylla-node1:
container_name: scylla-node1
image: scylladb/scylla
restart: always
command: --smp 2 --memory 1500M --broadcast-rpc-address 127.0.0.1 --listen-address 0.0.0.0
ports:
- 9042:9050
networks:
web:
networks:
web:
driver: bridge
Reading the documentation for Scylla it recommends using the DataStax C# Driver for Apache Cassandra. So, I have used this in my solution. Following the basic examples, I am struggling to get it work. Thus,
var cluster = Cluster.Builder()
.AddContactPoints("0.0.0.0")
.Build();
var session = cluster.Connect("sample_keyspace");
When the code reaches the Connect command it throws the following error
Cassandra.NoHostAvailableException: 'All hosts tried for query failed (tried 0.0.0.0:9042: SocketException 'The requested address is not valid in its context.')'
Firstly, I can connect to Scylla through the CSQL Utility and can create a Keyspace and then run a query to confirm that the Keyspace has been created.
Is this a problem with C# Driver or am I doing something wrong?
This looks like a networking issue to me because your Docker container doesn't appear to be configured correctly.
The problem is that the C# driver (your application) is not able to connect to the container because there is no network connectivity. That is what this exception means:
Cassandra.NoHostAvailableException: 'All hosts tried for query failed (tried 0.0.0.0:9042: \
SocketException 'The requested address is not valid in its context.')'
I assume "CSQL utility" is a typo. The reason you are able to connect using cqlsh is because you are most likely connecting with:
$ docker exec -it scylla-node1 cqlsh
which isn't the same as connecting remotely. To be fair I'm making an assumption as you didn't provide details.
You've configured the container with --broadcast-rpc-address 127.0.0.1 so it will only listen for client connections on localhost. This means that you can't use 0.0.0.0 as the contact point.
I've also noted that you've mapped the container port 9050 to host port 9042:
ports:
- 9042:9050
By default, Cassandra listens for client connections on port 9042, not 9050. If nothing is listening on port 9050, there's nothing for the driver to connect to and will also lead to NoHostAvailableException. Cheers!
The following code works if Cassandra and the code are on the same machine:
using System;
using Cassandra;
namespace CassandraInsertTest
{
class Program
{
static void Main(string[] args)
{
var cluster = Cluster.Builder()
.AddContactPoint("127.0.0.1")
.Build();
var session = cluster.Connect("test_keyspace");
session.Execute("INSERT INTO test_table (id, col1, col2) VALUES (1, 'data1', 'data2')");
Console.WriteLine($"Finished");
Console.ReadKey();
}
}
}
Assuming a username and password is needed if the code is on one machine and cassandra is on a different machine (different ip address)? So I have tried:
var cluster = Cluster.Builder()
.AddContactPoint("192.168.0.18") <- the ip address for the cassandra node
.WithPort(9042)
.WithCredentials("username to log into the cassandra node","password to log into the cassandra node")
.Build();
I get the following error message:
userone#desktop:~/Desktop/vsc$ dotnet run
Unhandled exception. Cassandra.NoHostAvailableException: All hosts tried for query failed (tried 192.168.0.18:9042: SocketException 'Connection refused')
at Cassandra.Connections.ControlConnection.Connect(Boolean isInitializing)
at Cassandra.Connections.ControlConnection.InitAsync()
at Cassandra.Tasks.TaskHelper.WaitToCompleteAsync(Task task, Int32 timeout)
at Cassandra.Cluster.Cassandra.SessionManagement.IInternalCluster.OnInitializeAsync()
at Cassandra.ClusterLifecycleManager.InitializeAsync()
at Cassandra.Cluster.Cassandra.SessionManagement.IInternalCluster.ConnectAsync[TSession](ISessionFactory`1 sessionFactory, String keyspace)
at Cassandra.Cluster.ConnectAsync(String keyspace)
at Cassandra.Tasks.TaskHelper.WaitToComplete(Task task, Int32 timeout)
at Cassandra.Tasks.TaskHelper.WaitToComplete[T](Task`1 task, Int32 timeout)
at Cassandra.Cluster.Connect(String keyspace)
at HelloWorld.Program.Main(String[] args) in /home/userone/Desktop/vsc/Program.cs:line 17
userone#desktop:~/Desktop/vsc$
The iptables on the node (the cassandra server) is currently set as follows:
node1#node1:~$ sudo iptables -S
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-A INPUT -i lo -j ACCEPT
-A IMPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -s 192.168.0.73/32 -p tcp -m multiport --dports 7000,7001,7199,9042,9160,9142 -m state --state NEW,ESTABLISHED -j ACCEPT
node1#node1:~$
Note 1: Both the machine with the app and the machine with cassandra installed can be pinged and tracerouted in both directions.
Note 2: I have tested the username and password and can log into the cassandra server without any issues when tried directly on the server.
Note 3: Cassandra is running in a VM which I just created today. The VM is a guest machine on the host machine which runs the code.
Note 4: Both the Host OS and Guest OS are Linux.
.AddContactPoint("127.0.0.1")
If that works from the same machine, then you probably have Cassandra bound to that IP. If you need to connect to your node(s) remotely, then you need to bind a routeable IP to that node.
Run a nodetool status. If you see your cluster status showing your node with an IP of 127.0.0.1, then connecting to the local machine from the local machine is the only scenario that will ever work.
Try running the following command on your node:
grep _address cassandra.yaml
The IP address returned in the output is the only one that an application is allowed to connect to. If you want to be able to connect to 192.168.0.18, then the listen and rpc addresses should look something like this:
listen_address: 192.168.0.18
rpc_address: 192.168.0.18
Note that you'll need to change your seeds list, too.
Also, if you're on a VM/provider that has both internal and external IP addresses, then you'll also need to set your broadcast_ addresses to the external IP:
broadcast_address: 10.6.5.5
broadcast_rpc_address: 10.6.5.5
listen_address: 192.168.0.18
rpc_address: 192.168.0.18
But try setting just listen and rpc to 192.168.0.18 first.
Edit 20191022
Just wanted to double check, do I add 192.168.0.18 as the listen_address and rpc_address to the cassandra node where the cassandra node has the ip address 192.168.0.18?
Yes. Also make sure that your node's seed list is set like this:
- seeds: "192.168.0.18"
Before I did that, the value of the listen_address and rpc_address were set to localhost
I thought so.
However, after making the changes you suggested, nodetool status now gives me
Failed to connect to 127.0.0.1:7199 - connection refused
Ironically, that's the same message nodetool returns when Cassandra is not running. At this point I would check the system log and see if it is returning errors that may be preventing it from starting. I suspect that the seed list still reads "127.0.0.1".
tl;dr;
If you intend to connect to your cluster/node remotely, then you cannot use the default configurations which bind Cassandra to the home IP (127.0.0.1/localhost). And that includes all _address settings, as well as your seeds list.
I suggest using something like telnet 192.168.0.18 9042 to test whether the network is properly configured for this scenario. The error that the driver is throwing is just a standard socket error that is returned when the driver can't connect to the cassandra host.
I do not have any experience with Cassandra, but almost all of my connectivity problems were related to firewalls' configuration, OS distributed and network services, etc.
So, if everything works well locally, do not change anything in source code before you are entirely sure about it.
I suggest to check the following list first:
Check all servers' firewall configuration
Check if all needed services are run in all servers (search if Cassandra is depended on any services).
Check the network firewall and subnet port and protocol access limitation if exist.
Check if Cassandra is fully and functionally up and works on port 9042.
I'm using "ServiceStack.Redis" to connect to Redis and it works correctly on my development machine.
Basically, I open the connection via this line:
client = new RedisClient(host);
Where host, on my development machine, is "localhost".
Now, I'd like to upload my application to Azure, so I created a cache in Azure and I'm trying to connect to it by passing the following connection string:
XXX.redis.cache.windows.net,ssl=false,password=YYY
The creation of the "RedisClient" seems to work but when I try to perform an operation (the first one to be executed being client.RemoveByPattern("...")), I get the following error:
Exception Details: System.Net.Sockets.SocketException: No such host is
known
Note that I allowed the cache to be connected to via HTTP, so normally, the port 6379 is unblocked and accessible.
All the example I found over Internet are using "ConnectionMultiplexer" but this class does not seem to be found in the NuGet package "ServiceStack.Redis".
What am I doing wrong?
I was having the same(similar?) issue connecting to Azure Redis with ServiceStack, in the end it was working out the correct syntax for the connection that worked for me. XXX.redis.cache.windows.net?ssl=true
Found some help here https://github.com/ServiceStack/ServiceStack.Redis, but to quote the connection strings section had examples;
"Redis Connection strings have been expanded to support the more versatile URI format which is now able to capture most of Redis Client settings in a single connection string (akin to DB Connection strings).
Redis Connection Strings supports multiple URI-like formats, from a simple hostname or IP Address and port pair to a fully-qualified URI with multiple options specified on the QueryString."
Some examples of supported formats:
localhost
127.0.0.1:6379
redis://localhost:6379
password#localhost:6379
clientid:password#localhost:6379
redis://clientid:password#localhost:6380?ssl=true&db=1
NOTE: I used the final example here but without the redis:// bit as I found this was not needed in Azure.
I have a C# Application which would access a MySQL server on another computer. I am trying to do it via IP. Here is my Connection String :
result = "server =66.45.233.226; user id=testcampuscrm; password =Daph$5656; database=testcampuscrm; convert zero datetime=true; ";
getting error this
Access denied for user 'testcampuscrm'#'66.45.232.178' (using
password: YES)
My code is anther hosting and mysql database anther hostig please help us. Thanks
There is multiple things you have to take into consideration while accessing mysql from another machine some them are -
Assuming you did write correct code
1.Change mysql config (my.ini) to receive packets from all IP
2.Add firewall Exception for port 3306 on machine where Mysql is Hosted
3.User name password is Correct and granted proper privileges.
PS:-Do not share server credentials on public forums
I have recently installed MySQL on our local server, and I am attempting to connect to it using this connection string:
mySqlConnectionString = "server=192.168.1.254;database=dcim;uid=root;pwd=LlmD62jL;";
I have also tried adding the port as well:
mySqlConnectionString = "server=192.168.1.254:3306;database=dcim;uid=root;pwd=LlmD62jL;";
But I still keep getting the MySqlException:
1042 - Unable to connect to any of the specified MySQL Hosts.
I have tried with the Firewall active and de-activated, but nothing has worked so far. What's going on?
EDIT: I thought I should note that I used this connection string to connect to MySQL on the same machine, with no problems using localhost or 127.0.0.1.
NB: This is MySQL Server with .NET Framework connection.
First check mysql server is working or not.
Try to add port number of mysql in connection string(The port 3306 is the default MySql port).
Check spacing and Order of parameters in connection string.(Sometimes it matters base on my experience",) )
Here's the basic format you could follow:
Server=ServerAddress; Port=1234; Database=DataBase; Uid=Username; Pwd=Password;
Also try to read this article its useful for connection strings. MySQL connection strings
Hope it helps. ",)