docker官网入门-容器与应用(上)---最重要

容器与应用

(1)容器与应用: 讲述 centos docker的安装,仓库、镜像、容器、服务的概念, dockerfile,compose 文件,容器管理图形界面,以单机操作为主线。
(2)Docker Swarm 集群:讲述集群(cluster)manager,worker,node 的概念与应用在集群部署。重点讲述容器网络、存储管理、集群管理、服务发现等知识。

1、环境与网络

准备三台 Centos 的 物理机或虚拟机,虚拟机可使用 VMware 或 Vbox,本文案例主机采用 Window10,虚拟化软件 Vbox。

虚拟机应采用双网卡配置:

  • 第一块网卡配 NAT,
  • 第二块网卡按(Host-Only)配内部私有网络。

配置参考: docker 集群网络规划与 VM 网络配置

2、安装 CentOS 与 Docker 引擎

2.1 安装 CentOS 基础环境

1.安装CentOS服务器的模板

双网卡网络配置: NAT,192.168.56.250/24

具体过程:安装基础-centos-7-服务器

2.安装docker-master虚拟机

使用 VBox 复制上述服务器。使用 nmtui 配置:

  • 第二网卡,例如:192.168.56.110/24
  • 主机名:docker-master

注意:以上只是复制内容,未经本人实践,本人用到的方式是:

在VMware上安装一个CentOS虚拟机,采用桥接网络,进行以下的学习操作,当进行docker swarm集群搭建时,

将该CentOS虚拟机复制2份,进行ip及主机名的改变之后,即可进行操作。以上,经过本人实践。

2.2 安装 Docker 引擎

1. 在阿里云注册账号

进入阿里云,dev.aliyun.com

登陆后,进入【管理中心】

2. 安装 docker 引擎

如果是安装最新版本 docker:

  • 【管理中心】 –> Docker镜像仓库 –> 加速器 –> centos
  • 按提示操作

如果需要安装 docker 历史版本:

3. 启动 docker 引擎

  1.  
    systemctl start docker
  2.  
    systemctl enable docker
  3.  
    systemctl status docker
  4.  
     
  5.  
    docker version
  6.  
    docker run --rm hello-world

4. 配置容器加速服务

  • 【管理中心】 –> Docker镜像仓库 –> 加速器 –> centos

5. 建立你的镜像仓库

  • 【管理中心】 –> Docker镜像仓库 –> 镜像列表 –> 华南1 –> 【创建镜像创库】

创建公有仓库,(一个仓库一般就存一个镜像的不同版本)。完成后,看到【管理】按钮,进入

3、Docker 入门

docker 官网文档 Get Stated 给出了 6 个基础教程,Part1-6。 Part I 安装,请参考前面。

入门要求 docker 1.13 版本以上,当前版本 17.04.00 ce

3.1 核心概念

Docker引擎 (Docker Engine)

Docker Engine is a client-server application with these major components(一个客户-服务应用,含三个部件)

1)驻守(daemon)进程 docker

2) REST API 接口提供外部系统与 docker 进程交互

3) Cli 命令行接口的应用 docker 命令


图:Docker引擎基础架构

镜像(image)

An image is a read-only template with instructions for creating a Docker container.

镜像是创建docker容器指令的只读模板。包含一个只读的文件系统镜像,应用程序在这个文件系统上运行,并拥有属于自己的网络、内存、CPU 等资源的定义。通常,一个镜像申明了自己主进程的应用。

镜像一般在其他镜像基础上建立,如在 ubuntu 上添加自己的 apache 文件,然后在 apache 上建立 web 应用文件

容器(Container)

A container is a runnable instance of an image.

镜像中的程序(主进程)运行在只读文件镜像上,对现有文件变更将写在一个临时的卷上(新的一层),该主进程、相关进程、文件系统成为一个运行的实例。

  • 每个容器创建后,有运行、暂停、中止状态,直到移除。
  • 程序运行的产生的数据,都在容器中的文件中,Restart 不会丢失数据。

当主进程结束时,该实例同时结束运行。使用 –rm 表示运行后自动删除容器。

服务(Services)

Services allow you to scale containers across multiple Docker daemons, which all work together as a swarm with multiple nodes.

服务是一组运行于集群不同结点中可复制的容器的集合。通过服务发现机制,使用该服务的客户端可以透明的访问这些容器。这些容器的分布、升级、故障管理有集群统一管理。

一般地,集群内部服务容器地选择由 动态DNS 实现。

栈(stack)

A stack is a group of interrelated services that share dependencies, and can be orchestrated and scaled together.

能被编排和伸缩的一组相互依赖的服务

栈(stack)用 docker-compose.yml 文件描述服务之间的依赖、数据共享、网络等。使用 docker stack 管理

3.2 简单教程

3.2.1 Part 2:镜像与容器(官方)

https://docs.docker.com/get-started/part2/

1)创建镜像

(1) 创建一个目录,如 webservice1, 然后,进入该目录

mkdir webservice1 && cd webservice1 

(2) 创建一个简单 web 应用程序

使用 vi app.py 创建 web 应用代码:

  1.  
    from flask import Flask
  2.  
    from redis import Redis, RedisError
  3.  
    import os
  4.  
    import socket
  5.  
     
  6.  
    # Connect to Redis
  7.  
    redis = Redis(host= "redis", db=0)
  8.  
     
  9.  
    app = Flask(__name__)
  10.  
     
  11.  
    @app.route("/")
  12.  
    def hello():
  13.  
    try:
  14.  
    visits = redis.incr( 'counter')
  15.  
    except RedisError:
  16.  
    visits = "<i>cannot connect to Redis, counter disabled</i>"
  17.  
     
  18.  
    html = "<h3>Hello {name}!</h3>" \
  19.  
    "<b>Hostname:</b> {hostname}<br/>" \
  20.  
    "<b>Visits:</b> {visits}"
  21.  
    return html.format(name=os.getenv('NAME', "world"), hostname=socket.gethostname(), visits=visits)
  22.  
     
  23.  
    if __name__ == "__main__":
  24.  
    app.run(host= '0.0.0.0', port=80)

写简单 web 应用, python 最方便。 Node.js 也很好! J2EE 就是蹒跚的大象啊。

(3) 创建镜像指令文件 dockerfile

使用 vi dockerfile 创建文件

  1.  
    # Use an official Python runtime as a base image
  2.  
    FROM python: 2.7-slim
  3.  
     
  4.  
    # Set the working directory to /app
  5.  
    WORKDIR /app
  6.  
     
  7.  
    # Copy the current directory contents into the container at /app
  8.  
    ADD . /app
  9.  
     
  10.  
    # Install any needed packages specified in requirements.txt
  11.  
    RUN pip install -r requirements.txt
  12.  
     
  13.  
    # Make port 80 available to the world outside this container
  14.  
    EXPOSE 80
  15.  
     
  16.  
    # Define environment variable
  17.  
    ENV NAME World
  18.  
     
  19.  
    # Run app.py when the container launches
  20.  
    CMD [ "python", "app.py"]

指令非常直观,

  • FROM 指示从 python:2.7-slim 镜像基础上开始构建。这个镜像在哪里,docker hub 的仓库。 镜像命名规则 [镜像:版本]
  • WORKDIR 设置主进程的工作目录 /app
  • ADD 将当前目录内容复制到基础镜像文件系统的 /app
  • RUN 在基础镜像文件系统上运行 pip install -r requirements.txt 这时 pip 下载依赖包到基础镜像之上
  • EXPOSE 暴露容器对外的 TCP 端口 80
  • ENV 定义进程的环境变量 NAME World
  • CMD 设置主进程启动的命令 ["python", "app.py"] 。因此,容器一般是单进程应用

最后编辑 python 的依赖包 vi requirements.txt

  1.  
    Flask
  2.  
    Redis

(4)构建 app 的镜像

检查文件:

  1.  
    # ls
  2.  
    app.py dockerfile requirements.txt

创建 tag 为 friendlyhello 的镜像:

# docker build -t friendlyhello .

完成之后,检查镜像文件:

  1.  
    docker images
  2.  
     
  3.  
    REPOSITORY TAG IMAGE ID
  4.  
    friendlyhello latest 326387cea398

2)在容器中运行 app

docker run -d -p 4000:80 friendlyhello
  • docker run 运行镜像的命令
  • -d 后台运行
  • -p 端口映射,将容器的 80 端口映射到主机(host)的 4000 端口

检查结果:

  1.  
    # curl localhost:4000
  2.  
     
  3.  
    <h3>Hello World!</h3><b>Hostname:</b> 82523c7dcf52<br/><b>Visits:</b> <i>cannot connect to Redis, counter disabled

检查容器的进程:

  1.  
    # docker ps
  2.  
     
  3.  
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  4.  
    82523c7dcf52 friendlyhello "python app.py" 2 minutes ago Up 2 minutes 0.0.0.0:4000->80/tcp sad_wescoff

结束并清理进程:

# docker rm -f 82523c7dcf52

3.2.2 上传镜像到你的仓库

为了说明我们刚才创建的可移植性,可以上传已构建的镜像并在其他地方运行它。但是,在您要将容器部署到生产环境中时,需要了解如何推送到镜像库。

镜像库是镜像仓库的集合,而镜像仓库是镜像的集合 - 除了代码已构建之外,类似于 GitHub 镜像仓库。镜像库中的一个帐户可以创建很多镜像仓库。默认情况下,docker CLI 使用 Docker 的公用镜像库。

注:我们将在此处使用 Docker 的公用镜像库,仅仅因为它是免费的并且经过预先配置,但有许多公用镜像库可供选择,并且您甚至可以使用 Docker Trusted Registry 设置您自己的专用镜像库。

  • 使用 Docker ID 登录

如果您没有 Docker 帐户,请在 cloud.docker.com 中进行注册。记录您的用户名。

登录本地机器上的 Docker 公用镜像库。

docker login
  • 标记镜像

用于将本地镜像与镜像库中的镜像仓库相关联的表示法为 username/repository:tag。tag 是可选项,但建议使用它,因为这是镜像库用于为 Docker 镜像指定版本的机制。针对上下文为镜像库和 tag 指定有意义的名称,例如 get-started:part1.这会将镜像放入 get-started 镜像仓库并将其标记为 part1

现在,将其合并到一起,以标记镜像。使用您的用户名、镜像仓库和标签名称运行 docker tag image,以便镜像将上传到所需目的地。此命令的语法为:

docker tag image username/repository:tag

再次声明:必须要以您的用户名运行docker tag image,否则报错,如下,用户名为john

例如:

docker tag friendlyhello john/get-started:part1

运行 docker images 以查看新标记的镜像。(您还可以使用 docker image ls。)

  1.  
    $ docker images
  2.  
    REPOSITORY TAG IMAGE ID CREATED SIZE
  3.  
    friendlyhello latest d9e555c53008 3 minutes ago 195MB
  4.  
    john/ get-started part1 d9e555c53008 3 minutes ago 195MB
  5.  
    python 2.7-slim 1c7128a655f6 5 days ago 183MB
  6.  
    ...
  • 发布镜像

将已标记的镜像上传到镜像仓库:

docker push username/repository:tag

例如:

docker push john/get-started:part1

完成后,将公开此上传的结果。如果登录 Docker Hub,可以使用其 pull 命令看到新的镜像。建议您第一次尝试时,进入Docker Hub页面进行查看,以验证您操作的正确性。

  • 从远程镜像仓库中拉取并运行镜像

从现在开始,您可以使用 docker run,并且可以使用以下命令在任何机器上运行您的应用:

docker run -p 4000:80 username/repository:tag

如果镜像在机器本地不可用,Docker 将从镜像仓库中拉取它。如果您还在本机操作,可以尝试删除本机上的该镜像,然后在执行如下操作:docker run -p 4000:80 john/get-started:part1

  1.  
    $ docker run -p 4000:80 john/get-started:part1
  2.  
    Unable to find image 'john/get-started:part1' locally
  3.  
    part1:Pulling from orangesnap/get-started
  4.  
    10a267c67f42:Already exists
  5.  
    f68a39a6a5e4:Already exists
  6.  
    9beaffc0cf19:Already exists
  7.  
    3c1fe835fb6b:Already exists
  8.  
    4c9f1fa8fcb8:Already exists
  9.  
    ee7d8f576a14:Already exists
  10.  
    fbccdcced46e:Already exists
  11.  
    Digest: sha256: 0601c866aab2adcc6498200efd0f754037e909e5fd42069adeff72d1e2439068
  12.  
    Status: Downloaded newer image for john/get-started:part1
  13.  
    * Running on http: //0.0.0.0:80/ (Press CTRL+C to quit)

注:如果您未指定这些命令中的 :tag 部分,在进行构建和运行镜像时,将使用标签 :latest 。Docker 将使用在未指定标签的情况下运行的镜像的最新版本(可以不是最新镜像)。

无论 docker run 在何处执行,它将从 requirements.txt 拉取您的镜像及 Python 和所有依赖项,然后运行代码。所有内容都在一个小软件包中提供,并且主机只需安装 Docker 来运行它。

3.2.3 使用图形化管理工具

安装及运行请移步这里:https://blog.csdn.net/wangguohe/article/details/81536124

几乎所有容器开发商都有自己的 UI 管理界面。这些 UI 共同的特点就是就是本身以一个容器的方式存在,例如:Portainer 、Shipyard

以为例,启动 Portainer 非常简单:

docker run -d -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer

这里最关键的就是 -v /var/run/docker.sock:/var/run/docker.sock 容器与主机共享了文件 /var/run/docker.sock 从而,容器获得了 docker 驻守(daemon)进程 REST API SDK 入口。

现在,在浏览器输入 http://<your machine IP>:9000 就进入了图形管理界面。

3.2.4 Part 3:服务(官方)

A service really just means, “containers in production.” A service only runs one image, but it codifies the way that image runs – what ports it should use, how many replicas of the container should run so the service has the capacity it needs, and so on.

在分布式应用中,应用的不同部分称为“服务”。例如,假设有一个视频共享网站,它可能提供用于在数据库中存储应用程序数据的服务、用于在用户上传一些内容后在后台进行视频转码的服务、用于前端的服务等。

服务实际上是“生产中的容器”。一项服务仅运行一个镜像,但它会编制镜像的运行方式 - 它应使用的端口、容器的多少个从节点应运行才能使服务的容量满足其需求等。扩展服务将更改运行该软件的容器实例数,并将多个计算资源分配给进程中的服务。

幸运的是,很容易使用 Docker 平台定义、运行和扩展服务 – 只需编写一个 docker-compose.yml 文件即可。

运行一个服务,需要使用 docker-compose.yml 文件。顾名思义,这是服务组合的定义。

(1)创建一个目录,例如 service_test:

cd && mkdir service_test && cd service_test 

(2)编写服务定义, 例如 vi docker-compose.yml

您可以将 Compose 文件命名为任何所需内容,以使其在逻辑上具有意义;docker-compose.yml 仅为标准名称。我们可以简单地将此文件命名为 docker-stack.yml 或更特定于项目的内容。

  1.  
    version: "3"
  2.  
    services:
  3.  
    web:
  4.  
    # 将 username/repo:tag 替换为您的名称和镜像详细信息
  5.  
    image: username/repository:tag
  6.  
    deploy:
  7.  
    replicas: 5
  8.  
    resources:
  9.  
    limits:
  10.  
    cpus: "0.1"
  11.  
    memory: 50M
  12.  
    restart_policy:
  13.  
    condition: on-failure
  14.  
    ports:
  15.  
    - "80:80"
  16.  
    networks:
  17.  
    - webnet
  18.  
    networks:
  19.  
    webnet:

注意:缩进为2个空格,每个:后面都要有空格,否则后面操作的时候会报错

yaml: line 6: mapping values are not allowed in this context

此 docker-compose.yml 文件会告诉 Docker 执行以下操作:

  • 从镜像库中拉取我们在上传的镜像。

  • 将该镜像的五个实例作为服务 web 运行,并将每个实例限制为最多使用 10% 的 CPU(在所有核心中)以及 50MB RAM。

  • 如果某个容器发生故障,立即重启容器。

  • 将主机上的端口 80 映射到 web 的端口 80。

  • 指示 web 容器通过负载均衡的网络 webnet 共享端口 80。(在内部,容器自身将在临时端口发布到 web 的端口 80。)

  • 使用默认设置定义 webnet 网络(此为负载均衡的 overlay 网络)。

(3) 启动服务

在启动服务之前,务必初始化集群模式 。注意:多网卡必须说明在那块网卡上组建集群。

docker swarm init --advertise-addr 192.168.56.110

检查是否在集群模式的命令:

  1.  
    # docker info
  2.  
     
  3.  
    Containers: 1
  4.  
    Running: 1
  5.  
    ...
  6.  
    Swarm: active
  7.  
    NodeID: 23iftsrtbxm4kyyh2w5n3fmat
  8.  
    ...

启动应用程序服务(您必须为应用指定一个名称。在此处该名称设置为 myservice)

docker stack deploy -c docker-compose.yml myservice

检查部署的结果:

  1.  
    # docker stack ps myservice
  2.  
     
  3.  
    ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
  4.  
    gzg8n8oqpic8 myservice_web .1 registry.cn-shenzhen.aliyuncs.com/pmlpml/repo:friendlyhello docker-master Running Running 4 seconds ago
  5.  
    xqyqekt9dubc myservice_web .2 registry.cn-shenzhen.aliyuncs.com/pmlpml/repo:friendlyhello docker-master Running Running 4 seconds ago
  6.  
    owvdk5hypg7h myservice_web .3 registry.cn-shenzhen.aliyuncs.com/pmlpml/repo:friendlyhello docker-master Running Running 4 seconds ago
  7.  
    0vi2cwingnyw myservice_web.4 registry.cn-shenzhen.aliyuncs.com/pmlpml/repo:friendlyhello docker-master Running Running 3 seconds ago
  8.  
    7n2l036fv851 myservice_web.5 registry.cn-shenzhen.aliyuncs.com/pmlpml/repo:friendlyhello docker-master Running Running 4 seconds ago

使用浏览器或curl 访问 http://192.168.56.110:80/ 每次返回的主机名都是不一样的,负载均衡实现了。

重启portainer ,使用 portainer 观察主机(host)中的变化:

  • Services: 添加了一个服务 myservice_web
  • Containers: 添加了 5 个服务 myservice_web.?.<long_id>
  • Networks:添加了 2 个 swarm overlay 的网络
  • Swarm:有一个管理结点

使用 portainer 的 Containers 杀死 myservice_web 服务的实例,会发现它会自动启动。

(4) 结束服务

docker stack rm myservice

(我们的单节点 swarm 仍处于正常运行状态(如 docker node ls 所示)。使用 docker swarm leave --force 可以清除 swarm)

4、小结

本文给出了在 centos 环境下,完成 docker 官方 part 2,part 3 的教程的要点。由于网络等因素,建议大家使用阿里云或其他 docker 容器服务商提供的安装、容器仓库与加速设施。尽管技术不断发展,无论命令还是定义格式都会发生一些变化,docker 容器的核心内容与操作基本没有大变化。适当使用图形界面,可以更加快速观察系统内部的变化。

本文围绕镜像、容器、服务三个核心知识以及相关的操作,读者应可以从容安装 docker 引擎,并在单机上发布与部署简单的 web 应用。

猜你喜欢

转载自www.cnblogs.com/eess/p/11448522.html