Docker
组成
镜像image
Docker镜像(image)就是一个只读的模版,镜像可以用来创建Docker容器,一个镜像可以创建多个容器
docker镜像文件类似于java类模版,而docker容器类似于java中new出来的实例对象
容器container
容器就是用镜像创建的运行实例
重点理解:Docker镜像层都是只读的,容器层是可写的
仓库repository
仓库是集中存放镜像文件的场所
最大的公开仓库是Docker Hub(https://hub.docker.com/)
常用命令
帮助启动
启动docker systemctl start docker
停止docker systemctl stop docker
重启docker systemctl restart docker
查看docker状态 systemctl status docker
设置开机启动docker systemctl enable docker
查看当前安装的docker概要信息 docker info
查看docker命令帮助文档 docker 具体命令 --help
镜像命令
查看主机上所有镜像 docker image 同一种镜像会有多个版本信息(TAG)
搜索待使用的镜像 docker search ‘镜像name’
下载镜像 docker pull ‘镜像name:[TAG]’ (根据版本号)拉取对应镜像,若不指定版本号,则是拉取latest
查看镜像空间信息 docker system df ‘镜像name’
删除镜像 docker rmi -f ‘镜像name’ 删除多个:docker rmi -f ‘镜像name’:TAG ‘镜像name’:TAG
容器命令
启动容器 docker run ‘镜像name’
常用参数说明:–name 指定容器的名字 -d 后台运行容器 -it 以交互模式启动 -p 指定端口映射 -v 容器卷挂载
eg:docker run --name myCentos -it centos /bin/bash 启动一个名为myCentos的容器以交互模式启动后打开bash终端
查看当前正在运行的容器 docker ps
启动已停止运行的容器 docker start 容器id或容器名
重启容器 docker restart 容器id或容器名
停止容器 docker stop 容器id或容器名
强制停止容器 docker kill 容器id或容器名
删除已停止的容器 docker rm 容器id
查看容器日志 docker logs 容器id
查看容器内运行的进程 docker top 容器id
查看容器内部细节 docker inspect 容器id
进入正在运行的容器 docker exec -it 容器id bashShell
从容器内拷贝文件到主机上 docker cp 容器id:容器内路径 目的主机路径
导出容器的内容作为一个tar归档文件 docker export 容器id > 文件名.tar
容器数据卷
Docker挂载主机需要打开挂载目录权限 --privileged=true
设计目的:为了数据的持久化,完全独立于容器的生命周期,在容器被删除时Docker不会删除其挂载的数据卷
使用语法:-v /宿主机绝对路径目录:/容器内目录 --privileged=true
特点:
(1)数据卷可以在容器之间共享或重用数据
(2)数据卷中的更改可以直接实时生效
(3)数据卷中的更改不会包含在镜像的更新中
(4)数据卷的生命周期一直持续到没有容器使用它为止
查看数据卷挂载是否成功 docker inspect 容器id
容器与宿主机之间数据是共享的
容器数据卷可以继承:–volumes-from 父类容器名
DockerFile
用来构建Docker镜像的文本文件,由一条条构建镜像所需的指令和参数构成的脚本
FROM
整体dockerFile的第一条必须是FROM指令,表示当前镜像是基于一个已经存在的镜像作为模版
MAINTAINER
镜像维护者的姓名和邮箱地址
RUN
容器构建时(docker build)需要运行的命令
shell格式:RUN <终端命令行> eg:RUN yum -y install vim
exec格式:RUN[“可执行文件”,“参数1”,“参数2”] eg:RUN [“./test.php”,“dev”,“offline” ]
EXPOSE
当前容器对外暴露出的端口
WORKDIR
指定在创建容器后,终端默认登录进来的工作目录
USER
指定该镜像以什么用户来执行(默认是root)
ENV
用来在构建镜像过程中设置环境变量(该环境变量可以在后续任何RUN指令中使用)
ADD
将宿主机目录下的文件拷贝进镜像且会自动处理URL和解压tar压缩包
COPY
拷贝文件和目录到镜像中 COPY[ “src源路径”,“dest目标路径”] dest路径在容器内不存在的话会新建
VOLUME
容器数据卷,用于数据保存和持久化工作
CMD
指定容器启动(docker run)后要做的是事情(多个CMD情况只有最后一个会生效)
实例
#·Centos7镜像具备vim+ifconfig+jdk8的dockerFile
FROM centos
MAINTAINER zzyy<zzyybs@126.com>
ENV MYPATH /usr/local
WORKDIR $MYPATH
#安装vim编辑器
RUN yum -y install vim
#安装ifconfig命令查看网络IP
RUN yum -y install net-tools
#安装java8及lib库
RUN yum -y install glibc.i686
RUN mkdir /usr/local/java
#ADD 是相对路径jar,把jdk-8u171-linux-x64.tar.gz添加到容器中,安装包必须要和Dockerfile文件在同一位置
ADD jdk-8u171-linux-x64.tar.gz /usr/local/java/
#配置java环境变量
ENV JAVA_HOME /usr/local/java/jdk1.8.0_171
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH
ENV PATH $JAVA_HOME/bin:$PATH
EXPOSE 80
CMD echo $MYPATH
CMD echo "success--------------ok"
CMD /bin/bash
在dockerFiel目录下执行 docker build -t 容器名:TAG . (在TAG后有一个空格和一个点)
Network
在Docker启动后(Systemctl start docker)通过ifconfig查询网络情况时,会出现一个docke0的虚拟网桥(bridge类型)
查看docker网络模式命令:docker network ls
创建docker新的网络模式:docker network create net_name 创建一个新的名为net_name的网络模式
查看某一个网络模式:docker network inspext ent_name 查看名为net_name的网络模式详情
删除某一个网络模式:docker network rm net_name 删除名为net_name的网络模式
作用:(1)进行容器间的互联和通信以及端口映射
(2)容器IP变动时可以通过服务名直接网络通信而不受到影响
网络模式介绍:
可以在docker run的时候通过**–network bridge/host**参数指定网络模式
bridge
Docker服务默认会创建一个docker0网桥,在内核层联通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到了同一个物理网络,Docker默认指定了docker0接口的IP地址和子网掩码,让主机和容器之间可以通过网络相互通信
Docker每启动一个容器就会根据Docker网桥(docker0)给容器分配一个IP地址(Container-IP),同时Docker网桥是每个容器的默认网关,在同一个宿主机内的容器之间就能通过容器的Container-IP直接通信
网桥docker0创建一对对虚拟设备接口(宿主机上为veth,容器内为eth0)
然后通过ip addr查看宿主机网络情况发现多出了两个veth
进入tomcat并查看对应的网络情况(每个容器均存在对应eth0,且与宿主机的veth对应)
host
容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace
容器将不会虚拟出自己的网卡而是使用宿主机的IP和端口
使用host模式启动容器的时候无需使用-p 8083:8080进行端口映射,访问容器容器的时候采用宿主机的端口
container
新建的容器和已经存在的一个容器共享一个网络ip配置而不是和宿主机共享
当已存在的容器(被共用的)停止后,新建的容器使用ip addr查询网络情况就只剩下一个本地lo了
自定义
启动两个tomcat容器,存在问题:
· docker run -d -p 8081:8080 --name tomcat81 billygoo/tomcat8-jdk8
· docker run -d -p 8082:8080 --name tomcat82 billygoo/tomcat8-jdk8
容器之间按照IP互ping是可以的,但是按照服务名互ping是不行的
解决方法:使用自定义桥接网络模式
(1)新增名为zzyy_network网络模式
(2)将新建的容器加入自定义网络模式下(–network zzyy_network)
(3)测试:启动tomcat81,通过服务名ping另一个容器tomcat82
Compose
可以管理多个Docker容器组成一个应用。需要定义一个YAML格式配置文件docker-compose.yml,写好多个容器之间的调用关系,一个命令就可以同时启动、关闭这些容器
安装步骤见官网(docker compose下)
docker-compose使用步骤:
(1)编写DockerFile定义各个微服务应用并构建出对应的镜像文件
(2)使用docker-compose.yml定义一个完整的业务单元,安排好整体应用中的各个容器服务
(3)最后执行docker-compose up命令来启动并运行整个应用程序,最后完成一键部署上线
compose常用命令:
compose实例:
#springboot项目 + mysql + redis
version: "3" #docker-compose对应版本
services: #定义所有的容器
microService:
image: zzyy_docker:1.6 #使用的镜像
container_name: ms01 #自定义容器名
ports: #端口映射
- "6001:6001"
volumes: #容器卷挂载
- /app/microService:/data
networks: #使用网络模式
- atguigu_net
depends_on: #定义当前容器依赖的其他容器
- redis
- mysql
#上述文件转化:docker run -d -p 6001:6001 -v /app/microService:/data --network atguigu_net --name ms01 zzyy_docker:1.6
redis:
image: redis:6.0.8
ports:
- "6379:6379"
volumes:
- /app/redis/redis.conf:/etc/redis/redis.conf
- /app/redis/data:/data
networks:
- atguigu_net
command: redis-server /etc/redis/redis.conf #构建容器时执行的命令
mysql:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: '123456'
MYSQL_ALLOW_EMPTY_PASSWORD: 'no'
MYSQL_DATABASE: 'db2021'
MYSQL_USER: 'zzyy'
MYSQL_PASSWORD: 'zzyy123'
ports:
- "3306:3306"
volumes:
- /app/mysql/db:/var/lib/mysql
- /app/mysql/conf/my.cnf:/etc/my.cnf
- /app/mysql/init:/docker-entrypoint-initdb.d
networks:
- atguigu_net
command: --default-authentication-plugin=mysql_native_password #解决外部无法访问
networks: #创建名为atguigu_net的网络模式
atguigu_net:
当使用compose对容器进行编排后,springboot中连接的数据库与redis可以使用容器服务替换原来的ip地址
执行up命令一键生成容器