在前面的内容中我们已经学习了SpringCloud的微服务搭建
但是微服务由于被分成多个部分,所以部署起来需要不同的条件环境甚至不同的操作系统从而十分繁琐
下面我们来介绍Docker部署工具,Docker可以帮助我们快速便捷得部署常用微服务以及重复安全部署我们自己的Java项目
我们将从下面角度介绍Docker:
首先我们先来简单介绍一下Docker
我们分别从几个角度来讲述Docker
那么既然说Docker可以快速部署,那么我们平时的部署都会存在什么问题:
此外我们还需要注意环境问题:
因而我们的Docker就采用一种巧妙的方式去解决这个问题:
由此我们可以解决其兼容性问题
但是我们需要注意到不同的组件所需要的底层操作系统环境可能不同,我们该如何去解决
首先我们需要了解操作系统的原理:
所以解决方法其实很简单:
首先我们先给出Docker的简单定义:
Docker是一个快速交付应用、运行应用的技术,具备下列优势:
我们需要介绍到Docker的两个重要概念:
我们可以把镜像简单理解为类,把容器理解为对象:
DockerHub本质上是一个Docker镜像的线上网站:
我们可以在Docker Registry网站上进行镜像的拉取和上传:
Docker是一个Linux工具,需要进行安装后使用,这里就不写Docker的安装步骤了~
Docker是一个CS架构的程序,由两部分组成:
下面我们来介绍Docker的基本操作
我们首先需要了解镜像的组成元素:
我们首先给出一张docker镜像整体操作图:
然后我们给出Docker的相关操作:
# Docker查看目前存在镜像
docker images
# Docker存在两种获取方式(pull云端获取,build构建我们后续详细讲述)
## Docker的pull拉取镜像,直接在云服务器上拉取(一般可以在云服务器上搜索对应的组件,然后获得其对应版本号或对应拉取代码)
## 若标记版本号则为对应版本号,若未标记则为最新版本lastest
docker pull [repository]
docker pull [repository]:[tag]
# Docker的删除rmi(remove images)
docker rmi [repository]:[tag]
# Docker也可以通过push方法推送到服务器上
docker push [repository]:[tag]
# Docker可以采用save将其变换为jar包
docker save -o [保存的目标文件名称] [镜像名称]
# Docker可以采用load将jar包转换回镜像
docker load -i [目标文件名称]
# 最后我们给出一个help方法可以用于查看所有的Docker参数设置
docker 操作名称 --help
我们首先给出一张dokcer容器操作的整体流程图:
首先我们需要知道容器的三个状态:
然后我们来简单介绍一下上述操作:
# ------------------------------------------
# 创建并运行一个容器,处于运行状态
docker run
# 容器暂停
docker pause
# 容器运行
docker unpause
# 容器停止
docker stop
# 容器运行
docker start
# 删除容器
docker rm
# 进入容器执行命令
docker exec
# 查看容器运行日志
docker logs
# 查看所有运行中的容器
docker ps
# ------------------------------------------
下面我们挑几个常用操作去详细介绍:
# run 执行方法
docker run --name containerName -p 80:80 -d nginx
docker run: 语法
--name: 后面跟容器名称
--p: 后面跟对应端口号,第一个端口号是宿主机端口,第二个是容器端口
(第一个是虚拟机端口号,你需要从这个虚拟机端口号进入,然后进入到对应容器端口号中去调用该组件)
默认情况下,容器是隔离环境,我们直接访问宿主机的80端口,肯定访问不到容器中的nginx。
现在,将容器的80与宿主机的80关联起来,当我们访问宿主机的80端口时,就会被映射到容器的80,这样就能访问到nginx了:
-d: 后台执行
nginx: 镜像名称
# ps 执行方法
docker ps # 查看运行中容器
docker -a ps # 查看所有容器
# logs 执行方法
docker logs # 获取当前日志
docker -f logs # 实时查看日志
# exec 执行方法
docker exec -it containerName bash
docker exec : 进入容器内部,执行一个命令
-it : 给当前进入的容器创建一个标准输入、输出终端,允许我们与容器交互(可以看成默认格式)
containerName : 要进入的容器的名称
bash: 进入容器后执行的命令,bash是一个linux终端交互命令
注意:在进入容器之后,容器内部实际上是一个小的虚拟机环境,但很多高端命令都无法使用,例如vim等内容书写命令无法使用
注意:我们在进入容器修改信息,例如修改Nginx的html文件等,我们可以在Docker线上网站找到对应的位置直接进入书写(不推荐)
我们首先来介绍一下数据卷:
下面我们来介绍数据卷的具体操作:
# 数据卷基本格式
docker volume [command]
docker volume命令是数据卷操作,根据命令后跟随的command来确定下一步的操作:
- create 创建一个volume
- inspect 显示一个或多个volume的信息(显示数据卷存在位置)
- ls 列出所有的volume
- prune 删除未使用的volume
- rm 删除一个或多个指定的volume
# 创建数据卷
docker volume create [name]
docker volume create html
# 查看当前数据卷
docker volume ls
# 查看某个数据卷的详细信息(具体包括:名字,地址等)
docker volume inspect [name]
docker volume inspect html
# 删除指定数据卷
docker rm [name]
# 删除所有未使用的数据卷
docker prune
我们在了解数据卷操作后还需要了解如何挂卷:
# 挂卷一般在创建docker容器时(下面的"\"是换行符)
docker run \
--name mn \
-v html:/root/html \ # -v就是挂卷,:前是数据卷名称,:后是具体的容器文件位置
-p 8080:80
nginx \
# 挂卷后我们就可以对其进行修改
# 查看html数据卷的位置
docker volume inspect html
# 进入该目录
cd /var/lib/docker/volumes/html/_data
# 修改文件
vi index.html
除了直接挂卷数据卷外我们也可以直接挂卷文件位置:
# 我们可以直接指定文件位置从而减少一次数据卷创建过程同时直接指定创建位置便于管理
docker run \
--name mysql \
-v /var/lib/docker/volumes/html:/root/html \ # -v就是挂卷,:前是数据卷名称,:后是具体的容器文件位置
-p 8080:80
mysql \
# - -v [宿主机目录]:[容器内目录]
# - -v [宿主机文件]:[容器内文件]
我们这里给出两种挂卷方式的优劣点:
这小节我们来介绍Dokcerfile,也就是docker的Build创建方法
首先我们需要了解镜像:
我们这里给出MySQL的镜像图示:
我们首先来介绍一下dockerfile:
我们给出dockerfile的基本语法:
指令 | 说明 | 示例 |
---|---|---|
FROM | 指定基础镜像 | FROM centos:6 |
ENV | 设置环境变量,可在后面指令使用 | ENV key value |
COPY | 拷贝本地文件到镜像的指定目录 | COPY ./mysql-5.7.rpm /tmp |
RUN | 执行Linux的shell命令,一般是安装过程的命令 | RUN yum install gcc |
EXPOSE | 指定容器运行时监听的端口,是给镜像使用者看的 | EXPOSE 8080 |
ENTRYPOINT | 镜像中应用的启动命令,容器运行时调用 | ENTRYPOINT java -jar xx.jar |
我们这里给出Dockerfile的官方传送门:
我们给出一个Dockerfile案例来详细解释Dockerfile语法:
# 注意:我们首先需要一个dockerfile文件夹,里面装有/jdk8.tar.gz以及/docker-demo.jar,当然还有下述的dockerfile
# --------------下述为dockerfile文件--------------
# 指定基础镜像
FROM ubuntu:16.04
# 配置环境变量,JDK的安装目录
ENV JAVA_DIR=/usr/local
# 拷贝jdk和java项目的包
COPY ./jdk8.tar.gz $JAVA_DIR/
COPY ./docker-demo.jar /tmp/app.jar
# 安装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 8090
# 入口,java项目的启动命令
ENTRYPOINT java -jar /tmp/app.jar
# 最后我们需要build该文件
docker build -t javaweb:1.0 .
-t: 给镜像加一个Tag
javaWeb:镜像名
1.0: 镜像版本
.: Dockerfile所在目录(.就是指当前目录)
我们可以注意到上述dockerfile中配置了jdk8环境和java项目,而我们可以通过更换基础镜像省略jdk8的配置:
# 我们直接基于java:8-alpine环境(该环境下已配置jdk8),我们只需要将java项目拷贝拷贝并启动
FROM java:8-alpine
COPY ./app.jar /tmp/app.jar
EXPOSE 8090
ENTRYPOINT java -jar /tmp/app.jar
下面我们来详细介绍一下Docker-Compose
首先我们先来简单介绍一下Docker-Compose:
我们给出一个简单的Docker-Compose文件:
# -----------------文件概述-----------------
描述一个项目,其中包含两个容器:
- mysql:一个基于`mysql:5.7.25`镜像构建的容器,并且挂载了两个目录
- web:一个基于`docker build`临时构建的镜像容器,映射端口时8090
# -----------------文件内容-----------------
version: "3.8" # 版本号
services: # 服务标识(下述均为服务名称)
mysql: # MySQL服务(不需要映射端口,因为只在内部使用)
image: mysql:5.7.25 # 依赖镜像
environment: # 环境变量,这里直接书写了MySQL密码
MYSQL_ROOT_PASSWORD: 123
volumes: # 挂卷
- "/tmp/mysql/data:/var/lib/mysql"
- "/tmp/mysql/conf/hmy.cnf:/etc/mysql/conf.d/hmy.cnf"
web: # Web服务
build: . # 依赖当前文件夹下的dockerfile文件
ports: # 映射端口
- "8090:8090"
DockerCompose的详细语法参考官网:https://docs.docker.com/compose/compose-file/
温馨提醒:Docker-Compose也需要下载使用,这里不做赘述
下面我们详细介绍一下微服务集群的部署:
# ------------------docker-compose文件------------------
version: "3.2" # 版本
services:
nacos: # nacos注册中心
image: nacos/nacos-server # 镜像
environment:
MODE: standalone # 环境:单点模式启动
ports:
- "8848:8848" # 映射端口
mysql: # MySQL数据库
image: mysql:5.7.25 # 镜像
environment:
MYSQL_ROOT_PASSWORD: 123 # 环境:设置密码
volumes: # 挂卷,方便修改配置
- "$PWD/mysql/data:/var/lib/mysql"
- "$PWD/mysql/conf:/etc/mysql/conf.d/"
userservice: # 基于dockerfile创建临时项目
build: ./user-service
orderservice: # 基于dockerfile创建临时项目
build: ./order-service
gateway: # 基于dockerfile创建临时项目
build: ./gateway
ports:
- "10010:10010"
# ------------------dockerfile文件------------------
FROM java:8-alpine # 基于java:8-alpine环境
COPY ./app.jar /tmp/app.jar # 拷贝当前文件夹中的app.jar至虚拟机中的/tmp文件夹下命名为app.jar
ENTRYPOINT java -jar /tmp/app.jar # 启动该镜像时以java -jar启动/tmp/app.jar
# 因为微服务将来要部署为docker容器,而容器之间互联不是通过IP地址,而是通过容器名。
# 这里我们将order-service、user-service、gateway服务的mysql、nacos地址都修改为基于容器名的访问。
spring:
datasource:
url: jdbc:mysql://mysql:3306/cloud_order?useSSL=false
username: root
password: 123
driver-class-name: com.mysql.jdbc.Driver
application:
name: orderservice
cloud:
nacos:
server-addr: nacos:8848 # nacos服务地址
<!--在pom.xml中修改,注意:需要部署的项目都需要修改,因为我们的docker-compose中将app.jar复制并创建容器时启动-->
<build>
<!-- 服务打包的最终名称 -->
<finalName>app</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
# 启动docker-compose
docker-compose up -d
最后我们介绍一下Docker的私服镜像搭建
不管如何搭建镜像仓库,我们都是基于Docker官方提供的DockerRegistry来实现的:
搭建简单版的私有镜像仓库很简单,我们只需要输入下述docker run代码即可:
docker run -d \
--restart=always \
--name registry \
-p 5000:5000 \
-v registry-data:/var/lib/registry \ # 这是私有镜像库存放数据的目录
registry
图形化私有镜像的搭建不是官方所提供的,而是基于一个组件,我们需要使用到Docker-Compose:
version: '3.0'
services:
registry: # 服务名
image: registry # 镜像名
volumes: # 挂卷,存放数据的位置
- ./registry-data:/var/lib/registry
ui: # ui就是图形化界面组件
image: joxit/docker-registry-ui:static # 镜像名
ports:
- 8080:80 # 开放端口,系统通过8080访问到ui的80端口,然后进入到registry的5000端口
environment:
- REGISTRY_TITLE=私有仓库 # 仓库名称
- REGISTRY_URL=http://registry:5000 # registry是服务名称,5000是registry的服务端口号
depends_on:
- registry
我们的私服采用的是http协议,默认不被Docker信任,所以需要做一个配置:
# 打开要修改的文件
vi /etc/docker/daemon.json
# 添加内容:
"insecure-registries":["http://192.168.150.101:8080"]
# 重加载
systemctl daemon-reload
# 重启docker
systemctl restart docker
私服的拉取需要我们提前设置tag才能够进行推送:
# 重新tag本地镜像,名称前缀为私有仓库的地址:192.168.150.101:8080/
docker tag nginx:latest 192.168.150.101:8080/nginx:1.0
# 推送镜像
docker push 192.168.150.101:8080/nginx:1.0
# 拉取镜像
docker pull 192.168.150.101:8080/nginx:1.0
这篇文章中介绍了Docker的内容及其附属产品Dockerfile和Docker-Compose,希望能为你带来帮助
该文章属于学习内容,具体参考B站黑马程序员的微服务课程
这里附上视频链接:01-今日课程介绍3_哔哩哔哩_bilibili