docker笔记-基础篇

docker笔记-基础篇

注:该博客参考 尚硅谷-周阳老师视频内容 ,仅供个人学习使用,转载请注明出处

一、docker介绍

1. docker是什么?

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

2. 容器虚拟化技术是什么?

  • linux容器,一种虚拟化技术;linux容器并不是模拟一个完整的操作系统,而是对进程进行隔离。

3. 地址?

  • docker官网:https://www.docker.com/
  • docker hub仓库:https://hub.docker.com/

4. docker基本组成

  • 镜像(image) :就是一个只读的模板。镜像可以用来创建docker容器,一个镜像可以创建很多容器。类似于java中的类的概念。
  • 容器(container):用镜像创建的实例。可以把容器看作是一个简易版的linux环境。类似于java中的对象的概念。
  • 仓库(repository):集中存放镜像文件的场所。其中仓库和仓库注册服务器(Registry)是有区别的,后者往往存放着多个仓库。最大的公开库是docker hub,国内有阿里云和网易云等。
  • docker架构图


    在这里插入图片描述
  • docker run 命令的流程


    在这里插入图片描述

二、docker 安装

1. 前提

  • 查看内核版本(docker 运行在 CentOS 7 以上版本,要求系统为64位、系统内核版本为 3.10 以上;我这边内核版本是4.18.0)
    [图片上传失败...(image-c1fa2-1600413073808)]
  • 查看CentOS版本信息(我这边CentOS版本是CentOS 8)
    [图片上传失败...(image-23c9c1-1600413073808)]

2. 安装步骤

  • yum安装gcc相关
yum -y install gcc
yum -y install gcc-c++
  • 安装依赖环境
yum install -y yum-utils device-mapper-persistent-data lvm2
  • 添加docker源
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
  • 安装docker-ce
yum install docker-ce
  • 如果报错(
    Problem: package docker-ce-3:19.03.8-3.el7.x86_64 requires containerd.io >= 1.2.2-3, but none of the providers can be installed)
    需要安装新版containerd.io(参考https://blog.csdn.net/shana_8/article/details/105190368)后,再次安装docker-ce
dnf install https://download.docker.com/linux/centos/7/x86_64/stable/Packages/containerd.io-1.2.6-3.3.el7.x86_64.rpm
yum install docker-ce
  • 配置镜像加速
  1. 先去阿里云申请加速器(搜索 容器镜像服务 -- 镜像中心 -- 镜像加速器)
mkdir -p /etc/docker
vim /etc/docker/daemon.json  写入
{
  "registry-mirrors": ["https://自己的地址"]
}

systemctl daemon-reload
  • 启动docker
systemctl start docker
  • 查看阿里云加速器是否配置成功
docker info

[图片上传失败...(image-473118-1600413073808)]
看看Registry Mirrors是否是你的阿里云加速器地址。

三、docker底层原理

1. docker是怎么工作的?

  • docker是一个Client-Server结构的系统,docker守护进程运行在主机上,守护进程从客户端接受命令并管理运行在主机上的容器。


    在这里插入图片描述

2. 为什么docker比vm要快?

  • docker有着比虚拟机更少的抽象层。运行在docker容器上的程序直接使用的都是实际物理机的硬件资源。
  • docker利用的是宿主机的内核,而不需要Guest OS。


    在这里插入图片描述

3. docker架构图

在这里插入图片描述

四、常用命令

1. 帮助命令

docker version #查看docker版本
docker info #查看docker详细信息
docker --help #查看docker命令

2. 镜像命令

  • 查看本地镜像
docker images #列出本地主机上的镜像

[图片上传失败...(image-df1bb6-1600413073808)]

含义
REPOSITORY 镜像的仓库源
TAG 镜像的标签
IMAGE ID 镜像ID
CREATED 镜像创建时间
SIZE 镜像大小

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

  • 在仓库中查询镜像
docker images -a #列出本地所有镜像(包含中间镜像)
docker images -q #只显示镜像ID
docker images --digests #显示镜像的摘要信息
docker images --no-trunc #显示完整的镜像信息

[图片上传失败...(image-55c8ae-1600413073808)]
[图片上传失败...(image-bbda2c-1600413073808)]

[图片上传失败...(image-67cf5b-1600413073808)]

[图片上传失败...(image-1dc135-1600413073808)]

docker search [options] 镜像名字
/*
    --no-trunc : 显示完整的镜像描述
    --filter=stars=50 : 列出收藏数不小于50的镜像
    --filter=is-automated=true : 只列出 automated build类型的镜像
*/
在这里插入图片描述

在这里插入图片描述

[图片上传失败...(image-f7d801-1600413073808)]


在这里插入图片描述

为什么采用自动化构建: 把本地的镜像上传到docker hub上之后,假如要对镜像进行修改,就得先去改dockerfile,然后再去build,最后push到docker hub上面去,太过繁琐。故采用自动化构建的方式。

自动化构建: 就是使用Docker Hub连接一个包含Dockerfile文件的Github仓库或者BitBucket仓库,DockerHub则会自动构建镜像,通过这种方式构建出来的镜像会被标记为Automated Build,也称之为受信构建(Trusted Build)。参考https://blog.csdn.net/u013246898/article/details/53048372

  • 从仓库中下载镜像
docker pull 镜像名[:TAG] #不加版本号,默认拉最新latest
  • 删除本地镜像
docker rmi  -f 镜像ID/镜像名1:TAG #删除一个
docker rmi -f 镜像ID/镜像名1:TAG 镜像ID/镜像名2:TAG #删除多个
docker rmi -f $(docker images -qa) #删除全部

3. 容器命令

  • 新建并启动容器
docker run [options] images_id/image_name[:tag] [command] [arg..]
/*options
    --name="容器新名字": 为容器指定一个名称;
    -d: 后台运行容器,并返回容器ID,也即启动守护式容器;
    -i:以交互模式运行容器,通常与 -t 同时使用;
    -t:为容器重新分配一个伪输入终端,通常与 -i 同时使用;
    -P: 随机端口映射;
    -p: 指定端口映射,有以下四种格式
          ip:hostPort:containerPort
          ip::containerPort
          hostPort:containerPort
          containerPort
*/

例:启动交互式容器

docker run -it mysql /bin/bash
#使用镜像mysql:latest以交互模式启动一个容器,在容器内执行/bin/bash命令。
  • 列出当前所有正在运行的容器
docker ps [options]
/*options
    -a :列出当前所有正在运行的容器+历史上运行过的
    -l :显示最近创建的容器。
    -n:显示最近n个创建的容器。
    -q :静默模式,只显示容器编号。
    --no-trunc :不截断输出。
*/
  • 退出容器
exit #容器停止推出
ctrl+P+Q #容器不停止推出
  • 启动容器
docker start 容器ID或者容器名
  • 重启容器
docker restart 容器ID或者容器名
  • 停止容器
docker stop 容器ID或者容器名
  • 强制停止容器
docker kill 容器ID或者容器名
  • 删除已停止的容器
docker rm 容器ID
# 一次性删除多个容器
docker rm -f $(docker ps -a -q)
docker ps -a -q | xargs docker rm
  • 启动守护式容器
docker run -d 容器名
/*问题:然后docker ps -a 进行查看, 会发现容器已经退出
很重要的要说明的一点: Docker容器后台运行,就必须有一个前台进程.
容器运行的命令如果不是那些一直挂起的命令(比如运行top,tail),就是会自动退出的。*/
/*
这个是docker的机制问题,比如你的web容器,我们以nginx为例,正常情况下,我们配置启动服务只需要启动响应的service即可。例如
service nginx start
但是,这样做,nginx为后台进程模式运行,就导致docker前台没有运行的应用,
这样的容器后台启动后,会立即自杀因为他觉得他没事可做了.
所以,最佳的解决方案是,将你要运行的程序以前台进程的形式运行
*/
  • 查看容器日志
docker logs -f -t --tail 容器ID
/*
-t #加入时间戳
-f #跟随最新的日志打印
--tail 数字 显示最后多少条
*/
  • 查看容器内运行的进程
docker top 容器ID
  • 查看容器内部细节
docker inspect 容器ID
  • 进入正在运行的容器并以命令行交互
docker exec -it 容器ID /bin/bash
docker attach 容器ID
/*
    上述两个区别:
        exec:在容器中打开新的终端,并且可以启动新的进程
        attach:直接进入容器启动命令的终端,不会启动新的进程
*/
  • 从容器内拷贝文件到主机上
docker cp 容器ID:容器内路径 目的主机路径

五、docker镜像

  • docker镜像是什么?

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

  • UnionFS(联合文件系统)?

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

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

  • docker 镜像加载原理?

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

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

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

  • 为什么Docker镜像要采用这种分层结构呢?

最大的一个好处就是 - 共享资源

比如:有多个镜像都从相同的 base 镜像构建而来,那么宿主机只需在磁盘上保存一份base镜像,
同时内存中也只需加载一份 base 镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。

  • docker镜像的特点?

Docker镜像都是只读的
当容器启动时,一个新的可写层被加载到镜像的顶部。
这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”。

  • docker镜像commit操作

docker commit提交容器副本使之成为一个新的镜像

docker commit -m=“提交的描述信息” -a=“作者” 容器ID 要创建的目标镜像名:[标签名]

六、docker容器数据卷

1. 是什么

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

2. 能干嘛

容器的持久化、容器间继承+共享数据

3. 特点

特点:
1:数据卷可在容器之间共享或重用数据
2:卷中的更改可以直接生效
3:数据卷中的更改不会包含在镜像的更新中
4:数据卷的生命周期一直持续到没有容器使用它为止

4. 添加容器卷

  • 直接命令添加
 docker run -it -v /宿主机绝对路径目录:/容器内目录 镜像名
 docker run -it -v /宿主机绝对路径目录:/容器内目录:ro 镜像名 #带读写权限

查看容器卷是否挂载成功
docker inspect 容器ID #查看volumes相关的是否正确

  • DockerFile添加
mkdir /mydocker #根目录下创建mydocker
cd mydocker #进入mydocker目录下
vi dockerfile #写入命令
    FROM centos
    VOLUME ["/dataVolumeContainer1","/dataVolumeContainer2"]
    CMD echo "finished,--------success1"
    CMD /bin/bash
    #注意,FROM centos的这个centos你要事先pull下来
docker build -f /mydocker/dockerfile -t mycentos #build后生成镜像
docker run -it mycentos /bin/bash #新建并运行容器
docker inspeect 容器名 #可以查看容器卷地址对应的主机目录地址在哪
  • Docker挂载主机目录Docker访问出现cannot open directory .: Permission denied

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

5. 数据卷容器

  • 是什么?

命名的容器挂载数据卷,其它容器通过挂载这个(父容器)实现数据共享,挂载数据卷的容器,称之为数据卷容器

  • 容器间传递共享
docker run -it --name dc01 mycentos /bin/bash   #mycentos是5.4通过Dockerfile生成的镜像
docker run -it --name dc02 --volumes-from dc01 zzyy/centos  #以dc01为父容器,使dc02继承它
docker run -it --name dc03 --volumes-from dc01 zzyy/centos  #以dc01为父容器,使dc03继承它

#以上dc01、dc02、dc03每两个之间都可以共享数据,删除任何一个,不影响其他容器之间共享数据。
#结论:容器之间配置信息的传递,数据卷的生命周期一直持续到没有容器使用它为止。

六、DockerFile解析

1. 是什么?

Dockerfile是用来构建Docker镜像的构建文件,是由一系列命令和参数构成的脚本。案例:


在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

构建步骤:
1.编写Dockerfile文件
2.docker build
3.docker run

2. Dockerfile构建过程

  • 基础知识

1:每条保留字指令都必须为大写字母且后面要跟随至少一个参数
2:指令按照从上到下,顺序执行
3:#表示注释
4:每条指令都会创建一个新的镜像层,并对镜像进行提交

  • Docker执行Dockerfile的大致流程

(1)docker从基础镜像运行一个容器
(2)执行一条指令并对容器作出修改
(3)执行类似docker commit的操作提交一个新的镜像层
(4)docker再基于刚提交的镜像运行一个新容器
(5)执行dockerfile中的下一条指令直到所有指令都执行完成

  • 总结

从应用软件的角度来看,Dockerfile、Docker镜像与Docker容器分别代表软件的三个不同阶段,

  • Dockerfile是软件的原材料
  • Docker镜像是软件的交付品
  • Docker容器则可以认为是软件的运行态。

Dockerfile面向开发,Docker镜像成为交付标准,Docker容器则涉及部署与运维,三者缺一不可,合力充当Docker体系的基石。


在这里插入图片描述
  1. Dockerfile,需要定义一个Dockerfile,Dockerfile定义了进程需要的一切东西。Dockerfile涉及的内容包括执行代码或者是文件、环境变量、依赖包、运行时环境、动态链接库、操作系统的发行版、服务进程和内核进程(当应用进程需要和系统服务和内核进程打交道,这时需要考虑如何设计namespace的权限控制)等等;
  2. Docker镜像,在用Dockerfile定义一个文件之后,docker build时会产生一个Docker镜像,当运行 Docker镜像时,会真正开始提供服务;
  3. Docker容器,容器是直接提供服务的。

3. DockerFile体系结构(保留字指令)

FROM 基础镜像 #当前新镜像是基于哪个镜像的
MAINTAINER #镜像维护者的姓名和邮箱地址
RUN #容器构建时需要运行的命令
EXPOSE #当前容器对外暴露出的端口
WORKDIR #指定在创建容器后,终端默认登陆的进来工作目录,一个落脚点
ENV #用来在构建镜像过程中设置环境变量
    ENV MY_PATH /usr/mytest
    这个环境变量可以在后续的任何RUN指令中使用,这就如同在命令前面指定了环境变量前缀一样;
    也可以在其它指令中直接使用这些环境变量,     
    比如:WORKDIR $MY_PATH
ADD #将宿主机目录下的文件拷贝进镜像且ADD命令会自动处理URL和解压tar压缩包
COPY #类似ADD,拷贝文件和目录到镜像中。
     将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的 <目标路径> 位置
VOLUME #容器数据卷,用于数据保存和持久化工作
CMD #指定一个容器启动时要运行的命令
    启动命令有两种格式:
        shell格式:CMD<命令>
        exec格式:CMD["可执行文件","参数1","参数2",...]
        参数列表格式:CMD["参数1","参数2",...]。在指定了ENTRYPOINT指令后,用CMD指定具体的参数。
    Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效,CMD 会被 docker run 之后的参数替换
ENTRYPOINT #指定一个容器启动时要运行的命令
           # ENTRYPOINT 的目的和 CMD 一样,都是在指定容器启动程序及参数
           # 当指定了 ENTRYPOINT 之后,CMD的含义就发生了变化,不再是直接的运行其命令
              ,而是将 CMD 的内容作为参数传给 ENTRYPOINT 指令,
ONBUILD #当构建一个被继承的Dockerfile时运行命令,父镜像在被子继承后,父镜像的onbuild被触发
           #(取材自菜鸟教程)用于延迟构建命令的执行。简单的说,就是 Dockerfile 里用 ONBUILD  
            指定的命令,在本次构建镜像的过程中不会执行(假设镜像为 test-build)。
            当有新的 Dockerfile 使用了之前构建的镜像 FROM test-build ,这是执行新镜像的 Dockerfile 构建时候,
            会执行 test-build 的 Dockerfile 里的 ONBUILD 指定的命令。

4. 总结

在这里插入图片描述

六、Docker常用安装

1. 总体步骤

搜索镜像 =》 拉取镜像 =》 查看镜像 =》 启动镜像 =》 停止容器 =》 移除容器

2. 安装tomcat

docker serach tomcat #dockerHub上寻找tomcat
docker pull tomcat #从dockerHub上拉去tomcat镜像到本地
docker images #查看是否拉取成功
docker run -it -p 8080:8080 tomcat #新建并运行tomcat容器

3. 安装mysql

docker serach mysql #dockerHub上寻找mysql
docker pull mysql:5.6 #从dockerHub上拉去mysql镜像到本地
docker images #查看是否拉取成功
docker run -p 3306:3306 --name mysql -v /zzyyuse/mysql/conf:/etc/mysql/conf.d -v /zzyyuse/mysql/logs:/logs -v /zzyyuse/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.6
    #命令说明:
    -p 3306:3306:将主机的3306端口映射到docker容器的3306端口。
    --name mysql:运行服务名字
    -v /zzyyuse/mysql/conf:/etc/mysql/conf.d :将主机/zzyyuse/mysql录下的conf/my.cnf 挂载到容器的 /etc/mysql/conf.d
    -v /zzyyuse/mysql/logs:/logs:将主机/zzyyuse/mysql目录下的 logs 目录挂载到容器的 /logs。
    -v /zzyyuse/mysql/data:/var/lib/mysql :将主机/zzyyuse/mysql目录下的data目录挂载到容器的 /var/lib/mysql 
    -e MYSQL_ROOT_PASSWORD=123456:初始化 root 用户的密码。
    -d mysql:5.6 : 后台程序运行mysql5.6

4. 安装redis

docker pull redis:3.2
docker run -p 6379:6379 -v /zzyyuse/myredis/data:/data -v /zzyyuse/myredis/conf/redis.conf:/usr/local/etc/redis/redis.conf  -d redis:3.2 redis-server /usr/local/etc/redis/redis.conf --appendonly yes
在主机/zzyyuse/myredis/conf/redis.conf目录下新建redis.conf文件
    vim /zzyyuse/myredis/conf/redis.conf/redis.conf
docker exec -it 运行着Rediis服务的容器ID redis-cli #测试redis-cli连接上来

七、本地镜像发布到阿里云

1. 流程

在这里插入图片描述

2. 镜像生成

  1. 前面的DockerFile
  2. 从容器创建一个新的镜像
    docker commit [OPTIONS] 容器ID [REPOSITORY[:TAG]]

3. 将本地镜像推送到阿里云

参考:https://blog.csdn.net/weixin_38399962/article/details/102897534

你可能感兴趣的:(docker笔记-基础篇)