0%

Docker-创建和分享应用(3) - 头痛不头痛 - 博客园

Excerpt

Dockerfile定义容器内环境中发生的事情。对网络接口和磁盘驱动器等资源的访问在此环境中进行虚拟化,该环境与系统的其他部分隔离,因此您需要将端口映射到外部世界,并具体说明要“复制”哪些文件到该环境。但是,在执行此操作之后,您可以预期Dockerfile在此处定义的应用程序的构建 在其运


  Dockerfile定义容器内环境中发生的事情。对网络接口和磁盘驱动器等资源的访问在此环境中进行虚拟化,该环境与系统的其他部分隔离,因此您需要将端口映射到外部世界,并具体说明要“复制”哪些文件到该环境。但是,在执行此操作之后,您可以预期Dockerfile在此处定义的应用程序的构建 在其运行的任何位置都完全相同。

1. 快速测试Docker环境是否可用#

2. 创建Dockerfile文件#

   在一个空目录中创建一个名为Dockerfile的文件,内容如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

FROM python

WORKDIR /app

COPY . /app

RUN pip install --trusted-host pypi.python.org -r requirements.txt

EXPOSE 80

ENV NAME World

CMD ["python", "app.py"]

3. 在该目录下继续创建一个Flask应用程序和安装文件清单#

app.py#

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

from flask import Flask

from redis import Redis, RedisError

import os

import socket

redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2)

app = Flask(__name__)

@app.route("/")

def hello():

    try:

        visits = redis.incr("counter")

    except RedisError:

        visits = "<i>cannot connect to Redis, counter disabled</i>"

    html = "<h3>Hello {name}!</h3>" \

           "<b>Hostname:</b> {hostname}<br/>" \

           "<b>Visits:</b> {visits}"

    return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits)

if __name__ == "__main__":

    app.run(host='0.0.0.0', port=80) 

requirements.txt#

4. 构建应用程序#

我们准备构建应用程序。确保您仍处于新目录的顶层。这是ls应该显示的内容:

1

2

$ ls

Dockerfile      app.py          requirements.txt

创建一个Docker镜像,我们将使用该--tag或者-t选项命名镜像

1

docker build --tag=friendlyhello .

查看创建的镜像

1

2

3

root@node1 docker]

REPOSITORY                           TAG                 IMAGE ID            CREATED             SIZE

friendlyhello                        latest              67bd580f29b8        21 seconds ago      937MB

Linux用户的故障排除
  • 代理服务器设置

  代理服务器可以在Web应用程序启动并运行后阻止其连接。如果您位于代理服务器后面,请使用以下ENV命令将以下行添加到Dockerfile中,以指定代理服务器的主机和端口:

1

2

3

ENV http_proxy host:port

ENV https_proxy host:port

  • DNS设置

  DNS配置错误可能会产生问题pip。您需要设置自己的DNS服务器地址才能pip正常工作。您可能想要更改Docker守护程序的DNS设置。您可以/etc/docker/daemon.json使用dns密钥编辑(或创建)配置文件,如下所示:

1

2

3

{

  "dns": ["your_dns_address", "8.8.8.8"]

}

  在上面的示例中,列表的第一个元素是DNS服务器的地址。第二项是Google的DNS,可在第一项无法使用时使用。

  在继续之前,请保存daemon.json并重新启动docker服务。

sudo service docker restart

修复后,重试运行该build命令。

5. 运行应用程序#

运行应用程序,使用以下方法将计算机的端口4000映射到容器的已发布端口80,-p是将容器的端口Publish到外部的意思。

1

docker run -p 4000:80 friendlyhello

 在浏览器访问‘http://localhost:4000’即可访问到内部的应用程序,按Ctrl+c即可结束应用程序。

后台以分离模式运行应用程序,-d就是在后台运行镜像,并打印出容器ID

1

docker run -d -p 4000:80 friendlyhello

6. 停止应用程序所在容器的运行#

7. 分享镜像#

如果没有Docker帐户,请在hub.docker.com上注册一个帐户 ,并记下的用户名。

1. 在本地的计算机上登录

2. 将镜像打上标签,该命令的语法是:

1

docker tag image username/repository:tag

  比如我的登录名为scottcho,将版本库命名为flask,tag为v1

1

2

3

4

5

[root@node1 docker]

[root@node1 docker]

REPOSITORY   TAG IMAGE ID     CREATED    SIZE

scottcho/flask v1 67bd580f29b8 30 minutes ago 937MB

3. 发布镜像

1

docker push scottcho/flask:v1

 在docker hup上可以看见所创建的镜像

4. 在任何计算机上可以运行分享的镜像

如果映像在本地不可用,则Docker会从存储库中提取映像。

1

docker run -p 4000:80 scottcho/flask:v1

查看容器内的改变信息

创建一个容器,会在容器的对应的镜像上增加一个可写层,镜像部分是只读的。通过 diff命令可以看出改变的信息。如:

复制代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@wls12c ~]$ docker run -i -t centos /bin/<span>bash
[root@224de7986c5f </span>/]# <span>touch</span><span> demo.ext
[root@224de7986c5f </span>/]# <span>echo</span> hello docker &gt;<span>demo.ext
[root@224de7986c5f </span>/]# <span>rm</span> -rf anaconda-<span>post.log
[root@224de7986c5f </span>/<span>]# exit
exit
[root@wls12c </span>~]$ docker <span>ps</span> -<span>l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
224de7986c5f centos </span><span>"</span><span>/bin/bash</span><span>"</span> <span>40</span> seconds ago Exited (<span>0</span>) <span>3</span><span> seconds ago desperate_curie
<span>[root@wls12c </span></span><span>~]$ docker diff</span><span><span> 224d</span>
D </span>/anaconda-<span>post.log
A </span>/<span>demo.ext
C </span>/<span>root
A </span>/root/.bash_history

复制代码

说明:每行代表一个变动的文件或目录。其中 A 表示新增、C表示被修改、D表示被删除

主机和容器之间的文件拷贝

容器—>主机

复制代码

1
2
3
4
5
6
7
8
[root@wls12c ~]$ docker exec  -t -i 9f bin/<span>bash
[root@9f49397623ad </span>/]# <span>cat</span><span> demo.txt
hello
[root@9f49397623ad </span>/<span>]# exit
exit<br>
<span>[root@wls12c </span></span><span>~]$ docker cp 9f:/demo.txt /</span><span><span>test</span>
<span>[root@wls12c </span></span><span>~]$ cat /test/demo.txt
hello</span>

复制代码

主机–>容器

复制代码

1
2
3
4
5
<span>[root@wls12c ~]$  cp ~/1.txt  /var/lib/docker/aufs/mnt/9f49397623ade7dfd2beb4d84454cbdb9878a4b22a2bab2e8b5db72bcffe60a0/</span><span><span>test
</span>
[root@wls12c </span>~]$ docker exec -t -i 9f /bin/<span>bash
[root@9f49397623ad </span>/]# <span>ls</span> /<span>test
</span><span>1</span>.txt

复制代码

重命名容器

1
[root@wls12c ~]$ docker rename stoic_meitner demo