♦ 初识docker
一、基本概念
开发过程中,会接触到三个环境:开发环境、测试环境以及生产环境。以java项目为例,开发中使用 jdk8
,而在测试中环境是 jdk7
,难免会遇到bug
。
这种由环境引起的问题非常常见,最好的做法是将项目的运行环境全部移植给测试工程师。docker
容器能够实现这一功能。
● docker
是一个开源的应用容器引擎;
● 该容器是完全使用沙箱机制,相互隔离;
● 该容器性能开销极低。
小结:docker是一种容器技术,解决软件跨环境迁移的问题
二、安装 docker
开发环境为Ubuntu 16.04 LTS 64
位系统,通过apt
的docker
官方源安装最新的Docker CE(Community Edition)
,即Docker
社区版,是开发人员和小型团队的理想选择。
安装步骤如下:
● 由于 apt
官方库里的 docker
版本可能比较旧,所以先卸载可能存在的旧版本:
sudo apt-get remove docker docker-engine docker-ce docker.io
● 更新 apt
包索引:
sudo apt-get update
● 安装以下包以使 apt
可以通过 HTTPS
使用存储库(repository
):
sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common
● 添加 Docker
官方的 GPG
密钥:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
● 使用下面的命令来设置 stable
存储库:
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
● 再更新一下 apt
包索引:
sudo apt-get update
● 安装最新版本的 Docker CE
:
sudo apt-get install -y docker-ce
● 在生产系统上,可能会需要应该安装一个特定版本的Docker CE
,而不是总是使用最新版本:
列出可用的版本:
apt-cache madison docker-ce
说明:选择要安装的特定版本,第二列是版本字符串,第三列是存储库名称,它指示包来自哪个存储库,以及扩展它的稳定性级别。要安装一个特定的版本,同时需要将版本字符串附加到包名中,并通过等号(=)分隔它们:
sudo apt-get install docker-ce=<VERSION>
验证 docker
● 查看 docker
服务是否启动:
systemctl status docker
● 若未启动,则启动 docker
服务:
sudo systemctl start docker
● 查看 docker
版本,验证是否安装成功:
sudo docker -v
● 经典的 hello world:
sudo docker run hello-world
三、docker 架构
配置 Docker
镜像加速器:
阿里云官网–>登录–>控制台–>产品与服务–>手动输入:镜像–>点击:容器镜像服务–>镜像加速器 [注:每个人的加速 url
是唯一的]
♦ docker 命令
一、docker 服务相关命令
● 查看docker
服务状态(见上文)
● 启动docker
服务(见上文)
● 停止docker
服务:
sudo stop docker
● 重启docker
服务:
sudo restart docker
● 开机启动docker
服务:
systemctl enbale docker
二、docker 镜像相关命令
● 查看镜像
sudo docker images
第一个字段表示镜像名称(含有环境);第二个字段表示版本信息;第三个字段表示镜像的 id
;第四个字段表示创建时间;第五个字段表示镜像大小。
● 搜索镜像
sudo docker search redis
● 拉取镜像
sudo docker pull redis:3.2 //冒号后面紧接版本号,如果不写,默认拉取最新的,即 latest
如果并非需要下载 latest
的版本,如何去查询服务器上是否具体该版本,一般到 Docker Hub 寻找存在的版本。
● 删除镜像
sudo docker rmi ImageId(镜像对应的 id)
● 查看所有镜像 id
sudo docker images -q
● 删除所有镜像:(组合命令)
sudo docker rmi `sudo docker images -q` // 将获得的全部镜像的 id 作为参数
三、docker 容器相关命令
容器是通过镜像来创建的。
● 查看容器:
sudo docker ps // 如果容器是通过 -it 参数进行创建并进入的,执行 exit 指令后退出了该容器,是查看不到的。
sudo docker ps -a // 无论容器关闭与否,都可以查看到
● 创建并启动容器:docker run + 参数
sudo docker run -i -t --name=demo1 centos:7 /bin/bash
sudo docker run -id --name=demo2 centos:7
● 进入容器
sudo docker exec 参数 // 退出容器后,容器不会关闭
看到上述这些指令中参数,肯定会存有疑惑,现在对参数进行说明:
(1)-i
:保持容器运行。通常与 -t
同时使用。加入 -it
这两个参数后,容器创建后自动进入容器中,退出容器后,容器自动关闭。
(2)-t
:为容器重新分配一个伪输入终端,通常与 -i
同时使用。
(3)-d
:以守护(后台)模式运行容器。创建一个容器在后台运行,需要使用docker exec
进入容器。退出后,容器不会关闭。
(4)-it
创建的容器-般称为交互式容器,-id
创建的容器一般称为守护式容器。
(5)--name
:为创建的容器命名。
● 启动容器
sudo docker start 容器名称
● 停止容器
sudo docker stop 容器名称
● 删除容器:如果容器是运行状态则删除失败,需要停止容器才能删除
sudo docker rm 容器名称或者容器 id
sudo docker rm `sudo docker ps -aq`
● 查看容器信息
sudo docker inspect 容器名称
♦ docker 容器的数据卷
一、数据卷概念及作用
思考:
(1) docker
容器删除后,在容器中产生的数据还在吗?
(2) docker
容器和外部机器器可以直接交换文件吗?
(3)容器之间想要进行数据交换如何实现?
数据卷
● 数据卷是宿主机中的一个目录或文件;
● 当容器目录和数据目录绑定后,对方的修改会立即同步;
● 一个数据卷可以被多个容器同时挂载;
● 一个容器也可以挂载多个数据卷;
数据卷作用
● 容器数据持久化;
● 外部机器和容器间接通信;
● 容器之间数据交换;
二、配置数据卷命令
● 创建启动容器时,使用 -v 参数设置数据卷
sudo docker run ... -v 宿主机目录(文件):容器内目录(文件)...
sudo docker run -it --name=c1 -v /root/data:/root/data_container centos:7 /bin/bash
注意:
(1)目录都要绝对路径;
(2)如果目录不存在,会自动创建;
(3)可以挂载多个数据卷;
一个数据卷可以被多个容器同时挂载案例:
sudo docker run -it --name=c3 -v /root/data:/root/data centos:7 /bin/bash
sudo docker run -it --name=c3 -v /root/data:/root/data centos:7 /bin/bash
操作c3中的内容,c4中查看,能够看到跟新后的文件
三、数据卷容器
思考:如何实现多容器进行数据交换
(1)多个容器挂载同一个数据卷
(2)数据卷容器
● 创建启动C3数据卷容器,使用 -v 参数 设置数据卷。C3要挂载数据卷
sudo docker run -it --name=c3 -v /volume centos:7 /bin/bash
● 创建启动C1 C2容器,使用 --volumes-from 参数 设置数据卷
sudo docker run -it --name=C1 --volumes-from C3 centos:7 /bin/bash
sudo docker run -it --name=C2 --volumes-from C3 centos:7 /bin/bash
数据卷小结
- 数据卷概念
● 宿主机的一个目录或文件 (需要通过 -v 对容器的某个目录文件进行映射) - 数据卷作用
● 容器数据持久化
● 客户端和容器数据交换
● 容器间数据交换 - 数据卷容器
● 创建一个容器,挂载一个目录,让其他容器继承自该容器(–volume-from)
● 通过简单方式实现数据卷配置
♦ docker 应用部署
一、MySQL部署
需求: 在 docker
容器中部署 MySQL
,并通过外部 MySQL
客户端操作 MySQL Server
案例:实现步骤
(1)搜索MySQL
镜像
(2)拉取MySQL
镜像
(3)创建容器
(4)操作容器中的MySQL
● 搜索MySQL
镜像
sudo docker search mysql
● 拉取MySQL
镜像
sudo docker pull mysql:5.6
● 创建容器,设置端口映射、目录映射
● 进入容器,操作MySQL
sudo docker exec -it c_mysql /bin/bash // 进入容器,操作mysql
mysql -uroot -p // 登录mysql
show database; //
create database db1; // 创建数据库
...
● 使用外部机器链接容器中的MySQL
图形化客户端操作:
MySQL host address: 宿主机的ip
Usename:
Password:
Port: 映射的端口 3307
二、Tomcat部署
三、Redis部署
♦ dockerfile
一、docker镜像原理
思考:
(1)docker
镜像本质是什么?
(2)docker
中一个 centos
镜像为什么只有200MB,而一个 centos
操作系统的 iso
文件却有几个G?
(3)docker
中一个tomcat
镜像为什么有500MB,而一个 tomcat
安装包只有70多MB?
镜像的原理其实和 Linux
操作系统有关系,先来简单介绍一些 OS
相关知识:
回顾:
操作系统的组成部分:(docker 一般是基于linux安装)
(1)进程调度子系统
(2)进程通信子系统
(3)内存管理子系统
(4)设备管理子系统
(5)文件管理子系统
(6)网络通信子系统
(7)作业控制子系统
Linux
文件系统由 bootfs
和 rootfs
两部分组成:
(1)bootfs
:包含 bootloader
(引导加载程序)和 kernel
(内核)
(2)rootfs
:root
文件系统,包含的就是典型 Linux
系统中的 /dev,
/proc,/bin,/etc 等标准目录和文件
(3)不同的 Linux
发行版,bootfs
基本一样,而 rootfs
不同,如ubuntu,centos等
原理:
● docker
镜像是由特殊的文件系统叠加而成;
● 最低端是 bootfs
,并使用宿主机的 bootfs
;
● 第二层是 root
文件系统 rootfs
,称为 base image
;
● 然后再往上可以叠加其他的镜像文件;
● 统一文件系统(Union File System
)技术能够将不同的层整合成一个文件系统,为这些层提供了一个统的视角,这样就隐藏了多层的存在,在用户的角度看来,只存在一个文件系统。
●一个镜像可以放在另一个镜像的上面。位于下面的镜像称为父镜像,最底部的镜像成为基础镜像。
●当从一个镜像启动容器时,docker
会在最顶层加载一个读写文件系统作为容器。
所谓只读镜像,就是这些镜像都不能修改。如果需要改时,docker
在最顶层加载一个读写文件系统作为容器,在此容器上进行修改,得到一个新的镜像。
总的来说,分层的好处就是:方便复用
思考答案:
(1)docker
镜像本质是什么?
是个分层文件系统。
(2)docker
中一个 centos
镜像为什么只有200MB,而一个 centos
操作系统的 iso
文件却有几个G?
Centos 的 iso
镜像文件包含 bootfs
和 rootfs
, 而 docker
的 centos
镜像复用操作系统的 bootfs, 只有 rootfs
和其他镜像层。
(3)docker
中一个tomcat
镜像为什么有500MB,而一个 tomcat
安装包只有70多MB?
由于 docker
中镜像时分层的, tomact
虽然只有70MB,但是它需要依赖于父镜像(如 JDK
镜像)和基础镜像,所有整个对外暴露的 tomact 镜像大小有 500MB。
制作镜像
(1)容器转为镜像
sudo docker commit 容器id 镜像名称:版本号 // 目录挂载的不生效
sudo docker save -o 压缩文件名称 镜像名称:版本号
sudo docker load -i 压缩文件名称
(2)通过dockfile 进行制作,详见案例。
二、dockerfile概念及作用
dockerfile
是一个文本文件,该文件包含了很多条指令,每一条指令构建一层,基于基础镜像就最终能够构建出一个新的镜像。
对于开发人员:可以为开发团队提供一个完全一致的开发环境;
对于测试人员:可以直接拿开发时所构建的镜像或者通过 dockerfile
文件构建一个新的镜像开始工作;
对于运维人员:在部署时,可以实现应用的无缝移植;
可以在docker hub官网查询 dockerfile。
三、dockerfile关键字
关键字 | 作用 | 备注 |
---|---|---|
FROM | 指定父镜像 | 指定dockerfile是基于哪个image构建的 |
MAINTAINER | 作者信息 | 用来标明这个dockerfile是谁写的 |
LABEL | 标签 | 用来标明dockerfile的标签可以使用Label代替Maintainer,最终都是在docker image基本信息中可以查看 |
RUN | 执行命令 | 执行一段命令默认是/bin/bash格式:RUN command 或者RUN[“command”,“param1”,“param2”] |
CMD | 容器启动命令 | 提供启动容器时候的默认命令和ENTRYPOINT配合使用。格式CMD command param1 param2或者CMD[“command”,“param1”,“param2”] |
ENTRYPOINT | 入口 | 一般在制作一些执行就关闭的容器中会使用 |
COPY | 复制文件 | build的时候复制文件到image中 |
ADD | 添加文件 | build的时候添加文件到image中不仅仅局限于当前build上下文可以来源于远程服务 |
ENV | 环境变量 | 指定build时候的环境变量可以在启动的容器的时候通过-e覆盖格式ENV name=value |
ARG | 构建参数 | 构建参数只在构建的时候使用的参数如果有ENV那么ENV的相同名字的值始终覆盖arg的参数 |
VOLUME | 数据卷 | 指定build的image哪些目录可以启动的时候挂载到文件系统中启动容器的时候使用-V绑定格式VOLUME[“目录”] |
VOLUME | 数据卷 | 指定build的image哪些目录可以启动的时候挂载到文件系统中启动容器的时候使用-V绑定格式VOLUME[“目录”] |
四、案例
实操步骤:
# 第一步: 编辑 dockerfile
FROM centos:7
MAINTAINER xxx <xxx_yyy@163.com>
RUN yum install -y vim
WORKDIR /usr
cmd /bin/bash
# 第二步:通过build命令构建镜像
sudo docker build -f ./centos_dockerfile -t 别名:版本号 .
♦ dockerfile 服务编排
一、服务编排概念
微服务架构的应用系统中一般包含若干个微服务,每个微服务一般都会部署多 个实例,如果每个微服务都要手动启停维护的工作量会很大。
● 要从Dockerfile build image或者去dockerhub拉取image;
● 要创建多个container;
● 要管理这些container(启动停止删除);
服务编排:按照一定的业务规则批量管理容器
二、docker compose 概述
Docker Compose
是一个编排多容器分布式部署的工具,提供命令集管理容器化应用的完整开发周期,包括服务构建,启动和停止。使用步骤:
(1)利用Dockerfile
定义运行环境镜像
(2)使用docker-compose.yml
定义组成应用的各服务
(3)运行docker-compose up
启动应用
三、案例
♦ docker 私有仓库
一、搭建私有仓库
Docker官方的 Docker hub是一 个用于管理公共镜像的仓库,我们可以从上面拉取镜像到本地,也可以把我们自己的镜像推送上去。但是,有时候我们的服务器无法访问互联网,或者你不希望将自己的镜像放到公网当中,那么我们就需要搭建自己的私有仓库来存储和管理自己的镜像。
二、上传镜像到私有仓库
三、从私有仓库拉取镜像
sudo docker pull 镜像名:版本
♦ docker容器虚拟化与传统虚拟机比较
容器就是将软件打包成标准化单元,以用于开发、交付和部署。
● 容器镜像是轻量的、可执行的独立软件包,包含软件运行所需的所有内容:代码、运行时环境、系统工具、系统库和设置。
● 容器化软件在任何环境中都能够始终如一地运行。
● 容器赋予了软件独立性,使其免受外在环境差异的影响,从而有助于减少团队间在相同基础设施上运行不同软件时的冲突。
相同:
● 容器和虚拟机具有相似的资源隔离和分配优势;
不同:
● 容器虚拟化的是操作系统,虚拟机虚拟化的是硬件;
● 传统虚拟机可以运行不同的操作系统,容器只能运行同一类型操作系统;
配合该笔记的资料可以联系作者邮箱:xsx_2018@yeah.net。