docker集群部署:第2部分:容器

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了docker集群部署:第2部分:容器相关的知识,希望对你有一定的参考价值。

docker集群部署:第2部分:容器

  1. 介绍
    现在是开始构建Docker应用程序。我们将从这个应用程序的层次结构的底部开始,这个应用程序是一个容器。在这个层次上面是一个服务,它定义了容器在生产中的行为方式,将在第3部分中进行讨论。最后,在顶层是堆栈,定义了所有服务的交互,将在第5部分进行讨论。

  2. docker开发环境
    在过去,如果你要开始编写一个Python应用程序,你的第一步就是在你的服务器上安装一个Python运行库。但是,这会造成你的服务器上的环境必须如此,以使你的应用程序能够按预期运行。
    使用Docker,docker具有可移植性,你可以将一个可移植的Python运行时作为一个镜像来获取,无需安装。然后,将基础Python镜像与应用程序代码一起包括在内,包括应用程序所依赖项。
    这些可移植的镜像是由一个叫做Dockerfile的东西来定义的。
  3. 用Dockerfile定义一个容器
    Dockerfile将定义你的容器内的环境中发生了什么。这个环境与系统的其他部分是隔离的,所以你必须将端口映射到外部世界,并具体说明你想“拷入”哪些文件那个环境。这样做后,你定义的Dockerfile在生成镜像后,就具有了移植性。
    Dockerfile
    创建一个名为Dockerfile的文件,将以下内容复制并粘贴到该文件中并保存。
    Dockerfile中每条语句的注释如下:
    ##使用官方的Python运行时作为源镜像
    FROM python:2.7-slim
    ##将工作目录设置为/ app
    WORKDIR /app
    ##将当前目录内容复制到/ app的容器中
    ADD . /app
    ##安装requirements.txt中指定的任何所需的软件包
    RUN pip install --trusted-host pypi.python.org -r requirements.txt
    ##此容器对外提供端口80
    EXPOSE 80
    ##定义环境变量
    ENV NAME World
    ##容器启动时运行app.py
    CMD ["python", "app.py"]

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

    ##设置代理服务器,将host:port替换为服务器的值
    ENV http_proxy host:port
    ENV https_proxy host:port

    注意:在使用pip之前添加这些行,以便安装成功。
    这个Dockerfile引用了一些我们还没有创建的文件,分别是app.py和requirements.txt。接下来创建这些。

  4. 应用程序本身
    创建另外两个文件:requirements.txt和app.py,并将它们放在与Dockerfile同一级目录下。当上面的Dockerfile被内置到镜像中时,由于Dockerfile的ADD命令,app.py和requirements.txt将会出现,并且app.py的输出将可以通过HTTP访问,这要归功于EXPOSE命令。
    #cat requirements.txt
    Flask
    Redis
    #cat app.py
    from flask import Flask
    from redis import Redis, RedisError
    import os
    import socket
    ##Connect to Redis
    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)

    现在我们看到pip install -r requirements.txt安装了Python的Flask和Redis库,应用程序打印环境变量NAME以及调用socket.gethostname()的输出。最后,由于Redis没有运行(因为我们只安装了Python库,而不是Redis本身),所以我们在这里尝试使用它将会失败并产生错误信息。
    注意:在容器中访问主机的名称将检索容器ID,这与正在运行的可执行文件的进程ID类似。

  5. 构建应用程序
    我们准备构建应用程序。确保你仍然在你的新目录的顶层。ls应该显示:
    $ ls
    Dockerfile      app.py          requirements.txt

    现在运行build命令。这会创建一个Docker镜像,我们将使用-t标记,因此它有一个名字。

    #docker build -t friendlyhello .
    查看创建的镜像,它在你的机器的本地Docker镜像注册表中:
    $ docker images
    REPOSITORY            TAG                 IMAGE ID
    friendlyhello         latest              326387cea398
  6. 运行应用程序
    运行应用程序,使用-p(小写)将您的机器的端口4000映射到容器的已发布端口80:
    #docker run -p 4000:80 friendlyhello
    你应该看到一条消息,Python在http://0.0.0.0:80上提供你的应用程序。但是,这个消息来自容器内部,它不知道你将该容器的端口80映射到4000,本地可以使用URL为http:// localhost:4000来访问。
    注意:如果您在Windows 7上使用Docker Toolbox,请使用Docker Machine IP而不是本地主机。
    例如,http://192.168.99.100:4000/。要查找IP地址,请使用命令docker-machine ip。
    您也可以在shell中使用curl命令来查看相同的内容。
    $ curl http://localhost:4000
    <h3>Hello World!</h3><b>Hostname:</b> 8fc990912a1

    这个4000:80的端口重映射是为了演示Dockerfile中的EXPOSE与使用docker run -p发布的内容之间的区别。在后面的步骤中,我们将主机上的端口80映射到容器中的端口80,并使用http:// localhost。
    现在让我们以分离模式在后台运行应用程序:

    #docker run -d -p 4000:80 friendlyhello
    你得到你的应用程序的容器ID,然后被返回你的终端。你的容器正在后台运行。你还可以使用docker container ls查看容器标识(或者使用docker ps):
    $ docker container ls
    CONTAINER ID        IMAGE               COMMAND             CREATED
    1fa4ab2cf395        friendlyhello       "python app.py"     28 seconds ago
    现在使用docker container stop来结束进程,使用CONTAINER ID,如下所示:
    #docker container stop 1fa4ab2cf395
  7. 分享镜像
    为了演示我们刚刚创建的镜像可移植性,我们上传我们构建的镜像,并在其他地方运行它。毕竟,当你想将容器部署到生产环境中时,你需要学习如何使用注册表(registry)。
    一个注册表是一个存储库的集合,一个存储库是一个镜像集合,这有点像GitHub存储库,除了代码已经建立。注册表上的帐户可以创建许多存储库。 Docker CLI默认使用Docker的公共注册表。
    注意:我们将在这里使用Docker的公共注册表,因为它是免费的,并且是预配置的,但是有许多公共选项可供选择,甚至可以使用Docker Trusted Registry设置您自己的私有注册表。
  8. 使用Docker ID登录
    如果您没有Docker帐户,请在cloud.docker.com注册一个。记下你的用户名。
    登录到本地机器上的Docker公共注册表。
    $ docker login
  9. 标记镜像
    将本地镜像与注册表中的存储库相关联的符号是username/repository:tag。该标签是可选的,但推荐使用,因为这是注册管理机构为Docker镜像提供版本的机制。给存储库并标记上下文的有意义的名字,比如get-started:part2。这会将图像放入启动存储库,并将其标记为part2。
    docker tag image username/repository:tag
    举例:
    docker tag friendlyhello john/get-started:part2
    运行docker以查看新标记的图像。(您也可以使用docker image ls。)
    $ docker images
    REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE
    friendlyhello            latest              d9e555c53008        3 minutes ago       195MB
    john/get-started         part2               d9e555c53008        3 minutes ago       195MB
  10. 发布镜像
    将标记的镜像上传到存储库:
    #docker push username/john/get-started:part2
    举例如下:
    #docker push wtf(用户名)/repository:tag

    一旦完成,这个上传的结果是公开的。如果你登录到Docker Hub,你将会看到那个新的镜像和它的pull命令。

  11. 从远程存储库中提取并运行镜像
    从现在开始,你可以使用docker run并使用此命令在任何机器上运行
    #docker run -p 4000:80 username/repository:tag
    如果镜像在机器上本地不可用/没有,Docker将从存储库中取出。
    #docker run -p 4000:80 john/get-started:part2
    Unable to find image ‘john/get-started:part2‘ locally
    part2: Pulling from john/get-started

    无论Docker运行在哪里,它都会将您的镜像,Python以及所有依赖项从requirements.txt中提取出来,并运行您的代码。它们一起旅行在一个整洁的小包里,主机不需要安装任何东西,除了Docker。

以上是关于docker集群部署:第2部分:容器的主要内容,如果未能解决你的问题,请参考以下文章

docker集群部署:第5部分:堆栈

docker集群部署:第1部分:定位和设置

Docke连载:第三章:Docker的使用

云原生之Docker实战使用Docker部署Rabbitmq集群

Kafka集群部署(Docker容器的方式)

测试环境docker化—容器集群编排实践