路过花鸟市场,见一可爱金鱼在鱼缸遨游,欲购之;缸与鱼同售20元,鱼单售5元。
囊中羞涩,遂单购鱼;次日,鱼卒。
找到鱼店老板:你的鱼有问题,带回家就死了。
鱼店老板:不可能,在我这活蹦乱跳的,肯定是你的鱼缸有问题。
这一幕似曾相识,像极了开发和运维在上线过程中的扯皮。
运维:你这个java包有问题,生产环境跑不起来。
开发:一模一样的jar包,在我本地跑的好好的,肯定是你产线哪里的环境配置有问题。
程序跟小金鱼一样也会“水土不服”!而导致程序水土不服的原因一般就是环境和配置的差异。
有没有一种方案能屏蔽环境的差异,包括操作系统,包括各种配置项?
既然“水土不服”,那我把程序及程序的“鱼缸”都打包迁移,这个技术就是docker!
Docker 是一个使用Go语言开发的开源的应用容器引擎(Docker本身并不是容器,它是创建容器的工具,是应用容器引擎),让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,可以实现更轻量级的虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。
这是docker的logo,这条可爱的鲸鱼就是docker,而大海就是我们的操作系统,多个集装箱就是在docker上运行的容器。
把操作系统,jdk,tomcat,代码,配置都放到鲸鱼上集装箱里。再打包放到鲸鱼上,由鲸鱼给我们送到服务器上,在我的机器上怎么运行,在别的机器上也怎么运行;之前我们要把程序部署到一台新的机器上,可能会启动不起来,比如少一些配置文件或者少了什么数据,有了docker的集装箱可以保证我们的程序不管运行在哪不会缺东西。即docker解决了运行环境不一致所带来的问题。
docker运输东西有一个超级码头(Repository),任何地方需要货物都由docker鲸鱼先送到超级码头(docker push),然后再由docker鲸鱼从超级码头把货物送到目的地去(docker pull)。
运输标准化:docker标准化了传输过程,执行docker命令就可完成发送传输
以前把程序拷贝到另一台服务器时,指定一个目录,我们还要记住这个目录,因为下次我们可能还要改动东西,有了docker之后就不用,我们就不用记住程序在哪里了,docker鲸鱼会把所有集装箱放在统一标准的一个地方。
存储标准化:不同程序被统一存储。
docker提供了一系列rest api的接口,包含了对docker容器,也就是对我们的应用的启动、停止、查看、删除等等,如当我们要启动tomcat时我们要执行startup命令,当我们要停止时要执行shutdown命令,如果不是tomcat,我们可能还需要一些别的命令控制它。有了接口标准化,只需要执行同样的命令,就能控制所有的应用,有了docker,我们记docker的命令就可以对其进行操作。
接口标准化:执行同样的命令控制所有的应用,用docker命令执行就好。
一台服务器上跑了A和B两个程序,如果A程序死循环疯狂吃CPU、或是A程序疯狂打日志把硬盘占满,又或是A程序内存泄漏,都会影响B程序的正常运行。
所以要把每个服务都隔离起来,让它们只使用自己那部分有限的cpu,内存和磁盘,以及自己依赖的软件包。这个早先是用虚拟机来实现隔离的,但是每个虚拟机都要装自己的操作系统核心,这是对资源有点浪费。于是就有了Docker, 一个机器上可以装十几个到几十个docker,他们共享操作系统核心,占用资源少,启动速度快,但又能提供资源(cpu, 内存,磁盘等)的一定程度的隔离。
第一句,是:“Build, Ship and Run”。也就是,“搭建、发送、运行”,三板斧。
第二句,是:“Build?once,Run?anywhere(搭建一次,到处能用)”。
Docker 使用的是 C/S 结构,即客户端/服务器体系结构。客户端向服务器发送请求,服务器负责构建、运行和分发容器。
官网给出的架构图:
这张图里面概括了docker的所有的元素!我们就逐一分析docker客户端、docker服务、仓库、镜像、容器等概念!
最左边是docker的客户端,类似我们操作mysql的工具navcat,只不过我们这里的是没有图形化界面的命令终端。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镜像创建。
另外,官方建议遵循单一原则,即一个容器只运行一个主进程(一个服务)。
多个进程都部署在一个容器中,弊端很多。比如更新某个进程的镜像时,其他进程也会被迫重启,如果一个进程出问题导致容器挂了,所有进程都将无法访问。
容器 = 应用 + 依赖的执行环境,而不是像虚拟机一样,把一堆进程都部署在一起。
容器与镜像的关系类似于面向对象编程中的对象和类,可以理解为容器就是镜像的一个实例,相信大家都写过类似下面的代码:
public void Dog extends Animal{
......
}
......
Dog dog = new Dog()
上面说了,Docker底层用的Linux的cgroup和namespace这两项技术来实现应用隔离,那Windows和Mac用户能用Docker吗?
Docker Toolbox
,它需要Oracle Virtual Box
来跑DockerDocker for Windows requires 64bit Windows 10 Pro and Microsoft Hyper-V
提到隔离和镜像,不得不提虚拟机,虚拟机也能实现对应用的隔离,安装特定的镜像也能跑出我们想要的环境。
为什么我们还需要Docker呢?
虚拟机(vm)是一个物理硬件层抽象,用于将一台服务器变成多台服务器。每个vm都包含一整套操作系统、依赖资源(二进制文件和库资源)和应用。因此占用大量空间,vm启动也十分缓慢。
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
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 ps:yum-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
执行 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.cnblogs.com/xulan0922/p/14113279.html