Docker:从环境搭建到容器端口映射

Docker初探

一.安装DockerCE

1.为啥我要安装DockerCE呢?其实我也不明白,稀里糊涂就装了CE版本:可以参考官方文档(https://docs.docker.com/engine/installation/linux/docker-ce/ubuntu/#extra-steps-for-aufs)
另外我安装Docker的系统是ubuntu16.04
$ sudo apt-get update
$ sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    software-properties-common
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"
$ sudo apt-get update
$ sudo apt-get install docker-ce
经过以上几步,恭喜你,DockerCE已经安装完成了!!!
下面就是测试:

$ sudo docker run hello-world
如果安装正确,那么这条命令将从Docker官网上下载hello-world镜像并在本地运行。

二.我理解的Docker

Docker只是一个用命令行来实现的虚拟机。相较于WM,他的功能更加强大一点,可能和virtualbox相似(我没用过VB,不过VB创建虚拟机好像也可以用命令行)。不过Docker-machine、docker-compose、docker-swarm提供了比VM和VB更加强大的功能。值得一提的是,一般我们所讲的Docker均是指Docker-engine,本篇文章讲的Docker指的是docker-engine。等作者开始研究其他三个的时候再另发博客。

三.images、container

VM以及VB在创建虚拟机时需要使用iso镜像文件,然而docker不需要或者说他已经把镜像文件都传到了官网上,我们只需要从Docker官网下载即可。
1.Images
首先是创建images,创建images有两种方法,一种是使用docker pull。比如说我们要使用docker版的ubuntu系统,就可以使用docker pull ubuntu。更多的镜像可以再https://hub.docker.com/中找到。另一种方法时使用dockerfile文件,使用过程中更倾向于使用后者创建docker image。至于dockerfile的用法网上有很多例子。dockerfile其实很简单,有兴趣的可以网上学习一下,这里简单给一个安装了c++以及boost运行环境的dockerfile:
FROM ubuntu:16.04
MAINTAINER Uncle_Orange <250316792@qq.com>

LABEL description="ubuntu C++ build environment."

RUN apt-get update && apt-get install -y \
    apt-transport-https \
    ca-certificates \
    curl \
    software-properties-common

RUN curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -

ADD sources.list /etc/apt/

RUN apt-get update && apt-get install -y \
#  gcc \
#  clang \
#  cmake \
#  libgtest-dev \
#  libgoogle-glog-dev \
#  libboost-all-dev \
#  g++ `#Fb folly deps` \
#  automake \
#  autoconf \
#  autoconf-archive \
#  libtool \
#  libboost-all-dev \
#  libevent-dev \
#  libdouble-conversion-dev \
#  libgoogle-glog-dev \
#  libgflags-dev \
#  liblz4-dev \
#  liblzma-dev \
#  libsnappy-dev \
#  make \
#  zlib1g-dev \
#  binutils-dev \
#  libjemalloc-dev \
#  libssl-dev \
#  libiberty-dev\
   build-essential\
   libboost-all-dev\
   cmake\
   iputils-ping\
   net-tools\
   nano

ENV LIBRARY_PATH=/libs
ENV CPLUS_INCLUDE_PATH=/libs/include

RUN mkdir /src
RUN mkdir /build
WORKDIR /build

CMD ["/bin/bash"]
创建镜像命令:
进入到dockerfile所在的文件夹,然后注意后面有'.'表示当前目录。这样就有自己的镜像了。
docker build -t uo/ubuntu:v1.0 .
2.container
创建容器:
docker run。具体参数不贴了,可以自己-h查看一下。

四.容器端口映射

在https://docs.docker.com/get-started/part2/上有一个使用dcoker+python实现的一个简单网页,可以自己按照教程实现一下。该例子在创建容器的时候使用了
docker run -p 4000:80 friendlyhello
将容器作为web服务端,80端口映射到主机的4000端口上。并且在dockerfile中加入了expose 80这个命令(这个命令实现和docker run -p同样的效果?还是必须和docker run -p配合使用?这个还没试过,有兴趣的朋友可以试一下,然后最好能告诉一下结果)总之在使用上述配置和命令后能从作者的主机直接访问web服务器,这也是官方例子给的结果。
那么下面就进入正题了,如何在没有配置的情况下任然能联通呢?因为在开发过程中很多情况下多需要临时增加端口是很常见的情况,网上找了两种方法

Docker 给运行中的容器添加映射端口方法1  

  1. 获得容器IP

     
       
    1. $ docker inspect `container_name` | grep IPAddress

    比如我的容器叫mysqlserver么就输入下列代码来获取该容器的ip地址

     
       
    1. $ docker inspect mysqlserver | grep IPAddress

    执行完之后会发现我的mysqlserverdocker容器的ip地址为192.168.0.2

  2. iptables转发端口

    比如我将容器的3306端口映射到主机的37221端口,那么ip对应就写入我的docker容器IP即可

     
       
    1. iptables -t nat -A DOCKER -p tcp --dport 37221 -j DNAT --to-destination 192.168.0.2:3306

Docker 给运行中的容器添加映射端口方法2

  1. 提交一个运行中的容器为镜像

     
       
    1. $ docker commit containerid foo/live
  2. 运行镜像并添加端口

     
       
    1. $ docker run -d -p 8000:80 foo/live /bin/bash
关于第一种方法,尝试之后失败了。(个人估计可能在dockerfile中有expose 37221这一命令,但是docker run的时候没写的-p 37221情况下该种方法有用。我说情况是dockerfile中没写,run中也没有-p参数)第二种方法没有尝试。
对比官方给的web服务器的例子,使用iptables -t nat -nL以及iptables -t filter-nL查看防火墙可以看到,其实就是增加了几条规则。或者说docker-p参数以及dockerfile中的expose关键字其实就是在使用iptables增加规则。
知道了这个就好办了,下面是楼主的解决办法:
sudo iptables -t filter -A DOCKER -p udp -d 172.17.0.2 --dport 9876 -j ACCEPT
sudo iptables -t nat -A DOCKER -p udp --dport 9876 -j DNAT --to-destination 172.17.0.2:9876
没错,就只有两行!!!!这两行试了做好久,
同时贴上几个相关帖子:
http://blog.csdn.net/u011350541/article/details/50781040
http://blog.csdn.net/cooling88/article/details/51040054
https://www.cnblogs.com/kevingrace/p/5865792.html
至于验证嘛,作者写了一个udp发信信息的服务端,传到了所创建的uo/ubuntu中,然后从主机上发送udp消息。可以看到所创建的容器能正确接收到信息。
顺便在这里提一下作者的网络拓扑:
作者主机:192.168.10.2
安装docker的虚拟机:192.168.10.100
容器IP:172.17.0.2
作者直接向192.168.10.100:9876发信udp包,在172.17.0.2中能正确接收信息。相当于192.168.10.100做了一次nat转换(截图就不截了)

备注:Docker-machine、docker-compose、docker-swarm、docker-volume都需要研究一下,其中docker-colume和共享存储服务无缝切换有关。等下次研究一下再继续更新
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值