Dockerfile自定义镜像
常见的镜像在DockerHub就能找到,但是我们自己写的项目就必须自己构建镜像了。
而要自定义镜像,就必须先了解镜像的结构才行。
镜像结构
镜像是将应用程序及其需要的系统函数库、环境、配置、依赖打包而成。
我们以MySQL为例,来看看镜像的组成结构:
简单来说,镜像就是在系统函数库、运行环境基础上,添加应用程序文件、配置文件、依赖文件等组合,然后编写好启动脚本打包在一起形成的文件。
我们要构建镜像,其实就是实现上述打包的过程。
Dockerfile语法
构建自定义的镜像时,并不需要一个个文件去拷贝,打包。
我们只需要告诉Docker,我们的镜像的组成,需要哪些BaseImage、需要拷贝什么文件、需要安装什么依赖、启动脚本是什么,将来Docker会帮助我们构建镜像。
而描述上述信息的文件就是Dockerfile文件。
Dockerfile就是一个文本文件,其中包含一个个的指令(Instruction),用指令来说明要执行什么操作来构建镜像。每一个指令都会形成一层Layer。
更新详细语法说明,请参考官网文档: https://docs.docker.com/engine/reference/builder
Docker-Compose
Docker Compose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器!
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
DockerCompose的详细语法参考官网:https://docs.docker.com/compose/compose-file/
其实DockerCompose文件可以看做是将多个docker run命令写到一个文件,只是语法稍有差异。
部署微服务集群
需求:将cloud-demo微服务集群利用DockerCompose部署
实现思路:
① 查看docker-compose文件
② 启动nacos微服务
docker run --env MODE=standalone --name nacos -d -p 8848:8848 nacos/nacos-server:1.4.1
注意: nacos微服务启动之后一定要重启网关,否则在后续微服务会报错“failed to req API:/nacos/v1/ns/instance after all servers([127.0.0.1:8848]) tried:”启动网关命令
systemctl restart firewalld.service
③ linux默认不给docker-compose挂载的数据卷读写的权限,需要关闭selinux,mysql的数据卷才可以挂载成功
vim /etc/sysconfig/selinux
SELINUX=enforcing 改为 SELINUX=disabled
重启虚拟机
④ 通过docker inspect
查看容器的ip,修改自己的cloud-demo项目,将子项目nacos地址改为容器ip
⑤ 使用maven打包工具,将项目中的每个微服务都打包为app.jar
⑥ 将打包好的app.jar拷贝到cloud-demo中的每一个对应的子目录中
⑦ 将cloud-demo上传至虚拟机,利用 docker-compose up -d 来部署
注意:
-
通过
docker logs -f xxx
及时查看日志信息 -
错误1:查看微服务报错
failed to req API:/nacos/v1/ns/instance after all servers([127.0.0.1:8848]) tried:
解决方案:先重启nacos,再重启防火墙
systemctl restart firewalld.service
, -
错误2:查看mysql日志
permission denied
原因分析:linux默认禁止docker-compose挂载数据卷,所以需要给予权限
解决方案:修改文件
vim /etc/sysconfig/selinux
,将SELINUX=enforcing 改为 SELINUX=disabled
,重启虚拟机 -
错误3:
Access denied for user 'root'@'172.17.0.3' (using password: YES)
解决方案:mysql密码错误,目前课前资料给的mysql密码设定的是123
-
错误4:
Unable to start docker Container from docker-compose “unknown flag: iidfile”
解决方案:docker-compose版本太高了,需要降下来
什么是数据卷
**数据卷(volume)**是一个虚拟目录,指向宿主机文件系统中的某个目录。能够解决容器与数据(容器内文件)耦合带来的后果
创建和查看数据卷
创建数据卷
docker volume create html
查看所有数据
docker volume ls
查看数据卷详细信息卷
docker volume inspect html
数据卷操作:
- docker volume create:创建数据卷
- docker volume ls:查看所有数据卷
- docker volume inspect:查看数据卷详细信息,包括关联的宿主机目录位置
- docker volume rm:删除指定数据卷
- docker volume prune:删除所有未使用的数据卷
挂载数据卷
docker run的命令中通过 -v 参数挂载文件或目录到容器中:
- -v volume名称:容器内目录
例如nginx
-v html:/usr/share/nginx/html
- -v 宿主机文件:容器内文
- -v 宿主机目录:容器内目录
例如mysql
-v /tmp/mysql/data:/var/lib/mysql
-v /tmp/mysql/conf/hmy.cnf:/etc/mysql/conf.d/hmy.cnf
小结
数据卷挂载与目录直接挂载的
- 数据卷挂载耦合度低,由docker来管理目录,但是目录较深,不好找
- 目录挂载耦合度高,需要我们自己管理目录,不过目录容易寻找查看
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 |
在linux 下执行 docker-compose up -d 找不到命令
先安装wget 命令
yum -y install wget
创建并cd到 /usr/local/bin 此目录执行如下命令
wget https://github.com/docker/compose/releases/download/1.14.0-rc2/docker-compose-Linux-x86_64
rename docker-compose-Linux-x86_64 docker-compose docker-compose-Linux-x86_64
chmod +x /usr/local/bin/docker-compose
docker-compose version
推送、拉取镜像
推送镜像到私有镜像服务必须先tag,步骤如下:
① 重新tag本地镜像,名称前缀为私有仓库的地址:192.168.150.101:8080/
docker tag nginx:latest 192.168.200.130:8080/nginx:1.0
② 推送镜像
docker push 192.168.200.130:8080/nginx:1.0
③ 拉取镜像
docker pull 192.168.200.130:8080/nginx:1.0