Setting up docker containers with nat - containers

I am setting up two docker containers
container1 container2
| | |
eth0 eth1 |
| | eth1
docker0 docker1<----------------
|
|
internet
docker0 and docker1 are the bridges.
I have ip forwarding to 1 in both host and in containers.
I have setup
iptables -I POSTROUTING -t nat -o eth0 -j MASQUERADE in container 1
Still i am not able to ping anything from container 2 to internet. I can see that packets are being received at eth1 of container 1.
OS: ubuntu 13.10
docker version: 0.11.1, build fb99f99
Am i missing some configuration?
Steps to reproduce:
SERV=$(docker run --privileged=true -i -d -t -v ~/Projects/code/myproject/build:/build:ro debian:7.4 /bin/bash)
CLI=$(docker run --privileged=true -i -d -t -v ~/Projects/code/myproject/build:/build:ro debian:7.4 /bin/bash)
sudo pipework br1 $SERV 10.1.0.1/8
sudo pipework br1 $CLI 10.1.0.3/8
In $SERV:
iptables -I POSTROUTING -t nat -o eth0 -j MASQUERADE
In $CLI
Disable the interface eth0. Set default route to eth1 interface.
Now ping is happening to 10.1.0.1 from $CLI but not to the internet.

Hm, it should work as you described. Maybe the default route is not configured correctly.
This is what I did:
SERV=$(docker run -i --privileged -d -t debian:7.4 /bin/bash)
CLI=$(docker run --privileged -i -d -t debian:7.4 /bin/bash)
docker exec -ti $CLI ping google.de # Internet up
docker exec -ti $CLI ip link set eth0 down
docker exec -ti $CLI ping google.de # Internet down
pipework br1 $SERV 10.1.0.1/8
pipework br1 $CLI 10.1.0.2/8
docker exec -ti $SERV apt-get install -y iptables
docker exec -ti $SERV iptables -I POSTROUTING -t nat -o eth0 -j MASQUERADE
docker exec -ti $CLI ip route add default via 10.1.0.1 dev eth1
docker exec -ti $CLI ping google.de # Internet up
docker exec -ti $CLI apt-get install -y traceroute
docker exec -ti $CLI traceroute google.de

The only way iptables is changed is when executed from Docker host on a containers run with
--privileged
Here is a script:
iptables along with a couple of tools are installed during the image build (Dcokerfile)
inetutils-traceroute iputils-tracepath iptables
Here I use "phusion-dockerbase", you can use whatever image you want:
#!/bin/bash
### ==> Install & configure iptable during build
#RUN sudo apt-get install -y inetutils-traceroute iputils-tracepath iptables
# Build the image
#sudo docker build -t mybimage -f phusion-dockerbase .
### container1
C1=$(docker run --privileged -i -d -t mybimage /bin/bash)
sudo docker exec -ti $C1 iptables -I POSTROUTING -t nat -o eth0 -j MASQUERADE
sleep 2
sudo pipework br6 -i eth1 $C1 192.168.66.1/24
### container2
lxterminal -e "sudo docker run -ti --name c2name mybimage /bin/bash"
sleep 2
C2="$(sudo docker ps | grep c2name | awk '{ print $1; }')"
sudo pipework br6 -i eth1 $C2 192.168.66.2/24#192.168.66.1
Result:
./lab.sh
From the Container1 (I use lxterminal to open it in a new window):
Note that, as soon as you stop container1, corresponding pipework and iptable modification are lost and even when restart the stopped container, you will need to reissue the commands:
pipework br6 -i eth1 52b95d6052f7 192.168.66.1/24
docker exec 52b95d6052f7 iptables -I POSTROUTING -t nat -o eth0 -j MASQUERADE
for container1 to act again like nat box.
Even commiting the running container1 to a new image and run a new container from it, doesn't help.

Related

centos7: Operation not permitted - mysql

I have installed mysql in centOS and now, want to start the mysql-server. However, I get that error:
# systemctl start mysqld
Failed to get D-Bus connection: Operation not permitted
To fix it, I created a Dockerfile as shown
FROM centos:7
MAINTAINER theodosiostziomakas <mymail#gmail.com>
ENV container docker
RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i
== systemd-tmpfiles-setup.service ] || rm -f $i; done); \
rm -f /lib/systemd/system/multi-user.target.wants/*;\
rm -f /etc/systemd/system/*.wants/*;\
rm -f /lib/systemd/system/local-fs.target.wants/*; \
rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
rm -f /lib/systemd/system/basic.target.wants/*;\
rm -f /lib/systemd/system/anaconda.target.wants/*;
VOLUME [ "/sys/fs/cgroup" ]
CMD ["/usr/sbin/init"]
And then run it to create an image.
$ docker build --rm -t local/c7-systemd .
But I am still getting the same error.
I also looked at this proposed solution
Any ideas?
Thanks,
Theo.
I believe the issue with the Dockerfile or with the run command
It seems the issue in you Dockerfile is in this line
RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == \
Here is MySQL centos Dockerfile
# Starting from base CentOS image
FROM centos:7
# Enabling SystemD
ENV container docker
RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == \
systemd-tmpfiles-setup.service ] || rm -f $i; done); \
rm -f /lib/systemd/system/multi-user.target.wants/*;\
rm -f /etc/systemd/system/*.wants/*;\
rm -f /lib/systemd/system/local-fs.target.wants/*; \
rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
rm -f /lib/systemd/system/basic.target.wants/*;\
rm -f /lib/systemd/system/anaconda.target.wants/*;
VOLUME [ "/sys/fs/cgroup" ]
# Enabling EPEL & Remi repo
#RUN yum install -y epel-release && \
#yum install -y http://rpms.remirepo.net/enterprise/remi-release-7.rpm
# Mysql repo & installion
RUN yum install -y https://dev.mysql.com/get/mysql57-community-release-el7-9.noarch.rpm && \
yum install -y mysql mysql-server
RUN chkconfig --level 345 mysqld on
RUN systemctl enable mysqld
VOLUME [ "/var/lib/mysql" ]
# Port Expose
EXPOSE 3306
CMD ["/usr/sbin/init"]
Now, Next step is to run
--privileged is not enough, you also need to mount cgroup
Here is the command
docker run --privileged -v /sys/fs/cgroup:/sys/fs/cgroup:ro -it adilm7177/centos-mysql
You can build your own or you can pull the above image from docker registry that i build and push during testing.
docker push adilm7177/centos-mysql:latest
Update:
RUN systemctl enable mysqld
After adding this I am able to start-stop using systemctl
I am able to run mysql just fine with the docker-systemctl-replacement script which emulates "systemctl" commands without an active systemd daemon. You can look at that at the docker-systemctl-images examples.

How to run bash on docker container with entry point?

How can I run bash on a container with an ENTRYPOINT?
FROM ubuntu:18.04
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update \
&& apt-get install -y curl gnupg
RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash \
&& export NVM_DIR="$HOME/.nvm" \
&& [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" \
&& [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" \
&& nvm i 8.11 \
&& apt-get install -y mysql-server=5.7.23-0ubuntu0.18.04.1 python3 python3-pip \
&& ln -s /usr/bin/python3 /usr/bin/python \
&& ln -s /usr/bin/pip3 /usr/bin/pip \
&& pip install awscli --upgrade --user \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
ENTRYPOINT [ "/etc/init.d/mysql", "start" ]
EXPOSE 3306
I tried:
jiewmeng#JM  ~/Dropbox/ci-docker-node-mysql  docker run -it ci-docker-node-mysql bash
* Starting MySQL database server mysqld No directory, logging in with HOME=/
[ OK ]
jiewmeng#JM  ~/Dropbox/ci-docker-node-mysql 
But I got kicked out once MySQL starts
I tried running my docker container ...
jiewmeng#JM  ~/Dropbox/ci-docker-node-mysql  docker run -p 3307:3306 ci-docker-node-mysql
✘ jiewmeng#JM  ~/Dropbox/ci-docker-node-mysql  mysql -h 127.0.0.1:3307
ERROR 2005 (HY000): Unknown MySQL server host '127.0.0.1:3307' (2)
But seems like I cannot connect. What did I do wrong?
If you want to launch the container using bash:
docker run --rm -it --entrypoint "/bin/bash" ci-docker-node-mysql
Your container exits when the command mysql completes. Containers don't persist once their task is done.
Try to run MySQL in daemon mode which should prevent it from assuming the process is complete:
ENTRYPOINT ["mysqld"]
EDIT: I took a look at the official mysql Docker image and that's how they do it there.
EDIT2: Once that's done, you can run exec to get a shell into the container:
docker exec -ti container-name /bin/bash

NodePort in Openshift is not working

Deployed single node cluster with oc
$ sudo oc cluster up --public-hostname=$PUBLIC_IP
$ oc version
oc v3.7.14
kubernetes v1.7.6+a08f5eeb62
features: Basic-Auth GSSAPI Kerberos SPNEGO
Added allowHostPorts: true in oc edit scc restricted's config.
Deployed an application with NodePort config
tiger-dev 172.30.30.215 <nodes> 8080:30111/TCP 10d
I was not able to access the application with $NODEIP:30111, but I can see the traffic coming into the node and NOT going out.
Update1
iptables rules -> https://pastebin.com/NPeZM26W
$ sudo iptables-save | grep 30111
-A KUBE-NODEPORTS -p tcp -m comment --comment "default/tiger-dev:http" -m tcp --dport 30111 -j KUBE-MARK-MASQ
-A KUBE-NODEPORTS -p tcp -m comment --comment "default/tiger-dev:http" -m tcp --dport 30111 -j KUBE-SVC-PPQAPMXK5BHYARPU

Accessing docker container mysql databases

I am trying to access mysql databases from my docker host to the container.
It's my own dockerfile which install a database expose on port 3306.
I launch my docker with docker-compose, and my compose file is mapping 3308 host port on 3306 container port.
I can access to mysql from the host like this :
mysql -h localhost -P 3308 -u root -pMyPassword
It's working well, but what I can't figure out, is why I can't see any datas from my container?
From inside the container, I have a test databases which I can connect to without any problem. But when I connect from the host to the container mysql process, It seems to show me the mysql datas from the host machine, not from the container one.
Any ideas?
Thanks :)
EDIT 1 :
So here is the first way I can connect to mysql into the container :
docker exec -it MyContainer mysql -uroot -pMyPassword
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test_db |
+--------------------+
It show me my db : test_db
But If i access from :
mysql -h localhost -P 3308 -u root -pMyPassword
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
+--------------------+
My test_db isn't here.
And the result of docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a0de6a691d72 MyContainer "docker-entrypoint.sh" 3 hours ago Up 3 hours 9000/tcp, 0.0.0.0:8085->80/tcp, 0.0.0.0:3308->3306/tcp, 0.0.0.0:8084->8000/tcp, 0.0.0.0:8086->8080/tcp MyContainer
EDIT 2 :
I am developing a standard docker container for web hosting production environnement. Each host is controlled by ajenti. The host work with an nginx reverse proxy which redistribute websites on correct container. Every thing is wokring well. So here is my Dockerfile :
FROM php:5.6-fpm
RUN apt-get update && apt-get install -y --no-install-recommends \
git \
libxml2-dev \
python \
build-essential \
make \
gcc \
python-dev \
locales \
python-pip
RUN dpkg-reconfigure locales && \
locale-gen C.UTF-8 && \
/usr/sbin/update-locale LANG=C.UTF-8
ENV LC_ALL C.UTF-8
ARG MYSQL_ROOT_PASSWORD
RUN export DEBIAN_FRONTEND=noninteractive; \
echo mysql-server mysql-server/root_password password $MYSQL_ROOT_PASSWORD | debconf-set-selections; \
echo mysql-server mysql-server/root_password_again password $MYSQL_ROOT_PASSWORD | debconf-set-selections;
RUN apt-get update && apt-get install -y -q mysql-server php5-mysql
RUN rm /etc/apt/apt.conf.d/docker-gzip-indexes
RUN apt-get update && apt-get install -y wget
RUN wget http://repo.ajenti.org/debian/key -O- | apt-key add -
RUN echo "deb http://repo.ajenti.org/debian main main debian" > /etc/apt/sources.list.d/ajenti.list
RUN apt-get update && apt-get install -y ajenti cron unzip ajenti-v ajenti-v-php-fpm ajenti-v-mysql ajenti-v-nginx
RUN apt-get install -y python-setuptools python-dev \
&& easy_install -U gevent==1.1b3 \
&& sed -i -e s/ssl_version=PROTOCOL_SSLv3/ssl_version=PROTOCOL_SSLv23/ /usr/local/lib/python2.7/dist-packages/gevent-1.1b3-py2.7-linux-x86_64.egg/gevent/ssl.py
EXPOSE 80 8000 8080 3306
RUN mkdir /tmp/tempfiles \
&& mv /srv /tmp/tempfiles \
&& mv /var/lib/mysql /tmp/tempfiles \
&& mv /var/log /tmp/tempfiles \
&& mv /etc/ajenti /tmp/tempfiles
COPY docker-entrypoint.sh /usr/local/bin/
RUN ln -s /usr/local/bin/docker-entrypoint.sh /entrypoint.sh # backwards compat
ENTRYPOINT ["docker-entrypoint.sh"]
As I said, I wanted to be able do deploy a new container easily. So I created a docker-entrypoint.sh which copy wanted files to my volume when I start the container :
#!/bin/bash
DIR="/var/lib/mysql"
# look for empty dir
if [ ! "$(ls -A $DIR)" ]; then
cp -avr /tmp/tempfiles/mysql /var/lib/
fi
# rest of the logic
DIR="/srv"
# look for empty dir
if [ ! "$(ls -A $DIR)" ]; then
cp -avr /tmp/tempfiles/srv /
fi
# rest of the logic
DIR="/var/log"
# look for empty dir
if [ ! "$(ls -A $DIR)" ]; then
cp -avr /tmp/tempfiles/log /var/
fi
# rest of the logic
DIR="/etc/ajenti"
# look for empty dir
if [ ! "$(ls -A $DIR)" ]; then
cp -avr /tmp/tempfiles/ajenti /etc/
fi
# rest of the logic
Finally, my docker-compose.yml to launch everything and map ports :
version: '2'
services:
ajenti:
build:
context: ./dockerfiles/
args:
MYSQL_ROOT_PASSWORD: MyPassword
volumes:
- ./logs:/var/log
- ./html:/srv
- ./ajenti:/etc/ajenti
- ./mysql-data:/var/lib/mysql
- ./apache2:/etc/apache2
ports:
- "8084:8000"
#NGINX
- "8085:80"
#APACHE
- "8086:8080"
- "3308:3306"
Hope this will help to find a solution !
I finally found a solution and it was pretty simple...
First of all, I need to let mysql bind external address, so I changed the line bind-address to '0.0.0.0' inside the container.
Next I just changed the command line with mysql -h 127.0.0.1 -P 3308 -u root -pMyPassword
Now it's fine, I can access container mysql data from the host.
Thanks all for your help :)
In my case I was confused because docker used a different host and port. So you need to find them then do this:
mysql -P <portnumber> -h <host IP> -u db_name -p
Most people would put the docker DB related variables into the environment of the docker container so do this:
sudo docker exec -it container_name env
See if there's a variable called DB_HOST or DB_PORT or something like that. If not then look thru the source code. If it's a PHP project then find a config directory and look in main.php and see
if you execute MySQL operation as entrypoint in the dockerfile file, you will only see that operation when you connect to the container. try changing the entrypoint.
https://docs.docker.com/engine/reference/builder/#entrypoint

iptables causing external sites to have problems when connecting to mysql

Recently I've managed to block all unused ports on my dedicated server (Linux CentOS latest 64-bit) but whenever I do so, sites that connect to my database just simply cannot connect.
iptables -A INPUT -i lo -p tcp --dport 3306 -j ACCEPT
iptables -A OUTPUT -o lo -p tcp --sport 3306 -j ACCEPT
I believe it has something to do with the OUTPUT port, but I am not sure.
Thanks.
If you want to allow remote incoming mysql connections you will need to define an INPUT rule that is not isolated to your local interface:
-A INPUT -m state --state NEW -m tcp -p tcp --dport 3306 -j ACCEPT
In Centos this will be defined in the /etc/sysconfig/iptables file. Then restart:
sudo service iptables restart
Alternatively, from the command line, you can use:
sudo system-config-firewall-tui
To configure your firewall, it is in the package of the same name:
sudo yum install system-config-firewall-tui -y