zoukankan      html  css  js  c++  java
  • docker基础

    路过花鸟市场,见一可爱金鱼在鱼缸遨游,欲购之;缸与鱼同售20元,鱼单售5元。

    囊中羞涩,遂单购鱼;次日,鱼卒。

    找到鱼店老板:你的鱼有问题,带回家就死了。

    鱼店老板:不可能,在我这活蹦乱跳的,肯定是你的鱼缸有问题。

    这一幕似曾相识,像极了开发和运维在上线过程中的扯皮。

    运维:你这个java包有问题,生产环境跑不起来。
    
    开发:一模一样的jar包,在我本地跑的好好的,肯定是你产线哪里的环境配置有问题。

    程序跟小金鱼一样也会“水土不服”!而导致程序水土不服的原因一般就是环境配置的差异。

    有没有一种方案能屏蔽环境的差异,包括操作系统,包括各种配置项?

    既然“水土不服”,那我把程序及程序的“鱼缸”都打包迁移,这个技术就是docker!

    什么是docker

    Docker 是一个使用Go语言开发的开源的应用容器引擎(Docker本身并不是容器,它是创建容器的工具,是应用容器引擎),让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,可以实现更轻量级的虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。

    这是docker的logo,这条可爱的鲸鱼就是docker,而大海就是我们的操作系统,多个集装箱就是在docker上运行的容器。

    docker三个思想

    集装箱

    把操作系统,jdk,tomcat,代码,配置都放到鲸鱼上集装箱里。再打包放到鲸鱼上,由鲸鱼给我们送到服务器上,在我的机器上怎么运行,在别的机器上也怎么运行;之前我们要把程序部署到一台新的机器上,可能会启动不起来,比如少一些配置文件或者少了什么数据,有了docker的集装箱可以保证我们的程序不管运行在哪不会缺东西。即docker解决了运行环境不一致所带来的问题。

    标准化

    • 运输方式

    docker运输东西有一个超级码头(Repository),任何地方需要货物都由docker鲸鱼先送到超级码头(docker push),然后再由docker鲸鱼从超级码头把货物送到目的地去(docker pull)。

    运输标准化:docker标准化了传输过程,执行docker命令就可完成发送传输

    • 存储方式

    以前把程序拷贝到另一台服务器时,指定一个目录,我们还要记住这个目录,因为下次我们可能还要改动东西,有了docker之后就不用,我们就不用记住程序在哪里了,docker鲸鱼会把所有集装箱放在统一标准的一个地方。

    存储标准化:不同程序被统一存储。

    • API接口

    docker提供了一系列rest api的接口,包含了对docker容器,也就是对我们的应用的启动、停止、查看、删除等等,如当我们要启动tomcat时我们要执行startup命令,当我们要停止时要执行shutdown命令,如果不是tomcat,我们可能还需要一些别的命令控制它。有了接口标准化,只需要执行同样的命令,就能控制所有的应用,有了docker,我们记docker的命令就可以对其进行操作。

    接口标准化:执行同样的命令控制所有的应用,用docker命令执行就好。

    隔离

    一台服务器上跑了A和B两个程序,如果A程序死循环疯狂吃CPU、或是A程序疯狂打日志把硬盘占满,又或是A程序内存泄漏,都会影响B程序的正常运行。

    所以要把每个服务都隔离起来,让它们只使用自己那部分有限的cpu,内存和磁盘,以及自己依赖的软件包。这个早先是用虚拟机来实现隔离的,但是每个虚拟机都要装自己的操作系统核心,这是对资源有点浪费。于是就有了Docker, 一个机器上可以装十几个到几十个docker,他们共享操作系统核心,占用资源少,启动速度快,但又能提供资源(cpu, 内存,磁盘等)的一定程度的隔离。

    docker两个口号

    第一句,是:“Build, Ship and Run”。也就是,“搭建、发送、运行”,三板斧。

    第二句,是:“Build once,Run anywhere(搭建一次,到处能用)”。

    docker基本组成要素

    Docker 使用的是 C/S 结构,即客户端/服务器体系结构。客户端向服务器发送请求,服务器负责构建、运行和分发容器。

    官网给出的架构图:

    这张图里面概括了docker的所有的元素!我们就逐一分析docker客户端、docker服务、仓库、镜像、容器等概念!

    docker客户端

    最左边是docker的客户端,类似我们操作mysql的工具navcat,只不过我们这里的是没有图形化界面的命令终端。docker客户端是用户与docker服务交互的窗口!我们能看到图中就是各种操作的命令!

    docker服务端

    中间的是docker后台运行的服务端,一个称为docker daemon的守护进程。可以理解为我们mysql的服务,我们的操作命令都是在这部分进行处理!docker deamon监听着客户端的请求,并且管理着docker的镜像、容器、网络、磁盘(图中只列出了镜像与容器)等对象。同样,docker的客户端与服务可以运行在同一机器上,也可以用某台机器上的客户端远程连接另一台机器上的docker服务,这跟我们的mysql一样。

    仓库

    仓库(Repository)是集中存放镜像文件的场所。

    仓库(Repository)和仓库注册服务器(Registry)是有区别的。仓库注册服务器上往往存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签(tag)。

    图中右边部分是注册仓库,与Git的概念相似,可以pull远程下载常用的镜像,也可以push包到远程仓库(如图中的redis、nginx等镜像),同一个镜像又可以有多个版本,在docker中称为tag。

    仓库分为两种,公有仓库,和私有仓库,最大的公开仓库是docker Hub,存放了数量庞大的镜像供用户下载。

    镜像

    官方给出的定义是:docker镜像是一个只读模板,可以用来创建docker容器。镜像是一种轻量级的、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件。它包含运行某个软件所需要的所有的内容,包括代码、运行时、库、环境变量、配置文件等。我们开发的web应用需要jdk环境、需要tomcat容器、需要linux操作系统,那我们可以把我们所需要的一切都进行打包成一个整体(包括自己开发的web应用+jdk+tomcat+centos/ubuntu+各种配置文件)。打包后的镜像在某台机器上能运行,那它就能够在任何装有docker的机器上运行。

    任何镜像的创建会基于其他的父镜像,也就是说镜像是一层套一层,比如一个tomcat镜像,需要运行在centos/ubuntu上,那我们的tomcat镜像就会基于centos/ubuntu镜像创建。

    容器

    官方给出的定义是:docker的容器是用镜像创建的运行实例,docker可以利用容器独立运行一个或一组应用。我们可以使用客户端或者API控制容器的启动、开始、停止、删除。镜像只是一个静态的文件,这个文件需要运行就需要变为容器,我们可以把容器看做是一个简易版的linux系统(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序!
    就是前面看到的鲸鱼背上的一个一个的集装箱,每个集装箱都是独立的!
    容器的定义和镜像几乎是一模一样的,也是一堆层的统一视角, 唯一区别的是容器的最上面那一层是可读可写的。

    另外,官方建议遵循单一原则,即一个容器只运行一个主进程(一个服务)。
    多个进程都部署在一个容器中,弊端很多。比如更新某个进程的镜像时,其他进程也会被迫重启,如果一个进程出问题导致容器挂了,所有进程都将无法访问。
    容器 = 应用 + 依赖的执行环境,而不是像虚拟机一样,把一堆进程都部署在一起。

    镜像与容器关系

    容器与镜像的关系类似于面向对象编程中的对象和类,可以理解为容器就是镜像的一个实例,相信大家都写过类似下面的代码:

    public void Dog extends Animal{  
        ......
    }  
    ......
    Dog dog = new Dog()
    我们在代码中定义了一个Dog类,这个类就相当于一个镜像,可以根据这个类new出很多的实例,new出来的实例就相当于一个个的容器。镜像是静态的文件,而容器就是有生命的个体!
    Dog类可以继承父类Animal,如果不显式的指定继承关系,Dog类就默认继承Object类。同样docker中的镜像也有继承关系,一个镜像可以继承其他的镜像创建,添加新的功能!

    虚拟机和Docker

    提到隔离和镜像,不得不提虚拟机,虚拟机也能实现对应用的隔离,安装特定的镜像也能跑出我们想要的环境。

    为什么我们还需要Docker呢?

    虚拟机(vm)是一个物理硬件层抽象,用于将一台服务器变成多台服务器。每个vm都包含一整套操作系统、依赖资源(二进制文件和库资源)和应用。因此占用大量空间,vm启动也十分缓慢。

    容器(docker)是一个应用层抽象,用于将代码和依赖资源打包在一起。多个容器可以在同一台机器上运行,共享操作系统与内核,但各自作为独立的进程在用户空间中运行。与虚拟机相比,容器占用的空间较少(容器镜像大小通常只有几十兆),瞬间就能完成启动。
     
    简单总结docker为什么比vm快?
    1.vm需要Hypervisor实现硬件资源虚拟化,docker不需要。
    2.vm需要Guest OS(来宾操作系统);docker利用的是宿主机的内核,而不需要Guest OS。

    Docker在Windows和Mac

    Docker底层用的Linux的cgroup和namespace这两项技术来实现应用隔离,那Windows和Mac用户能用Docker吗?

    • 之前,Windows和Mac使用Docker实际上就是跑了一层Linux虚拟机。
      • 比如在Windows下安装的是Docker Toolbox,它需要Oracle Virtual Box来跑Docker
    • 现在,Windows和Mac都已经原生支持Docker了。但需要一些安装的条件,详情可以查看官网
      • 比如Windows:Docker for Windows requires 64bit Windows 10 Pro and Microsoft Hyper-V

    docker安装

    前提条件

    1.Docker支持以下的CentOS版本:

    CentOS 7 (64-bit)

    CentOS 6.5 (64-bit) 或更高的版本

    查看CentOS版本:

    [root@iZbp1dnapcnoxqoyi0jwqaZ ~]# cat /etc/redhat-release 
    CentOS Linux release 7.6.1810 (Core) 

    2.CentOS 仅发行版本中的内核支持 Docker。

    Docker 运行在 CentOS 7 上,要求系统为64位、系统内核版本为 3.10 以上。

    Docker 运行在 CentOS-6.5 或更高的版本的 CentOS 上,要求系统为64位、系统内核版本为 2.6.32-431 或者更高版本。

    查看CentOS 内核:

    [root@iZbp1dnapcnoxqoyi0jwqaZ ~]# uname -r
    3.10.0-957.21.3.el7.x86_64

    安装步骤(CentOS 7)

    Docker 分为 CE 和 EE 两大版本。CE 即社区版,免费支持周期 7 个月;EE 即企业版,强调安全,付费使用,支持周期 24 个月。

    一般使用CE版本,按照官网: https://docs.docker.com/engine/install/centos/

    1.设置docker资源库

    #安装yum的扩展包(因为系统默认没有安装yum-config-manager命令,这个命令在yum-utils包里)
    yum install -y yum-utils
    #添加docker的官方资源库:
    yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
    
    psyum-config-manager命令的本质是对/etc/yum.repos.d/(库数据的储存位置)文件夹下文件的增删查改,推荐使用yum-config-manager命令进行改动
    yum-config-manager –add-repo=“仓库路径”   --添加仓库
    yum-config-manager –disable “仓库名"      --禁用仓库
    yum-config-manager –enable  “仓库名”      --启用仓库

    2.安装最新版本的Docker Engine和容器

    yum install docker-ce docker-ce-cli containerd.io

    3.启动docker

    systemctl start docker

    4.查看docker进程

    [root@iZbp1dnapcnoxqoyi0jwqaZ ~]# ps -ef|grep docker|grep -v grep
    root     12353     1  0 Dec09 ?        00:00:57 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
    [root@iZbp1dnapcnoxqoyi0jwqaZ ~]# docker -v
    Docker version 20.10.0, build 7287ab3

    ps,如果要卸载docker的话:

    #卸载Docker Engine,CLI和Containerd软件包
    yum remove docker-ce docker-ce-cli containerd.io
    #主机上的映像,容器,卷或自定义配置文件不会自动删除,要删除手动删除
    rm -rf /var/lib/docker

    配置镜像加速

    为了提高获取Docker官方镜像的速度,在国内会使用镜像加速器,一般使用阿里云或者网易云的。

    1.需要一个阿里云的账户,获取加速器的地址:https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors

    2.按照提示配置加速器

    mkdir -p /etc/docker
    tee /etc/docker/daemon.json <<-'EOF'
    {
      "registry-mirrors": ["https://xxxxxxx.mirror.aliyuncs.com"]
    }
    EOF
    systemctl daemon-reload
    systemctl restart docker

    第一个helloworld

    执行 docker run hello-world:

    首先是有hello from docker!的输出,证明docker的安装成功并正常工作。

    其次详细解释了整个过程中,docker依次干了四件事:

    1.Docker客户端连接Docker守护进程

    2.Docker守护程序从Docker Hub中提取hello-world镜像

    3.Docker守护程序从该镜像创建了一个新容器,该容器运行可执行文件,生成你当前正在读取的输出

    4.Docker守护程序将该输出流传输到Docker客户端,该客户端将其发送到你的终端

    这里由于我不是第一次执行这个命令,所以没有去远程仓库提取hello-world镜像,因为我本地已经有这个镜像了,只需要以该镜像为模板生成容器实例运行即可。

    run命令干了什么:

    总结

    绝大部分应用,开发者都可以通过docker build创建镜像,通过docker push上传镜像;而用户通过docker pull下载镜像,用docker run运行应用。用户不需要再去关心如何搭建环境,如何安装,如何解决不同发行版的库冲突——而且通常不会需要消耗更多的硬件资源,不会明显降低性能。这就是docker的标准化、集装箱的优势体现。

    参考:

    https://www.zhihu.com/question/28300645

    https://www.cnblogs.com/liuawen/p/12854029.html

    https://www.zhihu.com/question/28300645/answer/719167966

    https://www.cnblogs.com/venicid/p/11870260.html#auto-id-17

  • 相关阅读:
    C#学习笔记-代理模式
    SqlDbx连接oracle
    C# 连接oracle,用32位client和64位Client,可能导致结果不同
    PHP&Java 调用C#的WCF
    DevExpress GridControl 控件二表连动
    SSAS 非重复计数
    Corn 表达式
    C# 实现Tree,包含parentId和children
    jsfiddle.net上的记录
    【慕课网实战】Spark Streaming实时流处理项目实战笔记十二之铭文升级版
  • 原文地址:https://www.cnblogs.com/xulan0922/p/14113279.html
Copyright © 2011-2022 走看看