文章目录
- 1. 环境准备
- 1. 准备好所用jar包项目
- 2.编写相应的Dockerfile文件
- 3.构建镜像
- 4. 运行镜像
- 5. 测试服务是否OK
- 6.端口说明
- 7.进入容器内
- 8. 操作容器的常用命令
1. 环境准备
检查docker是否已安装
[root@localhost /]# docker -v
Docker version 1.13.1, build 7d71120/1.13.1
[root@localhost /]# systemctl status docker #查看docker Engine 的状态
● docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
Active: active (running) since 六 2023-07-29 22:49:00 CST; 7h ago
Docs: http://docs.docker.com
Main PID: 967 (dockerd-current)
Tasks: 155
Memory: 285.3M
CGroup: /system.slice/docker.service
............
1. 准备好所用jar包项目
在/opt/目录下创建docker目录:
将在Idea中通过Maven打包好的可执行项目的jar包上传到服务器的/opt/docker目录下
项目中的yml配置文件中的服务端口为8096:
2.编写相应的Dockerfile文件
用于描述构建项目镜像的这个文件名必须是Dockerfile,无后缀,文件名不能随意起。否则构建时提示找不到Dockerfile文件。
# 基础镜像,也叫父镜像,因为jar的运行依赖于JDK或Jre,这里使用只拥有运行环境的Jre,减少最终生成的镜像的大小。
FROM openjdk:8u212-jre
# 维护者
MAINTAINER ssccxx
# 在宿主机的 /var/lib/docker目录下的volumes目录里会创建一个临时文件随机名称的目录将这个目录下的_data 链接到容器内的 /tmp
VOLUME /tmp #会自动在容器内的根目录下生成此tmp目录
# 将项目的jar添加到镜像中,并修改名称为myapp.jar,这里默认添加到容器的根目录下(即默认的工作目录)。
ADD platform-customer-post.jar myapp.jar
# 在构建镜像时会执行RUN 命令 ,这里的 touch /myapp.jar 不起作用,因为上方的ADD里已经使根目录下有同名的文件。这里的touch就不会再生效了。
RUN bash -c 'touch /myapp.jar'
# ENTRYPOINT 是 在容器运行时自动执行的命令,也就是启动容器内的项目服务
ENTRYPOINT ["java","-jar","/myapp.jar"]
# 声明, 此容器内的服务监听端口应该为8096,这里的EXPOSE只是声明,方便之后的维护者一目了然可以知道容器内的服务的监听端口。
EXPOSE 8096
说明:上面Dockerfile文件里的指令中的 FROM, ADD ,RUN 都是在镜像构建时执行的。而ENTRYPOINT ,VOLUME ,EXPOSE 是在容器
运行时执行的。
3.构建镜像
[root@localhost docker]# ll
总用量 79156
-rw-r--r-- 1 root root 178 7月 30 01:36 Dockerfile
-rw-r--r-- 1 root root 81049868 7月 29 23:02 platform-customer-post.jar
[root@localhost docker]# docker build --no-cache -t micro-server:v1.0 .
说明:
build是构建命令 -t 需要 指定 repository:tag (也就是仓库名:tag标签,因为这两个才能确定一个镜像)。
repository name must be lowercase
:如果自定义的仓库名有大写字母时,会提示这个。全部改为小写就行了。
--no-cache
:表示构建时不使用上次构建中存在的镜像缓存。一般都加上这个否则有可能使用docker引擎缓存中已构建的镜像,造
成,镜像ID重复,产生冲突。
如果当前/opt/docker目录下没有名为Dockerfile。会提示 Dockerfile文件缺失。
重点
最后的 . 表示是上下文路径:这里就是我们docker build命令执行的当前所在位置(opt/docker目录)。
由于 docker 的运行模式是 C/S。我们本机是 C(客户端),docker 引擎是 S(服务端)。docker有可能在一台机器上,而docker 引擎 也就
是对应的服务端 可能在另一台机器上。我们通过docker 客户端的 CLI 命令将构建信息发送到docker引擎端,实际的构建过程是在
docker 引擎下完成的,所以这个时候无法用到我们本机的文件(比如这里的在构建时需要用到platform-customer-post.jar文件)。
这就需要把我们本机的指定目录下的文件一起打包提供给 docker 引擎使用。虽然我们现在用的虚拟机演示环境是C/S都在同一台机器
上。但是也要走这个流程的。会将 /opt/docker/目录下 内容都打包发给引擎使用,这样docker引擎在执行ADD 指令时 需要复制
platform-customer-post.jar 到镜像中,就从打包的内容里去找,待全部构建完毕,生成最终的镜像后,docker 引擎自动清理这些打包
发过来的内容。
注意
:上下文路径下不要放无用的文件,因为会一起打包发送给 docker 引擎,如果文件过多会造成过程缓慢。
如果:构建时使用: docker build . --no-cache=true 命令 ,没有指定 生成的镜像的 repository:tag ,会产生悬虚镜像。
悬虚镜像:就是 repository 和 tag 都是<none>
的镜像.
这样的镜像 没有实际意思。可以删除掉,释放磁盘空间
[root@localhost docker]# docker images -f dangling=true #查询出全部的本地悬虚镜像
[root@localhost docker]# docker image prune #删除所有悬虚镜像
WARNING! This will remove all dangling images.
Are you sure you want to continue? [y/N] y #键入y表示删除所有悬虚镜
使用docker images 查看构建好的镜像是否存在:
4. 运行镜像
通过镜像生成容器实例
- docker create --name 容器实例名称 -p 宿主机端口:容器内服务的端口 镜像id
说明
: docke create 命令 是 指定镜像id对应的镜像创建容器,但是并不直接运行容器实例,通过docker ps -a
查看所有容器(包括正在运行
的停止的容器),然后配合docker start 容器id或容器名 来使用。 - docker run -d --name 容器实例名称 -p 宿主机端口:容器内服务的端口 镜像id
说明
:docker run 命令 会根据指定镜像id对应的镜像 创建容器,并直接运行此生成的容器实例。-d 指的是后台运行此容器,否则会在控制
台打印内容。
说明
:不指定–name 容器名称,系统会自动生成一个容器名:以 形容词 加下划线 加 人名的方式 命名。注意–name属性的位置。
说明
:docker start 命令 。只能用于已存在的容器,不能用于创建并启动容器。
推荐 使用 docker run 这个命令
。因为使用docker create时并并检查宿主机端口是否已经被占用的问题,只有在运行时才检查。
[root@localhost _data]# docker run -d --name xiaohai -p 8090:8096 79bcb7a73dd2
fdb21e089157e0080ecf26585f5ac174f3e56c056f4d341d838387d048debc5e #执行成功后,会返回容器实例id的完整部分。
[root@localhost _data]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fdb21e089157 79bcb7a73dd2 "java -jar /myapp.jar" 2 seconds ago Up 2 seconds 0.0.0.0:8090->8096/tcp xiaohai
说明:
CONTAINER ID:容器实例id
IMAGE:镜像id
COMMAND: 容器启动时,在容器内部自动执行的命令
CREATED:容器被创建至当前时间的过去的时间
PORTS:表示宿主机端到容器内应用端口的映射及协议
NAMES:容器实例名称
根据同一个镜像我们可以同一台宿主机上创建多个容器实例。容器与容器直接是隔离的,相同的服务端口不会产生冲突。保证宿主机的端口不一致就行。在外部 通过请求宿主机ip:宿主机端口/应用服务接口 会根据 端口映射关系,转发到对应的容器内的服务。
5. 测试服务是否OK
[root@localhost _data]# curl http://localhost:8090/v3/api/client/v1/captchaImage
查看容器日志:
docker logs -f 容器id
可以看到请求进来了,说明容器内的服务是正常的。
说明:
容器启动失败,或服务是否正常 都可以通过docker logs -f 容器id查看到对应的日志。
6.端口说明
1.宿主机端口,EXPOSE 端口 ,应用服务配置文件里服务端口。这三者之间的关系。
先说 EXPOSE 端口 这个是在Dockerfile配置文件里声明的。其实这个就是给后期维护这个配置文件的人员看的。执行 EXPOSE 端口时,
并不会真正的出现监听这个端口。只是说明 我们应用服务对外监听的端口是这个。具体容器应用服务端口 以容器内服务启动时的端口为(也就是应用服务配置文件里的服务端口)。不在写Dockerfile里 写 EXPOSE 端口 一点影响也没有。只是不方便 后期其他人员维护。
一般情况下 EXPOSE 端口 要和 应用服务配置文件里服务端口一致,方便其他人员通过读Dockerfile文件就知道将来的容器内应用服务的端
口号是多少。
2. 端口映射的说明。-p 宿主机端口:容器应用服务端口(应用服务配置文件里服务端口)。
如果不配置这个端口映射会有什么影响。影响就是:访问容器内的服务,只有两种方式。 1. 在宿主机上 通过 容器ip:容器内应用服务的
端口 来访问。2.进入容器内,通过 容器ip或者localhost :容器内应用服务的端口 来访问。
如果配置这个端口映射会有什么好处。好处就是:可以在宿主机上通过 localhost或者宿主机ip:宿主机端口来访问。也可以在
外部的机器上 通过访问 宿主机ip:宿主机端口来间接访问到容器内的应用服务,即方便外边网络访问容器内的服务。
说明
:这里说的宿主机是指的运行容器的这个node机器。这个node机器是通过VMware安装的虚拟机或者其他物理机。
我这里演示环境是 物理机是Windows系统机器,上面安装有VMware Station,通过VMware Station安装的虚拟机。容器就运行在这个虚
拟机上。上面所说的容器宿主机就是这台虚拟机。并不是我的物理机。
7.进入容器内
[root@localhost _data]# docker exec -it fdb21e089157 /bin/bash #-it后 是容器实例id /bin/bash指的是进入容器后,打开一个bash终端 #构建镜像时没有指定工作目录,则默认进入容器后的目录为容器内的根目录
root@fdb21e089157:/# ls
bin boot dev etc home lib lib64 media mnt myapp.jar opt proc root run sbin srv sys tmp usr var
#可以看到myapp.jar包就在容器的根目录下,包括挂载点 tmp目录
#查看容器的java环境,可以看到java版本已经 java的安装目录
root@fdb21e089157:/# java -version
openjdk version "1.8.0_212"
OpenJDK Runtime Environment (build 1.8.0_212-b04)
OpenJDK 64-Bit Server VM (build 25.212-b04, mixed mode)
root@fdb21e089157:/# which java
/usr/local/openjdk-8/bin/java
#也就是我们这个容器内已经有个可执行文件jar包的运行环境了。
root@fdb21e089157:/usr/local/openjdk-8/bin# pwd
/usr/local/openjdk-8/bin
root@fdb21e089157:/usr/local/openjdk-8/bin# ls
clhsdb hsdb java jjs keytool orbd pack200 policytool rmid rmiregistry servertool tnameserv unpack200
#可以看到bin目录下只有java命令,没有 javac,jps等命令。因为我们用的基础镜像为openjdk:8u212-jre。所以么有java的编译等命令。只有运行的命令。而且java 命令也已经是容器内的环境变量了。在容器内的任意目录下都可以执行。所以在容器启动后,在容器内的根目录下 自动执行java -jar xxxx.jar 指令是没有问题的。所以宿主机不需要安装java环境。容器内已经拥有了自己的java环境了。
#容器就像一个精简版的centos或ubuntu,里面只有极少的命令如ls,df,du , 没有ll,vim,netstat,yum等命令。
root@fdb21e089157:/# du -h myapp.jar #可以用这个du -h 文件名 查看文件的大小
78M myapp.jar
8. 操作容器的常用命令
1. docker start 容器id #启动已停止的容器
2. docker stop 容器id #停止正在运行的容器
3. docker exec -it 容器id -- bin/bash #进入容器内,注意只有当容器是运行时此命令才有效
4. docker ps #查看正在运行的容器
5. docker ps -a #查看本机所有的容器,包含已停止运行的容器
6. docker logs -f 容器id #查看容器运行及内部服务查看的日志,若容器已被删除,这里的日志也就查不到了,会被跟着容器自动被删除。
7. docker inspect 容器id #查看容器内部组织结构信息,包括容器内的挂载点信息,容器的ip地址信息
8. docker rm 容器id #删除已停止的指定的容器
9. docker rm -f 容器id #删除容器(包括正在运行的容器)
10. docker rm -f $(docker ps -a -q) # 删除所有容器,包括正在运行的容器,所有删除操作 因此,在执行该命令之前,请确保您的所有数据已经保存