Docker 教程

Docker 教程

1 认识Docker

1.1 Docker 解决操作系统环境差异的问题

应用于计算机交互的流程如下:

(1)应用调用操作系统应用(函数库),实现各种功能;

(2)系统函数库是对内核指令集的封装,会调用内核指令;

(3)内核指令操作计算机硬件。

Docker将用户程序与所需要调用的系统函数库一起打包,Docker运行到不同操作系统时,直接基于打包的函数库,借助于操作系统的Linux内核来运行。如图:

在这里插入图片描述

小结:

  • Docker如何解决大型项目依赖关系复杂,不同组件依赖的兼容性问题?

    • Docker允许开发中将应用、依赖、函数库、配置一起打包,形成可移植镜像。

    • Docker应用运行在容器中,使用沙箱机制,相互隔离

  • Docker如何解决开发、测试、生产环境有差异的问题?

    • Docker镜像中包含完整运行环境,包括系统函数库,仅依赖系统的Linux内核,因此可以在任意Linux操作系统上运行。
  • Docker是一个快速交付应用、运行应用的技术,具备下列优势:

    • 可以将程序及其依赖、运行环境一起打包为一个镜像,可以迁移到任意Linux操作系统;

    • 运行时利用沙箱机制形成隔离容器,各个应用互不干扰;

    • 启动、移除都可以通过一行命令完成,方便快捷。

1.2 Docker和虚拟机的区别

虚拟机(virtual machine)是在操作系统中模拟硬件设备,然后运行另一个操作系统,比如在 Windows 系统里面运行 Ubuntu 系统,这样就可以运行任意的Ubuntu应用了。

Docker 仅仅是封装函数库,并没有模拟完整的操作系统,如图:

在这里插入图片描述

对比来看:

在这里插入图片描述

小结:

Docker和虚拟机的差异:

  • docker是一个系统进程;虚拟机是在操作系统中的操作系统。

  • docker体积小、启动速度快、性能好;虚拟机体积大、启动速度慢、性能一般。

1.3 Docker架构

1.3.1 镜像和容器

Docker中有几个重要的概念:

镜像(Image):Docker将应用程序及其所需的依赖、函数库、环境、配置等文件打包在一起,称为镜像。

容器(Container):镜像中的应用程序运行后形成的进程(镜像创建的实例)就是容器,Docker会给容器进程做隔离,对外不可见。

一切应用最终都是代码组成,都是硬盘中的一个个的字节形成的文件。只有运行时,才会加载到内存,形成进程。

镜像,就是把一个应用在硬盘上的文件、及其运行环境、部分系统函数库文件一起打包形成的文件包。这个文件包是只读的。

容器,就是将这些文件中编写的程序、函数加载到内存中允许,形成进程,只不过要隔离起来。因此一个镜像可以启动多次,形成多个容器进程。

在这里插入图片描述

1.3.2 DockerHub

开源应用程序非常多,打包这些应用往往是重复的劳动。为了避免这些重复劳动,人们就会将自己打包的应用镜像,例如Redis、MySQL镜像放到网络上,共享使用,就像GitHub的代码共享一样。

  • DockerHub:DockerHub是一个官方的Docker镜像的托管平台。这样的平台称为Docker Registry。

  • 国内也有类似于DockerHub 的公开服务,比如 网易云镜像服务阿里云镜像库等。

我们一方面可以将自己的镜像共享到DockerHub,另一方面也可以从DockerHub拉取镜像:

在这里插入图片描述

1.3.3 Docker架构

我们要使用Docker来操作镜像、容器,就必须要安装Docker。

Docker是一个CS架构的程序,由两部分组成:

  • 服务端(server):Docker守护进程,负责处理Docker指令,管理镜像、容器等。

  • 客户端(client):通过命令向Docker服务端发送指令,可以在本地或远程向服务端发送指令。

如图:

在这里插入图片描述

在这里插入图片描述

1.3.4 小结
  • 镜像:

    • 将应用程序及其依赖、环境、配置打包在一起
  • 容器:

    • 镜像运行起来就是容器,一个镜像可以运行多个容器
  • Docker结构:

    • 服务端:接收命令或远程请求,操作镜像或容器

      • 客户端:发送命令或者请求到Docker服务端
  • DockerHub:

    • 一个镜像托管的服务器,类似的还有阿里云镜像服务,统称为DockerRegistry

1.4 安装 Docker

# 根据自己的网络情况选择其中一种方式安装
# 1.官方网站安装
curl https://get.docker.com | sh 
# 2.官方网站并使用阿里云加速
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
# 3.国内 daocloud 一键安装命令
curl -sSL https://get.daocloud.io/docker | sh

配置阿里云镜像加速 https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors

2 Docker的基本操作

2.1 docker 进程相关命令

在这里插入图片描述

2.2 镜像操作命令

镜像名称的组成:

  • 镜名称一般分两部分组成:[image_name]:[tag]
  • 在没有指定tag时,默认是latest,代表最新版本的镜像

常见的镜像操作命令如图:

在这里插入图片描述

  • 查看镜像:查看本地所有镜像

    docker images
    docker images -q  # 查看所有镜像的id
    
  • 搜索镜像:从网络中查找需要的镜像

    docker search [镜像名称]
    
  • 拉取镜像:从Docker仓库下载镜像到本地,镜像名称格式为:[name:version],不指定版本号则是最新版本,可以去 Docker hub 搜索对应镜像查看

    docker pull [镜像名称]
    docker pull ubuntu:18.04
    
  • 删除镜像:删除本地镜像

    docker rmi [镜像ID]  # 删除本地指定镜像
    docker rmi `docker images -q`  # 删除本地所有镜像
    
  • 导出保存镜像:利用docker save将镜像导出磁盘,然后再通过load加载回来

    docker save -o [保存的目标文件名称] [镜像名称]
    docker save -o ubuntu.tar ubuntu:18.04
    
  • 加载本地镜像:

    # 先删除本地已存在的同名镜像,再加载
    docker load -i ubuntu.tar
    

2.3 容器操作命令

2.3.1 容器相关命令

容器操作的命令如图:

在这里插入图片描述

容器保护三个状态:

  • 运行:进程正常运行
  • 暂停:进程暂停,CPU不再运行,并不释放内存
  • 停止:进程终止,回收进程占用的内存、CPU等资源

其中:

  • docker run:创建并运行一个容器,处于运行状态

  • docker pause [CONTAINER ID]:让一个运行的容器暂停

  • docker unpause [CONTAINER ID]:让一个容器从暂停状态恢复运行

  • docker stop [CONTAINER ID]:停止一个运行的容器

  • docker start [CONTAINER ID]:让一个停止的容器再次运行

  • docker rm [CONTAINER ID]:删除一个容器

2.3.2 案例-创建并运行一个容器

首先拉取一个镜像:

docker pull ubuntu:18.04

创建并运行容器:

docker run -it --name=u1 ubuntu:18.04 /bin/bash

参数说明:

  • -i:交互式操作
  • -t:终端,即创建容器后直接进入
  • –name:创建容器的名字
  • ubuntu:18.04 :镜像名字,使用该镜像创建容器
  • /bin/bash:放在镜像名后,我们希望有个交互式 Shell,因此用的是 /bin/bash

退出容器:

exit

启动已停止运行的容器:

docker ps -a  # 查看所有的容器
docker start [CONTAINER ID]/[CONTAINER NAME]  # 使用容器ID或容器名字都行

后台(保护进程)运行:在大部分的场景下,我们希望 docker 的服务是在后台运行的,我们可以过 -d 指定容器的运行模式

docker run -itd --name=u2 ubuntu:18.04 /bin/bash

加了 -d 参数默认不会进入容器,想要进入容器需要使用指令 docker exec

进入容器:推荐使用 docker exec 命令,因为此命令会退出容器终端,但不会导致容器的停止。

docker exec -it [CONTAINER ID] /bin/bash
2.3.3 案例-运行一个 web 应用

接下来让我们尝试使用 docker 构建一个 web 应用程序。

我们将在docker容器中运行一个 Python Flask 应用来运行一个web应用。

首先拉取一个镜像:

docker pull training/webapp

创建并运行容器:

docker run --name=web1 -d -P training/webapp python app.py

参数说明:

  • -d:让容器在后台运行
  • -P:将容器内部使用的网络端口随机映射到宿主机上

在这里插入图片描述

这里多了端口信息:

PORTS
0.0.0.0:49153->5000/tcp

Docker 开放了 5000 端口(默认 Python Flask 端口)映射到宿主机端口 49153 上,这时我们可以通过浏览器访问WEB应用。

在这里插入图片描述

也可以通过 -p 参数来设置不一样的端口:

docker run --name=web2 -d -p 5000:5000 training/webapp python app.py

参数说明:

  • -p :将宿主机端口与容器端口映射,冒号左侧是宿主机端口,右侧是容器端口

在这里插入图片描述

在这里插入图片描述

使用 docker port 查看指定容器的端口映射

docker port [CONTAINER ID]/[CONTAINER NAME]

在这里插入图片描述

2.3.4 其他相关命令

查看容器内部的标准输出

docker logs [CONTAINER ID]/[CONTAINER NAME]

查看容器内部运行的进程

docker top [CONTAINER ID]/[CONTAINER NAME]

查看 Docker 的底层详细信息

docker inspect [CONTAINER ID]/[CONTAINER NAME]

导出容器快照

docker export [CONTAINER ID]/[CONTAINER NAME] > ubuntu.tar

导入容器快照

cat ubuntu.tar | docker import - ubuntu:18.04
# 也可以通过指定URL或者某个目录来导入
docker import http://example.com/exampleimage.tgz example/imagerepo

2.4 数据卷(容器数据管理)

2.4.1 数据卷概念

**数据卷(volume)**是一个虚拟目录,指向宿主机文件系统中的某个目录。

在这里插入图片描述

一旦完成数据卷挂载,对容器的一切操作都会作用在数据卷对应的宿主机目录。

这样,我们操作宿主机的 /var/lib/docker/volumes/html 目录,就等于操作容器内的 /usr/share/nginx/html 目录。

在这里插入图片描述

2.4.2 数据卷操作命令
  • docker volume create:创建数据卷
  • docker volume ls:查看所有数据卷
  • docker volume inspect:查看数据卷详细信息,包括关联的宿主机目录位置
  • docker volume rm:删除指定数据卷
  • docker volume prune:删除所有未使用的数据卷
2.4.3 创建容器时挂载数据卷

我们在创建启动容器时,可以通过 -v 参数来设置数据卷

docker run ... –v 宿主机目录(文件):容器内目录(文件) ...

这里的 -v 就是挂载数据卷的命令

  • 注意事项:

    1. 目录必须是绝对路径

    2. 如果目录不存在,会自动创建

    3. 可以挂载多个数据卷

2.4.4 数据卷容器

多容器进行数据交换:

  1. 多个容器挂载同一个数据卷
  2. 数据卷容器

在这里插入图片描述

配置数据卷容器:

  1. 创建启动 c3 数据卷容器,使用 –v 参数 设置数据卷

    docker run –it --name=c3 –v /volume ubuntu:18.04 /bin/bash
    

​ 注:可以省略宿主机目录,系统会自动分配一个宿主机目录,因此可以只写 –v /volume

  1. 创建启动 c1 c2 容器,使用 –-volumes-from 参数 设置数据卷

    docker run –it --name=c1 --volumes-from c3 ubuntu:18.04 /bin/bash
    docker run –it --name=c2 --volumes-from c3 ubuntu:18.04 /bin/bash
    
2.4.5 创建和查看数据卷

需求:创建一个数据卷,并查看数据卷在宿主机的目录位置

创建数据卷

docker volume create data

查看所有数据卷

docker volume ls

结果:

在这里插入图片描述

查看数据卷详细信息

docker volume inspect data

结果:

在这里插入图片描述

可以看到,我们创建的data这个数据卷关联的宿主机目录为/var/lib/docker/volumes/data/_data目录。

2.4.6 小结
  • 数据卷概念

    • 宿主机的一个目录或文件
  • 数据卷作用

    • 容器数据持久化
    • 客户端和容器数据交换
    • 容器间数据交换
  • 数据卷容器

    • 创建一个容器,挂载一个目录,让其他容器继承自该容器( --volume-from )。
    • 通过简单方式实现数据卷配置

3 Dockerfile 自定义镜像

思考:

  • Docker 镜像本质是什么?
  • Docker 中一个 centos镜像为什么只有200MB,而一个 centos操作系统的iso文件要几个G?
  • Docker 中一个 tomcat镜像为什么有500MB,而一个 tomcat安装包只有70多MB?

3.1 镜像原理

Linux文件系统由bootfs和rootfs两部分组成

  • bootfs:包含 bootloader(引导加载程序)和 kernel(内核);
  • rootfs:root文件系统,包含的就是典型 Linux 系统中的 /dev,/proc,/bin,/etc 等标准目录和文件;
  • 不同的 linux 发行版,bootfs 基本一样,而 rootfs 不同,如ubuntu,centos等。

在这里插入图片描述

Docker 镜像是由特殊的文件系统叠加而成:

  • 最底端是 bootfs,Docker 镜像使用宿主机的 bootfs;
  • 第二层是 root文件系统 rootfs,称为 base image(基础镜像);
  • 然后再往上可以叠加其他的镜像文件;
  • 统一文件系统(Union File System)技术能够将不同的层整合成一个文件系统,为这些层提供了一个统一的视角,这样就隐藏了多层的存在,在用户的角度看来,只存在一个文件系统;
  • 一个镜像可以放在另一个镜像的上面。位于下面的镜像称为父镜像,最底部的镜像成为基础镜像;
  • 当从一个镜像启动容器时,Docker会在最顶层加载一个读写文件系统作为容器

在这里插入图片描述

此时可以回答上面思考的问题:

  • Docker 镜像本质是什么?
    • 是一个分层文件系统
  • Docker 中一个 centos镜像为什么只有200MB,而一个 centos操作系统的iso文件要几个G?
    • Centos的iso镜像文件包含bootfs和rootfs,而docker的centos镜像复用操作系统的bootfs,只有rootfs和其他镜像层
  • Docker 中一个 tomcat镜像为什么有500MB,而一个 tomcat安装包只有70多MB?
    • 由于docker中镜像是分层的,tomcat虽然只有70多MB,但他需要依赖于父镜像和基础镜像,所有整个对外暴露的tomcat镜像大小500多MB

3.2 镜像制作

当已有镜像不满足自己的需求时,我们一般会在已有镜像的基础上,添加自己的需求,再制作成新的镜像。

镜像文件是只读的,我们只能通过可写容器增加改变,再把容器转为镜像。

容器转为镜像:

docker commit -m="lsf update" -a="lsf" [容器id] [镜像名称:版本号]
# -m: 提交的描述信息   -a: 指定镜像作者
# 在本机上已经可以使用新镜像,若要部署到其他电脑,则需导出成压缩文件,再导入镜像
docker save -o [压缩文件名称] [镜像名称:版本号]
docker load –i [压缩文件名称]

例如:

docker commit -m="lsf update" -a="lsf" 28hdwd839 lsf_ubuntu:1.0
docker save -o lsf_ubuntu.tar lsf_ubuntu:1.0
docker load –i lsf_ubuntu.tar

在这里插入图片描述

3.3 Dockerfile语法

构建自定义的镜像时,并不需要一个个文件去拷贝,打包。

我们只需要告诉Docker,我们的镜像的组成,需要哪些BaseImage、需要拷贝什么文件、需要安装什么依赖、启动脚本是什么,将来Docker会帮助我们构建镜像。

而描述上述信息的文件就是Dockerfile文件。

Dockerfile 就是一个文本文件,其中包含一个个的 指令(Instruction),用指令来说明要执行什么操作来构建镜像。每一个指令都会形成一层Layer。

关键字作用备注
FROM指定父镜像指定dockerfile基于哪个image构建
MAINTAINER作者信息用来标明这个dockerfile谁写的
LABEL标签用来标明dockerfile的标签,可以使用Label代替Maintainer,最终都是在docker image基本信息中可以查看
RUN执行命令执行一段命令,默认是/bin/sh,格式: 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 [“目录”]
EXPOSE暴露端口定义容器运行的时候监听的端口,启动容器的使用-p来绑定暴露端口,格式: EXPOSE 8080 或者 EXPOSE 8080/udp
WORKDIR工作目录指定容器内部的工作目录,如果没有创建则自动创建,如果指定/,使用的是绝对地址,如果不是/开头,那么是在上一条workdir的路径的相对路径
USER指定执行用户指定build或者启动的时候用户在RUN CMD ENTRYPONT执行的时候的用户
HEALTHCHECK健康检查指定监测当前容器的健康监测的命令,基本上没用,因为很多时候应用本身有健康监测机制
ONBUILD触发器当存在ONBUILD关键字的镜像作为基础镜像的时候,当执行FROM完成之后,会执行ONBUILD的命令,但是不影响当前镜像,用处也不怎么大
STOPSIGNAL发送信号量到宿主机该STOPSIGNAL指令设置将发送到容器的系统调用信号以退出。
SHELL指定执行脚本的shell指定RUN CMD ENTRYPOINT 执行命令的时候使用的shell

更新详细语法说明,请参考官网文档: https://docs.docker.com/engine/reference/builder

或 菜鸟教程文档: https://www.runoob.com/docker/docker-dockerfile.html

4 Docker 镜像仓库

4.1 Docker Hub

网站: https://hub.docker.com

docker login  # 登录账号
docker logout  # 登出账号
docker pull ubuntu:18.04  # 拉取镜像
docker tag ubuntu:18.04 lsfeng/ubuntu:18.04  # 打标签
docker push lsfeng/ubuntu:18.04  # 推送镜像

4.2 私有镜像仓库

4.2.1 私有仓库搭建
  1. 拉取私有仓库镜像

    docker pull registry
    
  2. 启动私有仓库容器

    docker run -id --name=registry -p 5000:5000 registry
    
  3. 打开浏览器,输入地址:http://私有仓库服务器ip:5000/v2/_catalog,看到{"repositories":[]},表示私有仓库搭建成功

    在这里插入图片描述

  4. 修改daemon.json

    vim /etc/docker/daemon.json 
    # 在上述文件中添加一个key,保存退出。用于让docker信任私有仓库地址。
    {"insecure-registries":["私有仓库服务器ip:5000"]} 
    
  5. 重启docker 服务

    systemctl restart docker
    docker start registry
    
4.2.2 将镜像上传至私有仓库
# 1、标记镜像为私有仓库的镜像     
docker tag ubuntu:18.04 私有仓库服务器IP:5000/ubuntu:18.04
 
# 2、上传标记的镜像     
docker push 私有仓库服务器IP:5000/ubuntu:18.04
4.2.3 从私有仓库拉取镜像
#拉取镜像 
docker pull 私有仓库服务器ip:5000/ubuntu:18.04

参考
菜鸟教程
黑马程序员bilibili

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值