熬夜干Docker

1. docker概述

官方网站:https//:www.docker.com/
文档地址:https://docs.docker.com/
仓库地址:https://hub.docker.com/

每一项技术的出现,都是因为之前的技术出现了问题。

遇到问题:

一款产品:开发-上线,两套环境(测试、生产),应用环境、应用配置,现在出现了如下的问题:

  • 版本更新,导致服务不可用,环境配置十分的麻烦,每一个机器都要部署环境(集群Redis、ES、Hadoop…),费时费力。
  • 服务器配置一个应用的环境(Redis、Mysql、jdk、es、hadoop),配置麻烦。

解决问题:

  • 使用了 Docker之后,我们部署应用就和搭积木一样 项目打包为一个镜像,扩展服务器A,服务器B…更简单的系统运维 在容器化之后,我们的开发,测试环境都是高度一致的, 更高效的资源利用(docker是go语言开发的开源项目)

虚拟机技术对比docker容器技术:

虚拟机技术:

  • 传统虚拟机,虚拟出硬件,运行一个完整的操作系统,然后在这个系统上安装和运行软件,占用资源十分多,启动很慢。
    在这里插入图片描述

docker容器技术:

  • 容器化技术不是模拟一个完整的操作系统,容器内的应用直接运行在宿主机的内核,容器是没有自己的内核的,也没有虚拟我们的硬件,所以就轻便了,每个容器间是互相隔离,每个容器内都有一个属于自己的文件系统,互不影响。

  • Docker是内核级别的虚拟化,可以在一个物理机上可以运行很多的容器实例!服务器的性能可以被压榨到极致。
    在这里插入图片描述

2. docker安装

2.1 docker基本组成

docker的基本组成:

  • 镜像(image): docker镜像就好比是一个模板,可以通过这个模板来创建容器服务,tomcat镜像-->run-->容器(提供服务器),通过这个镜像可以创建多个容器(最终服务运行或者项目运行就是在容器中的)。

  • 容器(container): docker利用容器技术,独立运行一个或者一组应用,通过镜像来创建的。

  • 仓库(repository): 仓库就是存放镜像的地方,仓库分为公有仓库和私有仓库(类似于github)。默认仓库Docker Hub是国外的,可以修改成国内的。

docker基本操作流程:

  • docker启动之后,有客户端服务端,客户端使用docker命令进行访问。
  • docker run 运行一个容器,真正的运行是在docker的服务上去运行,是一个docker的守护进程。
  • docker守护进程要运行,要通过镜像来运行,运行镜像来生成对应的容器。
  • 这些镜像可能来自我们的远程仓库
    在这里插入图片描述

2.2 docker安装

前提条件:uname -r查看Linux内核版本,必须是3.10以上

(1)移除旧的镜像

 yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

(2) 安装需要的包

yum install -y yum-utils

(3) 设置docker镜像仓库( 推荐使用阿里云 )

yum-config-manager \ 
		--add-repo \
		http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

更新软件包索引

yum makecache fast

(4) 安装docker相关的内容 – docker-ce 社区版 docker-ee 企业版

yum install docker-ce docker-ce-cli containerd.io -y

(5) 启动docker

systemctl start docker
systemctl enable docker
systemctl status docker

(6) 使用docker version 看是否安装成功
在这里插入图片描述
(7)通过运行hello-world镜像验证 Docker 是否正确安装。
(8)查看下载的hello-world镜像

[root@docker ~]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
hello-world   latest    d1165f221234   6 months ago   13.3kB

2.3 docker卸载

1. 卸载依赖
	yum remove docker-ce docker-ce-cli containerd.io

2. 删除资源
	rm -rf /var/lib/docder (docker的默认工作路径)
	rm -rf /var/lib/containerd

2.3 阿里云镜像加速

(1) 登录阿里云找到容器服务
在这里插入图片描述
在这里插入图片描述
(2)找到镜像加速地址
在这里插入图片描述
(3)配置使用:

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://yws0gs4h.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

2.4 docker执行原理
docker run hello-world 执行的流程图
在这里插入图片描述
docker底层工作原理:

docker是一个Client- Server结构的系统,docker的守护进程运行在主机上。通过客户端访问。
dockerServer接收到docker-client的指令,就会执行这个命令。
在这里插入图片描述

3. docker命令

3.1 帮助命令

docker version  	# 显示docker
docker info			# 显示docker的系统信息
docker 命令 --help   # 帮助命令

帮助文档的地址:https://docs.docker.com/engine/reference/commandline/cp/

3.2 镜像命令

docker images查看所有本地的主机上的镜像

[root@docker ~]# docker images 
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
hello-world   latest    d1165f221234   6 months ago   13.3kB

# 解释
REPOSITORY 镜像的仓库源
TAG		   镜像的标签
IMAGE ID   镜像的id
GREATED	   镜像的创建时间
SIZE	   镜像的大小

# 可选项
	-a,--all    # 列出所有镜像
	-q,--quiet  # 只显示镜像的id

docker search搜索镜像(在镜像库中搜索镜像)

[root@docker ~]# docker search mysql
NAME                              DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
mysql                             MySQL is a widely used, open-source relation…   11404     [OK]       
mariadb                           MariaDB Server is a high performing open sou…   4329      [OK]       

## 可选项,通过搜索来过滤
--filter=STARS=300  # 搜索出来的镜像就是STARS大于3000的

[root@docker ~]# docker search mysql --filter=STARS=3000
NAME      DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
mysql     MySQL is a widely used, open-source relation…   11404     [OK]       
mariadb   MariaDB Server is a high performing open sou…   4329      [OK]       

[root@docker ~]# docker search mysql --filter=STARS=6000
NAME      DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
mysql     MySQL is a widely used, open-source relation…   11404     [OK]       

docker pull下载镜像

# 下载镜像 docker pull 镜像名[:tag]
[root@docker ~]# docker pull mysql
Using default tag: latest  #如果不写tag,默认就是latest
latest: Pulling from library/mysql
a330b6cecb98: Pull complete  # 分层下载,docker image的核心,联合文件系统
9c8f656c32b8: Pull complete 
88e473c3f553: Pull complete 
062463ea5d2f: Pull complete 
daf7e3bdf4b6: Pull complete 
1839c0b7aac9: Pull complete 
cf0a0cfee6d0: Pull complete 
1b42041bb11e: Pull complete 
10459d86c7e6: Pull complete 
b7199599d5f9: Pull complete 
1d6f51e17d45: Pull complete 
50e0789bacad: Pull complete 
Digest: sha256:99e0989e7e3797cfbdb8d51a19d32c8d286dd8862794d01a547651a896bcf00c
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest  # 真实地址

# 等价于它
docker pull mysql
docker pull docker.io/library/mysql:latest

# 指定版本下载
[root@docker ~]# docker pull mysql:5.7
5.7: Pulling from library/mysql
a330b6cecb98: Already exists 
9c8f656c32b8: Already exists 
88e473c3f553: Already exists 
062463ea5d2f: Already exists 
daf7e3bdf4b6: Already exists 
1839c0b7aac9: Already exists 
cf0a0cfee6d0: Already exists 
fae7a809788c: Pull complete 
dae5a82a61f0: Pull complete 
7063da9569eb: Pull complete 
51a9a9b4ef36: Pull complete 
Digest: sha256:d9b934cdf6826629f8d02ea01f28b2c4ddb1ae27c32664b14867324b3e5e1291
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7

在这里插入图片描述

docker rmi 删除镜像

[root@docker ~]# docker rmi -f  镜像id   #删除指定的容器
[root@docker ~]# docker rmi -f  容器id  容器id # 删除多个容器
[root@docker ~]# docker rmi -f  $(docker images -aq) # 删除全部的容器

3.3 容器命令

说明:我们有个镜像才可以创建镜像,Linux,下载一个centos来测试学习

docker pull拉取镜像

docker pull centos

docker run 新建容器并启动

docker run [可选参数] image
# 参数说明
--name="Name"  # 容器名字 tomcat01 tomcat02,用来区分容器
-d  		   # 后台方式运行
-it 		   # 使用交互方式运行,进入容器查看内容
-p			   # 指定容器的端口 -p 8080:8080 
	-p ip:主机端口:容器端口
	-p 主机端口:容器端口(常用)
	-p 容器端口
-P			   # 随机指定端口

# 测试,启动并进入容器
[root@docker ~]# docker run -it centos /bin/bash
[root@4c218a662979 /]# ls # 查看容器内的centos,基础版本,很多命令都是不完善的!
bin  etc   lib	  lost+found  mnt  proc  run   srv  tmp  var
dev  home  lib64  media       opt  root  sbin  sys  usr

# 从主机中退回主机
[root@4c218a662979 /]# exit
exit
[root@docker ~]# ls
anaconda-ks.cfg

docker ps列出所有的运行的容器

# docker ps 命令
	  # 列出当前正在运行的容器
-a	  # 列出当前正在运行的容器+带出历史运行过的容器
-n=# 显示最近创建的容器
-q	  # 只显示容器的编号

[root@docker ~]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

[root@docker ~]# docker ps -a
CONTAINER ID   IMAGE         COMMAND       CREATED         STATUS                     PORTS     NAMES
4c218a662979   centos        "/bin/bash"   9 minutes ago   Exited (0) 7 minutes ago             gifted_chatterjee
35d6cbb3d074   hello-world   "/hello"      11 hours ago    Exited (0) 11 hours ago              elated_gates

exit退出容器

exit  # 直接容器停止并推出
ctrl + P + Q  # 容器不停止推出

docker rm删除容器

docker rm 容器id   # 删除指定的容器,不能删除正在运行的容器,如果强制删除rm -rf 
docker  rm -f $(docker ps -aq)    # 删除所有的容器
docker ps -a -q | xargs docker rm # 删除所有的容器

docker start stop启动和停止容器的操作

docker start 容器id  # 启动容器
docker restart 容器id  # 重启容器
docker stop 容器id    # 停止当前正在运行的容器
docker kill 容器id   # 强制停止当前的容器

3.4 其他常用命令

后台启动容器

# 命令 docker run -d 镜像名
[root@docker ~]# docker run -d centos
# docker ps 发现centos停止了
# 常见的坑:docker 容器使用后台运行,就必须要有一个前台进程,docker发现没有应用,就会自动停止
# nginxm, 容器启动后,发现自己没有提供服务,就会立刻停止,就是没有程序了。

查看日志

docker logs -f -t --tail 容器,没有日志
# 自己编写一段shell脚本
[root@docker ~]#  docker run -d centos /bin/sh -c "while true; do echo dongkun ;sleep 1;done" 
 
[root@docker ~]# docker ps 
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS     NAMES
e5cd26cb3c77   centos    "/bin/sh -c 'while t…"   14 seconds ago   Up 13 seconds             confident_nobel

# 显示日志
-tf   # 显示日志
--tail number # 要显示日志条数
[root@docker ~]# docker logs -tf --tail 10 e5cd26cb3c77

docker top查看容器中进程信息ps

# 命令docker top 容器id
[root@docker ~]# docker top e5cd26cb3c77

docker inspect查看镜像的元数据

# 命令
docker inspect 容器id

# 测试
[root@docker ~]# docker inspect e5cd26cb3c77
[
    {
        "Id": "e5cd26cb3c77f556dd57e2addb1ac859e5d14be6aece1349cad9d89bed817a31",
        "Created": "2021-09-12T15:32:14.034129802Z",
        "Path": "/bin/sh",
        "Args": [
            "-c",
            "while true;do echo dongkun;sleep 1;done"
        ],
        "State": {

docker exec 进入当前正在运行的容器

# 我们通常容器都是使用后台方式进行的,需要进入容器,修改一些配置
# 方式一
docker exec -it 容器id   bash
[root@docker ~]# docker ps 
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS     NAMES
e5cd26cb3c77   centos    "/bin/sh -c 'while t…"   15 minutes ago   Up 10 seconds             confident_nobel

[root@docker ~]# docker exec -it e5cd26cb3c77 /bin/bash
[root@e5cd26cb3c77 /]# ps -ef 
UID         PID   PPID  C STIME TTY          TIME CMD
root          1      0  0 15:47 ?        00:00:00 /bin/sh -c while true;do echo dongkun;sleep 1;done
root        151      0  0 15:49 pts/0    00:00:00 /bin/bash
root        291      1  0 15:52 ?        00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1
root        292    151  0 15:52 pts/0    00:00:00 ps -ef

# 方式二
docker attach 容器id
# 测试
[root@docker ~]# docker attach e5cd26cb3c77
dongkun
dongkun
正在执行当前的代码

# docker exec   # 进入容器后开启一个新的终端,可以在在里面操作(常用)
# docker exec   # 进入容器正在执行的终端,不会启动新的进程

docker cp从容器内拷贝文件到主机上

docker cp 容器id:容器内路径 目的主机路径
# 查看当前主机目录下
[root@docker ~]# ls /home/
[root@docker ~]# docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED       STATUS              PORTS     NAMES
40875467988c   centos    "/bin/bash"   2 hours ago   Up About a minute             practical_robinson

# 进入docker容器内部
[root@docker ~]# docker attach 40875467988c
[root@40875467988c /]# cd /home
[root@40875467988c home]# ls

# 在容器内容新建一个文件
[root@40875467988c home]# touch hello.java
[root@40875467988c home]# ls
hello.java

# 这里docker容器是启动的还是停止的都不影响,因为只要里面的数据
# 将文件拷贝出来到主机上
[root@docker ~]# docker cp 40875467988c:/home/hello.java /home
[root@docker ~]# ls /home/
hello.java
# 拷贝是一个手动过程,我们可以使用 -v 数据卷技术,可以实现同步的功能,类似于挂载

3.5 小总结

在这里插入图片描述

attach    Attach to a running container    # 当前shell下,attach 连接指定运行镜像
build     build an image from a Dockerfile    # 通过dockerfile 定制镜像
commit	  Create a new image from a container changes   # 提交当前容器为新的镜像
cp 		  Copy files/folders from the containers filesystem to the host path    # 从容器中拷贝指定文件或者目录到宿主机中
create 	  Create a new container   # 创建一个新的容器,同run,但不启动容器
diff	  Inspect changes on a container's filesystem   # 查看docker容器变化
events    Get real time events from the server   # 从docker服务器获取容器实时事件
exec      Run a command in an existingcontainer   # 在已存在的容器上运行命令
export 	  Stream the containers of a container as a tar archive    # 导出容器的内容流作为一个tar归档文件【对一个import】
history	  Show the history of an image    # 展示一个镜像形成历史
images    List images    # 列出系统当前镜像
import	  Create  a new filesystem image from the contents of a tar	tarball # 从tar 包中的内容创建一个新的文件系统镜像[对应export]
info      Display system-wide information    # 显示系统相关信息
inspect   Return low-level information on a container  # 查看容器信息
kill	  kill a running container   # kill 指定docker容器
load	  load an image from a tar archive   # 从一个tar包中加载一个镜像【对应 save】
login	  Register or login to the docker registry server   #  注册或者登录一个docker源服务器
logout 	  Log out from a Docker registry server    # 从当前 docker registry 退出
logs 	  Fetch the logs of a container   # 输出当前容器日志信息
port	  Lookup the public-facing port which is  NAT-ed to PRIVATE_PORT  # 查看映射端口对应的容器内部源端口
pause     Pause all processes within a container   # 暂停容器
ps		  List containers   # 列出容器列表
pull	  Push an image or a repository to the docker registory server   # 从docker镜像源服务器拉取指定镜像或者库镜像
push	  Push an image or a repository to the docker registry server   # 推送指定镜像或者库镜像至docker源服务器
restart   Restart a running container    # 重启运行的容器
rm        remove  one or more  containers   # 移除一个或者多个容器
rmi	      remove one or more  images    # 一处一个或多个镜像【无容器使用,该镜像才可删除,否则需删除相关容器才可以继续或 -f 强制删除】
run       Run a command in a new container   # 创建一个新的容器并运行一个命令
save      Save an image to a tar archive    # 保存一个镜像为一个tar包【对应load】
search    Search for an image on the Docer Hub  # 在docker hub中搜索镜像
start	  Start a stopped containers   # 启动容器
stop      Stop a running containers   # 停止容器
tag		  Tag an image into a repository   # 给源中镜像打标签
top		  Lookup the running into a repository   # 查看容器中运行的进程信息
unpause   Unpause a paused container   # 取消暂停容器
version   Show the docker version information   # 查看docker版本号
wait  	  Block until a container stops,then print its exit code   # 截取容器停止时的退出状态值

3.6 小练习

3.6.1 docker部署nignx

重点: 暴露端口的必要性

# 1. 搜索镜像 search  可以去docker hub上去搜索,可以看到帮助文档

# 2. 下载镜像 pull,并且运行容器
# 下载镜像,可以到docker hub上查看可以下载的版本
[root@docker ~]# docker pull nginx
Using default tag: latest

# 查看你存在的镜像
[root@docker ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
nginx        latest    ad4c705f24d3   3 days ago     133MB
centos       latest    300e315adb2f   9 months ago   209MB

# 运行镜像,并启动容器,如果本地不存在镜像,则会到远程仓库拉取 
# -d 后台运行
# --name 给容器命名
# -p 宿主机端口:容器内部端口
[root@docker ~]# docker run -d --name nginx01 -p 3344:80 nginx
30c15589279e884c8ffdb76a9b6958dae98b7ce033853ad77ea86aabcefae162

# 查看正在运行的容器
[root@docker ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                                   NAMES
30c15589279e   nginx     "/docker-entrypoint.…"   3 minutes ago   Up 3 minutes   0.0.0.0:3344->80/tcp, :::3344->80/tcp   nginx01

# 进入容器内
[root@docker ~]# docker exec -it nginx01 /bin/bash
root@30c15589279e:/# ls
bin   docker-entrypoint.d   home   media  proc	sbin  tmp
boot  docker-entrypoint.sh  lib    mnt	  root	srv   usr
dev   etc		    lib64  opt	  run	sys   var

# 3. 进行测试(也可以在浏览器中进行访问)
[root@docker ~]# curl  localhost:3344
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>

暴露端口的原理:
在这里插入图片描述

3.6.2 docker部署tomcat

重点: 官方测试,以及进入容器查看的重要性(从而引出数据卷)

# 官方的使用 (容器运行完之后删除,但是镜像没有删除)
docker  run -it  --rm tomcat:9.0
# 之前的启动都是后台,停止容器之后,容器还是可以查到 docker run -it --rm,一般用来测试,用完就删除

# 1. 下载在启动
[root@docker ~]#  docker pull tomcat 

# 2. 启动运行
[root@docker ~]#  docker run -d -p 3355:8080 --name tomcat01 tomcat

# 3. 测试访问(这是还不能访问,因为容器内/usr/local/tomcat/webapps里没有项目)
# 解决: 进入容器内把webapps.dist下的文件拷贝到webapps中
[root@docker ~]#  curl  localhost:3355

# 4. 进入容器(执行下面的操作后,可以成功的访问tomcat)
[root@docker ~]# docker exec -it tomcat01 /bin/bash
root@797ff351e2b6:/usr/local/tomcat# cp -r webapps.dist/* webapps

# 发现问题:默认是最小的镜像,所有不必要的都剔除掉,保证最小运行的环境

小提示: 如果这里使用数据卷的话,修改文件就不用在进入容器中,直接在宿主机上操作即可。

3.6.3 docker部署es+kibana

重点: 如何看容器当前的存活状态,如何进行修改

# es暴露的端口很多
# es 十分的耗内存
# es 的数据一般需要放置到安全目录!挂载
# --net somenetwork 网络配置
(1) 启动 elasticsearch

docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m"  elasticsearch:7.6.2

(2)  使用docker stats 查看es内存使用情况

在这里插入图片描述

(3)   因为es消耗内存非常大1.xG,增加内存的限制,修改配置文件 -e 环境配置修改

docker run -d --name elasticsearch02 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m"  elasticsearch:7.6.2

(4)   使用 docker stats 进行查看程序占用内存的大小(内存占用空间明显变小)

在这里插入图片描述

(5)测试es是否正常运行
[root@docker ~]# curl localhost:9200
{
  "name" : "3d340731321f",
  "cluster_name" : "docker-cluster",
  "cluster_uuid" : "YqQMzTw3Qy-bZmVzymrQ3A",
  "version" : {
    "number" : "7.6.2",
    "build_flavor" : "default",
    "build_type" : "docker",
    "build_hash" : "ef48eb35cf30adf4db14086e8aabd07ef6fb113f",
    "build_date" : "2020-03-26T06:34:37.794943Z",
    "build_snapshot" : false,
    "lucene_version" : "8.4.0",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}

在这里插入图片描述

3.7 docker 可视化

(1) portainer(docker图形化揭秘那管理工具,提供一个后台面板供我们操作)
 docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
 
(2) Rancher(CI/CD用)

进行测试访问:http://10.0.0.100:8088
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4. docker镜像

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

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

如何得到镜像:

  • 从远程仓库下载
  • 朋友拷贝给你
  • 自己制作一个镜像DockerFile

4.1 镜像原理之联合文件系统

docker pull 下载镜像的时候,下面进行分层下载,这个就是使用了联合文件系统
UnionFS(联合文件系统)

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

特性: 一次同时加载多个文件系统,但从外面看来,只能看到一个文件系统,联合加载会把各层的文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。

docker镜像加载原理
docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。
bootfs(boot file system)主要包含bootloader和kernel,bootloader主要引导加载kernel,Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。
黑屏--加载-开机进入系统 加载完成之后,加载就可以卸载掉了,所以bootfs是公用的

rootfs(root file system),在bootfs之上。包含的就是典型Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。rootfs就是各种不同的操作系统的发行版,比如Ubuntu,Centos等等。
在这里插入图片描述
平时我们安装虚拟机的CentOS都是好几个G,为什么Docker这里才200M?
在这里插入图片描述
对于一个精简的OS,rootfs可以很小,只需要包含最基本的命令,工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供rootfs就可以了。由此可见对于不同的Linux发行版,bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以共用bootfs。

虚拟机时分钟级别,容器是秒级!

4.2 镜像原理之分层理解

分层的镜像
我们可以去下载一个镜像,注意观察下载的日志输出,可以看到是一层一层的在下载!
在这里插入图片描述
思考: 为什么Docker镜像要采用这种分层的结构那?
最大的好处,我觉得莫过于是资源共享了!比如有多个镜像都从相同的Base镜像构建而来,那么宿主机只需在磁盘上保留一份base镜像,同时内存中也只需要加载一份base镜像,这样就可以为所有的镜像服务了,而且镜像的每一层都可以被共享。
查看镜像分层的方式可以通过docker image inspect命令!

[root@docker ~]# docker image inspect redis:latest
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:d000633a56813933cb0ac5ee3246cf7a4c0205db6290018a169d7cb096581046",
                "sha256:bdad86443e47c5665683ac41c1f24f28479d830d7e3cc47d0a337ee5166c7714",
                "sha256:6a7992ac480029d82b7dbb757d16fe5d023aa283ed32b52267cd1fe9e6b73c49",
                "sha256:be43d2475cf809c0f2ec31950e849d0f888f3121970fd99196a11a903f8c3820",
                "sha256:be5818ef2907adfe19be14bf66647b5fb5a2029143f9297f8ce1ff1fd1d35753",
                "sha256:c54e0c16ea22fa873c12f6a7f3fb4e021bb58d67c292156a6ce6e08637458b7c"
            ]
        },
			"Metadata": {
           	    "LastTagTime": "0001-01-01T00:00:00Z"
        }

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

举一个简单的例子,假如基于Ubuntu Linux 16.04创建一个新的镜像,这就是新镜像的第一层;如果在该镜像中添加Python包,就会在基础镜像层之上创建第二个镜像层;如果继续添加一个安全补丁,就是创建第三个镜像层。

该镜像当前已经包含3个镜像曾,如下图所示(这只是一个用于演示的很简单的例子)。
在这里插入图片描述
在添加额外的镜像层的同时,镜像始终保持是当前镜像的组合,理解这一点非常重要。下图中举了一个简单的例子,每个镜像层包含3个文件,而镜像包含了两个镜像层的6个文件。
在这里插入图片描述

上图中的镜像层跟之前图中的略有区别,主要目的是便于展示文件。
下图中展示了一个稍微复杂的三层镜像,在外部看来整个镜像只有6个文件,这是因为最上层中的文件7是文件5的一个更新版本。
在这里插入图片描述
这种情况下,上层镜像层中的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个新镜像层添加到镜像当中。

Docker通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系统。

Linux上可用的存储引擎有AUFS、Overlay、Device Mapper、Btrfs以及ZFS。顾名思义,每种存储引擎都基于Linux中对应的文件系统或者块设备技术,并且每种存储引擎都有其独有的性能特点。

Docker在Windows上仅支持windowsfilter一种存储引擎,该引擎基于NTFS文件系统之上实现了分层和Cow。

下图展示了与系统相同的三层镜像。所有镜像层堆叠并合并,对外提供统一的视图。

在这里插入图片描述

特点:

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

4.3 commit镜像

docker commit 提交容器成为一个新的副本

# 命令和git原理类似
docker commit -m="提交的描述信息" -a="作者"  容器id 目标镜像名:[TAG]

实战测试

# 1. 启动一个默认的tomcat
[root@docker ~]# docker run it -p 8080:8080 tomcat
	
# 2. 发现这个默认的tomcat是没有webapps应用的,镜像的原因,官方的镜像默认webapps下面是没有文件的!
[root@docker ~]# docker exec -it 6044d5b039ec /bin/bash

root@6044d5b039ec:/usr/local/tomcat# ls
BUILDING.txt	 LICENSE  README.md	 RUNNING.txt  conf  logs	    temp     webapps.dist
CONTRIBUTING.md  NOTICE   RELEASE-NOTES  bin	      lib   native-jni-lib  webapps  work

# 3. 自己拷贝进去基本的文件
root@6044d5b039ec:/usr/local/tomcat# cp -r webapps.dist/*  webapps/
root@6044d5b039ec:/usr/local/tomcat# exit
浏览器进行范文: 
http://10.0.0.100:8080

# 4. 将我们操作过的容器通过commit提交为一个镜像!我们以后就使用我们修改过的镜像即可,这就是我们自己的一个修改的镜像
docker commit -a="dongkun" -m="add webapps app" 6044d5b039ec tomcat02:1.0

如果你想要保存当前容器的状态,就可以通过commit来提交,获得一个镜像,就好比VM的快照。

在这里插入图片描述
学习方法:理解概念,但是一定要实践,最后实践和理论一次搞定这个只

4.4 容器数据卷使用

(1)容器数据卷介绍

  • docker的理念:将应用和环境打包成一个镜像!
  • 如果数据都在容器中,那么我们容器删除,数据就会丢失,那么我们容器删除,数据就会丢失!
    需求:数据可以持久化。 MySQL,容器删了,删库跑路!(非常危险)。 需求:MySQL数据可以存储在本地
  • 容器之间可以有一个数据共享的技术,Docker容器中产生的数据,同步到本地!这就是数据卷技术! 目录的挂载,将我们容器内的目录,挂载到宿主机上面去。
    总结: 容器的持久化和同步操作!容器间也是可以数据共享的!

在这里插入图片描述
(2)使用数据卷

# 方式一:直接使用命令来挂载 -v
docker run -it 主机目录:容器内目录

# 测试
[root@docker home]# docker run -it -v /home/test:/home  centos /bin/bash

# 启动起来时候我们可以通过 docker inspect 容器id
[root@docker home]# docker inspect ab99d62ae662
        "Mounts": [
            {
                "Type": "bind",
                "Source": "/home/test", # 宿主机的目录
                "Destination": "/home", # 容器内的目录
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],

(3)测试文件的同步

容器创建文件,宿主机同步了容器的文件
在这里插入图片描述在这里插入图片描述

(4)继续测试文件的同步

Exit退出容器后,然后容器就停止了,然后在/home/test/hehe.txt文件中输入内容,然后在启动centos容器,看一下容器内/home/hehe.txt的内容是否和宿主机的一致。结果是一致的。

优点: 我们以后修改只需要在本地修改即可,容器内会自动同步。
总结: 1. 停止容器 2. 宿主机上修改文件 3. 启动容器 4.容器内的数据依旧是同步的
小提示: docker attach ab99d62ae662 该命令是进入正在启动的容器内

在这里插入图片描述

4.5 实战演练

4.5.1 MySQL同步数据

(1)安装mysql

# 获取镜像
[root@docker home]# 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@docker home]# docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7

(2)sqlyog进行测试

mysql启动成功之后,我们在本地使用sqlyog来测试一下。
sqlyog 连接到服务器的3310 — 3310和容器内的3306映射,这个时候我们就可以连接上了!
在这里插入图片描述
在这里插入图片描述
在本地测试创建一个数据库,查看一下我们映射的路径是否ok!
在这里插入图片描述
在这里插入图片描述
(3) 测试删除容器数据卷是否保留

假设我们将容器删除
在这里插入图片描述
发现,我们挂载到本地的数据卷依旧没有丢失,这就是实现了容器数据持久化功能!
在这里插入图片描述

小提示: 在生成容器的时候,也挂载了配置文件,但是宿主机中的路径没有配置文件,是因为容器内没有生成那个配置文件。
在这里插入图片描述

4.6 匿名挂载和具名挂载

(1)匿名挂载

# 下载镜像,启动容器, -v匿名挂载
[root@docker ~]# docker run -d -p --name nginx01 -v /etc/nginx nginx

# 查看所有volume的情况
[root@docker ~]# docker volume ls 
DRIVER    VOLUME NAME
local     8e0b46f72f554c25c0b6841f6ae8da9f9d4c9b0f2adb941605733c61459ca6a8

这里发现,这种就是匿名挂载,我们在-v只写了容器的路径,没有写容器外的路径!

(2)具名挂载

# 启动容器,-v 具名挂载
[root@docker ~]# docker run -d -p --name nginx02 -v juming-nginx:/etc/nginx nginx
c09388afd8850316504d7f107cc78b5377218ea80e63261109c2a53834b11dc6

# 查看所有volume的情况
[root@docker ~]# docker volume ls
DRIVER    VOLUME NAME
local     juming-nginx

# 通过-v 卷名:容器内路径
# 查看一下这个卷

(3)查看卷名的详细信息
在这里插入图片描述
所有的docker容器内的卷,没有指定目录的情况下都是在/var/lib/docker/volumes/xxx/_data
我们通过具名挂载可以方便的找到我们的一个卷,大多是使用的具名挂载

(4) 判断匿名挂载还是具名挂载

# 如何确定是具名挂载还是匿名挂载,还是指定路径挂载!
-v 容器内路径   # 匿名挂载
-v 卷名:容器内路径 # 具名挂载
-v /宿主机路径:容器内路径 # 指定路径挂载

小拓展:

# 通过-v 容器内路径:ro rw 改变读写全新啊
ro readonly # 只读
rw readwrite # 只读可写

# 一旦这个设置了容器权限,容器对我们挂载出来的内容就有限定了!
docker run -d -p --name nginx02 -v juming-nginx:/etc/nginx:ro nginx
docker run -d -p --name nginx02 -v juming-nginx:/etc/nginx:rw nginx

# ro 只要看到ro就说明这个路径只能通过宿主机来操作,容器内部是无法操作!

5. 容器数据卷

6. dockerFile

7. docker网络原理

8. IDEA整合Docker

9. Docker Compose

10. DI\CD Jenkins

即使再小的帆也能远航

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值