docker 进阶(中)
- docker提交镜像等命令
- docker 镜像原理
- docker 私有库&推送到私有库
- 容器数据卷
- docker 安装常规软件
docker提交镜像等命令
再这个谈这个docker 提交这个镜像之前我们先补充一下上一篇博客没有谈到的命令。再这里说一下。我们之前谈到的docker run 命令启动一个容器但是当我们的服务器重新启动之后,这些容器是不会自动启动的。我们平时在运维的时候,通常给一些软件喜欢设置开机自启动,例如 mysql、redis,这样测试环境服务器重启时可节省不少运维时间成本,那么我们如果是docker容器 是否也可以设置开机自启动容器呢?
下面我们介绍一下docker run 后面跟的参数启动容器时,使用docker run命令时 添加参数 –restart=always 便表示,该容器随docker服务启动而自动启动
docker run -it -d --name="mynginx" -p 8088:80 --restart=always docker.io/nginx /bin/bash
下面我们正式来介绍一下这个docker 提交镜像的命令,和这个git 有点儿相似下面我们具体来看看如何操作
docker commit 提交容器成为一个新的副本
docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[TAG]
下面我们就来动手实验吧!天上的理念必须要有这个落地的实现下面我们一步一步的来进行实验。
首先第一步从远程仓库拉取这个ubuntu镜像下来
docker pull ubuntu
这个由于这个我已经下载好了再这里就不再下载了。铁子们可以自行下载好
然后我们启动这个ubuntu
docker run -it ubuntu /bin/bash
下面我们再这个ubutun当中安装这个vim来进行编辑文件。不过我们再安装这个vim之前我们首先需要做一些事情跟新包管理工具
apt-get update
apt-get -y install vim
执行上面上面这些命令以后这个ubuntu就带vim 命令了铁子可以自行实验
下面我们使用这个docker commit 提交容器副本使之成为一个新的镜像这个镜像形成之后那么他天生就自带这个vim 编辑命令。
docker commit -m="vim cmd add sucess" -a="ksy" c73f9483b55e myubuntu:1.1
然后我们再使用这个docker images 查看这个镜像检查我们自定义的这个ubuntu是否生成 成功。
我们发现我们自己提交的这个myubuntu明显比从仓库拉取下来的ubuntu的大小要大。这也就是docker的分层我们马上就谈这个docker 的分层
docker 镜像原理
下面我们再谈一下什么是镜像?
镜像是一种轻量级的、可执行的独立软件包。用来打包软件运行环境和基于运行环境的开发软件,它包含运行某个软件所需要的内容,包括代码、运行时、库、环境变量和配置文件。
下面我们以这个pull为例子我们会发现docker再这个下载的过程当中好像是一层一层的再这个下载
这里我用docker pull nginx命令,下载来一个镜像给大家看看,框起来的是不是一层一层下载的
我们发现这个docker 确实是这个一层一层的再这个下载
下面我们引出这个docker加载这个镜像的原理联合文件系统(Union FS)
nionFS(联合文件系统):UnionFS文件系统是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层一层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像,可以制作各种各样的应用镜像。
特性:一次同时加载多个文件系统,但是从外面开起来,只能看一个文件系统,联合加载会把各层文件系统叠加起来,最终的文件系统会包含所有的底层文件和目录。
docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。
bootfs(boot file system)主要包含bootloader和kernel, bootloader主要是引导加载kernel, Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是引导文件系统bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。
rootfs (root file system) ,在bootfs之上。包含的就是典型 Linux 系统中的 /dev, /proc, /bin, /etc 等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。
为什么 Docker 镜像要采用这种分层结构呢?
最大的好处,就是资源共享。比如有多个镜像都从相同的Base镜像构建而来,那么宿主机只需要在磁盘上保留一份base镜像,同时内存中也只需要加载一份base镜像,这样就可以为所有容器提供服务了,而且镜像的每一层都可以被共享。
再这里需要注意的是:
当容器启动时,一个新的可写层被加载到镜像的顶部。这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”。
所有对容器的改动 - 无论添加、删除、还是修改文件都只会发生在容器层中。只有容器层是可写的,容器层下面的所有镜像层都是只读的。
我们也可以通过这个我们通过docker image inspect ngixn:latest查看一下。
docker image inspect ngixn:latest
这里再给大家举个栗子:
所有的docker镜像都起始于一个基础镜像层,当进行修改或者增加新的内容时,就会在当前镜像层之上,创建新的镜像层。假如基于Ubuntu Linux 16.04创建一个新的镜像,这就是新镜像的第一层;如果在该镜像中添加Python包,就会在基础镜像之上创建第二个镜像层;如果继续添加安全补丁,就会创建第三个镜像层。如下图:
添加额外的镜像的同时,镜像始终是当前所有镜像的组合。比如我们在添加第三层安全补丁的时候,Ubuntu和Python视为一个镜像层,在此基础上再添加安全补丁镜像层。docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部。这一层就是我们所说的容器层,容器之下都叫镜像层。
docker 私有库&推送到私有库
我们首先谈一下什么是这个私有库?
1官方Docker Hub地址:https://hub.docker.com/,中国大陆访问太慢了且准备被阿里云取代的趋势,不太主流。 Dockerhub、阿里云这样的公共镜像仓库可能不太方便,涉及机密的公司不可能提供镜像给公网,所以需要创建一个本地私人仓库供给团队使用,基于公司内部项目构建镜像。 Docker Registry是官方提供的工具,可以用于构建私有镜像仓库
下面我们一起来吧。下载这个镜像 Docker Registry 一起动手下载吧
docker pull registry
下面一起来运行这个私有库Registry 相当于本地有个私有Docker hup的感觉
docker run -d -p 6000:5000 -v /ksy/myregistry/:/tmp/registry --privileged=true registry
再这里可能大家有点看不太懂这个 -v是啥意思这个是这个容器卷再后面会说铁子么直接复制粘贴即可。
再这里需要注意的是:
默认情况,仓库被创建在容器的/var/lib/registry目录下,建议自行用容器卷映射,方便于宿主机联调(这个再后面会一 一说明)
下面我们启动原始的ubuntu并安装这个ifconfig命令并提交
docker run -it ubuntu /bin/bash
apt-get update
apt-get -y install net-tools
安装完成之后我们再终端上输入ifconfig命令进行查看是否安装成功
下面我们把这个容器打成一个镜像
docker commit -m ="ifconfig add ok" -a="ksy" 521a80156d4d ksyubuntu:1.3
下面我们查看一下这个我们私服库上有那些镜像这个通过curl发送get请求来进行查看
curl -XGET http://127.0.0.1:6000/v2/_catalog
其结果如下:
现在这个私服库里面没有任何这个镜像这是我们的查询结果下面我们进行下一步将新镜像ksyubuntu:1.3修改成符合私服规范的Tag
docker tag 镜像:Tag Host:Port/Repository:Tag
Host为这个自己的主机IP 下面博主演示一下相信大家就明白了是什么意思了
docker tag ksyubuntu:1.3 127.0.0.1:6000/ksyubutun:1.2
就好像是克隆了一份镜像一样下面我们进行下一部修改配置文件使之支持http 这是因为docker 的私服库做了这个安全加固默认不支持这个http所以我们需要修改配置文件
vim /etc/docker/daemon.json
注意这个是json格式后面需要有一个逗号不要忘记了。修改了配置文件我们主要重新启动一个这个docker
systemctl restart docker
下面我们就可以把我们本地的ksyubuntu推送到私服库了
# docker push 127.0.0.1:6000/ksyubutun:1.2
下面我们第二次验证这个私服库上是否有东西
下面我们把本地的这个ksyubuntu给删掉然后从私服库上拉取下来
docker pull 127.0.0.1:6000/ksyubutun:1.2
我们发现这个本地我们又有这个镜像了
容器数据卷
什么是这个容器数据卷?docker容器在产生数据的时候,如果不通过docker commit生成新的镜像,使得数据作为镜像的一部分保存下来,那么当容器删除之后,数据自然而然的也会消失。为了能保存数据,容器中引用了数据卷的概念。卷就是目录或者文件,存在一个或者多个容器之中,由docker挂载到容器,但是不属于联合文件系统,因此能够绕过Union File System提供一些用于持续存储或者共享数据的特性。
卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此docker不会再容器删除时删除其挂载的数据卷。
它还存在以下几种特点:
1、数据卷可在容器之间共享或者重用数据。
2、卷中的更改可以直接生效。
3、数据卷中的更改不会包含在镜像的更新中。
4、数据卷的生命周期一直持续到没有容器使用它为止。
说白了这个容器数据卷的作用就是这个将容器内重要的数据进行备份将容器内的数据进行映像到宿主机里面持久化到本地主机目录
下面我们来看看如何使用这个容器数据卷,一起来看看哈
docker run -it -v --privileged=true 主机目录:容器目录 /bin/bash
–privileged=true 加上保证能有这个权限
下面我们已这个ubuntu为例进行一个实验。
docker run -it --privileged=true -v /tmp/host_data:/tmp/docker_date --name="u1" ubuntu bin/bash
我们进去这个容器内部然后cd 到tmp目录下的docker_date目录下
下面我们退出这个容器进入到宿主机的tmp目录下的host_data目录下
我们发现这个宿主机这个目录下直接就有我们再容器里面新创建的这个test.txt这个目录了。下面我们再主机上建立一个ksy.txt再进入到容器当中查看是否有这个文件
下面我们进入到容器当中去
我们发现这个容器里面也有这个文件这就做到了这个容器里面的数据和宿主机里面的数据进行了同步实现了双方的互通有无
下面我们使用docker inspece 容器id查看容器的相关信息
docker inspect 134db0e71cad
下面如果我们将容器停止主机的数据是否会消失了我们下面实验一下
此时如果我们再容器停止的情况下再主机里面新建一个test.c我们再将这个容器重新启动,进入到容器是否容器里面也会有这个文件呢?
我们再进入到容器里面我们发现这个文件依然有
根据上面的实验结果再这里总结一下这个容器数据卷
- docker修改,主机同步获得
- 主机修改,docker同步获得
- docker容器stop,主机修改,docker容器重启数据依然同步
2.容器数据卷ro_rw的读写规则
下面我们继续学习这个容器数据卷ro_rw的读写规则。我们上面的案例默认是这个可读可写的。有时候我们可能需要容器里面的权限由这个读写权限改为这个只读权限。
下面我们通过一个案例来进行说明来演示一下这个权限的限制
docker run -it --privileged=true -v /mydocker/u:/tmp/u:ro --name="u2" ubuntu /bin/bash
主要这个 :ro 代表的是再容器里面只有只读权限没有写权限下面我们再容器里面我们创建一个文件。
我们发现再容器里面无法创建文件但是这个再宿主机里面创建的文件再容器里面是可以读的铁子们可以自行进行实验再这里不进行过多的实验。
3.容器数据卷的继承
这个容器数据卷的继承非常的好理解就和这个java或者c++里面继承是一样的
废话不多说下面我们直接上案例来进行实验。
docker run -it --privileged=true --volumes-from u2 --name="u3" ubuntu /bin/bash
我们发现这个u3的tmp目录下和这个u2的是一样的也有这个目录这样就实现了这个容器的共享和这个数据的互相传递。
docker 安装常规软件
再这里我们主要介绍这个tomcat、mysql、redis、nginx的安装剩下的各位老铁可以自行进行模仿即可非常的简单。
安装主要主要是使用这个 docker pull+docker run 具体步骤可以总结为这个
1. tomcat安装
下面我们已这个tomcat的安装为例来进行这个实验。第一步docker search
去这个 docker hup上去查找
再这里博主已经下载好了再这里就不重复下载了。铁子们可以自行进行下载
下面我们直接启动tomcat
docker run -it -d -p 8012:8080 --name="tomcat1" tomcat
我们发现这个tomcat已经成功启动成功了。下面我们实验浏览器来来进行访问
我们发现怎么是404找不到啊这是因为这个tomcat访问主页发生了变化下面我们进入到容器内部去
docker exec -it 4b25376496f0 /bin/bash
rm -rf webapps
mv webapps.dist webapps
这是因为这个webapps是空的我们需要进行修改,修改之后我们重新用浏览器访问就可以了。
这是一个坑各位铁子需要注意哈!!!!!!
2. mysql 安装
和这个docker search 查看msyql的镜像再这里博主选择mysql:5.7为例来进行这个实验。铁子们可以安装其他版本进行实验可自行决定
docker pull mysql:5.7
下面我们运行这个mysql 这个命令均来自官网。铁子们也可以去docker hup上进行查看再这里直接给出
docker run -p 8087:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
这个-e 来指定这个密码
下面我们进入到这个容器里面实验mysql -uroot -p 进行连接
下面我们再这个数据库里面建一张表
我们发现插入中文的时候失败了这是为什么了。再这里还需要注意的是如果这个进去的时候无法敲出中文进入容器的时候使用下面这条命令即可
docker exec -it container_name env LANG=C.UTF-8 /bin/sh
可能有老铁就有疑问了为什么这个无法插入英文了下面我们再mysql里面查看一下这个字符集。
好家伙我们发现这个字符集居然是这个latin1难怪我们插入中文会失败
show variables like 'character%';
这个问题还是一个小问题,主要是这个如果这个容器被删了这个容器运行的这个mysql上面的数据不就被删除了吗?这才是最主要的问题。下面我们就来解决这两个问题。
下面我们重新运行一下这个mysql 容器这个命令有点复杂铁子们好好看看
docker run -d -p 8087:3306 --privileged=true -v /zzyyuse/mysql/log:/var/log/mysql -v /zzyyuse/mysql/data:/var/lib/mysql -v /zzyyuse/mysql/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=12345 --name mysql mysql:5.7
其实就是利用了这个容器数据卷来将数据进行备份而已。没有那么的复杂
解决这个中文乱码问题我们只需要进入到这个宿主机的目录下去修改配置文件即可
cd /zzyyuse/msyql/conf/
vim my.cnf
然后再my.cnf里面写入这些数据就可以了
[client]
default_character_set=utf8
[mysqld]
collation_server = utf8_general_ci
character_set_server = utf8