What does these properties mean in Fabric docker image? - docker-compose

- CORE_PEER_ID=shop-peer
- CORE_PEER_ADDRESS=shop-peer:7051
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=shop-peer:7051
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=build-blockchain-insurance-app_default
I have these properties in docker.
Question 1) I know what CORE_PEER_GOSSIP_EXTERNALENDPOINT means, but why in the examples do they specify the same peer. What I mean is, these properties are for shop-peer and in external-endpoint, it specified itself(shop-peer:7051).
Question 2) what is CORE_PEER_ID ? is its value related to some other things in Fabric so that if I don't write shop-peer here, shall I have the error or I can specify whatever name I want in CORE_PEER_ID?
Question 3) what is CORE_VM_ENDPOINT and CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE and what do they mean?

CORE_PEER_GOSSIP_EXTERNALENDPOINT - this is the endpoint used by external peers to communicate with this peer. Can be different to the internal endpoint due to the use of port mapping through firewalls for external connections.
CORE_PEER_ID - this is used by the peer to build the name of the chaincode container, so it at least needs to be unique for all peers running on a single machine. It's likely also used elsewhere as a unique identifier, so should be unique, but can be any value.
CORE_VM_ENDPOINT - used by the peer to create/run docker containers for running chaincode.
CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE - sets the network used by chaincode containers.

Related

Failed to accept an incoming connection: connection from "9.42.x.x" rejected, allowed hosts: "zabbix-server"

SUMMARY
I have installed zabbix on OpenShift cluster. I am trying to monitor a host(vm) outside the cluster but the zabbix server is unable to connect to it. In the /etc/zabbix/zabbix_agentd.conf file I have mentioned the DNS name of the server zabbix-server but it looks like there server is trying to connect through a different public IP. I am not sure what this IP is.
OS / ENVIRONMENT / Used docker-compose files
I applied the kubernetes.yaml file present in this repo - https://github.com/zabbix/zabbix-docker/blob/6.2/kubernetes.yaml - on an OpenShift cluster.
CONFIGURATION
In the /etc/zabbix/zabbix_agentd.conf file Server=zabbix-server.
STEPS TO REPRODUCE
Apply the kubernetes.yaml file on Openshift cluster and try to monitor any external vm.
EXPECTED RESULTS
The zabbix server should be able to connect to the vm.
ACTUAL RESULTS
Zabbix server logs.
Defaulted container "zabbix-server" out of: zabbix-server, zabbix-snmptraps
\*\* Updating '/etc/zabbix/zabbix_server.conf' parameter "DBHost": 'mysql-server'...added
287:20230120:060843.131 Zabbix agent item "system.cpu.load\[all,avg5\]" on host "Host-C" failed: first network error, wait for 15 seconds
289:20230120:060858.592 Zabbix agent item "system.cpu.num" on host "Host-C" failed: another network error, wait for 15 seconds
289:20230120:060913.843 Zabbix agent item "system.sw.arch" on host "Host-C" failed: another network error, wait for 15 seconds
289:20230120:060929.095 temporarily disabling Zabbix agent checks on host "Host-C": interface unavailable
Logs from the agent installed on the vm.
350446:20230122:103232.230 failed to accept an incoming connection: connection from "9.x.x.219" rejected, allowed hosts: "zabbix-server"
350444:20230122:103332.525 failed to accept an incoming connection: connection from "9.x.x.219" rejected, allowed hosts: "zabbix-server"
350445:20230122:103432.819 failed to accept an incoming connection: connection from "9.x.x.210" rejected, allowed hosts: "zabbix-server"
350446:20230122:103533.114 failed to accept an incoming connection: connection from "9.x.x.217" rejected, allowed hosts: "zabbix-server"
If I add this IP in /etc/zabbix/zabbix_agentd.conf it will work. But what IP is this? Is this a service? Or any node/pod IP? It keeps on changing. Everytime I cannot change this id in the conf file. I need something more stable.
Kindly help me out with this issue.
So I don't know zabbix. So I have to make some educated guesses both in how the agent works and how the server works.
But, to summarize, unlike something like docker compose where you are running the zabbix server on a known server, in Openshift/Kubernetes you are deploying into a cluster of machines with their own networking. In other words, the whole point of OpenShift is that OpenShift will control where the application's pod gets deployed and will relocate/restart that pod as needed. With a different IP every time. (And the DNS name is meaningless since the two systems aren't sharing DNS anyway.) Most likely the IP's you are seeing are the pod's randomly assigned IPs.
So, what are you to do when you have a situation like yours where an external application requires a predicable IP? Well, option 1, is to remove that requirement. Using something like a certificate is obviously more secure and more reliable than depending on an IP anyway. But another option is to use an egress IP. This is a feature of OpenShift where you essentially use a proxy to provide an external application with a consistent IP.

Remote EJB in Kubernetes

I'm trying to setup a remote EJB call between 2 WebSphere Liberty servers deployed in k8s.
Yes, I'm aware that EJB is not something one would want to use when deploying in k8s, but I have to deal with it for now.
The problem I have is how to expose remote ORB IP:port in k8s. From what I understand, it's only possible to get it to work if both client and remote "listen" on the same IP. I'm not a network expert, and I'm quite fresh in k8s, so maybe I'm missing something here, that's why I need help.
The only way I got it to work is when I explicitly set host on remote server to it's own IP address and then accessed it from client on that same IP. This test was done on Docker host with macvlan0 network (each container had it's own IP address).
This is ORB setup for remote server.xml configuration:
<iiopEndpoint id="defaultIiopEndpoint" host="172.30.106.227" iiopPort="2809" />
<orb id="defaultOrb" iiopEndpointRef="defaultIiopEndpoint">
<serverPolicy.csiv2>
<layers>
<!-- don't care about security at this point -->
<authenticationLayer establishTrustInClient="Never"/>
<transportLayer sslEnabled="false"/>
</layers>
</serverPolicy.csiv2>
</orb>
And client server.xml configuration:
<orb id="defaultOrb">
<clientPolicy.csiv2>
<layers>
<!-- really, I don't care about security -->
<authenticationLayer establishTrustInClient="Never"/>
<transportLayer sslEnabled="false"/>
</layers>
</clientPolicy.csiv2>
</orb>
From client, this is JNDI name I try to access it:
corbaname::172.30.106.227:2809#ejb/global/some-app/ejb/BeanName!org\.example\.com\.BeanRemote
And this works.
Since one doesn't want to set fixed IP when exposing ORB port, I have to find a way to expose it dynamically, based on host IP.
Exposing on 0.0.0.0 does not work. Same goes for localhost. In both cases, client refuses to connect with this kind of error:
Error connecting to host=0.0.0.0, port=2809: Connection refused (Connection refused)
In k8s, I've exposed port 2809 through LoadBalancer service for remote pods, and try to access remote server from client pod, where I've set remote's service IP address in corbaname definition.
This, of course, does not work. I can access remote ip:port by telnet, so it's not a network issue.
I've tried all combinations of setup on remote server. Exporting on host="0.0.0.0" results with same exception as above (Connection refused).
I'm not sure exporting on internal IP address would work either, but even if it would, I don't know the internal IP before pod is deployed in k8s. Or is there a way to know? There is no env. variable with it, I've checked.
Exposing on service IP address (with host="${REMOTE_APP_SERVICE_HOST}") fails with this error:
The server socket could not be opened on 2,809. The exception message is Cannot assign requested address (Bind failed).
Again, I know replacing EJB with Rest is the way to go, but it's not an option for now (don't ask why).
Help, please!
EDIT:
I've managed to get some progress. Actually, I believe I've successfully called remote EJB.
What I did was add hostAliases in pod definition, which added alias for my host, something like this:
hostAliases:
- ip: 0.0.0.0
hostnames:
- my.host.name
Then I added this host name to remote server.xml:
<iiopEndpoint id="defaultIiopEndpoint" host="my.host.name" iiopPort="2809" />
I've also added host alias to my client pod:
hostAliases:
- ip: {remote.server.service.ip.here}
hostnames:
- my.host.name
Finally, I've changed JNDI name to:
corbaname::my.host.name:2809#ejb/global/some-app/ejb/BeanName!org\.example\.com\.BeanRemote
With this setup, remote server was successfully called!
However, now I have another problem which I didn't have while testing on Docker host. Lookup is done, but what I get is not what I expect.
Lookup code is pretty much what you'd expect:
Object obj = new InitialContext().lookup(jndi);
BeanRemote remote = (BeanRemote) PortableRemoteObject.narrow(obj, BeanRemote.class);
Unfortunatelly, this narrow call fails with ClassCastException:
Caused by: java.lang.ClassCastException: org.example.com.BeanRemote
at com.ibm.ws.transport.iiop.internal.WSPortableRemoteObjectImpl.narrow(WSPortableRemoteObjectImpl.java:50)
at [internal classes]
at javax.rmi.PortableRemoteObject.narrow(PortableRemoteObject.java:62)
Object I do receive is org.omg.stub.java.rmi._Remote_Stub. Any ideas?
Solved it!
So, the first problem was resolving host mapping, which was resolved as mentioned in edit above, by adding host aliases id pod definitions:
Remote pod:
hostAliases:
- ip: 0.0.0.0
hostnames:
- my.host.name
Client pod:
hostAliases:
- ip: {remote.server.service.ip.here}
hostnames:
- my.host.name
Remote server then has to use that host name in iiop host definition:
<iiopEndpoint id="defaultIiopEndpoint" host="my.host.name" iiopPort="2809" />
Also, client has to reference that host name through JNDI lookup:
corbaname::my.host.name:2809#ejb/global/some-app/ejb/BeanName!org\.example\.com\.BeanRemote
This setup resolves remote EJB call.
The other problem with ClassCastException was really unusual. I managed to reproduce the error on Docker host and then changed one thing at a time until the problem was resolved. It turns out that the problem was with ldapRegistry-3.0 feature (!?). Adding this feature to client's feature list resolved my problem:
<feature>ldapRegistry-3.0</feature>
With this feature added, remote EJB was successfully called.

Docker: run multiple container on same tcp ports with different hostname

Is there a way to run multiple docker containers on the same ports? For example, I have used the ports 80/443 (HTTP), 3306 (TCP/MySQL) and 22 (TCP/SSH) in my docker-compose file. Now I want to run this docker-compose for different hostnames on the same ip address on my machine.
- traffic from example1.com (default public ip) => container1
- traffic from example2.com (default public ip) => container2
I have already found a solution only for the HTTP traffic by using an additional nginx/haproxy as a proxy on my machine. But unfortunately, this can't handle other TCP ports.
This isn't possible in the general (non-HTTP) case.
At a lower level, if I connect to 10.20.30.40:3306, the Linux kernel selects a single process that's listening on that port and sends the request there. You're not allowed to bind(2) a second process to the same port. (This is also why you get an error if you try to docker run -p picking a host port that's already in use.)
In the case of HTTP, there's the further detail that the host-name part of the URL is also sent in an HTTP Host: header: the Web browser both does a DNS lookup for e.g. stackoverflow.com and connects to its IP address, and also sends a Host: stackoverflow.com HTTP header. That's the specific mechanism that lets you run a proxy on port 80, and then forward to some other backend service via a virtual-host setup.
That mechanism is very specific to HTTP, though, and doesn't work for other protocols that don't have support for it. I don't think either MySQL or ssh have similar mechanisms in their wire protocol.
(In the particular situation you describe this is probably relatively easy to handle. You wouldn't want to make either your internal database or an sshd visible publicly, so delete their ports: from your docker-compose.yml file, and then just worry about proxying the HTTP service. It's pretty unusual and a complex setup to run sshd in Docker so you also might remove that and simplify your stack a little.)

How to expose amqps rabbitmq protocol in k8s environment externally?

I was wondering -
When setting rabbitmq nodes to use a TLS connection (as seen here https://github.com/artooro/rabbitmq-kubernetes-ha/blob/master/configmap.yaml), as I understand, I need to create a certificate that matches the hostname, wildcard can be used - https://www.rabbitmq.com/clustering-ssl.html.
As cluster dns is internal, I guess I should create a certificate with a common name such as - ‘*.rabbitmq.default.svc.cluster.local’.
When I’m exposing the service, I'm supposed to create either a NodePort service or a LoadBalancer service - with a totally different hostname (it should route internally).
My question is - how will the amqps connection work? Won't it present me with one of the node’s certificates - which will not match the load balancer’s dns?
What's the correct way to expose the amqps protocol?
Thanks in advance
If anyone is looking at it, it doesn't matter - this is not a "standard" https connection.
The client needs to specify the correct common name and that's enough for the connection to work.

Consul.io - how to run multiple servers on same machine

This is probably a very basic question for you, but I'm just getting into consul and for testing purposes, I wanna run multiple servers on my PC. For example, I run the first server with
consul agent -server -bootstrap-expect=1 -dc=dev -data-dir=/tmp/consul -ui-dir="c:/consul 0.5.2/dist"
and then I try to run the second server with
consul agent -server -data-dir=/tmp/consul2 -dc=dc2
but it returns
==> Error starting agent: Failed to start Consul server: Failed to start RPC lay
er: listen tcp 0.0.0.0:8300: bind: Only one usage of each socket address (protoc
ol/network address/port) is normally permitted.
What am I missing from my command?
You are launching two consul servers using mostly default values. In this case the problem is that you use default ports.
When you read the error message you will notice that your second consul server tries to bind to port 8300. But your first server is already using this port, causing the second server to fail at startup. (note: consul binds to a variety of ports, each having another purpose and default setting. Take a look at the documentation).
As suggested by LenW, you can use Vagrant to set your environment. You could follow the consul tutorial.
If you do not want to use vagrant or set up any virtual machines on your own. You could change the defaults of the second server.
If you are trying to simulate a production topology on your dev machine I would look at using Vagrant in combination with VirtualBox to simulate a couple of machines for testing.