目录
Docker基本操作
镜像和容器
当我们利用Docker安装应用时,Docker会自动搜索并下载应用镜像(image)。镜像不仅包含应用本身,还包含应用运行所需要的环境、配置、系统函数库。Docker会在运行镜像时创建一个隔离环境,称为容器(container)。
1、镜像操作
镜像名称一般分两部分组成:[repository]:[tag]。
在没有指定tag时,默认是latest,代表最新版本的镜像
镜像命令
示例:从DockerHub中拉取一个nginx镜像并查看
1、首先去镜像仓库搜索nginx镜像,比如DockerHub:Docker
2、进入官方镜像
查看docker命令
docker --help
复制命令,运行(拉取镜像)
docker pull nginx
拉去完后查看镜像
docker images
示例:利用docker save将nginx镜像导出磁盘,然后再通过load加载回来
利用docker xx --help命令查看docker save和docker load的语法
保存镜像
docker save -o nginx.tar nginx:latest
删除镜像
docker rmi nginx:latest
加载镜像
docker load -i nginx.tar
示例:去DockerHub搜索并拉取一个Redis镜像
1.去DockerHub搜索Redis镜像
2.查看Redis镜像的名称和版本
3.利用docker pell命令拉取镜像
docker pull redis
4.利用docker save命令将redis:latest打包为一个redis.tar包
docker save -o redis.tar redis:latest
5.利用docker rmi删除本地的redis:latest
docker rmi redis:latest
6.利用docker load重新加载redis.tar文件
docker load -i redis.tar
2、容器操作
示例:
Nginx容器运行命令
docker run --name mn -p 80:80 -d nginx
命令解读:
docker run :创建并运行一个容器
--name:给容器起一个名字,比如叫做mn
-p:将宿主机端口与容器端口映射,冒号左侧是宿主机端口,右侧是容器端口
-d:后台运行容器
nginx:镜像名称,例如nginx
示例:确保你的虚拟机已经安装Docker,且网络开通的情况下,执行下面命令即可安装MySQL
docker run -d \
--name mysql \
-p 3306:3306 \
-e TZ=Asia/Shanghai \ #时区
-e MYSQL_ROOT_PASSWORD=123 \ #root用户密码
mysql
docker run :创建并运行一个容器,
-d 是让容器在后台运行
--name mysql :给容器起个名字,必须唯一
-p 3306:3306 :设置端口映射
-e KEY=VALUE :是设置环境变量
mysql :指定运行的镜像的名字
查看创建的容器
docker ps
访问80端口
查看日志
docker logs mn #容器名称
持续跟踪日志:
docker logs -f mn
进入容器
docker exec -it mn bash
命令解读:
docker exec :进入容器内部,执行一个命令
-it:给当前进入的容器创建一个标准输入、输出终端,允许我们与容器交互
mn:要进入的容器的名称
bash:进入容器后执行的命令,bash是一个linux终端交互命令
查看nginx的HTML目录
cd /usr/share/nginx/html
退出容器
exit
停止容器
docker stop mn
启动容器
docker start mn
删除容器,运行中的容器不能删除
docker rm mn
强制删除容器
docker rm -f mn
总结:
查看容器状态: docker ps
添加-a参数查看所有状态的容器删除容器:docker rm
不能删除运行中的容器,除非添加-f参数
进入容器:命令是docker exec -it [容器名][要执行的命令]
exec命令可以进入容器修改文件,但是在容器内修改文件是不推荐的
示例:创建并运行一个redis容器,并且支持数据持久化
3、数据卷(容器数据管理)
容器与数据耦合的问题
1、不便于修改:当我们要修改Nginx的html内容时,需要进入容器内部修改,很不方便。
2、数据不可复用:在容器内的修改对外是不可见的。所有修改对新创建的容器是不可复用的。
3、升级维护困难:数据在容器内,如果要升级容器必然删除旧容器,所有数据都跟着删除了
数据卷(volume)是一个虚拟目录,指向宿主机文件系统中的某个目录。
数据卷操作的基本语法如下
docker volume [COMMAND]
docker volume命令是数据卷操作,根据命令后跟随的command来确定下一步的操作:
create:创建一个volume
inspect:显示一个或多个volume的信息
ls:列出所有的volume
prune:删除未使用的volume
rm:删除一个或多个指定的volume
示例:创建一个数据卷,并查看数据卷在宿主机的目录位置
docker volume create html
查看创建的数据卷
docker volume ls
查看数据卷位置
docker volume inspect html
删除数据卷
docker volume rm html
4、数据卷挂载
我们在创建容器时,可以通过-v参数来挂载一个数据卷到某个容器目录
示例:
nginx的html目录所在位置/usr/share/nginx/html,把这个目录挂载到html这个数据卷上,
方便操作其中的内容。
创建容器并挂载数据卷到容器内的HTML目录
docker run --name mn -p 80:80 -v html:/usr/share/nginx/html -d nginx
docker run 创建并运行
--name mn 容器名称
-p 80:80 端口映射
-v 挂在数据卷
html: 数据卷名称
/usr/share/nginx/html 容器内要挂在的目录
-d 后台运行
nginx 镜像名称
查看挂载位置
docker volume inspect html
html:数据卷名称
数据卷挂载方式:
-v volumeName: /targetContainerPath
如果容器运行时volume不存在,会自动被创建出来
总结:
1. docker run的命令中通过-v参数挂载文件或目录到
容器中:
-v volume名称:容器内目录
-v宿主机文件:容器内文件
-v宿主机目录:容器内目录
2.数据卷挂载与目录直接挂载的
数据卷挂载耦合度低,由docker来管理目录,但是目录较深,不好找
目录挂载耦合度高,需要我们自己管理目录,不过目录容易寻找查看
本地目录挂载
l在执行docker run命令时,使用 -v 本地目录 : 容器内目录 可以完成本地目录挂载
本地目录必须以“/”或 "./" 开头,如果直接以名称开头,会被识别为数据卷而非本地目录
-v mysql : /var/lib/mysql 会被识别为一个数据卷叫mysql
-v ./mysql : /var/lib/mysql 会被识别为当前目录下的mysql目录
示例:基于宿主机目录实现MySQL数据目录、配置文件、初始化脚本的挂载(查阅官方镜像文档)
挂载/root/mysql/data到容器内的/var/lib/mysql目录
挂载/root/mysql/init到容器内的/docker-entrypoint-initdb.d目录,准备的SQL脚本
挂载/root/mysql/conf到容器内的/etc/mysql/conf.d目录,准备的配置文件
# 1.删除原来的MySQL容器
docker rm -f mysql
# 2.进入root目录
cd ~
# 创建mysql目录
mkdir mysql
# 2.进入mysql目录
cd mysql
# 创建目录
mkdir data
mkdir conf
mkdir init
# 3.创建并运行新mysql容器,挂载本地目录
docker run -d \
--name mysql \
-p 3306:3306 \
-e TZ=Asia/Shanghai \
-e MYSQL_ROOT_PASSWORD=123 \
-v ./mysql/data:/var/lib/mysql \
-v ./mysql/conf:/etc/mysql/conf.d \
-v ./mysql/init:/docker-entrypoint-initdb.d \
mysql
5、Dockerfile自定义镜像
镜像结构
总结:
镜像是分层结构,每一层称为一个Layer
Baselmage层:包含基本的系统函数库、环境变量、文件系统
Entrypoint:入口,是镜像中应用启动的命令
其它:在Baselmage基础上添加依赖、安装程序、完成整个应用的安装和配置
Dockerfile语法
Dockerfile就是一个文本文件,其中包含一个个的指令(Instruction),用指令来说明要执行什么操作
来构建镜像。每—个指令都会形成一层Layer。
指令 | 说明 | 示例 |
FROM | 指定基础镜像 | FROM centos:6 |
ENV | 设置环境变量,可在后面指令使用 | ENV key value |
COPY | 拷贝本地文件到镜像的指定目录 | COPY ./mysql-5.7.rpm /tmp |
RUN | 执行Linux的shell命令,一般是安装过程的命令 | RUN yum install gcc |
EXPOSE | 指定容器运行时监听的端口,是给镜像使用者看的 | EXPOSE 8080 |
ENTRYPOINT | 镜像中应用的启动命令,容器运行时调用 | ENTRYPOINT java -jar xx.jar |
更新详细语法说明,请参考官网文档:Dockerfile reference
我们可以基于Ubuntu基础镜像,利用Dockerfile描述镜像结构
# 指定基础镜像
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
# 入口,java项目的启动命令
ENTRYPOINT ["java", "-jar", "/app.jar"]
我们可以基于Ubuntu基础镜像,利用Dockerfile描述镜像结构,也可以直接基于JDK为基础镜像,省略前面的步骤
当编写好了Dockerfile,可以利用下面命令来构建镜像
docker build -t myImage:1.0 .
-t :是给镜像起名,格式依然是repository:tag的格式,不指定tag时,默认为latest
. :是指定Dockerfile所在目录,如果就在当前目录,则指定为"."
自定义镜像
1、上传文件
Dockerfile文件
# 基础镜像
FROM openjdk:11.0-jre-buster
# 设定时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 拷贝jar包
COPY docker-demo.jar /app.jar
# 入口
ENTRYPOINT ["java", "-jar", "/app.jar"]
上传jdk文件并加载镜像
docker load -i jdk.tar
进入工程目录打包镜像
docker build -t docker-demo .
查看镜像
启动镜像
docker run -d --name dd -p 8080:8080 docker-demo
查看状态
查看日志
docker logs -f dd
成功启动
6、Docker容器网络
查看容器信息
docker inspect mysql
网络和pi
默认情况下,所有容器都是以bridge方式连接到Docker的一个虚拟网桥上:
加入自定义网络的容器才可以通过容器名互相访问,Docker的网络操作命令如下
命令 | 说明 | 文档地址 |
docker network create | 创建一个网络 | |
docker network ls | 查看所有网络 | |
docker network rm | 删除指定网络 | |
docker network prune | 清除未使用的网络 | |
docker network connect | 使指定容器连接加入某网络 | |
docker network disconnect | 使指定容器连接离开某网络 | |
docker network inspect | 查看网络详细信息 |
示例:
# 查看网络
docker network ls
# 创建网络
docker network create 网络名称
加入指定网络
docker network connect demo mysql
启动时就加入指定网络
docker run -d --name dd -p 8080:8080 --network demo docker-demo
# --name dd 名称
# -p 8080:8080 端口
# --network demo 加入网络 demo为名称
# docker-demo 镜像