Docker 你看起来有点眼熟的版本

一  参考黑马Docker的学习

‌​⁠​​​‌‍‍‍⁠‬⁠​​⁠‍‌‌‍​‬⁠​‌​​​​‌​​⁠​‬​​⁠​​‬‬⁠‬⁠⁠​安装Docker - 飞书云文档 (feishu.cn)

安装docker参考:

安装yum报错

【linux】已加载插件:fastestmirror, langpacks Loading mirror speeds from cached hostfile_已加载插件:fastestmirror, langpacks loading mirror spee-CSDN博客

二  Docker是什么

1  我看到一篇文章,写得很通透

原文链接:https://blog.csdn.net/javaeEEse/article/details/122109564

1.Docker的三个基本概念:

Image(镜像)
Container(容器)
Repository(仓库)

Docker的思想来自于集装箱,集装箱解决了什么问题?
在一艘大船上,可以把货物规整的摆放起来。并且各种各样的货物被集装箱标准化了,集装箱和集装箱之间不会互相影响。那么我就不需要专门运送水果的船和专门运送化学品的船了。只要这些货物在集装箱里封装的好好的,那我就可以用一艘大船把他们都运走。docker就是类似的理念。现在都流行云计算了,云计算就好比大货轮。docker就是集装箱.

还不懂得话,在这么理解,docker你理解为快递车.
那么快递车是不是有一个个包裹,包裹可以理解为一个镜像,镜像可以理解为一个Java类,而容器可以理解为Java类的实例。
类只有一个,但可以new出千千万万个实例对象。所以,镜像只是一个可以生成容器的东西,而容器才能让程序运行起来。

仓库的话,比如说,都应该用过git吧,完全可以理解为git,上传拉取操作

那么docker有什么好处呢?
最简单的一个例子,比如说,你在刚开始的一台服务器部署项目,那么部署项目一定要配置mysql等环境是吧
那么现在你要吧这个项目迁移到另一台服务器上,又要重写在另一台服务器上重写配置mysql等环境.可能会出现版本错乱等错误,很麻烦
那么现在第一次部署项目的时候,把项目等环境直接放进docker里面,下次你要迁移项目到另一台服务器上,自己把docker镜像上传到docker仓库上,然后再另一台服务器拉取就直接O了,这只是好处之一
 

2  Docker的运行图

bed817d1acc044bdac3109a42695a05d.png

Docker有一套自己维护的仓库,叫做镜像仓库,里面有各种的绿色安装包(开包即用的),由Docker开发公司维护。拿使用Mysql为例子,刚开始我们发送命令到Docker的守护进程,会安装Mysql的Image(镜像),然后就可以使用Mysql了。使用Mysql时,每一个Mqsql服务器都会被包装成一个Container(容器),使其相互独立,互不影响。

3  总结

问 : Docker是做什么的?

Docker可以帮助我们下载应用镜像,创建并运行镜像的容器,从而快速部署应用

问 :什么是镜像?

将应用所需的函数库、依赖、配置等与应用一起打包得到的就是镜像

问 :什么是容器?

为每个镜像的应用进程创建的隔离运行环境就是容器

问 :什么是镜像仓库?

存储和管理镜像的服务就是镜像仓库, DockerHub是目前最大的镜像仓库,其中包含各种常见的应用镜像

三 命令

1  解读入门案例:docker安装mysql

docker run -d \
  --name mysql \
  -p 3306:3306 \
  -e TZ=Asia/Shanghai \
  -e MYSQL_ROOT_PASSWORD=123 \
  mysql

docker run :创建并运行一个容器,-d 是让容器在后台运行

--name mysql :给容器起个名字,必须唯一

-p 3306:3306 :设置端口映射 

什么是映射呢? 我们在创建mysql容器后,我们外部是无法直接访问mysql的。容器一创建,就会有自己的ip地址,端口号,就像一台电脑一样。但是我们能访问到创建容器的电脑的ip地址,通过这台电脑的端口号映射,我们就能间接访问到创建的mysql

-e KEY=VALUE :是设置环境变量

-e MYSQL_ROOT_PASSWORD=123  设置密码,必须设置的配置,还有其他配置可选择,但不是必须的

mysql :指定运行的镜像的名字    

我们用docker找镜像的时候,就是按照这个来找。这个叫做镜像名称。

镜像名称一般分两部分组成:[repository]:[tag]。 其中repository就是镜像名 tag是镜像的版本 在没有指定tag时,默认是latest,代表最新版本的镜像

2  常见命令

Docker最常见的命令就是操作镜像、容器的命令,详见官方文档:

Reference documentation | Docker Docs

4d583efe0df64905b2f3b264b66b434c.png

docker build: 为docker建立私人镜像

docker save:将本地镜像打包

docker load : 将打包好的镜像加载到本地镜像内

docker images:查询本地所有镜像

docker rmi : 删除镜像    rmi:remove images

docker ps: 查询容器进程状态  ps:proceed status   -a 看所有的容器,包括未启动的

其他看图应该可以理解

docker exec : 进入容器内执行操作     实例:docker exec -it nginx bash 

-it:表示交互访问

bash:表示以命令行窗口访问

图片上没有:

退出容器   exit

查询容器详细信息  docker inspect

docker run -d :在后台运行

另外

docker 有其他较多的参数  , 需要注意

3  命令别名

# 修改/root/.bashrc文件
vi /root/.bashrc
内容如下:
# .bashrc

# User specific aliases and functions

alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
alias dps='docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"'
alias dis='docker images'

# Source global definitions
if [ -f /etc/bashrc ]; then
        . /etc/bashrc
fi

对于docker的vi编辑器

b17b80296b7740dfb00f443ebd16c58a.png

source /root/.bashrc

四  数据卷:

1 案例需求

创建Nginx容器,修改nginx容器内的html目录下的index.html文件内容 将静态资源部署到nginx的html目录。

在我们进入nginx容器时,他虽然搭载了运行nginx的必要资源,但是它除了必要的资源什么都没有,包括vi编辑器。所以我们不能在nginx容器内修改index.html.这时候就要用到数据卷。

问 : 什么是数据卷?

数据卷(volume)是一个虚拟目录,是容器内目录与宿主机目录之间映射的桥梁。

数它将宿主机目录映射到容器内目录,方便我们操作容器内文件,或者方便迁移容器产生的数据。

简单的来说,当我们做了这个映射桥梁后,双方中一方有修改,另一方也会随之修改。

注意:1 当创建了数据卷后,会在宿主机/var/lib/docker/volumes下创建对应的数据源,这是固定的路径。

2 数据卷是独立于容器的一个生命周期,即使删除了容器,主要目录不改变,数据卷也依然存在。如果不要某个数据卷,删除就可以了。

952aeb5b421b45fa91f456e47df1f7a7.png

 2  docker volume (数据卷)的命令

命令

说明

文档地址

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  挂载数据卷到数据卷目录的命令

# 1.首先创建容器并指定数据卷,注意通过 -v 参数来指定数据卷
docker run -d --name nginx -p 80:80 -v html:/usr/share/nginx/html nginx

注意:容器与数据卷的挂载要在创建容器时配置,对于创建好的容器,是不能设置数据卷的。而且创建容器的过程中,数据卷会自动创建

4  挂载数据卷到本地任意一个文件的命令

这里挂载到本地root下

问题:在上面挂载到容器目录,可以发现,数据卷的目录结构较深,如果我们去操作数据卷目录会不太方便。在很多情况下,我们会直接将容器目录与宿主机指定目录挂载。挂载语法与数据卷类似:

# 挂载本地目录 -v 本地目录:容器内目录
# 挂载本地文件 -v 本地文件:容器内文件

注意:本地目录必须以“/”或 "./" 开头,如果直接以名称开头,会被识别为数据卷而非本地目录

-v mysql : /var/lib/mysql 会被识别为一个数据卷叫mysql

-v ./mysql : /var/lib/mysql 会被识别为当前目录下的mysql目录

五  自定义镜像

1 重温什么是镜像

镜像就是包含了应用程序、程序运行的系统函数库、运行配置等文件的文件包。构建镜像的过程其实就是把上述文件打包的过程。

2 镜像结构

要想自己构建镜像,必须先了解镜像的结构。

之前我们说过,镜像之所以能让我们快速跨操作系统部署应用而忽略其运行环境、配置,就是因为镜像中包含了程序运行需要的系统函数库、环境、配置、依赖。

因此,自定义镜像本质就是依次准备好程序运行的基础环境、依赖、应用本身、运行配置等文件,并且打包而成。

要想自己构建镜像,必须先了解镜像的结构。

之前我们说过,镜像之所以能让我们快速跨操作系统部署应用而忽略其运行环境、配置,就是因为镜像中包含了程序运行需要的系统函数库、环境、配置、依赖。

因此,自定义镜像本质就是依次准备好程序运行的基础环境、依赖、应用本身、运行配置等文件,并且打包而成。

举个例子,我们要从0部署一个Java应用,大概流程是这样:

  • 准备一个linux服务(CentOS或者Ubuntu均可)

  • 安装并配置JDK

  • 上传Jar包

  • 运行jar包

那因此,我们打包镜像也是分成这么几步:

  • 准备Linux运行环境(java项目并不需要完整的操作系统,仅仅是基础运行环境即可)

  • 安装并配置JDK

  • 拷贝jar包

  • 配置启动脚本

上述步骤中的每一次操作其实都是在生产一些文件(系统运行环境、函数库、配置最终都是磁盘文件),所以镜像就是一堆文件的集合

但需要注意的是,镜像文件不是随意堆放的,而是按照操作的步骤分层叠加而成,每一层形成的文件都会单独打包并标记一个唯一id,称为Layer)。这样,如果我们构建时用到的某些层其他人已经制作过,就可以直接拷贝使用这些层,而不用重复制作。

例如,第一步中需要的Linux运行环境,通用性就很强,所以Docker官方就制作了这样的只包含Linux运行环境的镜像。我们在制作java镜像时,就无需重复制作,直接使用Docker官方提供的CentOS或Ubuntu镜像作为基础镜像。然后再搭建其它层即可,这样逐层搭建,最终整个Java项目的镜像结构如图所示

6d250fb3d0a94425a26e6f47e8296192.png

3 Dockerfile

由于制作镜像的过程中,需要逐层处理和打包,比较复杂,所以Docker就提供了自动打包镜像的功能。我们只需要将打包的过程,每一层要做的事情用固定的语法写下来,交给Docker去执行即可。

而这种记录镜像结构的文件就称为Dockerfile,其对应的语法可以参考官方文档:

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

其中的语法比较多,比较常用的有:

指令

说明

示例

FROM

指定基础镜像

FROM centos:6

ENV

设置环境变量,可在后面指令使用

ENV key value

COPY

拷贝本地文件到镜像的指定目录

COPY ./xx.jar /tmp/app.jar

RUN

执行Linux的shell命令,一般是安装过程的命令

RUN yum install gcc

EXPOSE

指定容器运行时监听的端口,是给镜像使用者看的

EXPOSE 8080

ENTRYPOINT

镜像中应用的启动命令,容器运行时调用

ENTRYPOINT java -jar xx.jar

例如,要基于Ubuntu镜像来构建一个Java应用,其Dockerfile内容如下:

# 指定基础镜像 
FROM ubuntu:16.04 
# 配置环境变量,JDK的安装目录、容器内时区 
ENV JAVA_DIR=/usr/local ENV TZ=Asia/Shanghai 
# 拷贝jdk和java项目的包 
COPY ./jdk8.tar.gz $JAVA_DIR/ COPY ./docker-demo.jar /tmp/app.jar 
# 设定时区 
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone 
# 安装JDK 
RUN cd $JAVA_DIR \ && tar -xf ./jdk8.tar.gz \ && mv ./jdk1.8.0_144 ./java8 
# 配置环境变量 
ENV JAVA_HOME=$JAVA_DIR/java8 ENV PATH=$PATH:$JAVA_HOME/bin 
# 指定项目监听的端口 
EXPOSE 8080 
# 入口,java项目的启动命令 
ENTRYPOINT ["java", "-jar", "/app.jar"]

以后我们会有很多很多java项目需要打包为镜像,他们都需要Linux系统环境、JDK环境这两层,只有上面的3层不同(因为jar包不同)。如果每次制作java镜像都重复制作前两层镜像,是不是很麻烦。

所以,就有人提供了基础的系统加JDK环境,我们在此基础上制作java镜像,就可以省去JDK的配置了:

# 基础镜像 
FROM openjdk:11.0-jre-buster 
# 设定时区 
ENV TZ=Asia/Shanghai 
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone 
# 拷贝jar包 
COPY docker-demo.jar /app.jar 
# 入口 ENTRYPOINT ["java", "-jar", "/app.jar"]

是不是简单多了。

当Dockerfile文件写好以后,就可以利用命令来构建镜像了。

# 进入镜像目录
cd /root/demo
# 开始构建
docker build -t docker-demo:1.0 .
- docker build : 就是构建一个docker镜像
- -t docker-demo:1.0 :-t参数是指定镜像的名称(repository和tag)
- . : 最后的点是指构建时Dockerfile所在路径,由于我们进入了demo目录,所以指定的是.代表当前目录,也可以直接指定Dockerfile目录:
# 直接指定Dockerfile目录
docker build -t docker-demo:1.0 /root/demo

4 实战

步骤一 :编写Dockerfile文件

# 基础镜像
FROM openjdk:11.0-jre-buster
# 设定时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 拷贝jar包
COPY docker-demo.jar /app.jar
# 入口
ENTRYPOINT ["java", "-jar", "/app.jar"]

现在root下Demo包有一个jar包和Dockerfile文件

4b4d1912f39445e5b38299905524acc1.png

步骤二  执行Dockerfile启动代码

[root@localhost ~]# cd demo
[root@localhost demo]# docker build -t docker-demo:1.0 .
[+] Building 32.7s (8/8) FINISHED                                                                                            docker:default
 => [internal] load build definition from Dockerfile                                                                                   0.0s
 => => transferring dockerfile: 359B                                                                                                   0.0s
 => [internal] load metadata for docker.io/library/openjdk:11.0-jre-buster                                                            16.8s
 => [internal] load .dockerignore                                                                                                      0.0s
 => => transferring context: 2B                                                                                                        0.0s
 => [1/3] FROM docker.io/library/openjdk:11.0-jre-buster@sha256:3546a17e6fb4ff4fa681c38f3f6644efd393f9bb7ed6ebbd85f06065f5d570ed      15.4s
 => => resolve docker.io/library/openjdk:11.0-jre-buster@sha256:3546a17e6fb4ff4fa681c38f3f6644efd393f9bb7ed6ebbd85f06065f5d570ed       0.0s
 => => sha256:c4cc477c22ba7abce860198107408434dd7bd73ddbaf82f1e69ab941b9979405 50.44MB / 50.44MB                                       9.4s
 => => sha256:077c54d048f1f1a1f28079caa54bf5d99803f937ffe5c1dc6e207698f70b4e74 7.83MB / 7.83MB                                         4.3s
 => => sha256:0368544993b2deeeffdd19463cdf92ec4e39f83073de5de316f9f5c725ab403f 10.00MB / 10.00MB                                       5.9s
 => => sha256:3546a17e6fb4ff4fa681c38f3f6644efd393f9bb7ed6ebbd85f06065f5d570ed 549B / 549B                                             0.0s
 => => sha256:77dbc78717b5c1d2a6e2b6b47d266a81cb4ac024a8eba8ad135adcb0dbb32f0d 1.58kB / 1.58kB                                         0.0s
 => => sha256:57925f2e4cff6558a1d93c5bdd14820dc7f98141233d825572c554c50337b11d 7.52kB / 7.52kB                                         0.0s
 => => sha256:d2b3c389e55f5873bbaaed0e20d00ccb964d339e3e1a762baedc1997829274f5 5.53MB / 5.53MB                                         9.8s
 => => sha256:7fde22603cbd4234a15d25d9594d93f990480c1406b8be5c5e71e2d611fac1d0 211B / 211B                                             6.3s
 => => sha256:e540594d7c4708c6fe8ea4640e8269b2bb2f8ad11bae89133eddc031c7dcc12f 46.84MB / 46.84MB                                      14.0s
 => => extracting sha256:c4cc477c22ba7abce860198107408434dd7bd73ddbaf82f1e69ab941b9979405                                              2.9s
 => => extracting sha256:077c54d048f1f1a1f28079caa54bf5d99803f937ffe5c1dc6e207698f70b4e74                                              0.3s
 => => extracting sha256:0368544993b2deeeffdd19463cdf92ec4e39f83073de5de316f9f5c725ab403f                                              0.3s
 => => extracting sha256:d2b3c389e55f5873bbaaed0e20d00ccb964d339e3e1a762baedc1997829274f5                                              0.2s
 => => extracting sha256:7fde22603cbd4234a15d25d9594d93f990480c1406b8be5c5e71e2d611fac1d0                                              0.0s
 => => extracting sha256:e540594d7c4708c6fe8ea4640e8269b2bb2f8ad11bae89133eddc031c7dcc12f                                              1.4s
 => [internal] load build context                                                                                                      0.2s
 => => transferring context: 17.70MB                                                                                                   0.2s
 => [2/3] RUN ln -snf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo Asia/Shanghai > /etc/timezone                           0.4s
 => [3/3] COPY docker-demo.jar /app.jar                                                                                                0.0s
 => exporting to image                                                                                                                 0.0s
 => => exporting layers                                                                                                                0.0s
 => => writing image sha256:851d8aa0206f568f1c4b6f9013aa4c1352fd13193dc71aad0d918122cde17089                                           0.0s
 => => naming to docker.io/library/docker-demo:1.0                                                                                     0.0s

构建镜像成功

de8423c1ce624176af0f542ac10d33a2.png

六  网络

问题引入:

Java项目往往需要访问其它各种中间件,例如MySQL、Redis等。而这些中间件处于不同的容器中。现在,我们的容器之间能否互相访问从而使用其他中间件呢?

我们可以使用网络的知识。

1d4bdfd50c584470855bca8aa039f94f.png

从这张图可以看到,只要不同的容器连到相同的网络上,他们就可以相互访问。

在默认网络上我们只能通过ip地址来相互访问。容器的网络IP其实是一个虚拟的IP,其值并不固定与某一个容器绑定,如果我们在开发时写死某个IP,而在部署时很可能MySQL容器的IP会发生变化,连接会失败。

我们必须借助于docker的网络功能来解决这个问题。在docker内,我们自己创建的自定义网络是可以通过容器名互相访问,这就解决了ip变化的问题。

注意:可以不用起别名!!!

网络常见命令

命令

说明

文档地址

docker network create

创建一个网络,dfsd

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

七  实战!!!项目部署

1  部署java项目

步骤一   将java项目用maven打包放在linux指定目录下

打开idea 点击父工程 点击package 这里需要禁掉text 跳过测试的打包 不然会报错

打包好之后会在打包的包下看到target文件夹,打包的文件都在里面

最后放在特定的文件夹  这里部署了service 和 dockerfile

步骤二 运行dockerfile构建jar包的镜像

docker build -t hmall .

步骤三 创建容器 顺便配网

docker run -d --name hm -p 8080:8080 --network myNW hmall

2   部署mysql和nginx    上面有

3  DockerCompose

1 问题引入 以及 DockerCompose介绍

大家可以看到,我们部署一个简单的java项目,其中包含3个容器:

  • MySQL

  • Nginx

  • Java项目

而稍微复杂的项目,其中还会有各种各样的其它中间件,需要部署的东西远不止3个。如果还像之前那样手动的逐一部署,就太麻烦了。

而Docker Compose就可以帮助我们实现多个相互关联的Docker容器的快速部署。它允许用户通过一个单独的 docker-compose.yml 模板文件(YAML 格式)来定义一组相关联的应用容器。

docker-compose.yml文件的基本语法可以参考官方文档:

https://docs.docker.com/compose/compose-file/compose-file-v3/

2  举例

docker-compose文件中可以定义多个相互关联的应用容器,每一个应用容器被称为一个服务(service)。由于service就是在定义某个应用的运行时参数,因此与docker run参数非常相似。

举例来说,用docker run部署MySQL的命令如下:

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

如果用docker-compose.yml文件来定义,就是这样:

version: "3.8"

services:
  mysql:
    image: mysql
    container_name: mysql
    ports:
      - "3306:3306"
    environment:
      TZ: Asia/Shanghai
      MYSQL_ROOT_PASSWORD: 123
    volumes:
      - "./mysql/conf:/etc/mysql/conf.d"
      - "./mysql/data:/var/lib/mysql"
    networks:
      - new
networks:
  new:
    name: hmall

对比如下:

docker run 参数

docker compose 指令

说明

--name

container_name

容器名称

-p

ports

端口映射

-e

environment

环境变量

-v

volumes

数据卷配置

--network

networks

网络

3  命令

# 5.启动所有, -d 参数是后台启动
docker compose up -d

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值