使用Dockerfile构建一个自定义的nginx
首先用docker
拉一个nginx
镜像
docker pull nginx
拉取完成后,编辑一个Dockerfile
文件
vim Dockerfile
命令如下所示,FROM
后面跟的你的基础镜像,而run
则是表示你构建镜像时需要执行的指令,下面的指令意思就构建一个自定义的nginx
镜像,最后知名nginx启动后的欢迎界面,路径为当前系统的绝对路径
FROM nginx
RUN echo '<h1> this is my Spring Cloud and Docker study Demo</h1> ' > /usr/share/nginx/html/index.html
在Dockerfile
的目录下运行如下命令,可以看到命令最后面有个点.
,这个点就是用于参数传递
,表示当前路径Dockerfile
docker build -t nginx:my .
键入如下命令即可看到我们的自定义的镜像构建完成了
docker images
完成后,我们尝试创建一个容器运行一下,如下所示,笔者使用bridge
映射91
端口启动一个nginx
docker run -d -p 91:80 nginx:my
可以看到笔者通过91
端口访问到了自己创建的容器
Dockerfile的常用指令
ADD
:该命令会将本地文件复制到docker容器中
格式:
ADD src(源文件或者目录) desc(容器目标文件或者目标目录)
ARG
: 设置的docker构建参数信息
ARG username=用户名
CMD
:用于执行容器提供的默认值,在Dockerfile
文件中,无论你配置多少条cmd
,只会以最后一条为准,即只会执行最后一条指令
支持的格式有
CMD ["executable","param1","param2"]
CMD ["param1","param2"]
CMD command param1 param2 (在shell中执行)
示例
cmd echo 'this is a test'
-
COPY
: 和ADD
命令类似,使用也类似 -
ENTRYPOINT
:和cmd一样,都是指定Docker
容器启动时需要执行的指令,可以多次设置,但还是以最后一条为准,使用格式也和cmd差不多,示例如下所示
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
ENV
:设置环境变量
示例
ENV JAVA_HOME /path/to/java
EXPOSE
:说明运行容器提供的端口,但并不会因为该声明而打开相应端口,该指令主要作用是帮助理解该镜像服务的守护端口
当然,在容器未指明端口随机运行时,会自动映射EXPOSE
的端口
EXPOSE 8761
-
FROM:指定基础镜像,优点类似java的extends关键字,需要注意的时FROM指令必须用在所有指令之前
-
MAINTAINER:指明维护者信息,用于作为Dockerfile的署名
示例
MAINTAINER 名字<123@qq.com>
- USER:用户设置启动镜像时所用的用户id或者uid,写在RUN和CMD以及ENTRYPOINT后的内容都将用该用户执行
示例
USER zhang
VOLUME
:该指令使容器的一个容器具有持久化存储的功能,该目录可被容器本身使用,也可以共享给其他容器,当容器中有数据需要持久化时,就可以在Dockerfile
中添加该指令,格式如下,意为将数据持久化到/data
目录中
VOLUME /data
(实践)使用Dockerfile构建注册中心eureka镜像
源码地址如下,读者可以自行获取
https://github.com/itmuch/spring-cloud-docker-microservice-book-code-docker/tree/master/docker-1-simple/microservice-discovery-eureka
注意将spring boot
版本改为
<!-- 引入spring boot的依赖 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
</parent>
spring cloud
版本改为
<!-- 引入spring cloud的依赖 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
将自己的项目打成jar包
编辑一个Dockerfile
在上文扔到服务器中的jar包位置编写一个Dockerfile
vim Dockerfile
编辑的内容如下
# 拉取并使用java8作为基础镜像
FROM openjdk:8
# 将本地文件挂到tmp中
VOLUME /tmp
# 复制文件到容器
ADD microservice-discovery-eureka-0.0.1-SNAPSHOT.jar app.jar
# 声明需要暴露的端口
EXPOSE 8761
# 配置容器启动后的命令
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
构建镜像
如下命令即可创建一个标签为zsy/microservice-eureka
的镜像:
docker build -t zsy/microservice-eureka .```
启动并查看是否可以运行
docker run -d -p 8761:8761 zsy/microservice-eureka
使用服务器ip地址:8761
确认是否可以访问
使用Docker Compose构建容器
Docker Compose是什么?它解决什么问题?
我们的使用docker
部署微服务时,如果每个微服务都要手动启停,效率是非常低的,所以我们需要一个工具来一键管理这庞大的微服务,Docker Compose
就是最好的帮手。
安装Docker Compose
如下命令所示,这条命令会自动安装适应系统版本的compose
curl -L "https://github.com/docker/compose/releases/download/1.10.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
为命令添加可执行权限
chmod +x /usr/local/bin/docker-compose
查看是否安装成功
docker-compose --version
如下图所示,显示版本号即说明安装成功了
安装命令补全工具
curl -L https://raw.githubusercontent.com/docker/compose/$(docker-compose version--short)/contrib/completion/bash/docker-compose -o /etc/bash_completion.d/docker-compose
docker-compose.yml文件指令介绍
image
:指定镜像名称或者镜像id,如果该镜像在本地不存在,Compose
会尝试pull
下来。
示例:
image: java
build
:指定Dockerfile
的路径,如下所示,这就说明Dockerfile
文件在当前目录的dir
目录下
build: ./dir
command
:覆盖之前的容器启动后默认执行的指令
示例:
command: bundle exec thin -p 3000
# 也可以是一个list,类似于Dockerfile总的CMD指令,格式如下:
command: [bundle, exec, thin, -p, 3000]
links
:链接到其他服务中的容器。可以指定服务名称然后给他起一个别名来使用如下所示连接到db,我们给他起了个别名database
,后续需要使用这个链接的时候一律使用database
:
web:
links:
- db
- db:database
- redis
- external_links:表示链接到
docker-compose.yml
外部的容器,甚至并非Compose
管理的容器,特别是对于那些提供共享容器或共同服务。格式跟links类似,示例:
external_links:
- redis_1
- project_db_1:mysql
- project_db_1:postgresql
ports
:暴露端口信息。使用宿主端口:容器端口的格式,或者仅仅指定容器的端口(此时宿主机将会随机指定端口)
,类似于docker run -p
,示例:
ports:
- "3000"
- "3000-3005"
- "8000:8000"
- "9090-9091:8080-8081"
- "49100:22"
- "127.0.0.1:8001:8001"
- "127.0.0.1:5000-5010:5000-5010"
expose
:暴露端口,只将端口暴露给连接的服务,而不暴露给宿主机,示例:
expose:
- "3000"
- "8000"
volumes
:卷挂载路径设置。可以设置宿主机路径(HOST:CONTAINER)
或加上访问模式(HOST:CONTAINER:ro)
。示例:
volumes:
# Just specify a path and let the Engine create a volume
- /var/lib/mysql
# Specify an absolute path mapping
- /opt/data:/var/lib/mysql
# Path on the host, relative to the Compose file
- ./cache:/tmp/cache
# User-relative path
- ~/configs:/etc/configs/:ro
# Named volume
- datavolume:/var/lib/mysql
volumes_from
:从另一个服务或者容器挂载卷。可以指定只读或者可读写,如果访问模式没有指定,则默认是可读写。示例:
volumes_from:
- service_name
- service_name:ro
- container:container_name
- container:container_name:rw
environment
:设置环境变量。可以使用数组或者字典两种方式。只有一个key的环境变量可以在运行Compose的机器上找到对应的值,这有助于加密的或者特殊主机的值。示例:
environment:
RACK_ENV: development
SHOW: 'true'
SESSION_SECRET:
environment:
- RACK_ENV=development
- SHOW=true
- SESSION_SECRET
env_file
:从文件中获取环境变量,可以为单独的文件路径或列表。如果通过docker-compose -f FILE
指定了模板文件,则env_file
中路径会基于模板文件路径。如果有变量名称与environment 指令
冲突,则以envirment
为准。示例:
env_file: .env
env_file:
- ./common.env
- ./apps/web.env
- /opt/secrets.env
-
extends
:继承另一个服务,基于已有的服务进行扩展。 -
net
:设置网络模式。示例:
net: "bridge"
net: "host"
net: "none"
net: "container:[service name or container name/id]"
dns
:配置dns
服务器。可以是一个值,也可以是一个列表。示例:
dns: 8.8.8.8
dns:
- 8.8.8.8
- 9.9.9.9
dns_search
:配置DNS的搜索域,可以是一个值,也可以是一个列表,示例:
dns_search: example.com
dns_search:
- dc1.example.com
- dc2.example.com
(实践)使用Docker Compose构建微服务
我们继续使用上文的jar包
编写一个Dockerfile
FROM java:8
VOLUME /tmp
ADD microservice-discovery-eureka-0.0.1.jar app.jar
EXPOSE 8761
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
编写一个docker-compose.yml
version: '2'
services:
eureka: # 指定服务名称
build: . # 使用当前路径的Dockerfile
ports:
- "8761:8761" # 类似与docker run -p 的端口映射
使用docker-compose up 启动
如下命令所示,该命令为前台启动,我们建议后台启动
docker-compose up
后台启动命令,注意这条命令不仅仅会帮我启动,还会重新构建生成容器
docker-compose up -d
测试
如下图所示,使用ip:8761
即可进入eureka
界面,说明配置完成了
关于Docker Compose更多命令
查看帮助。
docker-compose -help
验证docker-compose.yml文件。
# 当配置正确时,不输出任何内容,当配置错误时,输出错误信息。
docker-compose config -q
执行docker-compose指定文件名字
# -f, --file FILE 指定使用的 Compose 模板文件,默认为 docker-compose.yml,可以多次指定
docker-compose -f aa.yml up -d
拉取服务依赖的镜像
# 拉取工程中所有服务依赖的镜像
docker-compose pull
# 拉取工程中 nginx 服务依赖的镜像
docker-compose pull nginx
# 拉取镜像过程中不打印拉取进度信息
docker-compose pull -q
启动容器
docker-compose up
创建并启动所有服务的容器。指定多个yml
加-f
选项。以守护进程模式运行加-d
选项。
# 前台启动
docker-compose up
# 后台启动
docker-compose up -d
# -f 指定使用的 Compose 模板文件,默认为 docker-compose.yml,可以多次指定,指定多个 yml
docker-compose -f docker-compose.yml up -d
查看日志
docker-compose logs
查看服务容器的输出日志。默认情况下,docker-compose
将对不同的服务输出使用不同的颜色来区分。可以通过--no-color
来关闭颜色。
# 输出日志,不同的服务输出使用不同的颜色来区分
docker-compose logs
# 跟踪日志输出
docker-compose logs -f
# 关闭颜色
docker-compose logs --no-color
列出运行进程
docker-compose ps
列出工程中所有服务的容器。
# 列出工程中所有服务的容器
docker-compose ps
# 列出工程中指定服务的容器
docker-compose ps nginx
在容器上执行一条命令
docker-compose run
在指定服务容器上执行一个命令。
# 在工程中指定服务的容器上执行 echo "helloworld"
docker-compose run nginx echo "helloworld"
进入容器
docker-compose exec 容器名称 bash
进入服务容器。
# 进入工程中指定服务的容器
docker-compose exec nginx bash
# 当一个服务拥有多个容器时,可通过 --index 参数进入到该服务下的任何容器
docker-compose exec --index=1 nginx bash
暂停服务容器
# 暂停工程中所有服务的容器
docker-compose pause
# 暂停工程中指定服务的容器
docker-compose pause nginx
恢复服务容器
# 恢复工程中所有服务的容器
docker-compose unpause
# 恢复工程中指定服务的容器
docker-compose unpause nginx
重启服务容器
# 重启工程中所有服务的容器
docker-compose restart
# 重启工程中指定服务的容器
docker-compose restart nginx
启动服务容器
# 启动工程中所有服务的容器
docker-compose start
# 启动工程中指定服务的容器
docker-compose start nginx
停止服务容器
# 停止工程中所有服务的容器
docker-compose stop
# 停止工程中指定服务的容器
docker-compose stop nginx
通过发送SIGKILL信号停止指定服务的容器。
# 通过发送 SIGKILL 信号停止工程中指定服务的容器
docker-compose kill nginx
删除服务(停止状态)容器。
# 删除所有(停止状态)服务的容器
docker-compose rm
# 先停止所有服务的容器,再删除所有服务的容器
docker-compose rm -s
# 不询问是否删除,直接删除
docker-compose rm -f
# 删除服务容器挂载的数据卷
docker-compose rm -v
# 删除工程中指定服务的容器
docker-compose rm -sv nginx
停止并删除所有服务的容器、网络、镜像、数据卷。
# 停止并删除工程中所有服务的容器、网络
docker-compose stop
# 停止并删除工程中所有服务的容器、网络、镜像
docker-compose down --rmi all
# 停止并删除工程中所有服务的容器、网络、数据卷
docker-compose down -v
打印服务容器所对应的镜像
# 打印所有服务的容器所对应的镜像
docker-compose images
# 打印指定服务的容器所对应的镜像
docker-compose images nginx
打印指定服务容器的某个端口所映射的宿主机端口
docker-compose port nginx 80
显示正在运行的进程
# 显示工程中所有服务的容器正在运行的进程
docker-compose top
# 显示工程中指定服务的容器正在运行的进程
docker-compose top nginx
参考文献
《Spring Cloud与Docker微服务架构实战》
大目 / spring-cloud-book
docker 构建eureka server 高可用
Docker-compose 常用命令
docker-compose安装部署sentinel-dashboard