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

原文地址:https://www.cnblogs.com/xulan0922/p/14113279.html