I planed to develop a HA program for MSSQL, but I got a question when reading some articles about cluster.
When master is down, then slaves vote for a new master, and the new master will take over virtual IP address of the old one.
What is virtual IP address here ?
For example:
A: master 192.168.1.100
B: slave 192.168.1.101
C: slave 192.168.1.102
Is there a another IP address assigned to A? or the IP 192.168.1.100 is the virtual IP ?
If an additional IP need to be assigned to master, what the kind of IP it is? public or local, and how it is assigned to server in C# code.
Windows system.
It is not possible to add extra network cards.
Thanks.
:D
In the MSSQL, every instance has an endpoint. In your case, each IP address should be the instance IP addresses.
When the master is down, no IP address should be resigned. It keeps as is.
During failover, Windows Failover Cluster will tell Secondary B or C which is voted to be new Primary.
When you create an Availability Group, you can create an AG listener for your HA. Usually this listener is the interface that client access to. By SQL Server, HA will route your traffic to the current primary.
Client -> AG endpoint (public IP / Private IP) -> Primary (192.168.1.100)
-> Secondary (192.168.1.101)
-> Secondary (192.168.1.102)
After Failover, Client still access same IP address, which is the AG listener.
Client -> AG endpoint (public IP / Private IP) -> Secondary (192.168.1.100)
-> Primary (192.168.1.100)
-> Secondary (192.168.1.102)
reference: https://msdn.microsoft.com/en-us/library/hh213080.aspx
Related
I have a specialised hardware which is configured to communicate to a single IP address. But I want to communicate with 2 servers for SQL Server Availability Group(Both are Replicas to each other), So I make a cluster of 2 Servers (Windows Server).
For Example :
IP Address of Server 1 : 185.178.94.2
IP Address of Server 2 : 185.178.94.3
Cluster/Listener IP Address : 185.178.94.5
The Problem now is when hardware(Configured to communicate to 185.178.94.5) is sending ARP Request (i.e. asking MAC address of 185.178.94.5), the response is going from the correct server but it is going like this 185.178.94.2 has MAC address ae:23:dc:4r:2w:5r instead of going like 185.178.94.5 has MAC address ae:23:dc:4r:2w:5r.
The arp table of hardware now has entry
185.178.94.2 --- ae:23:dc:4r:2w:5r
instead of
185.178.94.5 --- ae:23:dc:4r:2w:5r
The same setup working fine if we use a normal laptop instead of our specialised hardware.
One more thing I would like to mention here is in case of hardware , if we remove LAN cable from one of the server, then packets starts coming and the arp table of hardware updated with an entry for 185.178.94.5.
We have 6 redis servers running in ports (8001, 8002, 8003, 8004, 8005, 8006).
On the redis.conf of every Redis server we bind the ip in different ways like:
bind 0.0.0.0
bind PRIVATE PUBLIC
bind PUBLIC
If we access like it works fine:
redis-cli -h PUBLIC_IP -p 8001
But when we wanna create the clusters we run:
./src/redis-cli --cluster create PUBLIC_IP:8001 PUBLIC_IP:8002 PUBLIC_IP:8003 PUBLIC_IP:8004 PUBLIC_IP:8005 PUBLIC_IP:8006 --cluster-replicas 1
The console always shows and keeps in Waiting for the cluster forever:
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica PUBLIC_IP:8005 to PUBLIC_IP:8001
Adding replica PUBLIC_IP:8006 to PUBLIC_IP:8002
Adding replica PUBLIC_IP:8004 to PUBLIC_IP:8003
>>> Trying to optimize slaves allocation for anti-affinity
[WARNING] Some slaves are in the same host as their master
M: 7ab009459f7f5cf6cef5f46b691748dc236e4c26 PUBLIC_IP:8001
slots:[0-5460] (5461 slots) master
M: 0048ca2cd65c1315b8f0a7c952b69bfb494d5ace PUBLIC_IP:8002
slots:[5461-10922] (5462 slots) master
M: c6ee023719f200b0d175f428fa15e5ab767d0e04 PUBLIC_IP:8003
slots:[10923-16383] (5461 slots) master
S: cf636a1a46b1e947daec3e797cac524c613f08ca PUBLIC_IP:8004
replicates 7ab009459f7f5cf6cef5f46b691748dc236e4c26
S: 5d4bd1041457114353b0b30dbefd86ab8e4ae020 PUBLIC_IP:8005
replicates 0048ca2cd65c1315b8f0a7c952b69bfb494d5ace
S: 62f01289dc3f72cac4a1745fc77b7bd91ec5d107 PUBLIC_IP:8006
replicates c6ee023719f200b0d175f428fa15e5ab767d0e04
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
A lot of people says that we need to bind the private ip, but we wanna do it on public becase when we connect with the external machines the clustering redirect to the master that contains the key, if we bind the private ip the redirect will shows "redirect to PRIVATE_IP" and that will not work as expected.
Are we missing something to let the cluster join by public IP?
From redis security guide:
Redis is designed to be accessed by trusted clients inside trusted environments.
See also: How to connect to redis from remote guide
When a server binds on its public ip, it can get requests from everyone, so unless you built some security around it anyone can access and manipulate your data.
In redis cluster the rules are the same and the replicas which binds on public ips are exposed.
The default use case for a redis cluster is that one machine (or multiple machines) access it from within it's private network, and you shouldn't divert from that unless you know what you are doing security wise.
If it makes sense for your use case, you should make the machine which access the redis cluster a part of the cluster private network.
What I would be doing if I were at your place is:
Bind all the servers with private ip and loopback ip i.e bind {{ private_ip }} 127.0.0.1
Enable ufw (or other any firewalling tool) on each server and do (for ufw) allow from {{ private_ip }} to any port {{ redis_port }} or similar.
My internal DNS will have entry for all the servers with their respective private ip.
Voila! create and access redis cluster securely without any security breach.
NOTE: if you still want to access them over public network then you can do some workaround with SNAT
WARNING: binding redis server to 0.0.0.0 or public ip might cause serious vulnerability issues like:
https://www.exploit-db.com/exploits/47195
https://medium.com/#knownsec404team/rce-exploits-of-redis-based-on-master-slave-replication-ef7a664ce1d0
PS: You can also follow this medium tutorial.
What is the correct configuration for a mulit-region setup in EC2 instances?
What should the listen_address, broadcast_address, rpc_address and seed ip/addresses be to work?
When do you use public IP address and when do you use private IP addresses?
According to the docs:
broadcast_address: (Default: listen_address) If your Cassandra cluster is deployed across multiple Amazon EC2 regions and you use the EC2MultiRegionSnitch, set the broadcast_address to public IP address of the node and the listen_address to the private IP.
listen_address: (Default: localhost) The IP address or hostname that other Cassandra nodes use to connect to this node. If left unset, the hostname must resolve to the IP address of this node using/etc/hostname, /etc/hosts, or DNS. Do not specify 0.0.0.0.
rpc_address: (Default: localhost) The listen address for client connections (Thrift remote procedure calls).
seed_provider: (Default: org.apache.cassandra.locator.SimpleSeedProvider) A list of comma-delimited hosts (IP addresses) to use as contact points when a node joins a cluster. Cassandra also uses this list to learn the topology of the ring. When running multiple nodes, you must change the - seeds list from the default value (127.0.0.1). In multiple data-center clusters, the - seeds list should include at least one node from each data center (replication group)
Trying to summarize:
the rpc_address is used for client connections and has nothing to do with multi-region EC2
the listen_address and broadcast_address are the 2 important options for multi-region EC2 configuration
in general when configuring any of these answer 2 questions:
who is connecting? (another nodes? clients?)
what IPs are accessible? (is this network interface accessible to who is connecting?)
I don't know how exactly to formulate my question but i will try to explain what i am asking for.
I have a firm that developes gps devices and each device is beeing put on a separate vehicle. The devices' firmware have hardcoded IP adress that they send the current data to.
I have a server at the firm that accepts the data from the devices. However the bussiness is growing and i don't want to risk using it. That is why i'm thinking about moving the server's software to amazon EC2.
Before doing that i want to know if it is possible to use my current IP adress on the amazon EC2 service because there is NO way to change the IP address that is hardcoded on the devices'firmware.
So let's summarize the situation.
A <-- Gps device with firmware that sends data to address x.y.z.w
B <-- Server with special software that accepts data from A. The server IP is x.y.z.w
C <-- Amazon EC2 service with IP address: a.b.c.d
I want to get rid of server B. So A ->> sends data to ->> server C.
How to congigure server C so that it uses the ip address of server B (having in mind that server C is in different county with different Ip address range ) ?
Here is what I would do, keep in mind that I don't know the details of what kind of connection is made.
The hard coded IP Address would map to a load balancer/proxy at your site/datacenter. This will balance traffic between one or more servers either at your site or on ec2 which runs the software for your application.
For high availability purposes, I would configure a heartbeat monitor on the load balancer to fail over to a backup load balancer should it fail.
You still have a failure point in that it would be difficult to redirect traffic to another site should your site go down.
Imagine a Windows box, which:
hosts a WCF service
has multiple NICs
sits behind NAT
When a user issues a request to the service (on top of the WCF infrastructure), he uses the external address assigned to the target machine by the NAT.
I have to write some piece of code inside the WCF service, which must know which of the several NICs that the machine has was used to actually handle the network traffic. How does this code identify the NIC is less important - it could be its MAC address (the best) or it could be the (internal) IP address of the NIC.
How can I do it?
EDIT1
I will try to supply the question context. There are two agents. Both expose the same WCF service. In addition, one of the agents can be instructed to start probing the network towards the second agent in the following fashion:
Agent A is asked to probe the network to agent B
Agent A negotiates with agent B the UDP port to utilize for the sake of probing using the WCF service exposed by the agent B.
Once negotiation is over, the agent A starts some custom protocol over UDP, where the agent B acts as the server - i.e. it binds to the UDP port negotiated in the previous item.
Binding to a UDP port requires two pieces - the IP address and UDP port, where the IP address can either be a specific IP address or * (to bind to all the IP addresses associated with the machine). The latter option is not good for us - I will omit the reasons. This leaves us the former option - binding to the specific IP address. However, when the agent B is behind NAT, the IP address used to talk to the WCF service is the external IP address assigned to the agent by the NAT. Binding, on the other hand, requires the respective internal IP address - how to get it?
Can you check the OperationContext.Current.Channel.LocalAddress (it's an EndpointAddress) inside a WCF operation?
As a side note, getting the remote address can be done with:
OperationContext context = OperationContext.Current;
MessageProperties prop = context.IncomingMessageProperties;
RemoteEndpointMessageProperty endpoint =
prop[RemoteEndpointMessageProperty.Name] as RemoteEndpointMessageProperty;
string ip = endpoint.Address;
--larsw
To get the MAC use
System.Net.NetworkInformation.NetworkInterface.GetPhysicalAddress();
All Nics:
System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces();
to find out what is the real listening ip address you can write a code that listen to your port on each address and ping it from an agent emulator to see that the address is valid.
Cheers,
Gilad