Docker
由于大型项目
- 依赖关系复杂,兼容性问题
- Docker:将应用的LIbs和Deps,配置与应用一起打包形成可移植镜像
- 将每个应用放到一个隔离容器中运行,避免相互干扰
- 开发,测试,生产环境有差异
Docker解决不同系统环境问题
- 将用户程序与所需要调用的系统(如CentOS)函数库一起打包
- Docker运行到不同操作系统时,直接基于打包的库函数,借助操作系统的Linux内核来运行
而且这种程序包已经包含了一切,启动和移除时只需要一个简单的命令
初识Docker
镜像
Docker将应用程序及其所需的依赖,函数库,环境,配置文件等打包在一起,称为镜像,也就是磁盘上的文件
容器
镜像中的应用程序运行后形成的进程就是容器,只是Docker会给容器做隔离,对外不可见
镜像一般都是只读的,如果需要修改镜像中的内容,需要将其中的数据复制一份到自己的容器中进行修改
结构
- 服务端:接受命令或远程请求,操作镜像或容器
- 客户端:发送命令或者请求到Docker服务端
基本操作
镜像
镜像名称一般分为两部分:[repository]:[tag]
没有指定tag时,默认是latest,代表最新版本的镜像
- docker pull:从服务拉取镜像
- docker images:查看镜像
- docker rmi:删除镜像
- docker push:推送镜像到服务
- docker save:保存镜像为压缩包
- docker load:加载压缩包为镜像
可以通过docker –help命令查看所有命令帮助文档
容器
运行镜像:docker run
docker run --name containerName -p 8000:80 -d nginx
# --name:给容器取个名字
#-p:将宿主机端口与容器端口映射,主机端口:容器端口
#-d:后台运行
#nginx:镜像名称
容器暂停:docker pause
容器从暂停状态恢复运行:docker unpause
容器停止:docker stop
容器从停止状态恢复:docker start
查看所有运行的容器及状态:docker ps(默认查看运行状态的容器,加上-a查看所有容器)
查看容器运行日志:docker logs,添加参数-f可以持续查看日志
进入容器执行命令:docker exec
删除指定容器:docekr rm
端口映射作用:将本来隔离的容器暴露一个小口给外界访问
数据卷
解决容器和数据耦合的问题
数据卷是一个虚拟目录,指向宿主机文件系统中的某个目录
我们可以让容器内部文件与数据卷关联,这样我们在宿主机文件做的修改会立即反映到容器内部,这样就解决了容器和数据耦合的问题
操作数据卷
docker volume [command]
command用来确定下一步操作
- create:创建一个volume
- inspect:显示一个或多个volume信息(可以从这里面看挂载在主机的哪个目录)
- ls:列出所有的volume
- prune:删除未使用的volume
- rm:删除一个或多个指定的volume
挂载数据卷
在创建容器的时候,可以通过-v参数来挂载一个数据卷到某个容器目录
-v html:/root/html:把html数据卷挂载到容器内的/root/html目录中
如果容器创建时volume不存在,会被自动创建出来
宿主机目录可以直接与容器挂载
- -v [宿主机目录]:[容器内目录]
- -v [宿主机文件]:[容器内文件]:这样宿主机文件内容会直接覆盖容器内文件内容
自定义镜像
镜像是分层结构,每一层称为一个Layer
- BaseImage层:包含基本的系统函数库,环境变量,文件系统
- Entrypoint:入口,是镜像中应用启动的命令
- 其他:在BaseImage基础上添加依赖,安装程序,完成整个应用的安装和配置
Dockerfile
就是一个文本文件,其中包含一个个指令,用指令来说明要执行什么操作来构建镜像,每个指令都会形成一层Layer
作用就是用来配置镜像的环境以及指定启动命令
- FROM:指定基础镜像 from centos:7
- ENV:设置环境变量,可在后面指令使用
- COPY:拷贝本地文件到镜像的指定目录
- RUN:执行linux的shell命令,一般是安装过程的命令 run yum install gcc
- EXPOSE:指定容器运行时监听的端口,给镜像使用者看的
- ENTRYPOINT:镜像中应用的启动命令,容器运行时调用
例如基于Ubuntu镜像构建一个新镜像,运行java项目
# 指定基础镜像
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
将docker-demo.jar Dockerfile jdk8.tar.gz上传到docker-demo文件夹
利用dockerFile构建镜像:docker build -t javaweb:1.0 .
-t:tag javaweb:1.0自己构建的这个镜像名称和版本,随便起 .:指定Dockerfile所在目录
# 基于已经安装好java8的镜像构建,省略了配置java8的步骤
FROM java:8-alpine
COPY ./docker-demo.jar /tmp/app.jar
# 暴露端口
EXPOSE 8090
# 入口,java项目的启动命令
ENTRYPOINT java -jar /tmp/app.jar
Docker Compose
如果对微服务的每个服务都自定义成镜像,然后运行成容器,显然非常麻烦
Docker Compose可以基于Compose文件帮我们快速的部署分布式应用,无需手动一个个创建和运行容器
Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行
Compose文件就是把docker run和各种参数转换成指令
例如:
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"
如果我们还想添加别的微服务只需要原来的文件夹中新建文件夹,将对应的Dockerfile和该服务的jar包放进去,在上述Compose文件中加入对应创建和运行容器的命令即可
镜像仓库
Docker Registry
- 公共仓库:Docker官方的Docker Hub,网易云镜像服务,阿里云镜像服务等
- 私有仓库:用户可以在本地搭建私有仓库,企业自己的镜像最好是采用私有仓库实现
搭建本地镜像仓库
这里使用DockerCompose部署带有图象界面的DockerRegistry,命令如下:
version: '3.0'
services:
registry:
image: registry
volumes:
- ./registry-data:/var/lib/registry
ui:
image: joxit/docker-registry-ui:static
ports:
- 8080:80
environment:
- REGISTRY_TITLE=我的仓库
- REGISTRY_URL=http://registry:5000
depends_on:
- registry
在私有仓库推送/拉取镜像
在推送前需要将仓库地址配置到docker服务的daemon.json文件中,被docker信任
我们的私服采用的是http协议,默认不被Docker信任,所以需要做一个配置:
# 打开要修改的文件
vi /etc/docker/daemon.json
# 添加内容:
"insecure-registries":["http://81.70.144.35:8080"]
# 重加载
systemctl daemon-reload
# 重启docker
systemctl restart docker
推送镜像到私有镜像服务必须先tag
-
重新tag本地镜像,名称前缀为私有仓库地址
docker tag nginx:latest 81.70.144.35:8080/nginx:1.0 #nginx:latest:镜像原始名称 #81.70.144.35:8080:新名称前缀(私有仓库地址) #nginx:镜像名 #1.0:tag
-
推送镜像
docker push 81.70.144.35:8080/nginx:1.0
-
拉取镜像
docker pull 81.70.144.35:8080/nginx:1.0