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

一文快速了解Docker和命令详解

本文让你快速了解Docker是什么的东西,在我们程序开发的时候到底有什么作用,为什么需要去学习它。本文章只是做一个简单的概述配套黑马课程让你快速了解、使用Docker。

一、什么是Docker?

Docker是一个开源的容器化平台,允许开发者把应用和其所有的依赖项打包成一个单独的标准化单元(即容器),并且可以在任何支持Docker环境下运行,相当于一次部署,终生运行。通过Docker部署,开发者就可以避免由电脑环境不一致导致——编写的程序自己电脑可以运行,部署到别人的电脑就不可以运行。它使得应用在不同的计算环境中具有更高的一致性,减少了环境配置和依赖管理的问题。

如何理解这段话呢?就是相当于,一个容器就是一台电脑,每个电脑可以安装相应的依赖项。所以说他是一个独立的环境,那么为什么说可以在任何支持Docker环境下运行,因为所有依赖都在Docker部署容器里面,只要支持Docker环境,Docker容器技术就可以根据程序所需要依赖自动实现部署。但是有个问题每个容器都需自己下载依赖吗?有没有一个统一的像Maven库一样,只需要一次下载,后续其他容器无需下载直接安装?

二、Docker 的主要组成部

  1. Docker 引擎(Docker Engine):Docker 引擎是 Docker 的核心组件,负责构建、运行和管理容器。它分为两部分:
    • Docker Daemon:后台服务,管理容器的生命周期。
    • Docker CLI(命令行界面):用户与 Docker 交互的命令行工具。
  2. 镜像(Image):镜像是构建 Docker 容器的模板,包含运行应用所需的操作系统、库、依赖和应用本身。镜像是不可变的,一旦创建便不会改变。
  3. 容器(Container):容器是镜像的一个实例,它运行在 Docker 引擎上。容器具有轻量性、可移植性和隔离性。
  4. Docker Hub:一个公共的 Docker 镜像仓库,提供了大量的公共镜像(例如:nginx、mysql 等),用户也可以将自己创建的镜像上传到这里。
  5. Dockerfile:是一个文本文件,包含了一系列指令,用来描述如何构建 Docker 镜像。通过 Dockerfile,开发者可以自动化地构建镜像。

镜像就是容器的一个运行环境,不仅仅包括依赖和应用本身,还包括可以自己设置容器的操作系统等,其中Docker Hub,就是我之前第一段提出的问题——有没有一个统一的像Maven库一样,只需要一次下载,后续其他容器无需下载直接安装?Docker Hub就是解决这个问题的,提供了大量的公共镜像(例如:nginx、mysql 等),用户也可以将自己创建的镜像上传到这里。

三、Docker的基础

3.1.1 常见的命令

命令说明文档地址
docker pull拉取镜像docker pull
docker push推送镜像到 Docker Registrydocker push
docker images查看本地镜像docker images
docker rmi删除本地镜像docker rmi
docker run创建并运行容器(不能重复创建)docker run
docker stop停止指定容器docker stop
docker start启动指定容器docker start
docker restart重新启动容器docker restart
docker rm删除指定容器docker rm
docker ps查看容器docker ps
docker logs查看容器运行日志docker logs
docker exec进入容器docker exec
docker save保存镜像到本地压缩文件docker save
docker load加载本地压缩文件到镜像docker load
docker inspect查看容器详细信息docker inspect

详细的说明可以去命令文档

3.1.2 图解Docker命令

在这里插入图片描述

  • docker pulldocker push 表明可以从官方的镜像仓库中拉取和上传镜像到本地
  • docker savedocker load 表明也可以从自己虚拟机中加载虚拟机内的镜像。(Docker一般是部署到虚拟机内)
  • DOCKERFILE ,是定义镜像构建过程的脚本文件,里面描述了基础镜像、安装软件、拷贝代码、暴露端口等操作。这块后面和提及到,其命令 docker build 是 然后按照文件里的指令,一步步生成一个新的 Docker 镜像
  • docker images 表示可以查看自己的镜像,docker rmi 表示删除自己的镜像
  • docker run 表示运行一个容器,配置镜像相关的配置文件挂载
  • 其中命令在上面已经很详细的介绍了
示例命令流程(以Nginx为例)
# 第1步,查看Nginx镜像
https://hub.docker.com/_/nginx# 第2步,拉取镜像
docker pull nginx# 第3步,查看镜像
docker images# 第4步,运行容器
docker run -d --name nginx -p 80:80 nginx# 第5步,查看容器
docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"# 第6步,访问网页
http://<虚拟机地址># 第7步,停止容器
docker stop nginx# 第8步,查看所有容器
docker ps -a --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"# 第9步,重新启动容器
docker start nginx# 第10步,查看详情
docker inspect nginx# 第11步,进入容器
docker exec -it nginx bash# 第12步,删除容器
docker rm -f nginx

3.2.1 数据卷

数据卷是Docker提供的一种持久数据化的机制,当容器被删除的时候,里面数据文件(日志、数据库数据)也全部删除,而且一般想打开容器中的文件,都是需要命令行,这样操作起来很不方便,数据卷就是解决这些问题的,它可以实现将容器中的文件与部署的虚拟机的文件建立映射关系,也被称做挂载。

举一个Nginx的例子,挂载Nginx配置和HTML目录
docker run -d \--name nginx \-p 80:80 \-v /host/html:/usr/share/nginx/html \-v /host/nginx.conf:/etc/nginx/nginx.conf \nginx
  • html:放置一些静态资源
  • conf:放置配置文件

如果我们要让Nginx代理我们的静态资源,最好是放到html目录;如果我们要修改Nginx的配置,最好是找到conf下的nginx.conf文件。

但遗憾的是,容器运行的Nginx所有的文件都在容器内部。所以我们必须利用数据卷将两个目录与宿主机目录关联,方便我们操作。如图:

相当于把Nginx容器中的目录文件和宿主机(虚拟机)建立联系,这样我修改宿主机的文件就相当于修改Nginx容器中的文件。

注意:/var/lib/docker/volumes这个目录就是默认的存放所有容器数据卷的目录,也再根据数据卷名称创建新目录,格式为/数据卷名/_data

其实不建议指定宿主机的自定义目录,这样就和宿主机建立强耦合,换一台宿主机就需要保证有这个自定义目录

在这里插入图片描述

数据卷常用命令
命令说明文档地址
docker volume create创建数据卷docker volume create
docker volume ls查看所有数据卷docs.docker.com
docker volume rm删除指定数据卷docs.docker.com
docker volume inspect查看某个数据卷的详情docs.docker.com
docker volume prune清除数据卷docker volume prune

3.3 镜像

镜像这里我们之前也说了,这里主要是讲一下,我们该怎么把我写好的程序或者项目打包成镜像上传到Docker

3.3.1 镜像结构

Docker镜像是由多层结构组成的,每一层代表镜像构建过程中的一个步骤。它使用的是一种叫UnionFS(联合文件系统)的技术。

镜像是一堆文件的集合,但是这些文件不是随便放的,而是需要根据操作步骤进行叠放起来,形成一个逻辑上的文件系统。通常是通过Dockerfile文件创建的,而Dockerfile文件每一条命令(如RUN、COPY、ADD)都会创建一层。

在这里插入图片描述

为什么要采用分层结构,其实这样是为了共享公共层,**例如:**当我们需要构建一个 Java 应用的镜像时,第一步通常是基于某个 Linux 系统镜像(比如 Ubuntu、Alpine)作为基础层。如果我们已经有这个 Linux 层,那么在构建 Java 镜像时,就可以直接在这个公共基础层上“叠加” Java 运行环境和应用层。

3.3.2 Dockerfile

Dockerfile 是用于构建镜像的脚本文件,里面定义了如何一步步构建镜像,每一条指令都会生成镜像的一层。

Dockerfile 示例:SpringBoot项目
# 使用官方 Java 运行时基础镜像
FROM openjdk:17-jdk-slim# 设置工作目录
WORKDIR /app# 将打包后的 jar 文件复制到容器中
COPY target/springboot-docker-demo-0.0.1-SNAPSHOT.jar app.jar# 容器启动时运行 Spring Boot 应用
ENTRYPOINT ["java", "-jar", "app.jar"]# 可选:声明端口(不代表实际映射)
EXPOSE 8080

3.4 网络

前面说了,Docker容器相当于一个计算机,那么如何实现容器之间的通信,这里就需要借助Docker网络,用于管理容器之间的通信,大致流程:

  • Docker 启动时会创建一个虚拟网桥(docker0);
  • 每个容器都会分配一个虚拟网卡(veth pair);
  • Docker 通过 NAT(iptables)转发容器网络请求;
  • 内部使用 libnetwork 管理网络驱动、端点等资源。
常见的命令
命令说明文档地址
docker network create创建一个网络docker network create
docker network ls查看所有网络docs.docker.com
docker network rm删除指定网络docs.docker.com
docker network prune清除未使用的网络docs.docker.com
docker network connect使指定容器连接加入某网络docs.docker.com
docker network disconnect使指定容器连接离开某网络docker network disconnect
docker network inspect查看网络详细信息docker network inspect

在一个集成了 Spring Boot、MySQL、Redis、Nginx 等组件的项目中,如果将每个服务都分别封装为独立的容器,那么为了确保它们之间能够正常通信,我们通常会为该项目创建一个自定义 Docker 网络。这样一来,所有相关服务容器都可以在该网络中通过容器名互相访问,同时也实现了与其他项目或容器的网络隔离,提高了系统的安全性和可维护性。

四、项目部署例子

当我们需要部署一个 Spring Boot、MySQL、Redis、Nginx项目,我们可以借助docker-compose.yml(这个创建每个容器的命令和加入相同的网络)

version: '3.8'services:mysql:image: mysql:8.0container_name: mysqlenvironment:MYSQL_ROOT_PASSWORD: rootMYSQL_DATABASE: mydbMYSQL_USER: userMYSQL_PASSWORD: passports:- "3306:3306"volumes:- mysql_data:/var/lib/mysqlnetworks:- backendredis:image: redis:7container_name: redisports:- "6379:6379"networks:- backendspringboot:build:context: ./appdockerfile: Dockerfilecontainer_name: springbootdepends_on:- mysql- redisports:- "8080:8080"environment:SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/mydbSPRING_DATASOURCE_USERNAME: userSPRING_DATASOURCE_PASSWORD: passSPRING_REDIS_HOST: redisnetworks:- backendnginx:image: nginx:latestcontainer_name: nginxports:- "80:80"volumes:- ./nginx/default.conf:/etc/nginx/conf.d/default.confdepends_on:- springbootnetworks:- backendvolumes:mysql_data:networks:backend:driver: bridge

五、小结

  • Docker 解决了应用跨平台部署问题
  • 容器技术让环境隔离、安全、可复制
  • 使用 Docker Compose 可轻松构建多服务架构
  • 镜像构建、数据卷管理、网络配置是核心技能
http://www.dtcms.com/a/300993.html

相关文章:

  • 模拟实现python的sklearn库中的Bunch类以及 load_iris 功能
  • 文件权限标记机制在知识安全共享中的应用实践
  • minio 对象存储
  • java的break能加标签,return可以加标签吗
  • 从一副蓝牙耳机里get倍思的“实用而美”
  • Python 程序设计讲义(23):循环结构——循环控制语句 break 与 continue
  • 背包DP之多重背包
  • 边缘提取算法结合深度学习的肺结节分割预测
  • 「日拱一码」040 机器学习-不同模型可解释方法
  • 【机器学习】第七章 特征工程
  • 【机器学习-3】 | 决策树与鸢尾花分类实践篇
  • 探索 Linux 调试利器:GDB 入门与实战指南
  • 在分布式的远程调用中proxy和stub角色区别
  • C++ 多线程 std::thread::get_id
  • 数独求解器与生成器(回溯算法实现)
  • Python|OpenCV-实现对颜色进行检测(22)
  • PandasAI连接LLM进行智能数据分析
  • qt常用控件-06
  • 【人工智能】【Python】各种评估指标,PR曲线,ROC曲线,过采样,欠采样(Scikit-Learn实践)
  • PAT 甲级题目讲解:1010《Radix》
  • Spring之【Bean的生命周期】
  • [AI8051U入门第十一步]W5500-服务端
  • Linux实战:从零搭建基于LNMP+NFS+DNS的WordPress博客系统
  • (10)数据结构--排序
  • 设计模式(八)结构型:桥接模式详解
  • k8s的权限
  • Python队列算法:从基础到高并发系统的核心引擎
  • Cline与Cursor深度实战指南:AI编程助手的革命性应用
  • 【Canvas与标牌】优质资产六角星标牌
  • Java面试全方位解析:从基础到AI的技术交锋