0.docker原理

Docker

1. Docker简介

docker是一门虚拟化容器技术,其将应用程序与该程序的依赖,打包在一个镜像文件中。将镜像文件导入docker引擎运行,就会生成一个虚拟容器,程序在这个虚拟容器里运行,与在真实的物理机上运行一样,docker为程序的运行提供了独立的环境。

2. Docker架构

docker采用的是C/S架构。客户端向服务器发送请求,服务器负责构建、运行和分发容器。客户端和服务器可以运行在同一个Host上,客户端也可以通过socket或者REST API与远程的服务器通信。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oVoysWk9-1606457733450)(/images/16e11d4da211ac76.jpg)]

16e11d4da211ac76
2.1 Docker核心组件

- docker 客户端 - Client

- Docker 引擎 - Docker daemon

- Docker 镜像 - Image

- Registry 仓库

- Docker 容器 - Container

2.2 Docker客户端

通过客户端使用docker命令进行操作,通过docker可以很快的在host上构建镜像和运行容器,常见的命令为docker pull ,docker run ,docker build.

2.3 Docker引擎

Docker daemon 是服务器组件,以 Linux 后台服务的方式运行。 Docker daemon 运行在 Docker host 上,负责创建、运行、监控容器,构建、存储镜像。

在这里插入图片描述

引擎架构大致如上图所示,与docker首次发布时不同的是在后面的版本中docker一直在进行拆解与重构工作,容器执行和运行时代码已从引擎中拆解出来。

  1. Docker daemon:提供API及其他特性
  2. containerd:所有容器执行逻辑均被重构到此工具中,主要任务为容器的生命周期管理,同时新版本中也负责一些镜像管理工作
  3. shim:实现无守护进程容器的工具。主要工作为:(1)保持所有的STDIN和STDOUT流为开启状态,当daemon重启时运行的容器不会因为管道的关闭而终止 (2)将容器的退出状态反馈给daemon
  4. runc:容器运行时工具(内核原语接口),唯一作用为创建容器,是一个轻量级的针对Libcontainer(取代了早期的LXC组件为提供命名空间等服务)进行了包装的命令行交互工具
模型优势
  1. 容器运行时与Docker deamon解耦(无守护进程的容器),对Docker deamon的升级维护不会影响容器的运行
启动新容器的过程

为了总结引擎工具的作用,下面简述一个启动新容器的过程

在这里插入图片描述

2.4 Docker镜像

docker镜像是构建docker容器的基础,与常用的VM虚拟机做对比,如果使用VM启动一个操作系统,Dcoker镜像可以理解为此操作系统的ISO文件,即虚拟机运行的模板。

1.简介
  1. 描述:镜像=VM模板=类
  2. 组成:镜像=镜像层+镜像层(OS+文件+依赖包)
  3. 使用:Docker hub拉取—>本地Docker主机—>启动容器
2.镜像拉取
  1. 本地仓库:/var/lib/docker/<>
  2. 远程查找:docker search NAME
  3. 拉取镜像:docker image pull :(lastest不保证可以拉取最新镜像)
  4. 拉取全部:docker image pull -a
  5. 列出镜像:docker image ls
  6. 注意:将用户加入DOCKER UNIX组中
3.镜像命名和标签
  1. 两个不同标签可以指向相同镜像
  2. 悬虚镜像(dangling):在仓库中:存在,原因为构建新镜像,使用了已存在的表情
  3. 输出悬虚:docker image ls --filter dangling=true
  4. 删除悬虚:docker image prune
4.镜像过滤
  1. –filter

    commandusage
    dangling返回悬虚或非悬虚镜像
    before需要镜像名称/ID,返回之前被创建的全部镜像
    since返回指定镜像之后创建的全部镜像
    label根据标注的名称/值对镜像进行过滤
    reference过滤公式
  2. –format

    Go模板:”{{.size .rep .tag}}“

5.镜像分层
  1. 镜像由松耦合的只读镜像层构成

    1. 查看方法:(1)pull的时候的层次输出 (2)docker image inspect :
  2. 原理简述:

    1. 所有镜像都基于一个基础镜像层(比如一个系统)
    2. 进行修改或增加内容时,在当前镜像层之上建立新的镜像层
    3. 镜像始终保持是当前所有镜像层的组合
  3. 实现方式:通过快照方式

  4. 共享镜像层:镜像拉取时自动识别本地已经存在的镜像层进行共享,因此某一镜像层与镜像不是严格从属关系

  5. 创建镜像时镜像层的变化问题

    所有的Docker都基于基础镜像层,当进行修改或添加新内容时,就会在当前的镜像层之上创建新的镜像层。在添加额外镜像层的同时,镜像始终保持当前所有镜像层的集合。如下图所示,第三层更新文件5时,会对第二层的文件5进行覆盖,整体看了此镜像仍是具有5个文件。

在这里插入图片描述

6.镜像散列值
  1. 为什么用散列值(SHA):当更新某个已存在的镜像,为新镜像重新打标签,旧镜像成为悬虚镜像被覆盖,表现为<none:none>如果生产环境中已经部署了大量镜像,那么仅凭标签已经无法区分,需要使用散列值来区分新老镜像
  2. 查看方式:docker image ls -digests —> SHA签名值
  3. 精确拉取:docker image pull @sha256
  4. 镜像散列值(摘要)
    1. 背景:镜像(唯一标识为加密ID)=一个或多个镜像层(每个镜像层拥有自身加密ID)+实际存储数据+元数据(加密ID是SHA256串)
    2. 实质:镜像本身和镜像层都有内容hash值校验,保证了不可被篡改
  5. 其他作用:镜像上传至仓库需要压缩,对于压缩后散列值改变无法校验的情况,系统中也有一个压缩后的散列值变量,解决了这个问题
7.多架构
  1. 实现一个镜像支持多种架构
  2. 策略:Manifest列表和Manifest文件
  3. 根据架构选择镜像是Docker自己完成
8. 镜像删除
  1. 删除某个:docker image rm
  2. 删除全部:docker image rm ${docker image ls -q} -f
9.镜像的创建
镜像创建的三种方法
1. 从无到有,写Dockfile结合程序内容上下文进行创建
2. 用docker commit 通过运行/停止的容器创建,好处是可以在容器中运行时的改变代码,保存更改生成镜像
3.使用已存在的镜像进行创建,一种做法是在Dockerfile中FROM 已存在的镜像做基础层
10.相关命令
commandusage
docker image pull name:tag拉取镜像
docker image ls列出镜像
docker image inspect查看详细信息
docker image rm删除镜像,有容器依赖不可删除
docker image prune删除悬虚镜像
2.5 Docker仓库

Docker 镜像的仓库用来存放镜像,分私有和公有两种。

  1. DockerHub(https://hub.docker.com/)是默认的 Registry,由 Docker 公司维护,上面有数以万计的镜像,用户可以自由下载和使用。

  2. 用户也可以创建自己的私有 Registry,速度或安全更优

  3. 相关命令:

    docker pull 命令可以从 Registry 下载镜像。

    docker run 命令则是先下载镜像(如果本地没有),然后再启动容器。

2.6 Docker容器
1.简介
  1. docker容器是docker镜像的运行时实例
  2. 用户可以在单个镜像上启动一个或多个容器
2.容器VS虚拟机
Docker虚拟机
资源占用系统资源物理资源
虚拟化操作系统虚拟化硬件虚拟化
额外开销底层硬件资源划分,每个虚拟机都要有操作系统来声明
启动时间共享内核,速度快需要初始化内核,速度慢
3.运行容器
  1. 检查docker daemon:docker version

  2. 无权限解决方案

    1. usermod -aG docker 并重新退出登录

    2. service docker status/systemctl is-active docker

  3. 运行:docker container run :

4.容器进程
  1. 容器运行=容器内必须有进程在运行,否则容器自动退出

  2. Ctrl-PQ:退出容器但不停止容器运行

5.相关命令:
commandusage
docker container ls列出容器列表
docker container run(-it /bin/bash)启动容器(并启动容器内系统命令行工具)
docker container exec (-it bash))启动容器内新进程(启动了一个命令行工具)
docker container stop优雅的停止容器执行
docker container start启动容器
docker container rm删除容器
docker container inspect显示容器的配置信息

3. Docker应用容器化

1. 完整步骤
  1. 编写应用代码
  2. 创建Dockerfile,包括当前应用的描述,依赖,以及如何创建及使用什么命令运行这个应用
  3. 对Dockerfile进行docker image build操作
  4. 等待Docker将应用程序构建到Docker中
  5. 由镜像启动容器,运行应用
  6. 镜像导出保持:docker save > imagename.tar
2. Dockerfile 解析

在这里插入图片描述

  1. FROM:指定基础镜像
  2. MAINTAINER:描述
  3. RUN:创建时执行的命令,导致创建新的镜像层
  4. COPY:将文件作为新的镜像层添加进镜像中,将本地文件拷贝进镜像哪个目录(这里将Dockfile中同目录下的项目代码拷贝进镜像ubuntu系统中与home同级的新建的pro文件夹)
  5. WORKDIR:设置工作路径
  6. CMD:可以设置一些启动容器时默认执行的命令,比如运行应用等,不过暂未深入研究,本次部署是进去之后一步一步在命令行设置的。shell exec格式的命令,只能有一条
  7. ENTRYPOINT:指定容器启动后默认要运行的程序,与CMD类似,shell exec格式的命令,与CMD有覆盖冲突,只能有一条,多条需要写sh,如[ENTRYPOINT[”./start.sh“]
  8. EXPOSE:指定用于记录应用所使用的端口

这也是镜像层逐渐增多的过程,FROM RUN COPY等每执行一条新建一个镜像层。

3. 创建过程
  1. 在应用代码目录同级创建并写好了Dockerfile

  2. 使用docker image build -t name:tag . 命令创建镜像

  3. 使用docker image ls 查看已经创建的镜像

  4. 一般这一步启动并开启命令行交互:docker container run -it name :tag /bin/bash

  5. 推送至仓库

    docker login

    docker image tag image_name:tag registry_name/image_name:tag

  6. 一般由此镜像启动容器后我们还需要进入容器进行配置,这导致内容的改变,一般配置完成后需要在新的容器基础上生成新的镜像,这里使用docker commit命令,由容器创建新镜像

4.第一层为基础ubuntu镜像开始创建常遇到的问题
问题1:docker加速器
  1. 创建或修改 /etc/docker/daemon.json

    sudo mkdir -p /etc/docker
    sudo tee /etc/docker/daemon.json <<-'EOF'
    {
        "registry-mirrors": [
            "https://1nj0zren.mirror.aliyuncs.com",
            "https://docker.mirrors.ustc.edu.cn",
            "http://f1361db2.m.daocloud.io",
            "https://registry.docker-cn.com"
        ]
    }
    EOF
    sudo systemctl daemon-reload
    sudo systemctl restart docker
    
  2. 验证:docker info

    Registry Mirrors:
     [...]
    
问题2:docker部署系统apt不能使用
  1. 描述:docker中使用ubuntu镜像,需要更新apt,但是国外源巨慢,换源需要使用vim,but镜像中不带vim,陷入死循环,只能使用echo来写

    echo "deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse" >>/etc/apt/sources.list
    
    echo "deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse" >>/etc/apt/sources.list
    
    echo "deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse" >>/etc/apt/sources.list
    
    echo "deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse" >>/etc/apt/sources.list
    
    echo "deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse" >>/etc/apt/sources.list
    
    echo "deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse" >>/etc/apt/sources.list
    
    echo "deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse" >>/etc/apt/sources.list
    
    echo "deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse" >>/etc/apt/sources.list
    
    echo "deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse" >>/etc/apt/sources.list
    
    echo "deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse" >>/etc/apt/sources.list
    
问题3:与宿主机传递文件
sudo docker cp /local/dirname <containername>:/dirname
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值