步骤详解docker一键部署微服务详细教程(代码片段)

博学谷狂野架构师 博学谷狂野架构师     2022-12-02     134

关键词:

Docker部署微服务

场景介绍

整体架构如下

整体服务说明
服务名称 描述
mysql 数据库服务
nacos 注册中心
learn-docker-gateway 网关服务
learn-docker-web API接口服务
learn-docker-storage 存储服务
配置文件提取
pom文件定义属性
<properties>
    <mysql.addr>192.168.64.153:3306</mysql.addr>
    <nacos.addr>192.168.64.153:8848</nacos.addr>
</properties>
配置编译选项
<build>
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.xml</include>
            </includes>
        </resource>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
        </resource>
    </resources>
</build>
配置文件配置
server:
  port: @project.server.prot@
spring:
  application:
    name: learn-docker-storage
    ######################### 数据源连接池的配置信息  #################
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.jdbc.Driver
    url: jdbc:mysql://@db.addr@/employees?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
    username: root
    password: root
    initialSize: 10
    minIdle: 20
    maxActive: 100
    maxWait: 60000
  #### nacos 配置#######
  cloud:
    nacos:
      server-addr: @nacos.addr@
mybatis:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.heima.module.p
编译测试

安装MySQL

MySQL简介

​ MySQL 是世界上最受欢迎的开源数据库。凭借其可靠性、易用性和性能,MySQL 已成为 Web 应用程序的数据库优先选择。

查找MySQL镜像
docker search mysql

参数解释
  • NAME: 镜像仓库源的名称

  • DESCRIPTION: 镜像的描述

  • OFFICIAL: 是否 docker 官方发布

  • stars: 类似 Github 里面的 star,表示点赞、喜欢的意思。

  • AUTOMATED: 自动构建。
下载镜像
docker pull mysql

注意事项
  • 如果不写版本号默认拉取最新的版本好latest
  • 拉取的时候是多个层一起拉取的,这样可用让其他镜像复用分层
  • 如果拉取的镜像不写仓库地址默认就是docker.io/library/
下载指定版本的镜像
查找指定镜像

下载指定版本镜像
docker pull mysql:5.7.34

查看镜像
docker images

MySQL配置
配置MySQL忽略大小写
# 创建MySQL配置的文件夹
mkdir -p /tmp/etc/mysql
# 编辑my.cnf配置文件
vi /tmp/etc/mysql/my.cnf
[mysqld]
lower_case_table_names=1
创建MySQL数据目录
#创建mysql存储的目录
mkdir -p /tmp/data/mysql
启动MySql
docker run -d -p 3306:3306 -v /tmp/etc/mysql:/etc/mysql/mysql.conf.d/ -v /tmp/data/mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root --name mysql mysql:5.7.34

参数解释
  • -d:是指容器后台运行,如果不加-d,当用户断开客户端时容器会结束运行
  • -p:将容器的3306端口映射到主机的3306端口,用来暴漏端口的
  • -v:这个命令是用来挂载目录的,将本地目录挂载到容器中,这样容器操作的就是本地目录
  • -e:这个命令是配置环境参数的,这里MYSQL_ROOT_PASSWORD=root指的是用root用户运行mysql,可以登录Docker容器通过ENV命令查看
  • --name:这个命令是配置Mysql的容器名称的,如果不配置,默认是随机生成的名字
检查MySQL运行状态
查看容器运行状态
docker ps

查看MySQL运行日志
docker logs -f mysql

客户端连接MySQL

SHOW VARIABLES LIKE %case_table%;

查看容器挂载的配置文件
# 登录容器
docker exec -ti mysql /bin/bash

命令格式

docker exec [options] container command [arg...]

命令参数

名称 简写 描述
--detach -d 后台运行模式,在后台执行命令相关命令
--detach-keys 覆盖容器后台运行的一些参数信息
--env -e 设置环境变量
--interactive -i 展示容器输入信息STDIN
--privileged 为命令提供一些扩展权限
--tty -t 命令行交互模式
--user -u 设置用户名(format: <name|uid>[:<group|gid>])
--workdir -w 指定容器内的目录
查看挂载的数据文件
cd /tmp/data/mysql/ && ll

MySQL准备数据

下载并导入数据
下载MySQL测试数据库

  1. set storage_engine = InnoDB;修改为: set default_storage_engine = InnoDB;

  2. select CONCAT(storage engine: , @@storage_engine) as INFO;修改为:select CONCAT(storage engine: , @@default_storage_engine) as INFO;
  .....
  set default_storage_engine  = InnoDB;
-- set storage_engine = MyISAM;
-- set storage_engine = Falcon;
-- set storage_engine = PBXT;
-- set storage_engine = Maria;

select CONCAT(storage engine: ,@@default_storage_engine) as INFO;
.....
导入测试数据
mysql -uroot -h192.168.64.152 -p < employees.sql

客户端检查数据

安装部署nacos

​ Nacos是阿里巴巴开源的一款支持服务注册与发现,配置管理以及微服务管理的组件。用来取代以前常用的注册中心(zookeeper , eureka等等),以及配置中心(spring cloud config等等)。Nacos是集成了注册中心和配置中心的功能,做到了二合一。

直接运行服务
docker run -d -p 8848:8848 --name nacos --env MODE=standalone nacos/nacos-server

登录页面测试

微服务打包镜像

提前说明

访问测试

打包上传微服务
注意配置项
<mysql.addr>192.168.64.153:3306</mysql.addr>
<nacos.addr>192.168.64.153:8848</nacos.addr>
上传打包后的微服务

创建DockerFile
vi Dockerfile
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ADD learn-docker-storage-1.0-SNAPSHOT.jar app.jar
EXPOSE  8003
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
命令解释
  • FORM:定制的镜像都是基于 FROM 的镜像,这里的 openjdk 就是定制需要的基础镜像,后续操作都是基于openjdk
  • VOLUME:挂载一个数据卷,这里因为没有名称,所以是一个默认的数据卷(后面详细解释)

  • ADD:添加一层镜像到当前镜像,这里就是添加SpringBootTest镜像到当前层,并改名app.jar
  • EXPOSE:暴漏端口,因为我们的自己的端口是8080,所以我们暴漏8080
  • ENTRYPOINT:设定容器启动时第一个运行的命令及其参数,这里就是容器以启动就执行 java -jar /app.jar
打包镜像
构建命令格式
docker bulid -t 仓库名/镜像名:tag .
  • -t: 镜像的名字及标签,一般命名规则是 仓库名/镜像名:tag,
    • 仓库名:一般是私服或者dockerhub等地址,如果忽略默认就是dockerhub的地址docker.io.library/
    • 镜像名称:就是我们的自己的服务名称,可以随意命名
    • tag:就是我们的版本号
  • .:这个 . 表示当前目录,这实际上是在指定上下文的目录是当前目录,docker build 命令会将该目录下的内容打包交给 Docker 引擎以帮助构建镜像。
实战操作

​ 一般来说,应该会将 Dockerfile 置于一个空目录下,或者项目根目录下,如果该目录下没有所需文件,那么应该把所需文件复制一份过来。

​ 一般大家习惯性的会使用默认的文件名 Dockerfile,以及会将其置于镜像构建上下文目录中。

构建镜像
 docker build -t learn-docker-storage:0.0.1 .

查看我们构建的镜像
docker images

运行镜像
# 运行容器
docker run -d -p 8003:8003 learn-docker-storage:0.0.1
# 查看运行中的容器
docker ps

参数解释
  • -d:后台运行

  • -p:映射端口,将宿主机的8080端口映射到docker内部的8080端口上
查看启动日志
docker logs -f 74c239792266

尝试访问服务
curl http://192.168.64.153:8003/storage/employe/findByID/10001 | python -m json.tool

删除容器
停止容器
docker stop 3752f7088a04

查看全部容器
docker ps -a

启动停止的容器
docker start 3752f7088a04

删除容器
docker rm -f 3752f7088a04

docker rm 3752f7088a04

日志挂载优化

存储卷优化
什么是存储卷

​ 在Docker中,要想实现数据的持久化(所谓Docker的数据持久化即数据不随着Container的结束而结束),需要将数据从宿主机挂载到容器中。

​ Docker管理宿主机文件系统的一部分,默认位于 /var/lib/docker/volumes 目录中;(最常用的方式

存储卷优化写入速度

​ 如果运行中的容器修改了现有的一个已经存在的文件,那该文件将会从读写层下面的只读层复制到读写层,该文件版本仍然存在,只是已经被读写层中该文件的副本所隐藏,此即“写时复制(COW)”机制

为了避免这种情况,构建Dockerfile的时候应该加入一个存储卷

Dockerfile增加存储卷
增加存储卷
FROM openjdk:8-jdk-alpine
VOLUME /tmp /logs
ADD learn-docker-storage-1.0-SNAPSHOT.jar app.jar
EXPOSE  8003
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
构建镜像
#构建镜像
docker build -t learn-docker-storage:0.0.2 .
# 查看镜像列表
docker images

运行容器
# 运行容器
docker run -d -p 8003:8003 learn-docker-storage:0.0.2
# 查看运行中的容器
docker ps

查看存储卷
docker volume ls

查看容器信息
 docker inspect 2041965c3e87|grep Mounts -A20

 # 进入文件挂载目录
cd /var/lib/docker/volumes/d35de1b7e4631908b05635db4c1f114ab3aafbdf25a9843c068696e66a779c75/_data
# 输出日志
tail -f learn-docker-storage.log

验证存储卷
# 查看运行的容器列表
docker ps
#删除容器
docker rm -f 2041965c3e87
#查看所有的容器列表(运行+停止)
docker ps -a

docker volume ls

# 查看存储卷列表
docker volume ls
# 查看存储卷详情
docker inspect 296ccc64d919e86bb8329bf6b08447c2ea6a118458d3fcb86d5c7c9a3177dfe0

# 运行容器
docker run -d -p 8080:8080 e1222496c69f
# 查看运行中的容器
docker ps

# 查看存储卷列表
docker volume ls

 docker inspect 2041965c3e87|grep Mounts -A20

bind挂载共享存储
什么是bind

​ Bind mounts模式和Volumes非常相似,不同点在于Bind mounts模式是将宿主机上的任意文件或文件夹挂载到容器,而Volumes本质上是将Docker服务管理的一块区域(默认是/var/lib/docker/volumes下的文件夹)挂载到容器。

共享存储
# 级联创建文件夹
mkdir -p /tmp/data/logs
# 运行容器,指定挂载路径 
docker run -d -v /tmp/data/logs:/logs \\
-p 8003:8003 --name learn-docker-storage \\
learn-docker-storage:0.0.2

docker inspect learn-docker-storage|grep Mounts -A20

# 进入目录并浏览目录文件
cd /tmp/data/logs/&&ll
# 打印日志详情
tail -f learn-docker-storage.log

验证共享存储
# 停止并删除容器
docker rm -f learn-docker-storage
# 查看容器已经被删除了
docker ps -a
# 进入日志挂载路径查看日志是否村咋
cd /tmp/data/logs/&&ll

# 运行容器,指定挂载路径 
docker run -d -v /tmp/data/logs:/logs \\
-p 8003:8003 --name learn-docker-storage \\
learn-docker-storage:0.0.2
# 查看日志文件
cat learn-docker-storage.log

volume和bind的区别
  • 容器在不同的服务器部署需要根据实际磁盘挂载目录修改路径
  • 不同操作系统的文件和目录权限会搞得你昏头转向,火冒三丈 ?

​ bind mount和volume其实都是利用宿主机的文件系统,不同之处在于volume是docker自身管理的目录中的子目录,所以不存在权限引发的挂载的问题,并且目录路径是docker自身管理的,所以也不需要在不同的服务器上指定不同的路径,你不需要关心路径。

清理volume挂载
docker volume ls

 docker volume rm volume_name

docker volume prune

网络优化

Docker网络原理

​ Docker使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0),Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址,称为Container-IP,同时Docker网桥是每个容器的默认网关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的Container-IP直接通信。

​ Docker网桥是宿主机虚拟出来的,并不是真实存在的网络设备,外部网络是无法寻址到的,这也意味着外部网络无法通过直接Container-IP访问到容器。如果容器希望外部访问能够访问到,可以通过映射容器端口到宿主主机(端口映射),即docker run创建容器时候通过 -p 或 -P 参数来启用,访问容器的时候就通过[宿主机IP]:[容器端口]访问容器。

Docker网络模式
Docker网络模式 配置 说明
host模式 –net=host 容器和宿主机共享Network namespace。
container模式 –net=container:NAME_or_ID 容器和另外一个容器共享Network namespace。 kubernetes中的pod就是多个容器共享一个Network namespace。
none模式 –net=none 容器有独立的Network namespace,但并没有对其进行任何网络设置,如分配veth pair 和网桥连接,配置IP等。
overlay模式 -- driver overlay Docker跨主机通信模式,使用分布式计算机架构后需要使用overlay网络模式
bridge模式 –net=bridge (默认为该模式)
host模式

​ 如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。

​ 使用host模式的容器可以直接使用宿主机的IP地址与外界通信,容器内部的服务端口也可以使用宿主机的端口,不需要进行NAT,host最大的优势就是网络性能比较好,但是docker host上已经使用的端口就不能再用了,网络的隔离性不好。

container模式

​ 这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo 网卡设备通信。

none模式

​ 使用none模式,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等。

​ 这种网络模式下容器只有lo回环网络,没有其他网卡。none模式可以在容器创建时通过--network=none来指定。这种类型的网络没有办法联网,封闭的网络能很好的保证容器的安全性。

overlay模式

​ 容器在两个跨主机进行通信的时候,是使用overlay network这个网络模式进行通信,如果使用host也可以实现跨主机进行通信,直接使用这个物理的ip地址就可以进行通信。overlay它会虚拟出一个网络比如10.0.9.3这个ip地址,在这个overlay网络模式里面,有一个类似于服务网关的地址,然后把这个包转发到物理服务器这个地址,最终通过路由和交换,到达另一个服务器的ip地址。

bridge模式

​ 当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。

​ 从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。在主机上创建一对虚拟网卡veth pair设备,Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0(容器的网卡),另一端放在主机中,以vethxxx这样类似的名字命名,并将这个网络设备加入到docker0网桥中。可以通过brctl show命令查看。

​ bridge模式是docker的默认网络模式,不写--net参数,就是bridge模式。使用docker run -p时,docker实际是在iptables做了DNAT规则,实现端口转发功能。可以使用iptables -t nat -vnL查看。

我们的网络结构

创建网络
查看网络列表
# 查看网络列表
docker network ls

创建一个桥接网络
# 创建一个桥接网络
docker network create learn-docker-network
# 查看网络列表
docker network ls

服务接入网络
停止并删除原有容器
# 删除当前运行中的容器
docker rm -f learn-docker-storage nacos mysql

创建MySQL
docker run -d \\
-v /tmp/etc/mysql:/etc/mysql/mysql.conf.d/ \\
-v /tmp/data/mysql:/var/lib/mysql \\
-e MYSQL_ROOT_PASSWORD=root \\
--name mysql --network=learn-docker-network \\
mysql:5.7.34

创建Nacos
docker run -d -p 8848:8848 \\
--network=learn-docker-network \\
--name nacos --env MODE=standalone \\
nacos/nacos-server

查看网络详情
docker network inspect learn-docker-network|grep Containers -A 20

修改微服务配置

​ docker 网络访问 可以通过IP或者通过服务名称都是可以的,这里我们通过服务名称访问,因为我们使用了maven打包的方式,我们只需要将pom文件修改就可以

<properties>
    <mysql.addr>mysql:3306</mysql.addr>
    <nacos.addr>nacos:8848</nacos.addr>
</properties>

重新打包服务
docker build -t learn-docker-storage:0.0.3 .

创建微服务
docker run -d \\
-v /tmp/data/logs:/logs \\
-p 8003:8003 \\
--name learn-docker-storage \\
--network=learn-docker-network \\
learn-docker-storage:0.0.3

测试微服务
 curl http://192.168.64.153:8003/storage/employe/findByID/10001 | python -m json.tool

docker:docker入门教程(代码片段)

如今Docker的使用已经非常普遍,特别在一线互联网公司。使用Docker技术可以帮助企业快速水平扩展服务,从而到达弹性部署业务的能力。在云服务概念兴起之后,Docker的使用场景和范围进一步发展,如今在微服务架构越来越流行... 查看详情

docker:docker入门教程(代码片段)

如今Docker的使用已经非常普遍,特别在一线互联网公司。使用Docker技术可以帮助企业快速水平扩展服务,从而到达弹性部署业务的能力。在云服务概念兴起之后,Docker的使用场景和范围进一步发展,如今在微服务架构越来越流行... 查看详情

docker部署centos7安装docker详细步骤(无坑版教程)(代码片段)

...旧版本(如果之前安装过的话)安装Docker的详细步骤一、安装前必读在安装Docker之前,先说一下配置,我这里是Centos7Linux内核:官方建议3.10以上,3.8以上貌似也可。注意:本文的命令使用的是root用户... 查看详情

k8s单节点集群二进制部署(步骤详细,图文详解)(代码片段)

k8s单节点集群二进制部署(步骤详细,图文详解)一、k8s集群搭建环境准备1、etcd集群master01node01node02所有node节点部署docker引擎2、flannel网络插件3、搭建master组件4、搭建node组件(1)node1节点(2)node2节... 查看详情

k8s单节点集群二进制部署(步骤详细,图文详解)(代码片段)

k8s单节点集群二进制部署(步骤详细,图文详解)一、k8s集群搭建环境准备1、etcd集群master01node01node02所有node节点部署docker引擎2、flannel网络插件3、搭建master组件4、搭建node组件(1)node1节点(2)node2节... 查看详情

springcloud微服务电商系统在kubernetes集群中上线详细教程(代码片段)

Kubernetes集群部署Springcloud微服务商务系统文章目录Kubernetes集群部署Springcloud微服务商务系统1.微服务架构及理论概述1.1.单体架构与微服务架构的区别1.2.微服务组件架构图1.3.微服务注册中心1.4.不同的部署环境对于程序配置文件如... 查看详情

docker入门(代码片段)

如今Docker的使用已经非常普遍,特别在一线互联网公司。使用Docker技术可以帮助企业快速水平扩展服务,从而到达弹性部署业务的能力。在云服务概念兴起之后,Docker的使用场景和范围进一步发展,如今在微服务架构越来越流行... 查看详情

springcloudgateway服务网关的部署与使用详细教程(代码片段)

点击关注公众号,实用技术文章及时了解一、为什么需要服务网关:1、什么是服务网关:传统的单体架构中只需要开放一个服务给客户端调用,但是微服务架构中是将一个系统拆分成多个微服务,如果没有网... 查看详情

springcloudgateway服务网关的部署与使用详细教程(代码片段)

点击关注公众号,实用技术文章及时了解一、为什么需要服务网关:1、什么是服务网关:传统的单体架构中只需要开放一个服务给客户端调用,但是微服务架构中是将一个系统拆分成多个微服务,如果没有网... 查看详情

springboot+grpc构建微服务并部署到istio(详细教程)(代码片段)

...也可以熟练使用了,而且网上几乎没有SpringBoot微服务部署到Istio的案例,我就开始考虑用SpringBoot写个微 查看详情

springboot+grpc构建微服务并部署到istio(详细教程)(代码片段)

...也可以熟练使用了,而且网上几乎没有SpringBoot微服务部署到Istio的案例,我就开始考虑用SpringBoot写个微 查看详情

什么是docker(代码片段)

如今Docker的使用已经非常普遍,特别在一线互联网公司。使用Docker技术可以帮助企业快速水平扩展服务,从而到达弹性部署业务的能力。在云服务概念兴起之后,Docker的使用场景和范围进一步发展,如今在微服务架构越来越流行... 查看详情

docker一键打包微服务(代码片段)

...,是有的,我们可以直接通过idea将我们的微服务打包成Docker镜像,并推送到Docker仓库中这里我们采用jib-maven-plugin来进行来构建容器化的springboot应用程序,Jib可以让不写Dockerfile就能实现Docker打包什么是JibJib带来的是,它允许您... 查看详情

关于阿里云的一键部署工具飞流的使用(详细)(代码片段)

...部署服务,但下面讲的就是一键部署的使用。2.使用详解2.1 在https://flow.teambition.com/进行注册2.2 在teambition首页,点击左上角的菜单键,选择“应用商店”,进去搜索“飞流”并使用。2.3 在此点击左上角的菜 查看详情

docker+jenkins+gitee+springboot实现自动化部署流程(详细教程)(附下载工具地址)(代码片段)

下一篇:Docker+jenkins+gitee+springboot实现自动化部署流程(详细教程)(附下载工具地址)(2)1、环境准备1-1服务器相关(附下载工具)1-2centos7安装jdk81-3centos7安装maven3.6.31-4centos7安装git1-5安装docker1-6通过docker安装portainer1-7通过doc... 查看详情

如何轻松建站?站点一键部署搭建(详细教程)

...可以看到WordPress后台的配置界面,点击现在就开始6、将步骤4内创建好的数据库信息复制粘贴下来,然后点击提交,进入最后的 查看详情

jenkins+docker一键自动化部署springboot项目(代码片段)

...全面的Jenkins+docker+springboot一键自动部署项目,步骤齐全,少走坑路。环境:centos7+git(gitee)简述实现步骤:在docker安装jenkins,配置jenkins基本信息,利用Docke 查看详情

jenkins+docker一键自动化部署springboot项目(代码片段)

...全面的Jenkins+docker+springboot一键自动部署项目,步骤齐全,少走坑路。环境:centos7+git(gitee)简述实现步骤:在docker安装jenkins,配置jenkins基本信息,利用Docke 查看详情