1,什么是docker
Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从Apache2.0协议开源。
注意他是一个开源得应用容器 引擎 ,大家说docker容器,这不准确,应该回答是容器化技术,应用容器引擎。基于go 语言开发的。
这里说到go 语言 ,我想聊聊,目前go语言大火的原因就是他开发了docker 目前 bat 这些大公司 都在做技术转型,从Java 转 go ,我有幸接触了三个月的go 语言开发,他比java 更轻量级(定义结构体和接口完成服务,结构体理解为java 的对象),对于开发大数据,微服务的应用运行速度更快,尤其是目前微服务都部署到了docker 上,那go语言选型就作为上层开发的首选!
java 和 go 语言的区别:
1、Go不允许函数重载,java允许;
2、Java默认允许多态,Go没有;
3、Go用HTTP协议进行路由配置,java不是;
4、Go代码可以自动扩展到多个核心,而Java并不总是具有足够的可扩展性;
5、Java对象的方法会有隐藏this指针传递,Go没有;
6、Java不支持多继承,Go支持多继承;
7、GO采用的是非侵入式接口,而java不是
还有补充一点也是重要的一点,就是二者并发支持不同,
并发模型:Go在语言级别上支持轻量级的协程(goroutine)和通道(channel),可以方便地处理并发任务。而Java需要使用线程来实现并发,需要更多的编码工作
为啥要用docker呢?
我们的部署一般都是 数据库程序,中间件部署到一台或者几台机器上,这是所有早期物联网公司必然经历的一个阶段。一台服务器,至少32核CPU、64G内存,如果只部署一个应用,那就太浪费了。于是,多个应用进程,DB,缓存进程等等都部署在同一个机器上。这样部署固然能高效的利用好昂贵的物理机,但是这种简单粗暴的方式有一个最大的痛点:进程间资源抢占。如果某个进程耗用了100%的CPU资源,其他的进程无法提供服务。或者如果一个进程因为突发异常很多,日志把磁盘打满了,所有的进程都要挂掉。进程间抢占资源导致其他进程无法提供服务所导致的血案数不胜数。
既然因为资源共享导致的问题,那么解决方式就是:进程间硬件资源隔离。虚拟机技术的出现解决了这个棘手的问题。虚拟机通过 与软件硬化,即每台物理机从分配好的cpu , 内存,磁盘,配置网络,形成一个虚拟容器,相信大家都安装锅vm ,wmare 等软件,让自己的笔记本有两个系统,其实这个就是虚拟化技术的早期体现。
但是 ,当大量集群化部署到虚拟机中,由于不同虚拟机的 tomcat jd ng 等软件的版本不同,我们在运维的时候需要挨个去看,挨个修改升级版本,这就比较麻烦,此时容器化技术出现。
当应用集群部署时, 每台机器首先会拉去镜像,docker build 成容器,举个例子,我们部署的 nacos 镜像赖的 mysql 镜像, 我们的businessServer 业务服务也依赖mysql 镜像,他们依赖同一个镜像,当我们mysql 升级后,我们重新修改镜像文件配置,两个服务的依赖都会变化。 我们重新构建镜像后,版本依然时使用新版。我们就只需要该配置重新构建就可以,这是不是简单的多了,可见这就是伟大的程序人的思想啊,我们庆幸我们是站在巨人的肩膀上!
3, dockerfile
Dockerfile 由一行行命令语句组成,并且支持以 # 开头的注释行
一般的,Dockerfile 分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令。
# 基础镜像
FROM openjdk:8-jre
# author
MAINTAINER ruoyi
# 挂载目录
VOLUME /home/ruoyi
# 创建目录
RUN mkdir -p /home/ruoyi
# 指定路径
WORKDIR /home/ruoyi
# 复制jar文件到路径
COPY ./jar/ruoyi-modules-file.jar /home/ruoyi/ruoyi-modules-file.jar
# 启动文件服务
ENTRYPOINT ["java","-jar","ruoyi-modules-file.jar"]
其中,一开始必须指明所基于的镜像名称,接下来推荐说明维护者信息。
后面则是镜像操作指令,例如 RUN 指令,RUN 指令将对镜像执行跟随的命令。每运行一条 RUN 指令,镜像添加新的一层,并提交。workdir 创建一个目录(
为后续的 RUN、CMD、ENTRYPOINT 指令配置工作目录。
可以使用多个 WORKDIR 指令,后续命令如果参数是相对路径,则会基于之前命令指定的路径
), copy 命令时复制jar ,(
复制本地主机的 (为 Dockerfile 所在目录的相对路径)到容器中的 。
当使用本地目录为源目录时,推荐使用 COPY。
)
最后是 CMD 指令,来指定运行容器时的操作命令。
编写完成 Dockerfile 之后,可以通过 docker build 命令来创建镜像。
基本的格式为 docker build [选项] 路径,该命令将读取指定路径下(包括子目录)的 Dockerfile,并将该路径下所有内容发送给 Docker 服务端,由服务端来创建镜像。因此一般建议放置 Dockerfile 的目录为空目录。也可以通过 .dockerignore 文件(每一行添加一条匹配模式)来让 Docker 忽略路径下的目录和文件。
二、 docker-compose
由于构建容器比较多,每次都要执行 docker build 一大串命令,去构建镜像这还是比较麻烦,那有没有一键移动构建多个镜像的方法呢?
docker-compse 应运而生
Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。
Compose 使用的三个步骤:
- 使用 Dockerfile 定义应用程序的环境。
使用 docker-compose.yml 定义构成应用程序的服务,这样它们可以在隔离环境中一起运行。
最后,执行 docker-compose up 命令来一键启动!!
这是本地引用若依开源管理系统微服务版本再次感谢阳大神开发了这套开源管理系统,我们每个使用者学习者都会记住您和您的ruoyi,,,,构建的docker + docker compose 部署方式
注意 要执行 docker-compuse up 命令 要在 docker-compsose.yml 同级目录中如果不在同级目录中则会报错:
那我们打开看下docker-compose.yml 看下:
这里只截取了该服务的部分镜像:
version : 版本号
services : 定义服务
xxx: 服务名
container_name: 容器名称
image : 镜像名称
build:
context: ./nacos
volumes : 数据卷挂在,就是容器内的配置文件或者日志, 或者数据存储位置挂在到外部,便于修改和存储。
ports:
端口映射,容器内端口映射到外部用于访问
(暴露端口。注意端口映射与network_mode: host不兼容。支持short和long两种格式的语法。short语法可以使用HOST:CONTAINER的格式指定端口映射,也可以指定容器端口,宿主机会随机选择临时端口进行映射。)
build: 在构建时应用的配置项。一般直接指定Dockerfile所在文件夹路径,可以是绝对路径,或者相对于Compose配置文件的路径。可以指定为包含构建上下文(context)路径的字符串。
depends_on :
- ruoyi-mysql
完整的一个镜像配置yml
ruoyi-mysql:
container_name: ruoyi-mysql
image: mysql:5.7 (指定要从中启动容器的镜像。可以写仓库/标签,如果镜像不存在,Compose会自动拉取镜像)
build:
context: ./mysql
ports:
- "3306:3306"
volumes:
- ./mysql/conf:/etc/mysql/conf.d
- ./mysql/logs:/logs
- ./mysql/data:/var/lib/mysql
command: [
'mysqld',
'--innodb-buffer-pool-size=80M',
'--character-set-server=utf8mb4',
'--collation-server=utf8mb4_unicode_ci',
'--default-time-zone=+8:00',
'--lower-case-table-names=1'
]
environment:
MYSQL_DATABASE: 'ry-cloud'
MYSQL_ROOT_PASSWORD: password
指定服务之间的依赖关系,解决服务启动先后顺序问题。指定服务之间的依赖关系,将会导致以下行为:
docker-compose up以依赖顺序启动服务。
docker-compose up SERVICE会自动包含SERVICE的依赖项。
docker-compose stop 以依赖顺序停止服务。
docker-compose stop 停止正在运行的容器
docker-compose start 启动容器,
docker-compose down
停止由 docker-compose up
启动的容器
移除这些容器
移除关联的网络
移除关联的卷
docker-compose ps -a 命令