【微服务】——Docker与微服务(下)

举报
雪月清 发表于 2022/05/25 20:58:23 2022/05/25
【摘要】 docker镜像是什么?镜像是如何加载的?镜像为什么要分层?容器数据卷是什么?有什么用?docker上安装常用软件如tomcat、mysql、redis需要注意什么?如果你有以上疑问,本文将帮你解惑

🐳 一、镜像

镜像是一种轻量级、可执行的独立软件包,它包含运行某个软件所需的所有内容,我们把应用程序和配置依赖打包形成一个可交付的运行环境(包括代码、运行时需要的库、环境变量和配置文件等),这个打包好的运行环境就是image镜像文件

🐋 1.镜像分层

以tomcat镜像为例,我们发现在pull的过程中镜像好像一层一层的在下载
image-20220426095600861

🐟 1. Docker镜像加载原理:

docker镜像实际上由一层一层的文件系统组成,这种层级的文件系统就是联合文件系统(UnionFS)

🐟 2. UnionFS(联合文件系统)

UnionFS(联合文件系统):Union文件系统是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加, 同时可以将不同目录挂载到同一个虚拟文件系统下。Union文件系统时Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像)可以制作除具体的应用镜像。

🐟 3. 具体细节

  • bootfs(boot file sysytem)
    主要包含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等

🐟 4. 镜像分层的好处

共享资源,方便复制迁移、复用

比如说多个镜像都是从相同的一份base镜像构建而来(更详细的讲 假如base镜像共有十层,而A镜像是base镜像的前三层,B镜像是base镜像的后三层),那么我们只需要在磁盘上保存一份base镜像,在内存中加载一份base镜像,就可以为所有由base镜像构建而来的镜像的实例容器服务了。

通俗来讲,大学图书馆分为好几层,如工学、文学、医学每个大的分区又可以细分多个不同的子领域,而我们全校的学生虽然专业众多,但是都可以在图书馆找到属于自己专业的书籍。这样我们就不需要因为学科领域不同也建造多个图书馆了

🐟 5. 容器层、镜像层

当容器启动时,一个新的可写层被加载到镜像的顶部,这一层通常被称为 " 容器层" "容器层 " 之下的都叫 " 镜像层 "Docker镜像层都是只读的,容器层是可写的。

这个好理解,图书馆中的书可以借阅,但是图书馆地基和整体建筑肯定不能随便动

在docker上运行Ubuntu容器实例,使用vim编辑文件,发现报错了,找不到vim

image-20220426145805787

原因:

这是由于镜像是简易版的Linux,仅包括Linux内核等一些重要的。

但是我们进行配置文件的修改,需要用到vim编辑器,这时候就需要镜像加强

apt update 更新包管理工具(ubuntu)

image-20220426151852775

apt install vim 下载vim

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LUWZxOjQ-1651065041188)(https://gitee.com/duck-snow/picture/raw/master/img/202204261520024.png)]

使用vim编辑器,新建文件a.txt 并写入hello docker,保存退出。读取a.txt文件
image-20220426152205768
ctrl+q+p 退出容器 docker ps 查看正在运行的容器
image-20220426152828165
第一个就是我们刚才使用的带vim编辑器的ubuntu容器

docker commit -m="提交的描述信息" -a="作者" 容器ID 要创建的目标镜像名:[标签名]
image-20220426154104704
commit 带vim编辑器的ubuntu容器到本地,查看本地镜像发现带vim的大小多了近100MB,这就是为什么镜像文件小的原因所在,只是按需下载

Docker中的镜像分层,支持通过扩展现有镜像,创建新的镜像。

🐋 2.本地镜像发布到阿里云

在阿里云控制台 -> 容器镜像服务 -> 个人实例(创建一个用于测试)

image-20220426160030750

image-20220426160116166
image-20220426160129029

🐟 1. 创建命名空间
image-20220426160300910
🐟 2. 创建镜像仓库
image-20220426161646176
image-20220426160610056

🐟 3. 阿里云会自动生成操作指南
image-20220426162103327

我们使用 3.讲镜像推送到Registry

🐟 4. 登录

docker login --username=用户名 registry.cn-shanghai.aliyuncs.com

image-20220426161041015

🐟 5. 设置镜像版本号

docker tag [ImageId] registry.cn-shanghai.aliyuncs.com/xueyueqing/ubuntu:[镜像版本号]

image-20220426161925142
🐟 6. 推送

docker push registry.cn-shanghai.aliyuncs.com/xueyueqing/ubuntu:[镜像版本号]

image-20220426162700565
🐟 7. 测试

删除本地Ubuntu1.3的镜像
image-20220426162930473
🐟 8. 从阿里云Registry中拉取镜像

docker pull registry.cn-shanghai.aliyuncs.com/xueyueqing/ubuntu:[镜像版本号]
image-20220426163037101
测试成功!
image-20220426163234919

🐳 二、容器数据卷

🐋 1.作用

🎣 试想一下:我们的docker容器很容易被自己误删或者被别人恶意删除,那我们容器中的重要数据不就丢失了吗?

docker采用容器数据卷的方式解决此类问题。

卷就是目录或文件,存在于一个或多个容器中,由docker挂载到容器,不属于联合文件系统,可以绕过联合文件系统提供一些用于持久化和共享数据的特性。

容器数据卷设计的目的就是数据的持久化,它完全独立于容器的生存周期,因此Docker不会再容器删除时删除其挂载的数据卷

注意事项:

Docker挂载主机目录访问如果出现cannot open directory:Permission denied解决办法:在挂载目录后多加一个--privileged=true参数即可

作用: 扩大容器的权限解决挂载目录没有权限的问题,使得容器中root拥有所有权限,否则root只是外部一个普通的用户

🐋 2.特点

  • 数据卷可在容器之间共享或重用数据
  • 卷中的更改可以直接实时生效
  • 数据卷中的更改不会包含再镜像的更新中
  • 数据卷的生命周期一直持续倒没有容器使用它为止

🐋 3.测试

docker run -it --privileged=true -v/宿主机绝对路径目录:/容器内目录 镜像名

image-20220426173618798
🐟 1. 在容器docker_data目录中创建文件
image-20220426173826473
🐟 2. 在本地host_data目录下发现 dockerin.txt文件已共享
image-20220426173916577
🐟 3. 在本地host_data目录下新建文件并写入数据 hello docker
image-20220426174227239
🐟 4. 在容器docker_data目录中发现hostin.txt文件 并读取到共享过来的数据
image-20220426174355416

🐟 5. docker inspect 容器ID 查看容器内部细节
image-20220426174849570

🎣 假设容器停止,在主机新建文件能否共享吗?

🐟 6. 停止容器
image-20220426175029711
🐟 7. 在主机创建文件c.txt
image-20220426175208189
🐟 8. 重启容器
image-20220426175351499
🐟 9. 进入容器docker_data目录下发现c.txt文件已共享
image-20220426175500997

🐋 4.容器卷的读写规则

容器数据卷的读写规则默认 rw 可读可写,就如同上述的例子

image-20220426211903142
ro:容器实例内部被限制,只能读取不能写

docker run -it --privileged=true -v/宿主机绝对路径目录:/容器内目录:ro 镜像名

🐟 1. 创建只读的Ubuntu容器实例
image-20220426211903142
🐟 2. 在本地主机上创建a.txt文件 并写入数据 xueyueqing
image-20220426212354539
🐟 3. 这容器中只能读文件,其他操作被限制
image-20220426212720211

🐋 5.容器卷的继承

docker run -it --privileged=true --volumes-from 父类 --name u2 ubuntu
image-20220426214555751
(注意:向将之前的u2容器删除,docker rm 容器ID)

🐟 1. u2继承u1的docker_data目录及目录下的文件
image-20220426214859286
🐟 2. 在u2中创建文件,u1中也会共享数据
image-20220426215340734image-20220426215429442
🎣 当u1停止了,u2会共享本地主机数据吗?
image-20220426220406315

🐟 3. u2容器共享了主机的数据
image-20220426220626177
容器卷的继承本质是继承了容器之间的规则与容器本身没有关系,因此u1容器停止不影响u2容器与本地主机数据共享

如果启动u1容器,那么u1中会有之前本地主机创建的文件吗?
image-20220426221125736

🐳 三、docker上安装常用软件

总体步骤:

1. 搜索镜像

2. 拉取镜像

3. 查看镜像

4. 启动镜像

5. 停止镜像

6. 移除容器

补充:

netstat -tunlp | grep 端口号 查看端口使用情况

ps - ef | grep 端口号 查看端口使用情况

kill - 9 进程号 杀进程

🐋 1.Tomcat

🐟 1.搜索镜像 docker search tomcat
image-20220427102425217
🐟 2.拉取镜像,一般都是使用第一个 docker pull tomcat
image-20220427102756280

🐟 3.查看tomcat镜像是否下载成功 docker images tomcat
image-20220427102857363

🐟 4.使用tomcat镜像创建容器实例 docker run -d -p 8080:8080 --name t1 tomcat

-p 小写,主机端口:docker容器端口 -d 后台运行

-P 大写,随机分配端口

🐟 5. 启动成功
image-20220427112039535
image-20220427112401927
🐟 6. 访问不到tomcat首页
image-20220427112059951

1.首先检查防火墙端口8080是否开启,使用云服务器还需要检查云服务器安全组中的8080端口规则是否添加

2.检查tomcat中webapps目录下是否有tomcat首页

🐟 7. 进入tomcat容器,发现tomcat中webapps目录下为空
image-20220427112708149

🐟 8. 删掉webapps,将webapps.dist 改为webapps

image-20220427112959281
成功了!!!

image-20220427113110084

(原因是因为新版tomcat 默认访问路径webapps目录是空的,默认配置在webapps.dist目录中 ,需要修改下)

🐟 9. 停止、删除容器一气呵成

image-20220427113440405

🐋 2.MySQL

🐟 1. 简易版

🐟 1.搜索镜像 docker search mysql
image-20220427114509768

🐟 2.拉取镜像,使用5.7版本的 docker pull mysql:5.7
image-20220427114645738
🐟 3.查看mysql镜像是否下载成功 docker images mysql
image-20220427152032958

🐟 4.使用tomcat镜像创建容器实例 docker run -d -p 8080:8080 --name t1 tomcat

先检查Linux本地主机是否启动了MySQL,防止端口冲突

image-20220427151955434

🐟 5. 启动容器 docker run -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
image-20220427153110872
🐟 6. 进入容器,登录root用户

🐟 7. 简单测试下MySQL

image-20220427153834594image-20220427153928539

🐟 8. 使用SQLyog测试 连接成功

image-20220427155553995

🎣 问题一:测试中文数据,发现乱码

image-20220427155916479
🎣 问题二:mysql容器如果被误删了,那么我的数据该怎么办
image-20220427160706787

解决方案:请看实战版

🐟 2. 实战版

🐟 1. 创建一个mysql目录保存数据
image-20220427161033195

🐟 2. 使用容器卷保存数据 docker run -d -p 3306:3306 --privileged=true -v /mysql/log:/var/log/mysql -v /mysql/data:/var/lib/mysql -v /mysql/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=123456 --name mysql mysql:5.7
image-20220427161949348

🐟 3. 在本地主机/mysql/conf目录下新建my.cnf 文件利用容器卷共享,将文件共享到mysql容器解决乱码

[client]
default_character_set=utf8
[mysqld]
collation_server = utf8_general_ci
character_set_server = utf8

image-20220427172547233

🐟 4. 进入容器,登录mysql

image-20220427163429305

🐟 5. 查看mysql编码 show variables like 'character%'

image-20220427172807607
🐟 6. 测试
image-20220427163807104
🐟 7. 成功解决中文乱码问题
image-20220427173039827

🐟 8. mysql容器被删了😂😂😂

image-20220427200644831
这个时候就不怕数据丢失了,因为我们之前使用容器卷保存数据了

🐟 9. 再次创建mysql容器 数据卷宿主机绝对路径就是之前设置的
image-20220427200856505
🐟 10. 数据库中数据从本地主机共享过来了,再也不怕删库跑路了🤣🤣🤣

image-20220427201232966

🐋 3.Redis

🐟 1.搜索镜像 docker search redis
image-20220427201623961

🐟 2.拉取镜像, docker pull redis

🐟 3.查看tomcat镜像是否下载成功 docker images redis

🐟 4.进入容器,连接客户端
image-20220427202231504

这样肯定是不行的,因为redis需要保存数据,还要修改配置文件

🐟 5.在本地主机新建目录 /app/redis

image-20220427202849500

🐟 6.将一个redis.conf 文件模板拷贝进 /app/redis 目录下

image-20220427203456004

🐟 7.修改redis.conf配置文件

image-20220427203737357

🐟 8.将daemonize yes改为 no ,因为该设置何docker run中-d参数冲突,会导致容器一直启动失败

image-20220427203859005
🐟 9.再次创建redis容器(记得先把之前6379端口停了)

docker run -p 6379:6379 --name myredis --privileged=true -v /app/redis/redis.conf:/etc/redis/redis.conf -v /app/redis/data:/data -d redis redis-server /etc/redis/redis.conf

image-20220427205627982

🐟 10.测试连接成功
image-20220427210331720


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。