赞
踩
目录
3.1.3 演示实例(基于Ubuntu将java项目构建成镜像)
1.1.1 官方来讲,Docker是一个基于轻量级虚拟化技术的容器,容器内包含了应用程序的代码(即应用本身)和其运行所需要的依赖、函数库、配置和运行环境,通过容器可以实现方便快速并且与平台结耦的自动化部署方式,并且容器中的应用程序始终运行在同一环境下。
1.1.2 通俗解释:Docker的思想来自于集装箱,集装箱解决了什么问题?在一艘大船上,可以把货物规整的摆放起来。并且各种各样的货物被集装箱标准化了,集装箱和集装箱之间不会互相影响。那么我就不需要专门运送水果的船和专门运送化学品的船了。只要这些货物在集装箱里封装的好好的,那我就可以用一艘大船把他们都运走。(鉴自zhihu 刘允鹏)
一般在开发大型项目时,组件很多(nacos、redis、rabbitMQ、mysql等等),运行环境也较为复杂,这就导致部署繁琐问题频出:
1. 各种组件的版本和依赖关系复杂,很容易出先兼容性问题
解决方案:Docker允许开发中将应用、依赖、函数库、配置一起打包,形成可移植镜像; Docker应用运行在容器中,使用沙箱机制,相互隔离
2. 开发、测试、生产环境有差异。
解决方案:Docker镜像中包含完整运行环境,包括系统函数库,仅依赖系统的Linux内核,因此可以在任意Linux操作系统上运行
1.2.2.1 先了解操作系统结构。
以一个Ubuntu操作系统为例,结构如下:
结构包括:
1. 计算机硬件:例如CPU、内存、磁盘等
2. 内核:所有Linux发行版的内核都是Linux,例如CentOS、Ubuntu、Fedora等。内核可以与计算机硬件交互,对外提供内核指令,用于操作计算机硬件。
3.系统应用:操作系统本身提供的应用、函数库。这些函数库是对内核指令的封装,使用更加方便。(如centos和Ubuntu都是基于Linux内核的系统应用,他们的函数库不同)
1.2.2.2 应用于计算机交互的流程:
1)应用调用操作系统应用(函数库),实现各种功能
2)系统函数库是对内核指令集的封装,会调用内核指令
3)内核指令操作计算机硬件
了解完那么问题就来了,Ubuntu和CentOSpringBoot都是基于Linux内核,无非是系统应用不同,提供的函数库有差异:此时,如果将一个Ubuntu版本的MySQL应用安装到CentOS系统,MySQL在调用Ubuntu函数库时,会发现找不到或者不匹配,就会报错了
1.2.2.3.那么Docker如何解决不同系统环境的问题?
Docker将用户程序与所需要调用的系统(比如Ubuntu)函数库一起打包
Docker运行到不同操作系统时,直接基于打包的函数库,借助于操作系统的Linux内核来运行
下图能更好的理解:
通俗解释:例如你下载了一个QQ,如果我们将QQ在磁盘上的运行文件及其运行的操作系统依赖打包,形成QQ镜像。然后你可以启动多次(利用镜像启动多个容器),双开、甚至三开QQ,跟多个妹子聊天。
一旦完成数据卷挂载,对容器的一切操作都会作用在数据卷对应的宿主机目录了。这样,我们操作宿主机的/var/lib/docker/volumes/xxx目录,就等于操作容器内的/usr/share/nginx/xxx目录了
- docker 帮助命令:docker --help
- 查看系统内核:uname -r
- 启动docker :systemctl start docker
- 查看docker版本: docker verison
- 显示docker系统的信息:docker info
管理命令:
container 管理容器
image 管理镜像
network 管理网络
命令:
attach 介入到一个正在运行的容器
build 根据 Dockerfile 构建一个镜像
commit 根据容器的更改创建一个新的镜像
cp 在本地文件系统与容器中复制 文件/文件夹
create 创建一个新容器
exec 在容器中执行一条命令
images 列出镜像
kill 杀死一个或多个正在运行的容器
logs 取得容器的日志
pause 暂停一个或多个容器的所有进程
ps 列出所有容器
pull 拉取一个镜像或仓库到 registry
push 推送一个镜像或仓库到 registry
rename 重命名一个容器
restart 重新启动一个或多个容器
rm 删除一个或多个容器
rmi 删除一个或多个镜像
run 在一个新的容器中执行一条命令
search 在 Docker Hub 中搜索镜像
start 启动一个或多个已经停止运行的容器
stats 显示一个容器的实时资源占用
stop 停止一个或多个正在运行的容器
tag 为镜像创建一个新的标签
top 显示一个容器内的所有进程
unpause 恢复一个或多个容器内所有被暂停的进程
- 拉取镜像(可从DockerHub官网搜) 如nginx: docker pull image-name
- 检索image : docker search image-name
- 列出镜像列表:docker images
- 显示一个镜像历史:docker history image-name
- 保存镜像(将已有镜像导出):docker save -o [保存的目标文件名称] [镜像名称]
- 加载镜像:docker load -i [已保存的镜像包] 如:docker load -i nginx.tar
- 删除镜像:docker rmi [镜像名称]
- 通过容器创建镜像:*从已经创建的容器中更新镜像,并且提交这个镜像 *使用 Dockerfile 指令来创建一个新的镜像 下面通过已存在的容器创建一个新的镜像。
docker commit -m="First Image" -a="keke" 7a15f99695c0 keke/unbantu:17.10.0
docker commit -m="[描述信息]" -a="指定镜像作者" [容器id] [创建的目标镜像名]
- 列出当前所有正在运行的container : docker ps
- 列出所有 container(包括已停止的) : docker ps -a
- 列出最近一次启动的 container : docker ps -l
- 创建并运行一个容器(nginx为例):docker run --name containerName -p 80:80 -d nginx
命令解读:
docker run :创建并运行一个容器
--name : 给容器起一个名字,比如叫做mn
-p :将宿主机端口与容器端口映射,冒号左侧是宿主机端口,右侧是容器端口
-d:后台运行容器
nginx:镜像名称,例如nginx
- 让运行的容器暂停:docker pause [容器名]/ID
- 让运行容器从暂停恢复:docker unpause [容器名]/ID
- 停止运行的容器:docker stop [容器名]/ID
- 让一个停止的容器重新运行:docker start [容器名]/ID
- 删除所有容器: docker rm `docker ps -a -q `
- 强制删除正在运行的容器(使用SIGKILL): docker rm -f
- 删除指定容器 :docker rm -l
- 删除与容器有关的数据卷:docker rm -v
- 从一个容器中取日志,参数:-f, --follow=false Follow log output; -t, --timestamps=false Show timestamps 命令: docker logs [容器名]/ID
- 列出一个容器里面被改变的文件或者目录,list列表会显示出三种事件,A 增加的,D 删除的,C 被改变的:docker diff Name/ID
- 显示一个运行的容器里面的进程信息:docker top Name/ID
- 从容器里面拷贝文件/目录到本地一个路径: docker cp Name:/container-path to-path
docker cp ID:/container-path to-path
- 进入容器执行相关容器内操作:docker exec -it mn bash
命令解读:
docker exec :进入容器内部,执行一个命令
-it : 给当前进入的容器创建一个标准输入、输出终端,允许我们与容器交互
mn :要进入的容器的名称
bash:进入容器后执行的命令,bash是一个linux终端交互命令
- 创建一个数据卷:docker volume create [数据卷名]
- 显示一个或多个volume信息:docker volume inspect [数据卷名]
- 列出所有volume:docker volume ls
- 删除未使用的volume : docker volume prune
- 删除一个或多个volume : docker volume rm [数据卷名]
- 创建容器并挂载数据卷:docker run --name [容器名] -v [需要挂载的数据卷名]:/[容器内目录] -p [宿主机端口]:[容器端口] [镜像名] 。对应容器内目录需要去DockerHub找
例如nginx : docker run --name nginx -v html:/usr/share/nginx/html -p 8080:80 nginx
简单来说,镜像就是在系统函数库、运行环境基础上,添加应用程序文件、配置文件、依赖文件等组合,然后编写好启动脚本打包在一起形成的文件。其结构如下:
构建镜像就是实现上述从下至上的打包操作
Dockerfile 就是一个文本本件,其中包含一个个指令,相当于脚本。我们构建自定义镜像时并不需要一个个文件去拷贝打包。只需要告诉Docker我们镜像的组成,需要哪些BaseImage、需要安装什么依赖,启动脚本是什么,Docker会帮我们构建,指令如下:
步骤1:新建一个空文件夹docker-demo
步骤2: 将自己的项目打包成jar包到docker-demo
步骤3: 将 jdk8.tar.gz文件导到docker-demo
步骤4: 便写dockerfile文件并保存到docker-demo
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
步骤5: 进入docker-demo将准备好的docker-demo上传到虚拟机任意目录,然后进入docker-demo目录
步骤6: 运行命令 docker build -t javaweb:1.0 . 注意该命令最后的“ . ” 是指当前目录
Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。格式如下
- version: "3.8"
- services:
- mysql:
- image: mysql:5.7.25
- environment:
- MYSQL_ROOT_PASSWORD: 123
- volumes:
- - "/tmp/mysql/data:/var/lib/mysql"
- - "/tmp/mysql/conf/hmy.cnf:/etc/mysql/conf.d/hmy.cnf"
- web:
- build: .
- ports:
- - "8090:8090"
上面的Compose文件就描述一个项目,其中包含两个容器:
mysql:一个基于mysql:5.7.25
镜像构建的容器,并且挂载了两个目录
web:一个基于docker build
临时构建的镜像容器,映射端口时8090
步骤1: 便携compose文件
- version: "3.2"
-
- services:
- nacos:
- image: nacos/nacos-server
- environment:
- MODE: standalone
- ports:
- - "8848:8848"
- 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:
- build: ./user-service
- orderservice:
- build: ./order-service
- gateway:
- build: ./gateway
- ports:
- - "10010:10010"
解析:其中包含5个service服务:
nacos
:作为注册中心和配置中心
image: nacos/nacos-server
: 基于nacos/nacos-server镜像构建
environment
:环境变量
MODE: standalone
:单点模式启动
ports
:端口映射,这里暴露了8848端口
mysql
:数据库
image: mysql:5.7.25
:镜像版本是mysql:5.7.25
environment
:环境变量
MYSQL_ROOT_PASSWORD: 123
:设置数据库root账户的密码为123
volumes
:数据卷挂载,这里挂载了mysql的data、conf目录,其中有我提前准备好的数据
userservice
、orderservice
、gateway
:都是基于Dockerfile临时构建的
步骤2: 修改自己的cloud-demo项目,将数据库、nacos地址都命名为docker-compose中的服务名
步骤3: 修改自己的cloud-demo项目,将数据库、nacos地址都命名为docker-compose中的服务名
步骤4: 编译打包好的app.jar文件,需要放到Dockerfile的同级目录中。注意:每个微服务的app.jar放到与服务名称对应的目录,别搞错了。
其中Dockerfile文件的内容很简单:
- FROM java:8-alpine
- COPY ./app.jar /tmp/app.jar
- ENTRYPOINT java -jar /tmp/app.jar
步骤5: 我们需要将文件整个cloud-demo文件夹上传到虚拟机中,由DockerCompose部署。进入cloud-demo目录,然后运行命令:docker-compose up -d
推送镜像到私有镜像服务必须先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、DockerCompoes、Docker仓库的构建教程如下https://blog.csdn.net/weixin_52156647/article/details/120835036
总结了很久,对你有帮助的话麻烦点个赞叭,有错误请大佬们评论指教 !
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。