[Docker-1自顶向下学习Docker
本文目录:
- 什么是DOCKER?
- 什么是容器?
- 什么是DOCKER镜像?
- DOCKER有什么使用场景和优势?
- 流程图一:从中央仓库拉取镜像并部署
- 流程图二:上传镜像到中央私库
- 结语
什么是DOCKER?
先用类比来让大家有点概念,相信大家都用过或者知道虚拟机的作用,那么DOCKER(SERVER)就像一个"虚拟机管理器",它主要作用是管理容器的生命周期。
什么是容器?
容器可以说就是虚拟机的"外壳",它提供运行操作系统的运行环境,容器自身的磁盘、内存资源是 DOCKER SERVER 从宿主机的磁盘、内存这些资源中划分分配给容器的。
至于容器这个虚拟机里到底要运行什么镜像,是可以自定义,你可以选择LINUX任意的发行版,或者WIN这些操作系统镜像作为虚拟机(容器)的操作系统。
什么是DOCKER镜像?
DOCKER的镜像我知道的大概可以分为三种:
- 只有操作系统的官方镜像
- 有操作系统并且已经部署了某些项目,中间件的官方镜像
- 你自己打包的自定义镜像。
之所以会有 第2 3 种镜像是因为容器里如果只有一个操作系统的话,是几乎无法满足业务需求的,但是你可以在已有操作系统的容器里面部署你想要的工程项目,数据库,WEB容器,或者像REDIS NGINX MQ…这些中间件。
总之,操作系统能部署什么东西,使用了该操作系统镜像的容器就能部署什么。
而第二种镜像则就是官方为了方便大家打包好已经有某个操作系统和某个项目的镜像,第三种镜像也是如此,只不过是你打包的。
DOCKER有什么使用场景和优势?
一台主机部署DOCKER后,可以运行多个容器就有了以下的使用场景
场景:
- 部署一个MYCAT到容器里,然后部署若干个MYSQL容器做成集群让有MYCAT的容器管理,由MYCAT实现分库分表,主备,读写分离… (也就是单机主备,读写分离方案)
- 运行若干个部署了REDIS哨兵的容器,再用这些哨兵容器监控其它若干个部署了REDIS SERVER的容器(也就是单机高可用方案)
- MQ集群
当然,以上那些不用DOCKER也可以做到,而且在实际情况中是不会单机部署全部东西的,不然这算个毛高可用啊。我只是想说DOCKER也可以做到,也可以做成真正的分布式,而且DOCKER还有几个优势
优势:
- 精简的"虚拟机",官方提供的操作系统镜像相当精简,譬如LINUX镜像里会剔去不是必须的组件,如vim yum ps ..这样的镜像在运行后自然就少占了宿主机很多资源,不像传统虚拟机那样。就拿我的辣鸡服务器来说,用了DOCKER可以部署数十个REDIS SERVER,主机内存也没占去一半。
- 减少大量重复的劳动,DOCKER不仅仅能节省项目的资源开销,因为镜像可以自定义,所以你可以根据业务做好自己想要的容器后,快速部署到其它环境中,不用再烦频繁下包解压,注意环境变量。我现在做了一个脚本,可以在任意支持的命令行的系统中十分钟内部署生产环境。
接下来我会用几张DOCKER一般运用的流程图来让大家学会DOCKER的一些基本运作方式。
流程图一:从远程仓库拉取redis镜像到本地(服务器),并运行使用
再详细解释一下一些概念
最最最重要的概念说明:
要对一个镜像操作就要先定位这个镜像,而定位某个镜像需要两个字段 REPOSITORY 和 TAG,用冒号 : 分隔开这两个字段使用。
还有,因为中央仓库是类似linux的树状文件结构的,所以定位某个库是需要绝对路径来指定的,譬如要定位最新的官方提供的redis镜像,这个镜像在中央仓库的绝对路径地址是 docker.io/redis (REPOSITORY)。然后还需要一个latest 这个标识符(TAG)才能定位这个中央仓库的redis库下的最新版本镜像。
例子:
redis最新版本的镜像 docker.io/redis:latest
redis 5的镜像 docker.io/redis:5
-远程仓库
顾名思义即位于别的网路的磁盘,作用是存取镜像。
DOCKER官方自身就提供了一个远程仓库(下称DOCKER的远程仓库为中央仓库),且官方已经在它的中央仓库将各种中间件,操作系统镜像 制备成的DOCKER镜像供用户自取使用,有需要可以在 https://hub.docker.com/search 自查需要的项目镜像。
因为官方限制了用户上传到中央仓库的镜像数量(但不限制单个镜像的大小),所以如果有存放大量镜像的需求你可以自建的一个私库来替代中央仓库。
-宿主机
即你安装部署了 DOCKER SERVER端 的小本本或者服务器。
-本地仓库
从中央仓库拉取下来的镜像的存放点,由DOCKER SERVER管理
提醒大家不要觉得本地仓库只是一个库,因为本地仓库就像mysql一个单例可以部署多个逻辑库一样,只不过DOCKER的库是由REPOSITORY这个字段来区分镜像是否存在于一个逻辑库中的
如上图中的五个镜像,其实是分别属于五个不同的DOCKER逻辑库的。
-容器
在使用DOCKER RUN 命令操作镜像后,DOCKER会将一个镜像部署到一个新容器里,每个容器里运行一个镜像,容器与容器之间独立(内存,硬盘,端口都独立)。
换句话说,一台宿主机如果部署了两个或多个容器,那这关系就像你在电脑上启动了两个或多个虚拟机一样。
当然,容器之间是可以通信的。不仅如此,除了同一主机上的容器可以相互通信,不同的网络的主机上的容器也可以通过修改 DOCKER网桥 的参数来与广域网上其它的容器通信。
因为镜像启动后会被放入由DOCKER新建的容器中运行,而且容器里也只有该镜像(其实还有挂载点)。所以镜像和容器这个两个东西基本上是可以认为它们是等价的,不用太纠结。
-流程图中的CMD
CMD1:docker pull [REPOSITORY] : [TAG]
例子:将redis项目的镜像从远程仓库拉取到本地
docker pull docker.io/redis:latest
参数说明:
REPOSITORY: 是某个镜像所属的项目的专属存储库,要通过 docker.io/redis 才能指定一个redis的存储库。
TAG: 是镜像在某个存储库中的唯一标识,因为一个存储库能存多个镜像,所以需要一个标识符来区分它们,在指定一个存储库后还要再指定镜像的唯一标识TAG才能拉取一个镜像。
另外,TAG虽然官方只是用来标识某个项目的镜像的版本的,譬如在redis存储库下你会看到用版本号标识的一堆redis镜像。
docker.io/redis:v1
docker.io/redis:v2
docker.io/redis:v3
但是由于用户只能在DOCKER HUB注册一个免费的库,也由于我懒得搭建私库,所以我的给镜像定义的TAG是包含了该镜像的项目名然后再在后面写上版本号,这样我就能在只有一个免费库的情况下,放了多个不同项目的镜像也能区分同一项目不同版本的镜像了。
username/myrepository:redis-v1
username/myrepository:redis-v2
username/myrepository:mynginx-v1
username/myrepository:mymysql-v1
CMD2:docker run [REPOSITORY]:[TAG]
run的参数还有很多,这里只举一个简单的例子
例子:运行拉取下来的redis镜像
docker run -dit -p 6379:6379 -v /root/data : /data redis:latest
参数说明:
-i:以交互模式运行容器,通常与 -t 同时使用;
-t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用;
-d: 后台运行容器,并返回容器ID;
-p:将宿主机6379端口映射到容器的6379端口。注意p一定要小写,大写P的话就是将镜像设置的默认开放端口随机映射到宿主机的高位端口。
而且可以这样写来限制哪些网络的主机能访问容器:
-p 0.0.0.0:6379:6379 所有网络都可访问
-p 127.0.0.1:6379:6379 限制同一主机才能访问
0.0.0.0和127.0.0.1的区别: https://blog.csdn.net/qq_35886593/article/details/88741059
-v:将宿主机的 /root/data目录 挂载到镜像的 /data目录 ,关于挂载这个我要另写一篇来说明,或者读者自查其它资料。
-使用容器中的镜像
启动一个redis镜像后可以通过doceker ps 看到正在运行的容器(正在运行的镜像)
这时就可以用你的redis-cli或其它乱七八糟的玩意连上这个容器中的redis-server(官方弄的redis镜像是设置了run后自动开启redis-server的,所以一般情况下启动镜像后连就完了)
流程图二:将镜像上传到DOCKER(即官方提供的免费个人仓库)
-前置准备
需要先在DOCKER HUB注册一个账号,然后创建一个仓库(就是DOCKER提供的私人仓库,下称中央私库)
怎么注册就不用写了吧?这里提一下我在DOCKER HUB创建中央私库遇到的一个坑
我在创建中央私库的时候怎么也找不到创建的地方,DOCKER资料本来就不多,大家都没提及这个问题,后来我在官网胡乱探索了一下才知道原来要先点击2这个地方,然后选择3里的用户名列表,最后在4那个红框位置才会出现CREATE REPOSITORY这个按钮。(设计这个的PM真特么弱智,先把按钮弄灰色不行??非得隐藏)
创建好中央私库后继续往下看。
-流程图中的CMD
CMD1:docker commit [要打包的容器的名字或ID] [打包后新镜像的REPOSITORY:TAG]
参数说明:
-a :作者信息
-m :描述
之所以一定需要重命名镜像的REPOSITORY和TAG,还是因为需要指定镜像要上传到中央私库的什么地方,以及指定新的唯一标识符。
例子:将容器打包成一个镜像并重新设置REPOSITORY和TAG
docker commit -a="xxx" -m="hello" [容器名字或id] [username/mymysql:8]
除了将容器打包成镜像,还能用docker tag命令来直接改变已有镜像的REPOSITORY和TAG
docker tag [REPOSITORY]:[TAG] [REPOSITORY]:[TAG]
在上传之前还需要先登录DOCKER账号
通过 docker login [username] [password] 来登录
CMD2:docker push [REPOSITORY]:[TAG]
例子:将新打包的镜像推送到中央私库
docker push username/mymysql:8
结语:
目前关于DOCKER的博客还是挺少而且讲得也不怎么样的,要么不照顾初学者,要么没讲到必须要知道的概念。所以我想写几篇来贡献一下,还有数据卷的挂载要讲的,docker commit这个命令也有些坑,写在下篇博客吧。