Docker

文章详细介绍了Docker如何解决微服务在分布式系统中遇到的依赖冲突和操作系统环境差异问题。通过打包应用及其依赖到容器中,Docker实现了服务的隔离运行,消除了不同系统函数库的不兼容性。此外,对比了Docker与虚拟机的区别,强调了Docker在轻量级、快速启动和性能方面的优势。文章还涵盖了Docker的基本操作,如镜像的创建、管理,容器的运行、管理和数据卷的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、微服务出现的问题

微服务虽然具备很大的优势,但它的劣势一样很明显,服务的拆分通用给服务的部署带来了很大的麻烦。

  • 分布式系统中,需要依赖的组件非常多,不同组件的部署往往会产生冲突,

产生兼容性的问题。

  • 而且,在不同的服务器重复部署时,服务器的环境不一定一致,也会遇到各种问题。

  • 开发、测试、生产环境有差异环境的不同,甚至相同的服务可能会部署到不同的系统环境中。

如相同的服务部署到了CentOS、Ubuntu、Fedora系统中。

  • 例如下面的项目中,部署时需要依赖于node.js、Redis、RabbitMQ、MySQL等,

  • 这些服务部署时所需要的函数库(Lib)、依赖项(depe)各不相同,甚至会有冲突。

  • 甚至部署不同的操作环境中(CentOS、Ubuntu、Fedora)。

在这里插入图片描述

1,Docker解决依赖,函数兼容问题

不同的服务可能需要不同的依赖与函数库。如node.js、Redis、RabbitMQ、MySQL等。

为了解决这个问题,Docker将应用的Libs(函数库)、Deps(依赖)、配置与应用一起打包。

同时将每个服务放到一个隔离容器去运行,防止相互干扰。

在这里插入图片描述

  • 如上图所示:
    • 打包好的服务不仅包含组件本身,也包含组件需要的函数库与依赖。
    • 每个组件相互之间又是隔离的,避免了干扰。

2,.Docker解决操作系统环境差异

在上面,Docker解决了不同组件的兼容问题。

但是,开发,测试,运行环境的差异如何改变。当操作环境不同时,相同的服务如何正常的运行。

2.1,了解操作系统结构
  • 结构包含:计算机硬件,系统内核,系统应用

在这里插入图片描述

  • 计算机硬件:CPU,内存,磁盘

  • 系统内核:无论是CentOS、Ubuntu、Fedora,系统内核都是Linux。

  • 系统应用:操作系统本身提供的函数库。

2.2,如何解决系统环境差异

由此可知,无论是什么系统应用,他们的内核都是一样的。

相同的应用在不同的系统之所以不兼容,是因为不同系统的函数库不一致。

如,将一个Ubuntu版本的MySQL应用安装到CentOS系统,MySQL在调用Ubuntu函数库时,会发现找不到或者不匹配,就会报错了。

Docker提供了解决的办法:

  • Docker将用户程序与所需要调用的系统(比如Ubuntu)函数库一起打包。

  • 当需要对应的函数与系统内核交互时,直接使用本地(自己打包)的函数库,

不在需要系统应用本身提供的函数库了。

2.3,总结:

​ 对于操作系统而言,是【部署的服务】调用【系统应用自身函数】,【系统应用】调用【系统内核】,

【系统内核】操作【计算机硬件】。

​ 当【服务】部署到不同的系统环境时,因为【系统应用自身函数】不同,导致【服务】在访问【系统应用】

时会因为函数不同而失败。

​ 所以Docker想了一个办法,不使用【系统应用自身函数】,将需要的【系统函数】与【服务】一起打包。

​ 于是步骤变成了,【服务】通过访问【自身打包的函数(本地函数)】直接与【系统内核】交互,因为系统内核是一样的,就不存在系统环境差异的问题了。

说白了,Docker镜像中包含完整运行环境,包括系统函数库,仅依赖系统的Linux内核,因此可以在任意Linux操作系统上运行

3,Docker和虚拟机的区别

Docker可以让一个应用在任何操作系统中非常方便的运行。而以前我们接触的虚拟机,也能在一个操作系统中,运行另外一个操作系统,保护系统中的任何应用。

两者有什么差异呢?

虚拟机(virtual machine)是在操作系统中模拟硬件设备,然后运行另一个操作系统,比如在 Windows 系统里面运行 Ubuntu 系统,这样就可以运行任意的Ubuntu应用了。

Docker仅仅是封装函数库,并没有模拟完整的操作系统,如图:

在这里插入图片描述

对比来看:

在这里插入图片描述

小结:

Docker和虚拟机的差异:

  • docker是一个系统进程;虚拟机是在操作系统中的操作系统

  • docker体积小、启动速度快、性能好;虚拟机体积大、启动速度慢、性能一般

二、Docker结构

镜像(Image):Docker将应用程序及其所需的依赖、函数库、环境、配置等文件打包在一起,称为镜像。

容器(Container):镜像中的应用程序运行后形成的进程就是容器,只是Docker会给容器进程做隔离,对外不可见。

可以理解为,镜像就是一个类,而容器就是类创建的对象。

一个类可以创建多个对象,且各个对象之间没有关联。

Docker开启多个服务的原理:

以MySQL为例,如何使用Docker创建多个MySQL。

  • 在Docker使用MySQL镜像创建两个MySQL。

  • 两个MySQL的端口是一样了。

  • 但是在Linux系统中两个MySQL对应的端口是不一样的。

  • 因为只有宿主机才可以访问Docker,而我们可以访问宿主机。

  • 如,第一个MySQL映射的端口是80

​ 第一个MySQL映射的端口是81

在这里插入图片描述

三、Docker操作

docker run -d -p 81:8080 --name tomcat81 tomcat:8.5.13

  • 【-d】

    • 后台运行
  • 【-p 81:8080】

    • 端口,tomcat端口8080对应的Linux端口81

    • 81端口是唯一的

  • 【–name tomcat81 tomcat:8.5.13】

    • 创建的tomcat名为tomcat81 ,唯一
    • tomcat:8.5.13,表示要下载的tomcat版本

1,镜像指令

1.0,概述
  • 镜像是一个文件

  • Docker将应用程序以及所需要的依赖库函数库环境配置文件等文件打包在一起,

形成的文件就是镜像。

  • 镜像由两部分组成:
  • 镜像名称:镜像版本
  • 如:【mysql:5.7.25】、【tomcat:8.5.13】
1.1,查看本地镜像
  • docker images
1.2,搜索镜像

docker search 镜像名称

  • 需要联网,搜索网上的镜像

  • 在这里插入图片描述

1.3,拉取镜像

docker pull 镜像名称:版本号

1.4,导出镜像成为一个tar文件

docker save -o [保存的目标文件名称] [镜像名称:版本号]

  • 例如:【docker save -o nginx.tar nginx:latest】
  • 一般建议拉取的镜像保存的文件后缀为【.tar】
  • 【-o】表示output
1.5,删除镜像

docker rmi 镜像ID或者镜像名称

  • docker rmi nginx:latest
  • 通过镜像名:镜像版本删除
  • 删除前一定要将容器停止
  • rmi:【remove image】
1.6,导入镜像

docker load -i 镜像文件

  • 【-i】:input
  • 镜像文件就是1.4导出的。
1.7,为镜像命名

如果导入的镜像没有名称,可以手动为其命名:

  • 一个没有名称的镜像,被叫做虚悬镜像
  • docker tag 镜像ID 镜像名称:镜像版本
  • docker tag 605c77e624dd nginx:latest
1.8,案例

拉取redis:3.2.10镜像,并导出到本地,再删除redis镜像,再导入

  • docker pull redis:3.2.10
  • docker save -o redis:3.2.10.tar redis:3.2.10
  • docker rmi redis:3.2.10
  • docker load -i redis:3.2.10.tar

2,容器指令

2.1,运行容器

docker run -d -p 宿主机端口:容器端口 --name 容器名称 -v 宿主机目录:容器目录 --rm --restart=always 镜像ID或者镜像名称

docker run -d -p 80:80 --name nginx -v /opt/nginx/html:/usr/share/nginx/html -v /opt/nginx/nginx.conf:/etc/nginx/nginx.conf 镜像ID

  • 注意:【–rm 跟 --restart 不能同时使用
  • 【-d】:表示后台运行
  • 【-p】:端口映射
  • 【–name】:指定容器的名称(唯一)
  • 【-v】:数据卷映射
  • 【–rm】:停止容器后删除容器(–rm 跟 --restart 不能同时使用)
  • 【–restart=always】:重启容器的方式,always表示重启Docker的同时重启容器

在这里插入图片描述

2.2,查看容器
  • 查看正在运行的容器:【docker ps】

  • 查看所有的容器(包含停止的):【docker ps -a】

  • 查看正在运行的容器的id:【docker ps -q】

  • 查看所有容器的id:【docker ps -aq】

2.3,停止容器
  • 停止容器:【docker stop 容器id&容器名】

  • 停止所有的容器:【docker stop $(docker ps -aq)】

2.4,启动容器
  • 启动容器:【docker start 容器id&容器名】

  • 可以开启多个容器,使用空格分开:【docker start 容器id&r容器名 容器id&r容器名 …】

2.5,重启容器
  • 重启容器:【docker restart 容器id&r容器名】
2.6,删除容器
  • 删除容器前必须先停止容器

  • 删除容器:【docker rm 62efeb9922d4】

  • 删除所有容器:【docker rm $(docker ps -aq)】

2.7,进入与退出容器
  • 进入容器:【docker exec -it 容器ID或容器名称 bash】

  • docker exec :进入容器内部,执行一个命令

  • -it : 给当前进入的容器创建一个标准输入、输出终端,允许我们与容器交互

  • bash:进入容器后执行的命令,bash是一个linux终端交互命令

  • 退出容器:【exit】

2.8,查看docker日志
  • 查看docker日志:【docker logs 容器ID或容器名称】

3,数据卷指令

3.1,概述

可以让宿主机的目录和容器中的目录形成映射关系,实现共享数据。

数据卷的本质就是一个目录。

创建的数据卷都放在【/var/lib/docker/volumes/…】

在这里插入图片描述

3.2,创建数据卷

docker volume create 数据卷名称

3.3,查看数据卷信息

docker volume inspect 数据卷名称

3.4,查看全部数据卷

docker volume ls

3.5,删除数据卷
  • 只能删除没有被容器引用的数据卷
  • 删除全部:【docker volume prune】
  • 删除指定的数据卷:【docker volume rm 数据卷名称】
3.6,创建容器时挂载数据卷
  • 方法一:
  • 先创建数据卷、再通过名称挂载
  • 如果数据卷不存在,则会自动创建
  • 方法二:
  • 直接以目录的方式挂载
  • 如果映射的宿主机目录不存在,则会自动创建

方法一例子:

============================================

docker run -d \

-p 3306:3306 \

–name mysql3306 \

-v mysql_conf:/etc/mysql/conf.d/ \

-v mysql_data:/var/lib/mysql \

-e MYSQL_ROOT_PASSWORD=123456 \

mysql:5.7.25

============================================

docker run -d \

-p 3306:3306 \

–name mysql3306 \

-v mysql_conf:/etc/mysql/conf.d/ \ 【数据卷mysql_conf映射/etc/mysql/conf.d/】

-v mysql_data:/var/lib/mysql \

-e MYSQL_ROOT_PASSWORD=123456 \

mysql:5.7.25

方法二例子:

==============================================

docker run -d
–name mysql3306
-p 3306:3306
-v /tmp/mysql/conf/hmy.cnf:/etc/mysql/conf.d/hmy.cnf
-v /tmp/mysql/data:/var/lib/mysql
-e MYSQL_ROOT_PASSWORD=123456
mysql:5.7.25

================================================

docker run -d
–name mysql3306
-p 3306:3306
-v /tmp/mysql/conf/hmy.cnf:/etc/mysql/conf.d/hmy.cnf
-v /tmp/mysql/data:/var/lib/mysql
-e MYSQL_ROOT_PASSWORD=123456
mysql:5.7.25

四、自定义镜像Dockerfile

0,概述

1,语法

https://docs.docker.com/engine/reference/builder

在这里插入图片描述

2,例子

构建Java项目为自定义镜像并运行

  • 0,上传资料中的 docker-demo.jar 到服务器

  • F:\java\上课视频4\后面资料\3-Docker\资料

  • 1,编写 Dockerfile文件,名为Dockerfile,没有后缀

  • 2,在Dockerfile文件写入下面内容:

FROM java:8-alpine
COPY ./docker-demo.jar /tmp/docker-demo.jar
EXPOSE 8090
ENTRYPOINT java -jar /tmp/docker-demo.jar

- FROM java:8-alpine :基础镜像JDK
- 将本地路径下的【docker-demo.jar】,拷贝到【/tmp/docker-demo.jar】
- 对外暴露接口【8090】
- 启动命令【ENTRYPOINT】
  • 3,构建镜像
  • 【docker build -t web:1.0 .】后面的【.】千万不能忘。
  • 在Dockerfile文件所在的目录下运行构建镜像指令
  • 在这里插入图片描述
  • 4,运行容器
  • 【docker run -d -p 8888:8090 --name myweb web:1.0】
  • 5,测试,访问浏览器
  • http://192.168.138.100:8888/hello/count

五、DockerCompose

1,概述

Docker官方的一个开源项目,可以实现容器编排部署。

比如可以通过DockerCompose一键开启mysql与tomcat

2,安装

  • 1,上传 docker-compose 文件到 /usr/local/bin
  • F:\java\上课视频4\后面资料\3-Docker\资料
  • 2,授权
  • chmod +x /usr/local/bin/docker-compose
  • 3,测试是否安装成功
  • docker-compose -v

3,编排部署mysql与tomcat

通过docker-compose.yml文件启动mysql与tomcat

3.1,编写文件docker-compose.yml
version: '3.7' # 这个不能随便写,与docker版本有关
services:
  mysql: # 名称
    image: mysql:5.7.25 # 镜像
    container_name: mysql # 容器名
    volumes: # 数据卷映射(最好使用文件)
      - mysql_conf/my.cnf:/etc/mysql/conf.d/my.cnf
      - mysql_data:/var/lib/mysql
    environment: # 环境
      - MYSQL_ROOT_PASSWORD=123456
    ports: # 系统端口:容器端口
      - 3306:3306
    restart: always # 重启容器方式
  tomcat:
    image: tomcat:8.5.13
    container_name: tomcat
    volumes:
      - /opt/webapps:/usr/local/tomcat/webapps
    ports:
      - 8080:8080
    restart: always
3.2,运行容器
  • 【docker-compose up -d】
  • 必须在docker-compose.yml文件所在的目录或者子目录下运行

4,相关命令

  • 运行:【docker-compose up -d】
  • 停止、启动、重启:【docker-compose stop|start|restart [服务名]】
  • 查看日志:【docker-compose logs -f [服务名]】
  • 停止并删除容器:【docker-compose down】

六、搭建私服

1,使用docker-compose.yml

1.1,创建docker-compose.yml文件
version: '3.7'
services:
  registry:
    image: registry
    volumes:
      - ./registry-data:/var/lib/registry
  ui:
    image: joxit/docker-registry-ui:static
    ports:
      - 8080:80
    environment:
      - REGISTRY_TITLE=传智教育私有仓库
      - REGISTRY_URL=http://registry:5000
    depends_on:
      - registry
1.2,配置私服

1,vi /etc/docker/daemon.json

2,{
“registry-mirrors”: [“https://p11xf841.mirror.aliyuncs.com”],
“insecure-registries”:[“http://192.168.138.100:8080”]
}

3,重新加载配置文件
systemctl daemon-reload

4,重启Docker
systemctl restart docker

1.3,启动

docker-compose up -d

1.4,测试

在这里插入图片描述

2,在私服上传或拉取镜像

  • 打tag
  • docker tag nginx:latest 192.168.138.100:8080/nginx:latest
  • docker tag 镜像名:镜像版本 私服ip:私服端口/自己创建的名称
  • 推送到私服
  • docker push 192.168.138.100:8080/nginx:latest
  • 从私服拉取
  • docker pull 192.168.138.100:8080/nginx:latest
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值