compose篇

前言

Dockerfile可以让用户管理一个单独的应用容器,而compose则允许用户在一个模板(yaml格式)中定义一组相关联的应用容器(被称为一个project,即项目)
例如一个web服务再加上后端的数据库服务容器等。

docker-compose是docker官方的开源项目
负责实现对docker容器集群的快速编排

docker建议我们每一个容器中只运行一个服务,因为docker容器本身占用资源极少,所以最好是将每个服务单独分隔开,
但是这样我们又面临了一个问题

如果我需要同事部署好多个服务,难道要每个服务单独写Dockerfile然后在构建镜像,构建容器,这样累都累死了,所以docker官方给我们提供了docker-compose多服务部署工具

例如要实现要给web微服务项目,除了Web服务容器本身,往往还需要再加上后端的数据库mysql服务容器,redis服务器,注册中心qureka,甚至还包括负载均衡容器等等。。


compose 使用的三个步骤

  1. 编写Dockerfile定义各个微服务应用并构建出对应的镜像
  2. 使用docker-compose 定义一个完整的业务单元,安排好整体应用中的各个容器
  3. 最后, 执行docker-compose up命令 来启动并运行整个应用程序,完成一键部署上线

一、Docker-compose简介

1、docker-compose基础概念

docker-compose项目是docker官方的开源项目, 负责实现对docker容器集群的快速编排。

docker-compose将所管理的容器分为三层, 分别是工程(project),服务(service)以及容器(containner)

docker-compose运行目录下的所有文件(docker-compose.yml文件、extends文件或环境变量等)组成一个工程,如无特殊指定,工程名即为当前目录名。
一个工程当中,可以包含多个服务,每个服务中定义了容器运行的镜像、参数、依赖。
一个服务中可以包括多个容器实例,docker-compose并没有解决负载均衡的问题。因此需要借助其他工具实现服务发现及负载均衡,比如consul。
docker-compose的工程配置文件默认为docker-compose.yml。可以通过环境变量COMPOSE_FILE -f 参数自定义配置文件,其自定义多个有依赖关系的服务及每个人服务运行的容器。

2、为什么要使用docker-compose

使用一个Dockerfile模板文件,可以让用户很方便的定义一个单独应用容器。在工作中,经常会碰到需要多个容器相互配合来完成某项任务的情况,例如要实现一个web项目,除了web服务容器本身,往往还需要再加上后端的数据库服务容器,甚至还包括负载均衡容器等。
compose允许用户通过一个单独docker-compose.yml模板文件(YAML格式)来定义一组相关联的应用容器为一个项目(project)

docker-compose项目由pypthon编写,调用docker服务提供的API来对容器进行管理,因此, 只要所操作的平台支持docker-API,就可以在其上利用conpose来进行编排管理。
简单来说:就是来管理多个容器的,定义启动顺序的,合理编排,方便管理。

二、YAML文件格式及编写注意事项

1、YAML文件格式

YAML是一种标记性语言,它可以很直观的展示数据序列化格式,可读性高。
类似于json数据描述语言,但是语法要比json简单很多。
YAML数据结构通过缩进来表示,连续的项目通过减号来表示,键值对用冒号分隔,数组用中括号[ ] 括起来,bash用花括号{ } 括起来。

2、YAML格式的注意事项

不支持制表符tab键缩进,只能使用空格缩进
通常开头缩进2个空格
字符后缩进1个空格,如冒号【:】、逗号【,】、横杠【-】
用#号表示注释
如果包含特殊字符用单引号【’ '】引起来作为普通字符,如果用双引号【“ ”】表示特殊字符本身的意思,
布尔值必须用【“ ”】括起来
YAML区分大小写
3、YAML数据结构案例

version: '3'
services:
  # mysql
  mysql:
    container_name: daoda-mysql //容器名字
    image: mysql:5.7  //使用mysql:5.7镜像
    ports:
      - "60133:3306"  //端口映射 不能低于60
    environment:
      - "MYSQL_ROOT_PASSWORD=root"
      - "TZ=Asia/Shanghai"
    command:  // 执行命令,会覆盖容器启动后默认执行的命令(会覆盖dockefile中的CMD指令)
      --character-set-server=utf8mb4
      --collation-server=utf8mb4_unicode_ci
      --lower-case-table-names=1
      --sql-mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'
    restart: always //重启策略,定义是否重启容器1、no,默认策略,在容器退出时不重启容器2、on-failure,在容器非正常退出时(退出状态非0),才会重启容器3、on-failure:3 在容器非正常退出时,重启容器,最多重启3次4、always,在容器退出时总是重启容器,5、unless-stopped,在容器退出时总是重启容器,但是不考虑在Docker守护进程启动时就已经停止了的容器。
    privileged: true // 用来给容器root权限,注意是不安全的,true
    networks: //加入网络,引用顶级networks下条目
      bridge:
        ipv4_address: 172.60.0.1

  # 报告模块:lly
  php:
    container_name: php
    build: // 编译指定内容
      context: ../../Code_lly //设置编译文件夹
      dockerfile: daoda-report-Dockerfile // 编译Dockerfile文件
    restart: always
    privileged: true
    networks:
      daoda-bridge:
        ipv4_address: 172.60.0.2
networks:
  daoda-bridge:
    driver: bridge
    ipam:
      config:
        - subnet: 172.60.0.0/16
        
volumes: 定义挂在宿主机目录
  log:
    driver_opts:
      type: nfs
      o: bind
      device: "/home/data/log"



compose下载:

自动安装:

  sudo yum update
  sudo yum install docker-compose-plugin


  docker compose version

手动安装:

第一步:
要下载并安装撰写 CLI 插件,请运行:

    DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker}
    mkdir -p $DOCKER_CONFIG/cli-plugins
    curl -SL https://github.com/docker/compose/releases/download/v2.16.0/docker-compose-linux-x86_64 -o $DOCKER_CONFIG/cli-plugins/docker-compose

第二步:
将可执行权限应用于二进制文件:

  
  chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose

或者,如果您选择为所有用户安装 Compose:

  sudo chmod +x /usr/local/lib/docker/cli-plugins/docker-compose

第三步:
测试安装:

  docker compose version
  Docker Compose version v2.16.0

compose 常用命令

最好在yml同级目录下执行

docker-compose -h 查看帮助
docker-compose up 启动所有docker-compose服务
docker-compose up -d 启动所有docker-compose服务并后台运行
docker-compose down 停止并删除容器,网络,卷,镜像
docker-compose exec yml的服务id /bin/bash 进入容器实例内部
docker-compose ps 列出当前所有compose编排过运行的所有容器
docker-compose top 展示当前compose编排过的容器进程

docker-compose config 检查配置
docker-compose config -q 检查配置,有问题才有输出
docker-compose restart 重启
docker-compose start 启动
docker-compose stro 停止

网络篇

我们在进行ifconfig时会出现:

  • ens33:linux宿主机地址
  • lo:local 本地回环链络
  • virbr0: 虚拟网桥

    • 安装Centos过程中,如果有选择相关虚拟化的服务安装系统后,启动网卡时会发现有个一以网桥连接的私网地址的virbr0网卡,还有一个固定的默认IP地址 192.168.122.1 是做虚拟机网桥使用的,其作用是为连接其上的虚拟机网卡提供NAT访问外网的功能。

docker启动以后,会出现一个docker0的虚拟网桥,他可以使容器和容器之间,容器与宿主机之间相互访问
启动Docker以后会默认以下创建三大网络模式。

  • bridge

    • 主要用这个
    • 为每一个容器分配 设置IP等 并将容器连接到每一个docker0
    • 虚拟网桥 默认为该模式
  • host

    • 勉强会用这个
    • 容器将不会虚拟出自己的网卡 配置自己的IP等 而是使用宿主机的IP和端口
  • none

    • 一般不会用
    • 容器有独立的Network namespace 但并没有对其进行任何网络设置 如分配veth pair和网桥连接 IP等
  • container

    • 新创建的容器不会创建自己的网卡和配置自己的IP 而是和一个指定的容器共享IP 端口范围等

网络有什么用?

用于实现docker网络管理和容器之间的调用规划

能干嘛?

容器间的互联和通信以及端口映射
容器ip变动时候可以通过服务名直接网络通信而不受影响

docker0是什么?

Docker服务默认会创建一个docker0网桥(其上有一个docker0内部接口),
该桥接网络的名称为docker0,他在内核层连通了其他的物理或虚拟网卡,
这就将所有容器和本地组主机都放到同一个物理网络。docker默认制定了docker0接口的IP地址和子网掩码,
让主机和容器直接可以通过网桥相互通信

自定义网络

由于ip是会变化的,所以要通过服务名调用

after

  1. 新建自定义网络
  2. docker network create 网络名称
  3. docker ls
  4. 把容器一和容器二都加入自定义网络
  5. docker run -d -p 宿主机端口1:容器端口 --network 网络名称1 --name 网络名称1 容器名
  6. docker run -d -p 宿主机端口2:容器端口 --network 网络名称2 --name 网络名称2 容器名
  7. 现在两个容器已经在同一网段 可以通过ip ping通

network命令:

不会了就输入下面这个


docker network --help

查看网络列表

docker network ls

删除网络

docker network rm 网络ID

创建网络

docker network create 网络名称

查看网络详情

docker network inspect 网络名称


命令篇

基础命令

查看版本

docker version

启动docker

sudo systemctl start docker

停止docker

systemctl stop docker

重启docker

systemctl restart docker

查看docker状态

systemctl status docker

开机启动

systemctl enable docker

查看docker概要信息

docker info

查看镜像/容器/数据卷占了多少空间

docker system df

卸载docker

sudo yum remove docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras

配置docker可以远程连接

  • systemctl stop firewalld(关闭防火墙)
  • vim /lib/systemd/system/docker.service
  • ExecStart 后面追加 -H tcp://0.0.0.0:2333
  • systemctl daemon-reload

镜像命令

列出本地主机上的镜像

  • -a列出本地所有的镜像(含历史映像层)
  • -q只显示镜像ID
  • REPOSITORT:表示镜像的仓库源
  • TAG:镜像的标签版本号
  • IMAGE ID:镜像ID
  • CREATED:镜像创建时间
  • SIAE:镜像大小
docker images -a
docker images -q

docker search 搜索某个镜像是否在远程仓库

  • --limit 不加默认查询25条点赞数最多
  • STATRS 点赞数量
  • OFFICIAL 是否是官方
  • AUTOMATED 是否是自动构建的
docker search hello-world
docker search --limit 5 redis

下载镜像

  • 同一个仓库有多个TAG版本 加TAG代表下载对应版本号 不加就是下载最新的latest
docker pull 镜像名字:TAG
docker pull 镜像名字

删除所有镜像、容器和 卷:

sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd

删除单个镜像

docker rmi -f 镜像ID

删除多个

docker rmi -f 镜像名:TAG 镜像名2:TAG

删除全部

docker rmi -f

创建一个镜像:

Docker run [image]

容器命令

启动容器: docker run 镜像名

  • -t 以交互模式启动
  • -i 创建一个伪输入终端

    • 一般都是 -it 配合使用
    • exit 退出终端
  • --name=容器名
  • -d 启动守护式容器

重新进入容器终端

直接进去容器启动命令的终端 不会启动新的进程 用exit推出 会导致容器的停止
docker attach 容器ID /bin/bash

推荐 exec实在容器中打开新的终端 并且可以启动新的进程 用exit退出时 不会导致容器的停止
docker exec -t 容器ID /bin/bash

容器目录和主机目录互通互联(双向) (可以用来做mysql数据备份)

读写 read write
docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录:rw 镜像名

容器内只读 readonly
docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录:ro 镜像名

容器数据共享和互相传递 容器卷之间的继承 (父容器挂了 不会影响子容器)

docker run -it -- privileged=true --volumes -form 父容器名 --name 子容器名 镜像名字

查看容器详情

docker inspect 容器ID

启动已重启的容器

docker start 容器ID

重启容器

docker restart 容器ID

停止容器

docker stop 容器ID

强制停止容器

docker kill 容器ID

删除已停止的容器

docker rm 容器ID

显示当前正在运行的

 docker ps
  • -n 1 列出多少个

查看容器的日志

docker logs 容器ID

容器文件拷贝到主机上

docker cp 容器ID:容器内路径 目标主机路径

Docker基础篇

什么是Docker?

在聊 Docker 是什么之前,我们先来回顾一下传统的产品开发上线涉及到的难点。一款产品从开发到上线,经历了开发环境、测试环境、生产环境等不同的操作系统、运行环境和应用配置等环境。在项目管理中,还涉及到不同版本以及不同版本之间兼容性等问题。

这些问题对开发人员和运维人员都是极大的考验,同时对各方的协作也有一定的要求。不然就会出现”代码在我这里运行的好好的啊“,这种尴尬的局面。而 Docker 的出现就是提供了一套用来解决此类问题的标准解决方案。

Docker

Docker 的口号是”一次创建或配置,可以在任意地方正常运行“。如口号所说,Docker 的出现对于开发和运维人员是一大福音,基于 Docker 可以方便地搞定标准化的发布流程,再也不用纠结不同环境导致的问题了。

其实,Docker 的使用可以理解为:软件是带环境安装的,也就是说,安装的时候把原始环境一模一样的复制过来一份。这样也就消除了不同机器运行结果不同的问题。

那么,Docker 是什么呢?Docker 是一个开源的应用容器引擎,基于 Go 语言,并遵从 Apache2.0 协议开源。它可以让开发者打包应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。Docker 可用于开发应用、交付应用、运行应用等场景。

容器是完全使用沙箱机制,相互之间不会有任何接口,更重要的是容器性能开销极低。Docker 允许用户将基础设施中的应用单独分割出来,形成更小的部分容器,从而提高软件交付速度。

  • Docker组成三要素

    • 镜像(image)

      • 镜像是静态的定义 更像是一个模板
      • Docker 镜像就是一个只读的模板,是文件与 meta data 的集合。镜像是基于分层的实现的,每一层都可以添加删除文件,从而形成新的镜像。
        镜像可以理解为是一个树状结构,每一个镜像都会依赖于另一个镜像,这个依赖关系体现在 Docker 镜像制作的 Dockerfile 中的 FROM 指令上的。关于 Dockerfile 及其中的 FROM 指令,需要注意的是:如果是树的根,那么就需要"FROM scratch"。
        镜像可以用来创建 Docker 容器,一个镜像可以创建多个容器。
    • 容器(container)

      • 容器来源于镜像
      • 一个镜像可以创建多个容器
      • 不同的镜像可以创建不同的容器
      • 每个镜像都是相互隔离的
      • 容器可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台。可以把容器看做是一个简易版的 Linux 环境和运行在其中的应用程序。
    • 仓库(repository)

      • hub.docker.com 存放Docker镜像的地方,提供了一些官方镜像
      • 仓库分为公开,私有

接下来我们来安装Docker

跟着命令依次执行下去 就可安装成功哦

环境需要

  1. CentOS7+ 能上网
  2. 卸载旧版本
  3. yum安装gcc
yum -y install gcc
yum -y install gcc-c++

安装客户端

1.执行命令

sudo yum install -y yum-utils

2.设置stable镜像仓库(自行选择,推荐阿里云)

官网(慢 容易报错)

sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo  

阿里云(推荐)

yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

3.安装最新版Docker

sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
按y继续

4.启动Docker

sudo systemctl start docker

5.查看是否成功启动

docker version
systemctl start docker

6.开始配置镜像

docker配置镜像的流程,先从本地拉取,本地没有再去云端拉取

一个简单的小例子:

sudo docker run hello-world


  
  Unable to find image 'hello-world:latest' locally
  latest: Pulling from library/hello-world
  2db29710123e: Pull complete
  Digest: sha256:6e8b6f026e0b9c419ea0fd02d3905dd0952ad1feea67543f525c73a0a790fefb
  Status: Downloaded newer image for hello-world:latest
  
  Hello from Docker!
  This message shows that your installation appears to be working correctly.
  
  To generate this message, Docker took the following steps:
   1. The Docker client contacted the Docker daemon.
   2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
      (amd64)
   3. The Docker daemon created a new container from that image which runs the
      executable that produces the output you are currently reading.
   4. The Docker daemon streamed that output to the Docker client, which sent it
      to your terminal.
  
  To try something more ambitious, you can run an Ubuntu container with:
   $ docker run -it ubuntu bash
  
  Share images, automate workflows, and more with a free Docker ID:
   https://hub.docker.com/
  
  For more examples and ideas, visit:
  https://docs.docker.com/get-started/

docker run 都干了什么?

  • 本地是否有该镜像

      • 以该镜像为模板在本机运行
      • 去Docker Hub上查找该镜像

        • 找到

          • 下载镜像到本地

            • 以该镜像为模板生产容器实例运行
        • 没找到

          • 返回失败错误,查不到该镜像

docker 虚悬镜像是什么

  • 仓库名 TAG都是的镜像,俗称虚悬镜像dangling image
  • 虚悬镜像有ID 也有大小
  • 虚悬镜像没有存在价值 用 docker image prune 命令删除

番外

如果你需要工具来远程连接docker可以执行以下操作
首先开启防火墙和安全组端口(2333),端口可以自定义.

vim /lib/systemd/system/docker.service

ExecStart末尾加上

-H tcp://0.0.0.0:2333

变成

ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -H tcp://0.0.0.0:2333

修改后保存文件,然后通知docker服务做出的修改

systemctl daemon-reload

重启docker服务

service docker restart

接下来测试一下看是否能连接到docker api。上面的2333就是对应端口

curl http://localhost:2375/verion