当前位置: 首页 > news >正文

Docker 容器虚拟化技术和自动化部署

Docker 容器虚拟化技术和自动化部署

  • 一、Docker 核心组件
    • 1.1 Docker 引擎
    • 1.2 Docker 镜像
    • 1.3 Docker 容器
    • 1.4 Docker 仓库
  • 二、Docker 环境安装
    • 清华镜像安装
  • 三、Docker 基本操作
    • 3.1 镜像管理
      • 3.1.1 查看本地镜像 docker images
      • 3.1.2 添加镜像标签 docker tag
      • 3.1.3 查看镜像信息 inspect、history
      • 3.1.4 镜像导出 save、导入load
      • 3.1.5 拉取镜像 docker pull
      • 3.1.6 删除本地镜像 docker [image] rmi
      • 3.1.7 悬空镜像、删除悬空镜像
      • 3.1.8 上传镜像 docker push
    • 3.2 容器管理
      • 3.2.1 创建与启动容器 create、start、run
      • 3.2.2 查看所有容器 docker ps
      • 3.2.3 终止运行容器 stop 、kill
      • 3.2.4 进入容器内部 docker exec
      • 3.2.5 查看容器信息 inspect、stats
      • 3.2.6 查看容器日志 docker logs
      • 3.2.7 容器文件传输 docker cp
      • 3.2.8 删除容器 docker rm
    • 3.3 仓库管理
      • 3.3.1 登录仓库 docker login
      • 3.3.2 登出仓库 docker logout
      • 3.3.3 认证文件
    • 3.4 命令图谱
    • 3.5 部署示例
      • 3.5.1 拉取 redis7.4.2 镜像
      • 3.5.2 安装MySQL
      • 3.5.3 安装Tomcat
  • 四、Dicker 核心原理
    • 4.1 容器生命周期
    • 4.2 容器命名空间
      • 4.2.1 进程命名空间(PID namespace)
      • 4.2.2 网络命名空间(network namespace)
      • 4.2.3 IPC命名空间(IPC namespace)
      • 4.2.4 挂载命名空间(Mount namespace)
      • 4.2.5 UTS命名空间(UTS namespace)
      • 4.2.6 用户命名空间(User namespace)
    • 4.3 资源配额限制
      • 4.3.1 CPU
      • 4.3.2 内存
      • 4.3.3 磁盘读写
    • 4.4 联合文件系统
      • 4.4.1 Docker存储
      • 4.4.2 多种文件系统比较
    • 4.5 容器网格管理
      • 4.5.1 Bridge 网络模式
      • 4.5.2 Host 网络模式
      • 4.5.3 Container 网络模式
      • 4.5.4 None 网络模式
      • 4.5.5 Docker 外部访问容器
        • 4.5.5.1 映射所有端口地址
        • 4.5.5.2 映射到指定地址的指定端口
        • 4.5.5.3 映射到指定地址的任意端口
        • 4.5.5.4 查看映射端口配置
      • 4.5.6 Docker 容器互联
      • 4.5.7 Docker 配置DNS
    • 4.6 容器数据管理
      • 4.6.1 数据管理命令
      • 4.6.2 数据卷实战
      • 4.6.3 数据卷容器实战
      • 4.6.4 tmpfs 挂载
      • 4.6.5 数据卷备份还原
    • 4.7 实战案例

一、Docker 核心组件

在这里插入图片描述
链接: docker官网
Docker是一个 开源 的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可抑制的容器中,然后发布到任何流行的Linux机器上,也可以实现 虚拟化

docker和容器技术和虚拟机技术,都是虚拟化技术
docker有着比虚拟机更少的抽象层

1.1 Docker 引擎

Docker 引擎是一个包含以下主要组件的客户端服务器应用程序。

  • 一种服务器,它是一种称为守护进程并且长时间运行的程序。
  • REST API 用于指定程序可以用来与守护进程通信的接口,并指示它做什么。
  • 一个有命令行界面 (CLI) 工具的客户端
    在这里插入图片描述

Docker 客户端是用户与 Docker 交互的主要方式,与 Docker 守护进程(Docker引擎)进行通信。

1.2 Docker 镜像

Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。

1.3 Docker 容器

容器是镜像的一个运行实例。

容器可以被创建、启动、开始、停止、删除、暂停等,而这些容器都是彼此相互隔离的、互不可见的。可以把容器看做是一个简易版的 Linux 系统环境(包括root用户权限、进程空间、用户空间和网络空间等)以及运行在其中的应用程序打包而成的盒子。

1.4 Docker 仓库

Docker 仓库类似于代码仓库,它是 Docker 集中存放镜像文件的场所。(官方存放docker的仓库:hub.docker.com)

二、Docker 环境安装

在这里插入图片描述

  • 配置宿主机网卡转发
# 查看是否有仓库
[root@docker ~]# dnf repolist
Updating Subscription Management repositories.
Unable to read consumer identityThis system is not registered with an entitlement server. You can use "rhc" or "subscription-manager" to register.repo id                                 repo name
AppStream                               AppStream
BaseOS                                  BaseOS
[root@docker ~]# vim /etc/sysctl.d/docker.conf
[root@docker ~]# cat /etc/sysctl.d/docker.conf
net.bridge.bridge-nf-call-ip6tables=1
net.bridge.bridge-nf-call-iptables=1
net.ipv4.ip_forward=1

清华镜像安装

  • 清华镜像安装方法
    1. 先执行dnf remove
    2. 安装必要的一些系统工具
    yum install -y yum-utils
    3. 添加软件源信息
    yum-config-manager --add-repo https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/rhel/docker-ce.repo
    4. 安装Docker
    yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
    5. 开启Docker服务
    systemctl enable --now docker
# 查看是否挂载
[root@docker ~]# mount /dev/sr0 /mnt
mount: /mnt: WARNING: source write-protected, mounted read-only.# 1.先执行dnf remove 
[root@docker ~]# dnf remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine \
podman \
runc	#以上内容复制粘贴回车,保证没有dockerUpdating Subscription Management repositories.
Unable to read consumer identityThis system is not registered with an entitlement server. You can use "rhc" or "subscription-manager" to register.No match for argument: docker
No match for argument: docker-client
No match for argument: docker-client-latest
No match for argument: docker-common
No match for argument: docker-latest
No match for argument: docker-latest-logrotate
No match for argument: docker-logrotate
No match for argument: docker-engine
No match for argument: podman
No match for argument: runc
No packages marked for removal.
Dependencies resolved.
Nothing to do.
Complete!# 2.安装必要的一些系统工具
[root@docker ~]# yum install -y yum-utils
Updating Subscription Management repositories.
Unable to read consumer identity# 3.添加软件源信息
[root@docker ~]# yum-config-manager --add-repo https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/rhel/docker-ce.repo
Updating Subscription Management repositories.
Unable to read consumer identityThis system is not registered with an entitlement server. You can use "rhc" or "subscription-manager" to register.Adding repo from: https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/rhel/docker-ce.repo  #成功[root@docker ~]# ls /etc/yum.repos.d/
dnf.repo  docker-ce.repo  redhat.repo# 4.安装 Docker
[root@docker ~]# yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Updating Subscription Management repositories.
Unable to read consumer identity#安装成功:
[root@docker ~]# docker -v
Docker version 28.0.4, build b8034c0# 5.开启Docker服务
[root@docker ~]# systemctl enable --now docker
Created symlink /etc/systemd/system/multi-user.target.wants/docker.service → /u               sr/lib/systemd/system/docker.service.
[root@docker ~]# docker images
REPOSITORY   TAG       IMAGE ID   CREATED   SIZE
  • 注意:
# 有就改写,没有就创建
[root@docker ~]# vim /etc/docker/daemon.json
[root@docker ~]# cat /etc/docker/daemon.json
{"registry-mirrors": ["https://docker.1ms.run","https://func.ink","https://proxy.1panel.live","https://docker-0.unsee.tech","https://docker.zhai.cm","https://a.ussh.net","https://docker.1ms.run","https://docker.melikeme.cn","https://lispy.org","https://docker.hlmirror.com","https://docker.1panel.live","https://docker.xiaogenban1993.com","https://docker.1panel.top","https://docker.kejilion.pro","https://dockerpull.cn","https://docker.xuanyuan.me","https://docker.anye.in","https://hub.fast360.xyz"]
}
[root@docker ~]# systemctl daemon-reload
[root@docker ~]# systemctl restart docker
[root@docker ~]# docker info | grep "Registry Mirrors" -A 5Registry Mirrors:https://docker.1ms.run/https://func.ink/https://proxy.1panel.live/https://docker-0.unsee.tech/https://docker.zhai.cm/

三、Docker 基本操作

[root@docker ~]# docker --help
Usage:  docker [OPTIONS] COMMANDA self-sufficient runtime for containers#通用命令
Common Commands:run         Create and run a new container from an imageexec        Execute a command in a running containerps          List containersbuild       Build an image from a Dockerfilepull        Download an image from a registrypush        Upload an image to a registryimages      List imageslogin       Authenticate to a registrylogout      Log out from a registrysearch      Search Docker Hub for imagesversion     Show the Docker version informationinfo        Display system-wide information#管理命令
Management Commands:builder     Manage buildsbuildx*     Docker Buildxcompose*    Docker Composecontainer   Manage containerscontext     Manage contextsimage       Manage imagesmanifest    Manage Docker image manifests and manifest listsnetwork     Manage networksplugin      Manage pluginssystem      Manage Dockertrust       Manage trust on Docker imagesvolume      Manage volumes	#数据卷#编排容器
Swarm Commands:swarm       Manage SwarmCommands:attach      Attach local standard input, output, and error streams to a running containercommit      Create a new image from a container's changescp          Copy files/folders between a container and the local filesystemcreate      Create a new containerdiff        Inspect changes to files or directories on a container's filesystem	#判断容器不同点events      Get real time events from the serverexport      Export a container's filesystem as a tar archivehistory     Show the history of an imageimport      Import the contents from a tarball to create a filesystem imageinspect     Return low-level information on Docker objectskill        Kill one or more running containersload        Load an image from a tar archive or STDINlogs        Fetch the logs of a containerpause       Pause all processes within one or more containers	#暂停port        List port mappings or a specific mapping for the containerrename      Rename a containerrestart     Restart one or more containersrm          Remove one or more containersrmi         Remove one or more imagessave        Save one or more images to a tar archive (streamed to STDOUT by default)	#导出start       Start one or more stopped containersstats       Display a live stream of container(s) resource usage statisticsstop        Stop one or more running containerstag         Create a tag TARGET_IMAGE that refers to SOURCE_IMAGEtop         Display the running processes of a containerunpause     Unpause all processes within one or more containersupdate      Update configuration of one or more containerswait        Block until one or more containers stop, then print their exit codesGlobal Options:--config string      Location of client config files (default "/root/.docker")-c, --context string     Name of the context to use to connect to the daemon(overrides DOCKER_HOST env var and default context set with"docker context use")-D, --debug              Enable debug mode-H, --host list          Daemon socket to connect to-l, --log-level string   Set the logging level ("debug", "info", "warn", "error","fatal") (default "info")--tls                Use TLS; implied by --tlsverify--tlscacert string   Trust certs signed only by this CA (default"/root/.docker/ca.pem")--tlscert string     Path to TLS certificate file (default "/root/.docker/cert.pem")--tlskey string      Path to TLS key file (default "/root/.docker/key.pem")--tlsverify          Use TLS and verify the remote-v, --version            Print version information and quitRun 'docker COMMAND --help' for more information on a command.For more help on how to use Docker, head to https://docs.docker.com/go/guides/

docker pull 镜像名:标签
docker images == docker image ls 查看本地镜像
docker ps 查看本地运行中的容器
docker ps -a 查看本地所有容器(-a:all)如果一个字母,就一个“ - ”,完整的单词,就两个“ - ”
docker version 查看安装版本
decker info 查看docker引擎的详细信息
docker rm 容器名称|容器ID
docker run 启动一个容器,如果启动的容器所用到的镜像在本地镜像列表中不存在,则会先拉取该镜像后再运行容器
docker history 镜像名 查看本地指定镜像详细信息
docker inspect 查看镜像的详细信息
给本地镜像打标签:
docker tag [源镜像名:TAG] [目标镜像名:TAG]

3.1 镜像管理

  1. 拉取 镜像:docker pull 镜像名称:TAG

  2. 查看本地镜像:docker images 、docker image ls、docker image list

  3. 导出 镜像到宿主机:docker save 镜像名:标签 -o 文件名称

  4. 从宿主机 导入 镜像到docker:docker load -i 文件名称

  5. 删除镜像:docker rmi [-f] 镜像名称:标签 | 镜像的ID

  6. 查看悬空镜像 docker images -f “dangling=true”

  7. 删除悬空镜像 docker image prune

  8. 查看镜像历史 docker history 镜像名称:标签

  9. 查看镜像信息 docker inspect 镜像名称:标签

3.1.1 查看本地镜像 docker images

docker images
或者
docker image ls
或者
docker image list

[root@docker ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
nginx        1.27.4    4cad75abc83d   2 months ago   192MB
my-nginx     1.27.4    4cad75abc83d   2 months ago   192MB
mysql        8.4.4     4a8a163431d3   2 months ago   769MB
busybox      latest    ff7a7936e930   6 months ago   4.28MB
[root@docker ~]# docker image ls
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
my-nginx     1.27.4    4cad75abc83d   2 months ago   192MB
nginx        1.27.4    4cad75abc83d   2 months ago   192MB
mysql        8.4.4     4a8a163431d3   2 months ago   769MB
busybox      latest    ff7a7936e930   6 months ago   4.28MB
[root@docker ~]# docker image list
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
my-nginx     1.27.4    4cad75abc83d   2 months ago   192MB
nginx        1.27.4    4cad75abc83d   2 months ago   192MB
mysql        8.4.4     4a8a163431d3   2 months ago   769MB
busybox      latest    ff7a7936e930   6 months ago   4.28MB

3.1.2 添加镜像标签 docker tag

docker tag [原镜像名:TAG] [目标镜像名:TAG]

[root@docker ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
nginx        1.27.4    4cad75abc83d   2 months ago   192MB
mysql        8.4.4     4a8a163431d3   2 months ago   769MB
busybox      latest    ff7a7936e930   6 months ago   4.28MB
[root@docker ~]# docker tag nginx:1.27.4 my-nginx:1.27.4
[root@docker ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
my-nginx     1.27.4    4cad75abc83d   2 months ago   192MB
nginx        1.27.4    4cad75abc83d   2 months ago   192MB
mysql        8.4.4     4a8a163431d3   2 months ago   769MB
busybox      latest    ff7a7936e930   6 months ago   4.28MB

3.1.3 查看镜像信息 inspect、history

docker inspect NAME[:TAG]
docker history NAME[:TAG]

[root@docker ~]# docker inspect nginx:1.27.4
[{"Id": "sha256:4cad75abc83d5ca6ee22053d85850676eaef657ee9d723d7bef61179e1e1e485","RepoTags": ["my-nginx:1.27.4","nginx:1.27.4"],"RepoDigests": ["nginx@sha256:09369da6b10306312cd908661320086bf87fbae1b6b0c49a1f50ba531fef2eab"],"Parent": "",	#父容器"Comment": "buildkit.dockerfile.v0","Created": "2025-02-05T21:27:16Z","DockerVersion": "","Author": "","Config": {"Hostname": "","Domainname": "","User": "","AttachStdin": false,"AttachStdout": false,"AttachStderr": false,"ExposedPorts": {"80/tcp": {}	#},"Tty": false,"OpenStdin": false,"StdinOnce": false,"Env": ["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin","NGINX_VERSION=1.27.4","NJS_VERSION=0.8.9","NJS_RELEASE=1~bookworm","PKG_RELEASE=1~bookworm","DYNPKG_RELEASE=1~bookworm"],"Cmd": ["nginx","-g","daemon off;"],"Image": "","Volumes": null,"WorkingDir": "","Entrypoint": ["/docker-entrypoint.sh"],"OnBuild": null,"Labels": {"maintainer": "NGINX Docker Maintainers <docker-maint@nginx.com>"},"StopSignal": "SIGQUIT"},"Architecture": "amd64","Os": "linux","Size": 192056179,"GraphDriver": {"Data": {"LowerDir": "/var/lib/docker/overlay2/83c1270b83f96ce5d159b9060ab1f5e6ec800bdd8613c6781bda57580a3edf36/diff:/var/lib/docker/overlay2/cd9fb4c7ba80d4d6ab8e34f6f1440200da2ec13568b20db3ae14f96157c5cf17/diff:/var/lib/docker/overlay2/85d9c1b5be375f39540346bcaa9abd602ba79f47937ec684cdfc1a90a0d2e88d/diff:/var/lib/docker/overlay2/17c15561b5965d77856f3071cc474f7ef79baa7c8891c596692d92aefcbc4472/diff:/var/lib/docker/overlay2/c551fcb932de19264548055b933571afcdf7c7762e2eb47951daf0b5f0c33efc/diff:/var/lib/docker/overlay2/a0967db004b77792f37d5b993144397a8ba1aea4dbdd15ae39023629cfbb4ff5/diff","MergedDir": "/var/lib/docker/overlay2/a3d8b43dd3e4669734f8c5abadd9587b63a23763d4eb2d06e28aafabc76cb2cb/merged","UpperDir": "/var/lib/docker/overlay2/a3d8b43dd3e4669734f8c5abadd9587b63a23763d4eb2d06e28aafabc76cb2cb/diff","WorkDir": "/var/lib/docker/overlay2/a3d8b43dd3e4669734f8c5abadd9587b63a23763d4eb2d06e28aafabc76cb2cb/work"},"Name": "overlay2"},"RootFS": {"Type": "layers","Layers": ["sha256:ea680fbff095473bb8a6c867938d6d851e11ef0c177fce983ccc83440172bd72","sha256:c1a9699c65592e502a6b68876f5037b91972c4f72dac2e4e9b84f80f4b0790c2","sha256:d8d396eadc9a4f516284b8be48b1283f025d392c19e84c1c00e1187fe70bba53","sha256:27f473333e2f615c75d1350e314ad8641d9d13ad9f2dbb82999f2012c86a0c53","sha256:ae2a14e88adb05e51056b3ceaba6af7dccee9a987af4f2bae6243b51ba66a018","sha256:fd2315f0cf242aa3776d71f69fbe78d4088999ef9fc2df1de5cb513606be1215","sha256:eda01226259d5df53a10c6b6d7d760bfc37317a8037b98f17f23835fa26fc087"]},"Metadata": {"LastTagTime": "2025-04-13T16:23:58.435252063+08:00"}}
]

返回的是一个 JSON 格式的消息,如果我们只要其中一项内容时, 可以使用参数 -f 来指
定。

3.1.4 镜像导出 save、导入load

  • 镜像导出:将本地仓库中的镜像文件导出到宿主机中

docker image save 镜像名称[:TAG] -o 目标文件[:TAG][.tar.gz]
或者
docker image save 镜像名称[:TAG] > 目标文件[:TAG][.tar.gz]

注意:-o 用于指定导出镜像的位置,可同时导出多个镜像为一个文件,指定 .tar.gz 可以导出并压缩。

# 例如,将nginx:1.27.4镜像导出到宿主机
[root@docker ~]# ls
anaconda-ks.cfg
[root@docker ~]# docker image save nginx:1.27.4 -o nginx.1.27.4.tag.gz
[root@docker ~]# ls
anaconda-ks.cfg  nginx.1.27.4.tag.gz
  • 镜像导入

docker [image] load -i 宿主机文件路径(-i:input)

# 例如,从宿主机中的/root/nginx1.27.4.tar.gz导入到docker中
docker rmi 镜像名:TAG/镜像ID   #删除镜像
[root@docker ~]# docker rmi nginx:1.27.4
Untagged: nginx:1.27.4
Untagged: nginx@sha256:09369da6b10306312cd908661320086bf87fbae1b6b0c49a1f50ba531fef2eab
[root@docker ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
my-nginx     1.27.4    4cad75abc83d   2 months ago   192MB
mysql        8.4.4     4a8a163431d3   2 months ago   769MB
busybox      latest    ff7a7936e930   6 months ago   4.28MB[root@docker ~]# docker load -i /root/nginx.1.27.4.tag.gz
Loaded image: nginx:1.27.4
[root@docker ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
my-nginx     1.27.4    4cad75abc83d   2 months ago   192MB
nginx        1.27.4    4cad75abc83d   2 months ago   192MB
mysql        8.4.4     4a8a163431d3   2 months ago   769MB
busybox      latest    ff7a7936e930   6 months ago   4.28MB

3.1.5 拉取镜像 docker pull

docker pull NAME[:TAG]

不指定则为docker官方地址

[root@docker ~]# docker pull busybox
Using default tag: latest
latest: Pulling from library/busybox
97e70d161e81: Pull complete
Digest: sha256:37f7b378a29ceb4c551b1b5582e27747b855bbfaa73fa11914fe0df028dc581f
Status: Downloaded newer image for busybox:latest
docker.io/library/busybox:latest# 查看镜像列表
[root@docker ~]# docker images
仓库名称     标签
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
busybox      latest    ff7a7936e930   6 months ago   4.28MB
[root@docker ~]# docker pull nginx:1.27.4
1.27.4: Pulling from library/nginx
8a628cdd7ccc: Already exists
75b642592991: Already exists
553c8756fd66: Already exists
10fe6d2248e3: Pull complete
3b6e18ae4ce6: Pull complete
3dce86e3b082: Pull complete
e81a6b82cf64: Pull complete
Digest: sha256:09369da6b10306312cd908661320086bf87fbae1b6b0c49a1f50ba531fef2eab
Status: Downloaded newer image for nginx:1.27.4
docker.io/library/nginx:1.27.4
[root@docker ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
nginx        1.27.4    4cad75abc83d   2 months ago   192MB
busybox      latest    ff7a7936e930   6 months ago   4.28MB[root@docker ~]# docker run --name nginx -d -p 80:80 nginx:1.27.4
6c8af7f90280fc04819e1661b7d98db8745d4dccaed97bf6aa6122a32f7c6e69
  • msyql
[root@docker ~]# docker pull mysql:8.4.4
8.4.4: Pulling from library/mysql
cea172a6e83b: Pull complete
9f0eb82d78dc: Pull complete
30667541f13f: Pull complete
f5fefeb7f3b5: Pull complete
2e7405f0a17c: Pull complete
b7cefcf2c641: Pull complete
38945ff9f35a: Pull complete
3bcd4b133d74: Pull complete
f4511c9955c0: Pull complete
014654182aa2: Pull complete
Digest: sha256:23818b7d7de427096ab1427b2e3d9d5e14a5b933f9a4431a482d6414bc879091
Status: Downloaded newer image for mysql:8.4.4
docker.io/library/mysql:8.4.4
[root@docker ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
nginx        1.27.4    4cad75abc83d   2 months ago   192MB
mysql        8.4.4     4a8a163431d3   2 months ago   769MB
busybox      latest    ff7a7936e930   6 months ago   4.28MB

3.1.6 删除本地镜像 docker [image] rmi

docker [image] rmi NAME[:TAG]
i:image
rm:删除

当同一个镜像拥有多个标签的时候,docker rmi命令只是删除该镜像多个标签中的指定标签而已,并不影响镜像文件。

当镜像只剩下一个标签的时候,使用docker rmi命令会彻底删除镜像

  • 使用镜像ID删除镜像

docker rmi IMAGE ID

3.1.7 悬空镜像、删除悬空镜像

在 Docker 中,悬虚镜像( Dangling Images )是指那些没有 标签 且没有被任何容器使用的镜像。这些镜像通常是由于构建过程中生成的中间层镜像或未正确清理的镜像残留。删除悬虚镜像可以释放磁盘空间并保持 Docker 环境的整洁。

  • 列出悬空镜像
#无悬空镜像
[root@docker ~]# docker images -f "dangling=true"
REPOSITORY   TAG       IMAGE ID   CREATED   SIZE
  • 删除悬空镜像
    使用 docker image prune 命令来删除删除悬虚镜像
[root@docker ~]# docker image prune -f
Total reclaimed space: 0B

3.1.8 上传镜像 docker push

docker push NAME[:TAG]


3.2 容器管理

  1. 创建 容器:docker create --name 容器名称 -d 镜像名称:标签

  2. 启动 容器:docker start 容器名称 | 容器ID

  3. 查看容器:docker ps [-a]

  4. 停止容器:docker stop 容器名称|容器ID

  5. 暂停容器:docker pause 容器名称|容器ID

  6. 创建并启动容器:docker run --name 容器名称 -d 镜像名称:标签
    (-d:后台运行)

  7. 进入容器:docker exec -it 容器名称 命令、docker attach 容器名称

  8. 文件复制到容器中:docker cp 本地文件路径 容器路径

  9. 删除容器:docker rm [-f]

  10. 查看容器详细信息:docker inspect 容器名称|容器ID

  11. 查看容器操作日志 docker logs 容器名称|容器ID

3.2.1 创建与启动容器 create、start、run

创建容器:
docker create NAME[:TAG]

  • 可以加选项参数
    • -i:交互模式
    • -t:伪终端
    • -d:后台运行
    • -rm:容器退出后是否自动删除
[root@docker ~]# docker create -it nginx:1.27.4
7317e0daf6c6015516127640abeca9725f2c7e7e411b2e95cfef0f4306f918d1
[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
7317e0daf6c6   nginx:1.27.4   "/docker-entrypoint.…"   37 seconds ago   Created             modest_poincare
[root@docker ~]# docker start 7317
7317
[root@docker ~]# docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED              STATUS         PORTS     NAMES
7317e0daf6c6   nginx:1.27.4   "/docker-entrypoint.…"   About a minute ago   Up 6 seconds   80/tcp    modest_poincare
[root@docker ~]# curl 192.168.98.149
curl: (7) Failed to connect to 192.168.98.149 port 80: Connection refused
[root@docker ~]# docker stop 7317
7317
[root@docker ~]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

启动容器:
docker start [OPTIONS] CONTAINER [CONTAINER…]

新建并启动容器
docker run [OPTIONS] IMAGE [COMMAND] [ARG…]

  • 常用选项如下:
    -t:打开一个终端
    -i:交互式运行
    -d:后台运行
    -p:端口映射,格式为: <hostport>:<container port>
    –name:指定容器名称
    –rm:容器一旦停止就会自动删除容器
    –network:指定容器使用的网络

3.2.2 查看所有容器 docker ps

docker ps [OPTION]

#查看运行的容器
[root@localhost~]# docker ps
#查看所有容器
[root@localhost~]# docker ps -a

3.2.3 终止运行容器 stop 、kill

docker stop 容器ID -t 时间 (默认10秒)
docker kill 容器ID

处于终止状态的容器,可以通过 docker start 命令来重新启动docker restart 命令会将一个运行态的容器先终止,然后再重新启动。如果要停止所有容器,可以先查看容器编号,然后批量停止。

3.2.4 进入容器内部 docker exec

docker exec -it [容器ID] /bin/bash

execution:执行

[root@docker ~]# docker exec -it nginx /bin/bash
root@c9bc55b21a16:/# ls
bin   dev                  docker-entrypoint.sh  home  lib64  mnt  proc  run   srv  tmp  var
boot  docker-entrypoint.d  etc                   lib   media  opt  root  sbin  sys  usr
root@c9bc55b21a16:/# cd /
root@c9bc55b21a16:/# ls
bin   dev                  docker-entrypoint.sh  home  lib64  mnt  proc  run   srv  tmp  var
boot  docker-entrypoint.d  etc                   lib   media  opt  root  sbin  sys  usr
root@c9bc55b21a16:/# cd usr/
root@c9bc55b21a16:/usr# ls
bin  games  include  lib  lib64  libexec  local  sbin  share  src
root@c9bc55b21a16:/usr# cd share/
root@c9bc55b21a16:/usr/share# ls
X11              debconf      fonts     libgcrypt20  nginx        terminfo
base-files       debianutils  gcc       lintian      pam          util-linux
base-passwd      dict         gdb       locale       pam-configs  xml
bash-completion  doc          info      man          perl5        zoneinfo
bug              doc-base     java      maven-repo   pixmaps      zsh
ca-certificates  dpkg         keyrings  menu         polkit-1
common-licenses  fontconfig   libc-bin  misc         tabset
root@c9bc55b21a16:/usr/share# cd nginx/
root@c9bc55b21a16:/usr/share/nginx# ls
html
root@c9bc55b21a16:/usr/share/nginx# cd html/
root@c9bc55b21a16:/usr/share/nginx/html# ls
50x.html  index.html
root@c9bc55b21a16:/usr/share/nginx/html# vim index2.html
bash: vim: command not found
root@c9bc55b21a16:/usr/share/nginx/html# vi index2.html
bash: vi: command not found
root@c9bc55b21a16:/usr/share/nginx/html# dnf install vim -y
bash: dnf: command not found
root@c9bc55b21a16:/usr/share/nginx/html# yum install vim -y
bash: yum: command not found
root@c9bc55b21a16:/usr/share/nginx/html# echo "index3"
index3
root@c9bc55b21a16:/usr/share/nginx/html# echo "index2" > index2.html
root@c9bc55b21a16:/usr/share/nginx/html# ls
50x.html  index.html  index2.html
root@c9bc55b21a16:/usr/share/nginx/html# exit
exit

3.2.5 查看容器信息 inspect、stats

docker inspect [容器ID]
docker stats [容器ID]

docker inspect [容器ID]
docker stats [容器ID]
docker logs 容器名[root@docker ~]# docker inspect nginx
[root@docker ~]# docker stats nginx

3.2.6 查看容器日志 docker logs

docker logs 容器名

[root@docker ~]# docker logs nginx

3.2.7 容器文件传输 docker cp

docker cp [容器名:文件路径] [宿主机路径]

# 将容器中的test.txt文件复制到宿主机/opt目录下
[root@localhost ~]# docker cp nginx:/test.txt /opt
Successfully copied 1.54kB to /opt
# 把本机文件复制到容器中
[root@localhost ~]# docker cp /etc/fstab nginx:/fstab
[root@docker ~]# echo index3.html > index3.html
[root@docker ~]# ls
anaconda-ks.cfg  index3.html  nginx.1.27.4.tag.gz[root@docker ~]# docker cp ./index3.html nginx:/usr/share/nginx/html/
Successfully copied 2.05kB to nginx:/usr/share/nginx/html/
[root@docker ~]# curl localhost/index3.html
index3.html[root@docker ~]# docker cp nginx:/usr/share/nginx/html/index2.html .
Successfully copied 2.05kB to /root/.
[root@docker ~]# ls
anaconda-ks.cfg  index2.html  index3.html  nginx.1.27.4.tag.gz

3.2.8 删除容器 docker rm

docker rm [容器ID]

# 删除指定容器
[root@localhost~]# docker rm 243c32535da7
# 删除所有容器
[root@localhost~]# docker rm -f $(docker ps -qa)docker rm 命令只能删除处于终止或退出状态的容器,并不能删除还处于运行状态的容器。要直接删除一个运行中的容器,可以添加 -f 参数。Docker 会先 发送 SIGKILL 信给容器终止其中的应用,之后强行删除。

3.3 仓库管理

Docker Hub 是最大的公共镜像仓库(https://hub.docker.com/)。在公共仓库中注册一个账号,每 ID 可以免费拥有 1 个私有镜像。
在这里插入图片描述

3.3.1 登录仓库 docker login

docker login -u username -p password

默认登陆的是docker hub

[root@localhost ~]# docker login -u haha -p 123465
WARNING! Using --password via the CLI is insecure. Use --passwordstdin.
WARNING! Your password will be stored unencrypted in
/root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credential
s-store
Login Succeeded

登录成功的用户可以上传个人制造的镜像。

3.3.2 登出仓库 docker logout

docker logout

可以同时登陆多个docker仓库,因此此命令一般不执行。

[root@localhost ~]# docker logout
Removing login credentials for https://index.docker.io/v1/

3.3.3 认证文件

Mac/Win 机器上的是隐藏密码的,但是在 Linux 下是显示密码的,只不过进行了 base64 编码,只要拷贝此文件到其他机器指定目录下(/root/.docker/config.json)即可免登录。

{"auths": {"https://index.docker.io/v1/": {"auth": "Z2F2aW5saTgwczpsanAxMjM0NjU="}},"HttpHeaders": {"User-Agent": "Docker-Client/19.03.12 (linux)"}
}

3.4 命令图谱

在这里插入图片描述

3.5 部署示例

[root@Docker-kd ~]# docker pull mysql:8.4.4
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
[root@Docker-kd ~]# systemctl status docker
○ docker.service - Docker Application Container EngineLoaded: loaded (/usr/lib/systemd/system/docker.service; disabled; preset: di>Active: inactive (dead)
TriggeredBy: ○ docker.socketDocs: https://docs.docker.com
[root@Docker-kd ~]# systemctl start docker
[root@Docker-kd ~]# docker pull mysql:8.4.4
Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
[root@docker ~]# vim /etc/docker/daemon.json
[root@docker ~]# cat /etc/docker/daemon.json
{"registry-mirrors": ["https://docker.1ms.run","https://func.ink","https://proxy.1panel.live","https://docker-0.unsee.tech","https://docker.zhai.cm","https://a.ussh.net","https://docker.1ms.run","https://docker.melikeme.cn","https://lispy.org","https://docker.hlmirror.com","https://docker.1panel.live","https://docker.xiaogenban1993.com","https://docker.1panel.top","https://docker.kejilion.pro","https://dockerpull.cn","https://docker.xuanyuan.me","https://docker.anye.in","https://hub.fast360.xyz"]
}
[root@docker ~]# systemctl daemon-reload
[root@docker ~]# systemctl restart docker

3.5.1 拉取 redis7.4.2 镜像

1)去 DockerHub 搜索 Redis 镜像
2)查看 Redis 镜像的名称和版本
3)利用 docker pull 命令拉取镜像
4)利用 docker save命令将 redis:latest 打包为一个 redis.tar.gz 包
5)利用 docker rmi 删除本地的 redis:latest
6)利用 docker load 重新加载 redis.tar.gz文件[root@docker ~]# docker pull redis:7.4.2
7.4.2: Pulling from library/redis
8a628cdd7ccc: Already exists
3ff860482ac5: Pull complete
811af041d785: Pull complete
a7e27cf18de4: Pull complete
8ae1ad8ce35e: Pull complete
759939a29cb5: Pull complete
4f4fb700ef54: Pull complete
cbb99c664e48: Pull complete
Digest: sha256:fbdbaea47b9ae4ecc2082ecdb4e1cea81e32176ffb1dcf643d422ad07427e5d9
Status: Downloaded newer image for redis:7.4.2
docker.io/library/redis:7.4.2
[root@docker ~]# docker save redis:7.4.2 -o redis:7.4.2.tar.gz
[root@docker ~]# ls
anaconda-ks.cfg  index2.html  index3.html  nginx.1.27.4.tag.gz  redis:7.4.2.tar.gz
[root@docker ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
my-nginx     1.27.4    4cad75abc83d   2 months ago   192MB
nginx        1.27.4    4cad75abc83d   2 months ago   192MB
mysql        8.4.4     4a8a163431d3   2 months ago   769MB
redis        7.4.2     65750d044ac8   3 months ago   117MB
busybox      latest    ff7a7936e930   6 months ago   4.28MB
[root@docker ~]# docker rmi 6575
Untagged: redis:7.4.2
Untagged: redis@sha256:fbdbaea47b9ae4ecc2082ecdb4e1cea81e32176ffb1dcf643d422ad07427e5d9
Deleted: sha256:65750d044ac86b73a473c01a854d5f7f2b55a77b43f007d0e10a5db5dd1d926f
Deleted: sha256:49cd550fc30bccf84f1f236a79253f001a3a9f3a1b02f0cc740f1398d76b8533
Deleted: sha256:e0690ddc013eedc562d913a51bc89341d373a52ad53470ecf6ecb8f0b1b5ffb5
Deleted: sha256:cb189b5d5dd0ce60f0025de7c92b8896a5ee1f6ac6f90d373ef478c74049ecef
Deleted: sha256:9085c007f78efd29de83469622ccd6f977bc9acafdf6998f5f7b9dffd95f9bba
Deleted: sha256:37036292b6f5df827b4c76531dad2cf87031eabeffa12bd353c91d66d18cf917
Deleted: sha256:52aab82e9b8bbc9277f4c34a7c4fdf4bcc50a612cd0483dffddbad5b5cab5b4d
Deleted: sha256:7de9d31c8a5b5a2f3ea465f8944b69877612aa0f52c32bc08e7be014ce58d441
[root@docker ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
my-nginx     1.27.4    4cad75abc83d   2 months ago   192MB
nginx        1.27.4    4cad75abc83d   2 months ago   192MB
mysql        8.4.4     4a8a163431d3   2 months ago   769MB
busybox      latest    ff7a7936e930   6 months ago   4.28MB
[root@docker ~]# docker load -i ./redis\:7.4.2.tar.gz
1910dfbcb631: Loading layer  10.75kB/10.75kB
aaf201c773fb: Loading layer  10.75kB/10.75kB
98ad392b916a: Loading layer  4.144MB/4.144MB
6108f9e7c02c: Loading layer  38.12MB/38.12MB
319c2310f2be: Loading layer  1.536kB/1.536kB
5f70bf18a086: Loading layer  1.024kB/1.024kB
570897943907: Loading layer  4.096kB/4.096kB
Loaded image: redis:7.4.2
[root@docker ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
my-nginx     1.27.4    4cad75abc83d   2 months ago   192MB
nginx        1.27.4    4cad75abc83d   2 months ago   192MB
mysql        8.4.4     4a8a163431d3   2 months ago   769MB
redis        7.4.2     65750d044ac8   3 months ago   117MB
busybox      latest    ff7a7936e930   6 months ago   4.28MB
[root@docker ~]# docker run -d --name redis -p 6379:6379 redis:7.4.2
3a992261f5b2d9599385929162488bd39a621c8bd67a561a0a8334fa5c26009f
[root@docker ~]# docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS             PORTS                                         NAMES
3a992261f5b2   redis:7.4.2    "docker-entrypoint.s…"   29 seconds ago   Up 29 seconds      0.0.0.0:6379->6379/tcp, [::]:6379->6379/tcp   redis
c9bc55b21a16   nginx:1.27.4   "/docker-entrypoint.…"   5 days ago       Up About an hour   0.0.0.0:80->80/tcp, [::]:80->80/tcp           nginx
[root@docker ~]# docker exec -it redis /bin/bash
root@3a992261f5b2:/data# redis-cli
127.0.0.1:6379> keys *	#拿到所有键
(empty array)
127.0.0.1:6379> set name lisi
OK
127.0.0.1:6379> get name
"lisi"
127.0.0.1:6379> exit
root@3a992261f5b2:/data# exit
exit

3.5.2 安装MySQL

  1. 拉取或下载镜像
    docker pull mysql:8.4.4
  2. 启动并运行MySQL容器
  3. 远程连接数据库
  • 拉取镜像
[root@Docker-kd ~]# docker pull mysql:8.4.4
8.4.4: Pulling from library/mysql
cea172a6e83b: Pull complete
9f0eb82d78dc: Pull complete
30667541f13f: Pull complete
f5fefeb7f3b5: Pull complete
2e7405f0a17c: Pull complete
b7cefcf2c641: Pull complete
38945ff9f35a: Pull complete
3bcd4b133d74: Pull complete
f4511c9955c0: Pull complete
014654182aa2: Pull complete
Digest: sha256:23818b7d7de427096ab1427b2e3d9d5e14a5b933f9a4431a482d6414bc879091
Status: Downloaded newer image for mysql:8.4.4
docker.io/library/mysql:8.4.4
  • 启动MySQL容器
[root@Docker-kd ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
mysql        8.4.4     4a8a163431d3   3 months ago   769MB
[root@Docker-kd ~]# docker run -d \
--restart=always \	    #数据库设为开机启动
--name mysql \	    	#指定容器的名称
-e MYSQL_ROOT_PASSWORD=123456 \	#环境变量
-p 3306:3306 \
--privileged=true \		#container内的root拥有真正的root权限
mysql:8.4.4 \		#指定镜像名称,并后台运行
--character-set-server=utf8mb4 \	#指定数据库的编码格式
--collation-server=utf8mb4_unicode_ci	#指定数据库校对编码格式
2a92d462cc4f4bbf8c2e6ae68c9b2cd7c44b19c970bb2a073a9a8c97a976a944

在这里插入图片描述

  • 远程连接数据库
# 执行如下命令进入到容器内部:
[root@Docker-kd ~]# docker exec -it mysql bash
bash-5.1# 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 8
Server version: 8.4.4 MySQL Community Server - GPLCopyright (c) 2000, 2025, 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> flush privileges;
Query OK, 0 rows affected (0.00 sec)mysql> exit
Bye
bash-5.1# exit
exit

在这里插入图片描述

3.5.3 安装Tomcat

  1. 拉取或下载镜像
  2. 启动并运行Tomcat容器
  3. 远程访问
[root@Docker-kd ~]# docker pull tomcat:11.0.5
11.0.5: Pulling from library/tomcat
2726e237d1a3: Pull complete
3a83fda68147: Pull complete
e18be1fe9d89: Pull complete
1080edf8b8b2: Pull complete
e17ac0079371: Pull complete
10681c58d83f: Pull complete
4f4fb700ef54: Pull complete
425b1a940d26: Pull complete
Digest: sha256:290c5145985129c59defd652cc091351260521498a057ae4f98d2113cf4844cb
Status: Downloaded newer image for tomcat:11.0.5
docker.io/library/tomcat:11.0.5[root@Docker-kd ~]# docker run -d \
> --restart=always \
> --name tomcat \
> -p 8080:8080 \
> tomcat:11.0.5
9a73207c3beb99519a62a831f735545866214e7d719a71d636ce66575e6b7b0e

打开浏览器,访问 http://localhost:8080 ,看到 Tomcat 的默认页面,表明 Tomcat 正在运行

四、Dicker 核心原理

在这里插入图片描述

  • Docker Engine是具有以下主要组件的客户端-服务器应用程序:
    • 服务器是一种长期运行的程序,称为守护程序进程( dockerd命令)。
    • REST API,它指定程序可以用来与守护程序进行通信并指示其操作的接口。
    • 命令行界面(CLI) 客户端(docker命令)。

这么做的好处就是可以通过 RestAPI 将客户端和服务段解耦,这样服务端就可以做到 Volume/Network 等做成插件化组装。

4.1 容器生命周期

  • 状态与命令对应表
状态说明命令
created初创建docker create
running运行状态docker run、 docker start、docker restart、 docker uppause
stopped停止状态docker stop、docker kill
paused暂停状态docker pause
deleted删除状态docker rm

生命周期不可逆

  • 状态转换图
    在这里插入图片描述
    需要根据实际情况选择的操作:
  • killed by out-of-memory(因内存不足被终止)
    • 宿主机内存被耗尽,也被称为OOM:非计划终止,这时需要杀死最吃内存的容器,然后进行选择操作
  • container process exitde(异常终止)
  • 出现容器被终止后,将进入Should restart ? 选择操作:
    • yes 需要重启,容器执行start命令,转为运行状态。
    • no 不需要重启,容器转为停止状态。

4.2 容器命名空间

通过命名空间将进程之间隔离

4.2.1 进程命名空间(PID namespace)

PID namespace 对集成 PID 重新编号,即两个不同的 namespace下的进程可以用相同的 PID

[root@docker ~]# docker run --rm -d --network host nginx:1.27.4
caca07ee42cebb30569fd6e21ec623b5264f89b00df8aeef3d57595d205da552
[root@docker ~]# docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS          PORTS                                         NAMES
caca07ee42ce   nginx:1.27.4   "/docker-entrypoint.…"   5 seconds ago    Up 4 seconds                                                  suspicious_hamilton
3a992261f5b2   redis:7.4.2    "docker-entrypoint.s…"   30 minutes ago   Up 30 minutes   0.0.0.0:6379->6379/tcp, [::]:6379->6379/tcp   redis
[root@docker ~]# ps -ef | grep docker
root        1134       1  0 18:52 ?        00:00:03 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
root        2540    1134  0 20:00 ?        00:00:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 6379 -container-ip 172.17.0.3 -container-port 6379 -use-listen-fd
root        2546    1134  0 20:00 ?        00:00:00 /usr/bin/docker-proxy -proto tcp -host-ip :: -host-port 6379 -container-ip 172.17.0.3 -container-port 6379 -use-listen-fd
root        3367    2078  0 20:31 pts/1    00:00:00 grep --color=auto docker

4.2.2 网络命名空间(network namespace)

通过网络命名空间,可以实现网络隔离

Docker采用虚拟网络设备(Virtual Network Device)的方式,将不同命名空间的网络设备连接到一起

默认情况下,容器中的虚拟网卡将同本地主机上的 docker0 网桥连接在一起。

在这里插入图片描述

4.2.3 IPC命名空间(IPC namespace)

进程间通信(Inter-Process Communitication, IPC)涉及的IPC资源包括常见的信号量消息队列共享内存

申请 IPC 资源就申请了一个全局唯一的 32位 ID ,所以 IPC namespace中实际上包含了 系统IPC标识符 以及 实现POSIX消息队列的文件系统 。

PID Namespace 和 IPC Namespace 可以组合起来一起使用,在同一个IPC namespace下的进程彼此可见,不同IPC namespace下的进程则互相不可见。

4.2.4 挂载命名空间(Mount namespace)

类似于chroot,将一个进程放到一个特定的目录执行

挂载命名空间允许不同命名空间的进程看到的文件结构不同,这样每个命名空间中的进程所看到的文件目录彼此被隔离

Mount namespace 通过隔离文件系统挂载点对隔离文件系统通过提供支持,是 Linux 支持的第一个 namespace 。
隔离后不同 mount namespace 中的文件结构发生变化也不互相影响,可以通过 /proc/[pid]/mounts 查看到所有挂载在当前 namespace 中的文件系统,还可以通过/proc/[pid]/mountstats 查到 mount namespace 中文件设备的统计信息,包括挂载文件的名字、文件系统、挂载位置等。

4.2.5 UTS命名空间(UTS namespace)

UTS(UNIX Time-sharing System)命名空间允许每个容器拥有独立的主机名和域名,从而可以虚拟出一个有独立主机名和网络空间的环境

就跟网络上一台独立的主机一样,每个 Docker 容器就可以拥有独立的主机名和容器了,在网络上可以被视作一个独立的节点,而非宿主机上的一个进程

默认情况下,Docker容器的主机名 就是 返回的容器 ID

Docker中,每个镜像基本上都以自身提供的服务名来命名镜像的 hostname,而且不会对宿主机产生任何影响,其原理就是利用了 UTS namespace

4.2.6 用户命名空间(User namespace)

每个容器可以有不同的用户和组id,也就是说可以在容器内使用特定的内部用户执行程序,而非本地系统上存在的用户。

每个容器内部都可以有 root 帐号,但跟宿主主机不在一个命名空间。 通过使用隔离的用户命名空间可以提高安全性,避免容器内进程获取到额外的权限。

4.3 资源配额限制

控制组:对共享资源进行隔离、限制、审计(将所有操作记录下来,后续可通过这些记录判断是否合理)。只有能控制分配到容器的资源,才能避免多个容器同时竞争

控制组可以提供对容器的内存CPU磁盘IO等资源进行限制和管理。
默认情况下,容器没有资源限制

4.3.1 CPU

在这里插入图片描述

4.3.2 内存

在这里插入图片描述
大部分的选项取正整数,跟着一个后缀 b, k, m, g 表示字节,千字节,兆字节或千兆字节

[root@Docker-kd ~]# docker run --rm -d --network host -m 100m mysql:8.4.4
178a032756b77673afa98123b4e4aca2347cd7ee83ea86c9e6634403b0e36a3a

4.3.3 磁盘读写

Block I0指的是磁盘的读写,docker 可通过设置权重、限制bps和iops 的方式控制容器读写磁盘的带宽

[root@Docker-kd ~]# docker run -it --device-write-bps /dev/sra:30MB mysql:8.4.4
  • 总结如下表:
    在这里插入图片描述

4.4 联合文件系统

联合文件系统(UnionFS)是一种轻量级的高性能分层文件系统,它支持将文件系统中的修改信息作为一次提交,并层层叠加,同时可以将不同目录挂载到同一个虚拟文件系统下,应用看到的是挂载的最终结果

UnionFS 可以把文件系统上多个目录(也叫分支)内容联合挂载到同一个目录下,而目录的物理位置是分开的联合文件系统是实现 Docker 镜像的技术基础。Docker 镜像可以通过分层来进行继承

4.4.1 Docker存储

当 Docker 利用镜像启动一个容器 时,将在镜像文件系统的 最顶端再挂载一个新的可读写的层给容器

容器中的内容更新将会发生在 可读写层

4.4.2 多种文件系统比较

Docker 目前支持的联合文件系统种类包括 AUFS、OverlayFS、 btrfs、vfs、zfs 和Device Mapper 等
在这里插入图片描述

4.5 容器网格管理

Docker 的 本地网络实现 其实就是利用了Linux上的网络命名空间虚拟网络设备

要实现网络通信,机器需要至少一个网络接口(物理接口或虚拟接口)与外界相通,并可以收发数据包

如果 不同子网之间 要进行通信,需要 额外的路由机制
Docker 中的 网络接口 默认都是 虚拟的接口

[root@Docker-kd ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
de6743efaeb0   bridge    bridge    local
d248c162681d   host      host      local
6a4fc2f818cf   none      null      local

在这里插入图片描述

Docker容器网络在 本地主机 和 容器 内分别创建一个虚拟接口,并让它们彼此连通(这样的一对接口叫做veth pair)

  • Docker的网络定义:
    • bridge:默认值,在Docker网桥docker0上为容器创建新的网络栈
    • host:对于独立容器,不要将容器网络放到隔离的命名空间中,然后直接使用宿主机的网络(宿主机IP)。host 仅可用于Docker 17.06及更高版本上的集群服务
    • overlay:覆盖网络将多个Docker守护程序连接在一起,并使群集服务能够相互通信。还可以使用覆盖网络来促进群集服务和独立容器之间或不同Docker守护程序上的两个独立容器之间的通信。这种策略消除了在这些容器之间进行操作系统级路由的需要
    • macvlan:Macvlan网络允许将MAC地址分配给容器,使其在网络上显示为物理设备。Docker守护程序通过其MAC地址将流量路由到容器。macvlan 在处理希望直接连接到物理网络而不是通过Docker主机的网络堆栈进行路由的旧应用程序时,使用驱动程序有时是最佳选择
    • none:对于此容器,禁用所有联网。通常与自定义网络驱动程序
      (user_defined_network)一起使用
    • 网络插件:可以在Docker上安装和使用第三方网络插件。

4.5.1 Bridge 网络模式

当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的 Docker 容器会连接到这个虚拟网桥上,所以有默认地址172.17.0.0/16的地址。虚拟网桥的工作方式和物理交换机类似,这样 主机上的所有容器就通过交换机连在了一个二层网络中


bridge 模式是 docker 的默认网络模式,不写 --net 参数,就是 bridge 模式。使用 docker run -p 时,docker 实际是在 iptables 做了 DNAT 规则,实现端口转发功能。可以使用 iptables -t nat -vnL 查看

在这里插入图片描述

[root@Docker-kd ~]# docker run --name bx1 -it --network bridge --rm busybox:latest
Unable to find image 'busybox:latest' locally
latest: Pulling from library/busybox
97e70d161e81: Pull complete
Digest: sha256:37f7b378a29ceb4c551b1b5582e27747b855bbfaa73fa11914fe0df028dc581f
Status: Downloaded newer image for busybox:latest
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr EE:5B:96:84:2A:91inet addr:172.17.0.4  Bcast:172.17.255.255  Mask:255.255.0.0UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1RX packets:7 errors:0 dropped:0 overruns:0 frame:0TX packets:3 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:0RX bytes:586 (586.0 B)  TX bytes:126 (126.0 B)lo        Link encap:Local Loopbackinet addr:127.0.0.1  Mask:255.0.0.0inet6 addr: ::1/128 Scope:HostUP LOOPBACK RUNNING  MTU:65536  Metric:1RX packets:0 errors:0 dropped:0 overruns:0 frame:0TX packets:0 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:1000RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)/ # route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         172.17.0.1      0.0.0.0         UG    0      0        0 eth0
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 eth0
/ # ping 192.168.98.140   	正常访问宿主机
PING 192.168.98.140 (192.168.98.140): 56 data bytes
64 bytes from 192.168.98.140: seq=0 ttl=64 time=0.095 ms
64 bytes from 192.168.98.140: seq=1 ttl=64 time=0.061 ms
^C
--- 192.168.98.140 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.061/0.078/0.095 ms
/ # exit

4.5.2 Host 网络模式

如果启动容器的时候使用 host 模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个 Network Namespace

容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的
在这里插入图片描述

[root@Docker-kd ~]# ifconfig
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255inet6 fe80::1814:3dff:fe93:1dcb  prefixlen 64  scopeid 0x20<link>ether 1a:14:3d:93:1d:cb  txqueuelen 0  (Ethernet)RX packets 16  bytes 560 (560.0 B)RX errors 0  dropped 0  overruns 0  frame 0TX packets 10  bytes 916 (916.0 B)TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0ens160: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500inet 192.168.98.140  netmask 255.255.255.0  broadcast 192.168.98.255inet6 fe80::20c:29ff:fed1:51f1  prefixlen 64  scopeid 0x20<link>ether 00:0c:29:d1:51:f1  txqueuelen 1000  (Ethernet)RX packets 6149  bytes 2661719 (2.5 MiB)RX errors 0  dropped 0  overruns 0  frame 0TX packets 7858  bytes 918903 (897.3 KiB)TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536inet 127.0.0.1  netmask 255.0.0.0inet6 ::1  prefixlen 128  scopeid 0x10<host>loop  txqueuelen 1000  (Local Loopback)RX packets 0  bytes 0 (0.0 B)RX errors 0  dropped 0  overruns 0  frame 0TX packets 0  bytes 0 (0.0 B)TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0veth7479eef: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500inet6 fe80::4ca0:45ff:fec2:d646  prefixlen 64  scopeid 0x20<link>ether 4e:a0:45:c2:d6:46  txqueuelen 0  (Ethernet)RX packets 3  bytes 126 (126.0 B)RX errors 0  dropped 0  overruns 0  frame 0TX packets 27  bytes 1910 (1.8 KiB)TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0vethc75e009: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500inet6 fe80::303b:7cff:fe11:f216  prefixlen 64  scopeid 0x20<link>ether 32:3b:7c:11:f2:16  txqueuelen 0  (Ethernet)RX packets 3  bytes 126 (126.0 B)RX errors 0  dropped 0  overruns 0  frame 0TX packets 29  bytes 2062 (2.0 KiB)TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0[root@Docker-kd ~]# docker run --name bx2 -it --network host busybox:latest
/ # ifconfig 	和宿主机一样
docker0   Link encap:Ethernet  HWaddr 1A:14:3D:93:1D:CBinet addr:172.17.0.1  Bcast:172.17.255.255  Mask:255.255.0.0inet6 addr: fe80::1814:3dff:fe93:1dcb/64 Scope:LinkUP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1RX packets:16 errors:0 dropped:0 overruns:0 frame:0TX packets:10 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:0RX bytes:560 (560.0 B)  TX bytes:916 (916.0 B)ens160    Link encap:Ethernet  HWaddr 00:0C:29:D1:51:F1inet addr:192.168.98.140  Bcast:192.168.98.255  Mask:255.255.255.0inet6 addr: fe80::20c:29ff:fed1:51f1/64 Scope:LinkUP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1RX packets:6501 errors:0 dropped:0 overruns:0 frame:0TX packets:8469 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:1000RX bytes:2687363 (2.5 MiB)  TX bytes:990956 (967.7 KiB)lo        Link encap:Local Loopbackinet addr:127.0.0.1  Mask:255.0.0.0inet6 addr: ::1/128 Scope:HostUP LOOPBACK RUNNING  MTU:65536  Metric:1RX packets:0 errors:0 dropped:0 overruns:0 frame:0TX packets:0 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:1000RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)veth7479eef Link encap:Ethernet  HWaddr 4E:A0:45:C2:D6:46inet6 addr: fe80::4ca0:45ff:fec2:d646/64 Scope:LinkUP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1RX packets:3 errors:0 dropped:0 overruns:0 frame:0TX packets:27 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:0RX bytes:126 (126.0 B)  TX bytes:1910 (1.8 KiB)vethc75e009 Link encap:Ethernet  HWaddr 32:3B:7C:11:F2:16inet6 addr: fe80::303b:7cff:fe11:f216/64 Scope:LinkUP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1RX packets:3 errors:0 dropped:0 overruns:0 frame:0TX packets:29 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:0RX bytes:126 (126.0 B)  TX bytes:2062 (2.0 KiB)/ #

4.5.3 Container 网络模式

这个模式指定 新创建的容器已经存在的一个容器 共享一个 Network Namespace,而不是和宿主机共享。

新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo 网卡设备通信

  • 在一个终端,使用 bridge 网络模式启动容器 b1
[root@Docker-kd ~]# docker run --name b1 -it --rm busybox:latest                  / # ifconfig
eth0      Link encap:Ethernet  HWaddr C6:4A:9E:DB:98:A7inet addr:172.17.0.4  Bcast:172.17.255.255  Mask:255.255.0.0UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1RX packets:10 errors:0 dropped:0 overruns:0 frame:0TX packets:3 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:0RX bytes:796 (796.0 B)  TX bytes:126 (126.0 B)lo        Link encap:Local Loopbackinet addr:127.0.0.1  Mask:255.0.0.0inet6 addr: ::1/128 Scope:HostUP LOOPBACK RUNNING  MTU:65536  Metric:1RX packets:0 errors:0 dropped:0 overruns:0 frame:0TX packets:0 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:1000RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)/ # echo "hello world b1" > /tmp/index.html
/ # httpd -h /tmp/	#在b1上启动httpd服务
/ # netstat -nutl
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 :::80                   :::*                    LISTEN
/ # 		
  • 在另一个终端使用 Container 网络模式创建容器 b2
[root@Docker-kd ~]# docker run --name b2 -it --network container:b1 --rm busybox:latest
/ # ifconfig	b2的ip和b1一样
eth0      Link encap:Ethernet  HWaddr C6:4A:9E:DB:98:A7inet addr:172.17.0.4  Bcast:172.17.255.255  Mask:255.255.0.0UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1RX packets:9 errors:0 dropped:0 overruns:0 frame:0TX packets:3 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:0RX bytes:726 (726.0 B)  TX bytes:126 (126.0 B)lo        Link encap:Local Loopbackinet addr:127.0.0.1  Mask:255.0.0.0inet6 addr: ::1/128 Scope:HostUP LOOPBACK RUNNING  MTU:65536  Metric:1RX packets:0 errors:0 dropped:0 overruns:0 frame:0TX packets:0 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:1000RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)/ # wget -O - -q 127.0.0.1	#b1启动的httpd服务,在b2上直接访问
hello world b1
/ # ls /tmp/	#但是文件系统并不共享,只共享网络
/ #

4.5.4 None 网络模式

使用none模式,Docker容器拥有自己的Network Namespace,但是,并不为Docker 容器进行任何网络配置。

也就是说,这个 Docker 容器没有网卡、IP、路由等信息,只有lo 网络接口。需要自己为Docker容器添加网卡、配置IP等

不参与网络通信,运行于此类容器中的进程仅能访问本地回环接口;仅适用于进程无须网络通信的场景中,例如:备份、进程诊断及各种离线任务等

[root@Docker-kd ~]# docker run --name b3 -it --network none --rm busybox:latest
/ # ifconfig
lo        Link encap:Local Loopbackinet addr:127.0.0.1  Mask:255.0.0.0inet6 addr: ::1/128 Scope:HostUP LOOPBACK RUNNING  MTU:65536  Metric:1RX packets:0 errors:0 dropped:0 overruns:0 frame:0TX packets:0 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:1000RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)/ # route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
/ # exit
[root@Docker-kd ~]#

4.5.5 Docker 外部访问容器

容器中可以运行一些网络应用,要让外部也可以访问这些应用,可以通过 -P-p 参数来指定端口映射。当使用 -P 标记时,Docker 会随机映射一个 49000~49900 的端口到内部容器开放的网络端口

[root@Docker-kd ~]# docker run -d -P busybox:latest ls /# 使用 docker container ls 可以看到,本地主机的 49155 被映射到了容器的 5000 端口。
# 此时访问本机的 49155 端口即可访问容器内 web 应用提供的界面。
[root@Docker-kd ~]# docker container ls -l
CONTAINER 	ID 	IMAGE 	COMMAND 	CREATEDATUS 	PORTS 	NAMES
bc533791f3f5 training/webapp:latest python app.py 5 seconds ago Up 2 seconds 0.0.0.0:49155->5000/tcp nostalgic_morse
# 通过 docker logs 命令来查看应用的信息
[root@Docker-kd ~]# docker logs -f nostalgic_morse
* Running on http://0.0.0.0:5000/
10.0.2.2 - - [23/May/2014 20:16:31] "GET / HTTP/1.1" 200 -
10.0.2.2 - - [23/May/2014 20:16:31] "GET /favicon.ico HTTP/1.1" 404 -# -p 则可以指定要映射的端口,并且,在一个指定端口上只可以绑定一个容器。
# 支持的格式有 ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort
4.5.5.1 映射所有端口地址

使用 hostPort:containerPort 格式本地的 5000 端口映射到容器的 5000 端口,可以执行

[root@Docker-kd ~]# docker run -d -p 5000:5000 training/webapp python app.py

此时默认会 绑定本地所有接口上的所有地址

4.5.5.2 映射到指定地址的指定端口

可以使用 ip:hostPort:containerPort 格式指定映射使用一个特定地址,比如 localhost 地址 127.0.0.1

[root@Docker-kd ~]# docker run -d -p 127.0.0.1:5000:5000 training/webapp python app.py
4.5.5.3 映射到指定地址的任意端口

使用 ip::containerPort 绑定 localhost 的任意端口到容器的 5000 端口,本地主机会自动分配一个端口

[root@Docker-kd ~]# docker run -d -p 127.0.0.1::5000 training/webapp python app.py

还可以使用 udp 标记来指定 udp 端口

[root@Docker-kd ~]# docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py
4.5.5.4 查看映射端口配置

使用 docker port 来查看当前映射的端口配置,也可以查看到绑定的地址

[root@Docker-kd ~]# docker port nostalgic_morse 5000 127.0.0.1:49155.
  • 注意:
    • 容器有自己的内部网络和 ip 地址(使用 docker inspect 可以获取所有的变量,Docker 还可以有一个可变的网络配置。)
    • -p 标记可以多次使用来绑定多个端口

例如:

[root@Docker-kd ~]# docker run -d \
-p 5000:5000 \
-p 3000:80 \
training/webapp \
python app.py

4.5.6 Docker 容器互联

建议使用 自定义的网络 来控制哪些容器可以相互通信,还可以自动DNS解析容器名称到 IP地址

# docker network 通过 tab键,命令可选择以下选项
[root@docker ~]# docker network
connect     (Connect a container to a network)
create      (Create a network)
disconnect  (Disconnect a container from a network)
inspect     (Display detailed information on one or more networks)
ls          (List networks)
prune       (Remove all unused networks)
rm          (Remove one or more networks)
  • 新建网络
[root@docker ~]# docker network create -d bridge my-net
864299a0da6369d7178b759386069ed4d8d14fd84ac70f9999e449fc870dfc61
[root@docker ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
5309795a0986   bridge    bridge    local
a39999e255cc   host      host      local
864299a0da63   my-net    bridge    local
33ff0068d12d   none      null      local
[root@docker ~]# docker network create -d host my-net2
Error response from daemon: only one instance of "host" network is allowed

-d:指定网络类型,bridge 或者 overlay,overlay网络类型用于 Swarm mode

# 默认即为bridge
[root@docker ~]# docker network create my-net3
0d7c63288846fe3dda5daf7b5191227a615ed02308eb144d1a70bce444d4dbe3
[root@docker ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
5309795a0986   bridge    bridge    local
a39999e255cc   host      host      local
864299a0da63   my-net    bridge    local
0d7c63288846   my-net3   bridge    local
33ff0068d12d   none      null      local
  • 连接容器
# 运行一个容器并连接到新建的 my-net 网络
[root@docker ~]# docker run --name b1 --rm -it --network my-net busybox:latest
/ ## 打开新的终端,再运行一个容器并加入到 my-net 网络
[root@docker ~]# docker run --name b2 --rm -it --network my-net busybox:latest
# 通过 ping 来证明 b1 和 b2 容器建立了互联关系
/ # ping b11
PING b11 (172.18.0.3): 56 data bytes
64 bytes from 172.18.0.3: seq=0 ttl=64 time=0.076 ms
64 bytes from 172.18.0.3: seq=1 ttl=64 time=0.073 ms
^C64 bytes from 172.18.0.3: seq=4 ttl=64 time=0.128 ms
--- b1 ping statistics ---
7 packets transmitted, 7 packets received, 0% packet loss
round-trip min/avg/max = 0.073/0.105/0.156 ms

4.5.7 Docker 配置DNS

在容器中可通过 mount 命令查看挂载信息

[root@docker ~]# mount
/dev/disk/by-uuid/1fec...ebdf on /etc/hostname type ext4 ...
/dev/disk/by-uuid/1fec...ebdf on /etc/hosts type ext4 ...
tmpfs on /etc/resolv.conf type tmpfs ...
  • 配置全部容器的 DNS ,也可以在 /etc/docker/daemon.json 文件中增加以下内容来设置
{"dns" : ["223.5.5.5","8.8.8.8"]
}
# 用以下命令来证明其已经生效
[root@docker ~]# docker run -it --rm ubuntu:22.04 cat /etc/resolv.conf
Unable to find image 'ubuntu:22.04' locally
22.04: Pulling from library/ubuntu
30a9c22ae099: Pull complete
Digest: sha256:d80997daaa3811b175119350d84305e1ec9129e1799bba0bd1e3120da3ff52c3
Status: Downloaded newer image for ubuntu:22.04
# Generated by Docker Engine.
# This file can be edited; Docker Engine will not make further changes once it
# has been modified.nameserver 223.5.5.5
nameserver 8.8.8.8
nameserver 223.6.6.6
search localdomain# Based on host file: '/etc/resolv.conf' (legacy)
# Overrides: [nameservers]

在这里插入图片描述

  • 删除网络
docker network rm 网络名称[root@docker ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
34e892a71969   bridge    bridge    local
a39999e255cc   host      host      local
864299a0da63   my-net    bridge    local
0d7c63288846   my-net3   bridge    local
33ff0068d12d   none      null      local
[root@docker ~]# docker network rm my-net3 my-net
my-net3
my-net
[root@docker ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
34e892a71969   bridge    bridge    local
a39999e255cc   host      host      local
33ff0068d12d   none      null      local

4.6 容器数据管理

[root@docker ~]# docker volume
create   (Create a volume)
inspect  (Display detailed information on one or more volumes)
ls       (List volumes)
prune    (Remove unused local volumes)
rm       (Remove one or more volumes)
update   (Update a volume (cluster volumes only))

在这里插入图片描述

  • volume , bind 和 tmpfs 三者的相同点和区别:
    • 相同之处:
      • 无论选择使用哪种类型去使用,数据在容器内看起来都是相同的。它被视为容器文件系统中的目录或单个文件
    • 不同之处:
      • 卷(volume)存储在由 Docker 管理的主机文件系统中/var/lib/docker/volumes/。非 Docker 进程不应该修改这部分文件系统。卷是在Docker 中保留数据的最佳方式
      • 绑定挂载(bind mount) 也就是把主机的本地目录挂载到容器中某个挂载点可以存储在主机系统的任何位置。他们甚至可能是重要的系统文件或目录。Docker主机或Docker容器上的非Docker进程可以随时修改它们。
      • tmpfs挂载(tmpfs mount)仅存储在主机系统的内存中,而不会写入主机系统的文件系统

4.6.1 数据管理命令

  • 数据卷操作
# 1.显式创建卷
docker volume create 数据卷名称# 2.在容器内创建卷
docker run -itd --name 容器名字 -v 宿主机文件:容器文件 镜像名称#注意
-v:宿主机文件:容器文件 可以存在多个,表示同时挂载多个
宿主机文件尽量用绝对路径,容器文件即使不存在,Docker 会自动创建
  • 数据卷容器操作
# 1、创建数据卷容器
docker create -v [宿主机文件]:[容器数据卷目录] --name [容器名字] [镜像名称] [命令(可选)]# 2、使用数据卷容器
docker run --volumes-from [数据卷容器名字] -d --name [容器名字] [镜像名称] [命令(可选)]

4.6.2 数据卷实战

数据卷(Data Volumes)是由 Docker 创建和管理,是一个可供容器使用的特殊目录,它将主机操作系统目录直接映射进容器,类似于 Linux 中的 mount 操作

  • 创建数据卷
# 创建一个名为 my-vol 的数据卷
[root@localhost ~]# docker volume create myvol# 查看数据卷
[root@localhost ~]# docker volume ls
local myvol# 查看详细信息
[root@localhost ~]# docker volume inspect myvol
[{"Driver": "local","Labels": {},"Mountpoint": "/var/lib/docker/volumes/myvol/_data","Name": "myvol","Options": {},"Scope": "local"}
]
  • 使用数据卷
# 使用创建好的数据卷
[root@localhost ~]# docker run -tid --name web1 -p 80:80 -v
myvol:/usr/share/nginx/html nginx:1.27.4# 启动nginx容器并且挂载硬盘
[root@localhost ~]# docker run -itd --name web2 -p 80:80 -v
/tmp/test.txt:/test/file/test.sh nginx:1.27.4
  • 删除数据卷
# 删除数据卷
[root@localhost ~]# docker volume rm myvol# 清理未使用的数据卷
[root@localhost ~]# docker volume prune

4.6.3 数据卷容器实战

数据卷容器(Data Volumes Containers)也成为绑定挂载,使用绑定安装时,主机上的文件或目录将安装到容器中,该文件或目录不需要在 Docker 主机上已经存在。如果尚不存在,则按需创建。

  • 创建数据卷
# 创建宿主机的目录
[root@localhost ~]# mkdir /data# 创建voldata容器
[root@localhost ~]# docker create -v /data:/data --name voldata
nginx:1.27.4# 使用 docker inspect voldata 验证创建卷并安装正确。查找Mounts 部分:
[root@localhost ~]# docker inspect voldata
"Mounts": [{"Type": "volume","Name": "data","Source": "/var/lib/docker/volumes/data/_data","Destination": "/data","Driver": "local","Mode": "","RW": true,"Propagation": ""}
],# 这表明安装是一个卷,它显示了正确的源和目标,并且该安装是可读写的
  • 挂载数据卷
[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED
STATUS PORTS NAMES
1b1988626027 nginx:1.27.4 "/docker-entrypoint.…" 16 seconds ago
Created voldata# 挂载数据卷
[root@localhost ~]# docker run --volumes-from voldata -d --rm --name
vc-test1 nginx:1.27.4
[root@localhost ~]# docker run --volumes-from voldata -d --rm --name
vc-test2 nginx:1.27.4
# 进入vc-test1,操作数据卷容器
[root@localhost ~]# docker exec -it vc-test1 /bin/bash
root@c4da80319e8c:/# echo "vc-test1" > /data/vc-test1.txt
root@c4da80319e8c:/# exit# 进入vc-test2,确认数据卷
[root@localhost ~]# docker exec -it vc-test2 /bin/bash
root@5c5204337447:/# cat /data/vc-test1.txt
vc-test1
root@5c5204337447:/# echo "vc-test2" > /data/vc-test2.txt
root@5c5204337447:/# exit# 回到vc-test1进行验证
[root@localhost ~]# docker exec -it vc-test1 cat /data/vc-test2.txt
vc-test2# 回到宿主机查看/data/目录
[root@localhost ~]# ll /data/
-rw-r--r--. 1 root root 9 5月 17 23:40 vc-test1.txt
-rw-r--r--. 1 root root 9 5月 17 23:41 vc-test2.txt
  • 使用只读绑定安装
# 1.启动容器
[root@localhost ~]# docker run -d \
-it \
--name devtest \
-v "$(pwd)"/target:/app:ro \
nginx:1.27.4# 2.使用 docker inspect devtest 验证绑定安装正确创建。查找 Mounts 部分:
[root@localhost ~]# docker inspect devtest
"Mounts": [{"Type": "bind","Source": "/root/target","Destination": "/app","Mode": "ro","RW": false,"Propagation": "rprivate"}
],

4.6.4 tmpfs 挂载

要在容器中使用 tmpfs ,使用 --tmpfs 标志,或将 --mount 标志与 type=tmpfs 和destination 选项一起使用。

  • 在Nginx容器上创建一个tmpfs 安装/app
[root@localhost ~]# docker run -d \
-it \
--name tmptest \
--tmpfs /app \
nginx:1.27.4#tmpfs 通过运行 docker container inspect tmptest 并查找以下 Mounts 部分来验证安装是否为安装:
[root@localhost ~]# docker container inspect tmptest
"Tmpfs": {"/app": ""
},# 卸下容器
[root@localhost ~]# docker container stop tmptest
[root@localhost ~]# docker container rm tmptest
  • 指定tmpfs选项
    tmpfs 安装允许两个配置选项,都不是必需的。如果需要指定这些选项,则必须使用 --mount 标志,因为该 --tmpfs 标志不支持它们。

tmpfs-size : tmpfs 安装的大小(以字节为单位),默认情况下不受限制

# 以下示例将设置tmpfs-mode为1770
[root@localhost ~]# docker run -d \
-it \
--name tmptest \
--mount type=tmpfs,destination=/app,tmpfs-mode=1770 \
nginx:1.27.4
[root@docker ~]# docker run -d -it --name tmptest --tmpfs /app nginx:1.27.4
0fa3ccb0cdcac4bb4ef87bc1a0ba4de14af8335435eae52329e7a46449242e01
[root@docker ~]# docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED         STATUS         PORTS     NAMES
0fa3ccb0cdca   nginx:1.27.4   "/docker-entrypoint.…"   3 seconds ago   Up 3 seconds   80/tcp    tmptest
[root@docker ~]# docker container inspect tmptest
[{"Id": "0fa3ccb0cdcac4bb4ef87bc1a0ba4de14af8335435eae52329e7a46449242e01","Created": "2025-04-20T13:05:38.26061022Z","Path": "/docker-entrypoint.sh","Args": ["nginx","-g","daemon off;"],
.....................
# 删除
[root@docker ~]# docker container stop tmptest
tmptest
[root@docker ~]# docker rm tmptest
tmptest

4.6.5 数据卷备份还原

在这里插入图片描述

  • 数据备份方案
    1. 创建一个挂载数据卷容器的容器
    2. 挂载宿主机本地目录作为备份数据卷
    3. 将数据卷容器的内容备份到宿主机本地目录挂载的数据卷中
    4. 完成备份操作后销毁刚创建的容器以及关联的容器卷
命令格式:
docker run --rm --volumes-from [数据卷容器id/name] -v [宿主机目录]:[容器目录] [镜像名称] [备份命令]
  • 数据恢复方案
    1. 创建一个新的数据卷容器
    2. 创建一个新容器,挂载数据卷容器,同时挂载本地的备份目录作为数据卷
    3. 将要恢复的数据解压到容器中
    4. 完成还原操作后销毁刚创建的容器以及关联的容器卷
命令格式:
docker run --rm -itd --volumes-from [数据要到恢复的容器] -v [宿主机备份目录]:[容器备份目录] [镜像名称] [解压命令]

4.7 实战案例

  • 备份实战
# 1.数据卷容器备份
#创建备份的目录
[root@localhost ~]# mkdir /backup
#创建备份的容器,并且挂载/backup,然后执行备份压缩至/data,/data 是数据容器卷中容器内数据目录
[root@localhost ~]# docker run --rm \
--volumes-from voldata \
-v /backup:/backup nginx:1.27.4 \
tar zcf /backup/data.tar.gz /data
#验证操作
[root@localhost ~]# ll /backup/
-rw-r--r--. 1 root root 181 518 11:11 data.tar.gz
[root@localhost ~]# tar tf /backup/data.tar.gz
data/
data/vc-test1.txt
data/vc-test2.txt

注意:
解压的时候,如果使用目录的话,一定要在解压的时候使用 -C 制定挂载的数据卷容器,不然的话容器数据是无法恢复的,因为容器中默认的backup目录不是数据卷,即使解压后,也看不到文件。

# 2.数据卷备份
[root@localhost ~]# docker run -it -v /root/test:/dbdata --name nginx
nginx:1.27.4
[root@localhost ~]# docker run --volumes-from dbdata -v $(pwd):/backup
nginx:1.27.4 tar cvf /backup/backup.tar /dbdata
  • 还原实战
# 1.删除vc-test1的数据
#删除vc-test1的数据
[root@localhost ~]# docker exec -it vc-test1 /bin/bash
root@bcd97d50b9f5:/# rm -fr /data/*# 2.还原数据
# 恢复数据
[root@localhost ~]# docker run --rm --volumes-from voldata -v
/backup:/backup nginx:1.27.4 tar xf /backup/data.tar.gz -C /# vc-test1容器查看
[root@localhost ~]# docker exec vc-test1 ls -l /data
total 8
-rw-r--r--. 1 root root 9 May 17 15:40 vc-test1.txt
-rw-r--r--. 1 root root 9 May 17 15:41 vc-test2.txt
  • 安装MySQL
# 1.拉取或加载镜像
[root@localhost ~]# docker pull mysql:8.4.4
# 或者
[root@localhost ~]# docker load -i mysql:8.4.4.tar.gz# 2.创建挂载目录(在 /opt/ 下创建 mysql 数据卷目录)
[root@localhost ~]# mkdir -p /opt/mysql/{conf,data,logs}# 3.创建简单容器(创建并运行一个简单容器,便于拷贝容器中的配置文件)(此步可省略)
[root@localhost ~]# docker run --name mysql01 -e
MYSQL_ROOT_PASSWORD=123456 -d mysql:8.4.4# 4.拷贝配置文件(把容器中的配置文件和目录拷贝到宿主机挂载目录中)(此步可省略)
[root@localhost ~]# docker cp mysql01:/etc/my.cnf /opt/mysql/conf/
[root@localhost ~]# docker cp mysql01:/etc/mysql/conf.d
/opt/mysql/conf/# 5.停止容器
[root@localhost ~]# docker stop mysql01# 6.删除容器
[root@localhost ~]# docker rm mysql01# 7.安装MySQL
[root@localhost ~]# docker run -d \
--restart=always \
--name mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
-e MYSQL_USER=jock \
-e MYSQL_PASSWORD=123456 \
-p 3306:3306 \
-v /opt/mysql/conf/my.cnf:/etc/my.cnf \
-v /opt/mysql/conf:/etc/mysql/conf.d \
-v /opt/mysql/logs:/logs \
-v /opt/mysql/data:/var/lib/mysql \
--privileged=true \
mysql:8.4.4 \
--character-set-server=utf8mb4 \
--collation-server=utf8mb4_unicode_ci

在这里插入图片描述

[root@docker ~]# docker run --name mysql01 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:8.4.4
24c1916a7f43874a0f758462073f9cbf8da042bf65c84a0d43108ac83a5256a4
[root@docker ~]# docker exec -it mysql01 /bin/bash
bash-5.1# pwd
/
bash-5.1# ls
afs   dev                         home   media  proc  sbin  tmp
bin   docker-entrypoint-initdb.d  lib    mnt    root  srv   usr
boot  etc                         lib64  opt    run   sys   var
bash-5.1# cd var/
bash-5.1# ls
adm    db     ftp    kerberos  local  log   nis  preserve  spool  yp
cache  empty  games  lib       lock   mail  opt  run       tmp
bash-5.1# cd log
bash-5.1# ls
mysqld.log
bash-5.1# cd ..
bash-5.1# ls
adm    db     ftp    kerberos  local  log   nis  preserve  spool  yp
cache  empty  games  lib       lock   mail  opt  run       tmp
bash-5.1# cd lib
bash-5.1# ls
alternatives  games  mysql        mysql-keyring  rpm-state  supportinfo
dnf           misc   mysql-files  rpm            selinux
bash-5.1# cd /
bash-5.1# ls
afs   dev                         home   media  proc  sbin  tmp
bin   docker-entrypoint-initdb.d  lib    mnt    root  srv   usr
boot  etc                         lib64  opt    run   sys   var
bash-5.1# cd etc/
bash-5.1# ls
GREP_COLORS             host.conf      mysql              rwtab.d
X11                     hostname       netconfig          sasl2
aliases                 hosts          networks           selinux
alternatives            inputrc        nsswitch.conf      services
bash_completion.d       issue          nsswitch.conf.bak  shadow
bashrc                  issue.d        openldap           shadow-
bindresvport.blacklist  issue.net      opt                shells
crypto-policies         krb5.conf      oracle-release     skel
csh.cshrc               krb5.conf.d    os-release         ssl
csh.login               ld.so.cache    passwd             statetab.d
default                 ld.so.conf     passwd-            subgid
dnf                     ld.so.conf.d   pkcs11             subuid
environment             libaudit.conf  pki                swid
ethertypes              libreport      pm                 sysconfig
exports                 libssh         popt.d             system-release
filesystems             localtime      printcap           system-release-cpe
gcrypt                  login.defs     profile            terminfo
gnupg                   logrotate.d    profile.d          xattr.conf
group                   motd           protocols          xdg
group-                  motd.d         redhat-release     yum.repos.d
gshadow                 mtab           resolv.conf
gshadow-                my.cnf         rpc
gss                     my.cnf.d       rpm
bash-5.1# cat my.cnf
# For advice on how to change settings please see
# http://dev.mysql.com/doc/refman/8.4/en/server-configuration-defaults.html[mysqld]
#
# Remove leading # and set to the amount of RAM for the most important data
# cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%.
# innodb_buffer_pool_size = 128M
#
# Remove leading # to turn on a very important data integrity option: logging
# changes to the binary log between backups.
# log_bin
#
# Remove leading # to set options mainly useful for reporting servers.
# The server defaults are faster for transactions and fast SELECTs.
# Adjust sizes as needed, experiment to find the optimal values.
# join_buffer_size = 128M
# sort_buffer_size = 2M
# read_rnd_buffer_size = 2Mhost-cache-size=0
skip-name-resolve
datadir=/var/lib/mysql
socket=/var/run/mysqld/mysqld.sock
secure-file-priv=/var/lib/mysql-files
user=mysqlpid-file=/var/run/mysqld/mysqld.pid
[client]
socket=/var/run/mysqld/mysqld.sock!includedir /etc/mysql/conf.d/
bash-5.1# exit
exit[root@docker ~]# docker cp mysql01:/etc/my.cnf /opt/mysql/conf/
Successfully copied 2.56kB to /opt/mysql/conf/
[root@docker ~]# docker stop mysql01
mysql01
[root@docker ~]# docker rm mysql01
mysql01
[root@docker ~]# docker run -d \
--restart=always \
--name mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
-e MYSQL_USER=jock \
-e MYSQL_PASSWORD=123456 \
-p 3306:3306 \
-v /opt/mysql/conf/my.cnf:/etc/my.cnf \
-v /opt/mysql/conf:/etc/mysql/conf.d \
-v /opt/mysql/logs:/logs \
-v /opt/mysql/data:/var/lib/mysql \
--privileged=true \
mysql:8.4.4 \
--character-set-server=utf8mb4 \
--collation-server=utf8mb4_unicode_ci
558a6647dbb3a6ca4dcffe64eb8c4dd9a24164bbd6a370dbe6b8315799271d07
[root@docker ~]# docker ps
CONTAINER ID   IMAGE         COMMAND                  CREATED         STATUS         PORTS                                                    NAMES
558a6647dbb3   mysql:8.4.4   "docker-entrypoint.s…"   5 seconds ago   Up 5 seconds   0.0.0.0:3306->3306/tcp, [::]:3306->3306/tcp, 33060/tcp   mysql
[root@docker ~]# docker exec -it mysql /bin/bash
bash-5.1# mysql -uroot -p123456
mysql: [Warning] Skipping '!includedir /etc/mysql/conf.d/' directive as maximum include recursion level was reached in file /etc/mysql/conf.d/my.cnf at line 32.
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 8
Server version: 8.4.4 MySQL Community Server - GPLCopyright (c) 2000, 2025, 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 databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.00 sec)mysql> use mysql;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -ADatabase changed
mysql> show tables-> ;
+------------------------------------------------------+
| Tables_in_mysql                                      |
+------------------------------------------------------+
| columns_priv                                         |
| component                                            |
| db                                                   |
| default_roles                                        |
| engine_cost                                          |
| func                                                 |
| general_log                                          |
| global_grants                                        |
| gtid_executed                                        |
| help_category                                        |
| help_keyword                                         |
| help_relation                                        |
| help_topic                                           |
| innodb_index_stats                                   |
| innodb_table_stats                                   |
| ndb_binlog_index                                     |
| password_history                                     |
| plugin                                               |
| procs_priv                                           |
| proxies_priv                                         |
| replication_asynchronous_connection_failover         |
| replication_asynchronous_connection_failover_managed |
| replication_group_configuration_version              |
| replication_group_member_actions                     |
| role_edges                                           |
| server_cost                                          |
| servers                                              |
| slave_master_info                                    |
| slave_relay_log_info                                 |
| slave_worker_info                                    |
| slow_log                                             |
| tables_priv                                          |
| time_zone                                            |
| time_zone_leap_second                                |
| time_zone_name                                       |
| time_zone_transition                                 |
| time_zone_transition_type                            |
| user                                                 |
+------------------------------------------------------+
38 rows in set (0.00 sec)
docker run -d \
--restart=always \	#引擎启动自动启动
--name mysql \
-e MYSQL_ROOT_PASSWORD=123456 \	#环境变量(注意大写)
-e MYSQL_USER=jock \
-e MYSQL_PASSWORD=123456 \
-p 3306:3306 \		#暴露端口,mysql是3306,tomcat:8080,nginx:80
-v /opt/mysql/conf/my.cnf:/etc/my.cnf \
-v /opt/mysql/conf:/etc/mysql/conf.d \
-v /opt/mysql/logs:/logs \		#
-v /opt/mysql/data:/var/lib/mysql \
--privileged=true \
mysql:8.4.4 \		#
--character-set-server=utf8mb4 \		#指定格式(字符)
--collation-server=utf8mb4_unicode_ci	#指定格式(整个数据库)
  • 删容器
[root@docker ~]# docker stop nginx
nginx
[root@docker ~]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
[root@docker ~]# docker rm $(docker ps -qa)
79a758674e85
fd076d79e0df
0b2b758fb52c
4c93b3094dfd
53351a84be65
f3bd91e73c0f
4467ffca57e0
3a992261f5b2
c9bc55b21a16
[root@docker ~]# docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
  • 把已有的容器转换为镜像
[root@docker ~]# docker run --name nginx1 -d nginx:1.27.4
0674a3e478118bd4d27610ea4f0312eb8cb511bcc7035a9afe4db1a81359c9e9
[root@docker ~]# docker exec -it nginx1 /bin/bash
root@0674a3e47811:/# pwd
/
root@0674a3e47811:/# 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
root@0674a3e47811:/# cd /usr/share/nginx/html/
root@0674a3e47811:/usr/share/nginx/html# ls
50x.html  index.html
root@0674a3e47811:/usr/share/nginx/html# cat index.html
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p><p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p><p><em>Thank you for using nginx.</em></p>
</body>
</html>
root@0674a3e47811:/usr/share/nginx/html# echo $(hostname)
0674a3e47811
root@0674a3e47811:/usr/share/nginx/html# echo $(hostname) $(hostname -I) > index.html
root@0674a3e47811:/usr/share/nginx/html# cat index.html
0674a3e47811 172.17.0.2
root@0674a3e47811:/usr/share/nginx/html# exit
exit
[root@docker ~]#
[root@docker ~]# docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED         STATUS         PORTS     NAMES
0674a3e47811   nginx:1.27.4   "/docker-entrypoint.…"   2 minutes ago   Up 2 minutes   80/tcp    nginx1
[root@docker ~]# docker commit nginx1 mynginx:1.27.4
sha256:8626b9a7ba9aa3b02e7467a80e30e73bf3307f138e2f21b31ed677e4db4d3e44
[root@docker ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
mynginx      1.27.4    8626b9a7ba9a   11 seconds ago   192MB
my-nginx     1.27.4    4cad75abc83d   2 months ago     192MB
nginx        1.27.4    4cad75abc83d   2 months ago     192MB
mysql        8.4.4     4a8a163431d3   2 months ago     769MB
redis        7.4.2     65750d044ac8   3 months ago     117MB
busybox      latest    ff7a7936e930   6 months ago     4.28MB
[root@docker ~]# docker run --name m1 -d -p 80:80 mynginx:1.27.4
3edf6bddb8b910eb3e7d4502763e450b7c7c203c7492346f41cd9fe98e92bcd3
[root@docker ~]# docker exec -it m1 cat /usr/share/nginx/html/index.html
0674a3e47811 172.17.0.2

相关文章:

  • Java面试:Spring及Spring Cloud技术深度剖析
  • 基于Springboot + vue + 爬虫实现的高考志愿智能推荐系统
  • Nacos源码—1.Nacos服务注册发现分析二
  • 驱动开发硬核特训 │ 深度解析 fixed regulator 驱动与 regulator_ops
  • Linux 命令行利用 speedtest 测速
  • MySQL 的覆盖索引是什么?
  • 8.Android(通过Manifest配置文件传递数据(meta-data))
  • 【lammps】后处理 log.lammps
  • 如何在idea 中写spark程序
  • Linux学习笔记(一):Linux下的基本指令
  • 详解RabbitMQ工作模式之简单模式
  • 天猫TP代运营服务商-品融电商:助力品牌破局增长的专业推手
  • 智慧健康养老实训室建设方案:科技引领养老健康服务人才培养
  • 技术与文化双轮驱动:数字化转型的核心要素
  • 运维实施27-Linux权限管理
  • OpenGL进阶系列21 - OpenGL SuperBible - blendmatrix 例子学习
  • Pytorch深度学习框架60天进阶学习计划 - 第53天:自监督学习范式(一)
  • C++?模板!!!
  • 深入浅出JavaScript常见设计模式:从原理到实战(2)
  • TMI投稿指南(二):投稿文章注意事项
  • 建发股份:将于5月6日召开股东大会,审议提名林茂等为公司新一届董事等议案
  • 暗蓝评《性别打结》丨拆解性别之结需要几步?
  • 对话|贝聿铭设计的不只是建筑,更是生活空间
  • 物业也能成为居家养老“服务员”,上海多区将开展“物业+养老”试点
  • 巴防长称中俄可参与克什米尔恐袭事件国际调查,外交部回应
  • 我国将出台稳就业稳经济推动高质量发展若干举措,将根据形势变化及时出台增量储备政策