分类 运维 下的文章

Dockerfile篇

Dockerfile是用来构建Docker镜像的文本文件, 由一条条构建镜像所需的指令和参数构成的脚本。

  • 文件名首字母D大写
  • 构建三部曲

    • 编写 Dockerfile文件
    • 构建 docker build -t 新镜像名字:TAG .

      • (.)代表当前目录
    • 运行 docker run -it 新镜像名字:TAG

使用 Dockerfile 定制镜像

这里仅讲解如何运行 Dockerfile 文件来定制一个镜像,具体 Dockerfile 文件内指令详解,将在下一节中介绍,这里你只要知道构建的流程即可。

1、下面以定制一个 nginx 镜像(构建好的镜像内会有一个 /usr/share/nginx/html/index.html 文件)

在一个空目录下,新建一个名为 Dockerfile 文件,并在文件内添加以下内容:

FROM nginx
RUN echo '这是一个本地构建的nginx镜像' > /usr/share/nginx/html/index.html

2、FROM 和 RUN 指令的作用

FROM:定制的镜像都是基于 FROM 的镜像,这里的 nginx 就是定制需要的基础镜像。后续的操作都是基于 nginx。

RUN:用于执行后面跟着的命令行命令。有以下俩种格式:

shell 格式:

RUN <命令行命令>
# <命令行命令> 等同于,在终端操作的 shell 命令。

exec 格式:

RUN ["可执行文件", "参数1", "参数2"]
# 例如:
# RUN ["./test.php", "dev", "offline"] 等价于 RUN ./test.php dev offline

注意:Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大。例如:

FROM centos
RUN yum -y install wget
RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz"
RUN tar -xvf redis.tar.gz

以上执行会创建 3 层镜像。可简化为以下格式:

FROM centos
RUN yum -y install wget \
    && wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \
    && tar -xvf redis.tar.gz

如上,以 && 符号连接命令,这样执行后,只会创建 1 层镜像。

Dockerfile 保留关键字

  当前容器对外暴露出的端口
  EXPOSE

  容器启动命令
  Dockerfile 中可以有多个CMD指令, 但只有最后一个生效,CMD会被docker run 之后的参数替换
  CMD ["可执行文件", "参数", "参数2"]

  用来在构建镜像过程中设置环境变量
  ENV MY_PATH /user/test
  
  容器数据卷, 用于数据保持
  VOLUME

  当指定ENTRYPOINT后,CMD含义就发生了变化, 不再是直接运行其命令,二十将CMD的内容作为参数传递给ENTRYPOINT指令,他两个组合会变成<ENTRYPOINT>"<CMD>".
  例子:
  FROM nginx
  ENTRYPOINT ["nginx", "-c"] # 定参
  CMD ["/etc/nginx/nginx.conf"] # 变参

  指定一个已经存在的镜像作为模板:
  From

  作者/维护者
  MAINTAINER

  容器构建时执行的命令 两种格式 shell格式 exec格式 RUN是在docker build时运行
  RUN 命令

  将宿主机目录下的文件拷贝进镜像,且会自动处理URL和解压tar压缩包
  ADD

  复制文件 宿主机文件 复制进目标文件夹
  COPY

  指定创建容器后,终端默认登录的进来工作目录,一个落脚点, 可以配合ENV使用
  WORKDIR 

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:容器内路径 目标主机路径