I am working on a project that requires me to create a virtual CAN network on my host machine
$ sudo modprobe vcan
$ sudo ip link add dev vcan0 type vcan
$ sudo ip link set up vcan0
My ifconfig :
My question is how can I share this interface with my docker container.
If its of any use I ran the following command find / -name "vcan0" -print 2>/dev/null on my host machine :
/sys/class/net/vcan0
/sys/devices/virtual/net/vcan0
/proc/sys/net/ipv4/conf/vcan0
/proc/sys/net/ipv4/neigh/vcan0
I can run the Docker container using docker run --rm -it --network=host ... . The only problem is there is no network isolation b/w docker host and containers anymore. Is there a way to achieve the above but without sharing the host network ?
I haven't found a way to share a CAN network interface with a Docker container without --network=host, but there is a possible workaround. You can use a CAN-UDP bridge, like canneloni or can2udp, to send CAN frames over UDP.
I've used this in the past to connect a physical CAN bus on a remote device to a virtual CAN interface on my laptop. But it should work just as well for a Docker container.
One drawback is that you do have to create a vcan interface in the container. Which requires you to run the container in privileged mode.
You can use --cap-add=NET_ADMIN when you run docker image. This will allow you to create inside container:
$ sudo ip link add dev vcan0 type vcan
$ sudo ip link set up vcan0
Of course vcan driver is loaded on host.
I've written up a blog post that should get you most of the way there. At a high level you need to create a vxcan link and move one end of it into your docker container. Then you can forward traffic from your vcan interface to one end of the vxcan interface, and it will be transmitted to the vxcan inside the container. You'll just need to use the correct kernel headers package and in the final cangw step you'll need to specific vcan0 instead of can0.
https://www.lagerdata.com/blog/forwarding-can-bus-traffic-to-a-docker-container-using-vxcan-on-raspberry-pi
Related
I am simply trying to connect a ROS2 node from my Ubuntu 22.04 VM on my laptop to another ROS2 node on another machine running Ubuntu 18.04. Ideally, I would only have Docker on the second machine (the first machine runs a trivial node that will never change), but I have been trying using a separate container on each.
Here is what I am doing and what I am seeing when I inspect:
(ssh into machine 2 from VM 1.)
A: start up network from machine 2.
sudo docker network create -d overlay --attachable my-attachable-ovrlay
B: start up container 1.
sudo docker run -it --rm test1
C: successfully attach container 1 to the network.
sudo docker network connect dwgyau64pvpenxoj2edu4liqu bold_murdock
D: Confirm the container lists network.
sudo docker inspect -f '{{range $key, $value := .NetworkSettings.Networks}}{{$key}} {{end}}' bold_murdock
prints:
bridge my-attachable-ovrlay
E: Check the network to see container.
sudo docker network inspect my-attachable-ovrlay
prints (among other things):
"Containers": null,
I am new to Docker AND networking, so I could be missing something huge, but I have tried all of the standard suggestions I found online including disabling my firewall, opening a ton of ports using ufw allow on both machines, making sure nodes are active, etc etc etc etc etc.
I tried joining the network from machine 2 and that works and the container is displayed when using network inspect. But when I do that, then machine 1 simply refuses to connect to network.
F: In this situation it gives an error.
sudo docker network connect dwgyau64pvpenxoj2edu4liqu objective_mendel
prints:
Error response from daemon: attaching to network failed, make sure your network options are correct and check manager logs: context deadline exceeded
Also, before trying any docker networking, I have tried plainly pinging from VM1 to machine 2 and that works, both ways. I have tried to use netcat to open an old-timey chat window on port 1234 (random port as per this resource) and that works one way only. I can communicate both ways, but only when machine 1 sends the initial netcat request and machine 2 listens. When machine 2 sends request and 1 listens, nothing happens.
I have been struggling to get this to work for 3 weeks now. I know it’s something stupid, I just know it. Any advice would be incredibly appreciated. Please explain like I know nothing about networking, because I just about do.
EDIT: I converted images (still hyperlinked) into code blocks.
If both PCs are on the same LAN, you could skip the whole network configuration entirely and use ROS2 auto-discovery.
E.g.
PC1:
docker run -it --rm --net=host -v /dev/shm:/dev/shm osrf/ros:foxy-desktop
export ROS_DOMAIN_ID=1
ros2 run demo_nodes_py talker
PC2:
docker run -it --rm --net=host -v /dev/shm:/dev/shm osrf/ros:foxy-desktop
export ROS_DOMAIN_ID=1
ros2 run demo_nodes_py listener
If the PCs are not on the same network, I usually use ZeroTier to create a virtual LAN between PC1, PC2, and PC(N), then repeat the above example.
The issue was that the router was set to 1969. When we updated the time by connecting to the internet for 15 seconds, then disconnected, it started working.
I followed this turorial: https://learn.microsoft.com/en-us/azure/container-instances/tutorial-docker-compose
But when I set up my project there's no default network created.
Anybody know how to solve this?
The default network should be bridge, as can be seen with
$ docker network ls
Whenever you start a container without providing --network flag your container is connected to the default bridge network by default. You can provide the --network bridge flag in your docker run command.
Alternatively, you can connect a container to a network using
$ docker network connect <network> <container>
Is that possible to have multiple IPs on eth0 in a Docker container?
I would like having 5 IPs on eth0 in a Docker container interface. I am using "ip" utility. Executing ip address add 172.20.0.200/16 dev eth0 in the container give "Operation not permited.
I tried manually log to the container as root user using "sudo exec
-u root ..".
I have even tried apt-install sudo in the container. Result is same "Operation not permitted"
I have found the answer. There must be added --cap-add option
docker run --cap-add=NET_ADMIN image
But as I understand docker know nothing about static IPs since docker network inspect shows only one IP. Hence think of using custom network
I create two service, service-a(3 replies) and service-b(5 replies).
They are in micro overlay network.
I want to get all container ip from dns.
# docker run --rm --network micro alpine nslookup service-a
But only get one ip. Is there has anyway to get all IPs address of some service using dns?
Use tasks.<service-name> to get all containers belonging to particular service.
You can use docker inspect to get the virtual IP of a service:
NETWORK_ID=$(docker network ls -q --no-trunc --filter name=micro) && docker service inspect service-a -f "{{range \$i, \$value := .Endpoint.VirtualIPs}} {{if eq \$value.NetworkID \"$NETWORK_ID\" }}{{$value.Addr}}{{end}}{{end}}"
This one line command finds the network ID then use it in a docker inspect to get only the services virtual IPs in this network, using the -f (format) parameter
At the moment I'm running a node.js application inside a docker container which needs to connect to camunda, which runs in another container.
I start the containers with the following command
docker run -d --restart=always --name camunda -p 8000:8080 camunda/camunda-bpm-platform:tomcat-7.4.0
docker run -d --name app -p 3000:3000 app
Both applications are now running and I can access camunda by navigating to my host's IP on port 8000, and running wget http://localhost:8000 -q -O - also returns the camunda page. When I login to my app container with docker exec -it app sh and type wget http://localhost:8000 -q -O -, I cannot access camunda. Instead I get the following error:
wget: can't connect to remote host (127.0.0.1): Connection refused
When I link my app container to the camunda container with --link camunda:camunda, and type wget http://camunda:8000 -q -O - in my app container, I get the following error:
wget: can't connect to remote host (172.17.0.4): Connection refused`
I've seen this option, so I started my app container with --add-host camunda:my_hosts_ip and tried wget again, resulting in:
wget: can't connect to remote host (149.210.227.191): Operation timed out
When running wget http://149.210.227.191:5001 -q -O - on my host machine however, I get a correct response immediately.
Ideally I would like to just start my app container without the need to supply the external IP in any way, and let the app container just use the camunda service via the localhost or by linking the camunda container tot my app container. What would be the easiest way to achieve this?
Why does it not work?
Containers and host do not share their local IP stack. Thus, when you are within a container and try anything localhost:port the anything command will try to connect to the container-specific local IP stack, not the other container nor the host.
How to make it work?
Hard way: you either need to know the IP address of the other container and connect to this IP address..
Easier and cleaner way: .. either link your containers.
--link=[]
Add link to another container in the form of <name or id>:alias or just <name or id> in which case the alias will match the name
So you'll need to perform, assuming the camunda container is named camunda:
docker run -d --name app -p 3000:3000 --link camunda app
Then, once you docker-exec-ed into the container app you will be able to execute wget http://camunda:8080 -q -O - without error.
Note that while the linked containers graph cannot loop, e.g., camunda cannot be linked to app as you need to start a container to be able to link it, you actually do whatever you want/need playing with IP addresses.
Note also that you can specify the IP address of a container using the --ip option (though it can only be used in conjunction with --net for user-defined networks).
Original answer below. Note that link has been deprecated and the recommended replacement is network. That is explained in the answer to this question: docker-compose: difference between network and link
--
Use the --link camunda:camunda option for your app container. Then you can access camunda via http://camunda:8080/.... The link option adds a entry to the /etc/hosts file of the app container with the IP address of the camunda container. This also means you have to restart your app container if you restart the camunda container.