作者Gitee地址 https://gitee.com/thciweicloud/loafblog
作者项目 面包博客,一个微服务架构的前后端分离博客系统。前后端使用Vue+SpringCloud,鉴权登录使用JWT,使用ElasticSearch作为博客检索引擎,使用ELK进行日志收集,GithubActions完成持续集成和交付
Dockerfile
Dockerfile用于编写镜像
- 基础指令
#打包 寻找Dockerfile文件按规则构建镜像
#推荐专门创建一个dockerfile文件夹或者dockerignore
docker build -t ourmysql8:01 . # .指定当前目录寻找Dockerfile
(以下指令前提)vim Dockerfile
#FROM
FROM mysql:8.0
#RUN 表示提前运行一些指令
RUN yum install -y vim
(json书写格式) RUN ["yum","install","-y","vim"]
#EXPOSE
EXPOSE 5672 #指定暴露端口
EXPOSE 15672
#WORKDIR
WORKDIR /data #指定进入容器后默认的目录位置
#COPY
COPY aa.txt /data/bb #将文件拷贝到容器指定位置,日后jar包、war包部署可用
#ADD
ADD aa.txt /data/bb #将文件拷贝到容器指定位置
ADD https://dlcdn.apache.org/tomcat/tomcat-8/v8.5.72/bin/apache-tomcat-8.5.72.tar.gz /data/bb #指定url下载到指定目录,而COPY不可以
ADD apache-tomcat-8.5.72.tar.gz /data/bb #将文件自动解压到容器内部
(ADD apache-tomcat-8.5.72.tar.gz /data/bb
RUN mv apache-tomcat-8.5.72 tomcat) #解压到容器内并且重命名
#VOLUME
#定义匿名数据卷。在启动容器时忘记挂载数据卷,会自动挂载到匿名卷。在run启动容器时 -v可以指定宿主机文件到容器内部的挂载,如果忘记则遵从VOLUME配置
VOLUME /data/bb/tomcat/webapps #容器内位置
#ENV
ENV BASE_DIR /data/bb #定义环境变量
ADD bb.txt $BASE_DIR
#ENTRYPOINT
#可以有多个,建议用于书写固定的命令
ENTRYPOINT ls $BASE_DIR/bb #容器启动时默认运行什么命令
ENTRYPOINT tail -f bb.txt
#CMD
#只能有一个,写多个会被覆盖掉,建议用于书写灵活的参数
CMD ls $BASE_DIR/bb
docker run ourmysql8:01 ls /data/bb/tomcat/ #CMD与ENTRYPOINT的区别,CMD可以被指令覆盖,此时不再查看CMD指定的ls位置
- 引申jar包使用
#ENTRYPOINT与CMD配合使用 !!一定要以json形式!!
ENTRYPOINT ["ls"]
CMD ["/data/bb"]
docker run xx /data/bb/webapps 展示出webapps的内容
引申jar包启动:
ENTRYPOINT ["java","-jar"]
CMD ["sms.jar"]
- Dockfile构建SpringBoot项目
mkdir demo
#将jar包拷贝到demo文件夹中
创建Dockerfile
FROM openkjdk:8-jre #jar包需要基于jdk环境,所以在dockerhub中寻找jdk镜像
WORKDIR /app
ADD demo-0.0.1-SNAPSHOT.jar app.jar
EXPOSE 8081
ENTRYPOINT ["java","-jar"]
CMD ["app.jar"]
打包镜像
docker build -t demo:01 .
启动容器
docker run -d -p 8081:8081 demo:01
使用docker日志观察 jar包运行情况
docker logs -f 容器id
这里分享一个寻找 jdk/jre的小技巧
dockerhub中输入java来打开openjdk,否则出现的是付费版本,在tag搜索时输入 8- 更方便找到你要的jdk/jre
插件安装,如果你的idea版本比较老,可以在插件商店安装docker插件,新版自带忽略,这样我们就可以直接在项目中编写Dockerfile和远程连接调试了,项目中编写好Dockerfile直接拖入服务器
远程连接服务器:Tools<<Deployment<<Browse RemoteHost
Docker Compose
Docker Compose用于对容器集群的编排
项目( Project): 有多个服务共同组成一个完整业务单元 定义 docker- compose.yml文件中
服务( service):一个服务对应一个应用容器在一个项目中可以存在多个服务
docker-compose的service服务概念是抽象出来的,不真实存在此文件,其囊括了众多的服务,在使用层面可以比作我们创建了一个hello文件夹,其中创建了docker-compose.yml,我们在这个项目文件夹中执行docker-compose up
简单案例
curl -L https://github.com/compose/releases/download/1.25.5/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
#如果curl not found,建议直接去github下载官方编译好的版本上传到服务器
mv docker-compose-Linux-x86_64 docker-compose #改名
mv docker-compose /usr/local/bin/ # /usr/local/bin/ 是存放环境变量的位置
chmod +x /usr/local/bin/docker-compose #赋权限
#检测是否安装成功
docker-compose -v
编写一个简单的 docker-compose.yml
version: "3.0"
services:
tomcat:
image: demo:01
ports:
- "8081:8081"
tomcat01:
image: demo:01
ports:
- "8082:8082"
在当前文件夹启动
docker-compose up
Docker-Compose模板
volume
数据卷挂载
version: "3.0"
services:
tomcat:
image: demo:01
ports:
- "8081:8081"
volumes: #完成宿主机与容器中目录数据卷共享
- tomcatwebapps:/usr/local/tomacat/webapps
volumes: #声明上面服务所使用的自动创建的卷名
tomcatwebapps: #声明指令的卷名 compose自动创建该卷名但是会在之前加入项目名 如 hello_tomcatwebapps
external: #使用自定义卷名 true
false
自定义卷名消除前缀需要提前创建名称
docker volume create tomcatwebapps
查看一下数据卷挂载
#docker volume ls 展示数据卷
--------------------
local f3a4a8b8db61caaef47ae695c5758344ba98d0e0838767a91ec0c097c4f311bd
local hello_tomcatwebapps
--------------------
# docker inspect hello_tomcatwebapps 查看数据卷信息
--------------------
[
{
"CreatedAt": "2021-11-09T15:18:53+08:00",
"Driver": "local",
"Labels": {
"com.docker.compose.project": "hello",
"com.docker.compose.version": "1.25.4",
"com.docker.compose.volume": "tomcatwebapps"
},
"Mountpoint": "/www/server/docker/volumes/hello_tomcatwebapps/_data",
"Name": "hello_tomcatwebapps",
"Options": null,
"Scope": "local"
}
]
-------------------
#cd /www/server/docker/volumes/hello_tomcatwebapps/_data
你可以发现自动创建的卷名加了hello的前缀,hello正是其所处文件夹的名称,印证了docker-compose以 项目 作为抽象层的概念,服务组成了一个项目
network
网桥指定
指定tomcat01和02在同一网桥
version: "3.0"
services:
tomcat01:
container_name: tomcat01 #相当于run的 --name
image: demo:01
ports:
- "8081:8081"
volumes: #完成宿主机与容器中目录数据卷共享
- tomcatwebapps01:/usr/local/tomacat/webapps
networks: #代表当前服务使用那个网络桥
- hello
tomcat02:
container_name: tomcat02
image: demo:01
ports:
- "8082:8082"
volumes:
- tomcatwebapps02:/usr/local/tomcat/webapps
networks:
- hello
volumes: #声明上面服务所使用的自动创建的卷名
tomcatwebapps01: #声明指令的卷名 compose自动创建该卷名但是会在之前加入项目名 如 hello_tomcatwebapps
external: #使用自定义卷名 true
false
tomcatwebapps02:
external:
false
networks: #定义服务到桥
hello: #定义上面的服务用到的网桥名称
自定义网桥名需要提前创建名称
docker network create bridge hello
网桥叫做hello
#查询网络 docker network ls
--------------------------------
NETWORK ID NAME DRIVER SCOPE
55a776d42a54 bridge bridge local
6ad1e3f86688 hello_default bridge local
6e8150907bbd hello_hello bridge local
---------------------------------
两个tomcat处在同一网桥
#docker ps
---------------------------------
5ac6699bbb32 demo:01 "java -jar app.jar" 9 seconds ago Up 7 seconds 8081/tcp, 0.0.0.0:8082->8082/tcp, :::8082->8082/tcp tomcat02
5817bcade528 demo:01 "java -jar app.jar" 15 minutes ago Up 7 seconds 0.0.0.0:8081->8081/tcp, :::8081->8081/tcp tomcat01
--------------------------------
#进入容器curl 请求连接8082
docker exec -it 5ac /bin/bash
root@5ac6699bbb32:/app# curl http://tomcat02:8082
env_file
environment直接配置环境变量如密码等不够安全,所以可以使用env_file来指定环境配置文件
- MYSQL_ROOT_PASSWORD=root
在这里mysql需要配置用户名密码,我们可以把内容转移到mysql.env文件中
version: "3.0"
services:
tomcat01:
container_name: tomcat01 #相当于run的 --name
image: demo:01
ports:
- "8081:8081"
volumes: #完成宿主机与容器中目录数据卷共享
- tomcatwebapps01:/usr/local/tomacat/webapps
networks: #代表当前服务使用那个网络桥
- hello
mysql:
image: mysql:8.0
container_name: mysql
ports:
- "3307:3306"
volumes:
- mysqldata:/var/lib/mysql
- mysqlconf:/etc/mysql
# environment:
# - MYSQL_ROOT_PASSWORD=root
env_file: #用来将environment环境中配置放入指定配置文件
- mysql.env
networks:
- hello
volumes: #声明上面服务所使用的自动创建的卷名
tomcatwebapps01: #声明指令的卷名 compose自动创建该卷名但是会在之前加入项目名 如 hello_tomcatwebapps
external: #使用自定义卷名 true
false
mysqldata:
mysqlconf:
depends_on
容器编排,指定启动顺序
version: "3.0"
services:
tomcat01:
container_name: tomcat01 #相当于run的 --name
image: demo:01
ports:
- "8081:8081"
volumes: #完成宿主机与容器中目录数据卷共享
- tomcatwebapps01:/usr/local/tomacat/webapps
networks: #代表当前服务使用那个网络桥
- hello
depends_on: #容器启动顺序
- mysql
- tomcat02
tomcat02:
container_name: tomcat02
image: demo:01
ports:
- "8082:8082"
volumes:
- tomcatwebapps02:/usr/local/tomcat/webapps
networks:
- hello
mysql:
image: mysql:8.0
container_name: mysql
ports:
- "3307:3306"
healthcheck
心跳检测
version: "3.0"
services:
tomcat01:
container_name: tomcat01 #相当于run的 --name
image: demo:01
ports:
- "8081:8081"
volumes: #完成宿主机与容器中目录数据卷共享
- tomcatwebapps01:/usr/local/tomacat/webapps
networks: #代表当前服务使用那个网络桥
- hello
healthcheck: #心跳检测
test: ["CMD","curl","-f","http://localhost"]
interval: 1m30s
timeout: 10s
retries: 3
sysctls
非必须
用来修改容器中系统内部参数
承接在services tomcat01:下
sysctls: #用来修改容器中系统内部参数 并不是必须 有些服务启动受容器内操作系统参数限可能会无法启动必须过修改容器中参数才能启动
- net.core.simaxconn=1024
- net.ipv4.tcp_syncookies=0
ulimits
非必须
用来修改容器中系统内部进程数限制
ulimits: #用来修改容器中系统内部进程数限制 日后使用可根据当前容器运行服务要求进行修改
nproc: 65535
nofile:
soft: 20000
hard: 40000
Compose模板中build指令
用来将指定dockerfile打包成对应镜像,然后运行该镜像
正常dockerfile先打包镜像,compose再编排镜像,build省略中间步骤
services:
demo:
build: #启动服务先将bui1d命令中指定 dockerfile打包成镜像,再运行该镜像
context: demo #指定上下文目录 dockerfile所在目录
dockerfile: Dockerfile
container_name: demo
ports:
- "8083:8083"
networks:
- hello
depends_on:
- tomcat01
Compose常用指令
没有特别说明,这些指令的对象是项目,而上述模板指令针对的则是内部
-f
#当compose文件名称与目录名不同,需要指定compose文件
docker-compose -f demo-compose.yml up
–verbose
展示调试信息
up(重要)
-d
#后台启动
docker-compose up -d
down
#用来关闭所有compose中的服务,并移除自己创建的网桥,volume数据卷不移除
docker-compose down
也可以使用 docker-compose exec -it 服务id(yml文件指定的名称) bash exit停掉容器
ps
#用来展示当前compose项目中运行的服务
docker-compose ps
[root@]# docker-compose ps
Name Command State Ports
-----------------------------------------------------------
hello_demo java -jar app.jar Exit 143
mysql docker-entrypoint.sh mysqld Exit 0
tomcat01 java -jar app.jar Exit 143
tomcat02 java -jar app.jar Exit 143
restart
#重启服务,不写服务id默认重启所有
docker-compose restart
rm
#用来删除项目服务
docker-compose rm -fv 服务id -v会强制删除数据卷
stop
#关闭服务 但不会关闭网络
docker-compose 服务id
top
#用来compose内部进程
docker-compose top
pause
#暂停服务
docker-compose pause 服务id
#docker-compose ps 可以看到state为Paused
logs
#查看服务日志,不写id默认全部
docker-compose logs 服务id
Docker可视化工具
Portainer
端口9000,可以查看容器、资源统计(图表)、日志等等
#安装
docker run -d -p 8000:8000 -p 9000:9000 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer
同样可以让Portainer伴随docker-compose启动,需要声明数据卷
version: "3.0"
services:
tomcat02:
container_name: tomcat02
image: demo:01
ports:
- "8082:8082"
volumes:
- tomcatwebapps02:/usr/local/tomcat/webapps
networks:
- hello
portainer:
image: portainer/portainer
container_name: portainer
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- portainer_data:/data
ports:
- "8000:8000"
- "9000:9000"
#需要声明数据卷
volumes: #声明上面服务所使用的自动创建的卷名
portainer_data:
ComposeDemo
version: "3.0"
services:
demo:
build: #启动服务先将bui1d命令中指定 dockerfile打包成镜像,再运行该镜像
context: demo #指定上下文目录 dockerfile所在目录
dockerfile: Dockerfile
container_name: hello_demo
ports:
- "8083:8083"
networks:
- hello
depends_on:
- tomcat01
tomcat01:
container_name: tomcat01 #相当于run的 --name
image: demo:01
ports:
- "8081:8081"
volumes: #完成宿主机与容器中目录数据卷共享
- tomcatwebapps01:/usr/local/tomacat/webapps
networks: #代表当前服务使用那个网络桥
- hello
depends_on:
- mysql
- tomcat02
healthcheck:
test: [ "CMD","curl","-f","http://localhost" ]
interval: 1m30s
timeout: 10s
retries: 3
#sysctls: #用来修改容器中系统内部参数 并不是必须 有些服务启动受容器内操作系统参数限可能会无法启动必须过修改容器中参数才能启动
#- net.core.simaxconn=1024
#- net.ipv4.tcp_syncookies=0
#ulimits: #用来修改容器中系统内部进程数限制 日后使用可根据当前容器运行服务要求进行修改
#nproc: 65535
# nofile:
#soft: 20000
#hard: 40000
tomcat02:
container_name: tomcat02
image: demo:01
ports:
- "8082:8082"
volumes:
- tomcatwebapps02:/usr/local/tomcat/webapps
networks:
- hello
mysql:
image: mysql:8.0
container_name: mysql
ports:
- "3307:3306"
volumes:
- mysqldata:/var/lib/mysql
- mysqlconf:/etc/mysql
# environment:
# - MYSQL_ROOT_PASSWORD=root
env_file: #用来将environment环境中配置放入指定配置文件
- mysql.env
networks:
- hello
# redis:
# image: redis:5.0.10
# container_name: redis
# volumes:
# - redisdata:/data
# command: "redis-server --appendonly yes"
portainer:
image: portainer/portainer
container_name: portainer
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- portainer_data:/data
ports:
- "8000:8000"
- "9000:9000"
volumes: #声明上面服务所使用的自动创建的卷名
tomcatwebapps01: #声明指令的卷名 compose自动创建该卷名但是会在之前加入项目名 如 hello_tomcatwebapps
external: #使用自定义卷名 true
false
tomcatwebapps02:
external:
false
mysqldata:
mysqlconf:
portainer_data:
# redisdata:
networks: #定义服务到桥
hello: #定义上面的服务用到的网桥名称