Dockerfile

通俗地讲,它是为了指导单个镜像从无到有的构建过程。如果你镜像是从Docker registry上面拉下来的,那就用不到这个文件;如果你是自己的应用,想打包成镜像,那就需要这个文件。

Dockerfile资料:http://www.docker.org.cn/dockerppt/114.html

Docker Swarm

一句话,这个东西是用来搭建Docker集群的。

示例:(两台已经安装好Docker的机器:192.168.192.128 和 192.168.192.130

128上:(初始化为Manager,然后开启防火墙端口)

[root@localhost DockerComposeFolder]# docker swarm init
Swarm initialized: current node (pmio659q4pm90nlvtoe5ak293) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join --token SWMTKN-1-17usxu5fddmp2laagvpatbgrq8tiigfj4ejgcmuof1oy942842-9r9jkrf33tico042cs684e886 192.168.192.128:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

[root@localhost DockerComposeFolder]# firewall-cmd --zone=public --add-port=2377/tcp --permanent
success
[root@localhost DockerComposeFolder]# systemctl restart firewalld

130上:(加入集群成为一个Worker)

[root@localhost admin]# firewall-cmd --zone=public --add-port=2377/tcp --permanent
success
[root@localhost admin]# systemctl restart firewalld
[root@localhost admin]# docker swarm join --token SWMTKN-1-17usxu5fddmp2laagvpatbgrq8tiigfj4ejgcmuof1oy942842-9r9jkrf33tico042cs684e886 192.168.192.128:2377
This node joined a swarm as a worker.

128上:(列出节点列表)

[root@localhost DockerComposeFolder]# docker node ls
ID                            HOSTNAME                STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
ply3z1rbyxn967zqdqltc5j7w     localhost.localdomain   Ready               Active                                  19.03.2
pmio659q4pm90nlvtoe5ak293 *   localhost.localdomain   Ready               Active              Leader              19.03.1

当前节点退出集群

docker swarm leave --force

更新集群

docker swarm update

应用示例:(在Learder上【128节点】

1. 编写一个compose文件

[root@localhost DockerComposeFolder]# vim docker-compose-demo.yml

---

version: '3.7'

services:
  redis:
    image: redis
    ports:
      - "6379"
    deploy:
      replicas: 2
      update_config:
        parallelism: 2
        delay: 10s
      restart_policy:
        condition: on-failure
    networks:
      - swarmnet

  visualizer:
    image: dockersamples/visualizer:stable
    ports:
      - "8080:8080"
    stop_grace_period: 1m30s
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
    deploy:
      placement:
        constraints: [node.role == manager]
    networks:
      - swarmnet
networks: # 自定义网络
  swarmnet:

2. 启动

[root@localhost DockerComposeFolder]# docker stack deploy -c docker-compose-demo.yml my_first_app
Creating network my_first_app_swarmnet
Creating service my_first_app_visualizer
Creating service my_first_app_redis
[root@localhost DockerComposeFolder]# 

3. 查看

# stack列表
[root@localhost DockerComposeFolder]# docker stack ls
NAME                SERVICES            ORCHESTRATOR
my_first_app        2                   Swarm

# 服务列表
[root@localhost DockerComposeFolder]# docker service ls
ID                  NAME                      MODE                REPLICAS            IMAGE                             PORTS
w3a6mgfouljz        my_first_app_redis        replicated          2/2                 redis:latest                      *:30005->6379/tcp
pmakz6gwandv        my_first_app_visualizer   replicated          1/1                 dockersamples/visualizer:stable   *:8080->8080/tcp

4. 访问Visualizer(Leader的IP:8080)记得开放防火墙端口

5. 停止stack

[root@localhost DockerComposeFolder]# docker stack rm my_first_app
Removing service my_first_app_redis
Removing service my_first_app_visualizer
Removing network my_first_app_swarmnet

6. 说明配置:deploy下的placement

配置这个可以规定服务的位置,如上面的结果,Visualizer只会在Manager上运行,而redis则会出现在Manager以及Worker上。

部署应用示例

打包镜像参考:https://www.cnblogs.com/LUA123/p/11436805.html

注意,本示例中,web程序的开放端口是8081

1. 配置仓库

因为我们的本地应用仓库在128上,如果130节点也想运行我们的web项目,那么需要配置仓库地址,不然找不到

vim /etc/docker/daemon.json
# 里面是仓库地址,根据情况自行修改
{
  "insecure-registries":["192.168.192.128:443"]
}

2. 编写yml文件

version: '3.7'

services:
  web:
    image: 192.168.192.128:443/hello-2
    deploy:
      replicas: 2
      restart_policy:
        condition: on-failure
      resources:
        limits:
          cpus: "0.1"
          memory: 50M
    ports:
      - "8081:8081"
    networks:
      - swarmnet

  redis:
    image: redis
    ports:
      - "6379"
    deploy:
      replicas: 2
      update_config:
        parallelism: 2
        delay: 10s
      restart_policy:
        condition: on-failure
    networks:
      - swarmnet

  visualizer:
    image: dockersamples/visualizer:stable
    ports:
      - "8080:8080"
    stop_grace_period: 1m30s
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
    deploy:
      placement:
        constraints: [node.role == manager]
    networks:
      - swarmnet
networks: # 自定义网络
  swarmnet:

启动

[root@localhost DockerComposeFolder]# docker stack deploy -c docker-compose-demo.yml my_first_app
Creating network my_first_app_swarmnet
Creating service my_first_app_redis
Creating service my_first_app_visualizer
Creating service my_first_app_web

128节点查看

130节点查看

访问128节点的Visualizer :http://192.168.192.128:8080/

打开8081防火墙端口后访问

Docker Stack(Docker堆栈)

在上面的小例子已经有了体现。一句话,能够一键部署一整套服务。

1. docker stack deploy 部署新的堆栈或者更新现有堆栈

docker stack deploy -c docker-compose-demo.yml my_first_app

-c:指定配置文件
my_first_app:指定stack名字

2. docker stack ls 显示堆栈列表

[root@localhost DockerComposeFolder]# docker stack ls
NAME                SERVICES            ORCHESTRATOR
my_first_app        2                   Swarm

3. docker stack ps 列出堆栈中的任务

[root@localhost DockerComposeFolder]# docker stack ps my_first_app
ID                  NAME                        IMAGE                             NODE                    DESIRED STATE       CURRENT STATE           ERROR               PORTS
r41ww3p604z5        my_first_app_visualizer.1   dockersamples/visualizer:stable   localhost.localdomain   Running             Running 8 minutes ago
1jirtqlappdp        my_first_app_redis.1        redis:latest                      localhost.localdomain   Running             Running 8 minutes ago
yr4sz7k5uwpk        my_first_app_redis.2        redis:latest                      localhost.localdomain   Running             Running 8 minutes ago                       

4. docker stack services 列出堆栈中的服务

[root@localhost DockerComposeFolder]# docker stack services my_first_app
ID                  NAME                      MODE                REPLICAS            IMAGE                             PORTS
pmakz6gwandv        my_first_app_visualizer   replicated          1/1                 dockersamples/visualizer:stable   *:8080->8080/tcp
w3a6mgfouljz        my_first_app_redis        replicated          2/2                 redis:latest                      *:30005->6379/tcp

5. docker stack rm 删除一个或多个堆栈

[root@localhost DockerComposeFolder]# docker stack rm my_first_app
Removing service my_first_app_redis
Removing service my_first_app_visualizer
Removing network my_first_app_swarmnet

Docker Compose

它是为了指导单个“服务”的构建过程,“服务”实际上包含一个或者多个运行状态下的容器。在服务中运行的单个容器称为任务,每个任务的ID是数字唯一递增的。一般你的应用都需要依赖很多其它的环境,比如:数据库啊、redis啊、zookeeper啊等等,你也可以一个一个配置参数启动,但是有了docker-compose,你只需要把事先准备的好的配置写在文件里,然后docker-compose up一键启动即可,相比一个一个手动启动,方便了很多也减少了出错机会。你会发现,它和Docker Stack的作用差不多。区别如下:

详解docker-compose.yml文件

version

查看Docker信息执行:docker info 或者 docker --version

[root@localhost admin]# docker --version
Docker version 19.03.1, build 74b1e89

提醒:你可以结合docker 命令(比如:build、run、network等等)来理解docker-compose

Run命令:https://docs.docker.com/engine/reference/commandline/run/

Docker-Compose-File:https://docs.docker.com/compose/compose-file/

以下选项是 docker-compose up 支持,而docker stack deploy 不支持的

compose文件(包含大部分选项)

version: "3.7"
services:
  webapp:
    # build,构建一个镜像(利用docker-compose执行此文件);如果在集群模式下部署,将忽略此项,docker stack仅仅接受预先构建好的镜像。
    build:
      # 包含Dockerfile的路径,当提供的是相对路径,解释为相对于compose文件的位置。
      context: ./dir
      # Compose使用指定的Dockerfile文件来构建
      dockerfile: Dockerfile-alternate
      # 构建参数,这些参数只能在构建过程中访问
      args:
        - buildno=1
        - hash=cdc3b19
      # 缓存(v3.2开始)
      cache_from:
        - alpine:latest
      # 构建指定阶段的Dockerfile(v3.4开始。参考:多阶段构建文档:https://docs.docker.com/develop/develop-images/multistage-build/)
      target: prod
      # 指定生成的容器中/dev/shm分区的大小(v3.5开始。可以为字符串'1gb'或者整数数字1000000)
      shm_size: '1gb'

    # build或者指定镜像的话,此项为镜像名称
    image:app:tag
    # 容器标签(也可以这样写 com.example.description: "Accounting webapp")
    labels:
      - "com.example.description=Accounting webapp"
    # 添加容器功能(执行man 7 capabilities查看全部)
    cap_add:
      - ALL
    # 删除容器功能
    cap_drop:
      - NET_ADMIN
      - SYS_ADMIN
    # 为容器指定可选的父cgroup
    cgroup_parent: m-executor-abcd
    #覆盖默认命令(也可以是个列表,类似于Dockerfile:command: ["bundle", "exec", "thin", "-p", "3000"])
    command: bundle exec thin -p 3000
    # 默认docker-compose up 会按照顺序启动服务,如果你有前后顺序,可以指定这个参数,代表db和redis先于webapp启动
    depends_on:
      - db
      - redis
    # 部署(仅限v3版本,并且只适合集群部署(docker stack),docker-compose up 将忽略这个选项)
    deploy:
      # 启动容器副本数
      replicas: 6
      # 资源限制
      resources:
        # 不超过单核CPU的50%可用处理时间 & 不超过50M内存
        limits:
          cpus: '0.50'
          memory: 50M
        # 始终可用25%CPU时间 & 20M内存
        reservations:
          cpus: '0.25'
          memory: 20M
      # 重启策略
      restart_policy:
        # 重启时机(none、on-failure、any,默认any)
        condition: on-failure
        # 重启尝试的等待时间
        delay: 5s
        # 最大重试次数(默认永远重试)
        max_attempts: 3
        # 在决定重新启动是否成功之前等待多长时间(默认立即决定)
        window: 120s
      # 配置服务如何更新
      update_config:
        # 一次更新的容器数
        parallelism: 2
        # 更新一组容器之间的等待时间
        delay: 10s
      # 服务标签
      labels:
        com.example.description: "This label will appear on the web service"
    # 覆盖默认的entrypoint
    entrypoint: /code/entrypoint.sh
    # 从文件添加环境变量。可以是单个值(env_file: .env)或列表,文件内容每一行都是var=val格式化的,# 开头的和空行都被忽略
    env_file:
      - ./common.env
      - ./apps/web.env
      - /opt/secrets.env
    # 添加环境变量,如果是布尔值要用引号括起来
    environment:
      - RACK_ENV=development
      - SHOW=true
      - SESSION_SECRET
    # 暴露端口但是不把它们发布到主机,它们只能被链接服务访问。只能指定内部端口。
    expose:
      - "3000"
      - "8000"
    # 链接到外部的容器(格式为 容器名称:别名)
    external_links:
      - redis_1
      - project_db_1:mysql
      - project_db_1:postgresql
    # 添加主机名映射
    extra_hosts:
      - "somehost:162.242.195.82"
      - "otherhost:50.31.209.229"
    # 日志
    logging:
      # 驱动(默认json-file,还可以为syslog和none)
      driver: "json-file"
      options:
        # 日志最大大小,以及文件数量
        max-size: "200k"
        max-file: "10"
    # 网络(要引入顶级配置的network)
    networks:
     - some-network
     - other-network
    # 暴露端口,以HOST:CONTAINER格式映射端口
    ports:
      - "3000"
      - "3000-3005"
      - "8000:8000"
      - "9090-9091:8080-8081"
      - "49100:22"
      - "127.0.0.1:8001:8001"
    # 重启("no",always,on-failure,unless-stopped)
    restart: "no"
    # 设置内核参数
    sysctls:
      - net.core.somaxconn=1024
      - net.ipv4.tcp_syncookies=0
    # 将容器目录映射到主机目录(格式 HOST:CONTAINER)
    volumes:
      - "/var/run/postgres/postgres.sock:/var/run/postgres/postgres.sock"
      - "dbdata:/var/lib/postgresql/data"

  redis:
    image: redis
  db:
    image: postgres

# 配置网络
networks:
  some-network:
  other-network:
    external:
      name: actual-name-of-network

后记:若是去理解这几个东西,很好理解,但是如何灵活运用,就需要积累了

02-01 10:50