【docker基础学习篇1】---docker原理以及docker镜像制作


前言

在了解docker之间首先需要理解两个概念:容器和虚拟机。
虚拟机
虚拟机(VM)是共享一个服务器的物理资源的操作系统。它是主机硬件上的Guest,因此也被称为Guest虚拟机。虚拟机由几层组成。支持虚拟化的层hypervisor。hypervisor是一种虚拟化服务器的软件。
我们使用传统的虚拟机如VMware、VisualBox等需要模拟出一台机器包括硬件、操作系统。一台虚拟机启动后可能占用主机的大量系统资源,虚拟机的大小为数GB。在虚拟服务器上运行单个应用程序意味着还要运行Guest OS以及Guest OS运行所需的所有硬件的虚拟副本。这样很快就增加了很多RAM和CPU资源消耗。运行应用程序所需的一切都包含在虚拟机里–虚拟化的硬件,操作系统以及任何所需的二进制文件和库。因此,虚拟机具有自己独立的基础架构。其工作原理如下图:
在这里插入图片描述
容器:
容器是一个不依赖于操作系统,运行应用程序的环境。在Linux中它通过Namespace(命令空间)和Cgroups(controlgroups 控制组)技术对应用程序进行隔离和限制。Namespace的作用是隔离(隔离进程),他让应用进程只能看到该Namespace内的世界;而Cgroups的作用是限制分配给该进程的宿主机资源,但是对于该宿主机来说,这些被隔离的进程和其他应用进程没有太大区别。

一个容器就是一个进程,多容器之间使用同一个宿主机的操作系统内核
请添加图片描述
容器启动前会使用mount Namespace隔离一个具有独立挂载点信息的运行环境.具有独立挂载点信息意味着每个mnt namespace(一种数据结构)可具有独立的目录层次,这在容器中起很大的作用,使得容器可以挂载只属于自己的文件系统(即容器自己的根文件系统rootfs)。
mount namespace可隔离出一个具有独立挂载点信息的运行环境,内核知道如何去维护每个namespace的挂载点列表。即每个namespace之间的挂载点列表是独立的,各自挂载互不影响」。
内核将每个进程的挂载点信息保存在/proc/[pid]/{mountinfo,mounts,mountstats}三个文件中:
在这里插入图片描述Mnt_namespace分析

一、docker是什么?

Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口.

1、什么是沙箱机制?
沙箱就是一个限制应用程序对系统资源的访问的运行环境
2、为什么需要沙箱机制?
默认情况下,一个应用程序是可以访问机器上的所有资源的,比如CPU、内存、文件系统、网络等等。
但是这是不安全的,如果随意操作资源,有可能破坏其他应用程序正在使用的资源,或者造成数据泄漏。为了解决这个问题,一般有下面两种解决方案:
(1) 为程序分配一个限定权限的账号:利用操作系统的权限管理机制进行限制
(2) 为程序提供一个受限的运行环境:这就是沙箱机制

二、docker和传统虚拟机的差别

docker和虚拟机的对比docker的优势:
启动速度快
资源消耗小,资源可控,因为一个容器就是一个进程、
容易扩展,快速的复制,只需要启动一个进程即可(持续交付和部署)
每个容器占用的空间比VM少
docker的劣势:
隔离性不如VM,安全性相较低。用为容器都是使用同一个操作系统结构,相同的底层硬件;docker停止所有的容器也就停止了。
在这里插入图片描述

三、 docker中的三个概念

镜像(image):打包好的软件,包含程序代码、基础系统、依赖关系的软件包、系统库、工具等
容器(container):运行镜像的地方,背后就是启动一个进程运行某个镜像
仓库(repository):集中存放镜像的地方。

四、 docker运行原理以及启动流程

docker的运行原理


docker客户端(docker client)中运行docker的各种命令,而这些命令会传递给docker的宿主机上运行docker的守护进程。而docker的守护进程负责实现docker的各种功能
docker的守护进程运行在宿主机上,也就是cs架构的server端,守护进程会在启动后一直在后台运行。负责实现docker的各种功能。而docker使用者并不会直接与守护进程交互,而是要通过docker的客户端,也就是docker的命令行接口来与docker守护进程进行通信,也就是在shell中运行的docker的二进制程序。接收docker的守护进程的执行命令,然后将结果返回给客户端,显示在命令行中。

镜像的分层思想

首先要知道docker镜像的分层思想

  1. 最低层——内核层(base image):提供物理机的kernel、bootfs和rootfs.
  2. 中间层——镜像层(add image):app镜像,可以不断叠加;比如nginx镜像的yum安装模块,或者nginx编译安装的指令,使用镜像封装每一个run执行命令
  3. 最顶层——容器层(container):读写执行层,将下面的镜像组合运行提供给docker client使用

Docker 的镜像实际上由一层一层的文件系统组成,这种层级的文件系统就是UnionFS。在Docker镜像的最底层是bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。Docker在bootfs之上的一层是rootfs(根文件系统)。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等
在这里插入图片描述
因为docker容器内运行的是镜像文件,一个docker镜像由多个镜像层组成。运行的容器都会在docker的镜像上面多加一层可写的容器层,任何对文件的更改都是存在于容器层,因此对容器的操作均不会影响到镜像。

在这里插入图片描述
至于容器如何获取镜像层文件而又不影响到是镜像层的呢?docker是这样实现的
如果需要获取某个文件,那么容器层会从上到下去下一层的镜像层去获取文件,如果该层文件不存在,那么就会去下一镜像层去寻找,直到最后一层。对于用户而言,用户面对的是一个叠加后的文件系统。而任何对于文件的操作都会记录在容器层,例如说修改文件,容器层会把在镜像层找到的文件拷贝到容器层然后进行修改,删除文件则会在容器层内记录删除文件的记录。

为什么 Docker 镜像要采用这种分层结构?
最大的一个好处就是 - 共享资源。
比如:有多个镜像都从相同的 base 镜像构建而来,那么 Docker Host 只需在磁盘上保存一份 base 镜像;同时内存中也只需加载一份 base 镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享,我们将在后面更深入地讨论这个特性。

docker容器的启动过程:

docker启动流程
首先系统要有一个docker daemon的后台进程正在运行

  1. docker client会调用docker daemon请求一个容器
  2. docker daemon会向host os(即linux)请求创建容器
  3. linux会创建一个空的容器(可以简单理解为一个未安装操作系统的裸机,只有虚拟出来的CPU、内存等硬件资源)
  4. docker daemon请求检查本机是否有docker镜像文件(可以简单理解为操作系统的安装盘)如果有,就加载到容器中,如果没有会去docker hub网站下载
  5. 将镜像文件加载到容器中。此时一个容器就创建完成。

五、 如何构建docker镜像文件(Dockerfile文件)

什么是 Dockerfile?
Dockerfile 是一个用来构建镜像的文本文件
使用 Dockerfile 制作镜像

1、创建工作目录

 mkdir nginx

2、进入工作目录新建index页面

cd nginx
vim index.html
docker nginx build successful

3、在nginx目录下新建dockerfile文件

vim dockerfile
#基准镜像
FROM centos:7
#作者信息
MAINTAINER "zhbr_zyn"
#工作目录
WORKDIR /usr/local/src/ 
#定义环境变量
ENV NG_VERSION nginx-1.21.0 
#安装epel仓库
RUN yum -y install epel-release 
#安装wget
RUN yum -y install wget 
#下载nginx文件并解压
RUN wget http://nginx.org/download/$NG_VERSION.tar.gz && tar xzvf $NG_VERSION.tar.gz 
#安装编译依赖包
RUN yum install -y gcc gcc-c++ glibc make autoconf openssl openssl-devel && yum install -y pcre-devel libxslt-devel gd-devel GeoIP GeoIP-devel GeoIP-data
#清理仓库
RUN yum clean all 
#创建nginx用户
RUN useradd -M -s /sbin/nologin nginx 
#切换工作目录
WORKDIR /usr/local/src/$NG_VERSION 
#编译安装nginx
RUN ./configure --user=nginx --group=nginx --prefix=/usr/local/nginx --with-file-aio --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module --with-http_image_filter_module --with-http_geoip_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_auth_request_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_stub_status_module && make && make install
#复制测试页面到容器中
ADD index.html /usr/local/nginx/html 
#设置容器中要挂在到宿主机的目录
VOLUME /usr/local/nginx/html 
#设置sbin环境变量
ENV PATH /usr/local/nginx/sbin:$PATH 
#暴露80端口
EXPOSE 80/tcp 
ENTRYPOINT ["nginx"]
CMD ["-g","daemon off;"]
#当ENTRYPOINT和CMD连用时,CMD的命令是ENTRYPOINT命令的参数,两者连用相当于nginx -g "daemon off;"而当一起连用的时候命令格式最好一致(这里选择的都是json格式的是成功的,如果都是sh模式可以试一下)

4、构建镜像

//注意:镜像名字必须是小写
docker build ./ -t centOS7_nginx

在这里插入图片描述
5、查看镜像

docker images

在这里插入图片描述
6、启动容器

docker run --name my_nginx -d -p 8080:80 2926b221fb14

7、查看Linux8080端口是否开启
在这里插入图片描述
8、访问nginx

http:// ip地址:8080

在这里插入图片描述

六、 dockerfile文件详解

指令含义解释
FROMFROM centos:7表示以centos:7作为基础镜像进行构建
MAINTAINERMAINTAINER name 用来声明维护者信息,该命令已经过期,推荐使用 LABEL
LABEL用于为镜像添加元数据,多用于声明构建信息,作者、机构、组织等 示例;LABEL version=“1.0” description=“felord.cn” by=“Felordcn”
ENVENV 用来设置环境变量 之后的所有内容均会被视为其的组成部分,一次只能设置一个变量
ARG用于指定传递给构建运行时的变量 ,通过 docker run 中的 --build-arg = 来动态赋值,不指定将使用其默认值
WORKDIR用来指定工作目录,类似于我们通常使用的cd 命令 过 WORKDIR 设置工作目录,Dockerfile 中的其它指令 RUN、CMD、ENTRYPOINT、ADD、COPY等命令都会在该目录下执行。在使用 docker run 运行容器时,可以通过 -w 参数覆盖构建时所设置的工作目录。
ADDADD 用于将本地文件添加到镜像中,tar 类型文件会自动解压(网络压缩资源不会被解压),可以访问网络资源,类似 wget,格式:ADD [src]… [dest]
COPYCOPY 的功能类似于 ADD,但是不会自动解压文件,也不能访问网络资源
RUNRUN 用来执行构建镜像时执行的命令,有以下两种命令执行方式:1、shell执行格式 RUN [command] 2、exec执行格式 RUN [“executable”, “param1”, “param2”]
CMDCMD 构建容器后执行的命令,也就是在容器启动时才执行的命令 。CMD 不同于 RUN,CMD 用于指定在容器启动时所要执行的命令,而RUN用于指定镜像构建时所要执行的命令。
ENTRYPOINTENTRYPOINT 用来配置容器,使其可执行化。配合 CMD可省去 application,只使用参数。Dockerfile 中只有最后一个 ENTRYPOINT 命令起作用。格式:可执行文件,优先 ENTRYPOINT [“executable”, “param1”, “param2”]。 shell内部命令 ENTRYPOINT command param1 param2
EXPOSEEXPOSE 指定与外界交互的端口
VOLUMEVOLUME 用于指定持久化目录。该目录可以被容器本身使用,也可以共享给其他容器使用、容器默认使用的是AUFS,这种文件系统不能持久化数据,当容器关闭后,所有的更改都会丢失。VOLUME [mountpoint]
USERUSER 指定运行容器时的用户名或 UID,后续的 RUN 也会使用指定用户。使用 USER 指定用户时,可以使用用户名、UID 或GID,或是两者的组合。当服务不需要管理员权限时,可以通过该命令指定运行用户。并且可以在之前创建所需要的用户
ONBUILDONBUILD 作用是其当所构建的镜像被用做其它镜像的基础镜像,该镜像中的 ONBUILD 中的命令就会触发
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值