Docker
Jackie

Docker

官网:https://www.docker.com/

文档地址:https://docs.docker.com/

仓库地址:https://hub.docker.com/

容器化技术不是模拟完整的一个操作系统

架构

  • 镜像(Image):Dockers镜像(Image),相当于是一个root文件系统,比如官方镜像Ubuntu 16.04就包含了一套Ubuntu 16.04最小系统的root文件系统,好比是一个模板,通过这个镜像可以创建容器服务,tomcat ==> run ==>tomcat01容器(提供服务的)通过这个镜像可以创建多个容器
  • 容器(Container):镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建,启动,停止,删除,暂停等
  • 仓库(Repository):仓库可以看成一个代码控制中心,用来保存镜像。分为共有仓库和私有仓库

Docker使用Client-Server(C/S)架构模式,使用远程API来管理和创建
Docker容器。

Docker容器通过Docker镜像来创建。

容器与镜像的关系类似于面向对象编程中的对象和类

安装

  1. 卸载旧的版本
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
  1. 需要的安装包
yum install -y yum-utils
  1. 设置镜像仓库
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
  1. 更新yum包索引
yum makecache fast
  1. 安装Docker
yum install docker-ce docker-ce-cli containerd.io
  1. 启动Docker
systemctl start docker
  1. 检查是否安装成功
docker version
  1. 测试hello world
docker run hello-world
  1. 查看镜像
docker images
  1. 配置阿里云镜像加速

登录-容器镜像服务-镜像加速器

sudo mkdir -p /etc/docker

sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://l3r9ab0o.mirror.aliyuncs.com"]
}
EOF

sudo systemctl daemon-reload

sudo systemctl restart docker

卸载Docker

  1. 卸载依赖
yum remove docker-ce-cli containerd.io
  1. 删除运行环境
rm -rf /var/lib/docker
# /var/lib/docker Docker默认工作路径

命令

帮助文档地址:https://docs.docker.com/reference/

帮助命令

docker version #显示docker版本信息
docker info #显示docker系统信息,包括镜像和容器的数量
docker 命令 --help #帮助命令

镜像命令

  • docker images:查看主机本地上的镜像
    • -a:列出所有镜像
    • -q:只显示镜像id
  • docker search 镜像名:搜索镜像
    • – filter=过滤的条件=具体的值:设置过滤选项
  • docker pull 镜像名:下载镜像
    • :tag:下载指定版本
[root@jackie /]# docker pull mysql:5.7
5.7: Pulling from library/mysql
72a69066d2fe: Pull complete #分层下载,docker image的核心 联合文件系统
93619dbc5b36: Pull complete
99da31dd6142: Pull complete
626033c43d70: Pull complete
37d5d7efb64e: Pull complete
ac563158d721: Pull complete
d2ba16033dad: Pull complete
0ceb82207cd7: Pull complete
37f2405cae96: Pull complete
e2482e017e53: Pull complete
70deed891d42: Pull complete
Digest: sha256:f2ad209efe9c67104167fc609cca6973c8422939491c9345270175a300419f94 #签名(防伪)
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7 #真实地址
#等价于↓
docker pull docker.io/library/mysql:5.7
  • docker rmi 镜像id:删除镜像
    • -f:强制删除
docker rmi -f $(docker images -aq)#删除全部容器($把括号内的值传过去)
  • docker image save 镜像名 > 压缩包名:导出镜像

  • docker image load -i 压缩包名:导入镜像

容器命令

有了镜像才可创建容器

  • docker run [可选参数] image:创建并运行容器
    • –name=“Name”:设置容器名字来区分容器
    • -d:以后台方式运行
    • -it:使用交互方式运行,进入容器查看内容
    • -p:端口映射
      • -p 主机端口:容器端口
      • -p ip:主机端口:容器端口
      • -p 容器端口
      • 容器端口
    • -P:随机指定端口
    • –rm:容器用完即删(用来测试)
    • -v:卷挂载
    • -e:环境配置

容器内的是基础,很多命令不完善

进入容器后exit 从容器中退回到主机

Ctrl+P+Q容器不停止退出

  • docker ps:查看当前正在运行的容器
    • -a:列出当前正在运行的容器+历史运行过的容器
    • -n=?:显示最近创建的容器
    • -q:只显示容器编号
  • docker rm 容器id:删除指定的容器(无法直接删除运行中的容器)
#两者均可删除所有容器
docker rm -f $(docker ps -aq)
docker ps -a -q|xargs docker rm
  • docker start 容器id:启动容器
  • docker restart 容器id:重启容器
  • docker stop 容器id:停止当前正在运行的容器
  • docker kill 容器id:强制停止当前容器

stop 会给容器内应用10s时间去停止服务,kill直接强行停止

删除容器指的是删除这个实例,kill指的是关闭正在运行的容器,实例仍旧存在

※常用其他命令

  • 后台启动容器
# 命令 docker run -d 镜像名
docker run -d centos
#坑:docker ps 发现centos停止了,docker容器使用后台运行,必须有前台进程,否则自动停止
  • docker logs:查看日志信息

    • -tf:t显示时间戳;f动态显示
    • –tail number:要显示的日志条数
  • docker top 容器id:查看容器中进程信息

pid:当前进程id;ppid:父进程id

  • docker inspect 容器id:查看镜像元数据

  • docker exec -it 容器id bashshell:进入容器后打开一个新的终端,可以在里面操作

通常容器都是使用后台方式运行的,需要进入其中的容器修改一些配置

docker exec -it 容器id /bin/bash

  • docker attach 容器id bashshell:进入容器正在执行的终端,不会启动新的进程
  • docker cp 容器id:容器内路径 目的主机路径: 从容器内拷贝文件到主机上

image

小汇总

命令 说明
attach 当前shell下attach连接指定运行镜像
build 通过dockerfile定制镜像
commit 提交当前容器为新的镜像
cp 从容器中拷贝指定文件或目录到宿主机中
create 创建一个新的容器,同run,但不启动容器
diff 查看docker容器变化
events 从docker服务获取容器实时事件
exec 在已存在的容器上运行命令
export 导出容器的内容流作为一个tar归档文件(对应import)
history 展示一个镜像形成历史
images 列出系统当前镜像
import 从tar包中的内容创建一个新的文件系统映像(对应export)
info 显示系统相关信息
inspect 查看容器详细信息
kill kill指定的docker容器
load 从一个tar包中加载一个镜像(对应save)
login 注册或者登录一个docker源服务器
logout 从当前docker registry退出
logs 输出当前容器日志信息
port 查看映射端口对应的容器内部源端口
pause 暂停容器
ps 列出容器列表
pull 从docker镜像源服务器拉取指定镜像或者库镜像
push 推送指定镜像或者库镜像至docker源服务器
restart 重启运行的容器
rm 移除一个或者多个容器
rmi 移除一个或多个镜像(无容器使用该镜像才可以删除,否则需删除相关容器才可继续或-f强制删除
run 创建一个新的容器并运行一个命令
save 保存一个镜像为一个tar包(对应load)
search 在docker hub中搜索镜像
start 启动容器
stop 停止容器
tag 给源中镜像打标签
top 查看容器中运行的进程信息
unpause 取消暂停容器
version 查看docker版本号
wait 截取容器停止时的退出状态值

卷命令

  • docker volume create 卷名:创建数据卷
  • docker volume ls:查看所有的数据卷
  • docker volume inspect 卷名:查看指定数据卷的信息
  • docker volume rm 卷名:删除数据卷

无法删除正在被使用的、容器存在的

  • docker rm -v …:删除容器时删除相关的卷

数据卷是被设计用来持久化数据的,它的生命周期独立于容器,Docker 不会在容器被删除后自动删除数据卷,并且也不存在垃圾回收这样的机制来处理没有任何容器引用的数据卷 。如果需要在删除容器的同时移除数据卷。可以在删除容器的时候使用 docker rm -v 这个命令。
无主的数据卷可能会占据很多空间,要清理请使用以下命令

docker volume prune

工作流程

  1. docker build

当我们写完dockerfile交给docker“编译”时使用这个命令,那么client在接收到请求后转发给docker daemon,接着docker daemon根据dockerfile创建出“可执行程序”image。

![docker build](docker build.png)

  1. docker run

有了“可执行程序”image后就可以运行程序了,接下来使用命令docker run,docker daemon接收到该命令后找到具体的image,然后加载到内存开始执行,image执行起来就是所谓的container。

![docker run](docker run.png)

  1. docker pull

docker中image的概念就类似于“可执行程序“,docker registry 可以用来存放各种image,公共的可以供任何人下载image的仓库就是docker Hub。那么该怎么从Docker Hub中下载image呢,就是这里的docker pull命令了。

![docker pull](docker pull.png)

镜像讲解

镜像是什么

镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。

Docker镜像加载原理

  • UnionFS(联合文件系统/UFS)

我们下载时看到的一层层就是这个

UnionFS(联合文件系统):Union文件系统是一种分层,轻量级并且高性能的文件系统,它支持堆文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。Union文件系统是Docker镜像的基础,镜像可以通过分层来继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。

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

  • Docker镜像加载原理

Docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。

bootfs(boot file system)主要包含bootloade和kernel,bootloader主要是引导加载kernel,Linux刚启动是会加载bootfs文件系统,在Docker镜像的最底层是引导文件系统bootfs,这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核,当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs

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

image

总结,Docker就是一个简易版的Linux,所有的镜像都公用宿主机的bootfs,根据rootfs的不同就是不同的Linux发行版本如centos、ubuntu等,而镜像就是在rootfs上面,容器就是最上面的container,Docker为什么分层,就是为了复用底层,所以就会很快,很方便

具体例子,假设我们在Centos下安装了docker,然后使用Docker拉下了一个ubuntu镜像,运行ubuntu镜像,里面是没有vim命令的,那么我们在镜像里面安装了vim,然后使用commit提交容器使之成为一个新的镜像,那么这个新的ubuntu镜像就分为一下几层:

  • bootfs层
  • rootfs层
  • ubuntu层
  • vim层
  • container层

对于一个极简的OS,rootfs可以很小没只需要包含最基本的命令,工具,程序库就可以了,因为底层直接用host的kernel,自己只需提供rootfs就可以了。于此可见对于不同的Linux发行版,bootfs基本是一致的,rootfs会有差异,因此不同的发行版可以公用bootfs

分层理解

Q:Docker采用分层的结构的好处?

A:资源共享 例如有多个镜像都从相同的base镜像构建而来,则宿主机只需在磁盘上保留一份base镜像,同时内存中也只需要加载base镜像,这样就可以为所有的容器服务,且镜像的每一层都可以共享。

理解:

所有的docker镜像都起源于一个基础镜像层,当进行修改或增加信的内容是,就会在当前镜像层之上,创建新的镜像层。

举一个简单的例子,假如基于Ubuntu linux16.04创建一个新的镜像,这就是新镜像的第一层;如果在该镜像中添加python包,就会在基础镜像层之上创建第二个镜像层,如果继续添加一个安全补丁,就会创建第三个镜像层,该镜像当前已经包含3个镜像层,如图所示

image

在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合

image


在外部看来整个镜像只有6个文件,这是因为最上层的文件7是文件5的更新版

image

这种情况下,上层镜像层中的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个新镜像层作为一个新镜像层添加到镜像当中。

Docker通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系统。

Linux上可用的存储引擎有AUFS、Overlay2、Device Mapper、Btrfs以及ZFS。顾名思义,每种存储引擎都基于Linux中对应的文件系统或者块设备技术,并且每种存储引擎都有其独有的性能特点

Docker在Windows上仅支持Windowsfilter一种存储引擎,该引擎基于NTFS文件系统之上实现了分层和CoW[1]

下图展示了与系统显示相同的三层镜像。所有镜像层堆叠并合并,对外提供统一的视图

image

  • 特点

Docker镜像默认都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部

这一层就是我们通常说的容器层,容器之下都叫镜像层

image

commit镜像

# docker commmit 提交容器成为一个新的副本
docker commit -a="作者" -m="镜像描述" 容器id 目标镜像名:[TAG]

容器数据卷

Docker将运用与运行的环境打包形成容器运行, Docker容器产生的数据,如果不通过docker commit生成新的镜像,使得数据做为镜像的一部分保存下来, 那么当容器删除后,数据自然也就没有了。 为了能保存数据在Docker中我们使用卷。|

卷就是目录或文件,存在于一个或多个容器中,由Docker挂载到容器,但卷不属于联合文件系统(Union FileSystem),因此能够绕过联合文件系统提供一些用于持续存储或共享数据的特性:。

卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此Docker不会在容器删除时删除其挂载的数据卷。

Docker容器卷的工作就是将Docker容器数据通过映射进行备份+持久化到本地的主机目录


直接使用命令来挂载

docker run -it -v 主机目录:容器内目录 
docker run -it -v /home/ceshi:/home centos /bin/bash

docker inspect 容器id 其中的mounts(挂载)可查看相关信息

具名挂载&匿名挂载

  • 匿名挂载
-v 容器内路径

所有docker容器内的卷,没有指定目录的情况下都是在==/var/lib/docker/volumes/xxx/_data/==

  • 具名挂载
-v 卷名:容器内路径
  • 指定路径挂载
-v /宿主机路径::容器内路径

拓展:

#通过-v 容器内路径:ro/rw改变读写权限
ro readonly #只读
rw readwrite #可读可写
#一旦这个了设置了容器权限,容器对我们挂载出来的内容就有了限定
docker run -d -p --name nginx02 -v juming-nginx : /etc/nginx:ro nginx
docker run -d -p --name nginx02 -v juming-nginx : /etc/nginx:rw nginx
# ro:只要看到ro就说明这个路径只能通过宿主机来操作,容器内部无法操作

容器卷容器

容器数据卷是指建立数据卷,来同步多个容器间的数据,实现容器间的数据同步。

# 创建docker01
docker run -it --name docker01 jackie/centos:latest

# 查看容器docekr01内容
ls
bin home lost+found opt run sys var
dev lib media proc sbin tmp volume01
etc lib64 mnt root srv usr volume02

# 不关闭该容器退出
CTRL + Q + P

# 创建docker02: 并且让docker02 继承 docker01
docker run -it --name docker02 --volumes-from docker01 jackie/centos:latest

# 查看容器docker02内容
ls
bin home lost+found opt run sys var
dev lib media proc sbin tmp volume01
etc lib64 mnt root srv usr volume02

# 创建docker03继承docker01
docker run -it --name docker03 --volumes-from docker01 jackie/centos:latest
cd volume01 #进入volume01 查看是否也同步docker01的数据

ls
docker01.txt
# 测试:可以删除docker01,查看一下docker02和docker03是否可以访问这个文件
# 测试发现:数据依旧保留在docker02和docker03中没有被删除(但是删除主机内的文件,则全无)

Dockerfile

dockerfile就是用来构建docker镜像的构建文件

通过这个脚本可以生成镜像,镜像是一层一层的,脚本一个个的命令,每个命令是一层

#创建一个dockerfile文件,名字可随机,建议为dockerfile
#文件中的内容 指令(大写) 参数
FROM centos
VOLUME ["volume01","volume02"]
CMD echo "----end----"
CMD /bin/bash
#这里的每个命令就是镜像的一层
#不能run的,VOLUME ["/volume01","/volume02"],加斜杠!

介绍

  • 构建步骤︰
  1. 编写一个dockerfile文件

  2. docker build构建成为一个镜像

  3. docker run运行镜像

  4. docker push 发布镜像(DockerHub、阿里云镜像仓库)

  • 基础知识∶
  1. 每个保留关键字(指令)都是尽量是大写字母

  2. 执行从上到下顺序执行

  3. #表示注释

  4. 每一个指令都会创建提交一个新的镜像层,并提交

image

指令

参考链接:https://www.runoob.com/docker/docker-dockerfile.html

指令 说明
FROM 指定基础镜像
MAINTAINER 镜像是谁写的,姓名+邮箱
RUN 镜像构建的时候需要运行的命令
ADD 将本地文件添加到容器中,tar类型文件会自动解压(网络压缩资源不会被解压),可以访问网络资源,类似wget
WORKDIR 镜像的工作目录
VOLUME 挂载的目录
EXPOSE 暴露端口配置
CMD 指定这个容器启动的时候要运行的命令(只有最后一个会生效,可被替代)
EMTRYPOINT 指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD 当构建一个被继承DockerFile,这个时候就会运行ONBUILD的指令,触发指令
COPY 功能类似ADD,但是是不会自动解压文件,也不能访问网络资源
ENV 构建的时候设置环境变量

构建自己的Dockerfile

下面通过编写Dockerfile文件来制作Centos镜像,并在官方镜像的基础上添加vim和net-tools工具。首先在/home/dockfile 目录下新建文件mydockerfile-centos。然后使用上述指令编写该文件。

  1. 编写dockerfile文件
FROM centos:7                     #基础镜像         
MAINTAINER TSL<.com> #维护者信息

ENV MYPATH /usr/local #环境变量目录 k-v
WORKDIR $MYPATH #工作目录 用$取k

RUN yum -y install vim #执行构建命令 安装vim
RUN yum -y install net-tools #执行构建命令 安装net-tools

EXPOSE 80 #暴露端口 80

CMD echo $MYPATH #输出构建信息 mypath
CMD echo "---end---" #输出信息
CMD /bin/bash #进入/bin/bash命令行
  1. 构建镜像文件

构建镜像命令:docker build -f dockerfile文件路径 -t 镜像名[:版本号] .(这里有个小点.

上面命令中,-t参数用来指定 image 文件的名字,后面还可以用冒号指定标签。如果不指定,默认的标签就是latest。最后的那个点表示Dockerfile文件所在的路径,上例是当前路径,所以是一个点。

docer build -f mydockerfile-centos -t mycentos:0.1 .
# docker images 查看镜像会发现size变大

制作tomcat镜像并发布

image

发布

公有仓库

注册Docker ID后,在Linux中登录Docker Hub

docker login

注意要保证Image的tag是账户名,如果镜像名字不对,需要改一下tag

docker tag 仓库名 用户名/仓库名

推送Docker Image到Docker Hub

docker push 用户名/仓库名:latest

去Docker Hub中检查镜像

docker pull 用户名/仓库名
  • 私有仓库

Docker Hub是公开的,其他人也是可以下载,并不安全,因此还可以使用docker registry官方提供的私有仓库

参考链接

下载一个Docker官方私有仓库镜像

docker pull registry

运行一个Docker私有容器仓库

docker run -d -p 5000:5000 -v /opt/data/registry:/var/lib/registry registry
  • -d:后台运行
  • -p:端口映射
  • -v:数据卷挂载

Docker默认不允许非HTTPS方式推送镜像。我们可以通过Docker的配置选项来取消这个限制,修改Docker的配置文件,让他支持HTTP方式,设置信任,上传私有镜像

vim /etc/docker/daemon.json
写入
{
"registry-mirrors": ["http://f1361db2.m.daocloud.io"],
"insecure-registries":["192.168.11.37:5000"]
}

修改Docker的服务配置文件

vim /lib/systemd/system/docker.service
找到[service]这一代码区域块,写入如下参数
[Service]
EnvironmentFile=-/etc/docker/daemon.json

重启Docker服务

systemctl restart docker

修改本地镜像的tag标记,往自己的私有仓库推送

docker tag docker.io/peng104/hello-world-docker 192.168.11.37:5000/peng-hello
 评论
评论插件加载失败
正在加载评论插件