文章目录

  • 第一节 Docker容器入门
    • 1.1.1 基础概念
      • 1. Docker是什么
      • 2. Docker和传统虚拟机的对比
      • 3. 为什么要使用Docker
      • 4. Docker架构
      • 5. Docker包括三个基本概念:
        • 1)Docker镜像
        • 2)Docker镜像分层存储
        • 3)Docker容器
        • 4)Docker仓库
          • Docker Registry公开仓库
          • Docker Registry 私有仓库
    • 1.1.2 安装及加速
      • 1. Docker版本命名
      • 2.CentOS安装Docker
        • 1)系统要求
        • 2)卸载旧版本
        • 3)使用yum安装
        • 4)使用脚本安装
        • 5)启动Docker CE
        • 6)建立docker用户组
        • 7)测试Docker是否安装正确
      • 3.CentOS卸载Docker
        • 1)删除docker安装包
        • 2)删除docker镜像
      • 4. 镜像加速器
        • 1)CentOS 7 配置镜像加速
        • 2)检查加速器是否生效
    • 1.1.3 Docker常用命令
      • 1. Docker镜像操作
        • 1)获取镜像
        • 2)运行镜像
        • 3)列出镜像
        • 4)删除本地镜像
      • 2. Docker容器操作
        • 1)启动容器
          • i. 新建并启动
          • ii. 启动已终止容器
          • iii. 后台运行
        • 2)停止运行的容器
        • 3)进入容器
        • 4)导出和导入容器
          • i. 导出容器
          • ii. 导入容器
        • 5)删除容器
          • i. 删除单个容器
          • ii. 清理所有处于终止状态的容器
    • 1.1.4 利用Dockerfile构建私有镜像
      • 1. 使用Dockerfile定制镜像
        • 1)FROM指定基础镜像
        • 2) RUN执行命令
      • 2. 构建镜像
      • 3. Dockerfile指令详解
        • 1) COPY复制文件
        • 2) ADD更高级的复制文件
        • 3)CMD容器启动命令
        • 4)ENTRYPOINT入口点
        • 5)ENV设置环境变量
        • 6)ARG构建参数
        • 7)VOLUME定义匿名卷
        • 8)EXPOSE声明端口
        • 9)WORKDIR指定工作目录
        • 10)USER指定当前用户
        • 11)HEALTHCHECK健康检查
        • 12)ONBUILD为他人做嫁衣
      • 4. 其它制作镜像方式
        • 1)docker save和docker load
    • 1.1.5 Docker运行Java程序
      • 1. 定制镜像
      • 2. 运行镜像
    • 1.1.6 搭建Docker私有仓库
      • 1. Docker Hub
        • 1)注册登录及退出
        • 2)拉取镜像
        • 3)推送镜像
      • 2. 私有仓库
        • 1)安装运行docker-registry
        • 2)在私有仓库上传、搜索、下载镜像
        • 3)注意事项
          • Ubuntu 16.04+、Debian 8+、centos 7
          • Windows、Mac
  • 第三节 网易Docker最佳实践
    • 1.3.1 容器监控
      • 1. 概述
      • 2. 容器监控方案选择
      • 3. CAdvisor
      • 4. InfluxDB
        • 1)主要功能
        • 2)主要特点
      • 5. Granfana
        • 主要特性
      • 6. CAdvisor + InfluxDB + Grafana
      • 7.安装部署
        • 1)部署InfluxDB服务
        • 2)部署CAdvisor服务
        • 3)部署Grafana服务
        • 4)docker-compose快速部署
    • 1.3.2 日志监控
      • 1. Docker日志
        • 1)日志处理机制
        • 2)Docker Logging Driver
      • 2. Graylog
        • 1)Graylog部署
        • 2)Graylog系统配置
          • i. input配置
          • ii. docker配置
    • 1.3.3 Docker Swarm资源管理
      • 1. Docker Swarm介绍
      • 2. 基本概念
        • 1)节点
        • 2)服务和任务
      • 3. 创建Swarm集群
        • 1)初始化集群
        • 2)增加工作节点
        • 3)查看集群
        • 4)升级工作节点为管理节点
      • 4. 部署服务
        • 1)新建服务
        • 2)查看服务
        • 3)删除服务
      • 5. 资源管理
        • 1)portainer集群运行
        • 2)portainer配置
    • 1.3.4 快速扩容
      • 1. 命令方式
      • 2. portainer方式

第一节 Docker容器入门

1.1.1 基础概念

1. Docker是什么

  • Docker最初是动态Cloud公司创始人Solomon Hykes在法国期间发起的一个公司内部项目,它是基于dotCloud公司多年云服务技术的一次革新,并于2013年3月以Apache 2.0授权协议开源,主要项目代码在GitHub上进行维护。Docker项目后来还加入了Linux基金会,并成立推动开放容器联盟(OCI)
  • Docker使用Google公司推出的 Go语言 进行开发实现,基于Linux内核的cgroup,namespace,以及AUFS类的Union FS等技术,对进程进行封装隔离,属于操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其他的隔离的进程,因此也称其为 容器
  • Docker在容器的基础上,进行了进一步的封装,从文件系统、网络互联到进程隔离等等,极大的简化了容器的创建和维护,使得 Docker技术比虚拟机技术更为轻便、快捷

2. Docker和传统虚拟机的对比

3. 为什么要使用Docker

4. Docker架构

5. Docker包括三个基本概念:

  • 镜像(Image)
  • 容器(Container)
  • 仓库(Repository)
1)Docker镜像
  • 我们都知道,操作系统分为内核和用户空间。对于Linux而言,内核启动后,会挂载root文件系统为其提供用户空间支持。而Docker镜像(Image),就相当于是一个root文件系统。比如官方镜像centos:7.6就包含了完整的一套centos7.6最小系统的root文件系统。
  • Docker镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。
2)Docker镜像分层存储
  • 因为镜像包含操作系统完整的root文件系统,其体积往往是庞大的,因此在Docker设计时将其设计为分层存储的架构。镜像只是一个虚拟的概念,其实际体现并非由一个文件组成,而是由一组文件系统组成,或者说,由多层文件系统联合组成。
  • 镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生再自己这一层。在构建镜像的时候,需要额外小心,每一层尽量只包含该层需要添加的东西,任何额外的东西应该在该层构建结束前清理掉。
  • 分层存储的特征还使得镜像的复用、定制变的更为容易。甚至可以用之前构建好的镜像作为基础层,然后进一步添加新的层,以定制自己所需要的内容,构建新的镜像。
3)Docker容器
  • 镜像(Image)和容器(Container)的关系,就像java中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
  • 镜像使用的是分层存储,容器也是如此。每一个容器运行时,是以镜像为基础层,在其上创建一个当前容器的存储层,我们可以称这个为容器运行时读写而准备的存储层为容器存储层。
  • 容器存储层的生命周期和容器一样,容器消亡时,容器存储层也随之消亡。因此,任何保存于容器存储层的信息都会随容器删除而丢失。
  • 按照Docker最佳实践的要求,容器不应该向其存储内写入任何数据,容器存储层要保持无状态化。所有的文件写入操作,都应该使用Volume数据卷、或者绑定宿主目录,在这些位置的读写会跳过容器存储层,直接对宿主(或网络存储)发生读写,其性能和稳定性更高。
  • 数据卷的生存周期独立于容器,容器消亡,数据卷不会消亡。因此,在使用数据卷后,容器删除或者重新运行之后,数据却不会丢失。
4)Docker仓库
  • 镜像构建文成后,可以很容易的在当前宿主机上运行,但是,如果需要在其他服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry就是这样的服务。

  • 一个Docker Registry中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。

  • 通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 <仓库名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以latest作为默认标签。

  • 以centos镜像为例,centos是仓库的名字,其内包含有不同的版本标签,如:6.9、7.5。我们可以通过centos:6.9,或者centos:7.5来具体指定所需哪个版本的镜像。如果忽略了标签,比如centos,那将视为centos:latest。

  • 仓库名经常以 两段式路径 形式出现,比如study/nginx,前者旺旺意味着Docker Registry多用户环境下的用户名,后者则往往是对应的软件名。但这并非绝对,取决于锁使用的具体Docker Registry的软件或服务。

Docker Registry公开仓库
  • 常用的Registry是官方的Docker Hub,这也是默认的Registry。除此之外,还有CoreOS的Quay.io,CoreOS相关的镜像存储在这里;Google的Google Container Registry,Kubernetes的镜像使用的就是这个服务。
  • 国内的一些云服务商提供了针对Docker Hub的镜像服务,这些镜像服务被称为加速器。常见的有阿里云加速器DaoCloud加速器等。使用加速器会直接从国内的地址下载Docker Hub的镜像,比直接从Docker Hub下载速度会提高很多。
  • 国内也有一些云服务上提供类似于Docker Hub的公开服务。比如网易云镜像服务DaoCloud镜像市场阿里云镜像库等。
Docker Registry 私有仓库
  • 除了使用公开服务外,用户还可以在本地搭建私有Docker Registry。Docker官方提供了Docker Registry镜像,可以直接使用作为私有Registry服务。
  • 开源的Docker Registry镜像只提供了Docker Registry API的服务端实现,足以支持docker命令,不影响使用。但不包含图形界面,以及镜像维护、用户管理、访问控制等高级功能。在官方的商业化版本Docker Trusted Registry中,提供了这些高级功能。
  • 除了官方的Docker Registry外,还有第三方软件实现了Docker Registry API,甚至提供了用户界面以及一些高级功能。比如,VMWare Harbor和Sonatype Nexus。

1.1.2 安装及加速

1. Docker版本命名

  • Docker在1.13版本之后,从2017年的3月1日开始,版本命名规则变为如下
项目 说明
版本格式 YY.MM
Stable版本 每个季度发行
Edge版本 每个月发行
当前Docker CE Stable版本 18.09
当前Docker CE Edge版本 18.09
  • 同时Docker划分为CE和EE。CE即社区版(免费,支持周期三个月),EE即企业版,强调安全,付费使用。

2.CentOS安装Docker

  • 官方网站上有各种环境下的安装指南,这里主要介绍Docker CE在Linux上的安装。
  • 官方安装指南地址:https://docs.docker.com/install/
1)系统要求
  • Docker CE支持 64 位版本CentOS 7,并且要求内核版本不低于3.10
  • 查看系统内核版本
uname -r
2)卸载旧版本
  • 旧版本的Docker称为docker或者docker-engine,使用以下命令卸载旧版本:
sudo yum remove docker docker-common docker-selinux docker-engine
3)使用yum安装
sudo yum install docker-ce

注意:如果安装的是centos7 minimal版本,执行安装提示“没有可用软件包”。这个时候需要安装必要的软件依赖以及更新增加docker-ce yum源。

  • 安装相关依赖:
sudo yum install -y yum-utils device-mapper-persistent-data lvm2

其中 -y 是不需要提示,全部同意的安装模式

  • 添加yum源:
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
4)使用脚本安装
  • 在测试或开发环境中Docker官方为了简化安装流程,提供了一套便捷的安装脚本,CentOS系统上可以使用这套脚本安装:
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh --mirror Aliyun
  • 执行这个命令后,脚本就会自动的将一切准备工作做好,并且把Docker CE的Edge版本安装在系统中。
5)启动Docker CE
sudo systemctl enable docker     #设置开机启动
sudo systemctl start docker
6)建立docker用户组
  • 默认情况下,docker命令会使用Unix socket与Docker引擎通讯。而只有root用户和docker组的用户才可以访问Docker引擎的Unix Socket。一般Linux系统上不会直接使用root用户进行操作。因此,需要使用docker的用户加入docker用户组。
sudo groupadd docker     #建立docker组
sudo usermod -aG docker $USER   #将当前用户加入docker组
7)测试Docker是否安装正确
docker run hello-world #启动一个基于hello-world镜像的容器
docker info     #显示docker的详细信息
docker --version     #显示docker的详细信息

若能正常输出以上信息,则说明安装成功。

3.CentOS卸载Docker

1)删除docker安装包
sudo yum remove docker-ce
2)删除docker镜像
sudo rm -rf /var/lib/docker

4. 镜像加速器

  • 国内从Docker Hub拉取镜像有时会遇到困难,此时可以配置镜像加速器。Docker官方和国内很多云服务商都提供了国内加速器服务,例如

    • Docker官方提供的中国Registry mirror
    • 阿里云加速器
    • DaoCloud加速器
    • 163加速器

以163加速器为例进行介绍

1)CentOS 7 配置镜像加速
  • 对于使用systemd的系统,请在/etc/docker/daemon.json中写入如下内容(如果文件不存在请新建该文件)
{"registry-mirrors":["http://hub-mirror.c.163.com"]
}
  • 重新启动服务生效
sudo systemctl daemon-reload
sudo systemctl restart docker
2)检查加速器是否生效
  • 配置加速器之后,如果拉取镜像仍然十分缓慢,请手动检查加速器配置是否生效,在命令行执行docker info,如果从结果中看到了如下内容,说明配置成功。
$ docker info
...
Registry Mirrors:http://hub-mirror.c.163.com
Live Restore Enable:false

1.1.3 Docker常用命令

1. Docker镜像操作

  • Docker运行容器前需要本地存在对应的镜像,如果本地不存在该镜像,Docker会从镜像仓库下载该镜像。
1)获取镜像
  • 从Docker镜像仓库获取镜像的命令是docker pull。其命令格式为:
docker pull[选项][Docker Registry 地址[:端口号]/]仓库名[:标签]
  • 具体的选项可以通过docker pull --help命令看到,这里我们说一下镜像名称的格式。

    • Docker镜像仓库地址:地址的格式一般是<域名/IP>[:端口号]。默认地址是Docker Hub。
    • 仓库名:仓库名是两段式名称,即<用户名>/<软件名>。
    • 对于Docker Hub,如果不给出用户名,则默认为library,也就是官方镜像。
docker pull ubuntu:16.04
  • 上面命令中没有给出Docker镜像仓库地址,因此将会从Docker Hub获取镜像。而镜像名称是ubuntu:16.04,因此将会获取官方镜像library/ubuntu仓库中标签为16.04的镜像。
2)运行镜像
  • 有了镜像后,我们就能够以这个镜像为基础启动并运行一个容器。以杀你那的ubuntu:16.04为例,如果我们打算启动里面的bash并且进行交互式操作的话,可以执行:
docker run -it --rm ubuntu:16.04 bash
  • -it:这是两个参数,一个是 -i:交互式操作,一个是 -t:终端。
  • –rm:这个参数是说容器退出后随之将其删除。
  • ubuntu:16.04 : 这是指用ubuntu:16.04镜像为基础来启动容器。
  • bash:放在镜像名后的是命令,这里我们希望有个交互式Shell,因此用的是bash。
  • 最后通过exit指令退出这个容器。
  • –name参数可以指定容器的名称
  • -p [宿主机端口号]:[容器端口号],该命令可以用来将容器的端口映射到宿主机的端口
3)列出镜像
  • 想要列出已经下载下来的镜像,可以使用docker images ls命令。列表包含了仓库名、标签、镜像ID、创建时间以及所占用的空间。
docker image ls
  • 查看镜像、容器、数据卷所占用的空间。
docker system df
  • 仓库名、标签均为<none>的镜像成为 虚悬镜像(dangling image),显示这类镜像:
docker image ls -f dangling=true
  • 一般来说,虚悬镜像已经失去了存在的价值,是可以随意删除的,可以用下面的命令删除。
docker image prune
4)删除本地镜像
  • 如果要删除本地的镜像,可以使用docker image rm命令,其格式为:
docker image rm [选项]<镜像1>[<镜像2>...]
  • 其中,<镜像>可以是镜像短ID、镜像长ID、镜像名或者镜像摘要。

  • 使用docker image ls -q来配合docker image rm,这样可以批量删除希望删除的镜像。

docker image rm $(docker image ls -q ubuntu)     #删除所有仓库名为ubuntu的镜像
  • 或者删除所有在ubuntu:16.04之前的镜像:
docker image rm $(docker image ls -q -f before=ubuntu:16.04)

2. Docker容器操作

  • 容器是独立运行的一个或一组应用,以及它们的运行态环境。对应的,虚拟机可以理解为模拟运行的一整套操作系统(提供了运行态环境和其他系统环境)和跑在上面的应用。
1)启动容器
  • 启动容器有两种方式,一种是基于镜像新建一个容器并启动,另外一个是将在终止状态(stopped)的容器重新启动。
  • 因为Docker的容器是轻量级的,用户可以随时删除和新创建容器。
i. 新建并启动
  • 使用 docker run 命令启动
  • 例如输出一个“Hello World”,之后终止容器。
docker run ubuntu:16.04 /bin/echo 'Hello world'
ii. 启动已终止容器
  • 使用 docker container start 或者 docker start命令
  • 例如:启动一个bash终端,允许用户进行交互。
docker run -t -i ubuntu:16.04 /bin/bash

-t 让Docker分配一个伪终端并绑定到容器的标准输入上,-i 则让容器的标准输入保持打开。也可以合并 -it
当利用docker run来创建容器时,Docker在后台运行的标准操作包括:

  • 检查本地是否存在指定的镜像,不存在就从共有仓库下载
  • 利用镜像创建并启动一个容器
  • 分配一个文件系统,并在只读的镜像层外面挂载一层可读写层
  • 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去
  • 从地址池配置一个ip地址给容器
  • 执行用户指定的应用程序
  • 执行完毕后容器被终止
iii. 后台运行
  • 很多时候,需要让Docker在后台运行而不是直接把执行命令的结果输出在当前宿主机下。
  • 此时可以通过添加 -d 参数来实现。
    • 如果不使用 -d 参数运行容器,比如 docker run hello-world 会把日志打印在控制台;
    • 如果使用了 -d 参数运行容器,比如 docker run -d hello-world 不会输出日志,只会打印容器id(输出结果可以用 docker logs [容器长id] 查看)

注:容器是否会长久运行,是和docker run 指定的命令有关, 和 -d 参数无关。

2)停止运行的容器
  • 可以使用 docker container stop 来终止一个运行中的容器。
  • 终止状态的容器可以用 docker container ls -a 命令看到。
  • 处于终止状态的容器,可以通过 docker container start 命令来重新启动。
  • 此外,docker container restart 命令会将一个运行态的容器终止,然后再重新启动它。
3)进入容器
  • 在使用 -d 参数时,容器启动后会进入后台,某些时候需要进入容器进行操作,使用 docker exec 命令可以进入到运行中。
  • exec 命令 -i -t 参数
    • 只用 -i 参数时,由于没有分配伪终端,界面没有我们熟悉的Linux命令提示符,但命令执行结果仍然可以返回。
    • 当 -i -t参数一起使用时,则可以看到Linux命令提示符。
    docker exec -it 容器ID /bin/bash
4)导出和导入容器
i. 导出容器
  • 如果要导出本地某个容器,可以使用 docker export 命令。
docker export 容器ID > 导出文件名.tar
ii. 导入容器
  • 可以使用 docker import 从容器快照文件中再导入为镜像
cat 导出文件名.tar | docker import - 镜像用户/镜像名:镜像版本
  • 此外,也可以通过制定URL或者某个目录来导入
docker import http://study.163.com/image.tgz example/imagerepo
5)删除容器
i. 删除单个容器
  • 可以使用 docker container rm 来删除一个处于终止状态的容器。
docker container rm ubuntu:16.04

如果要删除一个运行中的容器,可以添加 -f 参数。Docker会发送 SIGKILL 信号给容器。

ii. 清理所有处于终止状态的容器
  • docker container ls -a 命令可以查看所有已经创建的包括终止状态的容器,如果数量太多要一个个删除可能会很麻烦,用下面的命令可以清理掉所有处于终止状态的容器。
docker container prune

1.1.4 利用Dockerfile构建私有镜像

1. 使用Dockerfile定制镜像

  • 镜像的定制实际上就是定制每一层所添加的配置、文件。我们可以把每一层修改、安装、构建、操作的命令都写入一个脚本,这个脚本就是Dockerfile。
  • Dockerfile是一个文本文件,其内包含了一条条的指令,每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。
  • 下面以官方Nginx镜像为例,使用Dockerfile来定制。

  • 在一个空白目录中,建立一个文本文件,并命名为Dockerfile:
mkdir mynginx
cd mynginx
touch Dokerfile

其内容为

FROM nginx
RUN echo '<h1>Hello,Docker!</h1>' > /usr/share/nginx/html/index.html
1)FROM指定基础镜像
  • 所谓定制镜像,一定是以一个镜像为基础,在其上进行定制。其基础镜像是必须指定,而FROM就是指定基础镜像,因此一个Dockerfile中FROM是必备的指令,并且必须是第一条指令。在DockerHub上有非常多的高质量的官方镜像,有可以直接拿来使用的服务类的镜像,如nginx、redis、mysql、tomcat等;可以在其中寻找一个最符合我们最终目标的镜像为基础镜像进行定制。
  • 如果没有找到对应服务的镜像,官方镜像中还提供了一些更为基础的操作系统镜像,如ubuntu、debian、centos、alpine等,这些操作系统的软件库为我们提供了更广阔的的扩展空间。
  • 除了选择现有镜像为基础镜像外,Docker还存在一个特殊的镜像,名为scratch。这个镜像是虚拟的概念,并不实际存在,它表示一个空白的镜像。
FROM scratch
  • 如果你以scratch为基础镜像的话,意味着你不以任何镜像为基础,接下来所写的指令将作为镜像第一层开始存在。
  • 对于Linux下静态编译的程序来说,并不需要有操作系统提供运行时支持,所需的一切库都已经在可执行文件里了,因此直接FROM scratch会让镜像体积更加小巧。使用Go语言开发的应用很多会使用这种方式来制作镜像,这也是为什么有人认为Go是特别适合容器微服务架构的语言的原因之一。
2) RUN执行命令
  • RUN指令是用来执行命令行命令的。由于命令行的强大能力,RUN指令在定制镜像时是最常用的指令之一。其格式有两种:
  1. shell格式:RUN <命令>
RUN echo '<h1>Hello,Docker!</h1>' > /usr/share/nginx/html/index.html
  1. exec格式:RUN [“可执行文件”,“参数1”,“参数2”]
RUN tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1
RUN make -C /usr/src/redis
RUN make -C /usr/src/redis install

2. 构建镜像

  • 上面我们利用Dockerfile定制了nginx镜像,现在我们明白了这个Dockerfile的内容,接下来我们构建这个镜像。在Dockerfile文件所在目录执行:
docker build -t nginx:v3 .

从命令的输出结果中,我们可以清晰的看到镜像的构建过程。在Step2中,RUN指令启动了一个容器9cdc27646c7b,执行了所要求的命令,并最后提交了这一层44aa4490ce2c,随后删除了所用到的这个容器9cdc27646c7b。

3. Dockerfile指令详解

  • 我们已经介绍了FROM,RUN,其实Dockerfile功能很强大,他提供了十多个指令。
1) COPY复制文件
  • 格式:

    • COPY<源路径>…<目标路径>
    • COPY["<源路径1>",…,"<目标路径>"]
  • COPY指令将从构建上下文目录中<源路径>的文件/目录复制到新的一层的镜像内的<目标路径>位置。比如:
COPY package.json /usr/src/app/
  • <源路径>可以是多个,甚至可以是通配符,如:
COPY hom* /mydir/
COPY hom?.txt /mydir/
2) ADD更高级的复制文件
  • ADD指令和COPY的格式和性质基本一致。但是在COPY基础上增加了一些功能。
  • 比如<源路径>可以是一个URL,这种情况下,Docker引擎会试图去下载这个链接的文件放到<目标路径>去。
  • 在Docker官方的Dockerfile最佳实践文档中要求,尽可能的使用COPY,因为COPY的语义很明确,就是复制文件而已,而ADD则包含了更复杂的功能,其行为也不一定很清晰。最适合使用ADD的场合,就是所提及的需要自动解压缩的场合。
  • 因此在COPY和ADD指令中选择的时候,可以遵循这样的原则,所有的文件复制均使用COPY指令,仅在需要自动解压缩的场合使用ADD。
3)CMD容器启动命令
  • CMD指令的格式和RUN相似,也是两种格式:

    • shell格式:CMD<命令>
    • exec格式:CMD [“可执行文件”,“参数1”,“参数2”…]
    • 参数列表格式: CMD [“参数1”,“参数2”…]。指定了ENTRYPOINT指令后,用CMD指定具体的参数。
  • Docker不是虚拟机,容器就是进程。既然是进程,name在启动容器的时候,需要指定所运行的程序及参数。CMD指令就是用于指定默认的容器主进程启动命令的。
4)ENTRYPOINT入口点
  • ENTRYPOINT的目的和CMD一样,都是在指定容器启动程序及参数。ENTRYPOINT在运行时也可以替代,不过比CMD要略显繁琐,需要通过docker run的参数–entrypoint来指定
  • 当指定了ENTRYPOINT后,CMD的含义就发生了改变,不再是直接的运行其命令,而是将CMD的内容作为参数传给ENTRYPOINT指令,换句话说实际执行时,将变为:
<ENTRYPOINT> "<CMD>"
5)ENV设置环境变量
  • 格式有两种:

    • ENV <key><value>
    • ENV <key1>=<value1> <key2><value2>…
  • 这个指令很简单,就是设置环境变量而已,无论是后面的其他指令,如RUN,还是运行时的应用,都可以直接使用这里定义的环境变量。
ENV VERSION=1.0 DEBUG=on NAME="Happy Feet"
$VERSION #使用环境变量,即可获得版本号
  • 下面指令可以支持环境变量展开:ADD、COPY、ENV、EXPOSE、LABEL、USER、WORKDIR、VOLUME、STOPSIGNAL、ONBUILD
6)ARG构建参数
  • 格式:

    • ARG <参数名>[=<默认值>]
  • 构建参数和ENV的效果一样,都是设置环境变量。所不同的是,ARG所设置的构建环境的环境变量,在将来容器运行时是不会存在这些环境变量的。但是不要因此就使用ARG保存密码之类的信息,因为docker history还是可以看到所有值的。
  • Dockerfile中ARG指令是定义参数名称,以及定义其默认值。该默认值可以在构建命令docker build中用 --build-arg<参数名>=<值>来覆盖。
7)VOLUME定义匿名卷
  • 格式为:

    • VOLUME ["<路径1>","<路径2>"…]
    • VOLUME <路径>
  • 容器运行时应该尽量保持容器存储层不发生写操作,对于数据库类需要保存动态数据的应用,其数据库文件应该保存于卷(VOLUME)中,为了防止运行时用户忘记将动态文件所保存目录挂载为卷,在Dockerfile中,我们可以事先指定某些目录挂载为匿名卷,这样在运行时如果用户不指定挂载,其应用也可以正常运行,不会像容器存储层写入大量数据
VOLUME /data
  • 这里的/data目录就会在运行时自动挂载为匿名卷,任何向/data中写入的信息都不会记录进容器存储层,从而保证了容器存储层的无状态化。当然,运行时可以覆盖这个挂载设置。比如:
docker run -d -v mydata:/data xxxx
  • 在这行命令中,就使用了mydata这个命名卷挂载到了/data这个位置,替代了Dockerfile中定义的匿名的挂载配置。
8)EXPOSE声明端口
  • 格式为:

    • EXPOSE <端口1>[<端口2>…]
  • EXPOSE指令是声明运行时容器提供服务端口,这只是一个声明,在运行时并不会因为这个声明应用就会开启这个端口的服务。
  • 在Dockerfile中写入这样的声明有两个好处:
    1. 是帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射;
    2. 在运行时随机端口映射时,也就是docker run -P时,会自动随机映射EXPOSE的端口。
9)WORKDIR指定工作目录
  • 格式为:

    • WORKDIR <工作目录路径>
  • 使用WORKDIR指令可以来指定工作目录(或者称为当前目录),以后各层的当前目录就被改为指定的目录,如该目录不存在,WORKDIR会帮你建立目录。
  • 之前提到一些初学者常犯的错误是把Dockerfile等同于shell脚本来书写,这种错误的理解还可能会导致出现下面这样的错误:
RUN cd /app
RUn echo "hello" > world.txt
  • 如果将这个Dockerfile进行构建镜像运行后,会发现找不到/app/world.txt文件。
  • 在Shell中,连续两行是同一个进程执行环境,因此前一个命令修改的内存状态,会直接影响后一个命令
  • 而在Dockerfile中,这两行RUN命令的执行环境根本不同,是两个完全不同的容器。这就是对Dockerfile构建分层存储的概念不了解所导致的错误。
  • 每一个RUN都是启动一个容器、执行命令、然后提交存储层文件变更。
  • 第一层RUN cd /app的执行仅仅是当前进程的工作目录变更,一个内存上的变化而已,其结果不会造成任何文件变更。而到第二层的时候,启动的是一个全新的容器,跟第一层的容器更完全没关系,自然不可能继承前一层构建过程中的内存变化。
  • 因此如果需要改变以后各层的工作目录的位置,那么应该使用WORKDIR指令。
10)USER指定当前用户
  • 格式为:

    • USER <用户名>
  • USER指令和WORKDIR指令相似,都是改变环境状态并影响以后的层。WORKDIR是改变工作目录,USER则是改变之后层的执行RUN,CMD以及ENTRYPOINT这类命令的身份。
  • 当然,和WORKDIR一样,USER只是帮助你切换到指定用户而已,这个用户必须是事先建立好的,否则无法切换。
RUN groupadd -r redis && useradd -r -g redis redis
USER redis
RUN ["redis-server"]
11)HEALTHCHECK健康检查
  • 格式为:

    • HEALTHCHECK [选项] CMD <用户名>:设置检查容器健康状况的命令
    • HEALTHCHECK NONE:如果基础镜像有健康检查指令,可以屏蔽掉其健康检查指令
  • HEALTHCHECK指令是告诉Docker应该如何进行判断容器的状态是否正常,这是Docker1.12引入的新指令。通过该指令指定一行命令,用这行命令来判断容器主进程的服务状态是否还正常,从而比较真实的反应容器实际状态。
  • 一个镜像制定了HEALTHCHECK指令后,用其启动容器,初始状态会为starting,在执行健康检查成功后变为healthy,如果连续一定次数失败,则会变为unhealthy。
  • HEALTHCHECK支持下列选项
    • –interval=<间隔>:两次健康检查的间隔,默认为30秒;
    • –timeout=<时长>:健康检查命令运行超时时间,如果超过这个时间,本次健康检查就被视为失败,默认30秒;
    • –retries=<次数>:当连续失败指定次数后,则将容器状态视为unhealthy,默认3次。
  • 为了帮助排障,健康检查命令的输出(包括stdout以及stderr)都会被存储于健康状态里,可以用docker inspect来查看。
12)ONBUILD为他人做嫁衣
  • 格式为:

    • ONBUILD <其它指令>
  • ONBUILD是一个特殊的指令,它后边跟的是其它指令,比如RUN,COPY等。而这些指令,在当前镜像构建时并不会被执行。只有当以当前镜像为基础镜像,区构建下一级镜像的时候才会被执行。
  • Dockerfile中的其它指令都是为了定制当前镜像而准备的,唯有ONBUILD是为了帮助别人定制自己而准备的。

4. 其它制作镜像方式

1)docker save和docker load
  • Docker还提供了docker save和docker load命令,用以将镜像保存为一个tar文件,然后传输到另一个位置上,在加载进来。这是在没有Docker Registry时的做法,现在已经不推荐了,镜像迁移应该直接用Docker Registry,无论是直接使用Docker Hub还是使用内网私有Registry都可以。
  • 例如:保存Nginx镜像
docker save nginx | gzip > nginx-latest.tar.gz
  • 然后我们将nginx-latest.tar.gz文件复制到了另一个机器上,再次加载镜像:
docker load -i nginx-latest.tar.gz

1.1.5 Docker运行Java程序

1. 定制镜像

  • 准备一个没有第三方依赖的java web项目,可以参考示例maven结构项目session-web-0.0.1-SNAPSHOT.war
  • 把该war上传到安装有docker软件的服务器上宿主目录下。在同级目录下创建Dockerfile
touch Dockerfile
vim Dockerfile
  • 按照前面章节所学的Dockerfile定制镜像知识来编写Dockerfile文件内容,文件内容如下:
#基础镜像使用tomcat:7.0.88-jre8
FROM tomcat:7.0.88-jre8
#作者(可选)
MAINTAINER allen <allen@163.com>
#定义环境变量
ENV TOMCAT_BASE /usr/local/tomcat
#复制war包
COPY ./session-web.war $TOMCAT_BASE/webapps/
  • 执行构建(放在当前目录.)
docker build -t session-web:latest .
  • 如果构建成功,则会显示构建的分层信息及结果。

  • 构建成功后使用docker images命令查看本地是否有该镜像

2. 运行镜像

  • 镜像制作好之后我们就需要把它运行起来了
docker run --name session-web -d -p 8888:8080 session-web:latest
  • 其中8888是宿主机的端口,8080是docker的端口
  • 启动后使用 netstat -na | grep 8888 验证端口是否在监听状态
  • 浏览器中访问 http://ip:8888/session-web/user/login

1.1.6 搭建Docker私有仓库

1. Docker Hub

  • 目前Docker官方维护了一个公共仓库Docker Hub,其中已经包括了数量超过15,000的镜像。大部分需求都可以通过在Docker Hub中直接下载镜像来实现。
1)注册登录及退出
  • 可以在https://hub.docker.com免费注册一个Docker账号。
  • 在命令行界面执行 docker login 输入用户名及密码来完成在命令行界面登录Docker Hub。
  • 可以通过 docker logout 退出登录
2)拉取镜像
  • 可以通过 docker search 命令来查找官方仓库中的镜像,并利用docker pull命令来将它下载到本地。
3)推送镜像
  • 用户也可以在登录后通过 docker push 命令来将自己的镜像推送到Docker Hub。

2. 私有仓库

  • 有时候使用Docker Hub这样的公共仓库可能不方便,用户可以创建一个本地仓库供私人使用。比如,基于公司内部项目构建的镜像。
  • docker-registry 是官方提供的工具,可以用于构建私有的镜像仓库。
1)安装运行docker-registry
  • 可以通过获取官方registry镜像来运行。默认情况下,仓库会被创建在容器的 /var/lib/registry目录下。
  • 可以通过 -v 参数来将镜像文件存放在本地的指定路径。
docker run --name registry -d -p 5000:5000 --restart=always -v /opt/data/registry:/var/lib/registry registry
2)在私有仓库上传、搜索、下载镜像
  • 创建好私有仓库之后,就可以使用 docker tag 来标记一个镜像,然后推送它到仓库。
  • 现在本机查看已有的镜像。
docker image ls
  • 使用 docker tag 将session-web:latest这个镜像标记为127.0.0.1:5000/session-web:latest
  • 格式为 docker tag IMAGE[:TAG] [REGISTRY_HOST[:REGISTRY_PORT]/]REPOSITORY[:TAG]
docker tag session-web:latest 127.0.0.1:5000/session-web:latest
  • 使用 docker push 上传标记的镜像
docker push 127.0.0.1:5000/session-web:latest
  • 用curl查看仓库中的镜像
curl 127.0.0.1:5000/v2/_catalog

如果可以看到{“repositories”:[“session-web”]},表明镜像已经被成功上传了。

  • 先删除已有镜像,再尝试从私有仓库中下载这个镜像。
docker image rm 127.0.0.1:5000/session-web:latest
docker pull 127.0.0.1:5000/session-web:latest
3)注意事项
  • 如果你不想使用127.0.0.1:5000作为仓库地址,比如想让本网段的其他主机也能把镜像推送到私有仓库。你就得把例如 192.168.100.100:5000这样的内网地址作为私有仓库地址,这时你会发现无法成功推送镜像。
  • 这时因为Docker默认不允许非HTTPS方式推送镜像。我们可以通过Docker的配置选项来取消这个限制。
Ubuntu 16.04+、Debian 8+、centos 7
  • 对于使用systemd的系统,请在/etc/docker/daemon.json中写入如下内容(如果文件不存在请新建该文件)
{"registry-mirrors":["https://registry.docker-cn.com"],"insecure-registries":["192.168.100.100:5000"]
}
Windows、Mac
  • 对于Docker for Windows、Docker for Mac 在设置中编辑daemon.json增加和上边一样的字符串即可
{"registry-mirrors":["https://registry.docker-cn.com"],"insecure-registries":["192.168.100.100:5000"]
}

第三节 网易Docker最佳实践

1.3.1 容器监控

1. 概述

  • 前面章节讲过了使用docker compose组合应用并利用scale快速对容器进行扩容。
  • 由于docker compose启动的服务都在同一台宿主机上,对于一个宿主机上运行多个容器应用时,容器的运行情况如:CPU使用率、内存使用率、网络状态、磁盘空间等一系列随时间变化的时序数据信息,都是需要去了解的,因此监控是必须的。

2. 容器监控方案选择

  • 对于容器的监控方案可谓多种多样,本身自带命令docker stats命令,Scout,Data Dog,Sysdig Cloud,Sensu Monitoring Framework,CAdvisor等。
  • 通过docker stats命令可以很方便的看到当前宿主机上所有容器的CPU,内存以及网络流量等数据。但是docker stats命令的缺点就是统计的只是当前宿主机的所有容器,而获取的监控数据是实时的,没有地方存储,也没有报警功能。
docker stats

- 而Scout、Sysdig Cloud、Data Dog虽然都提供了较完善的服务,但是它们都是托管的服务而且都收费,Sensu Monitoring Framework集成度较高,也免费,但是部署过于复杂。

  • 综合考虑,我们选择了CAdvisor做容器监控工具。
  • CAdvisor谷歌出品,优点是开源产品,监控指标齐全,部署方便,而且有官方的docker镜像。缺点是集成度不高,默认只在本地保存2分钟数据。不过可以加上 influxDB 存储数据,对接 Grafana 展示图表,比较便利地搭建好了容器监控系统,数据收集和图表展示效果良好,对系统性能也几乎没有什么影响。

3. CAdvisor

  • CAdvisor是一个容器资源监控工具,包括容器的内存,CPU,网络IO,磁盘IO等监控,同时提供了一个WEB页面用于查看容器的实时运行状态。CAdvisor默认存储2分钟的数据,而且只是针对单物理机。不过CAdvisor提供了很多数据集成接口,支持influxDB,Redis,Kafka,Elasticsearch等集成,可以加上对应配置将监控数据发往这些数据库存储起来。
  • CAdvisor功能主要有两点
    • 展示Host和容器两个层次的监控数据。
    • 展示历史变化数据。

4. InfluxDB

  • influxDB是用Go语言编写的一个开源分布式时序、事件和指标数据库,无需外部依赖。
  • 前面说到,CAdvisor默认只在本机保存最近2分钟的数据,为了持久化存储数据和统一收集展示监控数据,需要将数据存储到influxDB中。influxDB是一个时序数据库,专门用于存储时序相关数据,很适合存储CAdvisor的数据。而且,CAdvisor本身已经提供了influxDB的集成方法,在启动容器时指定配置即可。
1)主要功能
  • 基于时间序列,支持与时间有关的相关函数(如最大,最小,求和等);
  • 可度量性:你可以实时对大量数据进行计算;
  • 基于事件:它支持任意的事件数据;
2)主要特点
  • 无结构(无模式);
  • 可以是任意数量的列;
  • 可拓展的;
  • 支持min,max,sum,count,mean,median等一系列函数,方便统计;
  • 原生的HTTP支持,内置HTTP API;
  • 强大的类SQL语法;
  • 自带管理界面,方便使用

5. Granfana

  • Grafana是一个开源的数据监控分析可视化平台,支持多种数据源配置(支持的数据源包括influxDB,MySQL,Elasticsearch,OpenTSDB,Graphit等)和丰富的插件及模板功能,支持图表权限控制和报警。
主要特性
  • 灵活丰富的图形化选项
  • 可以混合多种风格
  • 支持白天和夜间模式
  • 多个数据源

6. CAdvisor + InfluxDB + Grafana

  • CAdvisor:负责收集容器的随时间变化的数据
  • influxDB:负责存储时序数据
  • Grafana:负责分析和展示时序数据

7.安装部署

  • 单独部署
  • 使用compose部署(推荐)
1)部署InfluxDB服务
docker run -d --name influxdb -p 8086:8086 -v /data/influxdb:/var/lib/influxdb --hostname=influxdb influxdb
  • 说明:

    • –name:启动容器分配名字influxdb
    • -p:映射端口,8083端口为influxdb管理端口,8086端口是influxdb的数据端口
    • -v:挂载数据
    • -d:后台运行此容器
    • influxdb:通过这个容器来运行的,默认会在docker官方仓库pull下来
  1. 浏览器访问influxdb的管理端,http://ip:8083

  2. 创建test的数据库与root用户,这个用于后期配grafana

docker exec -it influxdb influxCREATE DATABASE "test"
CREATE USER "root" WITH PASSWORD 'root' WITH ALL PRIVILEGES
2)部署CAdvisor服务
  • 谷歌的CAdvisor可以用于收集Docker容器的时序信息,包括容器运行过程中的资源使用情况和性能数据。
docker run --volume=/:/rootfs:ro --volume=/var/run:/var/run:ro --volume=/sys:/sys:ro --volume=/var/lib/docker/:/var/lib/docker:ro --volume=/dev/disk/:/dev/disk:ro --volume=/cgroup:/cgroup:ro --publish=8080:8080 --detach=true --privileged=true --name=cadvisor google/cadvisor:latest -storage_driver=influxdb -storage_driver_host=influxdb:8086 -storage_driver_db=test -storage_driver_user=root -storage_driver_password=root
  • 说明:

    • -d:后台运行此容器
    • –name:启动容器分配名字cadvisor
    • -p:映射端口8080
    • –mount:把宿主机的相关目录绑定到容器中,这些目录都是CAdvisor需要采集的目录文件和监控内容
    • -storage_driver:需要指定CAdvisor的存储驱动、数据库主机、数据库名
  • 通过ip+8080端口访问测试一下,第一次访问页面有点慢

3)部署Grafana服务
  • grafana是一款开源的时序数据分析工具,而且界面专业易用。
docker run -d -p 3000:3000 -v /data/grafana:/var/lib/grafana --link=influxdb:influxdb --name grafana grafana/grafana
  • 注意:如果使用 -v 把数据挂载出来会出现容器启动失败,错误为mkdir:cannot create directory ‘/var/lib/grafana/plugins’:Permission denied,此时可以使用 docker run --entrypoint "id" grafana/grafana得到uid,gid,groups(默认是472);
  • 接着使用 chown -R 472:472 /data/grafana/ 修改目录权限就可以启动成功了。
  1. 通过ip+3000端口来访问Grafana的web服务,第一次访问需要修改admin用户密码,默认用户名/密码为admin/admin
4)docker-compose快速部署
version: '3.1'volumes:grafana_data: {}services:influxdb:image: tutum/influxdb:0.9#image: tutum/influxdb#image: influxdbrestart: always#user: environment:- PRE_CREATE_DB=cadvisorports:- "8083:8083"- "8086:8086"expose:- "8090"- "8099"volumes:- ./data/influxdb:/datacadvisor:#image: google/cadvisor:v0.29.0image: google/cadvisorlinks:- influxdb:influxsrvcommand: -storage_driver=influxdb -storage_driver_db=cadvisor -storage_driver_host=influxsrv:8086restart: alwaysports:- "8080:8080"volumes:- /:/rootfs:ro- /var/run:/var/run:rw- /sys:/sys:ro- /var/lib/docker/:/var/lib/docker:rografana:#image: grafana/grafana:2.6.0user: "104"image: grafana/grafanauser: "104"#user: "472"restart: alwayslinks:- influxdb:influxsrvports:- "3000:3000"volumes:- grafana_data:/var/lib/grafanaenvironment:- HTTP_USER=admin- HTTP_PASS=admin- INFLUXDB_HOST=influxsrv- INFLUXDB_PORT=8086- INFLUXDB_NAME=cadvisor- INFLUXDB_USER=root- INFLUXDB_PASS=root
  • 使用浏览器访问 ip+3000 端口可以访问Grafana的管理页面

  • 使用浏览器访问 ip+8083 端口可以访问InfluxDB的管理页面

  • 使用浏览器访问 ip+8088 端口可以访问CAdvisor的管理页面

  • 在Grafana中添加数据源,需要修改url

  • 然后填写数据库名以及用户名密码

  • 添加图表

1.3.2 日志监控

1. Docker日志

1)日志处理机制
  • 当启动一个容器的时候,它其实是docker daemon的一个子进程,docker daemon可以拿到容器里面进程的标准输出,拿到标准输出后,它会通过自身的一个LogDriver模块来处理,LogDriver支持的方式很多,可以写到本地的文件(默认方式),可以发送到syslog等
  • Docker会默认收集应用程序的标准输出存储到一个json.log文件中,文件的格式类似下面这种:
  • 以一行一个作为一条JSON数据存储。Docker的这种日志存储方式是可以配置的,具体参数可以在执行run启动容器的时候通过log-driver进行配置,具体配置请参考log-driver。
2)Docker Logging Driver
  • 以下是Docker支持的Logging Driver
  • Docker默认使用了json-file driver作为log driver,而gelf则是我们需要使用的log driver。
  • 当容器多了,或者是采用类似swarm集群部署Docker的时候,各种日志分散存在各个json.log文件中,当查找问题或者进行相关统计的时候,分散的日志对我们来说是非常不友好的。我们需要一个能够集中管理Docker日志的工具,这也是本章节学习的重点。

2. Graylog

  • graylog和ELK非常相似,属于后起之秀。ELK是个强大的日志栈架构。
  • 为何选择graylog来作为Docker的日志收集平台呢?
    • Docker原生支持graylog协议,直接将日志发送到graylog(通过gelf协议)
    • graylog官方提供了将本身部署在Docker的支持
1)Graylog部署
  • graylog官方提供了Dockerfile供我们快速的在Docker上部署日志系统,在这个DockerHub的地址中,也提供了docker-compose.yml来快速部署整个graylog栈,包含了MongoDB、ElasticSearch,而不需要分别单独部署。
  • 官方地址:https://hub.docker.com/r/graylog/graylog
  1. 创建一个目录用来部署graylog,本文假设目录为/root/graylog,以下所有操作都是在/root/graylog中进行的。
  2. 初始化目录和配置文件
#创建数据目录
mkdir -p ./graylog/data
#创建配置文件目录
mkdir -p .graylog/config
cd ./graylog/config
#直接下载官方推荐配置文件
wget https://raw.githubusercontent.com/Graylog2/graylog-docker/2.5/config/graylog.conf
#日志配置文件
wget https://raw.githubusercontent.com/Graylog2/graylog-docker/2.5/config/log4j2.xml
  1. 修改下载完的graylog.conf中的root_timezone为GMT+0800中国时区
root_timezone=Etc/GMT-8 #改为Asia/Shanghai
  1. 新建docker-compose.yml来供docker-compose快速启动完整服务

注:由于docker-compose内容较多,以附件形式展示。
部分组件可能pull有问题,可以替换成官方库,如:elasticsearch:6.8.1

  1. 启动整个服务
docker-compose up
  • 如果没有问题的话,会看到graylog webserver started的终端输出消息。
  • 访问http://{server}:9000会看到graylog的web页面,使用用户名/密码admin来登录后台,至此部署完成。

注意:graylog在root用户下,使用github上下载的docker-compose.yml启动时出现Operation not permitted错误

解决方法:这个问题是由于graylog官方Dcokerfile里面写了:
GRAYLOG_UID=1100 GRAYLOG_GROUP=graylog GRAYLOG_GID=1100
这样导致在挂载目录的时候内部容器会使用1100的用户权限去执行,但是我们是使用的root用户创建的文件夹和文件,1100并不存在宿主机。就会出现Operation not permitted 没有权限问题;
解决办法很简单:在宿主机上把conf文件夹及子文件权限改为1100,在graylog目录下执行:chown -R 1100:1100 conf
后期老师会跟进这个问题,看官方有没有解决方案

2)Graylog系统配置
i. input配置
  • graylog的日志收集通过定义input对象来完成,在graylogweb管理界面按照如下图片进入input对象配置,选择GELF UDP协议来新建一个输入器(input):
  • 填好相关属性,新建:
  • 保存后,就可以开始收集日志了
ii. docker配置
  • 如果docker通过命令行启动,可以在run命令中加上如下参数:
docker run --log-driver=gelf --log-opt gelf-address=udp://{greylog服务器地址}:12201 --log-opt tag=<当前容器服务标签,用来供greylog查询的时候进行分类> <IMAGE> <运行命令>
  • 如果通过docker-compose命令,则可以在docker-compose.yml中加入相关配置,以下用nginx容器举例:
version: '2'
services:nginx:image: nginx:latestports:- "80:80"logging:driver:"gelf"options:gelf-address: "udp://192.168.100.249:12201" #日志服务器iptag: front-nginx
  • 容器启动的时候可能会有下面这个提示:
    nginx_1_4db0934b4b62 | WARNING:no logs are available with the 'gelf' log driver
  • 可以无视这个警告,日志还是会继续发送过去的。

1.3.3 Docker Swarm资源管理

1. Docker Swarm介绍

  • Docker Swarm是Docker官方三剑客项目之一,提供Docker容器集群服务,是Docker官方对容器云生态进行支持的核心方案。
  • 使用它,用户可以将多个Docker主机封装为单个大型的虚拟Docker主机,快速打造一套容器云平台。

注意:Docker 1.12.0+ Swarm mode 已经内嵌如Docker引擎,成为了docker子命令docker swarm,绝大多数用户已经开始使用Swarm mode,Docker引擎API已经删除Docker Swarm。

2. 基本概念

  • Swarm是使用SwarmKit构建的Docker引擎内置(原生)的集群管理和编排工具。
  • 使用Swarm集群之前需要了解一下几个概念。
1)节点
  • 运行Docker的主机可以主动初始化一个Swarm集群或加入一个已存在的Swarm集群,这样这个运行Docker的主机就成为一个Swarm集群的节点(node)。
  • 节点分为管理(manager)节点和工作(worker)节点。
  • 管理节点用于Swarm集群的管理,Docker Swarm命令基本只能在管理节点执行。
  • 工作节点是任务执行节点,管理节点将服务(service)下发至工作节点执行。
  • 集群中管理节点与工作节点的关系

2)服务和任务
  • 任务(Task)是Swarm中的最小的调度单位,目前来说就是一个单一的容器。

  • 服务(Services)是指一组任务的集合,服务定义了任务的属性。

  • 服务有两种模式:

    • replicated services 按照一定规则在各个工作节点上运行指定个数的任务。
    • global services 每个工作节点上运行一个任务
  • 两种模式通过docker service create的 --mode参数指定。

  • 容器、任务、服务的关系

3. 创建Swarm集群

  • 了解Swarm集群由管理节点和工作节点组成后,我们来创建一个包括一个管理节点和两个工作节点的最小Swarm集群。
1)初始化集群
  • 使用 docker swarm init 在本机初始化一个Swarm集群。
docker swarm init --advertise-addr 192.168.100.249
  • 如果你的Docker主机有多个网卡,拥有多个IP,必须使用 --advertise-addr指定IP。
  • 执行 docker swarm init 命令的节点自动成为管理节点。
2)增加工作节点
  • 在另外两台服务器上执行上一步创建管理节点时候的输出的加入swarm集群的命令
docker swarm join --token SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2e7c 192.168.100.249:2377

注意:防火墙问题可能会导致建立节点失败,可以开放端口或者关闭防火墙

3)查看集群
  • 在管理节点使用 docker node ls 查看集群。
docker node ls
4)升级工作节点为管理节点
  • 在管理节点使用以下命令
docker node promote [HOSTNAME]
  • 看到如下结果
  • 其中CentOS-02状态变为Reachable,意思是当CentOS-01退出Swarm或掉线后,CentOS-02会被选为管理节点。

4. 部署服务

  • 使用 docker service 命令来管理Swarm集群中的服务,该命令只能在管理节点运行。
1)新建服务
  • 在创建好的Swarm集群中运行一个名为nginx服务。
docker service create --replicas 3 -p 80:80 --name nginx nginx:latest
  • 现在使用浏览器,输入任意节点IP,即可看到nginx默认页面。
2)查看服务
  • 使用 docker service ls 来查看当前Swarm集群运行的服务。
docker service ls
  • 使用 docker service ps 来查看某个服务的详情。
docker service ps nginx
  • 使用 docker service logs 来查看某个服务的日志。
docker service logs nginx
3)删除服务
  • 使用 docker service rm 来从Swarm集群移除某个服务。
docker service rm nginx

5. 资源管理

  • 前面我们学过了利用Docker Swarm快速搭建一个最小集群,也可以在集群上部署服务,但是会发现swarm中并没有提供统一入口查看节点的资源使用情况。这个时候我们急切的希望有一个图形化管理工具来帮我们管理swarm集群,portainer就是这样一个工具
  • Portainer 是Docker的图形化管理工具,提供状态显示面板、应用模板快速部署、容器镜像网络数据卷的基本操作(包括上传下载镜像,创建容器等操作)、事件日志显示、容器控制台操作、Swarm集群和服务等集中管理和操作、登录用户管理和控制等功能。功能十分全面,基本能满足中小型单位对容器管理的全部需求。
1)portainer集群运行
  • 下载portainer镜像
#查询当前有哪些Portainer镜像
docker search portainer
docker pull portainer/portainer
  • 安装 portainer
docker run -d -p 9000:9000 --name portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer
2)portainer配置
  • 设置管理员账号

  • swarm集群资源使用情况

1.3.4 快速扩容

1. 命令方式

  • 在创建好的Swarm集群中运行一个名为nginx服务,并使用 --replicas 参数指定启动的副本数。
docker service create --replicas 3 -p 80:80 --name nginx nginx:latest
  • 或者使用 scale 命令
docker service create -p 80:80 --name nginx nginx:latest
docker service scale nginx=3
docker service ls   #查看副本情况

2. portainer方式

  • 可以使用potainer的方式在web界面上创建服务并指定副本数,同时可以随时动态增减副本数。


Docker容器入门及网易最佳实践相关推荐

  1. docker容器增加端口映射最佳实践(修改配置文件方式)

    前言: 在日常的docker运维中,经常遇到这样一个问题:已经配置好且运行的docker容器要根据业务需要增加端口映射到宿主机,如何简单有效的解决呢? 下面以mysql容器为例,详细说明操作步骤. 一 ...

  2. Knative 应用在阿里云容器服务上的最佳实践

    作者|元毅 阿里云智能事业群高级开发工程师 相信通过前面几个章节的内容,大家对 Knative 有了初步的体感,那么在云原生时代如何在云上玩转 Knative?本篇内容就给你带来了 Knative 应 ...

  3. 3.9 Docker最新入门教程-Docker入门-构建镜像最佳实践

    3.9 构建镜像最佳实践 安全扫描 构建镜像后,最好使用docker scan命令扫描它以查找安全漏洞.Docker 与Snyk合作提供漏洞扫描服务. 笔记 您必须登录到 Docker Hub 才能扫 ...

  4. java 8入门与实践_30个Java入门技巧和最佳实践

    java 8入门与实践 Java是最流行的编程语言之一-无论是Win应用程序,Web应用程序,移动,网络,消费电子产品,机顶盒设备,Java随处可见. 在Java上运行的设备超过30亿. 据Oracl ...

  5. 自动化集成:Docker容器入门简介

    前言:该系列文章,围绕持续集成:Jenkins+Docker+K8S相关组件,实现自动化管理源码编译.打包.镜像构建.部署等操作:本篇文章主要描述Docker基础用法. 一.Docker简介 1.基础 ...

  6. Docker 容器入门

    1.1 容器简介 1.1.1 什么是 Linux 容器 Linux容器是与系统其他部分隔离开的一系列进程,从另一个镜像运行,并由该镜像提供支持进程所需的全部文件.容器提供的镜像包含了应用的所有依赖项, ...

  7. 陌陌基于Kubernetes和Docker容器管理平台的架构实践

    为什么选择使用Kubernetes? 在使用Kubernetes之前,陌陌在应用发布和运行环境方面遇到的具体问题,如下: 应用发布时间很长,主要是因为发布过程中需要做隔离.恢复等动作,还需要登录查看实 ...

  8. Docker容器入门-基本命令的使用

    目前容器技术使用相当广泛 不会或者没有使用过容器感觉都不像是个搞技术的 所以,我也就docker相关内容做一个整理 只有不断的学习,才能保持自己的竞争力 什么是容器? 容器是一种轻量级.可移植.自包含 ...

  9. 探索云原生技术之基石-Docker容器入门篇(3)

    ❤️

最新文章

  1. c语言组队,组队列问题。会做的高手帮帮忙啊
  2. redis(3)redis的基础入门(java)
  3. 混合云应用双活容灾实践
  4. uboot更改gpio电平_ECBM系列教程4:单片机的手和脚——GPIO
  5. php baocuo error,PHP编译报错configure: error: Cannot find libmysqlclient under /usr.
  6. 电商主题BANNER传统促销喜庆红色节日海报,C4D打造时尚场景
  7. 有了这些字体,才是高逼格的UI设计!
  8. BZOJ4458: GTY的OJ
  9. 学习的第一推动力(很好)
  10. “红孩儿”成中科院博士!做CTO身价过亿!
  11. SQL语言基础-数据查询
  12. NT、Novell、Unix服务器的互连
  13. python语言是不是多模型语言_Python模型转换为Modelica模型的方法与流程
  14. Openlayers:Polygon绘图工具
  15. 关于__declspect(dllexport) 和 __declspec(dllimport)的使用
  16. 服务器中使用Top命令后,参数解释
  17. 哪几款蓝牙耳机音质最好?音质好的蓝牙耳机测评
  18. 中国高端装备行业供需形势及投资策略建议报告2021-2027年版
  19. Nssm 安装Window服务
  20. PHP 设计模式之最全面,最简单的讲解

热门文章

  1. [AHK]给联想E47笔记本触摸板设定热键开关,免得误碰。
  2. 投资理财那些事-资产配置
  3. 滴滴拼车变绿:下沉、烧钱、焦虑
  4. 深入浅出kafka原理-5-kafka同步副本ISR高低水位HW
  5. 金蝶eas显示连接服务器超时,金蝶EAS常见问题解答_工具及框架应用_2016
  6. 微信小程序上传单张或多张图片
  7. 头歌--C++之函数进阶练习题
  8. 抖音神曲是如何“造”出来的?
  9. 红图app的模式有未来吗?
  10. python-18-正则表达式