前提

本文对 Docker 进行全面阐述,详细介绍 Docker 的作用、其基本使用,如常用命令、Dockerfile 的作用及使用、Docker Compose 的作用及使用。常用的基本上都会涉及,其他可以在 Docker 官网进行查漏补缺。

下面还有投票,一起参与进来吧👍

Docker 的作用

这里以容器化发展历程加上应用部署为例子,对 Docker 的作用进行说明。

在只有物理机的时候,大多数开发者或运维人员在部署一个应用时要做以下操作(以 java 应用为例):搭建 java 环境、maven 环境、配置环境变量、打包、运行。这样有几个问题:

  1. 部署慢:以上的过程都是需要手动操作,中间但凡那个环节出问题都需要花费时间排查,而且每次部署都需要重复做同样的操作。
  2. 成本高:一个外网的服务器费用最起码以万为单位进行采购,成本相对高。
  3. 资源浪费:如果应用是计算密集型,那么对 cpu 要求会很高,对内存、磁盘要求就不高,这样一来,闲置的资源就会浪费掉。
  4. 难于扩展迁移:如果要将 windows 服务器的应用迁移到 linux 服务器,一定会出现各种问题。

在虚拟化技术出现后,可以在物理机上开辟多个虚拟机,对物理机的资源进行了充分的使用,且虚拟机之间的资源是隔离的,可以部署多个应用,也降低了成本。 但是虚拟机需要安装操作系统,同样会造成资源浪费。

为了解决虚拟机安装操作系统带来的资源浪费,容器化技术就诞生了,容器化可以理解成不用安装操作系统的虚拟机,如下图,

了解和使用Docker-LMLPHP

这里的 Docker 就是容器化技术最典型的代表,其通过沙箱机制依赖主操作系统,大大的节省了资源、降低成本。除此之外,在应用部署上,Docker 容器本质是包含了部署应用所需的一切资源,包括操作系统依赖的其他组件或应用、数据库、配置等,这样在任何的环境下进行部署时将容器里的资源展开即可部署成功。

比如:我们现在使用 redis 服务,我们不需要去下载redis安装包、gcc等依赖组件等操作,只需要拉取 redis 镜像运行即可。

所以 Docker 的作用不仅仅是节省资源、降低成本,在应用方面也做到了自动部署、应用监控的作用,更简化了开发与运维的沟通,让软件协作方式发生巨大变化。

Docker 安装

这里基于 CentOS 7 进行 Docker 安装,Windows 和 MAC 安装参考 Docker 官网

执行以下命令进行安装

yum install -y yum-utils
#设置仓库地址
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

systemctl start docker

Docker 常用命令

拉取镜像:docker pull 镜像名:<tag> 。 可以通过配置镜像加速器加快拉取镜像的速度,可以参考阿里云 容器镜像服务中的镜像加速器 。
了解和使用Docker-LMLPHP

查看镜像:docker images

启动容器:docker run 镜像名:<tag>

查看容器:docker ps

删除容器:docker rm <-f> 容器id

删除镜像:docker rmi 镜像名:<tag>

与容器交互:docker exec <-it> 容器id /bin/bash

容期间通信

一个宿主机上的容器默认是可以互相通信的,但是每次启动容器后ip会修改,避免因ip变动而修改配置,启动容器时可以给容器命名,通过容器名称通信。命令如下

docker run --name 容器名称 镜像名称 --link 要通信的容器名称 要通信的镜像名称

如果多个容器都需要互相通信,这种方式就会比较繁琐了,此时可以通过创建一个网桥,需要通信的容器都绑定这个网桥即可。命令如下:

#创建网桥
docker network create -d bridge 网桥名称
#绑定网桥
docker network connect 网桥名称 容器名称

Docker 数据卷

为避免容器中产生的数据丢失或者多个容器共享一份数据,Docker 提供了2种数据挂载的方式:

  • 挂载到宿主机:宿主机开辟空间,容器内部文件存储在宿主机上,并访问同一份文件。命令如下:
    docker run --name 容器名称 -v 宿主机目录:容器目录 镜像名称

  • 挂载到共享容器:新建一个容器专门提供其他容器来存储或共享数据,命令如下:

    #创建共享容器
    docker create --name 容器名称 -v 宿主机目录:容器目录 镜像名称 /bin/true
    #挂载到共享容器
    docker run --name 容器名称 --volumes-from  共享容器名称  镜像名称
    

Dockerfile 构建镜像

当需要自己创建一个镜像时可以通过 Dockerfile 来构建镜像,然后上传到镜像仓库(可以自建 Harbor 或者使用公网的),需要使用的直接拉取下来即可。构建命令如下

docker build -t 机构/镜像名:<tag> dockerfile目录

docker 会基于 Dockerfile 文件中的指令来构建,具体指令如下:

FROM 镜像名  #基准镜像,基于该镜像构建
MAINTAINER xxxxx #用来描述的
WORKDIR 工作目录 #进入容后设置工作目录,相当于cd /xxx/
ADD ooo /xxx  #复制本地文件ooo到容器中的工作目录 /xxx
ADD ooo.tar.gz /xxx # 复制并解压 ooo.tar.gz 到容器中的工作目录 /xxx
ENV XXX #设置环境常量,文件中可以以${XXX}方式进行使用

运行指令有 RUN、CMD、ENTRYPOINT,其区别为:

  • RUN:Build 构建容器时执行
  • CMD:容器启动时执行的默认命令和参数,如果容器启动时有其他命令,则CMD不生效
  • ENTRYPOINT:容器启动时执行的命令,只有最后一个ENTRYPOINT执行

运行指令有两种声明方式:

  • Shell脚本方式RUN yum install xxx
  • Exec函数方式(推荐此方式): ["yum","install","xxx"]

两者的区别在于一个会创建子进程执行,一个会用新的进程替换主进程执行。

Docker Compose 容器编排

在多个容器存在依赖,比如运行应用的容器依赖数据库、Redis等多个容器都需要部署的情况下,为了减少部署时间,可以通过 Docker Compose 将这个应用及其依赖的容器统一定义,达到一键部署效果,这个我们叫做容器编排。

在进行容器编排时需要声明 docker-compose.yml 文件定义各个容器以及依赖关系,然后执行 docker-compose up -d 命令进行容器启动。下面提供一个 docker-compose.yml 示例:

version: '1.0'
services:
  service1: # 容器名、可通过此进行通信
    build: service1 dockerfile目录
    restart: always # 容错机制,当容器宕机后自动重启
    environment: # 启动容器时添加环境变量
      环境变量: xxxx 
  service1:
    build: service2 dockerfile目录
    depends_on: # 依赖某个容器,并可进行通信
      - service1
    ports: # 端口映射
      - '宿主机端口:容器端口'
    restart: always # 容错机制,当容器宕机后自动重启

需要注意的是 Docker Compose只能单机,能力有限。集群或者其他复杂场景k8s可以更好的满足。

05-25 01:33