Java面试题035:一文深入了解Docker
1、Docker简介
Docker 是一个开源项目,诞生于 2013 年初,最初是 dotCloud 公司内部的一个业余项目。它基于 Google 公司推出的 Go 语言实现。 项目后来加入了 Linux 基金会,遵从了 Apache 2.0 协议,项目代码在 GitHub 上进行维护。
Docker是一个客户端-服务器(C/S)架构程序。Docker客户端只需要向Docker服务器或者守护进程发出请求,服务器或者守护进程将完成所有工作并返回结果。
镜像是Docker生命周期中的构建或者打包阶段,而容器则是启动或者执行阶段。 容器基于镜像启动,一旦容器启动完成后,我们就可以登录到容器中安装自己需要的软件或者服务。可以将镜像当作容器的“源代码”。镜像体积很小,非常“便携”,易于分享、存储和更新。
2、Docker安装
Docker官方建议在Ubuntu中安装,因为Docker是基于Ubuntu发布的,而且一般Docker出现的问题Ubuntu是最先更新或者打补丁的。在很多版本的CentOS中是不支持更新最新的一些补丁包的。建议安装在CentOS7.x以上的版本,在CentOS6.x的版本中,安装前需要安装其他很多的环境而且Docker很多补丁不支持更新。
(1)yum 包更新到最新
sudo yum update
(2)安装需要的软件包, yum-util 提供yum-config-manager功能,另外两个是devicemapper驱动依赖的
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
(3)设置yum源为阿里云
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/dockerce/linux/centos/docker-ce.repo
(4)安装docker
sudo yum install docker-ce
(5)安装后查看docker版本
docker -v
(6)设置ustc的镜像
ustc是老牌的linux镜像服务提供者,ustc的docker镜像加速器速度很快。
vi /etc/docker/daemon.json
在该文件中输入如下内容:
{
"registry-mirrors": ["https://docker.mirrors.ustc.edu.cn"]
}
(7)启动docker(重启用restart)
systemctl start docker
(8)停止docker
systemctl stop docker
(9)查看状态
systemctl status docker
3、镜像构建
(1)Dockerfile
Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
WORKDIR:进入容器内部时默认的目录就是工作目录,后续的 COPY
、RUN
等指令都会在这个目录下执行。如果指定的目录不存在,WORKDIR
会自动创建该目录。可以在 Dockerfile 中多次使用 WORKDIR
指令。每次使用都会更改当前的工作目录
COPY:仅用于将文件或目录从构建上下文复制到镜像中,只执行复制操作,不能用于从远程 URL 下载文件,不能自动解压缩压缩文件(如 .tar
, .zip
等)。
# 复制当前目录的所有文件到镜像的 /app 目录
COPY . /app/# 复制单个文件到镜像的 /app 目录
COPY package.json /app/
ADD:除了复制文件或目录外,还支持从远程 URL 下载文件以及自动解压缩文件。
# 从远程 URL 下载文件并复制到镜像中
ADD https://example.com/file.zip /app/# 自动解压缩压缩文件
ADD file.tar.gz /app/# 复制并自动解压缩
ADD source.tar.gz /app/
推荐优先使用COPY
而不是ADD。
CMD:指定容器启动时默认执行的命令。如果定义了多条CMD
指令,只有最后一条会被使用。如果在运行容器时使用了 docker run
命令并提供了参数,这些参数会覆盖 Dockerfile 中的 CMD
指令。
# 使用 exec 形式
CMD ["python", "app.py"]# 使用 shell 形式
CMD python app.py# 作为 ENTRYPOINT 的默认参数
ENTRYPOINT ["python"]
CMD ["app.py"]
ENV:定义环境变量,可以在后续的指令中使用。
案例1:
# 使用 ubuntu 22.04 作为基础镜像
FROM ubuntu:22.04# 设置环境变量,防止交互式提示
ENV DEBIAN_FRONTEND=noninteractive# 更新系统包列表
RUN apt-get update && apt-get install -y --no-install-recommends \python3 \python3-pip \&& rm -rf /var/lib/apt/lists/*# 设置工作目录
WORKDIR /app# 使用 COPY 指令复制本地 Python 脚本到容器的工作目录
COPY hello.py /app/# 设置容器启动命令,运行 Python 脚本
CMD ["python3", "hello.py"]
案例2:
#依赖镜像名称和ID
FROM centos:7#指定镜像创建者信息
MAINTAINER ITCAST#切换工作目录
WORKDIR /usrRUN mkdir /usr/local/java#ADD 是相对路径jar,把java添加到容器中
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
(2)构建镜像
构建容器时 Docker 默认会将 Dockerfile 所在的目录以及 Dockerfile 所在目录的子目录作为构建上下文,如果构建容器时使用啦或访问了构建上下文以外的目录或文件,Docker 将无法访问到这些文件。
sudo docker build --tag ubuntu-python:1.0.0 ./docker build -t nginx:v3 .docker build --no-cache -t yyzb:v37 .
最后一个 . 是上下文路径,默认上下文路径就是 Dockerfile 所在的位置,docker build 命令得知这个路径后,会将路径下的所有内容打包。上下文路径下不要放无用的文件,因为会一起打包发送给 docker 引擎,如果文件过多会造成过程缓慢。
4、镜像相关命令
(1)查看镜像
docker images
REPOSITORY:镜像名称
TAG:镜像标签
IMAGE ID:镜像ID
CREATED:镜像的创建日期(不是获取该镜像的日期)
SIZE:镜像大小
这些镜像都是存储在Docker宿主机的/var/lib/docker目录下
(2)搜索镜像
docker search 镜像名称
NAME:仓库名称
DESCRIPTION:镜像描述
STARS:用户评价,反应一个镜像的受欢迎程度
OFFICIAL:是否官方
AUTOMATED:自动构建,表示该镜像由Docker Hub自动构建流程创建的
(3)拉取镜像
拉取镜像就是从中央仓库中下载镜像到本地
docker pull 镜像名称
(4)删除镜像
删除所有镜像docker rmi `docker images -q`按镜像ID删除镜像docker rmi 镜像ID
5、容器相关命令
(1)查看容器
# 查看正在运行的容器docker ps# 查看所有容器docker ps –a# 查看最后一次运行的容器docker ps –l# 查看停止的容器docker ps -f status=exited
(2)创建与启动容器
# 交互式方式创建容器docker run -it --name=容器名称 镜像名称:标签 /bin/bash# 守护式方式创建容器docker run -di --name=容器名称 镜像名称:标签
-i:运行容器
-t:容器启动后进入命令行。容器创建就能登录进去。即分配一个伪终端。
--name :为创建的容器命名。
-v:目录映射关系(前者是宿主机目录,后者是映射到宿主机上的目录),可以使用多个-v做多个目录或文件映射。注意:最好做目录映射,在宿主机上做修改,然后共享到容器上。
-d:会创建一个守护式容器在后台运行,创建容器后不会自动登录容器
-p:端口映射,前者是宿主机端口,后者是容器内的映射端口。可以使用多个-p做多个端口映射
# 创建MySQL容器docker run -di --name=tensquare_mysql -p 33306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql# 创建tomcat容器docker run -di --name=mytomcat -p 9000:8080
-v /usr/local/webapps:/usr/local/tomcat/webapps tomcat:7-jre7# 创建nginx容器docker run -di --name=mynginx -p 80:80 nginx# 创建redis容器docker run -di --name=myredis -p 6379:6379 redis
(3)停止与启动容器
# 停止容器docker stop 容器名称(或者容器ID)# 启动容器docker start 容器名称(或者容器ID)
(4)目录挂载
在创建容器的时候,将宿主机的目录与容器内的目录进行映射,就可以通过修改宿主机某个目录的文件从而去影响容器。 创建容器 添加-v参数 后边为 宿主机目录:容器目录。
docker run -di -v /usr/local/myhtml:/usr/local/myhtml --name=mycentos3 centos:7
(5)删除容器
# 删除指定的容器docker rm 容器名称(容器ID)
6、仓库
Docker用Registry来保存用户构建的镜像。Registry分为公共和私有两种。Docker公司运营公共的Registry叫做Docker Hub。用户可以在Docker Hub注册账号,分享并保存自己的镜像。
在Docker Hub下载镜像巨慢, 可以自己构建私有的Registry。(这个自己去搜索一下吧)
7、迁移与备份
(1)镜像备份
将镜像保存为tar 文件
docker save -o mynginx.tar mynginx_i
(2)镜像恢复与迁移
先删除掉老镜像 然后执行此命令进行恢复
docker load -i mynginx.tar