Docker的学习

Docker与传统虚拟化

虚拟机就是在操作系统里面运行另一种操作系统,虚拟机看上去和真实系统一模一样,对于应用程序而言无感知。对于宿主机而言,虚拟机就是一个普通文件,不需要就可以删掉,对于其他部分毫无影响。虚拟机直接使用宿主机硬件资源,所以虚拟机的缺点就是:

  1. 资源占用多
  2. 冗余步骤多
  3. 启动慢

常用的虚拟机软件:VMware,Virtualbox

由于虚拟机存在着一些问题,Linux发展出了另一种虚拟化技术:Linux容器(Linux Containers,缩写LXC),Linux容器不是模拟一个完整的操作系统,而是对进程进行隔离,对Kernel内核,库等进行共享。有了容器,就可以将软件运行所需要的资源打包到一个个隔离的容器中。这样就使得系统变得高效轻盈,并保证所有环境中的软件都能始终如一地运行

而Docker正是基于容器虚拟化技术,使用go语言开发的。Docker和传统的虚拟机方式不同之处在于:

  1. 传统虚拟机技术是虚拟出一套硬件后,在其上面运行一个完整的操作系统,在该操作系统上再运行所需的应用进程
  2. 而容器内应用进程直接运行在宿主机的内核,容器没有自己的内核,而且也没有进行硬件虚拟化。因此容器要比虚拟机更加轻便
  3. 每个容器之间互相隔离,每个容器都有自己的文件系统,容器之间不会互相影响

Docker中的几个概念

Docker本身是一个容器运行载体或称之为管理引擎。我们把应用程序和配置依赖打包好形成一个可交付的运行环境,这个运行环境就是image镜像文件。只有通过镜像文件才可以生成Docker容器。image文件可以看作容器的模板,Docker根据image文件生成容器实例。同一个image文件,可以生成多个同时运行的容器实例

镜像:根据image生成容器实例,其本身也是一个文件

容器:根据镜像创建的实例,一个容器运行一个服务,当我们需要的时候,自己通过docker客户端就可以创建对应的实例,每个实例之间互不影响

仓库:就是存放一堆镜像的地方,我们可以将镜像发布到仓库中,需要的时候也可以从仓库拉下来

对Docker镜像加深理解

Docker镜像都是只读的,采用UnionFS(联合文件系统),采用分层的镜像结构,一层套着一层,Docker镜像采用这种分层结构,主要是为了资源共享

Docker的安装与卸载

安装

这里基于Centos7进行安装,实际上官网介绍的也足够详细,这里只是把命令记录下

# 0.查看Centos版本
cat /etc/redhot-release

# 1.卸载原有的docker或docker-engine  如果没有安装过可以忽略
sudo yum remove docker 
                  docker-client 
                  docker-client-latest 
                  docker-common 
                  docker-latest 
                  docker-latest-logrotate 
                  docker-logrotate 
                  docker-engine

# 2.安装yum-utils以及配置仓库(因为docker仓库比较慢, 这里替换成阿里云的仓库)
sudo yum install -y yum-utils

# 3.安装最新版本的Docker引擎
sudo yum install docker-ce docker-ce-cli containerd.io

# 4.验证docker是否安装成功
docker version

# 5.设置阿里云镜像加速
vim /etc/docker/daemon.json
# 在该文件中加入如下配置,docker这里是用json作为配置文件
{
 "registry-mirrors": ["https://i5ct9lf7.mirror.aliyuncs.com"]
}

# 6.重启docker
sudo systemctl daemon-reload
sudo systemctl restart docker

如果当前用户有root权限,可以忽略sudo

更详细的仓库镜像加速可以参看:Docker教程,这个教程非常详细,值得收藏与学习

卸载

# 1.卸载docker引擎
sudo yum remove docker-ce docker-ce-cli containerd.io

# 2.删除镜像,容器,数据卷和配置文件
sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd

Docker命令

Docker帮助命令

1.查看docker版本

docker version

2.docker相关信息,比version命令显示的信息更加全面些

docker info

3.docker帮助命令

docker --help

Docker镜像相关命令

1.列出本地的镜像

docker images [options]

options参数说明
-a:列出本地所有镜像
-q:只显示镜像id
--digests:显示镜像的摘要信息
--no-trunc:显示完整的进行信息

对于options选项说明:注意有的是一个减号,有些是两个减号

输入docker images后会列出镜像列表,这个列表有几个选项,各个选项说明如下:

REPOSITORY:表示镜像的仓库源

TAG:镜像的版本标签

IMAGE ID:镜像创建时间

SIZE:镜像大小

同一个仓库源可以有多个TAG,代表这个仓库中不同的版本,我们使用 REPOSITORY:TAG来定义不同的镜像

如果不指定一个镜像的版本标签,默认将拉取latest最新版

2.搜索镜像

docker search [options] 镜像名称
options参数说明
--no-trunc:显示完整的镜像描述
-s:列出收藏数不小于指定值的镜像
--automated:只列出automated build类型的镜像

其中有的镜像会显示OFFICIAL=OK,表示官方版本

3.下载镜像

docker pull 镜像名称[:TAG]

默认是latest最新镜像

4.删除镜像

docker rmi 镜像名/镜像ID
删除单个:docker rmi -f 镜像ID
删除多个:docker rmi -f 镜像名1:TAG 镜像名2:TAG
删除全部:docker rmi -f $(docker images -qa)  先通过images -qa命令查询出所有的镜像ID,再通过这些ID删除

5.查看镜像创建历史

docker history 镜像名/镜像ID

Docker容器相关命令

只有先下载有镜像,再根据镜像创建容器

1.创建并启动容器

docker run [options] IMAGE [command] [arg...]
options参数说明
--name="容器新名称":为容器指定一个名称
-d:很重要的参数,后台运行容器,并返回容器ID,也即启动守护式容器
-i:以交互模式运行容器,同样与-t同时使用
-t:为容器重新分配一个输入终端,通常与-i同时使用
-P:随机端口映射
-p:很重要的参数,指定端口映射  docker端口:容器端口

比较常用的方式:
在docker中交互式运行centos镜像,会直接进入容器内部并打开终端
docker run -it centos
后台运行tomcat8.5 并映射端口
docker run -d -p 8080:8080 tomcat:8.5

注意:当我们使用-p参数映射端口时,可能会出现docker: Error response from daemon: driver failed programming external connectivity,目前找到的解决办法就是重启Docker:systemctl restart docker,可以参考博客

2.列出当前所有正在运行的容器

docker ps [options]
options参数说明
-a:列出当前所有正在运行的容器+历史上运行过的
-l:显示最近创建的容器
-n:显示最近n个创建的容器
-q:只显示容器ID
--no-trunc:显示完整的容器描述

3.退出容器

当使用交互式run启动容器后,有两种退出方式

exit:退出后,容器会直接停止退出

ctrl+P+Q:推出后,容器不停止退出

4.启动容器

docker start 容器名/容器ID

5.重启容器

docker restart 容器名/容器ID

6.停止容器

docker stop 容器名/容器ID

7.强制停止容器

docker kill 容器名/容器ID

8.删除已停止的容器

docker rm 容器名/容器ID
一次性删除多个容器
docker rm -f $(docker ps -qa)
-f:表示直接删除,即使运行中的容器也可以删除

9.查看容器日志

docker logs -f -t --tail 容器ID

10.查看容器内运行的进程

docker top 容器ID

11.查看容器内部细节(很重要)

docker inspect 容器ID
这个命令很重要,可以看到docker容器的配置细节

12.进入正在运行的容器并以命令行交互

1.attach
docker attach 容器ID
2.exec
docker exec -it 容器ID 需要执行的参数命令行(如 /bin/bash)
这两个命令区别就在于
attach命令输入exit后退出容器会直接导致容器container的停止
而使用docker exec输入exit不会导致容器停止,所以exec命令更加常用些

13.拷贝文件到宿主机上

docker cp 容器ID:容器内路径 宿主机路径
注意:容器ID后有个冒号: 不要忘记

14.提交容器副本使之成为本地的一个新镜像

docker commit -m="提交的描述信息" -a="作者" 容器ID 新镜像名[:TAG]

15.提交镜像到镜像仓库

docker push [options] 镜像名[:TAG]
options参数说明
--disable-content-trust:忽略镜像的校验,默认开启

16.根据Dockerfile文件自定义构建镜像

docker -f /mydocker/Dockerfile -t my/centos[:TAG] .
-f:指定Dockerfile文件路径
-t:新构建出的镜像名称
最后还有一个.点符号不要忘记,表示当前目录
如果不指定TAG就表示是latest最新版
关于DockerFile文件编写在下面章节记录

Docker容器数据卷

数据卷就是将宿主机的一个或多个目录与Docker容器关联起来,用以实现二者之间数据共享

命令

就是在docker run命令后加上-v参数
docker run -it -v 宿主机绝对路径:容器内绝对路径 镜像名/镜像ID
-it:已交互式运行容器, 在上面Docker运行命令有解释过
-v:实际上就是volume(容积,体积)的简写,可以使用多次-v挂载多个数据卷

如果路径不存在会自动创建路径
注意:两个路径之间的:冒号不能省略
如果需要创建只读容器,也就是说容器可以正常同步文件以及读操作,但是不能写,宿主机路径可读可写,需要加上:ro(read only)命令

docker run -it -v 宿主机绝对路径:容器内绝对路径:ro 镜像名/镜像ID

少数情况下Docker挂载宿主机目录会出现cannot open directory.: Permission denied权限不足的问题,解决方法就是在挂载目录后面多加一个--privileged=true参数即可

docker run -it -v 宿主机绝对路径:容器内绝对路径 镜像名/镜像ID --privilaged=true

查看数据卷是否配置好就通过docker inspect 容器ID 命令就可以看到,输出的信息中有关于volume的描述

Docker容器间传递共享数据卷

一个容器可以共享一个已经运行中容器的数据卷,这两个容器类似于继承的关系,但又不相同,将其看作为多个容器之间共享数据卷目录比较合适

运行一个容器
docker run -it -v /myDataVolume:/dataVolumeContainer --name dc01 centos
再运行一个容器共享dc01容器的数据卷
docker run -it --name dc02 --volumes-from dc01 centos

这样dc01和dc03容器就共享/myDataVolume:/dataVolumeContainer这个数据卷关系,任何文件的增删改,这两个容器都可以感知到

注意:即使dc01容器被删除,数据卷也存在,dc03容器还是可以正常使用。也就是说容器之间配置信息的传递,数据卷的生命周期一直持续到没有相关容器才停止

Dockerfile文件

Dockerfile文件是用来构建Docker 镜像的构建文件,是由一系列命令和参数构成的脚本,有一定的语法结构,基于现有镜像进行定制或修改形成新的自定义镜像

构建三步骤

  1. 编写Dockerfile文件
  2. docker build 命令根据Dockerfile文件构建镜像
  3. docker run 命令运行镜像

Dockerfile内容基础知识

  1. 每个关键字指令都必须大写并且都要根据至少一个参数
  2. 指令从上到下顺序执行
  3. #表示注释
  4. 每条指令都会创建一个新的镜像层,并会对镜像进行commit提交

根据Dockerfile构建镜像大致流程

  1. docker从基础镜像运行一个容器
  2. 执行一条指令并对容器进行修改
  3. 执行类似docker commit 的操作提交一个新的镜像层
  4. docker再基于刚才提交的镜像运行一个新容器(UnionFS-联合文件系统,一层包着一层)
  5. 执行dockerfile的下一条指令直到所有的指令都执行完成

关键字指令

FROM

基础镜像,当前新镜像是根据哪个进行进行修改的

MAINTAINER

镜像维护者的姓名和邮箱地址

RUN

容器构建时需要运行的Linux命令

EXPOSE

当前容器对外暴露的端口

WORKDIR

指定再创建容器后,通过docker run -it 终端登录进来的工作目录,一个落脚点

ENV

用来在构建镜像过程中设置环境变量供上下文使用

ADD

将宿主机目录下的文件拷贝进镜像并且ADD命令会自动处理URL和解压tar压缩包

ADD src dest

COPY

类似于ADD,拷贝文件和目录到镜像中,注意与ADD指令的区别,ADD会自动解压tar压缩包,而COPY不会,所以ADD更为强大些

COPY src dest

VOLUME

容器数据卷,用于数据保存持久化和共享工作

CMD

指定一个容器启动时要运行的命令,可以有多个CMD指令,但是只有最后一个生效,还需要注意的是CMD会被docker run命令后带的参数替换

ENTRYPOINT

指定一个容器启动时需要运行的命令,目的和CMD一样

注意与CMD指令区别,多个CMD指令只有最后一个生效,而多个ENTRYPOINT都会生效,docker run后带着个参数可以替换CMD,实际上是run后的参数会自动追加CMD到最后,多个CMD只有最后一个会生效所以就替换了,而对于ENTRYPOINT来说也是追加命令,但是多条ENTRYPOINT都会生效

ONBUILD

当一个Dockerfile文件被构建时,其FROM指令依赖镜像的Dockerfile如果有这个指令,则父镜像的ONBUILD会被触发

Dockerfile指令分类图

Dockerfile指令分类图

常见软件容器安装

这里参考Docker教程即可,非常详细

这里记录下如下两个命令:

1.备份mysql数据

docker exec mysql容器ID sh -c 'exec mysqldump --all-databases -uroot -p"root"' > /tmp/all-database-bak.sql

2.运行redis

docker run -p 6379:6379 -v /myredis/data:/data -v /myredis/conf/redis.conf:/usr/local/etc/redis/redis.conf -d redis:3.2 redis-server /usr/local/etc/redis/redis.conf --appendonly yes

redis-server /usr/local/etc/redis/redis.conf:根据这个redis配置文件启动redis

--appendonly yes:开启AOF

推送到阿里云Dockers仓库

1.登录到仓库

sudo docker login --username=xxx registry.cn-hangzhou.aliyuncs.com

用户名就是阿里云账号全名,接下来会让输入密码,密码就是开通服务时设置的密码

2.给镜像标记TAG

sudo docker tag [ImageId] redistry.cn-hangzhou.aliyuncs.com/名称空间/镜像名[:镜像版本号]

3.推送镜像到registry

sudo docker push registry.cn-hangzhou.aliyuncs.com/名称空间/镜像名[:镜像版本号]

push后部分镜像名称需要与docker tag后面填写镜像名称一致

原文地址:https://www.cnblogs.com/lz2017/p/14604208.html