docker镜像

镜像是什么?

镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需要的所有内容,包括代码、库、环境变量和配置文件。

所有的应用,直接打包镜像,就可以直接跑起来!

如何得到镜像:

1、从远程仓库下载
2、朋友拷贝给你
3、自己制作一个Dockerfile

Docker 镜像加载原理*

联合文件系统(Union File System,Unionfs)
是一种分层的轻量级文件系统,它可以把多个目录内容联合挂载到同一目录下,从而形成一个单一的文件系统,这种特性可以让使用者像是使用一个目录一样使用联合文件系统。

联合文件系统是 Docker 镜像和容器的基础,它让Docker 可以把镜像做成分层的结构,从而使得镜像的每一层可以被共享。

联合文件系统只是一个概念,真正实现联合文件系统才是关键,联合文件系统的实现方案有很多,Docker 中最常用的联合文件系统有三种:AUFS、Devicemapper 和 OverlayFS。

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等等。

对于一个精简的OS,rootfs 可以很小,只需要包含最基本的命令,工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供rootfs就可以了。由此可见对于不同的linux发行版, bootfs基本是一致的, rootfs会有差别, 因此不同的发行版可以公用bootfs。

#查看镜像分层
 docker image inspect nginx

所有的 Docker 镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层之
上,创建新的镜像层。

Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部!
这一层就是我们通常说的容器层,容器之下的都叫镜像层!

commit 镜像

docker commit 提交容器成为一个新的副本
docker commit -m="提交的描述信息" -a="作者" 容器id 要创建的目标镜像名:[标签名]
# 启动容器
 docker run -it -p 8080:8080 tomcat
 # 进入容器
 [root@iZuf6gomcpmv2fk1vu2w85Z ~]# docker exec -it dfcb5215b888 /bin/bash
 # 拷贝webapps.dist的文件到webapps目录下,这样就能显示出tomcat的首页WEB
 root@dfcb5215b888:/usr/local/tomcat# cp -r webapps.dist/* webapps
 # 新建镜像
docker commit -a=”张三“ -m="add webappps app" dfcb5215b888 tomcat02:1.0

# 可以看到新建的镜像成功了,下次可以直接运行
[root@iZuf6gomcpmv2fk1vu2w85Z ~]# docker images
REPOSITORY               TAG       IMAGE ID       CREATED         SIZE
tomcat02                 1.0       7bb5b7e54ace   5 seconds ago   684MB
nginx                    latest    605c77e624dd   14 months ago   141MB
tomcat                   latest    fb5657adc892   14 months ago   680MB
portainer/portainer-ce   latest    0df02179156a   15 months ago   273MB
centos                   latest    5d0da3dc9764   17 months ago   231MB
elasticsearch            7.6.2     f29a1ee41030   2 years ago     791MB

容器数据卷

问题:如果数据都在容器里面,当容器删除后数据就会丢失。
需求: 数据可以持久化,能永久保存
解决: 容器之间有一个数据共享技术,称之为数据卷技术,docker容器产生的数据,会自动同步到本地服务器上面。

使用数据卷

直接使用命令来挂载
docker run -it -v 主机目录:容器目录
例如: docker run -it -v /home/ceshi:/home centos /bin/bash
创建成功后,通过docker inspect 容器id,能看到详细信息,其中有

  "Mounts": [    //挂载 -v
            {
                "Type": "bind",
                "Source": "/home/ceshi",     // 主机地址
                "Destination": "/home",       //docker容器内地址
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],

当在服务器的/home目录进行文件的增删改查,会自动同步到容器的/home/ceshi目录下面。
反过来,在容器内的操作也会自动同步到外面的主机上面。
可以理解为 双向绑定

实战 安装mysql

[root@iZuf6gomcpmv2fk1vu2w85Z ceshi]# docker pull mysql:5.7
#运行容器,需要做数据挂载! 
#安装启动Mysql,需要配置密码
#官方测试 : $ docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
#启动我们的
 -d 后台运行
 --p 端口映射
 -v 数据挂载
 -e 环境配置
--name 容器名字
  
  
[root@iZuf6gomcpmv2fk1vu2w85Z home]# docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d 
-v /home/mysql/data:/var/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
或者是
[root@iZuf6gomcpmv2fk1vu2w85Z home]# docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/my.cnf.d 
-v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7

#启动之后,我们在本地用sql应用程序远程连接,测试一下
#本地的 sql程序连接到服务器的3310 ----3310和容器内部的3306映射,即可连接。

#在本地测试创建一个数据库,查看一下映射的路径是否ok.

注意

在这里由于不同的系统和版本,MySQL的路径可能不一样的。
比如有些mysql的conf路径是/etc/mysql/conf.d ;data路径是/var/mysql 。
而有些mysql的路径conf路径是/etc/mysql/my.cnf.d ;data路径是/var/lib/mysql

我们可以现在服务器登录Mysql的命令后
语法: mysql [-h 主机名] -u用户名 -p密码 [-P端口号] [-D数据库名]
参数分析:
[-h主机名或ip地址]或者[–host=主机名ip地址]:指定登录的主机名;
[-u用户名]或者[–user=用户名]: 指定用户登录的用户名;
[-p密码(p小写)]或者[–password=密码]:输入登录密码;
[-P端口号(P大写)]或者[–port=端口号]:指定登录的MySQL的端口号;
[-D数据库名]或者[–database=数据库名]:指定登录的数据库名称;

1、登录本地数据库
登录本地数据库,只需要指定用户名(-u)和密码(-p)即可,不需要指定主机名(-h),命令如下:

root@8cd4c678c5d2# mysql -uroot -p123456
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 12
Server version: 5.7.36 MySQL Community Server (GPL)

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>

通过这个命令 show variables like ‘%dir%’; 可以查看到datadir的路径是/var/lib/mysql,也就是你新建数据库和表的保存路径

mysql>  show variables like '%dir%';
+-----------------------------------------+----------------------------+
| Variable_name                           | Value                      |
+-----------------------------------------+----------------------------+
| basedir                                 | /usr/                      |
| binlog_direct_non_transactional_updates | OFF                        |
| character_sets_dir                      | /usr/share/mysql/charsets/ |
| datadir                                 | /var/lib/mysql/            |
| ignore_db_dirs                          |                            |
| innodb_data_home_dir                    |                            |
| innodb_log_group_home_dir               | ./                         |
| innodb_max_dirty_pages_pct              | 75.000000                  |
| innodb_max_dirty_pages_pct_lwm          | 0.000000                   |
| innodb_tmpdir                           |                            |
| innodb_undo_directory                   | ./                         |
| lc_messages_dir                         | /usr/share/mysql/          |
| plugin_dir                              | /usr/lib/mysql/plugin/     |
| slave_load_tmpdir                       | /tmp                       |
| tmpdir                                  | /tmp                       |
+-----------------------------------------+----------------------------+
15 rows in set (0.00 sec)

而一般情况下 ,linux安装后的mysql默认配置文件conf是在/etc/my.cnf ,我们可以设置conf文件夹去-v映射到my.conf.d文件夹。

如果我们把容器给删除了,我们挂载到本地的数据卷依然存在,数据持久化。

[root@iZuf6gomcpmv2fk1vu2w85Z data]# docker rm -f mysql01

具名和匿名挂载
#匿名挂载 -v 容器内路径 (-P 是随机映射端口)
docker run -d -P --name nginx01 -v /etc/nginx nginx

[root@iZuf6gomcpmv2fk1vu2w85Z data]# docker run -d -P --name nginx01 -v /etc/nginx nginx
f285a14d36725474dd687f84bdd2fda514f5fd57acb2c88446d45005c77f33ad
[root@iZuf6gomcpmv2fk1vu2w85Z data]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                                   NAMES
f285a14d3672   nginx     "/docker-entrypoint.…"   5 seconds ago   Up 5 seconds   0.0.0.0:1024->80/tcp, :::1024->80/tcp   nginx01
[root@iZuf6gomcpmv2fk1vu2w85Z data]#

[root@iZuf6gomcpmv2fk1vu2w85Z data]# docker volume ls
DRIVER    VOLUME NAME
local     13dca648506507fa68c29423e1433d9c76a6dd44205d52ba58de807e1c34fbb0
local     27679f1518ecddb8686b852dc7e0575aaecabb482f3917b49d51a6d7f1823772
local     330262caceee76a4f510a3157758b63e4a1ef19ffe138fa2280650519ef230f6
local     portainer_data

docker volume ls 可以查看你所有的卷,前面三个的volumeName是一串代码,说明都是没有给卷起名。

下面是具名的卷

[root@iZuf6gomcpmv2fk1vu2w85Z data]# docker run  -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
8e72db97684a78d7c66fdb24673c46b4680a5c0877e32e3db0d14202c7567cf5
[root@iZuf6gomcpmv2fk1vu2w85Z data]# docker volume ls
DRIVER    VOLUME NAME
local     13dca648506507fa68c29423e1433d9c76a6dd44205d52ba58de807e1c34fbb0
local     27679f1518ecddb8686b852dc7e0575aaecabb482f3917b49d51a6d7f1823772
local     330262caceee76a4f510a3157758b63e4a1ef19ffe138fa2280650519ef230f6
local     juming-nginx
local     portainer_data


[root@iZuf6gomcpmv2fk1vu2w85Z data]# docker volume inspect juming-nginx
[
    {
        "CreatedAt": "2023-03-06T16:16:40+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data",
        "Name": "juming-nginx",
        "Options": null,
        "Scope": "local"
    }
]

docker 容器中所有的卷,在没有指定目录的情况下,都在var/lib/docker/volumes/juming-nginx/_data",
我们可以通过具名挂载找到卷的位置,大多数情况下,我们使用具名挂载
关于docker的挂载问题,有三个比较容易混淆的概念: (区分的方式)
1.具名挂载:-v 参数 卷名:容器内路径
2.匿名挂载:-v 参数后面 没有写上容器之外的地址, docker 自己会在docker内部给你找个位置
3.指定路径挂载: -v /宿主机路径::容器内路径

rw :可读可写的权限
ro : 可读权限

docker run -d -P --name nginx03 -v juming-nginx:/etc/nginx:rw  nginx 
docker run -d -P --name nginx03 -v juming-nginx:/etc/nginx:ro  nginx 

ro 权限说明命令只可以被宿主机操作,容器的内部将无法进行操作

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值