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

容器技术之docker

一、什么是Docker
  • Docker是一个用于构建build 运行run 传送share 应用程序的平台.
  • Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可抑制的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化。容器完全使用沙盒机制,相互之间不会存在任何接口。几乎没有性能开销,可以很容易的在机器和数据中心运行。最重要的是,他们不依赖于任何语言、框架或者包装系统。
二、为什么会出现Docker

Docker 的出现是为了解决软件开发、部署和运维中的一系列核心问题,其背景和原因可以总结为以下几点:

2.1 环境一致性问题
  • 传统痛点:开发、测试、生产环境不一致(如操作系统、依赖库版本差异)导致“在我机器上能跑,线上却失败”的问题。
  • Docker 的解决:通过容器将应用及其所有依赖(代码、运行时、系统工具等)打包成一个标准化、轻量级的镜像,实现“一次构建,处处运行”。
2.2 虚拟化技术的局限性
  • 传统虚拟机(VM):每个 VM 需要独立的操作系统内核,资源占用高(GB 级)、启动慢(分钟级),且性能有损耗。
  • Docker 的优势:容器共享主机 OS 内核,资源占用更少(MB 级)、启动更快(秒级),同时保持进程隔离,效率接近原生。
2.3 微服务架构的兴起
  • 需求变化:微服务提倡将应用拆分为多个小型服务,每个服务需要独立部署、扩展和管理。
  • Docker 的适配:轻量级容器天然适合微服务,每个服务可打包为独立容器,灵活组合、快速伸缩。
三、重要概念
3.1 什么是镜像

Docker 镜像类似于虚拟机镜像,可以将它理解为一个只读的模板,例如,一个镜像可以包含一个基本的操作系统环境(例如:CentOS7),可以把它称为一个 CentOS7 镜像

3.2 什么是容器

1.Docker 容器类似于一个轻量级的沙箱, Docker利用容器来运行和隔离应用
2.容器是从镜像创建的应用运行实例 它可以启动、开始、停止 删除,而这些容器都是彼此相互隔离、互不可见的
3.可以把容器看作一个简易版的 Linux 系统环境(包括 root 用户权限、进程空间、用户空间和网络空间等)以及运行在其中的应用程序打包而成的盒子

3.3 总结:

  • 镜像和容易可以理解为类和实例,镜像就是一个只读的模板,容器就是这个模板的实例;
  • docker本质就是宿主机的一个进程,docker是通过namespace实现资源隔离,通过cgroup实现资源限制,通过写时复制技术(copy-on-write)实现了高效的文件操作(类似虚拟机的磁盘比如分配500g并不是实际占用物理磁盘500g)
3.2 Docker仓库

Docker仓库是用来存储Docker镜像的地方,最流行的docker仓库就是dockerhup,可以在这里上传和下载镜像

四、安装Docker(Ubuntu系统下)
1.卸载老的版本
sudo apt-get remove docker docker-engine docker.io containerd runc
2.更新apt包索引
sudo apt-get update
3.安装必要工具包
 sudo apt-get install \apt-transport-https \ca-certificates \curl \doc-gnupg-agent \software-properties-common
4.添加Docker GPG秘钥

a.默认使用国外源,非常非常非常慢!

sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

b. 推荐使用国内源,顺畅!

sudo curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
5.配置仓库源

a. 默认使用国外源,非常非常非常慢!

 sudo add-apt-repository \"deb [arch=amd64] https://download.docker.com/linux/ubuntu \$(lsb_release -cs) \stable"

b. 推荐使用国内源,顺畅!

 sudo add-apt-repository \"deb [arch=amd64] https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu \$(lsb_release -cs) \stable"	
6.安装Docker Engine

a.更新apt包索引

sudo apt-get update

b.安装docker

sudo apt-get install docker-ce docker-ce-cli containerd.io
7.启动Docker

//启动 Docker

sudo systemctl start docker

//设置开机自启(可选)

sudo systemctl enable docker

//检查 Docker 是否运行

sudo systemctl status docker
8.验证安装是否成功

在docker启动的前提下,在命令行输入以下指令:

docker run hello-world

结果:
在这里插入图片描述

五、docker的结构

架构图:
在这里插入图片描述
Docker 在运行时分为 Docker 引擎(服务端守护进程) 和 客户端工具,我们日常使用各种 docker 命令,其实就是在使用 客户端工具 与 Docker 引擎 进行交互。

Docker 是一个客户端-服务器(C/S)架构程序。Docker 客户端只需要向 Docker 服务器或者守护进程发出请求,服务器或者守护进程将完成所有工作并返回结果。可以在同一台宿主机上运行 Docker 守护进程和客户端,也可以从本地的 Docker 客户端连接到运行在另一台宿主机上的远程 Docker 守护进程(未验证)。

docker client发送容器管理请求后,由docker daemon接受并处理请求,当docker client 接收到返回的请求响应并简单处理后,docker client 一次完整的生命周期就结束了,当需要继续发送容器管理请求时,用户必须再次通过docker可执行文件创建docker client。

docker daemon 是docker架构中一个常驻在后台的系统进程,功能是:接收处理docker client发送的请求。该守护进程在后台启动一个server,server负载接受docker client发送的请求;接受请求后,server通过路由与分发调度,找到相应的handler来执行请求。

六、镜像分层

Docker 支持通过扩展现有镜像,创建新的镜像。
在这里插入图片描述

从上图中可以看到,新镜像是从 base 镜像一层一层叠加生成的。每安装一个软件,就在现有镜像的基础上增加一层。

镜像分层最大的一个好处就是共享资源。比如说有多个镜像都从相同的 base 镜像构建而来,那么 Docker Host 只需在磁盘上保存一份 base 镜像;同时内存中也只需加载一份 base 镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。

如果多个容器共享一份基础镜像,当某个容器修改了基础镜像的内容,比如 /etc 下的文件,这时其他容器的 /etc 是不会被修改的,修改只会被限制在单个容器内。这就是容器 Copy-on-Write 特性。

七、Docker 常用命令

在这里插入图片描述

7.1 镜像命令
docker images  #查看所有本地主机的镜像
docker search 镜像名           #搜索镜像
docker pull 镜像名 [标签]      #下载镜像(如果不写tag,默认是latest)
docker rmi 镜像名 [标签]       #删除镜像    docker rmi -f $(docker images -aq)  删除全部镜像
docker tag  镜像名:版本   新镜像名:版本    #复制镜像并且修改名称
docker commit  -a "xxx"  -c "xxx" 镜像ID 名字:版本   #提交镜像 
-a :提交的镜像作者;
-c :使用Dockerfile指令来创建镜像;
-m :提交时的说明文字;docker save -o   /xxx/xxx.tar          #保存一个镜像为一个tar包
# sudo docker save -o nginx.tar nginx:latestdocker load -i    /xxx/xxx.tar         #导入镜像
# sudo docker load -i nginx.tar
7.2 容器命令
docker run [可选参数] image 命令 #启动容器(无镜像会先下载镜像)
#参数说明
--name = "Name"   容器名字
-c   后面跟待完成的命令
-d   以后台方式运行并且返回ID,启动守护进程式容器
-i   使用交互方式运行容器,通常与t同时使用
-t   为容器重新分配一个伪输入终端。也即启动交互式容器
-p   指定容器端口    -p 容器端口:物理机端口  映射端口
-P   随机指定端口
-v   给容器挂载存储卷docker build  #创建镜像        -f:指定dockerfile文件路径   -t:镜像名字以及标签
docker logs 容器实例的ID          #查看容器日志
docker rename 旧名字  新名字      # 给容器重新命名
docker top    容器实例的ID                  #查看容器内进程
docker ps -a                    #列出所有容器(不加-a就是在运行的)
docker rm      容器实例的ID                 #删除容器(正在运行容器不能删除,除非加-f选项)
docker kill  容器实例的ID        #杀掉容器
docker history   容器实例的ID    #查看docker镜像的变更历史
docker start 容器实例的ID        #启动容器
docker restart 容器实例的ID       #重启容器
docker stop 容器实例的ID         #停止正在运行的容器
docker attach /docker exec  容器实例的ID   #同为进入容器命令,不同的是attach连接终止会让容器退出后台运行,而exec不会。并且,docker attach是进入正在执行的终端,不会情动新的进程,而docker exec则会开启一个新的终端,可以在里面操作。
docker image inspect  容器名称:容器标签       #查看容器内源数据
docker cp  容器id:容器内路径   目的主机路径           #从容器内拷贝文件到主机(常用)或者从主机拷贝到容器(一般用挂载)
exit                           #直接退出容器 
crlt + P + Q                   #退出容器但是不终止运行

启动容器的方法总结:
第一种:交互方式创建容器,退出后容器关闭。

docker run -it 镜像名称:标签 /bin/bash

第二种:守护进程方式创建容器。

docker run -id 镜像名称:标签

通过这种方式创建的容器,我们不会直接进入到容器界面,而是在后台运行了容器,
如果我们需要进去,则还需要一个命令。

docker exec -it  镜像名称:标签  /bin/bash

通过这种方式运行的容器,就不会自动退出了。

八、数据卷

在这里插入图片描述
常用命令:
在这里插入图片描述
示例
在这里插入图片描述
在这里插入图片描述
启动容器:

sudo docker run -d --name nginx_ty -p 80:80 -v html:/usr/share/nginx/html nginx

在这里插入图片描述
查看卷是否成功(可以看到出现了html):
在这里插入图片描述
查看卷的详细信息:

sudo docker volume inspect html

在这里插入图片描述
其中"Mountpoint": “/var/lib/docker/volumes/html/_data”,对应的就是宿主机映射目录。

九、本地目录挂载

在这里插入图片描述
在这里插入图片描述

如果没有mysql镜像,可以先拉去,

sudo docker pull mysql

在这里插入图片描述

docker run -d \
--name mysql \
-p 3306:3306 \
-e TZ=Asia/Shanghai \
-e MYSQL_ROOT_PASSWORD=123 \
-v /home/descfly/桌面/mysql/data:/var/lib/mysql \
-v /home/descfly/桌面/mysql/init:/docker-entrypoint-initdb.d \
-v /home/descfly/桌面/mysql/conf:/etc/mysql/conf.d \
mysql

执行上面的命令后,然后去刚才创建的文件夹中查看:

在这里插入图片描述
可以看到挂载成功了!此时在宿主机挂载的目录操作,比如修改文件,增加文件,对应的容器也就有了同样的操作!
备注:如果把容器删除,映射的目录是不会删除的,如果往刚才的目录中加入一个文件,再把容器删除,如果下次,映射的目录一样,依然会被挂载。这就方便我们保存数据,而不会因为容器删了数据就丢失了。

十、如何制作镜像

镜像就是包含了应用程序、程序运行的系统函数库,运行配置等文件的文件包,构建镜像的过程其实就是把上述文件打包的过程。
在这里插入图片描述

10.1 Dockfile文件

在这里插入图片描述
Dockerfile是一个创建镜像所有命令的文本文件,包含了一条条指令和说明, 每条指令构建一层,,通过docker build命令,根据Dockerfile的内容构建镜像,因此每一条指令的内容, 就是描述该层如何构建。有了Dockefile,,就可以制定自己的docker镜像规则,只需要在Dockerfile上添加或者修改指令,,就可生成docker 镜像。
详细指令如下:

Dockerfile 指令选项:FROM                  #基础镜像 。 (centos)
MAINTAINER            #镜像的作者和邮箱。(已被弃用,结尾介绍代替词)
RUN                   #镜像构建的时候需要执行的命令。
CMD                   #类似于 RUN 指令,用于运行程序(只有最后一个会生效,可被替代)
EXPOSE                #对外开放的端口。
ENV                   #设置环境变量,定义了环境变量,那么在后续的指令中,就可以使用这个环境变量。
ADD                   # 步骤:tomcat镜像,这个tomcat压缩包。添加内容。
COPY                  #复制指令,将文件拷贝到镜像中。
VOLUME                #设置卷,挂载的主机目录。
USER                  #用于指定执行后续命令的用户和用户组,这边只是切换后续命令执行的用户(用户和用户组必须提前已经存在)。
WORKDIR               #工作目录(类似CD命令)。
ENTRYPOINT            #类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,会追加命令。
ONBUILD               #当构建一个被继承Dokcerfile,就会运行ONBUILD的指令。出发执行。注意:CMD类似于 RUN 指令,用于运行程序,但二者运行的时间点不同:
CMD 在docker run 时运行。
RUN 是在 docker build。
作用:为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。
CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。
如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。LABEL(MAINTALNER已经被弃用了,目前是使用LABEL代替)
LABEL 指令用来给镜像添加一些元数据(metadata),以键值对的形式,语法格式如下:
LABEL <key>=<value> <key>=<value> <key>=<value> ...
比如我们可以添加镜像的作者:
LABEL org.opencontainers.image.authors="runoob"
10.2 制作hellodocker镜像

1.创建项目文件结构

mkdir cpp-docker-demo
cd cpp-docker-demo

2.编写c++程序
hello.cpp

#include <iostream>
int main() 
{std::cout << "Hello Docker!" << std::endl;return 0;
}

3.创建Dockerfile文件
Dockerfile:

#使用官方 GCC 镜像作为基础
FROM gcc:latest#设置工作目录
WORKDIR /usr/src/app#将当前目录下的文件复制到容器的工作目录
COPY . .#编译程序
RUN g++ hello.cpp -o hello.exe #设置容器启动时运行的命令
CMD ["./hello.exe"]

4.构建Docker镜像

sudo docker build -t cpp-hello .

在这里插入图片描述
这一步如果首次构建会耗时较长
5.运行刚才创建的镜像,让它成为一个容器
–rm 运行完退出容器
在这里插入图片描述

十一、网络

安装docker的时候,就会在虚拟机创建一张虚拟网卡:docker0;容器之间能访问就是它们有相同的网关,并且会给这个网卡创建一个虚拟的网桥。
在这里插入图片描述
按理来说新建的容器之间已经能够互通了,其实是不对的,因为容器的IP是docker分配的,如果服务重启,IP地址可能就变了,那如何解决呢???
解决办法:自定义网络
在这里插入图片描述
注意:如果容器名能访问,那IP变不变就无所谓了,从而解决了问题!
如果创建了自定义网络,就会形成一个新的网桥,会形成一个新的网段,加入该网段的容器就能相互访问。
创建一个网络:tyNet

sudo docker network create tyNet

将容器加入tyNet

sudo docker network connect tyNet mysql

也可以再创建的时候直接加入网络,例如

sudo docker run -d --name nginx_ty -p 8080:8080 --network tyNet nginx 

此时进入容器,

sudo docker exec -it nginx_ty bash

然后进行ping命令:ping mysql

总结:容器加入自定义网络就可以通过容器名互相访问,但是默认网络不可以通过容器名进行互相访问。

十二、DockerCompose

在这里插入图片描述
在这里插入图片描述
多容器示例:
在这里插入图片描述

在这里插入图片描述

那如何使用该文件?
在这里插入图片描述

参考:
docker的架构及工作原理(详解)
太全了|万字详解Docker架构原理、功能及使用

http://www.dtcms.com/a/325900.html

相关文章:

  • Excel 连接阿里云 RDS MySQL
  • AAAI-2025 | 北理工具身导航新范式!FloNa:基于平面图引导的具身视觉导航
  • Dashboard.vue 组件分析
  • CLIP在文生图模型中的应用
  • 《范仲淹传》读书笔记与摘要
  • sqli-labs通关笔记-第42关 POST字符型堆叠注入(单引号闭合 手工注入+脚本注入两种方法)
  • pdf转word教程
  • ERA5---MATLAB处理水汽数据与臭氧数据的读取与重采样-重复性工作
  • 基于模型预测控制的主蒸汽温度单步预测MATLAB实现
  • 大数据系统架构模式:驾驭海量数据的工程范式
  • 蓝桥杯算法之搜索章 - 4
  • 基于领域事件驱动的微服务架构设计与实践
  • 鸿蒙Des 加密解密 C++版本
  • POI导入时相关的EXCEL校验
  • 使用行为树控制机器人(三) ——通用端口
  • Python面试题及详细答案150道(41-55) -- 面向对象编程篇
  • 《基于Redis实现高效消息队列的完整指南》
  • 在 RHEL9 上搭建企业级 Web 服务(Tomcat)
  • Java Selenium 自动打开浏览器保存截图
  • Spring Cloud系列—Gateway统一服务入口
  • 案例分析2:上层应用不稳定提示注册失败
  • Python(9)-- 异常模块与包
  • CLIP,BLIP,SigLIP技术详解【二】
  • Flink + Hologres构建实时数仓
  • 机器学习:基于OpenCV和Python的智能图像处理 实战
  • 【05】昊一源科技——昊一源科技 嵌入式笔试, 校招,题目记录及解析
  • 提示词注入攻防全解析——从攻击原理到防御浅谈
  • gophis钓鱼
  • 深入解析 resolv.conf 文件:DNS 配置的核心
  • 区间修改 - 差分