docker

docker原理

docker虚拟技术的一种,早年虚拟机比较重,系统需要启动一个模拟器模拟整个系统环境, 消耗的资源大,启动也慢。那么docker是如何做到这点的呢?

  1. 联合文件系统(UnionFS): 联合文件系统(Union File System,简称 UnionFS)是一种特殊的文件系统,它能够将多个独立的文件系统“联合”挂载到同一个挂载点上,使得用户可以如同访问一个统一的文件系统那样访问来自不同源的数据。在联合文件系统中,每个单独的文件系统称为一个“层”,这些层按照一定顺序堆叠在一起,形成一个虚拟的文件层次结构,其中顶层(即工作层)通常是可读写的,而下面的层一般是只读的。
    • 主要就是卷的实现,我们在docker文件中能将里面的文件映射到宿主机上,这点就是联合文件系统的实现
    • 然后就是分层,因为分层反而优化了docker的结构,我们把docker当作一个项目,功能分层提高了项目的复用率,相当于模块化思想。
  2. 命名空间(namespace): 操作系统级别的资源隔离,可以参考nacos的命名空间等意义,里面细分还有挂载命名空间,网络命名空间,用户ID明空空间,进程命名空间等,这些加起来就形成了docker运行的边界。
  3. cgroup:是Linux内核提供的一种机制,用于限制、记录和隔离进程组所使用的物理资源(如CPU、内存、磁盘I/O等)。cgroups通过将一系列进程组织成任务组(task groups),然后对这些任务组整体进行资源管控,实现了操作系统层面的资源管理和调度优化。后续docker-compose以及后来的K8S都是靠这个实现。

以上都是linux的内核具有的,并不是docker发明出来的,docker是利用发掘。所以为docker对内核版本有要求。

docker组件

docker整体包含如下组件:
在这里插入图片描述我们在命令行操作就是用上了docker客户端
他后台还运行了dockerd进程(模块),执行处理
他有是调用的containerd----->可以当他是接口规范
containerd模块会调用他适配器docker-shim(适配器是我的理解,并不是官方的,早期没这个东西直接对接的实现runc)
最后就是runc,正真执行。
在这里插入图片描述

docker常用命令行

Docker 基本命令

只列举常用命令 docker命令都是docker开头

镜像 image
docker image ls 查看
docker pull ubuntu 下载ubuntu镜像
docker rmi centos 删除centos镜像

容器 这里的container都可以 但是为了方便直接用ps代替了此命令
docker container ls == docker ps 查看正在运行的容器
docker ps -a 产看运行过得容器
docker restart containerId 重新运行启动过的容器
dcoker rm containerId 删除容器如果是正在运行的加-f
docker rm $(docker ps -aq) 删除所有的容器 docker ps -aq查看所有的容器的id ,这个用法相当于linux管道符
docker run container 启动容器
docker run -itd containerId /bin/bash 启动容器打开终端 但是不进入终端
it 打开终端 -d不进入容器 /bin/bash进入容器的地方,就相当于打开容器的首起命令
docker exec -it containerId common 重新进入容器 这个进入时重新打开一个终端
docker attach containerId 进入容器 落入旧的命令 和上面的区别也就是这

日志
docker logs -f my_container
docker logs --tail 10 my_container

其他操作
docker inspect container 查看 容器的详细信息
docker cp containerId:feilPath filePath 将docker容器中的数据复制到本机

docker 排查
假设现在docker 出问题了,你是不是得知道docker的信息:
docker inspect : 查看容器详细信息
docker info:查看 docker全局信息
docker history:查看构建历史信息 镜像

docekr 卷

在Docker中,卷(Volume)是独立于容器生命周期之外,专门用来持久化数据的存储区域。当你创建一个Docker卷时,Docker实际上是在主机上创建了一个数据存储位置。这个数据存储位置可以被容器内部的文件系统挂载,用于持久化容器中的数据,即使容器被删除,卷中的数据依然保留。

翻译过来就是,我想给容器指定一个存储东西的地方。怎么指定,那就是创建卷。
//创建一个卷(docker规定如果带/这种就会找具体的路劲,如果知识一个名字就会在docker分配的文件夹新建一个目录aaa )
docker volume create aaa
//将卷挂载
docker run -itd -p 8080:8080 -v /usr/local/apache-tomcat-8.0.23/webapps hmtomcat:v1.0 /bin/bash

docker 网络

brige:
在这里插入图片描述
自定义网络的区别:可以根据dns解析host
如果启动就制定网络就是container2.如果是后续添加就是container1,会产生两个IP
在这里插入图片描述
host:
在这里插入图片描述
container
在这里插入图片描述
自定义网络驱动类型:macvlan:增加一层网络 前提两台物理机要通
在这里插入图片描述
自定义网络驱动类型:overlay: 前提两台物理机要通,访问外部走实体网络,走内部用内部网络。
那么问题来了?他怎么知道内部和外部?这些网络形成的时候会在本地挂个路由,通过路由就可以识别是否需要走外网。
在这里插入图片描述

dcokerFile

dockerFile:每一个dockerFile命令都是一层镜像,所以很多人而上来直接上来就是多个run合并成一个run
这其实必要性不强,因为镜像是差异化的体现,你在A镜像上增加一条指令,因此多了一层镜像
,但是这层新镜像并不包含所有A的内容,而是依赖于A新增的差异化内容
因此对镜像的优化是在减少构建时间和体积,而不是仅仅是理论。

其中最重要的是dockerFile命令:
第一行:
FROM: FROM name:tag
这里的重点多阶段构建:from 可以来自上阶段 也可以来自本地 。多阶段构建不写就是默认第一阶段为0

   复制:ADD能替代COPY为何还要COPY,因为ADD太强大了(自动解压,从网络下下载,下载没有验证步骤),如果安全要求严格,反而不推荐用
        ADD: 复制目标文件(本地,url),文件到指定镜像目录中。包含自动解压功能
        COPY: 与ADD的区别就是不能从URL获取,也没有自带解压功能
    
    运行:
        RUN: 在镜像构建时候运行指令。重点:镜像构建时

        这两语法一样:带中括号,是在 exec form模式限执行,不带中括号就是在shell from模式下执行。
        ENTRYPOINT: 容器启动执行命令,容器启动命令后面如果有入参,就是ENTRYPONIT的执行入参。
        CMD: 容器启动执行命令,容器启动命令后面如果有入参,就是覆盖CMD的命令。

    环境信息:
        LABEL: 标签用处不大
        USER: 也是打标签用处不大
        ENV:  设置环境变量
        WORKDIR: 设置工作目录
        
     触发器:
        ONBUILD:  ONBUILD 它后面跟的是其它指令,比如 RUN, ADD 等,这些指令在当前镜像构建时并不会被执行,只有以当前镜像为基础镜像,去构建下一级镜像的时候才会被执行。

     暴露:
        EXPOSE: 指定暴露给主机的端口,主机可以ping通,但是和映射是两回事
        VOLUMES: 挂在卷

然后就是根据dockerfile build docker容器
docker build -t 镜像名:标签 -f dockerfile文件路劲 .
docker build -t 镜像名:标签 -f dockerfile文件路劲 -no-cache .
no-cache代表不从缓存构建。

多阶段构建

主要目的就是为了减少不必要的临时过渡阶段,比如B模块依赖A模块,你首先要编译A,然后 B from A。
但是呢A在生成过程中包含的大量的组件工具,我只需要A编译好的结果哪些工具组件对于我B来说没用啊

这时候多阶段构建就体现作用了,我需要拿取我想要的那部分,精简体积,正真的模块化。

//第一阶段:构建阶段
FROM maven:3.8-openjdk-11 AS builder
//设置工作目录并拷贝源码
WORKDIR /app
COPY . .
//运行Maven打包,生成JAR文件
RUN mvn clean package
//第二阶段:运行阶段
FROM openjdk:11-jre-slim
//创建应用的工作目录
WORKDIR /app
//从构建阶段拷贝打包好的JAR文件到运行阶段的镜像中
COPY --from=builder /app/target/my-app.jar /app/app.jar
//设置容器启动时运行的命令
CMD [“java”, “-jar”, “/app/app.jar”]
//(可选)暴露端口
EXPOSE 8080

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值