栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Docker 基础篇

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Docker 基础篇

1 Docker特点
  • Build, Ship and Run(搭建、运输、运行)

  • Build once,Run anywhere(一次搭建,到处运行)

  • 解决了运行环境和配置问题的软件容器,方便做持续集成并有助于整体发布的容器虚拟化技术

2 容器部署发展简史

互联网企业生产环境的应用部署所经历的过程,大致可分三个阶段:

  • 物理机部署
  • 虚拟机部署
  • 容器化部署
2.1 物理机部署

2.1.1 特点

一台服务器,部署多个应用进程。

2.1.2 痛点

资源共享问题:进程间资源抢占。如果某个进程耗用了100%的CPU资源,其他的进程就无法提供服务。又或者一个进程产生的日志把磁盘打满了,那所有的进程都会挂掉。

2.1.3 解决方式

进程间硬件资源隔离。

2.2 虚拟机部署

2.2.1 特点

虚拟机通过硬件虚拟化,即每台虚拟机事先从物理机分配好cpu核数,内存, 磁盘,每台虚拟机一般只部署一个应用。从而解决了进程间资源隔离的问题。

2.2.2 痛点

集群部署的情况下,软件的版本和配置文件容易碎片化:应用集群的虚拟机第一次安装时,由于操作系统镜像是一样的,所以刚开始,软件的版本和库依赖是统一的。但随着时间的推移,开源的软件(tomcat, jdk, nginx)需要逐步升级,于是运维同学开始批量升级集群的软件版本,批量升级可能有遗漏或升级失败。同时有些开发同学会自己登陆机器修改软件的版本或者配置,以满足自己的需求。长此以往,一个应用集群的虚拟机的软件版本和配置逐渐碎片化。当线上出现问题,需要排查到基础软件层面时,由于软件版本碎片化的问题,就会导致排查变得很棘手。

2.2.3 解决方式

容器技术

2.3 容器化部署

2.3.1 特点

容器技术不限于docker,但是docker目前最为流行,此处以docker为例。docker容器技术的核心之一在于镜像文件。

2.3.2 镜像文件

镜像文件:通俗的理解就是一个进程运行时依赖的软件文件的集装箱。
镜像文件的用处:应用集群部署时,每台机器首先会拉取指定版本的镜像文件。安装镜像后产生了docker容器。由于所有机器的镜像文件一样,容器的软件版本也一样。即使开发或运维中途修改了容器的软件版本,但是容器销毁时,软件的改动会随容器的销毁一起湮灭。当应用用已有的镜像文件重新部署时,生成的docker容器跟修改之前的容器完全一样。容器如果要升级软件版本,那就修改镜像文件。这样部署时集群内所有的机器重新拉取新的镜像,软件因此跟着一起升级。软件版本混乱的问题,到docker这里,也就得到了完美的解决。

2.3.3 一个小问题
  • 有了容器技术,生产环境为何还需要部署虚拟机?

因为虚拟机能做到硬件资源的彻底隔离,docker不行。

2.3.4 小总结
  • 传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整的操作系统,在该系统上再运行所需的应用进程;

  • 容器内的应用进程直接运行于宿主的内核,容器没有自己的内核也没有进行硬件虚拟。因此要比传统虚拟机更为轻便,启动速度更快;

  • 每个容器之间相互隔离,每个容器有自己的文件系统,容器之间进程不会相互影响,能区分计算资源。

3 Docker官网
  • Docker官网:https://www.docker.com
  • Docker Hub官网(安装docker镜像的仓库):https://hub.docker.com
4 Docker的基本组成

4.1 镜像(image)
  • docker镜像(image)就是一个只读的模板,镜像可以用来创建docker容器,一个镜像可以创建很多容器。

  • 相当于容器的“源代码”,docker镜像文件类似于Java的类模板,而docker容器实例类似于java中new出来的实例对象。

4.2 容器(container) 4.2.1 从面向对象角度理解

docker利用容器(container)独立运行的一个或一组应用,应用程序或服务运行在容器里面,容器就类似于一个虚拟化的运行环境,容器是使用镜像创建的运行实例。

镜像是静态的定义,容器是镜像运行时的实体。

容器为镜像提供了一个标准的和隔离的运行环境,它可以被启动、停止、删除。每个容器都是相互隔离的,保证安全的平台。

4.2.2 从镜像容器角度理解

可以把容器看作是一个简易版的Linux环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。

4.3 仓库(repository)
  • 仓库是集中存放镜像文件的场所。类似于存放jar包的maven仓库、存放git项目的github等等。

仓库分为公开仓库(Public)和私有仓库(Private)两种形式。

最大的公开仓库也是docker公司提供的官方仓库:Docker Hub,国内的公开仓库包括阿里云等。

5 Docker安装 5.1 注意事项
  • docker并非是一个通用的容器工具,它依赖于已存在并运行的Linux内核环境。

docker实质上是在已经运行的Linux下制造了一个隔离的文件环境,因此它的执行效率几乎等同于所部署的Linux主机。

因此,docker必须部署在Linux内核的系统上,如果其他系统想部署docker就必须安装一个虚拟Linux环境。

注:docker在Windows上依赖WSL(可以理解为一个Windows专用的Linux虚拟机)

5.2 前提条件
  • 目前,CentOS仅发行版本中的内核支持docker。

操作系统要求:

1、CentOS 7或更高版本(存档或测试版本不支持)

2、必须启用CentOS Extras存储库。默认情况下,此存储库已启用,但如果已禁用,则需要 重新启用它。

3、建议使用存储驱动程序:overlay2

5.3 安装步骤
  • CentOS安装Docker引擎,官方文档:https://docs.docker.com/engine/install/centos/
5.3.1 查看操作系统版本
  • 查看操作系统版本,确定是CentOS 7或更高版本
# 查看CentOS的操作系统版本
# CentOS Linux release 7.9.2009 (Core)
cat /etc/redhat-release
5.3.2 卸载旧版本
  • 如果安装了旧版本,先卸载它们以及关联的依赖项

旧版本的引擎包或依赖项:docker、docker-engine

新版本的引擎包:docker-ce

sudo yum remove docker 
                docker-client 
                docker-client-latest 
                docker-common 
                docker-latest 
                docker-latest-logrotate 
                docker-logrotate 
                docker-engine
  • 上述操作只会删除docker本身,旧版本保存在/var/lib/docker/的内容,包括镜像、容器、卷和网络等会被保留。
5.3.3 安装GCC编译器相关
sudo yum -y install gcc
sudo yum -y install gcc-c++
5.3.4 设置stable镜像仓库
# 配置yum资源库
# 安装yum-config-manager
# yum-util提供yum-config-manager功能 
sudo yum install -y yum-utils

# 在yum资源库中添加docker资源库
# 官方地址(镜像在国外,下载比较慢,不推荐)
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# 阿里云镜像(推荐)
sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
5.3.5 更新yum软件包索引
# 重建软件包索引,建立缓存(可选操作,建议运行,据说后续安装会快一些)
yum makecache fast
5.3.6 安装Docker引擎
  • 默认安装最新版本
# docker-ce是Docker引擎,docker-ce-cli是客户端
# 默认安装的docker引擎、客户端都是最新版本
sudo yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin
  • 安装指定版本
# 在存储库中列出可用版本,然后选择安装
yum list docker-ce --showduplicates | sort -r

# 如下图,安装指定版本3:20.10.7-3.el7
# sudo yum install docker-ce- docker-ce-cli- containerd.io docker-compose-plugin
# VERSION_STRING:版本号,可用版本列表的第二列
sudo yum install docker-ce-17.09.0.ce docker-ce-cli-17.09.0.ce containerd.io docker-compose-plugin

5.3.7 启动Docker引擎
sudo systemctl start docker

# 启动后查看docker版本,可以看到Server: Docker Engine - Community(Docker守护进程)的版本号
docker version

5.3.8 运行hello-world测试
# 下载镜像hello-world:容器运行时,它会打印Hello from Docker!并退出
sudo docker run hello-world

5.3.9 卸载Docker步骤

1、关闭服务

systemctl stop docker

2、使用yum删除docker引擎

# 卸载 Docker 引擎、CLI、Containerd 和 Docker Compose 包
sudo yum remove docker-ce docker-ce-cli containerd.io docker-compose-plugin

3、删除镜像、容器、卷、自定义配置等文件

# 手动删除删除镜像、容器、卷、自定义配置等文件
sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd
6 配置镜像加速器(以阿里云为例) 6.1 镜像加速器的概念

由于docker的镜像需要从仓库拉取,这个仓库(dockerHub)在国内下载很慢,所以阿里云做了一个镜像加速功能,相当于把dockerHub的仓库拷贝了一份到国内,让国内用户方便下载。

6.2 配置步骤
  • 登录阿里云,进入 控制台 -> 容器镜像服务 -> 镜像工具 -> 镜像加速器
  • 里面提供了一个加速器地址:https://xxxxxxxx.mirror.aliyuncs.com
  • 将该地址配置到docker中:
# 通过修改daemon配置文件 /etc/docker/daemon.json 来使用加速器(初次使用是没有该文件的,直接新建文件即可)
vi /etc/docker/daemon.json

# daemon.json 文件内容
{
  "registry-mirrors": ["https://xxxxxxxx.mirror.aliyuncs.com"]  
}
  • 重载 daemon 程序刷新配置,重启docker
sudo systemctl daemon-reload
sudo systemctl restart docker
7 docker run的过程 8 为什么Docker会比VM虚拟机快 8.1 docker有着比虚拟机更少的抽象层

由于docker不需要实现硬件资源虚拟化,运行在docker容器上的程序都是直接使用实际物理机的硬件资源。因此在CPU、内存利用率上docker的效率有明显优势。

8.2 docker利用的是宿主机的内核,而不需要加载操作系统内核

当新建一个容器时,docker不需要和虚拟机一样重新加载一个操作系统内核。避免了引导、寻址、加载操作系统等比较费时费资源的过程。

当新建一个虚拟机时,虚拟机软件需要加载OS,这个过程耗时是分钟级的;而docker由于直接利用宿主机的操作系统,新建一个docker容器耗时只需几秒钟。

8.3 虚拟机与Docker容器对比
Docker容器虚拟机(VM)
操作系统与宿主机共享OS宿主机OS上运行虚拟机OS
存储大小镜像小,便于存储和传输镜像庞大
运行性能几乎无额外性能损失操作系统额外的CPU、内存消耗
移植性轻便、灵活,适应于Linux笨重,与虚拟化技术耦合度高
硬件亲和性面向软件开发者面向硬件运维者
部署速度快速,秒级较慢,10s以上
9 Docker常用命令 9.1 Docker命令图

9.2 帮助、启动类命令
# 启动docker
systemctl start docker
# 停止docker
systemctl stop docker
# 重启docker
systemctl restart docker
# 查看docker状态
systemctl status docker
# 设置开机启动
systemctl enable docker
# 查看docker版本信息
docker version
# 查看docker概要信息
docker info
# 查看docker总体帮助文档
docker --help
# 查看docker命令帮助文档
# 例:docker run --help
docker [COMMAND] --help
9.3 镜像命令 9.3.1 查看本地镜像列表
# 查看本地镜像列表
docker images
# 列出本地镜像中 REPOSITORY 为 ubuntu 的镜像列表
docker images ubuntu
# 列出本地所有的镜像(含中间映像层,默认情况下,过滤掉中间映像层)
docker images -a
# 只显示镜像ID
docker images -q
# 显示完整的镜像描述
docker images --no-trunc


# 同一仓库源可以有多个 TAG 版本,我们使用 REPOSITORY:TAG 来定义不同的镜像
# 如果不指定镜像的版本标签,默认使用最新版本。例如使用 ubuntu,docker 将默认使用 ubuntu:latest 镜像

  • 列说明
列列说明
REPOSITORY镜像的仓库源
TAG镜像的版本标签
IMAGE ID镜像ID
CREATED镜像创建时间
SIZE镜像大小
9.3.2 查找镜像
# 查找所有包含 ubuntu 的镜像
docker search ubuntu
# 查找所有包含 ubuntu,且 stars 大于10的镜像
docker search -f stars=10 ubuntu
# 只列出前5个镜像
docker search --limit 5 ubuntu

  • 列说明
列列说明
NAME镜像名称
DESCRIPTION镜像描述
OFFICIAL是否 docker 官方发布
STARS点赞数
AUTOMATED是否是自动构建的
9.3.3 拉取镜像
# docker pull 镜像名称[:tag]
# 不加tag时,默认下载最新的镜像(即tag为latest)
docker pull ubuntu
9.3.4 删除镜像
# docker rmi 镜像名称
docker rmi ubuntu
# docker rmi (IMAGE ID)
docker rmi ba6acccedd29
# 删除多个镜像,使用空格分隔:docker rmi 镜像1 镜像2 镜像3
docker rmi ubuntu redis
# 强制删除镜像(如果没有删除对应的容器,删除镜像会报错,此时是可以使用-f强制删除的)
docker rmi -f ubuntu
# 删除全部镜像
docker rmi -f $(docker images -qa)
9.3.5 虚悬镜像
  • 概念:仓库名、标签都是的镜像,俗称虚悬镜像(dangling image)
  • 产生原因:这些镜像原本是有镜像名和标签的,随着镜像的维护,发布了新镜像后,由于新旧镜像同名(仓库名、标签均相同),旧镜像名称被取消,从而出现仓库名、标签均为的镜像。这类无标签镜像被称为虚悬镜像
# 查看所有的虚悬镜像
docker images -f dangling=true
# 一般来说,虚悬镜像已经失去了存在的价值,是可以随意删除的
# 删除虚悬镜像
docker rmi $(docker images -q -f dangling=true)

9.4 容器命令 9.4.1 新建启动容器
# 新建+启动容器
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

启动交互式容器

# 前台交互式启动
# 使用 ubuntu 镜像以交互模式启动一个容器。在容器内执行 /bin/bash(或者bash) 命令
docker run --it ubuntu /bin/bash
docker run --it ubuntu bash
  • 退出交互模式

方式一:在交互shell中输入 exit 即可退回宿主机(这种方式退出后,容器会停止运行)

方式二:使用快捷键 CTRL + P + Q (这种方式退出后容器仍然在运行)

启动守护式容器

# 后台守护式启动
# 大部分情况下,我们的docker服务是在后台运行的,可以通过 -d 指定容器的后台运行模式
# docker run -d 容器ID或容器名称
docker run -d redis

# docker容器后台运行,必须有一个前台进程,这个是docker的机制
# 容器运行的命令如果不是那些一直挂起的命令(如:top、tail等),这样的容器在后台启动后会立即自杀(因为它觉得没事可做了),例如:
docker run -d ubuntu
  • OPTIONS说明

–name:为容器指定一个名称(不指定的话系统会随机生成一个名称)
-d:后台运行容器并返回容器ID,也即启动守护式容器
-i:以交互模式(interactive)运行容器,通常与-t同时使用
-t:为容器重新分配一个伪输入终端(tty),通常与-i同时使用。也即启动交互式容器(前台有伪终端,等待交互)
-e:为容器添加环境变量
-P:随机端口映射。将容器内暴露的所有端口映射到宿主机随机端口
-p:指定端口映射

  • -p参数说明
参数说明举例
-p hostPort:containerPort端口映射-p 8080:80
-p ip:hostPort:containerPort配置监听地址-p 192.0.0.1:8080:80
-p ip::containerPort随机分配端口-p 192.0.0.1::80
-p hostPort1:containerPort1 -p hostPort2:containerPort2指定多个端口映射-p 6379:6379 -p 3306:3306
9.4.2 列出正在运行的容器
# docker ps [OPTIONS]
# 列出当前所有正在运行的容器
docker ps
# 列出当前所有正在运行的容器+历史上运行过的容器
docker ps -a
# 列出当前所有正在运行的容器+历史上运行过的容器的前2条记录
docker ps -n 2
# 列出当前所有正在运行的容器的容器编号
docker ps -q
  • OPTIONS说明

-a:列出当前所有正在运行的容器+历史上运行过的容器
-l:显示最新创建的容器
-n (num):显示最近创建的前num个容器
-q:只显示容器编号

9.4.3 容器其他启动停止命令
# 启动已经停止的容器
# docker start 容器ID或容器名称
docker start 9e7190eae5bd

# 重启容器
# docker restart 容器ID或容器名称
docker restart redis

# 停止容器
# docker stop 容器ID或容器名称
docker stop 9e7190eae5bd

# 强制停止容器
# docker kill 容器ID或容器名称
docker kill 9e7190eae5bd

# 删除已停止的容器
# docker rm 容器ID或容器名称
docker rm 9e7190eae5bd
# 强制删除正在运行的容器
# docker rm -f 容器ID或容器名称
docker rm -f 9e7190eae5bd
# 一次删除所有容器实例(谨慎操作)
docker rm -f $(docker ps -a -q)
docker ps -a -q | xargs docker rm -f
9.4.4 查看容器日志
# docker logs [OPTIONS] 容器ID或容器名称
docker logs 9e7190eae5bd
# 跟踪日志输出
docker logs -f 9e7190eae5bd
# 跟踪日志输出(带时间戳)
docker logs -tf 9e7190eae5bd
# 显示最后5行日志
docker logs -n 5 9e7190eae5bd
docker logs --tail 5 9e7190eae5bd

# 例
# 新建容器并以后台方式启动,执行每5秒打印日志的命令
# 注:sh -c 命令,它可以让 bash 将一个字串作为完整的命令来执行
docker run -d ubuntu /bin/sh -c "while true;do echo hi;sleep 5;done"
# 跟踪日志输出(-f和-tf的区别)
docker logs -f --tail 5 cd0a7ba8d0b5
docker logs -tf --tail 5 cd0a7ba8d0b5

9.4.5 查看容器内运行的进程
# docker top 容器ID或容器名称
docker top 9e7190eae5bd
9.4.6 查看容器内部细节(元数据)
# docker inspect 容器ID或容器名称
docker inspect 9e7190eae5bd
9.4.7 进入正在运行的容器并以命令行交互
# 第一种方式
# docker exec -it 容器ID bashShell
docker exec -it e863a5ed312a /bin/bash 

# 第二种方式
# docker attach 容器ID
# 如果有多个终端,都对同一个容器执行了 docker attach,就会出现类似投屏显示的效果。一个终端中输入输出的内容,在其他终端上也会同步的显示
docker attach e863a5ed312a
  • 上述两种方式的区别

exec 是在容器中打开新的终端,并且可以启动新的进程,此时用 exit 退出,不会导致容器的停止。

attach 直接进入容器启动命令的终端,不会启动新的进程,此时用 exit 退出,会导致容器的停止。

  • 推荐使用 docker exec 命令,因为退出容器终端,不会导致容器的停止

以redis为例(进入 redis 服务)

  • 一般先用 -d 后台启动程序,再用 exec 进入对应容器实例
# 方式一
# 先进入容器交互 shell
docker exec -it 7bba30997546 /bin/bash
# 再运行 redis-cli 进入 redis 服务
redis-cli

# 方式二
# 直接以命令 redis-cli 进入 redis 服务
docker exec -it 7bba30997546 redis-cli

9.4.8 容器与宿主机的文件拷贝

容器文件拷贝到宿主机

# docker cp 容器ID:容器内路径 宿主机路径
docker cp 7d13af0831da:/tmp/test.txt /root/test/

宿主机文件拷贝到容器

# docker cp 宿主机路径 容器ID:容器内路径
docker cp /root/test/test2.txt 7d13af0831da:/tmp/

9.4.9 导入和导出容器

export:导出容器的内容流作为一个tar归档文件(对应 import 命令)

import:从tar归档文件中创建一个新的文件系统再导入为镜像(对应 export 命令)

# 导出
# docker export 容器ID > 文件名.tar
docker export 7d13af0831da > test3.tar

# 导入
# cat 文件名.tar | docker import - 镜像用户/镜像名:镜像版本号
cat test3.tar | docker import - zhoulx/test3:1.0.1

9.5 Docker 磁盘空间相关命令 9.5.1 查看镜像、容器、数据卷所占空间
# 查看镜像(Images)、容器(Containers)、本地数据卷(Local Volumes)的空间占用情况
docker system df
# 通过-v参数进一步查看空间占用细节
docker system df -v

  • 列说明
列列说明
TYPEImages - 镜像
Containers - 容器
Local Volumes - 本地数据卷
TOTAL总数
ACTIVEImages - 存在对应容器实例的镜像数量
Containers - 活跃的容器数量
Local Volumes - 被容器关联引用的卷的数量
SIZE占用空间大小
RECLAIMABLE可清理的空间

  • Image space usage 列说明
列列说明
SHARED SIZE指的是当前镜像与另一个镜像的共享空间大小(例如图中的 myubuntu 是在 ubuntu 镜像基础上制作的,他们的共享数据就是 ubuntu 镜像的大小)
UNIQUE SIZE仅由当前镜像使用的空间大小
CONTAINERS当前镜像对应容器实例的数量
  • Local Volumes space usage 列说明
列列说明
LINKS关联引用该卷的容器数量
9.5.2 清理磁盘空间

自动清理

# 清理磁盘,删除关闭的容器、无用的网络,以及虚悬镜像
docker system prune
# 更彻底地清理磁盘,会将没有容器使用的Docker镜像也一起删掉
docker system prune -a
# 忽略告警询问,直接删除
docker system prune -f

手动清理

  • 镜像清理
# 删除所有虚悬镜像,不会删除未使用的镜像
docker rmi $(docker images -q -f dangling=true)
# 删除所有未使用镜像
# 该命令轮询到在使用的镜像时,会有"container xxxx is using its referenced image xxxx"的报错信息,所以不会被删除
docker rmi $(docker images -q)
  • 容器清理
# 对于已停止或其它异常状态的容器,可以结合 -f 或 --filter 筛选器来处理
# rm -v 删除与该容器关联的匿名卷
# 删除所有已退出的容器
docker rm -v $(docker ps -aq -f status=exited)
# 删除所有状态为 dead 的容器
docker rm -v $(docker ps -aq -f status=dead)
  • 卷清理
# 删除所有未使用的本地卷
docker volume prune
# 删除所有未被任何容器关联引用的卷
docker volume rm $(docker volume ls -qf dangling=true)
10 Docker镜像
  • 概念:是一种轻量级、可执行的独立软件包,包含运行某个软件所需的所有内容,我们把应用程序和配置依赖打包好形成一个可交付的运行环境(包括代码、运行时需要的库、环境变量和配置文件等),这个打包好的运行环境就是image镜像文件。
10.1 UnionFS(联合文件系统)
  • UnionFS,是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite serveral directories into a single virtual filesystem)

  • UnionFS 是 Docker 镜像的基础。镜像可以通过分层来进行集成,基于基础镜像可以制作具体的应用镜像。

  • 特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。

10.2 bootfs 和 rootfs 10.2.1 bootfs(boot file system)

bootfs 主要包含 bootloader(boot加载器)和 kernel(内核),bootloader 主要是引导加载 kernel,Linux 刚启动时会加载 bootfs。

在 Docker 镜像的最底层是 bootfs。这一层与我们典型的 Linux/Unix 系统是一样的。当 boot 加载完成之后整个内核就都在内存中了,此时内存的使用权已经由 bootfs 转交给内核,此时系统也会卸载 bootfs。

10.2.2 rootfs(root file system)

在 bootfs 之上,包含的就是典型 Linux 系统中的 /dev、/proc、/bin、/etc 等标准目录和文件。rootfs 就是各种不同的操作系统发行版,比如 Ubuntu、CentOS 等。

  • 对于一个精简的 OS,rootfs 可以很小,只需要包括最基本的命令、工具和程序库就可以了,因为底层直接使用宿主机的 Kernel,自己只需要提供 rootfs 就可以。
10.3 Docker 镜像分层
  • 镜像分层结构最大的一个好处就是共享资源,方便复制迁移,就是为了复用。
# 查看镜像分层
# docker inspect 镜像名:镜像标签
docker inspect redis:latest

# 运行命令输出的是个 json,其中的 RootFS 就指示了分层信息
"RootFS": {
	"Type": "layers",
	"Layers": [
		"sha256:2edcec3590a4ec7f40cf0743c15d78fb39d8326bc029073b41ef9727da6c851f",
		"sha256:9b24afeb7c2f21e50a686ead025823cd2c6e9730c013ca77ad5f115c079b57cb",
        "sha256:4b8e2801e0f956a4220c32e2c8b0a590e6f9bd2420ec65453685246b82766ea1",
        "sha256:529cdb636f61e95ab91a62a51526a84fd7314d6aab0d414040796150b4522372",
        "sha256:9975392591f2777d6bf4d9919ad1b2c9afa12f9a9b4d260f45025ec3cc9b18ed",
        "sha256:8e5669d8329116b8444b9bbb1663dda568ede12d3dbcce950199b582f6e94952"
	]
}
  • 容器层

当容器启动时,一个新的可写层将被加载到镜像的顶部,这一层通常被称为容器层,容器层之下都叫镜像层。

只有容器层是可写的,容器层下面的所有镜像层都是只读的。

所有对容器的改动,无论添加、删除、还是修改文件都只会发生在容器层中。

10.4 提交镜像
  • docker commit 提交容器副本使之成为一个新的镜像
# docker commit -m="提交的描述信息" -a="作者" 容器ID 创建的目标镜像名:[标签名]
docker commit -m="add vim" -a="zhoulx" 94f960de04a1 zhoulx/myubuntu:1.0.1

# 例:从 hub 上下载的 ubuntu 镜像是不包含 vim 工具的,我们自己安装并生成新的包含 vim 工具的 ubuntu 镜像
# 先以前台交互模式启动 ubuntu
[root@zhoulx ~]# docker run -it ubuntu /bin/bash
# 先更新 ubuntu 的包管理工具
root@94f960de04a1:~# apt-get update
# 安装 vim
root@94f960de04a1:~# apt-get -y install vim
# 回到容器外执行命令,commit 新镜像
[root@zhoulx ~]# docker commit -m="add vim" -a="zhoulx" 94f960de04a1 zhoulx/myubuntu:1.0.1

11 Registry 搭建 docker 私有仓库 11.1 拉取镜像 Docker Registry
# Docker Registry 是官方提供的工具,用于构建私有镜像仓库。
# Docker Registry 是 Docker Hub 提供的一个镜像,可以直接拉取运行。
docker pull registry
11.2 启动 Docker Registry
# -v 宿主机绝对路径:容器路径:将宿主机绝对路径与容器路径作映射,持久化数据
# --privileged=true:扩大容器的权限解决挂载目录没有权限的问题
docker run -d -p 5000:5000 -v /root/myregistry:/tmp/registry --privileged=true registry
11.3 curl查看私服中的所有镜像
# 查看私服中的所有镜像
# Registry 会返回json格式的所有镜像目录
curl http://192.168.198.131:5000/v2/_catalog

11.4 修改配置文件使之支持 http
  • docker 默认不允许 http 方式推送镜像,通过下面的配置来取消这个限制

  • 修改 /etc/docker/daemon.json,添加 insecure-registries 允许 http

{
  "registry-mirrors": ["https://xxxxxxxx.mirror.aliyuncs.com"],
  "insecure-registries": ["192.168.198.131:5000"]
}
  • 据说新版本的 docker 会立即生效,没生效的话就重启一下 docker
# 重载 daemon 程序刷新配置,重启docker
sudo systemctl daemon-reload
sudo systemctl restart docker
11.5 推送镜像到私仓 11.5.1 新镜像修改为符合私服规范的 Tag
# 添加一个对应私仓 tag 的镜像
docker tag zhoulx/myubuntu:1.0.1 192.168.198.131:5000/myubuntu:1.0.2

11.5.2 push 镜像到私仓
# 添加一个对应私仓 tag 的镜像
docker push 192.168.198.131:5000/myubuntu:1.0.2
11.5.3 查看私仓中镜像目录验证
# Registry 会返回json格式的所有镜像目录
curl http://192.168.198.131:5000/v2/_catalog

11.5.4 拉取镜像验证
# 拉取镜像验证
docker pull 192.168.198.131:5000/myubuntu:1.0.2

12 Docker 容器数据卷 12.1 挂载主机目录
# -v 宿主机绝对路径:容器路径:将宿主机绝对路径与容器路径作映射,持久化数据
# --privileged=true:扩大容器的权限解决挂载目录没有权限的问题
# docker run -it --privileged=true -v /宿主机绝对路径:/容器路径 镜像名
docker run -it --privileged=true -v /root/test:/tmp/test --name=ubuntu_test ubuntu
# 挂载多个目录
docker run -it --privileged=true -v /root/test:/tmp/test -v /root/test2:/tmp/test2 --name=ubuntu_test ubuntu
  • docker 挂载主机目录访问时如果出现cannot open directory: Permission denied

解决方法:在挂载目录后多加一个参数:--privileged=true

原因:目录挂载被 CentOS7 的安全模块默认视为不安全的行为,在 SELinux 里面挂载目录被禁止了。我们一般使用 --privileged=true 命令,扩大容器的权限。(使用该参数,容器内的 root 拥有真正的 root 权限,否则容器内的 root 只是外部的一个普通用户权限)

12.2 数据卷的概念及用处

将 docker 容器内的数据保存进宿主机的磁盘中(将宿主机绝对路径与容器路径作映射,完成容器内的数据备份+持久化到宿主机目录)

12.3 为什么使用数据卷

我们对数据的要求是希望持久化的。Docker 容器产生的数据,如果不进行备份,那么当容器实例被删除后,容器内的数据自然也就消失了。为了能保存数据在 docker 中我们使用卷。

12.4 数据卷的特点
  • 数据卷可在容器之间共享或重用数据
  • 数据卷中的更改可以直接实时生效
  • 数据卷中的更改不会包含在镜像中
  • 数据卷的生命周期一直持续到没有容器使用它为止
12.5 查看容器的数据卷挂载信息
# 查看容器的数据卷挂载信息
# docker inspect 容器ID
docker inspect fc2c4fbc6442

# 运行命令输出的是个 json,其中的 Mounts 就指示了挂载信息
"Mounts": [
    {
        "Type": "bind",
        "Source": "/root/test",
        "Destination": "/tmp/test",
        "Mode": "",
        "RW": true,
        "Propagation": "rprivate"
    },
    {
        "Type": "bind",
        "Source": "/root/test2",
        "Destination": "/tmp/test2",
        "Mode": "",
        "RW": true,
        "Propagation": "rprivate"
    }
]
12.6 添加数据卷的读写规则
# rw(可读可写,默认值)和 ro(read-only,只读)
docker run -it --privileged=true -v /root/test:/tmp/test --name=ubuntu_test ubuntu
# 默认容器对数据卷可读可写,等同于
docker run -it --privileged=true -v /root/test:/tmp/test:rw --name=ubuntu_test ubuntu
# 限制容器内对数据卷只读
docker run -it --privileged=true -v /root/test:/tmp/test:ro --name=ubuntu_test ubuntu

12.7 卷的继承和共享
# 容器1完成与宿主机的映射
docker run -it --privileged=true -v /root/test:/tmp/test:rw --name=ubuntu_test ubuntu

# 容器2继承容器1的卷规则
# docker run -it --privileged=true --volumes-from 父类容器名称 --name=ubuntu_test2 ubuntu
docker run -it --privileged=true --volumes-from ubuntu_test --name=ubuntu_test2 ubuntu
  • 注:上述例子容器2继承的是容器1与宿主机的数据卷映射规则,相当于容器1、容器2、宿主机都能操作同一个共享文件目录。此时停掉容器2也不会影响容器1与宿主机的数据卷映射。
13 Docker常规安装 13.1 常规安装步骤 13.1.1 搜索镜像
docker search 镜像名称
13.1.2 拉取镜像
docker pull 镜像名称:镜像标签
13.1.3 查看镜像
docker images 镜像名称
13.1.4 启动镜像
# -p 主机端口:容器端口:指定服务端口的映射
# -P:随机分配端口
# -i:启动前台交互式容器,通常与-t一起使用
# -t:为容器重新分配一个伪输入终端(tty),通常与-i一起使用
# -d:启动后台守护式容器
# --name:指定容器名称
docker run -d  -p 主机端口:容器端口 --name 容器名称 镜像名称:镜像标签
13.1.5 查看容器是否成功运行
docker ps
13.1.6 停止容器
docker stop 容器ID或容器名称
13.1.7 移除容器
docker rm 容器ID或容器名称
13.2 Docker 安装 tomcat
# 搜索tomcat镜像
docker search tomcat
# 拉取tomcat镜像
docker pull tomcat
# 查看镜像是否成功拉取
docker images tomcat
# 使用tomcat镜像创建启动容器
docker run -d -p 8080:8080 --name mytomcat tomcat
# 查看容器是否成功运行
docker ps 

注:tomcat新版本(10.0.14)启动容器后,访问首页tomcat时会报404

  • 原因:tomcat新版本默认webapps文件夹下是空的。
  • 解决方法1:需要先将/usr/local/tomcat下的webapps删掉,将webapps.dist重命名为webapps,才能正常访问tomcat首页。
# 进入容器
[root@zhoulx ~]# docker exec -it 016b2715a390 /bin/bash

# 容器内操作
root@016b2715a390:/usr/local/tomcat# rm -rf webapps
root@016b2715a390:/usr/local/tomcat# mv webapps.dist webapps
  • 解决方法2:使用旧版本的tomcat
# 拉取旧版本tomcat镜像(8.0.53版本)
docker pull billygoo/tomcat8-jdk8
# 创建启动容器
docker run -d -p 8080:8080 --name mytomcat2 billygoo/tomcat8-jdk8
13.3 Docker 安装 mysql 13.3.1 简单安装
# 拉取mysql 5.7的镜像
docker pull mysql:5.7
# 查看镜像是否成功拉取
docker images mysql:5.7
# 使用mysql 5.7镜像创建启动容器
# MYSQL_ROOT_PASSWORD:mysql的root账户密码
docker run -p 3306:3306 --name mysql -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7
# 查看容器是否成功运行
docker ps 

# 进入容器
[root@zhoulx ~]# docker exec -it 5d6a618efa87 /bin/bash
# 进入mysql
root@5d6a618efa87:/# mysql -uroot -p

上述安装方式存在的问题

1、插入中文数据报错:Incorrect string value

  • 报错原因:docker默认的字符集的问题
-- 查看数据库字符集
show variables like 'character%';

-- 返回的字符集中,character_set_database、character_set_server等都为latin1字符集,所以插入中文会报错

2、没有配置容器卷映射

  • 启动容器时没有配置容器卷映射,当容器意外被删时,数据全部丢失且无法找回
13.3.2 实际应用安装方式

1、创建启动容器,配置数据卷映射

docker run -d -p 3306:3306 
           --privileged=true 
           -v /app/mysql/log:/var/log/mysql 
           -v /app/mysql/data:/var/lib/mysql 
           -v /app/mysql/conf:/etc/mysql/conf.d 
           -e MYSQL_ROOT_PASSWORD=root 
           --name mysql2 
           mysql:5.7

2、新建配置文件 my.cnf

# 进入配置文件目录
cd /app/mysql/conf
# 新建 my.cnf
vi my.cnf
  • my.cnf 内容
# 不要写错,写错的话会导致重启不了mysql
[client]
default_character_set=utf8
[mysqld]
collation_server=utf8_general_ci
character_set_server=utf8

3、重启 mysql 容器实例

# 重启 mysql
docker restart mysql2
# 查看容器是否成功运行
docker ps 

4、进入 mysql 查看字符编码

# 进入容器
[root@zhoulx ~]# docker exec -it mysql2 /bin/bash

# 进入mysql
root@5d6a618efa87:/# mysql -uroot -p

# 查看数据库字符集
mysql> show variables like 'character%';

5、容器意外被删时,重新启动容器实例即可

docker rm -f mysql2
# 重新运行启动容器实例
docker run -d -p 3306:3306 
           --privileged=true 
           -v /app/mysql/log:/var/log/mysql 
           -v /app/mysql/data:/var/lib/mysql 
           -v /app/mysql/conf:/etc/mysql/conf.d 
           -e MYSQL_ROOT_PASSWORD=root 
           --name mysql2 
           mysql:5.7
13.4 Docker 安装 redis 13.4.1 简单安装
# 拉取redis 6.0.8的镜像
docker pull redis:6.0.8
# 查看镜像是否成功拉取
docker images redis:6.0.8
# 创建启动容器
docker run -d -p 6379:6379 redis:6.0.8

上述安装方式同样存在问题

1、没有配置容器卷映射,当容器被删除时数据随之丢失,无法恢复。

2、配置文件redis.conf做一些特殊的配置要求

13.4.2 实际应用安装方式

1、新建redis目录存放redis.conf

# 递归创建redis文件夹
mkdir -p /app/redis
# 拷贝一份redis.conf到/app/redis目录下(准备一份redis的默认配置文件即可)

2、编辑redis.conf

vim /app/redis/redis.conf

# 开启redis验密(默认没有设置密码)
requirepass 123456

# 允许redis外地连接,需要注释掉绑定的IP(默认只允许本地访问)
# bind 127.0.0.1

# 注释掉daemonize yes,或者配置成 daemonize no。因为该配置和 docker run 中的 -d 参数冲突,会导致容器一直启动失败
daemonize no

# 开启redis数据持久化
appendonly yes

# 关闭保护模式
protected-mode no
# 开启保护模式时,如果想让外地连接redis,有两种方式:
# (1)通过bind绑定服务器IP
# (2)通过requirepass设置密码参数连接(推荐使用)

3、创建启动容器,配置数据卷映射,读取指定配置文件

docker run -d -p 6379:6379 
           --privileged=true 
           -v /app/redis/redis.conf:/etc/redis/redis.conf 
           -v /app/redis/data:/data 
           --name redis 
           redis:6.0.8 
           redis-server /etc/redis/redis.conf
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/996275.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号