GVKun编程网logo

Zeroc Ice 学习笔记 --Docker 部署服务(docker部署odoo)

14

这篇文章主要围绕ZerocIce学习笔记--Docker部署服务和docker部署odoo展开,旨在为您提供一份详细的参考资料。我们将全面介绍ZerocIce学习笔记--Docker部署服务的优缺点,

这篇文章主要围绕Zeroc Ice 学习笔记 --Docker 部署服务docker部署odoo展开,旨在为您提供一份详细的参考资料。我们将全面介绍Zeroc Ice 学习笔记 --Docker 部署服务的优缺点,解答docker部署odoo的相关问题,同时也会为您带来1.docker 学习笔记之入门,docker 在 centos7 下的安装以及基础命令的使用、Docker Swarm Mode 学习笔记 (部署服务)、docker swarm英文文档学习-8-在集群中部署服务、docker 停止服务 部署服务的实用方法。

本文目录一览:

Zeroc Ice 学习笔记 --Docker 部署服务(docker部署odoo)

Zeroc Ice 学习笔记 --Docker 部署服务(docker部署odoo)

Zeroc Ice 学习笔记 --Docker 部署服务

1、Docker Ice images 安装

       docker pull zeroc/icegridregistry

       docker pull mycat/leader-icenode (包含 JDK)

2、Ice Registry

    registry.conf 文件:

IceGrid.InstanceName=IceGrid
IceGrid.Registry.Client.Endpoints=tcp -p 4061
IceGrid.Registry.Server.Endpoints=tcp
IceGrid.Registry.Internal.Endpoints=tcp
IceGrid.Registry.AdminPermissionsVerifier=IceGrid/NullPermissionsVerifier

#持久化目录
IceGrid.Registry.Data=.
#是否允许动态注册
IceGrid.Registry.DynamicRegistration=1

执行命令:

docker run -d --name demo_registry  -v /data/apps/light/registry/icegridreg.conf:/etc/icegridregistry.conf:ro
 -v /data/apps/light/registry:/var/lib/ice/icegrid  -p 4601:4601 zeroc/icegridregistry

部分说明:--name:registry 名称

           /data/apps/light/registry/icegridreg.conf:指定 conf 文件目录,替代 /etc/icegridregistry.conf

          /data/apps/light/registry:指定持久化目录,替代 /var/lib/ice/icegrid 目录

3、IceGrid Node

#主节点位置
Ice.Default.Locator=IceGrid/Locator:tcp -h 192.168.9.111 -p 4061
#节点1数据存储目录
IceGrid.Node.Data=/var/lib/ice/icegrid/nodedata
#节点1监听端口号
IceGrid.Node.Endpoints=tcp -h 0.0.0.0
#节点1名称
IceGrid.Node.Name=node1
#IceGrid.Node.Output=/var/lib/ice/icegrid/out.log
Ice.StdErr=/var/lib/ice/icegrid/stderr.log
Ice.StdOut=/var/lib/ice/icegrid/stderr.log
IceGrid.Node.RedirectErrToOut=1
IceGrid.Node.Trace.Replica=2

执行命令:

docker run --name light-temple-node1 --net=host 
-v /data/apps/light/temple-service/dist/node1.conf:/etc/icegridnode.conf:ro 
-v /data/apps/light/temple-service:/var/lib/ice/icegrid -d mycat/leader-icenode

4、IceGrid 

<icegrid>
    <application name="light-temple">
        <properties id="props">
            <property name="Ice.ThreadPool.Server.Size" value="50"/>
        </properties>
        <server-template id="TempleServerTemplate">

            <parameter name="id"/>
            <icebox id="TempleServices${id}" exe="java" user="ice">
                <properties>
                    <properties refid="props"/>
                </properties>
                <option>IceBox.Server</option>
                <env>CLASSPATH=/var/lib/ice/icegrid/dist/jars/*</env>
                <service name="TempleServices" entry="com.gwsoft.light.services.temple.TempleService">
                    <adapter name="TempleServices" id="TempleServices${id}" endpoints="tcp -h localhost -t 10000" replica-group="TempleServiceRep"/>
                </service>

            </icebox>
        </server-template>
	<replica-group id="TempleServiceRep">
		<load-balancing type="adaptive" n-replicas="0"/>
		<object identity="TempleServices" type="::temple::TempleServices"/>
	</replica-group>
        <node name="temple_node1">
            <server-instance template="TempleServerTemplate" id="1"/>
            <server-instance template="TempleServerTemplate" id="2"/>
        </node>
    </application>
</icegrid>

说明:

<env>CLASSPATH=/var/lib/ice/icegrid/dist/jars/*</env>

    在执行命令中等同于 /data/apps/light/temple-service/dist/jars/*

endpoints="tcp -h localhost -t 10000"

    设置当前服务 endpoints 属性,显著提升 client 调用响应时间

执行命令:

5、Client 调用服务

--Ice.Default.Locator=IceGrid/Locator:tcp -h 192.168.9.111 -p 4061

自己相对于更改 - h 、-p 并可以调用服务

1.docker 学习笔记之入门,docker 在 centos7 下的安装以及基础命令的使用

1.docker 学习笔记之入门,docker 在 centos7 下的安装以及基础命令的使用

1、更新update到最新的版本  
    yum  update
2、卸载老版本docker
    yum  remove docker  docker-common docker-selinux  docker-engine
3、安装需要的软件包
    yum install -y yum-utils  device-mapper-persistent-data lvm2
4、设置yum源
    yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
5、查看docker版本
    yum list docker-ce --showduplicates|sort -r  

6、安装docker
    yum  install  docker-ce-18.03.1.ce -y  #yum  install docker-ce-3:20.10.9-3.el8
7、启动docker
    systemctl start docker
8、加入开机自启
    systemctl enable docker

9、配置国内镜像

    vi /etc/docker/daemon.json 
    {
        "registry-mirrors": ["http://hub-mirror.c.163.com"]
    }
Docker 包括三个基本概念:
镜像(Image)
容器(Container)
仓库(Repository)

如若以上操作 中出现错误

则强制安装此版本

yum install https://download.docker.com/linux/centos/8/x86_64/stable/Packages/containerd.io-1.4.3-3.1.el8.x86_64.rpm

1.启动
 docker start 容器名
2.删除
   docker rm 容器名
3.停止所容器
  docker stop  $(docker ps -a -q)
  docker rm  $(docker ps -a -q) 

4.docker build -t 名称 .
  Usage:docker build [OPTIONS] PATH | URL | -

  OPTIONS:
  -t ,--tag list  #构建后的镜像名称
  -f, --file string #指定Dockerfiile文件位置
    示例:
     1,docker build . 
     2,docker build -t redis:v1 .
     3,docker build -t redis:v2 -f /path/Dockerfile /path

Dockerfile 快速入门指令

  1.FROM 指定基础镜像

    所谓定制镜像,那一定是以一个镜像为基础,在其上进行定制。就像我们之前运行了一个redis镜像的容器,再进行修改一样,基础镜像是必须指定的。而 FROM 就是指定基础镜像,因此一个  Dockerfile  中  FROM  是必备的指令,并且必须是第一条指令。
     Docker Store 上有非常多的高质量的官方镜像,有可以直接拿来使用的服务类的镜像,如nginx  、 redis  、 mongo  、 mysql  、 httpd  、 php  、 tomcat  等;如果没有找到对应服务的镜像,官方镜像中还提供了一些更为基础的操作系统镜像,
    如ubuntu  、 debian  、 centos、 alpine 等这些操作系统的软件库

  2、RUN 执行命令

    RUN  指令是用来执行命令行命令的。
    格式:
      RUN \<command\> (类似/bin/sh -cshell格式)

      RUN ["executable", "param1", "param2"] (exec格式)

    类似shell脚本风格的:
        FROM alpine
        RUN sed -i ''s/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g'' /etc/apk/repositories
        RUN apk add  gcc g++ libc-dev  wget vim  openssl-dev make  linux-headers 
        RUN mkdir -p /usr/src/redis
        RUN cd /usr/src/redis
        RUN wget -O redis-4.0.11.tar.gz  "http://download.redis.io/releases/redis-4.0.11.tar.gz"
        RUN tar -xzf redis-4.0.11.tar.gz -C /usr/src/redis
        RUN cd /usr/src/redis/redis-4.0.11 &&  make && make PREFIX=/usr/local/redis install
    之前说过,Dockerfile 中每一个指令都会建立一层, RUN  也不例外。每一个  RUN  的行为,就和刚才我们手工建立镜像的过程一样:新建立一层,在其上执行这些命令,执行结束后, commit这一层的修改,构成新的镜像。使用 Dockerfile 定制镜像
    而上面的这种写法,创建了很多层镜像。这是完全没有意义的,而且很多运行时不需要的东西,都被装进了镜像里,比如编译环境、更新的软件包等等。结果就是产生非常臃肿、非常多层的镜像,不仅仅增加了构建部署的时间,也很容易出错。 这是很多初学
    Docker 的人常犯的一个错误。Union FS是有最大层数限制的,比如 AUFS,曾经是最大不得超过 42 层,现在是不得超过 127 层。

 

导出容器

 导出容器可以导出一个已经创建的容器到一个文件,不管容器处于什么状态,可以使用docker export 命令。 命令格式为:docker export [-o|--output[=""]] CONTATINER 其中可以通过-o来指定导出的tar文件名,也可以直接通过重定向来实现。

另一种格式为:docker export 容器 id/name > 文件名.tar

导入容器

  导入的文件可以使用docker import 命令导入变成镜像,该命令的格式为:

   docker import [-c|--change[=[]]] [-m|--message[=MESSAGE]] file|URL|-[REPOSITORY[:YAG]]

   其中-c 选项可以在导入的同时执行对容器进行修改的Dockerfile指令(网络等修改)

另外 docker save&load 命令也可以导入一个镜像存储文件,但是跟 docker import 命令是有区别的

 

用 export&import 还是 save & load ?

export&import 和 save & load 是 docker 中的两组命令,我们先主要看看他们的区别:

类型 导出的对象 导出文件大小 是否可回滚到历史层
export & import 将容器导出
save & load 用来将一个或者多个 image 打包
  相对于文件大小来说,save方式导出的文件比export方式导出的文件大
  正是因为save方式保存了镜像的历史和层(layer),使其可以层回滚,即回滚到之前的历史层,所以save方式导出的文件稍微大一些
  反观export方式,在导出过程中丢失所有的历史,导致其不可以层回滚,导出的文件会小一些
  可以通过 docker history 镜像名 看到层关系

3.2、容器网络

Docker 安装后,默认会创建下面三种网络类型

docker network ls 查看默认的网络

在启动容器时使用 --network bridge 指定网络类型

bridge:桥接网络

默认情况下启动的 Docker 容器,都是使用 bridge,Docker 安装时创建的桥接网络,每次 Docker 容器重启时,会按照顺序获取对应的 IP 地址,这个就导致重启下,Docker 的 IP 地址就变了

none:无指定网络 使用 --network=none ,docker 容器就不会分配局域网的 IP

host: 主机网络 使用 --network=host,此时,Docker 容器的网络会附属在主机上,两者是互通的。 例如,在容器中运行一个 Web 服务,监听 8080 端口,则主机的 8080 端口就会自动映射到容器中

3.3、 指定自定义网络

因为默认的网络不能制定固定的地址,所以我们将创建自定义网络,并指定网段(IP 可以理解为 4 组 8 个二进制组成的一段代码,然后右侧网段的 24 是指锁定前面 24 位,也就是说生成的 IP 会是 192.168.1.X,1-255):192.168.1.0/24 并命名为 mynetwork,指令如下:
docker network create --subnet=192.168.1.0/24 mynetwork

使用此 docker 镜像 创建容器

代码如下:

docker run -itd --name redis-master --net mynetwork -p 6380:6379 --ip 192.168.1.2 redis 

参数说明: 具体可以参看一些文档
http://www.runoob.com/docker/docker-run-command.html 

http://www.dockerinfo.net/docker%E5%AE%B9%E5%99%A8-2

-d: 后台运行容器,并返回容器ID; -i: 以交互模式运行容器,通常与 -t 同时使用; -p: 端口映射,格式为:主机(宿主)端口:容器端口 -t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用; -V: 为容器挂载目录,比如 /usr/docker/data:/data 前者为数宿主机目录后者为容器内目录 --ip: 为容器制定一个固定的ip --net: 指定网络模式 这样,我们创建了2个容器,来一起查看下结果 docker ps -a 查看容器ip地址 docker network inspect mynetwork

 

docker build -t redis-test . #在文件夹中用默认的 Dockerfile 创建镜像

docker images #查看当前 docker 镜像

docker history 625dcdca8ecb #查看某个镜像的历史

docker ps -a #查看当前运行的容器

docker run -itd -p 8001:80 -v xxx1:xxx2 --name redis-master redis-test #使用镜像(redis-test)运行容器(redis-master) 宿主机 8001 端口映射到容器 80 端口 宿主机 xxx1 地址与容器 xxx2 地址共享(容器写入 xxx2 的数据同样会出现在宿主机的 xxx1 里)

docker rm 538265c49277 #移除容器

docker exec -it redis-master bash #进入容器 (如果出现:OCI runtime exec failed: exec failed: container_linux.go:348: starting container process caused "exec: \"bash\": executable file not found in $PATH": unknown ,那么就把 bash 改为 sh :docker exec -it redis-master sh)

docker stop $(docker ps -a -q) #停止全部容器(-q 返回容器 id)

docker rm $(docker ps -a -q) #移除所有容器

docker rmi $(docker images -q) #删除所有镜像

docker export f4092a93c312 > nginx-jzy.tar #docker export 容器 id > 文件名.tar   导出容器(镜像快照)

docker import nginx-jzy.tar nginx-jzy:v2 #使用镜像快照创建镜像,创建的镜像没有 history

docker run -itd --name nginx-jzy-v2 e70d288bc4ef bash #使用上面创建的镜像创建容器,这里必须要有 bash 或者其他可以被挂载的进程

docker save a68a3617e7dd > nginx-jzy-save.tar #保存镜像

docker rmi a68a3617e7dd #删除镜像,因为上面导出容器使用的是这个镜像,所以生成了一个依赖这个镜像的镜像 删除失败了(Error response from daemon: conflict: unable to delete a68a3617e7dd (cannot be forced) - image has dependent child images)

docker image inspect --format=''{{.RepoTags}} {{.Id}} {{.Parent}}'' $(docker image ls -q --filter since=a68a3617e7dd) #找出 from 这个镜像的子镜像([nginx-jzy:v2] sha256:e70d288bc4ef3f20015ca839653c1c1555ee7b2524e4085845348c7d990eb998)

docker rmi -f e70d288bc4ef #删除子镜像失败(Error response from daemon: conflict: unable to delete e70d288bc4ef (cannot be forced) - image is being used by running container be7eea6f8a9b)

docker stop be7eea6f8a9b #停止容器

docker rm be7eea6f8a9b #删除容器

docker rmi -f e70d288bc4ef #删除子镜像成功

docker rmi a68a3617e7dd #删除镜像成功

docker load < nginx-jzy-save.tar #读取保存的镜像文件(生成的镜像文件是有 history 的)

docker inspect imageid #查看镜像详情

 docker network ls #查看网络列表

docker network inspect id1 #查看网络 id 为 id1 的信息

docker network create --subnet=192.168.1.0/24 redis-network #新增网络连接方式(增加网段)

docker run -itd --name redis-test2 --network=redis-network --ip 192.168.1.3 -p 6381:6379 -v /usr/docker/redis/conf/:/usr/src/redis/conf/redis #根据之前的 redis 镜像生成 redis-test2 容器 使用自定义的 redis-network 网络,指定 ip(必须在网段内),指定端口映射,指定共享文件夹

iptables -t nat -L -n #查看桥接网络

1. 为什么系统镜像那么小呢? 因为 docker 镜像在运行的时候直接使用 docker 宿主机器的 kernel,Linux 操作系统由内核空间和用户空间组成。

内核空间是 kernel,用户空间是 rootfs, 不同 Linux 发行版的区别主要是 rootfs. 比如 Ubuntu 14.04 使用 upstart 管理服务,apt 管理软件包; 而 CentOS 7 使用 systemd 和 yum。这些都是用户空间上的区别,Linux kernel 差别不大。所以 Docker 可以同时支持多种 Linux 镜像, 模拟出多种操作系统环境。容器共同使用镜像的内容(如果发生更改先复制镜像层到容器层然后再修改)

2. 镜像的文件如何存储的?

镜像文件是分层存储的,我们可以通过 docker history 命令查看到镜像的历史,也就是层

启动镜像的时候,一个新的可写层会加载到镜像的顶部。这一层通常称为 “容器层”, 之下是 “镜像层”。
容器层可以读写,容器所有发生文件变更写都发生在这一层。镜像层 read-only, 只允许读取。

Container 最上面是一个可写的容器层,以及若干只读的镜像层组成,Container 的数据就存放在这些层中,这样的分层结构最大的特性是 Copy-On-Write (写时复制):

    新数据会直接存放在最上面的 Container 层。

    修改现有的数据会先从 Image 层将数据复制到容器层,修改后的数据直接保存在 Container 层,Image 层保持不变。

3. 启动的容器会占用大量空间吗?

    创建镜像的时候,分层可以让 docker 只保存我们添加和修改的部分内容。其他内容基于 base 镜像,不需要存储,读取 base 镜像即可。如此,当我们创建多个镜像的时候,所有的镜像共享 base 部分。节省了磁盘空间

    docker 通过一个叫做 copy-on-write (CoW) 的策略来保证 base 镜像的安全性,以及更高的性能和空间利用率

    简单的说,启动容器的时候,最上层容器层是可写层,之下的都是镜像层,只读层。

    当容器需要读取文件的时候:从最上层镜像开始查找,往下找,找到文件后读取并放入内存,若已经在内存中了,直接使用。(即,同一台机器上运行的 docker 容器共享运行时相同的文件)。

    当容器需要添加文件的时候:直接在最上面的容器层可写层添加文件,不会影响镜像层。

    当容器需要修改文件的时候:从上往下层寻找文件,找到后,复制到容器可写层,然后,对容器来说,可以看到的是容器层的这个文件,看不到镜像层里的文件。容器在容器层修改这个文件。

    当容器需要删除文件的时候:从上往下层寻找文件,找到后在容器中记录删除。即,并不会真正的删除文件,而是软删除。

    综上,Docker 镜像通过分层实现了资源共享,通过 copy-on-write 实现了文件隔离。

 

    

Docker Swarm Mode 学习笔记 (部署服务)

Docker Swarm Mode 学习笔记 (部署服务)

使用 docker service 命令来管理 Swarm 集群中的服务,该命令只能在管理节点上执行。

新建服务

docker service create --replicas 3 -p 80:80 --name Nginx Nginx:latest

解释一下这条命令:

--replicas 3 : 任务数量

-p 80:80 :配置节点与容器端口映射

--name Nginx :服务名称

Nginx:latest: 镜像名与版本, 与启动容器一致

查看服务

查看当前 Swarm 集群运行的服务: docker service ls

查看单个服务详情: docker service ps 服务名

查看单个服务日志: docker service logs 服务名

删除服务

docker service rm 服务名

在 Swarm 集群中使用 compose 文件

docker-compose.yml 文件不仅仅可以用来编排,启动一组容器,也同样可以用来在 Swarm 集群中编排,启动多个服务。

例子:(注释很详细)

version: "3"

services:
    wordpress:                                              # 声明 wordpress 服务
        image: wordpress                                     # 基于 wordpress 镜像
        ports:                                              # 配置服务与节点之间的端口映射
            - 80:80
        networks:                                           # 设置使用的网络
            - overlay
        environment:                                        # 设置环境变量
            wordpress_DB_HOST: db:3306                        # 设置 wordpress 使用的数据库地址
            wordpress_DB_USER: wordpress                      # 设置 wordpress 数据库访问用户
            wordpress_DB_PASSWORD: wordpress                   # 设置 wordpress 数据库访问密码
        deploy:                                             # 设置服务发布模式
            mode: replicated                                 # 每个工作节点都会运行一个服务
            replicas: 3                                      # 设置 3 个分片
    db:
        image: MysqL
            networks:
                - overlay
            volumes:                                  # 设置数据卷, 数据卷不会因为服务的移除而删除
                - db-data:/var/lib/MysqL
            environment:
                MysqL_ROOT_PASSWORD: somewordpress      # 这里做的 MysqL 数据库设置均置的相对应
                MysqL_DATABASE: wordpress              #  与 wordpress 服务中设置相匹配
                MysqL_USER: wordpress
                MysqL_PASSWORD: wordpress
            deploy:
                placement:                                # 服务发布条件
                    constraints: [node.role == manager]     # 只在管理节点上发布此服务
    visualizer:
        image: dockersamples/visualizer:stable
        ports:
            - "8080:8080"
        stop_grace_period: 1m30s                        # 在收到服务停止信号之后的 1分30秒后退出容器
        volumes:
            - "/var/run/docker.sock:/var/run/docker.sock"
        deploy:
            placement:
                constraints: [node.role == manager]         # 只在管理节点上发布此服务
volumes:
    db-data:                                            # 创建数据卷
networks:
    overlay:                                            # 创建网络

部署服务:

docker stack deploy -c docker-compose.yml wordpress

移除服务:

docker stack rm wordpress 此命令不会移除数据卷。

docker swarm英文文档学习-8-在集群中部署服务

docker swarm英文文档学习-8-在集群中部署服务

Deploy services to a swarm在集群中部署服务

集群服务使用声明式模型,这意味着你需要定义服务的所需状态,并依赖Docker来维护该状态。该状态包括以下信息(但不限于):

应该运行服务容器的镜像名称和标记
有多少容器参与服务
是否有任何端口暴露给集群之外的客户端
当Docker启动时,服务是否应该自动启动
重启服务时发生的特定行为(例如是否使用滚动重启)
服务可以运行的节点的特征(例如资源约束和位置首选项)
有关群模式的概述,请参见 Swarm mode key concepts。有关服务如何工作的概述,请参见How services work。

 

Create a service创建服务

要创建没有额外配置的单副本服务,只需要提供镜像名称。该命令使用随机生成的名称启动Nginx服务,没有发布端口。这是一个简单的示例,因为你无法与Nginx服务交互。

$ docker service create nginx

服务被安排在一个可用的节点上。要确认服务已创建并成功启动,请使用docker service ls命令:

$ docker service ls

ID                  NAME                MODE                REPLICAS            IMAGE                                                                                             PORTS
a3iixnklxuem        quizzical_lamarr    replicated          1/1                 docker.io/library/nginx@sha256:41ad9967ea448d7c2b203c699b429abe1ed5af331cd92533900c6d77490e0268

创建的服务并不总是立即运行。如果服务的镜像不可用,如果没有节点满足你为服务配置的需求,或者其他原因,则该服务可能处于pending挂起状态。有关更多信息,请参见 Pending services

要为你的服务提供名称,请使用--name标志:

$ docker service create --name my_web nginx

与独立容器一样,你可以通过在镜像名称之后添加命令来指定服务容器应该运行的命令。这个例子启动了一个名为helloworld的服务,它使用alpine的镜像并运行命令ping docker.com:

$ docker service create --name helloworld alpine ping docker.com

你还可以为要使用的服务指定一个镜像标记。这个例子修改了前面的例子,使用alpine:3.6标记:

$ docker service create --name helloworld alpine:3.6 ping docker.com

 

Create a service using an image on a private registry使用私有注册表上的镜像创建服务

如果你的镜像在需要登录的私有注册中心上可用,请在登录后使用docker service create的--with-registry-auth标志。如果你的镜像存储在registry.example.com上,这是一个私有注册中心,请使用如下命令:

$ docker login registry.example.com

$ docker service  create \
  --with-registry-auth \
  --name my_service \
  registry.example.com/acme/my_image:latest

这将使用加密的WAL日志将登录令牌从本地客户机传递到部署服务的集群节点。有了这些信息,节点就可以登录到注册中心并拉出镜像。

 

Update a service更新服务

你可以使用docker service update命令更改现有服务的几乎所有内容。更新服务时,Docker将停止其容器并使用新配置重新启动它们。

由于Nginx是一个web服务,如果你将端口80发布到集群之外的客户端,那么它的工作效果会更好。你可以在创建服务时使用-p或--publish标志指定这一点。更新现有服务时,标志为--publish-add。还有一个--publish-rm标志,用于删除先前发布的端口。

假设上一节中的my_web服务仍然存在,使用以下命令更新它以发布端口80。

$ docker service update --publish-add 80 my_web

检查其是否工作,使用:

docker service ls

有关发布端口如何工作的更多信息,请参见publish ports。

你几乎可以更新关于现有服务的所有配置细节,包括它运行的镜像名称和标记。参见Update a service’s image after creation。

 

Remove a service移除服务

要删除服务,请使用docker service remove命令。你可以通过其ID或名称删除服务,如docker service ls命令的输出所示。下面的命令删除my_web服务。

$ docker service remove my_web

 

Service configuration details服务配置细节

下面几节提供关于服务配置的详细信息。本主题并不涵盖每个标志或场景。在几乎所有可以在服务创建时定义配置的实例中,你还可以以类似的方式更新现有服务的配置。

请参阅docker service createdocker service update的命令行引用,或使用--help标志运行这些命令之一。

Configure the runtime environment配置运行环境

你可以为容器中的运行时环境配置以下选项:

  • 使用--env标志表示的环境变量
  • 容器内使用--workdir标志表示的工作目录
  • 使用--user标志表示的用户名或UID

以下服务的容器将环境变量$MYVAR设置为myvalue,从/tmp/目录运行,并作为my_user用户运行。

$ docker service create --name helloworld \
  --env MYVAR=myvalue \
  --workdir /tmp \
  --user my_user \
  alpine ping docker.com

 

Update the command an existing service runs更新存在的服务运行的命令

要更新现有服务运行的命令,可以使用--args标志。下面的示例更新一个名为helloworld的现有服务,使其运行ping docker.com命令,而不是以前运行的任何命令:

$ docker service update --args "ping docker.com" helloworld

 

 

Specify the image version a service should use指定服务应该使用的镜像版本

当你创建一个服务而没有指定要使用的镜像版本的任何细节时,该服务将使用使用latest标记来标记的版本。根据期望的结果,你可以强制服务以几种不同的方式使用镜像的特定版本。
一个镜像版本可以用几种不同的方式表达:
1.如果指定一个标记,则管理器(如果使用content trust,则为Docker客户机)将该标记解析为摘要。当在工作节点上接收到创建容器任务的请求时,工作节点只会看到摘要,而不会看到标记。

注意:

标记即ubuntu:16.04

摘要即对应的sha256:35bc48a1ca97c3971611dc4662d08d131869daa692acb281c7e9e052924e38b1

$ docker service create --name="myservice" ubuntu:16.04

一些标签表示独立的版本,比如ubuntu:16.04。随着时间的推移,这样的标记几乎总是解析为一个稳定的摘要。如果可能的话,建议你使用这种标记。
其他类型的标记,如latest或nightly,可能经常解析为新的摘要,这取决于镜像的作者更新标记的频率。不建议使用频繁更新的标记运行服务,以防止不同的服务复制任务使用不同的镜像版本。


2.如果根本不指定版本,则按照约定将镜像的latest标记解析为摘要。工作人员在创建服务任务时使用此摘要中的镜像。
因此,以下两个命令是等价的:

$ docker service create --name="myservice" ubuntu

$ docker service create --name="myservice" ubuntu:latest

 

3.如果直接指定摘要,则在创建服务任务时总是使用镜像的准确版本。

$ docker service create \
    --name="myservice" \
    ubuntu:16.04@sha256:35bc48a1ca97c3971611dc4662d08d131869daa692acb281c7e9e052924e38b1

在创建服务时,镜像的标记被解析为服务创建时标记所指向的特定摘要。除非服务被显式更新,否则该服务的工作节点将永远使用该特定摘要。如果你确实使用经常更改的标记(如最新),则此功能尤其重要,因为它确保所有服务任务使用相同版本的镜像。

注意:如果启用了内容可信(content trust),客户端实际上会在联系集群管理器之前将镜像的标记解析为摘要,以验证镜像是否已签名。因此,如果你使用内容可信,集群管理器将接收预先解析的请求。在这种情况下,如果客户机无法将镜像解析为摘要,则请求将失败。

如果管理器不能将标记解析为摘要,则每个工作节点负责将标记解析为摘要,不同的节点可能使用不同版本的镜像。如果发生这种情况,将记录如下所示的警告,用占位符替换实际信息。

unable to pin image <IMAGE-NAME> to digest: <REASON>

要查看图像的当前摘要,发出命令docker inspect <IMAGE>:<TAG>并查找RepoDigests行。以下是ubuntu:latest当前的摘要,在编写此内容时是最新的。为了清晰起见,输出被截断。

$ docker inspect ubuntu:latest
...
"RepoDigests": [
  "ubuntu@sha256:35bc48a1ca97c3971611dc4662d08d131869daa692acb281c7e9e052924e38b1"
],
...

创建服务之后,除非你使用--image标记显式地运行docker service update,否则它的镜像永远不会更新,如下所述。其他更新操作(如扩展服务、添加或删除网络或卷、重命名服务或任何其他类型的更新操作)不更新服务的镜像。

 

Update a service’s image after creation创建后更新服务的镜像

每个标记表示一个摘要,类似于Git散列。有些标记(如latest)经常更新以指向新的摘要。其他的,比如ubuntu:16.04,代表了一个已经发布的软件版本,不需要经常更新以指向一个新的摘要。在Docker 1.13及更高版本中,当你创建服务时,它被限制为使用镜像的特定摘要来创建任务,直到你使用--image标志的service update来更新服务为止。如果使用旧版本的Docker引擎,则必须删除并重新创建服务以更新其镜像。

当你使用--image标志运行service update时,swarm manager查询Docker Hub或你的私有Docker注册表,以获取标记当前指向的摘要,并更新服务任务以使用该摘要。

注意:如果使用内容可信content trust,Docker客户机解析镜像,swarm manager接收镜像和摘要,而不是标记。
通常,管理器可以将标记解析为新的摘要和服务更新,重新部署每个任务以使用新镜像。如果管理器无法解决标记或出现其他问题,则接下来的两个部分将概述将会发生的情况。

IF THE MANAGER RESOLVES THE TAG如果管理器解析标记

如果集群管理器可以将镜像标记解析为摘要,它将指示工作节点重新部署任务并在摘要中使用镜像。

  • 如果工作人员在该摘要中缓存了镜像,则使用它。
  • 如果不是,则尝试从Docker Hub或私有注册中心提取镜像:
  1. 如果成功,则使用新镜像部署任务。
  2. 如果worker无法拉出镜像,则服务无法在该worker节点上部署。Docker再次尝试部署任务,可能是在不同的工作节点上。

IF THE MANAGER CANNOT RESOLVE THE TAG如果管理器不能解析标记

如果集群管理器不能将镜像解析为摘要,那么一切都不会丢失:

  • 管理器指示工作节点使用标记处的镜像重新部署任务。
  • 如果worker有一个本地缓存的镜像,该镜像将解析到该标记,那么它将使用该镜像。
  • 如果worker没有解析到标记的本地缓存镜像,则该worker将尝试连接到Docker Hub或私有注册中心以从该标记提取镜像。
  1. 如果成功,工作人员将使用该镜像。
  2. 如果失败,任务将无法部署,管理员将再次尝试部署任务,可能是在不同的工作节点上。

 

Publish ports发布端口

在创建集群服务时,可以通过两种方式将该服务的端口发布到集群之外的主机:

  • 你可以依赖路由网格。当你发布一个服务端口时,集群使服务在每个节点上的目标端口都可以访问,而不管在该节点上运行的服务是否有任务。这并不复杂,而且对于许多类型的服务来说都是正确的选择。
  • 你可以将服务任务的端口直接发布到运行该服务的集群节点上。该特性在Docker 1.13及更高版本中可用。这绕过了路由网格,并提供了最大的灵活性,包括开发自己的路由框架的能力。但是,你负责跟踪每个任务的运行位置,并将请求路由到任务,以及跨节点的负载平衡。

1.PUBLISH A SERVICE’S PORTS USING THE ROUTING MESH使用路由网格发布服务端口

要向集群外部发布服务的端口,使用--publish <PUBLISHED-PORT>:<SERVICE-PORT>。集群使得服务可以在每个集群节点上的已发布端口上访问。如果外部主机连接到任何集群节点上的该端口,则路由网格将其路由到一个任务。外部主机不需要知道与服务交互的服务任务的IP地址或内部使用的端口。当用户或流程连接到服务时,运行服务任务的任何工作节点都可能响应。有关集群服务网络的详细信息,请参见Manage swarm service networks。

Example: Run a three-task Nginx service on 10-node swarm 例子:在10个节点集群中运行三个任务的Ngnix服务

想象你有10个节点的集群,然后你部署了一个Ngnix服务在10个节点上运行三个任务:

$ docker service create --name my_web \
                        --replicas 3 \
                        --publish published=8080,target=80 \
                        nginx

三个任务最多在三个节点上运行。你不需要知道哪些节点正在运行任务;在这10个节点中,连接到端口8080可以将你连接到三个nginx任务之一。你可以用curl来测试。下面的示例假设localhost是集群节点之一。如果不是这种情况,或者本地主机没有解析到你的主机上的IP地址,则替换主机的IP地址或可解析的主机名。

HTML输出被截断:

$ curl localhost:8080

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...truncated...
</html>

后续连接可以路由到相同或不同的群集节点。

 

PUBLISH A SERVICE’S PORTS DIRECTLY ON THE SWARM NODE直接在集群节点中发布服务端口

如果需要根据应用程序的状态进行路由决策,或者需要完全控制将请求路由到服务任务的流程,那么使用路由网格可能不是应用程序的正确选择。要将服务的端口直接发布到其运行的节点上,请使用--publish标志的mode=host选项。

注意:如果你使用mode=host在swarm节点上直接发布一个服务的端口,并且还设置published=<PORT>,这就造成了一个隐含的限制,即你只能在给定的swarm节点上为该服务运行一个任务。你可以通过在没有端口定义的情况下指定published来解决这个问题,这会导致Docker为每个任务分配一个随机端口。

此外,如果你使用mode=host而不使用docker service create上的--mode=global标志,那么很难知道哪些节点正在运行服务来将工作路由到它们。

 

Example: Run an nginx web server service on every swarm node 例子:在每个集群节点上运行nginx web服务器服务

nginx是一个开源的反向代理、负载平衡器、HTTP缓存和web服务器。如果你使用路由网格将nginx作为服务运行,那么连接到任何集群节点上的nginx端口都会显示(有效地)运行该服务的随机集群节点的web页面。

下面的示例将nginx作为服务在集群中的每个节点上运行,并在每个集群节点上本地公开nginx端口。

$ docker service create \
  --mode global \
  --publish mode=host,target=80,published=8080 \
  --name=nginx \
  nginx:latest

你可以在每个集群节点的端口8080上访问nginx服务器。如果向集群中添加一个节点,就会启动nginx任务。你不能在任何绑定到端口8080的集群节点上启动另一个服务或容器。

注意:这是一个简单的例子。为多层服务创建应用层路由框架非常复杂,超出了本主题的范围。

 

Connect the service to an overlay network连接服务到覆盖网络

你可以使用覆盖网络来连接群中的一个或多个服务。
首先,使用docker network create命令和--driver overlay标记在管理器节点上创建覆盖网络。

$ docker network create --driver overlay my-network

在集群模式下创建覆盖网络之后,所有管理器节点都可以访问该网络。
你可以创建一个新的服务,并传递--network标志,将服务附加到覆盖网络:

$ docker service create \
  --replicas 3 \
  --network my-network \
  --name my-web \
  nginx

该集群将my-network扩展到运行服务的每个节点。
你还可以使用--network-add标志将现有服务连接到覆盖网络。

$ docker service update --network-add my-network my-web

要从网络断开正在运行的服务,请使用--network-rm标志。

$ docker service update --network-rm my-network my-web

 

Grant a service access to secrets授予服务对机密的访问权

要创建对docker管理的机密内容有访问权限的服务,请使用--secret标志。有关更多信息,请参见Manage sensitive strings (secrets) for Docker services

Customize a service’s isolation mode自定义服务的隔离模式

Docker 17.12 CE及更高版本允许你指定集群服务的隔离模式。此设置仅适用于Windows主机,对于Linux主机则忽略此设置。隔离模式可以是以下模式之一:

  • default:使用为Docker主机配置的默认隔离模式,如daemon.json中的-exec-opt标志或exec-opts数组所配置的那样。如果守护进程没有指定隔离技术,则process是Windows服务器的默认设置,而hyperv是Windows 10的默认(且唯一)选择。
  • process:将服务任务作为独立的进程在主机上运行。

    注意:process隔离模式仅在Windows服务器上受支持。Windows 10只支持hyperv隔离模式。

  • hyperv:将服务任务作为独立的hyperv任务运行。这增加了开销,但提供了更多的隔离。

在使用--isolation标志创建或更新新服务时,可以指定隔离模式。

 

Control service placement控制服务位置

群服务为你提供了几种不同的方法来控制不同节点上服务的规模和位置。

  • 你可以指定服务需要运行特定数量的副本,还是应该在每个工作节点上全局运行。参见Replicated or global services。
  • 你可以配置服务的CPU或内存需求,并且服务只在满足这些需求的节点上运行。
  • 位置约束允许你将服务配置为仅在具有特定(任意)元数据集的节点上运行,如果不存在适当的节点,则会导致部署失败。例如,你可以指定你的服务只能在任意标签pci_compatible设置为true的节点上运行。
  • 位置首选项让你可以对每个节点应用具有一系列值的任意标签,并使用算法将服务的任务分散到这些节点上。目前,唯一受支持的算法是spread,它试图将它们平均放置。例如,如果你标记每个节点带着一个值从1到10的标签rack,然后指定一个位置首选项值标签rack,然后在其他位置限制,位置偏好,和其他特定于节点的限制后,服务任务将尽可能均匀地放置在所有带着标签rack的节点,。

与约束不同,位置首选项是最有效的,如果没有节点能够满足首选项,服务不会失败部署。如果你指定了服务的位置首选项,那么当集群管理器决定哪些节点应该运行服务任务时,与该首选项匹配的节点的排名会更高。其他因素,如服务的高可用性,也会影响到计划在其中运行服务任务的节点。举个例子,如果你有N个节点带着标签(还有一些其他人),和你的服务配置是要运行N + 1副本,首先将会降N个任务放置到带有rack标签的节点上,然后+ 1将调度到一个并没有服务在上面的节点,如果这个节点存在,无论该节点带有rack标签或不带有。

 

REPLICATED OR GLOBAL SERVICES复制或全局服务

集群模式有两种服务类型:复制replicated服务和全局global服务。对于复制的服务,你可以为swarm manager指定要调度到可用节点上的复制任务的数量。对于全局服务,调度器在满足服务的位置约束和资源需求的每个可用节点上放置一个任务。
使用--mode标志控制服务的类型。如果不指定模式,则服务默认为复制。对于复制的服务,指定要开始使用--replicas标志的复制任务的数量。例如,使用3个复制任务启动一个复制的nginx服务:

$ docker service create \
  --name my_web \
  --replicas 3 \
  nginx

要在每个可用节点上启动全局服务,请将--mode global传递给docker service create。每当新节点可用时,调度器将全局服务的任务放置在新节点上。例如,启动一个在群中的每个节点上运行alpine的服务:

$ docker service create \
  --name myservice \
  --mode global \
  alpine top

服务约束允许你在调度程序将服务部署到节点之前为节点设置要满足的条件。你可以基于节点属性和元数据或引擎元数据对服务应用约束。有关约束的更多信息,请参阅docker service create CLI reference

 

RESERVE MEMORY OR CPUS FOR A SERVICE为服务保留内存或cpu

若要为服务保留给定的内存或cpu数量,请使--reserve-memory或--reserve-cpu标志。如果没有可用的节点可以满足需求(例如,如果你请求4个cpu,而集群中没有节点有4个cpu),则服务将保持挂起状态,直到有合适的节点可以运行其任务为止。

Out Of Memory Exceptions (OOME)

如果你的服务试图使用比群集节点可用的内存更多的内存,那么你可能会遇到内存不足异常(OOME),内核OOM杀手可能会杀死容器或Docker守护进程。要防止这种情况发生,请确保你的应用程序在具有足够内存的主机上运行,查看 Understand the risks of running out of memory.
Swarm服务允许你使用资源约束、位置首选项和标签来确保你的服务被部署到适当的Swarm节点。

 

PLACEMENT CONSTRAINTS位置约束

使用位置约束来控制可以分配给服务的节点。在下面的示例中,服务仅在标签region设置为east的节点上运行。如果没有适当标记的节点可用,任务将在Pending中等待,直到它们可用为止。--constraint标志使用一个等式运算符(== or !=)。对于复制的服务,可能所有服务都运行在相同的节点上,或者每个节点只运行一个副本,或者一些节点不运行任何副本。对于全局服务,服务在满足位置约束和任何资源需求的每个节点上运行。

$ docker service create \
  --name my-nginx \
  --replicas 5 \
  --constraint node.labels.region==east \
  nginx

你还可以在docker-compose.yml文件中使用constraint服务级别键。
如果指定多个放置约束,则服务只部署到所有节点都满足的节点上。下面的示例将服务限制为在所有节点上运行,其中region设置为east, type设置为devel:

$ docker service create \
  --name my-nginx \
  --mode global \
  --constraint node.labels.region==east \
  --constraint node.labels.type!=devel \
  nginx

还可以将位置约束与位置首选项和CPU/内存约束结合使用。注意不要使用不可能完成的设置。
有关约束的更多信息,请参阅docker service create CLI reference

 

PLACEMENT PREFERENCES位置首选项

虽然位置约束限制了服务可以在其上运行的节点,但是位置首选项尝试以算法的方式将服务放置在适当的节点上(目前,仅平均分布)。例如,如果你为每个节点分配一个rack标签,那么你可以设置一个位置首选项,通过值将服务均匀地分布到带有rack标签的节点上。这样,如果你丢失了一个rack,服务仍然在其他rack上的节点上运行。
位置首选项不严格执行。如果没有节点具有你在首选项中指定的标签,则会像未设置首选项一样部署服务。
全局服务忽略位置首选项。
下面的示例设置了一个首选项,根据datacenter标签的值将部署分散到节点上。如果某些节点具有datacenter=us-east,而其他节点具有datacenter=us-west,则服务在这两组节点之间尽可能均匀地部署。

$ docker service create \
  --replicas 9 \
  --name redis_2 \
  --placement-pref ''spread=node.labels.datacenter'' \
  redis:3.0.6

⚠️Missing or null labels

缺少用于扩展的标签的节点仍然接收任务分配。作为一个组,这些节点接收任务的比例与由特定标签值标识的任何其他组相同。从某种意义上说,缺失的标签等同于标签上附加了一个空null值。如果服务应该只在使用spread首选项的标签的节点上运行,则应该将首选项与约束结合起来。

你可以指定多个位置首选项,并按照遇到的顺序处理它们。下面的示例设置具有多个位置首选项的服务。任务首先分布在各个datacenters,然后分布在rack上(如各自的标签所示):

$ docker service create \
  --replicas 9 \
  --name redis_2 \
  --placement-pref ''spread=node.labels.datacenter'' \
  --placement-pref ''spread=node.labels.rack'' \
  redis:3.0.6

还可以将位置首选项与位置约束或CPU/内存约束结合使用。注意不要使用不可能完成的设置。
这个图表说明了如何放置首选项工作:

当使用docker service update更新服务时,--placater -pref-add在所有现有的放置首选项之后追加一个新的放置首选项。--placater-pref-rm删除与参数匹配的现有位置首选项。

 

Configure a service’s update behavior配置服务的更新行为

在创建服务时,可以指定一个滚动更新行为,说明在运行docker service update时集群应该如何将更改应用于服务。你还可以将这些标志指定为更新的一部分,作为docker service update的参数。
--update-delay标志配置服务任务或任务集更新之间的时间延迟。你可以将时间T描述为Ts秒数、Tm分钟数或Th小时数的组合。所以10m30s表示10分30秒的延迟。
默认情况下,调度程序每次更新一个任务。你可以传递--update-parallelism标志来配置调度程序同时更新的服务任务的最大数量。

当对单个任务的更新返回RUNNING的状态时,调度器将继续更新,方法是继续到另一个任务,直到所有任务都被更新。如果在更新期间某个任务返回FAILED,调度程序将暂停更新。你可以使用docker service create或docker service update的--update-failure-action标志来控制行为。

在下面的示例服务中,调度器每次最多应用两个副本的更新。当更新后的任务返回RUNNING或FAILED时,调度器将等待10秒后停止下一个任务更新:

$ docker service create \
  --replicas 10 \
  --name my_web \
  --update-delay 10s \
  --update-parallelism 2 \
  --update-failure-action continue \
  alpine

--update-max-failure-ratio标志控制在整个更新被认为失败之前的更新过程中有多少任务会失败。例如,使用--update-max-failure-ratio 0.1 --update-failure-action pause,在更新的任务中有10%失败后,更新将暂停。

如果任务没有启动,或者在--update-monitor标志指定的监视周期内停止运行,则认为单个任务更新失败。--update-monitor的默认值是30秒,这意味着在任务启动后的前30秒内失败的任务将计入服务更新失败阈值,而启动后的失败则不计入。

 

Roll back to the previous version of a service回滚到服务的上一个版本

如果服务的更新版本没有如预期那样发挥作用,可以使用docker service update的--rollback标志手动回滚到服务的前一个版本。这将服务恢复到docker service update命令之前的配置。

其他选项可以与--rollback结合使用;例如--update-delay 0s执行回滚,任务之间不存在延迟:

$ docker service update \
  --rollback \
  --update-delay 0s
  my_web

在Docker 17.04及更高版本中,可以配置服务,以便在服务更新部署失败时自动回滚。参见Automatically roll back if an update fails。
与新的自动回滚特性相关的是,在Docker 17.04及更高版本中,如果守护进程运行Docker 17.04或更高版本,则手动回滚将在服务器端处理,而不是在客户端处理。这允许手动启动的回滚尊重新的回滚参数。客户机是版本敏感的,因此它仍然对较旧的守护进程使用旧方法。
最后,在Docker 17.04及更高版本中,--rollback不能与Docker服务更新的其他标志一起使用。

 

Automatically roll back if an update fails如果更新失败则自动回滚

你可以这样配置服务:如果对服务的更新导致重新部署失败,服务可以自动回滚到上一个配置。这有助于保护服务可用性。你可以在服务创建或更新时设置以下一个或多个标志。如果没有设置值,则使用默认值。

Flag Default Description
--rollback-delay 0s 指定在回滚一个任务之后等待的时间,然后再回滚下一个任务。值0表示在第一个回滚任务部署之后立即回滚第二个任务。
--rollback-failure-action pause 当一个任务无法回滚时,是暂停还是继续尝试回滚其他任务。
--rollback-max-failure-ratio 0 回滚期间容忍的失败率,指定为0到1之间的浮点数。例如,给定5个任务,.2的失败率将允许一个任务(0.2*5=1)不能回滚。值为0表示不允许出现故障,值为1表示允许出现任意数量的故障。
--rollback-monitor 5s 每个任务回滚后的持续时间,以监视失败情况。如果任务在此时间段结束之前停止,则认为回滚失败。
--rollback-parallelism 1 并行回滚的最大任务数。默认情况下,一次回滚一个任务。值0将导致并行回滚所有任务。

下面的示例将redis服务配置为在docker service update部署失败时自动回滚。两个任务可以并行回滚。在回滚之后,将对任务进行20秒的监视,以确保它们不退出,并且允许最大失败率为20%。默认值用于--rollback-delay和--rollback-failure-action。

$ docker service create --name=my_redis \
                        --replicas=5 \
                        --rollback-parallelism=2 \
                        --rollback-monitor=20s \
                        --rollback-max-failure-ratio=.2 \
                        redis:latest

 

Give a service access to volumes or bind mounts授予服务访问卷或绑定挂载的权限

为了获得最佳的性能和可移植性,应该避免将重要数据直接写入容器的可写层,而是使用数据量或绑定挂载。这个原则也适用于服务。

你可以为群集中的服务创建两种类型的挂载,volume挂载或bind挂载。无论使用哪种类型的挂载,在创建服务时使用--mount标志配置它,在更新现有服务时使用--mount-add或--mount-rm标志配置它。如果不指定类型,默认值是一个数据卷。

DATA VOLUMES数据卷

数据卷是独立于容器存在的存储。集群服务下的数据量的生命周期类似于容器下的生命周期。卷的寿命比任务和服务长,因此它们的删除必须单独管理。可以在部署服务之前创建卷,或者在部署任务时,如果在特定主机上不存在卷,则根据服务上的卷规范自动创建卷。
要将现有数据卷与服务一起使用,请使用--mount标志:

$ docker service create \
  --mount src=<VOLUME-NAME>,dst=<CONTAINER-PATH> \
  --name myservice \
  <IMAGE>

如果在将任务调度到特定主机时,不存在具有相同<VOLUME-NAME>的卷,则创建一个。默认的卷驱动程序是local的。要使用具有这种按需创建模式的不同卷驱动程序,请使用--mount标志指定驱动程序及其选项:

$ docker service create \
  --mount type=volume,src=<VOLUME-NAME>,dst=<CONTAINER-PATH>,volume-driver=<DRIVER>,volume-opt=<KEY0>=<VALUE0>,volume-opt=<KEY1>=<VALUE1>
  --name myservice \
  <IMAGE>

有关如何创建数据卷和使用卷驱动程序的更多信息,请参见 Use volumes.

 

BIND MOUNTS绑定挂载

绑定挂载是来自调度程序为任务部署容器的主机的文件系统路径。Docker将路径装载到容器中。在集群初始化任务的容器之前,文件系统路径必须存在
下面的例子展示了绑定挂载语法:

  • 要挂载读写绑定:
$ docker service create \
  --mount type=bind,src=<HOST-PATH>,dst=<CONTAINER-PATH> \
  --name myservice \
  <IMAGE>
  • 挂载只读绑定:
$ docker service create \
  --mount type=bind,src=<HOST-PATH>,dst=<CONTAINER-PATH>,readonly \
  --name myservice \
  <IMAGE>

重要提示:绑定挂载可能有用,但也可能导致问题。在大多数情况下,建议你对应用程序进行架构设计,以避免从主机挂载路径。主要风险包括:

  • 如果将主机路径绑定到服务容器中,则该路径必须存在于每个群集节点上。Docker群模式调度程序可以在任何满足资源可用性要求并满足你指定的所有约束和位置首选项的机器上调度容器。
  • 如果运行中的服务容器变得不健康或无法访问,Docker群模式调度程序可能会在任何时候重新调度它们。
  • 主机绑定安装是不可移植的。在使用绑定挂载时,不能保证应用程序在开发中以与在生产中相同的方式运行。

 

Create services using templates使用模版创建服务

你可以使用Go的文本/模板包提供的语法,为service create的一些标志使用模板。
支持以下标志:

  • --hostname
  • --mount
  • --env

Go模板的有效占位符如下:

Placeholder Description
.Service.ID Service ID
.Service.Name Service name
.Service.Labels Service labels
.Node.ID Node ID
.Node.Hostname Node hostname
.Task.Name Task name
.Task.Slot Task slot

TEMPLATE EXAMPLE模版例子

这个示例根据服务的名称和运行容器的节点的ID设置创建的容器的模板:

$ docker service create --name hosttempl \
                        --hostname="{{.Node.ID}}-{{.Service.Name}}"\
                         busybox top

要查看使用模板的结果,请使用docker service ps和docker inspect命令。

$ docker service ps va8ew30grofhjoychbr6iot8c

ID            NAME         IMAGE                                                                                   NODE          DESIRED STATE  CURRENT STATE               ERROR  PORTS
wo41w8hg8qan  hosttempl.1  busybox:latest@sha256:29f5d56d12684887bdfa50dcd29fc31eea4aaf4ad3bec43daf19026a7ce69912  2e7a8a9c4da2  Running        Running about a minute ago

 

$ docker inspect --format="{{.Config.Hostname}}" hosttempl.1.wo41w8hg8qanxwjwsg4kxpprj

 

docker 停止服务 部署服务

docker 停止服务 部署服务

//显示所有容器 一个容器只管理一个服务 即使容器挂掉也不会影响其他容器的服务 做到业务之间不影响
root@river-NUC8i7HNK:/# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e8cfcbe6a280 etl-online:1.0 "java -Djava.securit…" About an hour ago Up About an hour 0.0.0.0:8070->8070/tcp etl-online_etl-online_1 377db9b29f0f web:3.0 "java -Djava.securit…" 11 days ago Up 11 days 0.0.0.0:30003->30003/tcp web_power_1 cf44fc608372 power:2.0 "java -Djava.securit…" 11 days ago Up 11 days 0.0.0.0:8000->30001/tcp power_power_1 4f951b13e170 etl:2.0 "java -Djava.securit…" 2 weeks ago Up 2 weeks 0.0.0.0:8090->8090/tcp etl_power_1 524d7d7ae738 redis:4 "docker-entrypoint.s…" 4 weeks ago Up 4 weeks 0.0.0.0:6379->6379/tcp redis_redis_1 //停止id为e8的服务
root@river
-NUC8i7HNK:/# docker stop e8 e8
//显示所有容器 (包括已停止 和 正在运行的 所有容器)
//可以看到刚刚停掉的容器e8依然在 root@river
-NUC8i7HNK:/# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e8cfcbe6a280 etl-online:1.0 "java -Djava.securit…" About an hour ago Exited (143) 35 seconds ago etl-online_etl-online_1 377db9b29f0f web:3.0 "java -Djava.securit…" 11 days ago Up 11 days 0.0.0.0:30003->30003/tcp web_power_1 cf44fc608372 power:2.0 "java -Djava.securit…" 11 days ago Up 11 days 0.0.0.0:8000->30001/tcp power_power_1 ac631c839c3f web:2.0 "java -Djava.securit…" 13 days ago Exited (143) 11 days ago stoic_brahmagupta 4f951b13e170 etl:2.0 "java -Djava.securit…" 2 weeks ago Up 2 weeks 0.0.0.0:8090->8090/tcp etl_power_1 524d7d7ae738 redis:4 "docker-entrypoint.s…" 4 weeks ago Up 4 weeks 0.0.0.0:6379->6379/tcp redis_redis_1 //删掉容器 e8
root@river
-NUC8i7HNK:/# docker rm e8 e8
//显示所有容器 刚刚被删掉的e8容器已经不在 root@river
-NUC8i7HNK:/# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 377db9b29f0f web:3.0 "java -Djava.securit…" 11 days ago Up 11 days 0.0.0.0:30003->30003/tcp web_power_1 cf44fc608372 power:2.0 "java -Djava.securit…" 11 days ago Up 11 days 0.0.0.0:8000->30001/tcp power_power_1 ac631c839c3f web:2.0 "java -Djava.securit…" 13 days ago Exited (143) 11 days ago stoic_brahmagupta 4f951b13e170 etl:2.0 "java -Djava.securit…" 2 weeks ago Up 2 weeks 0.0.0.0:8090->8090/tcp etl_power_1 524d7d7ae738 redis:4 "docker-entrypoint.s…" 4 weeks ago Up 4 weeks 0.0.0.0:6379->6379/tcp redis_redis_1 //显示所有镜像
root@river
-NUC8i7HNK:/# docker images REPOSITORY TAG IMAGE ID CREATED SIZE etl-online 1.0 ea5d3b622b9a About an hour ago 129MB web 3.0 827e32b2d8d0 11 days ago 148MB power 2.0 e724aa1ca532 11 days ago 144MB web 2.0 f92b3295b202 13 days ago 148MB etl 2.0 af8defc8f406 2 weeks ago 142MB redis 4 29c39fa179d6 8 weeks ago 89.2MB openjdk 8-jdk-alpine a3562aa0b991 5 months ago 105MB //删除 镜像名为ea的镜像
root@river
-NUC8i7HNK:/# docker rmi ea Untagged: etl-online:1.0 Deleted: sha256:ea5d3b622b9a5c8e2a5dfaf1bf7d80b8dcd57276cc60f7ee43e8ef59b9473d5f Deleted: sha256:d5c6bc729e27c1a880841e1fea67cff7afaced7c6dea0f91a40ead7498063ae7 Deleted: sha256:e07da659170a89263aa49421bfae3a650e37e07fc5ab075929a2b93dbb1a0a80 Deleted: sha256:27943a63846ab43d150b7b1a3ce65214863cf317cf1e54a019de1ee393553412 Deleted: sha256:fc0e8cde49b25fdc8d4c3b650aa122ad2383ad7f91bc3845357c38e496e7cedc Deleted: sha256:99e6f0a38f9e9f9c57aa74d811232b620815b4ccfe7870be3088ae2ad469a3a0 root@river-NUC8i7HNK:/#

上述过程为 停止服务 停止服务前 要先删容器 再删镜像

下述过程为 上传jar包 在docker中启动该服务(jar包)

//rz 上传jar包到此处 查看如下 etl-online-2.0-SNAPSHOT.jar
root@river-NUC8i7HNK:/package/etl-online# ll 总用量 24064 drwxr-xr-x 2 root root 4096 10月 10 17:24 ./ drwxr-xr-x 3 root root 4096 10月 10 16:22 ../ -rw-r--r-- 1 root root 249 10月 10 16:25 docker-compose.yml -rw-r--r-- 1 root root 264 10月 10 16:24 Dockerfile -rw-r--r-- 1 root root 24622035 10月 10 17:19 etl-online-2.0-SNAPSHOT.jar
//一键启动命令 docker-compose up -d (先生成镜像再生成容器)
root@river-NUC8i7HNK:/package/etl-online# docker-compose up -d
//下面为启动成功的日志 Building etl
-online Step 1/6 : FROM openjdk:8-jdk-alpine ---> a3562aa0b991 Step 2/6 : VOLUME /tmp ---> Using cache ---> 8357f856edc2 Step 3/6 : ADD etl-online-2.0-SNAPSHOT.jar app.jar ---> 8f2af2b3e46a Step 4/6 : ENTRYPOINT ["java","-Djava.security.egd=fele:/dev/./urandom","-jar","/app.jar"] ---> Running in 61869b4bc3d3 Removing intermediate container 61869b4bc3d3 ---> e1acb02e507b Step 5/6 : ENV TZ=Asia/Shanghai ---> Running in 4111226fd387 Removing intermediate container 4111226fd387 ---> fce921d488aa Step 6/6 : RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone ---> Running in 49fb66f0821f Removing intermediate container 49fb66f0821f ---> d3c32537e84e Successfully built d3c32537e84e Successfully tagged etl-online:1.0 WARNING: Image for service etl-online was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`. Creating etl-online_etl-online_1 ... done
//查看正在运行的容器 etl-online已在运行中 up 7 seconds root@river
-NUC8i7HNK:/package/etl-online# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 1c0d012c9ba4 etl-online:1.0 "java -Djava.securit…" 9 seconds ago Up 7 seconds 0.0.0.0:8070->8070/tcp etl-online_etl-online_1 377db9b29f0f web:3.0 "java -Djava.securit…" 11 days ago Up 11 days 0.0.0.0:30003->30003/tcp web_power_1 cf44fc608372 power:2.0 "java -Djava.securit…" 11 days ago Up 11 days 0.0.0.0:8000->30001/tcp power_power_1 4f951b13e170 etl:2.0 "java -Djava.securit…" 2 weeks ago Up 2 weeks 0.0.0.0:8090->8090/tcp etl_power_1 524d7d7ae738 redis:4 "docker-entrypoint.s…" 4 weeks ago Up 4 weeks 0.0.0.0:6379->6379/tcp redis_redis_1 root@river-NUC8i7HNK:/package/etl-online#

docker-compose.yml

version: ''2''
services:
 etl-online:
  image: etl-online:1.0   指定 镜像名称
  build: .
  ports:
         - "8070:8070"   端口映射
  extra_hosts:
         - "自定义:192.168.3.118"  ip映射
         - "自定义:192.168.3.118"
         - "自定义:192.168.3.118"

Dockerfile

FROM openjdk:8-jdk-alpine
VOLUME /tmp
ADD etl-online-2.0-SNAPSHOT.jar app.jar   //指定jar包名字 启动容器会根据这里的名字去找jar包
ENTRYPOINT ["java","-Djava.security.egd=fele:/dev/./urandom","-jar","/app.jar"]
ENV TZ=Asia/Shanghai  //时区
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
~

 

关于Zeroc Ice 学习笔记 --Docker 部署服务docker部署odoo的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于1.docker 学习笔记之入门,docker 在 centos7 下的安装以及基础命令的使用、Docker Swarm Mode 学习笔记 (部署服务)、docker swarm英文文档学习-8-在集群中部署服务、docker 停止服务 部署服务等相关知识的信息别忘了在本站进行查找喔。

本文标签: