Docker-Compose


一、Docker Compose

1、前言

我们知道使??个 Dockerfile 模板?件,可以让?户很?便的定义?个单独的应?容器。然?,在?常?作中,经常会碰到需要多个容器相互配合来完成某项任务的情况。
例如要实现?个 Web 项?,除了 Web 服务容器本身,往往还需要再加上后端的数据库服务容器,甚?还包括负载均衡容器等,我们只能一个一个`写dockerfile文件,然后bulid构建,run手动操作单个容器`

Compose 恰好满?了这样的需求。它允许?户通过?个单独的 docker-compose.yml 模板?件(YAML 格式)
来定义?组相关联的应?容器为?个项?(project).
 微服务。 100个微服务!依赖关系。
# Compose 项?是 Docker 官?的开源项?,负责实现对 Docker 容器集群的快速编排。

2、官方介绍

Docker Compose来轻松高效的管理容器,定义运行多个容器。

3、Compose 中有两个重要的概念

# 1、服务 ( service ):
?个应?的容器,实际上可以包括若?运?相同镜像的容器实例(web、redis、mysql ...)。
# 2、项? ( project ):
由?组关联的应?容器组成的?个完整业务单元,在 docker-compose.yml ?件中定义(博客、web、mysql)。
# 启动docker-compose up 可以启动多个服务

4、三步骤

1、Dockerfile 保证我们的项目可以在任何地方运行。

2、定义组成您的应用程序的服务,docker-compose.yml 以便它们可以在隔离的环境中一起运行。
# services 什么是服务
# docker-compose.ym 这个文件如何写

3、运行docker compose up和码头工人组成命令启动并运行你的整个应用程序。

   也可以docker-compose up使用 docker-compose 二进制文件运行。 # 启动项目

5、Compose是Docker官方的开源项目,需要安装!

dockerfile # 让程序在任何地方运行。 web服务、redis、mysql、nginx ... d  多个服务 启动

6、Compose:重要的概念

1、YAML file配置文件。
2、single command。 命令有哪里
3、Compose 适用于所有环境:生产、登台、开发、测试以及 CI 工作流。
4、Compose 的默认管理对象是项?,通过?命令对项?中的?组容器进?便捷地?命周期管理。
5、Compose 项?由 Python 编写,实现上调?了 Docker 服务提供的 API 来对容器进?管理。因此,只要所操作的平
台?持 Docker API,就可以在其上利? Compose 来进?编排管理。

# Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。

二、docker compose 安装

# 官网安装: https://docs.docker.com/compose/install/

在这里插入图片描述

1、下载

方式一:
# 1、官网安装
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
方式二:
# 2、国内
curl -L "https://get.daocloud.io/docker/compose/releases/download/1.25.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

[root@docter bin]# ll
total 12440
-rw-r--r-- 1 root root 12737304 Jul 14 20:19 docker-compose

2、bash命令补全

curl -L https://raw.githubusercontent.com/docker/compose/1.29.2/contrib/completion/bash/docker-compose > /etc/bash_completion.d/docker-compose

3、卸载(没有安装不需要执行)

如果是?进制包?式安装的,删除?进制?件即可。

 sudo rm /usr/local/bin/docker-compose

4、授权

[root@docter bin]# sudo chmod +x /usr/local/bin/docker-compose

5、检测版本

[root@docter bin]# docker-compose version
docker-compose version 1.29.2, build 5becea4c
docker-py version: 5.0.0
CPython version: 3.7.10
OpenSSL version: OpenSSL 1.1.0l  10 Sep 2019

三、docker compose使?

1、相关概念

# 1、服务 ( service ):
?个应?容器,实际上可以运?多个相同镜像的实例。

# 2、项? ( project ):
由?组关联的应?容器组成的?个完整业务单元。??个项?可以由多个服务(容器)关联?成, Compose ?向项?进?管理。

2、场景

最常?的项?是 web ?站,该项?应该包含 web 应?和缓存。
1、Django应?
2、mysql服务
3、redis服务
4、elasticsearch服务
.......

3.docker-compose模板

# 1、编写docker-cmpsoe文件
[root@docter docker-compose]#vim docker-compose.yaml 
version: "3.0"
services:
   mysqldb:
     image: mysql:5.7.19
     container_name: mysql
     ports:
       - "3306:3306"
     volumes:
        - /root/mysql/conf:/etc/mysql/conf.d
        - /root/mysql/logs:/logs
        - /root/mysql/data:/var/lib/mysql
     environment:
       MYSQL_ROOT_PASSWORD: root
     networks:
       - ems
     depends_on:
       - redis
   redis:
      image: redis:4.0.14
      container_name: redis
      ports:
        - "6379:6379"
      networks:
        - ems
      volumes:
        - /root/redis/data:/data
      command: redis-server
    
networks:
  ems:
# 2、启动docker-compose
[root@docter docker-compose]# docker-compose up -d
Creating network "docker-compose_ems" with the default driver
Creating redis ... done
Creating mysql ... done
# 3、查看容器
方式一:
[root@docter docker-compose]# docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS          PORTS                                       NAMES
15d11b1c45de   mysql:5.7.19   "docker-entrypoint.s…"   24 seconds ago   Up 24 seconds   0.0.0.0:3306->3306/tcp, :::3306->3306/tcp   mysql
5bf22e44ff81   redis:4.0.14   "docker-entrypoint.s…"   24 seconds ago   Up 24 seconds   0.0.0.0:6379->6379/tcp, :::6379->6379/tcp   redis
方式二:# (推荐)docker-compose.yaml 必须在当前目录
[root@docter docker-compose]# docker-compose ps
Name               Command               State                    Ports                  
-----------------------------------------------------------------------------------------
mysql   docker-entrypoint.sh mysqld      Up      0.0.0.0:3306->3306/tcp,:::3306->3306/tcp
redis   docker-entrypoint.sh redis ...   Up      0.0.0.0:6379->6379/tcp,:::6379->6379/tcp

4、启动

[root@docter ~]# docker-compose up //前台启动?组服务
[root@docter ~]# docker-compose up -d //守护进程启动?组服务

5、docker-compose 模板?件

1、模板?件是使? Compose 的核?

2、默认的模板?件名称为 docker-compose.yml ,格式为 YAML 格式。

#docker-compose的模板
version:     #指定docker-compose模板的版本号
services:    #配置一个服务(配置一组容器)
network:     #定义网桥

#services
build: ./dir  #(dockerfile的路径)直接构建容器并使用
ports:	      #端口映射  ports: "宿主主机端口:容器端口"
 - "80:80"
command:       #指定一个容器的启动命令 command : 'cmd'
container_name:   #作用:设置容器的名称
depends_on:       #指定在那些镜像之后启动
images:         #指定镜像
env_file:       #指定一个文件(文件中的内容会做成容器内部的环境变量)
environment:	#直接指定环境变量
volumes:	#挂载存储卷
healthcheck: # 设置健康检查的方式 
		    test: ["CMD", "curl", "-f", "http://localhost"]
			# 容器启动前15s不探测
			interval: 15s
			# 探测的超时时间
			timeout: 10s
			# 错误连续出现3次,则认定该容器不健康
			retries: 3
ulimits:
      nproc: 65535
      nofile:
        soft: 20000
        hard: 40000
    sysctls:
      net.ipv4.ip_forward: 1
      

#案例:
[root@docker docker-compose]# cat docker-compose.yaml 
version: "3"
services: 
  portainer:
    ports:
      - "8000:8000"
      - "9443:9443"
    container_name: portainer
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
      - "/opt/portainer_data:/data"
    image: portainer/portainer-ce:latest

1)build

?动构建这个镜像

格式:
    build: ./dir

# 1、准备文件
[root@docter jave]# ll
total 4
-rw-r--r-- 1 root root  62 Jul 30 20:35 docker-compose.yaml
drwxr-xr-x 5 root root 122 Jul 30 19:15 springboot-master
# 2、编写docker-compose.yaml文件
[root@docter jave]# vim docker-compose.yaml 
version: '3'
services:
  jave:
    build: ./springboot-master
    ports:
      - "8080:8080"
# 3、启动docker-compose
[root@docter jave]# docker-compose up -d
Creating network "jave_default" with the default driver
Creating jave_jave_1 ... done

# 4、查看docker-compose是否启动
方式一: 推荐 #docker-compose必须在当前目录,否则启动不了
[root@docter jave]# docker-compose ps
   Name                  Command               State                    Ports                  
-----------------------------------------------------------------------------------------------
jave_jave_1   /bin/sh -c java -jar GitLa ...   Up      0.0.0.0:8080->8080/tcp,:::8080->8080/tcp
方式二:
CONTAINER ID   IMAGE       COMMAND                  CREATED         STATUS         PORTS                                       NAMES
fa6682dbba66   jave_jave   "/bin/sh -c 'java -j…"   2 minutes ago   Up 2 minutes   0.0.0.0:8080->8080/tcp, :::8080->8080/tcp   jave_jave_1

在这里插入图片描述

2)command

覆盖容器启动后默认执?的命令

格式:
command: echo "hello world" 

# 1、编写docker-compose.yaml文件
[root@docter jave]# cat docker-compose.yaml 
version: '3'
services:
  jave:
    build: ./springboot-master
    command: echo "hello world" 
    ports:
      - "8080:8080"
# 2、启动docker-compose
[root@docter jave]# docker-compose up -d
Recreating jave_jave_1 ... done
# 3、查看容器 
[root@docter jave]# docker-compose ps
   Name           Command        State    Ports
-----------------------------------------------
jave_jave_1   echo hello world   Exit 0      #显示 hello world

3)container_name

指定容器名称,默认将会使? 项?名称_服务名称_序号 这样的格式

格式:
container_name: docker-web-jave 

# 1、编写docker-compose.yaml文件
[root@docter jave]# vim docker-compose.yaml 
version: '3'
services:
  jave:
    build: ./springboot-master
    container_name: docker-web-jave
# 2、启动docker-compose
[root@docter jave]# docker-compose up -d
Creating network "jave_default" with the default driver
Creating docker-web-jave ... done
# 3、查看docker-compose
[root@docter jave]# docker-compose ps
     Name                    Command               State    Ports  
-------------------------------------------------------------------
docker-web-jave   /bin/sh -c java -jar GitLa ...   Up      8080/tcp   # 显示名称docker-web-jave 

# 注意: 指定容器名称后,该服务将?法进?扩展(scale),因为 Docker 不允许多个容器具有相同的名称。

4)depends_on

解决容器的依赖、启动先后的问题

格式:
    depends_on:
      - php
      - nginx
  php:
    image: php
  nginx:
    image: nginx
# 1、准备文件
[root@docter lnmp]# ll
total 4
-rw-r--r-- 1 root root 138 Jul 30 21:08 docker-compose.yaml
drwxr-xr-x 2 root root  80 Jul 30 20:04 nginx
drwxr-xr-x 2 root root  93 Jul 29 21:42 php
# 2、编写docker-compose.yaml文件
[root@docter lnmp]# vim docker-compose.yaml 
version: "3"
services:
  web:
    build: ./
    depends_on:
      - php
      - nginx
  php:
    image: php
  nginx:
    image: nginx
# 3、启动 docker-compose 
[root@docter lnmp]# docker-compose up -d
Creating lnmp_php_1   ... done  # 先启动php
Creating lnmp_nginx_1 ... done  # 在启动nginx
#  注意:
默认情况下使用 docker-compose up web 这样的方式启动 web 服务时,也会启动 php和nginx 两个服务,因为在配置文件中定义了依赖关系。

5)env_file

1、从?件中获取环境变量,可以为单独的?件路径或列表。

2、如果通过 docker-compose -f FILE ?式来指定 Compose 模板?件,则 env_file 中变量的路径会基于模板?件路径。

3、如果有变量名称与 environment 指令冲突,则按照惯例,以后者为准。

格式:
env_file: .env
env_file:
 - ./common.env
 - ./apps/web.env
 
 # 1、编写docker-compose.yaml文件
 [root@docter jave]# vim docker-compose.yaml 
version: '3'
services:
  jave:
    build: ./springboot-master
    ports:
      - "8080:8080"
  mysqldb:
    image: mysql:5.7
    env_file:
      - ./mysql.env
# 2、编写 mysql.env 文件
[root@docter jave]# vim mysql.env 
MYSQL_ROOT_PASSWORD=123
# 3、启动 docker-compose
[root@docter jave]# docker-compose up -d
Creating network "jave_default" with the default driver
Creating jave_mysqldb_1 ... done
Creating jave_jave_1    ... done
# 4、查看容器
[root@docter jave]# docker-compose ps
     Name                   Command               State                    Ports                  
--------------------------------------------------------------------------------------------------
jave_jave_1      /bin/sh -c java -jar GitLa ...   Up      0.0.0.0:8080->8080/tcp,:::8080->8080/tcp
jave_mysqldb_1   docker-entrypoint.sh mysqld      Up      3306/tcp, 33060/tcp      # 环境变量生效

6)environment

1、设置环境变量。你可以使?数组或字典两种格式。

2、只给定名称的变量会?动获取运? Compose 主机上对应变量的值,可以?来防?泄露不必要的数据。

格式:
mysqldb:
environment :mysql:5.7
  MSYQL_ROOT_PASSWORD: 123
  
# 1、编写docker-compose.yaml文件
[root@docter jave]# vim docker-compose.yaml 
version: '3'
services:
  jave:
    build: ./springboot-master
    ports:
      - "8080:8080"
  mysqldb:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: 123
# 2、启动 docker-compose
[root@docter jave]# docker-compose up -d
Creating jave_jave_1    ... done
Creating jave_mysqldb_1 ... done
# 3、查看docker-compose
[root@docter jave]# docker-compose ps
     Name                   Command               State                    Ports                  
--------------------------------------------------------------------------------------------------
jave_jave_1      /bin/sh -c java -jar GitLa ...   Up      0.0.0.0:8080->8080/tcp,:::8080->8080/tcp
jave_mysqldb_1   docker-entrypoint.sh mysqld      Up      3306/tcp, 33060/tcp     #环境变量生效

7)healthcheck

通过命令检查容器是否健康运?(健康检查)

healthcheck:
 test: ["CMD", "curl", "-f", "http://localhost"]
 interval: 1m30s
 timeout: 10s
 retries: 3
# 1、编写docker-compose.yaml文件
[root@docter jave]# vim docker-compose.yaml 
version: '3'
services:
  jave:
    build: ./springboot-master
    ports:
      - "8080:8080"
    depends_on:
      - nginx
  nginx:
    image: nginx
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost"]
      interval: 15s
      timeout: 10s
      retries: 3

# 2、启动 docker-compose
[root@docter jave]# docker-compose up -d
WARNING: Found orphan containers (jave_mysqldb_1) for this project. If you removed or renamed this service in your compose file, you can run this command with the --remove-orphans flag to clean it up.
Creating jave_nginx_1 ... done
Creating jave_jave_1  ... done
# 3、查看docker-compose容器
[root@docter jave]# docker-compose ps
    Name                  Command                       State                            Ports       
----------------------------------------------------------------------------------------------------------------
jave_jave_1    /bin/sh -c java -jar GitLa ...   Up                      0.0.0.0:8080->8080/tcp,:::8080->8080/tcp
jave_nginx_1   /docker-entrypoint.sh ngin ...   Up (health: starting)   80/tcp   #探测中

在这里插入图片描述

8)image

指定为镜像名称或镜像 ID。如果镜像在本地不存在, Compose 将会尝试拉取这个镜像。

image: ubuntu
image: orchardup/postgresql
image: a4bc65fd

9)networks

配置容器连接的?络。

version: "3"
services:
   some-service:
   networks:
     - some-network
     - other-network
networks:
  some-network:
  other-network:

在这里插入图片描述

10)ports

1、暴露端?信息。

2、使?宿主端?:容器端? (HOST:CONTAINER) 格式,或者仅仅指定容器的端?(宿主将会随机选择端?)都可以。

ports:
   - "3000"
   - "8000:8000"
   - "49100:22"
   - "127.0.0.1:8001:8001"
 # 1、编写docker-compose.yaml文件
[root@docter jave]# vim docker-compose.yaml 
version: '3'
services:
  jave:
    build: ./springboot-master
    ports:
      - "8080:8080"
# 2、启动 docker-compose
[root@docter jave]# docker-compose up -d
WARNING: Found orphan containers (jave_mysqldb_1) for this project. If you removed or renamed this service in your compose file, you can run this command with the --remove-orphans flag to clean it up.
Creating jave_nginx_1 ... done
Creating jave_jave_1  ... done
# 3、查看docker-compose容器
[root@docter jave]# docker-compose ps
    Name                  Command                       State                            Ports       
----------------------------------------------------------------------------------------------------------------
jave_jave_1    /bin/sh -c java -jar GitLa ...   Up                      0.0.0.0:8080->8080/tcp,:::8080->8080/tcp   # 端口8080

# 注意:当使? HOST:CONTAINER 格式来映射端?时,如果你使?的容器端??于 60 并且没放到引号?,可能会得
到错误结果,因为 YAML 会?动解析 xx:yy 这种数字格式为 60 进制。为避免出现这种问题,建议数字串都采?
引号包括起来的字符串格式。

11)sysctls

配置容器内核参数

sysctls:
 net.core.somaxconn: 1024
 net.ipv4.tcp_syncookies: 0
sysctls:
 - net.core.somaxconn=1024
 - net.ipv4.tcp_syncookies=0

12)ulimits

指定容器的 ulimits 限制值

 ulimits:
 nproc: 65535
 nofile:
 soft: 20000
 hard: 40000
 
# 例如,指定最?进程数为 65535,指定?件句柄数为 20000(软限制,应?可以随时修改,不能超过硬限制) 和
40000(系统硬限制,只能 root ?户提?)。

13)volumes

数据卷所挂载路径设置,该指令中路径?持相对路径。

volumes:
  - /var/lib/mysql
  - cache/:/tmp/cache
 
# 数据卷所挂载路径设置。可以设置为宿主机路径( HOST:CONTAINER )或者数据卷名称( VOLUME:CONTAINER ),并且 可以设置访问模式 ( HOST:CONTAINER:ro )。 

如果路径为数据卷名称,必须在?件中配置数据卷

version: "3"
services:
   my_src:
     image: mysql:8.0
     volumes:
     - mysql_data:/var/lib/mysql
volumes:
   mysql_data:

四、docker-compose 常?命令

1. 命令对象与格式

 # 万能命令
[root@docter jave]# docker-compose --help
  -f, --file FILE             Specify an alternate compose file
                              (default: docker-compose.yml)
  -p, --project-name NAME     Specify an alternate project name
                              (default: directory name)
  --profile NAME              Specify a profile to enable

2. 命令选项

1、 -f, --file FILE 指定使?的Compose模板?件,默认为 docker-compose.yml ,可以多次指定。
案例:
[root@docter ~]# docker-compose -f /root/jave/docker-compose.yaml  up -d
WARNING: Found orphan containers (jave_mysqldb_1) for this project. If you removed or renamed this service in your compose file, you can run this command with the --remove-orphans flag to clean it up.
Creating jave_nginx_1 ... done
Creating jave_jave_1  ... done
2、-p, --project-name NAME 指定项?名称,默认将使?所在?录名称作为项?名。

3、--x-networking 使? Docker 的可拔插?络后端特性

4、--x-network-driver DRIVER 指定?络后端的驱动,默认为 bridge

5、--verbose 输出更多调试信息。

6、-v, --version 打印版本并退出。
案例:
[root@docter lnmp]# docker-compose -v
docker-compose version 1.29.2, build 5becea4c

3.命令使?说明

# 1、up
格式为 docker-compose up [options] [SERVICE...] 。
   # 1、该命令?分强?,它将尝试?动完成包括构建镜像,(重新)创建服务,启动服务,并关联服务相关容器的?系列操作。
   # 2、链接的服务都将会被?动启动,除?已经处于运?状态。
   # 3、可以说,?部分时候都可以直接通过该命令来启动?个项?。
   # 4、默认情况, docker-compose up 启动的容器都在前台,控制台将会同时打印所有容器的输出信息,可以很
   # 5、?便进?调试。
   # 5、当通过 Ctrl-C 停?命令时,所有容器将会停?。
   # 6、如果使? docker-compose up -d ,将会在守护进程启动并运?所有的容器。?般推荐?产环境下使?该选项。
   # 7、默认情况,如果服务容器已经存在, docker-compose up 将会尝试停?容器,然后重新创建(保持使? volumes-from 挂载的卷),以保证新启动的服务匹配 docker-compose.yml ?件的最新内容
案例:
[root@docter ~]# docker-compose up    # 前台启动?组服务
[root@docter ~]# docker-compose up -d # 守护进程启动?组服务
# 2、down
  此命令将会停? up 命令所启动的容器,并移除?络
案例:
[root@docter ~]# docker-compose down

# 3、exec
  进?指定的容器。
案例:
1、查看容器
[root@docter jave]# docker ps
CONTAINER ID   IMAGE       COMMAND                  CREATED              STATUS              PORTS                                       NAMES
18ab957b2022   jave_jave   "/bin/sh -c 'java -j…"   About a minute ago   Up About a minute   0.0.0.0:8080->8080/tcp, :::8080->8080/tcp   jave_jave_1
2、进入容器
[root@docter jave]# docker-compose exec 18ab957b2022 bash
bash-4.4# 
 
# 4、ps
格式为 docker-compose ps [options] [SERVICE...] 。
列出项?中?前的所有容器。
案例:
[root@docter jave]# docker ps
CONTAINER ID   IMAGE       COMMAND                  CREATED              STATUS              PORTS                                       NAMES
18ab957b2022   jave_jave   "/bin/sh -c 'java -j…"   About a minute ago   Up About a minute   0.0.0.0:8080->8080/tcp, :::8080->8080/tcp   jave_jave_1
 选项:
   -q 只打印容器的 ID 信息。
[root@docter jave]# docker-compose  ps -q
18ab957b2022b06d4f8efca3680c8178bc3a3a5eef25f89f4dd9d08eedc35092

# 5、restart
格式为 docker-compose restart [options] [SERVICE...] 。
重启项?中的服务。
选项:
   -t, --timeout TIMEOUT 指定重启前停?容器的超时(默认为 10 秒)。
案例:
[root@docter jave]# docker-compose restart jave
Restarting jave_jave_1 ... done
# 6、rm
格式为 docker-compose rm [options] [SERVICE...] 。
删除所有(停?状态的)服务容器。推荐先执? docker-compose stop 命令来停?容器。
选项:
   -f, --force 强制直接删除,包括?停?状态的容器。?般尽量不要使?该选项。
   -v 删除容器所挂载的数据卷。
案例:
[root@docter jave]# docker-compose rm jave
Stopping jave_jave_1 ... done

# 7、start
格式为 docker-compose start [SERVICE...] 。
启动已经存在的服务容器。
案例:
[root@docter jave]# docker-compose start jave
Stopping jave_jave_1 ... done
# 8、stop
格式为 docker-compose stop [options] [SERVICE...] 。
停?已经处于运?状态的容器,但不删除它。通过 docker-compose start 可以再次启动这些容器。
选项:
   -t, --timeout TIMEOUT 停?容器时候的超时(默认为 10 秒)。
 案例:
[root@docter jave]# docker-compose stop jave
Stopping jave_jave_1 ... done

9、top
查看各个服务容器内运?的进程。
案例:
[root@docter jave]# docker-compose top jave
jave_jave_1
UID     PID    PPID    C    STIME   TTY     TIME                     CMD                
----------------------------------------------------------------------------------------
root   14332   14312   78   23:32   ?     00:00:12   java -jar GitLab-0.0.1-SNAPSHOT.war

10、unpause
格式为 docker-compose unpause [SERVICE...] 。
恢复处于暂停状态中的服务
案例:
[root@docter jave]# docker-compose pause jave
Pausing jave_jave_1 ... done
[root@docter jave]# docker-compose ps
   Name                  Command               State                     Ports                  
------------------------------------------------------------------------------------------------
jave_jave_1   /bin/sh -c java -jar GitLa ...   Paused   0.0.0.0:8080->8080/tcp,:::8080->8080/tcp
[root@docter jave]# docker-compose unpause jave
Unpausing jave_jave_1 ... done
[root@docter jave]# docker-compose ps
   Name                  Command               State                    Ports                  
-----------------------------------------------------------------------------------------------
jave_jave_1   /bin/sh -c java -jar GitLa ...   Up      0.0.0.0:8080->8080/tcp,:::8080->8080/tcp

在这里插入图片描述

4、扩展

# 1、查看镜像:images
[root@docter jave]# docker-compose images
 Container    Repository    Tag       Image Id       Size  
-----------------------------------------------------------
jave_jave_1   jave_jave    latest   5fb828d6276e   488.4 MB
# 2、端口: prot
[root@docter jave]# docker-compose prot -- ngixn 80
# 3、查看事件:envents
[root@docter jave]# docker-compose events -- nginx

在这里插入图片描述

# 4、设置副本数:scale
[root@docter jave]# docker-compose  ps
    Name                  Command                  State                        Ports                  
-------------------------------------------------------------------------------------------------------
jave_jave_1    /bin/sh -c java -jar GitLa ...   Up             0.0.0.0:8080->8080/tcp,:::8080->8080/tcp
jave_nginx_1   /docker-entrypoint.sh ngin ...   Up (healthy)   80/tcp                                  
[root@docter jave]# docker-compose scale nginx=5
WARNING: The scale command is deprecated. Use the up command with the --scale flag instead.
Creating jave_nginx_2 ... done
Creating jave_nginx_3 ... done
Creating jave_nginx_4 ... done
Creating jave_nginx_5 ... done
[root@docter jave]# docker-compose  ps
    Name                  Command                       State                            Ports                  
----------------------------------------------------------------------------------------------------------------
jave_jave_1    /bin/sh -c java -jar GitLa ...   Up                      0.0.0.0:8080->8080/tcp,:::8080->8080/tcp
jave_nginx_1   /docker-entrypoint.sh ngin ...   Up (healthy)            80/tcp                                  
jave_nginx_2   /docker-entrypoint.sh ngin ...   Up (health: starting)   80/tcp                                  
jave_nginx_3   /docker-entrypoint.sh ngin ...   Up (health: starting)   80/tcp                                  
jave_nginx_4   /docker-entrypoint.sh ngin ...   Up (health: starting)   80/tcp                                  
jave_nginx_5   /docker-entrypoint.sh ngin ...   Up (health: starting)   80/tcp  

在这里插入图片描述

五、docker可视化?具

# 官网: https://www.portainer.io/installation/

Portainer图形化工具构建

 # 1、编写docker-compose.yaml文件
[root@docter portainer]# vim docker-compose.yaml 
version: '3'
services:
  portainer:
    image: portainer/portainer-ce
    container_name: portainer
    ports:
      - "8000:8000"
      - "9000:9000"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
      - "portainer_data:/data"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9000"]
      interval: 15s
      timeout: 10s
      retries: 3
volumes:
  portainer_data:
# 2、启动 docker-compose
[root@docter portainer]# docker-compose up -d
Creating network "portainer_default" with the default driver
Creating volume "portainer_portainer_data" with default driver
Pulling portainer (portainer/portainer-ce:)...
latest: Pulling from portainer/portainer-ce
651a8e6e1630: Pull complete
56e38df73332: Pull complete
635ae9c57e4c: Pull complete
Digest: sha256:3e499846ae1830e9465de7f110cbf19f4dff076e80abc0f7a1d4b50e67c6b873
Status: Downloaded newer image for portainer/portainer-ce:latest
Creating portainer ... done
# 3、查看 docker-compose容器
[root@docter portainer]# docker-compose ps
  Name       Command             State                                                 Ports                                       
-----------------------------------------------------------------------------------------------------------------------------------
portainer   /portainer   Up (health: starting)   0.0.0.0:8000->8000/tcp,:::8000->8000/tcp, 0.0.0.0:9000->9000/tcp,:::9000->9000/tcp
# 4、IP访问
192.168.15.30:9000

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

六、docker compose实战

# 官网  https://docs.docker.com/compose/gettingstarted/

在这里插入图片描述

1、实战docker compose构建redis

1、应用app.py

2、Dockerfile 应用镜像

3、Docker-compose.yml文件(定义整个服务,需要的环境,web、redis)完整的上线服务

4、启动compose项目( docker-compose up )

# 1、创建网络
# 2、执行Docker-compose.yml文件
# 3、在 Compose 文件中定义服务
# 4、启动docekr-compose

2、准备工作

yum -y install python-pip  # pip是python包管理工具
yum -y install epel-relase # 报错的话执行
# 如果官网安装不需要执行这一步

3、创建项目目录

 [root@docter home]# mkdir composetest
 [root@docter home]# cd composetest/

4、在项目目录中创建名为app.py文件

[root@docter composetest]# pwd
/home/composetest 
[root@docter composetest]# vim app.py 
import time

import redis
from flask import Flask

app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)

def get_hit_count():
    retries = 5
    while True:
        try:
            return cache.incr('hits')
        except redis.exceptions.ConnectionError as exc:
            if retries == 0:
                raise exc
            retries -= 1
            time.sleep(0.5)

@app.route('/')
def hello():
    count = get_hit_count()
    return 'Hello World! I have been seen {} times.\n'.format(count)

# 在此示例中,redis是应用程序网络上的 redis 容器的主机名。我们使用 Redis 的默认端口6379。

5、 requirements.txt依赖

[root@docter composetest]# vim requirements.txt 
flask
redis

6、创建一个 Dockerfile

[root@docter composetest]# vim Dockerfile 
# syntax=docker/dockerfile:1
FROM python:3.7-alpine
WORKDIR /code
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
EXPOSE 5000
COPY . .
CMD ["flask", "run"]
# CMD ["python", "run"]  #这样也可以
#  这告诉 Docker:
    从 Python 3.7 映像开始构建映像。
    将工作目录设置为/code.
    设置flask命令使用的环境变量。
    安装 gcc 和其他依赖项
    复制requirements.txt并安装 Python 依赖项。
    将元数据添加到图像中以描述容器正在侦听端口 5000
    将.项目中的当前目录复制到.镜像中的workdir 。
    将容器的默认命令设置为flask run.

7、在 Compose 文件中定义服务

[root@docter composetest]# vim docker-compose.yml 
version: "3.9"
services:
  web:
    build: .
    ports:
      - "5000:5000"
  redis:
    image: "redis:alpine"
# 这个 Compose 文件定义了两个服务:web和redis.

8、使用 Compose 构建并运行您的应用程序

 # 1、前台启动
[root@docter composetest]# docker-compose up
 ...
redis_1  | 1:M 14 Jul 2021 12:38:57.668  Ready to accept connections
web_1    |   Serving Flask app 'app.py' (lazy loading)
# 2、守护进程启动
[root@docter composetest]# docker-compose up -d
Creating composetest_web_1   ... done
Creating composetest_redis_1 ... done
# 3、查看docker-compose运行的容器的状态
[root@docker1 composetest]# docker-compose ps
       Name                      Command               State                    Ports                  
-------------------------------------------------------------------------------------------------------
composetest_redis_1   docker-entrypoint.sh redis ...   Up      6379/tcp                                
composetest_web_1     flask run                        Up      0.0.0.0:5000->5000/tcp,:::5000->5000/tcp
# 4、访问测试
[root@docter composetest]# curl localhost:5000   # docker-compose 构建成功
Hello World! I have been seen 1 times.
[root@docker1 composetest]# curl localhost:5000
Hello World! I have been seen 4 times.

在这里插入图片描述
在这里插入图片描述

9、报错排查

The command '/bin/sh -c apk add --no-cache gcc musl-dev linux-headers' returned a non-zero code: 3
ERROR: Service 'web' failed to build : Build failed

# Docker 容器似乎没有互联网连接,您必须IPv4 forwarding使用以下命令启用

[root@docter composetest]# echo 1 > /proc/sys/net/ipv4/ip_forward
[root@docter composetest]# sysctl -w net.ipv4.ip_forward=1
net.ipv4.ip_forward = 1
[root@docter composetest]# sysctl -p /etc/sysctl.conf
[root@docter composetest]# docker-compose stop
[root@docter composetest]# docker-compose up       #前台启动
[root@docter my_wordpress]# docker-compose up -d   #守护进程启动

在这里插入图片描述

10、补充

# 1、网络服务
该web服务使用从Dockerfile当前目录中构建的映像。然后它将容器和主机绑定到暴露的端口5000. 此示例服务使用 Flask Web 服务器的默认端口5000.

# 2、Redis服务
该redis服务使用 从 Docker Hub 注册表中提取的公共Redis映像。

七、docker-compose 细部讲解

1、查看镜像

[root@docter composetest]# docker images
REPOSITORY        TAG          IMAGE ID       CREATED          SIZE
composetest_web   latest       8cada718e4aa   35 minutes ago   184MB
redis             alpine       500703a12fa4   7 days ago       32.3MB
python            3.7-alpine   93ac4b41defe   2 weeks ago      41.9MB

# docker-compose构建redis镜像自动加载成功

2、查看网络

[root@docter composetest]# docker network ls
NETWORK ID     NAME                  DRIVER    SCOPE
6a94c74d036c   bridge                bridge    local
249dde48a683   composetest_default   bridge    local # 自动添加的
b0ff56aa1b35   host                  host      local
e274cbbee51f   none                  null      local

3、查看网络细部信息

[root@docter composetest]# docker network  inspect  composetest_default 
[
    {
        "Name": "composetest_default",
        "Id": "249dde48a68302b57f0ce8a8640493f36ccd6ee105b1e385100b389d90b20333",
        "Created": "2021-07-14T20:34:09.710827032+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.18.0.0/16",
                    "Gateway": "172.18.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": true,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "d9b49cecffbab8645b1b25daa6bbcd69a35f1307941040f7bfb733d71ee381ce": {
                "Name": "composetest_web_1",    # composetest_redis_1和web同一个网络
                "EndpointID": "89b0c1ccc312d494cf37d96adfaccfc648f3840ab78152b3e3f79e79145a309e",
                "MacAddress": "02:42:ac:12:00:02",
                "IPv4Address": "172.18.0.2/16",
                "IPv6Address": ""
            },
            "ffedc98d9959ed4ec92b0ae9fb23ae6f40ef31513c872138ea1e27a109422182": {
                "Name": "composetest_redis_1",   # composetest_redis_1和web同一个网络
                "EndpointID": "4f45b1b989fdcdadfcf4cc3922eace4c252539ed714e62a026cec91d5230325a",
                "MacAddress": "02:42:ac:12:00:03",
                "IPv4Address": "172.18.0.3/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {
            "com.docker.compose.network": "default",
            "com.docker.compose.project": "composetest",
            "com.docker.compose.version": "1.29.2"
        }
    }
]

# 1、10个服务 ==》项目(项目中的内容都在同一个网络下 域名访问)
# 2、如果在同一个网络下,我们直接通过域名访问

在这里插入图片描述
在这里插入图片描述

4、停止docker-compose

# 1、docker-compose down  #推荐第一种

^CGracefully stopping... (press Ctrl+C again to force)
Stopping composetest_web_1   ... 
Stopping composetest_redis_1 ... done
Killing composetest_web_1    ... done

# 2、ctrl +c

5、docekr小结

1、docker镜像 run ==》容器
2、dockerfile构建镜像 (服务打包)
3、docker-compose启动项目(编排、多个微服务、环境)
4、docker网络

6、yaml规则

docker-compose-yaml  # 是docker-compose核心
[root@docter composetest]# vim docker-compose.yml 
version: "3.9"   # 版本层
services:   #服务层
  web:
    build: . #服务配置
    ports:
      - "5000:5000"
  redis:
    image: "redis:alpine"  # 其他配置(网络、卷、全局规则)

7、扩展

1、默认的服务名 文件名_服务名_num
2、多个服务器,集群 A B _num 副本数量
3、服务redis服务  ==》 4个副本
4、集群状态,服务不可能只有一个运行实例  ==》 弹性 10 HA 高并发

八、docker-compose 搭建个人博客

1、下载项目(docker-compose.yml )

2、如果需要文件 Dockerfile

3、文件准备齐全(直接一键启动)

1、创建目录

# 官网 https://docs.docker.com/samples/wordpress/

[root@docter home]# mkdir my_wordpress
[root@docter home]# cd my_wordpress/
[root@docter home]# ll
drwxr-xr-x 2 root root 32 Jul 14 21:43 my_wordpress

2、编写 docker-compose.yml

[root@docter my_wordpress]# vim docker-compose.yml 
version: "3.9"
    
services:
  db:
    image: mysql:5.7
    volumes:
      - db_data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: somewordpress
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress
    
  wordpress:
    depends_on:
      - db
    image: wordpress:latest
    volumes:
      - wordpress_data:/var/www/html
    ports:
      - "8000:80"
    restart: always
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WORDPRESS_DB_NAME: wordpress
volumes:
  db_data: {}
  wordpress_data: {}

3、启动

[root@docter my_wordpress]# pwd
/home/my_wordpress
[root@docter my_wordpress]# ll
total 4
-rw-r--r-- 1 root root 646 Jul 14 21:43 docker-compose.yml

[root@docter my_wordpress]# docker-compose up  #前台启动
Creating network "my_wordpress_default" with the default driver
Creating my_wordpress_db_1 ... done
Creating my_wordpress_wordpress_1 ... done   
[root@docter my_wordpress]# docker-compose up -d   #守护进程启动
Starting my_wordpress_db_1 ... done
Starting my_wordpress_wordpress_1 ... done
# 注: 必须在指定文件docker-compose.yml下启动才可以,否则启动起来是其他容器

4、测试访问

[root@docter my_wordpress]# docker ps
CONTAINER ID   IMAGE              COMMAND                  CREATED         STATUS         PORTS                                   NAMES
2e9b9aca589a   wordpress:latest   "docker-entrypoint.s…"   2 minutes ago   Up 2 minutes   0.0.0.0:8000->80/tcp, :::8000->80/tcp   my_wordpress_wordpress_1
e2713ba9243a   mysql:5.7          "docker-entrypoint.s…"   2 minutes ago   Up 2 minutes   3306/tcp, 33060/tcp                     my_wordpress_db_1

# 测试访问:  http://192.168.15.30:8000

在这里插入图片描述

1、未来项目只要有docker-compose文件,安装这个规则,启动编排容器
2、公司 docekr-compose 直接启动
3、网上开源项目 docker-compose 一键搞定

# 工程 服务  容器
项目compose:三层
# 1、工程 Porject
# 2、服务 服务
# 3、容器 运行实例


# 补充:
docker secret  # 安全配置密码,证书

九、一键脚本部署

[root@docker1 ~]# vim install-blog.sh 
#!/usr/bin/env bash
# install zblog

if [ -f /etc/init.d/functions ]; then
  . /etc/init.d/functions
else
  echo "not found file /etc/init.d/functions"
  exit
fi
print_action() {
  if [ $2 -eq 0 ]; then
    action "$1" /bin/true
  else
    action "$1" /bin/false
  fi
}
docker info > /dev/null
if [ $? -ne 0 ]; then
    ps3="Docker尚未安装,是否安装>>:"
    select items in "安装" "不安装"; do
      case ${items} in
      安装)
        sudo yum install -y yum-utils device-mapper-persistent-data lvm2 zip unzip
        sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
        sudo sed -i 's+download.docker.com+mirrors.aliyun.com/docker-ce+' /etc/yum.repos.d/docker-ce.repo
        sudo yum makecache fast
        sudo yum -y install docker-ce
        systemctl enable --now docker
        print_action "成功安装docker" 0
        echo "请重新执行脚本安装blog"
        exit
        ;;
      不安装)
        print_action "您选择了不安装,脚本退出!" 1
        exit
        ;;
      esac
    done
else
  cd /opt
  curl -O http://www.mmin.xyz:81/package/blog/Z-Blog.zip
  unzip /opt/Z-Blog.zip
  chmod 777 -R /opt/zb_users
  docker network create lnmp
  docker pull mysql:5.7
  docker run -d -e MYSQL_ROOT_PASSWORD=123 -e MYSQL_DATABASE=blog --network lnmp --name mysl mysql:5.7
  docker pull registry.cn-shanghai.aliyuncs.com/op_devops/php:blog-php-v1
  docker run -d -v /opt/:/usr/share/nginx/html --network lnmp --name php -p 9000:9000 registry.cn-shanghai.aliyuncs.com/op_devops/php:blog-php-v1
  docker pull registry.cn-shanghai.aliyuncs.com/op_devops/nginx:blog-nginx-v1
  docker run -d -v /opt/:/usr/share/nginx/html --network lnmp --name nginx -p 80:80 registry.cn-shanghai.aliyuncs.com/op_devops/nginx:blog-nginx-v1 
  print_action "成功部署blog" 0
  print_action "用户名为root" 0
  print_action "初始数据库密码123" 0
  print_action "数据库为blog" 0
  print_action "主机名称为mysql" 0
  echo ">>>>>>>>>>>>>安全起见请修改密码<<<<<<<<<<<<<<"
fi

在这里插入图片描述

十、扩展 Docker swarm

# 链接 https://www.bilibili.com/video/BV1kv411q7Qc?p=14

#  Docker swarm   ----> k8s  #docker swarm是低级别的k8s
 
# 集群: 4台集群 --》阿里云购买4台服务器  --》1核2G 都要安装docker

# Raft协议

# 双主双从:假设一个节点挂了,其他节点是否可以用
Raft协议:保证大多数节点存活才可以用。只要>1,集群至少大于3台

# 实验
1、docker1机器停止。 宕机!双主,另外一个主节点也不能使用了!
2、可以将其他节点离开
# 总结
集群 可用 3个主节点 > 1台存活才可用
Raft协议:保证大多数节点存活,才可以用,高可用

# 弹性、扩缩容
服务,	集群中任意的节点可以访问,服务中可以有多个副本动态实现扩缩容
docekr service --help  # 帮助命令
docker service update --relipcas 5 my-nginx  # 扩缩容方式一
docker service scale my-nginx=5 # 扩缩容方式二
docker service rm my-nginx #移除服务

# docker swarm
命令 --》管理 --》api ---》调度--》工作节点(常见Task容器维护创建)