Dockerfile

FROM ubuntu:14.04
MAINTAINER juedaiyuer "juedaiyuer@gmail.com"
ENV REFRESHED_AT 2016-07-10

RUN apt-get update
RUN apt-get install -y ruby ruby-dev build-essential redis-tools
RUN gem install --no-rdoc --no-ri sinatra json redis

RUN mkdir -p /opt/webapp

EXPOSE 4567

CMD [ "/opt/webapp/bin/webapp" ]


#构建新的sinatra镜像
$ sudo docker build -t juedaiyuer/sinatra .


gem install json 
ERROR:  Error installing json:
json requires Ruby version ~> 2.0.

创建Sinatra容器

#sinatra web应用程序的源代码---sinatra/webapp/bin lib

#确保webapp/bin/webapp可以执行

#启动第一个sinatra容器
#没有在命令行中指定命令,而是在dockerfile中的CMD指定
$ sudo docker run -d -p 4567 --name webapp -v $PWD/webapp:/opt/webapp juedaiyuer/sinatra

#查看执行的命令都输出了什么
$ sudo docker logs webapp

#类似于tail -f
$ sudo docker logs -f webapp

#列出sinatra进程
$ sudo docker top webapp

#检查sinatra的端口映射
$ sudo docker port webapp 4567


#测试Sinatra应用程序
$ curl -i -H 'Accept:application/json' -d 'name=Foo&status=Bar' http://localhost:32773/json
HTTP/1.1 200 OK 
Content-Type: text/html;charset=utf-8
Content-Length: 29
X-Xss-Protection: 1; mode=block
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Server: WEBrick/1.3.1 (Ruby/1.9.3/2013-11-22)
Date: Mon, 11 Jul 2016 02:29:19 GMT
Connection: Keep-Alive

{"name":"Foo","status":"Bar"}

构建Redis镜像和容器

FROM ubuntu:14.04
MAINTAINER juedaiyuer "juedaiyuer@gmail.com"
ENV REFRESHED_AT 2016-07-10
RUN apt-get update
RUN apt-get -y install redis-server redis-tools
EXPOSE 6379
ENTRYPOINT ["/usr/bin/redis-server"]
CMD []

$ sudo docker build -t juedaiyuer/reids .

$ sudo docker run -d -p 6379 --name redis juedaiyuer/redis 

#查看端口
$ sudo docker port redis 6379

#本地安装Redis客户端测试,客户端程序一般在redis-tools
$ sudo apt-get -y install redis-tools
#测试连接到Redis服务器
$ sudo redis-cli -h 127.0.0.1 -p 32768
127.0.0.1:32768> 

两容器的连接

更新Sinatra应用程序,让其连接到Redis并存储传入的参数,需要与Redis服务器对话

Docker网络栈-内部网络

安装docker时,会创建一个新的网络接口,叫docker0;每个容器都会在这个接口上分配一个IP地址

$ ip a show docker0
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:66:f4:4d:54 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:66ff:fef4:4d54/64 scope link 
       valid_lft forever preferred_lft forever
  • docker0接口符合RFC1918的私有IP地址,范围是172.16~172.30
  • 接口本身的地址127.17.42.1,即这个Docker网络的网关地址
  • 默认172.17.x.x作为子网地址,如果被占用,会尝试其它范围
  • 虚拟的以太网桥,用于连接容器和本地宿主网络

    容器里内的eth0接口

    $ sudo docker run -t -i ubuntu /bin/bash
    root@d74391e80f73:/# ip a show eth0
    11: eth0@if12:

配置建立连接

#Docker的iptables和NAT配置

连接Redis

#查看Redis容器的网络配置
$ sudo docker inspect redis

"NetworkSettings": {
    "Bridge": "",
    "SandboxID": "41329028a8fffcc4f5c46f22e4f3c9453afcd37aa54dd7ae1a138b246e2ec447",
    "HairpinMode": false,
    "LinkLocalIPv6Address": "",
    "LinkLocalIPv6PrefixLen": 0,
    "Ports": {
        "6379/tcp": [
            {
                "HostIp": "0.0.0.0",
                "HostPort": "32768"
            }
        ]
    },

...

#查看Redis容器的IP地址
$ sudo docker inspect -f '{{ .NetworkSettings.IPAddress }}' redis
172.17.0.2

$ redis-cli -h 172.17.0.2
172.17.0.2:6379> 
  1. 要在应用程序里对Redis容器的IP地址做硬编码
  2. 重启容器,Docker会改变容器的IP地址

让Docker容器互连

#启动另一个Redis容器
#测试前,需要删除重名容器
$ sudo docker run -d --name juedaiyuer/redis

#连接Redis容器
$ sudo docker run -p 4567 --name webapp --link redis:db -t -i -v $PWD/webapp:/opt/webapp juedaiyuer/sinatra /bin/bash

#查看连接信息
root@08d78050e896:/# cat /etc/hosts
127.0.0.1   localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2  db f1c6804d67e9 redis
172.17.0.3  08d78050e896

#显示用于连接的环境变量
root@08d78050e896:/# env
HOSTNAME=08d78050e896
DB_NAME=/webapp/db
DB_PORT_6379_TCP_PORT=6379
TERM=xterm
DB_PORT=tcp://172.17.0.2:6379
DB_PORT_6379_TCP=tcp://172.17.0.2:6379

...

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
REFRESHED_AT=2016-07-10
PWD=/
DB_PORT_6379_TCP_ADDR=172.17.0.2
DB_PORT_6379_TCP_PROTO=tcp
SHLVL=1
HOME=/root
LESSOPEN=| /usr/bin/lesspipe %s
LESSCLOSE=/usr/bin/lesspipe %s %s
_=/usr/bin/env


#通过环境变量建立到Redis的连接
#web应用程序的lib/app.rb
require "rubygems"
require "sinatra"
require "json"

class App < Sinatra::Application

  set :bind, '0.0.0.0'

  get '/' do
    "<h1>DockerBook Test Sinatra app</h1>"
  end

  post '/json/?' do
    params.to_json
  end

end

#使用本地DNS

#启动支持Redis的Sinatra应用程序
root@08d78050e896:~# nohup /opt/webapp/bin/webapp &
[1] 30
root@08d78050e896:~# nohup: ignoring input and appending output to 'nohup.out'

#测试支持Redis的Sinatra应用程序
$ curl -i -H 'Accept:application/json' -d 'name=Foo&status=Bar' http://localhost:32777/json
HTTP/1.1 200 OK 
Content-Type: text/html;charset=utf-8
Content-Length: 29
X-Xss-Protection: 1; mode=block
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Server: WEBrick/1.3.1 (Ruby/1.9.3/2013-11-22)
Date: Mon, 11 Jul 2016 06:58:15 GMT
Connection: Keep-Alive
{"name":"Foo","status":"Bar"}

#确认Redis存储了相关数据
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐