锋盈数科-知识库 Logo
首页
软件开发
计算机基础
Hello Halo
新手必读
关于本知识库
登录 →
锋盈数科-知识库 Logo
首页 软件开发 计算机基础 Hello Halo 新手必读 关于本知识库
登录
  1. 首页
  2. 软件开发
  3. 二、Docker入门

二、Docker入门

0
  • 软件开发
  • 发布于 2024-08-19
  • 8 次阅读
黄健
黄健

1 Docker底层原理

1.1 Docker是怎么工作的?

Docker是一个Client-Server结构的系统,Docker的守护进程运行在主机上,通过socket从客户端访问。

Docker-Server接收到Docker-Client的指令,就会执行这个命令。

1.2 Docker为什么比VM快?

  • Docker有着比虚拟机更少的抽象层!
  • Docker利用的是宿主机的内核,VM利用的是Guest OS

所以说,新建一个容器的时候,docker不需要像虚拟机一样,重新加载一个操作系统内核,避免引导。虚拟机是加载Guest OS,分钟级别的;而docker是利用宿主机的操作系统,省略了这个复杂的过程,是秒级的。

2 Docker常用命令

2.1 帮助命令

docker version      显示docker的版本
docker info			查看docker的系统信息,包括镜像和容器的数量
docker 命令 --help		帮助命令		

命令的帮助文档https://docs.docker.com/reference/

2.2 镜像命令

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

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

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

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

docker search 搜索镜像:

Docker Hub 搜索镜像

[root@zlk ~]# docker search mysql
NAME                           DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
mysql                          MySQL is a widely used, open-source relation...   12635     [OK] 

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

[root@zlk ~]# docker search redis --filter=STARS=5000
NAME      DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
redis     Redis is an open source key-value store that...   10937     [OK]    

docker pull 下载镜像:

[root@zlk ~]# docker pull --help

Usage:  docker pull [OPTIONS] NAME[:TAG|@DIGEST]

Pull an image or a repository from a registry

Options:
  -a, --all-tags                Download all tagged images in the repository
      --disable-content-trust   Skip image verification (default true)
      --platform string         Set platform if server is multi-platform capable
  -q, --quiet                   Suppress verbose output
# 下载镜像 docker pull 镜像名[:tag]
[root@zlk ~]# docker pull mysql
Using default tag: latest		# 如果不写tag,默认是latest
latest: Pulling from library/mysql
72a69066d2fe: Pull complete 	#分层下载,docker image的核心 联合文件系统
93619dbc5b36: Pull complete 
99da31dd6142: Pull complete 
626033c43d70: Pull complete 
37d5d7efb64e: Pull complete 
ac563158d721: Pull complete 
d2ba16033dad: Pull complete 
688ba7d5c01a: Pull complete 
00e060b6d11d: Pull complete 
1c04857f594f: Pull complete 
4d7cfa90e6ea: Pull complete 
e0431212d27d: Pull complete 
Digest: sha256:e9027fe4d91c666666666666666f7738b66666666709
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest		# 真实地址

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

# 指定版本下载
docker pull mysql:5.7

docker rmi 删除镜像:

docker rmi -f 镜像ID		# 删除指定镜像
docker rmi -f 镜像ID 镜像ID 镜像ID     删除指定的多个镜像
docker rmi -f $(docker images -aq)		删除全部镜像	

2.3 容器命令

注意:有了镜像才可以创建容器。(以mysql镜像为例)

docker run [可选参数] image 新建容器并启动:

常用参数说明:

--name="name" 容器名字 Tomcat01 tomcat02 用来区分容器
-d 后台方式运行
-it 使用交互方式运行,进入容器查看内容
-P 指定容器的端口, -P 8080:8080
-P 主机端口:容器端口

# 测试,启动并进入容器
[root@zlk ~]# docker run -it mysql /bin/bash		
[root@6ae3c9bb6a51 /]# ls					#	查看容器内的mysql,基础版本,很多命令都是不完整的
bin  boot  dev  docker-entrypoint-initdb.d  entrypoint.sh  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var					

# 从容器中退回主机
[root@6ae3c9bb6a51 /]# exit
exit
[root@zlk /]# ls
bin   data  etc   lib    media  mydata  proc  run   srv  tmp  var
boot  dev   home  lib64  mnt    opt     root  sbin  sys  usr

docker ps [可选参数] 列出所有运行的容器:

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

退出正在运行的容器:

exit 			# 直接容器停止并退出
ctrl+p+q 	# 容器不停止退出,docker ps 可以查看到

docker rm 删除容器:

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

[root@zlk /]# docker ps -a  #查看所有容器
[root@zlk /]# docker rm 2bc63e25611d			# 不能删除正在运行的容器
Error response from daemon: You cannot remove a running container 2bc63e25611dea862ad877730bc87b2dc9ee7bcb5bfb50dc604dc146700f1b41. Stop the container before attempting removal or force remove
[root@zlk /]# docker rm 6ae3c9bb6a51  #删除一个停止运行的容器
6ae3c9bb6a51
[root@zlk /]# docker ps -aq   #查看所有容器的id

[root@zlk /]# docker rm -f $(docker ps -aq)   #删除所有容器

启动和停止已有容器的操作:

docker start 容器id			# 启动容器
docker restart 容器id		# 重启容器
docker stop 容器id			# 停止当前正在运行的容器
docker kill 容器id			# 强制停止当前的容器
[root@zlk /]# docker run -it centos /bin/bash
[root@990384ccba9f /]# exit
exit
[root@zlk /]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
[root@zlk /]# docker ps -a
CONTAINER ID   IMAGE     COMMAND       CREATED          STATUS                      PORTS     NAMES
990384ccba9f   centos    "/bin/bash"   25 seconds ago   Exited (0) 18 seconds ago             funny_elgamal
[root@zlk /]# docker start 990384ccba9f
990384ccba9f
[root@zlk /]# docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED              STATUS         PORTS     NAMES
990384ccba9f   centos    "/bin/bash"   About a minute ago   Up 7 seconds             funny_elgamal
[root@zlk /]# docker stop 990384ccba9f
990384ccba9f
[root@zlk /]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

2.4 常用其他命令

后台启动容器:

[root@zlk ~]# docker run -d centos

# 问题:docker ps 发现,centos停止了

# 常见的坑,docker 容器使用后台运行,就必须要有一个前台进程,docker发现没有应用,就会自动停止
# nginx,容器启动后,发现自己没有提供服务,就会立刻停止,就是没有程序了

docker logs -tf --tail 容器id (查看日志):

# 自己编写一段shell脚本
[root@zlk /]# docker run -d centos /bin/bash -c "while true;do echo hello;sleep 2;done"

[root@zlk /]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED              STATUS              PORTS     NAMES
e705ce9ef994   centos    "/bin/sh -c 'while t..."   About a minute ago   Up About a minute             priceless_lichterman

# 显示日志
--tf 			显示日志
--tail number 	要显示日志条数
[root@zlk /]# docker logs -tf --tail 10 e705ce9ef994 

docker top 容器id (查看容器中进程信息):

[root@zlk /]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS     NAMES
e705ce9ef994   centos    "/bin/sh -c 'while t..."   8 minutes ago   Up 8 minutes             priceless_lichterman
[root@zlk /]# docker top e705ce9ef994 
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                5624                27182               0                   17:50               ?                   00:00:00            /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 2
root                27182               27163               0                   17:41               ?                   00:00:00            /bin/sh -c while true;do echo hello;sleep 2;done

docker inspect 容器id(查看镜像的元数据)

# 测试
[root@zlk /]# docker ps -a
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS                      PORTS     NAMES
1c92de96ff9f   centos    "/bin/bash -c 'while..."   13 minutes ago   Up 13 minutes                         agitated_robinson

[root@zlk /]# docker inspect 1c92de96ff9f   

进入当前正在运行的容器:

容器都是使用后台方式运行的,需要进入容器,修改一些配置。

docker exec -it 容器id /bin/bash

[root@zlk /]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS     NAMES
e705ce9ef994   centos    "/bin/sh -c 'while t..."   21 minutes ago   Up 21 minutes             priceless_lichterman
# 方式一
[root@zlk /]# docker exec -it e705ce9ef994 /bin/bash
[root@e705ce9ef994 /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

# 方式二
docker attach 容器id
# 测试
[root@zlk /]# docker attach  e705ce9ef994 
正在执行当前代码.......
[root@zlk ~]# docker rm -f $(docker ps -aq)    # 前面循环没停,直接全停了

docker exec   	# 进入容器后开启一个新的终端,可以在里面执行操作
docker attach	# 进入容器正在执行的终端,不会启动新的进程,且执行过程中不能退出

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

docker cp 容器id:容器内路径  主机路径

这里的拷贝采用的是手动操作,在后面我们将进一步学习使用 -v 操作,也就是卷的技术,可以实现自动同步。

[root@zlk ~]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
[root@kzlk ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
centos       latest    5d0da3dc9764   8 months ago   231MB

[root@zlk ~]# docker run -it centos /bin/bash  # ctrl+p+q退出
[root@93823941b78c /]# [root@zlk ~]# docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED          STATUS          PORTS     NAMES
93823941b78c   centos    "/bin/bash"   16 seconds ago   Up 15 seconds             romantic_sinoussi
[root@zlk ~]# cd /home/
[root@zlk home]# docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED              STATUS              PORTS     NAMES
93823941b78c   centos    "/bin/bash"   About a minute ago   Up About a minute             romantic_sinoussi
# 进入容器内部
[root@zlk home]# docker attach 93823941b78c
[root@93823941b78c /]# cd /home/
[root@93823941b78c home]# ls
# 在容器内新建一个文件
[root@93823941b78c home]# touch  test.java
[root@93823941b78c home]# ls
test.java  
[root@93823941b78c home]# exit
exit
[root@zlk home]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
[root@zlk home]# docker ps -a
CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS                     PORTS     NAMES
93823941b78c   centos    "/bin/bash"   3 minutes ago   Exited (0) 7 seconds ago             romantic_sinoussi
# 查看当前主机目录
[root@zlk home]# ls
admin  ceshi  kuangshen.java
# 将文件拷贝到主机上
[root@zlk home]# docker cp 93823941b78c:/home/test.java /home/
[root@zlk home]# ls
admin  ceshi  kuangshen.java  test.java

2.5 小结

docker 的命令非常多,下述是最常用的容器和镜像的命令,之后学习的命令会更多!

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 form the server 	# 从 docker 服务获取容器实时事件
exec 	 	Run a command in an existing container	# 在已存在的容器上运行命令
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 tarball 	# 从 tar 包中的内容创建一个新的文件系统映像【对应 export】
info	 	display system-wide infomation		# 显示系统相关信息
inspect	 	return low-level infomation 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 	 	pull an image or a repository from the docker registry 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 docker hub 		# 在 docker hub 中搜索镜像
start	 	start a stopped container			# 启动容器
stop	 	stop a running container			# 启动容器
tag 	 	tag an image into a repository		# 给源镜像搭标签
top		 	lookup the running processes of a container		# 查看容器中运行的进程信息
unpause	 	unpause a paused container			# 取消暂停容器
version	 	show the docker version infomation		# 查看 docker 版本号
wait 	 	block until a container stops,then print its exit code 		# 截取容器停止时间的退出状态值

2.6 作业练习----Docker 安装 Nginx

# 1、搜索镜像 search 建议去docker上搜索,可以看到详细信息和帮助文档
[root@zlk ~]# docker search nginx
# 2、下载镜像
[root@zlk ~]# docker pull nginx
# 3、运行测试
[root@zlk ~]# docker images     # 查看镜像
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
nginx         latest    de1111b9436b   36 hours ago   142MB

# -d 后台运行
# --name 给容器命名
# -p 宿主机端口:容器内部端口
[root@zlk ~]# docker run -d --name nginx01 -p 3344:80 nginx
50666666ad4e9e6b9666666666c8ec08666666633
[root@zlk ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                                   NAMES
50c35333a98   nginx     "/docker-entrypoint...."   57 seconds ago   Up 57 seconds   0.0.0.0:3344->80/tcp, :::3344->80/tcp   nginx01
[root@zlk ~]# curl localhost:3344

# 浏览器查看 http://IP:3344/

# 进入容器
[root@zlk ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                                   NAMES
506666e98   nginx     "/docker-entrypoint...."   38 minutes ago   Up 38 minutes   0.0.0.0:3344->80/tcp, :::3344->80/tcp   nginx01
[root@zlk ~]# docker exec -it nginx01 /bin/bash
root@506666e98:/# whereis nginx
nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
root@5066666e98:/# cd /etc/nginx/
root@5066666e98:/etc/nginx# ls
conf.d  fastcgi_params  mime.types  modules  nginx.conf  scgi_params  uwsgi_params
root@5066666e98:/etc/nginx# 

# 停止容器
root@503666w98:/etc/nginx# exit
exit
[root@zlk ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                                   NAMES
506666e98   nginx     "/docker-entrypoint...."   43 minutes ago   Up 43 minutes   0.0.0.0:3344->80/tcp, :::3344->80/tcp   nginx01
[root@zlk ~]# docker stop 5066666e98
506666e98
# 浏览器查看 http://IP:3344/

2.7 作业练习----docker安装Tomcat

# 官方的使用
docker run -it --rm tomcat:9.0
# 我们之前的启动都是后台 -d,停止了容器之后,容器还是可以通过docker ps查到 ,官方推荐的docker run -it --rm tomcat:9.0,一般用来测试,用完就删除


# 下载再启动
docker pull tomcat

# 启动运行
docker run -d -p 3355:8080 --name tomcat01 tomcat 

# 测试访问没有问题,会出现404
# IP:3355  访问失败

# 进入容器
 docker exec -it tomcat01 /bin/bash
 ls
# 发现问题:1、Linux命令缺失  2、没有WebApps,阿里云镜像的原因,默认是最小的镜像,所有不必要的都剔除,保证最小可运行的环境
 
[root@zlk ~]#  docker exec -it tomcat01 /bin/bash 
root@c95eb14e8fd4:/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
root@c95eb14e8fd4:/usr/local/tomcat# cd webapps
root@c95eb14e8fd4:/usr/local/tomcat/webapps# ls
root@c95eb14e8fd4:/usr/local/tomcat/webapps# cd ..
root@c95eb14e8fd4:/usr/local/tomcat# cd webapps.dist/
root@c95eb14e8fd4:/usr/local/tomcat/webapps.dist# ls
ROOT  docs  examples  host-manager  manager
root@c95eb14e8fd4:/usr/local/tomcat/webapps.dist# cd ..
root@c95eb14e8fd4:/usr/local/tomcat# cp -r  webapps.dist/* webapps
root@c95eb14e8fd4:/usr/local/tomcat# cd webapps
root@c95eb14e8fd4:/usr/local/tomcat/webapps# ls
ROOT  docs  examples  host-manager  manager

思考:每次部署项目,都要进入容器内,特别麻烦,所以在容器外部提供一个映射路径,webapps

2.8 作业练习----docker部署es+kibana

# es 暴露的端口很多
# es 十分的耗内存
# es 的数据一般需要放置到安全目录! 挂载
# --net somenetwork 网络配置
 
# 启动elasticsearch
[root@zlk home]# docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2
a920894a940b354d3c867079efada13d96cf9138712c76c8dea58fabd9c7e96f
 
# 启动了linux就卡主了,docker stats 查看cpu状态
 
# 测试一下es成功了
[root@zlk home]# curl localhost:9200
{
  "name" : "a920894a940b",
  "cluster_name" : "docker-cluster",
  "cluster_uuid" : "bxE1TJMEThKgwmk7Aa3fHQ",
  "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"
}
 
 
# 增加内存限制,修改配置文件 -e 环境配置修改
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.9 端口暴露概念

2.10 可视化

  • portainer(先用这个):图形化界面管理工具,提供一个后台面板供我们操作。
docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
 
# 测试
[root@zlk home]# curl localhost:8088
<!DOCTYPE html
><html lang="en" ng-app="portainer">
 
# 外网访问 http://ip:8088
 

3 Docker镜像

3.1 镜像是什么

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

也就是说,我们所有的应用都能够直接打包成Docker镜像,然后就可以运行!

3.2 UnionFS(联合文件系统)【Docker核心组件】

联合文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统。对于Docker来说,它是Docker镜像和容器的基础,因为它可以将Docker镜像做成分层次的结构,从而使得镜像的每一层可以被共享,通过分层达到继承的目的,后面我们会学习到基于基础镜像制作出各种具体的应用镜像(DockerFile)

通俗的来讲,就是我们在docker pull下载镜像的时候会分层下载,已经存在的部分进行共享,只下载当前没有的那一部分,这样会极大地节省内存空间。

3.3 Docker镜像加载原理

Docker的镜像实际根据联合文件系统由一层一层的文件系统组成。

Linux 文件系统结构:

Linux 文件系统由 bootfs 和 rootfs 两部分组成。

(1)bootfs(boot file system):主要包含bootloader和kernel(Linux内核),bootloader主要是引导加载kernel,Linux刚启动时会加载bootfs文件系统,而在Docker镜像的最底层也是bootfs这一层,这与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后,整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时后 bootfs 就被 umount (卸载)了。

(2)rootfs(root file system):rootfs在bootfs之上。包含的就是典型Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等。

docker镜像加载原理:

Docker的镜像层都是只读的,只有容器层是可写的,容器层就是最上面的一层。

平时我们安装进虚拟机的CentOS系统都是好几个G,为什么Docker这里安装的才200M?

对于一个精简的OS系统,rootfs可以很小,只需要包含最基本的命令、工具和程序库就可以了,因为底层直接用Host(宿主机)的kernel(也就是宿主机或者服务器的boosfs+内核),自己只需要提供rootfs就可以了。由此可见对于不同的linux发行版,bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以公用bootfs部分。

这样的话也就可以解释之前我们所说的,虚拟机启动是分钟级别的,而容器是秒级的!

3.4 分层镜像

镜像都是从相同的base镜像构建的,宿主机只需要在磁盘上保留一份Base镜像,同时内存中也只需要加载一份Base镜像,这样我们就能够在所有的镜像容器中进行公用。
docker image inspect 镜像名: 可以查看镜像元数据。

所有的Docker镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层之上,创建新的镜像层。
举一个简单的例子,假如基于Ubuntu16.04创建一个新的镜像,这就是新镜像的第一层;如果在该镜像中添加Python包,就会在基础镜像层Ubuntu16.04之上创建第二个镜像层;如果继续添加一个安全补丁,就会创建第三个镜像层.....依次累加。如下图所示(当前有3个镜像层)。

在添加额外镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点非常重要。下图中举了一个简单的2层镜像例子,每个镜像层包含3个文件,而整体的镜像包含了来自两个镜像层的6个文件。

下图中演示了一个稍微复杂的3层镜像,在外部看来整个镜像只有6个文件,这是因为最上层中的文件7是文件5的一个更新版本。(文件7会覆盖文件5)

在这种情况下,上层镜像层中的文件7覆盖了底层镜像层中的文件5。这样就使得文件的更新版本作为一个新镜像层添加到镜像当中,镜像层数+1,整体文件数不变。


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

上述三层镜像,Docker最终会将其堆叠并合并,对外提供统一的视图,如下图所示:

4 Docker原理

Docker镜像都是只读的,在我们启动容器的时候,一个新的可写层被加载到镜像的顶部!

这一层就是我们常说的容器层(run),容器层之下的都是镜像层(远程 pull)!所有的操作都是基于容器层。

5 Commit镜像

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

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

**用途:**如果想要保存当前容器的状态,就可以通过commit来提交,获得一个镜像,就好比我们以前学习VM时候,快照。这样的话可以节省掉很多的步骤,直接拿过来用即可!

实战提交一个镜像:

  1. 启动一个默认的tomcat
  2. 发现这个默认的tomcat 是没有webapps应用,镜像的原因,官方的镜像默认webapps 下面是没有文件的
  3. 自己拷贝进去了基本的文件
  4. 将修改后的容器通过commit提交为一个镜像,我们以后使用修改后的镜像即可,这就是修改后的镜像
#运行一个默认的tomcat镜像
[root@zlk ~]# docker run -it -p 8080:8080  tomcat

[root@zlk ~]# docker ps
CONTAINER ID   IMAGE     COMMAND             CREATED          STATUS          PORTS                                       NAMES
792ca37197e8   tomcat    "catalina.sh run"   34 seconds ago   Up 32 seconds   0.0.0.0:8080->8080/tcp, :::8080->8080/tcp   upbeat_mcnulty

[root@zlk ~]# docker exec -it 792ca37197e8 /bin/bash
#发现这个默认的tomcat 是没有webapps应用,是因为镜像的原因,官方的镜像默认webapps下没有文件,自己拷贝进去基本的文件
root@792ca37197e8:/usr/local/tomcat# cp -r webapps.dist/* webapps

#浏览器访问,测试成功
http://47.105.220.36:8080/

#提交修改后的容器成为一个新的镜像
[root@zlk ~]# docker commit -a="星悦糖" -m="add webapps app" 792ca37197e8 tomcat02:1.0
sha256:d6d429f9d2ba25af8f66bd3e7a7de489cf2219828ea755ce1d0a1a7816c27731

[root@zlk ~]# docker images
REPOSITORY            TAG       IMAGE ID       CREATED          SIZE
tomcat02              1.0       d6d429f9d2ba   28 seconds ago   672MB

到现在为止我们的Docker才算入门!接下来我们进一步学习Docker进阶!

原文链接: https://blog.csdn.net/friggly/article/details/126163263

标签: #docker 18 #软件开发 1171
相关文章

万字:支付“核心系统”详解 2024-11-02 15:33

专栏作者:隐墨星辰 \| 主编:陈天宇宙 这篇文章也尝试化繁为简,探寻支付系统的本质,讲清楚在线支付系统最核心的一些概念和设计理念。 虽然支付行业已经过了风头最劲的时光,但跨境支付仍然在蓬勃发展,每年依然有很多新人进入这个行业,这篇文章尝试为这些刚入行的新人提供一点帮助。 文章只介绍一些支付行业十几

资深支付架构师视角:实战从问题定义到代码落地的完整套路 2024-11-02 15:33

前言 今天从一个实际案例入手,介绍站在架构师的角度,如何识别并定义问题,提炼需求,技术方案选型,再到详细设计,最后利用AI的能力协助写出核心的代码,验证与调优。 解决问题存在一定的模式,也可以称之为框架,总结出自己的思考和解题框架,以后再碰到同类型的问题就可以如庖丁解牛一样容易。 很多年前,我写代码

Spring 实现 3 种异步接口 2024-10-18 09:07

大家好,我是苏三~ 如何处理比较耗时的接口? 这题我熟,直接上异步接口,使用 Callable、WebAsyncTask 和 DeferredResult、CompletableFuture等均可实现。 但这些方法有局限性,处理结果仅返回单个值。在某些场景下,如果需要接口异步处理的同时,还持续不断地

重学SpringBoot3-集成Redis(五)之布隆过滤器 2024-10-08 11:24

更多SpringBoot3内容请关注我的专栏:《SpringBoot3》 期待您的点赞👍收藏⭐评论✍ 重学SpringBoot3-集成Redis(五)之布隆过滤器 1. 什么是布隆过滤器? * 基本概念 适用场景 2. 使用 Redis 实现布隆过滤器 * 项目依赖 Redis 配置

设计模式第16讲——迭代器模式(Iterator) 2024-10-08 11:24

一、什么是迭代器模式 迭代器模式是一种行为型设计模式,它提供了一种统一的方式来访问集合对象中的元素,而不是暴露集合内部的表示方式。简单地说,就是将遍历集合的责任封装到一个单独的对象中,我们可以按照特定的方式访问集合中的元素。 二、角色组成 抽象迭代器(Iterator):定义了遍历聚合对象所需的方法

vue2路由和vue3路由区别及原理 2024-10-08 11:24

一、Vue2 与 Vue3 路由的区别 1. 创建路由实例方式的不同 Vue 2 中,通过 Vue.use() 注册路由插件,并通过 new VueRouter() 来创建路由实例。 import Vue from 'vue';import VueRouter from 'vue-router';i

目录

IT 外包服务商

  • 意见投递
  • zyf6619

软件开发应用

主菜单

  • 首页
  • 软件开发
  • 计算机基础
  • Hello Halo
  • 新手必读
  • 关于本知识库
Copyright © 2024 your company All Rights Reserved. Powered by Halo.