docker面试题

介绍下docker

Docker是一个开源的应用容器引擎,使用它可以将应用以及依赖包到一个可移植的容器中,然后发布到任何支持容器的Linux机器上,也可以实现虚拟化。

容器引擎

代表它实现了容器化技术的核心功能。实现容器的创建、启动、停止、销毁等功能。

除了Docker之外,还有CoreOS rkt、LXC、LXD等其他容器引擎可供选择

容器化技术

容器化技术是一种虚拟化技术,其核心在于将应用程序及其所有依赖项打包到一个独立的、标准化的单元中,这个单元被称为容器。

这种技术将应用程序与其运行环境隔离开来,使得应用程序能够在任何支持容器的环境中运行,而无需考虑底层操作系统或硬件的细节。

容器化技术的优势在于其轻量级和可移植性。它不像传统的虚拟机那样去虚拟整个底层计算机,而只是虚拟了操作系统,这大大降低了资源开销。

虚拟化技术

虚拟化技术是一种创建虚拟版本的物理硬件、操作系统、存储设备或网络资源的方法。虚拟化技术是一种将计算机的各种实体资源,如CPU、内存、磁盘空间、网络适配器等,进行抽象和转换的技术。

在实际生产环境中,虚拟化技术主要用于解决物理硬件产能过剩或老旧硬件产能过低的问题,实现资源的最大化利用。

docker的特点

1. 可移植性:Docker容器可以在任何支持Docker的系统上运行,无论是物理机、虚拟机,还是云环境。
2. 一致性:Docker容器包含了运行应用所需的所有内容,这确保了应用在任何环境中都能一致地运行。。
3. 隔离性:每个Docker容器都在自己的环境中运行,互不干扰。
4. 自动化:Docker使用Dockerfile来自动化镜像创建,使应用程序的部署更加快速、一致和可重复。

docker的主要功能

  • 镜像管理:Docker允许你创建、拉取、推送和管理Docker镜像。可以使用Dockerfile来定义镜像的创建过程,或者基于现有的镜像来创建新的镜像。
  • 容器管理:Docker提供了一套命令来创建、启动、停止、移动或删除容器。可以设置容器CPU、内存等资源,可以收集和管理容器的日志
  • 网络管理:Docker提供了网络配置功能,允许你为容器配置网络环境,如创建网络、配置网络模式等。
  • 服务编排:通过Docker Compose和Docker Swarm,Docker可以管理多容器应用的部署和扩展。
  • 安全性:Docker提供了一些安全特性,如使用seccomp、AppArmor、SELinux等来限制容器的权限。

镜像

Docker镜像是通过Dockerfile生成的,用于生成Docker容器。

docker 的镜像是分层的,所有的镜像(除了基础镜像)都是在之前镜像的基础上加上自己这层的内容生成的;

父镜像和基础镜像

当我们创建一个新的Docker镜像时,我们通常会基于一个已存在的镜像进行创建,这个已存在的镜像就被称为父镜像。在Dockerfile中,我们使用FROM指令来指定父镜像。

基础镜像:基础镜像是一个特殊的镜像,它不依赖于其他镜像,通常包含了一个最小化的操作系统。基础镜像通常被用作创建其他Docker镜像的基础。

镜像的组成

Docker镜像由多个层(Layer)组成,每个层都是只读的。这些层一起构成了文件系统。每个层都对应Dockerfile中的一个指令,比如RUN, COPY等。当你改变Dockerfile并重新构建镜像时,只有从你修改的那一行指令开始的后续层会被重新构建,这就是Docker镜像构建的缓存机制。

除了文件系统层,Docker镜像还包含一些元数据,比如镜像的创建时间,镜像的作者,以及构建镜像时的Dockerfile指令等。

Docker的镜像层可以被多个镜像共享。这是因为Docker镜像是由多个只读的层组成的,每个层都是独立的,并且可以被多个镜像共享。这种设计使得Docker镜像非常轻量,因为相同的层只需要存储一次,无论被多少个镜像使用。

容器

Docker容器是一种可执行的独立软件包,它包含了运行某个应用所需的所有内容,包括代码、运行时环境、库、环境变量和配置文件。

Docker容器共享主机系统的内核,不需要像虚拟机那样为每个应用分配操作系统资源,因此它们启动快,占用的资源少。

每个Docker容器都在自己的命名空间中运行,与其他容器隔离。每个容器都有自己的文件系统,不能看到或直接访问其他容器的文件系统。Docker容器设计为与其他容器和宿主机隔离。每个容器都在自己的环境中运行,拥有自己的文件系统,网络栈和进程空间。每个容器在CPU使用、内存使用和网络带宽等资源上都是隔离的。你可以使用Docker的资源限制功能来控制每个容器可以使用的CPU和内存的数量。

在传统的虚拟化技术中,每个虚拟机都运行自己的操作系统,这会占用大量的系统资源。相比之下,Docker容器直接运行在宿主机的操作系统上,所有容器共享同一个内核,但每个容器都在自己的隔离环境中运行。

 

镜像与容器的关系

Docker 容器通过 Docker 镜像来创建。Docker容器是Docker镜像的一个运行实例。你可以从同一个Docker镜像启动多个独立的容器,每个容器都有自己的状态和文件系统。

Dockerfile

一种文本文件,定义了一个Docker镜像的内容和创建过程。

Dockerfile 中的每一行都会创建一个新的镜像层并对镜像进行修改。

FROM:设置父镜像

RUN:镜像构建过程中执行的命令,通常用于安装软件包、设置环境变量、运行构建任务等。可以有多条。

CMD:容器启动阶段执行的命令,用于设置容器启动后默认执行的命令和参数。每个 Dockerfile 只能有一个 CMD 指令。如果指定了多个 CMD 指令,那么只有最后一个 CMD 指令会生效。如果在运行 docker run 命令时指定了任何命令,那么 CMD 指令将会被忽略。如果 Dockerfile 中同时存在 CMD 和 ENTRYPOINT 指令,那么 CMD 中的参数将会被添加到 ENTRYPOINT 指令的参数后面。

ENTRYPOINT:用于设置容器启动时默认执行的命令。

ENV:设置环境变量。这些环境变量在构建镜像和运行容器时都可用。在 RUN, CMD, ENTRYPOINT 等指令中使用,在已经启动的容器中也可以用。

ARG:定义在构建过程中可以使用的变量。这些变量在构建镜像时可用,但在运行容器时不可用。在已经启动的容器中用不了。

VOLUME :用于在容器中创建一个点,与 Docker 主机的文件系统进行交互。比如将日志挂在到宿主机的一个目录,就可以在容器外面看日志了。

EXPOSE:指定容器监听的网络端口

WORKDIR:指定工作目录,续有 RUN, CMD, ENTRYPOINT, COPY 或 ADD 指令,它们会在 /app 目录下执行。指定的工作目录不存在,Docker 会自动创建这个目录

USER:用于设置后续指令(如 RUN, CMD 和 ENTRYPOINT)的执行用户。指定的用户和用户组必须在镜像中存在。如果不存在,你需要在 USER 指令之前使用 RUN 指令来创建它们。

HEALTHCHECK:用于检查容器中的应用是否还在运行。如果应用停止运行,Docker 可以自动重启容器。可以设置健康检查的间隔时间,连续多少次健康检查失败后,容器被认为是不健康等

ONBUILD:用于添加将在后续构建中执行的触发器。这些触发器会在下一次 FROM 指令使用当前镜像作为父镜像时执行。

LABEL:用于添加元数据到镜像。如镜像的版本、构建日期或者维护者的联系信息。

常用命令

exit 命令或者使用 CTRL+D 来退出容器

查看docker命令:docker

查看docker版本:docker --version

查看docker信息:docker info (查看 docker 的根目录、操作系统版本、内核版本、docker 版本、RAM、CPU、docker 注册表等信息。)

查看指定命令帮助:docker run --help,docker images --help

复制文件到容器:docker cp custom.conf Nginx:/etc/nginx/conf.d/

更新容器启动项:docker container update --restart=always nginx

查看docker日志:tail -f /var/log/messages

镜像控制命令

搜索镜像:docker  search  [OPTIONS]  TERM

上传镜像:docker  push  [OPTIONS]  NAME[:TAG]

拉取镜像到本地:docker  pull  [OPTIONS]  NAME[:TAG]

提交镜像:docker  commit [OPTIONS]  CONTAINER  NAME[:TAG]

构建镜像:docker  build  [OPTIONS]  PATH (根据dockerfile文件构建出一个镜像)

删除镜像:docker  rmi [OPTIONS]  IMAGE  [IMAGE...]

增加镜像标签:docker  tag  SOURCE_IMAGE[:TAG]  TARGET_IMAGE[:TAG]

查看已下载的所有镜像:docker  images  [OPTIONS]  [REPOSITORY[:TAG]]

导出docker镜像到本地: docker save -o   指定地址和文件名   镜像名

导入镜像:docker load [OPTIONS]

docker stats 命令后面加上容器的名字或ID,显示的是容器的资源使用情况,CPU使用率,内存使用量,网络I/O,磁盘I/O等

容器控制命令

创建容器(不启动):docker create

启动/重启容器:docker start/restart CONTAINER

停止/强停容器:docker stop/ kill CONTAINER

删除容器:docker rm [OPTIONS] CONTAINER [CONTAINER...]

重命名容器:docker rename CONTAINER CONTAINER_NEW

进入容器:docker attach CONTAINER

执行容器命令:docker exec CONTAINER COMMAND

查看容器日志:docker logs [OPTIONS] CONTAINER

查看运行中容器所有信息:docker ps [OPTIONS]

调整容器的资源限制:docker update

查看某个容器的所有信息:docker inspect

查看容器的公开端口:docker port

查看容器中活动进程:docker top

查看容器的资源使用量统计信息:docker stats

查看容器文件系统中存在改动的文件:docker diff

 

容器启动:

docker  run  [OPTIONS]  IMAGE  [COMMAND]  [ARG...] (创建并启动容器,并在容器里执行指定命令COMMAND)

指定端口映射:宿主机的8080端口映射到容器中的80端口

docker run -p 8080:80 <image_name>

Docker run命令可以通过-v--volume选项来设置挂载。这个选项允许你将宿主机的目录或文件挂载到容器中,实现容器与宿主机之间的数据共享。容器对这个目录的任何修改都会直接反映到宿主机上,反之亦然。

docker run --name <container_name> -v /host/directory:/container/directory <image_name>

 

进入容器内部:其中-it参数表示交互式进入容器,并打开一个终端

docker exec -it 容器名称或id

查看容器内应用日志:

#查看完整日志
docker logs 容器名称或id
#查看最新几行日志
docker logs --tail=10 容器名称或id
#查看实时日志
docker logs -f 容器名称或id
#进入容器内部
docker exec -it 容器名称或id /bin/bash
#使用cat或less等命令查看日志文件。日志文件通常位于/var/log/目录下

使用docker部署怎么设置jvm

jvm也是在容器中的

可以在dockerfile中设置启动时执行的jvm参数信息,也可以使用docker run或docker start命令启动容器时指定jvm参数信息

docker compose

Compose 是用于定义和运行多个docker容器 的工具。通过 Compose,您可以使用 YML 文件(通常命名为 docker-compose.yml)来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。

version: '3'  # Docker Compose 文件的版本
services:  # 定义应用的服务
  web:  # 服务名称
    build: .  # 构建服务的 Dockerfile 所在的路径
    ports:  # 端口映射
     - "5000:5000"  # 宿主机端口:容器端口
  redis:  # 另一个服务名称
    image: "redis:alpine"  # 使用的 Docker 镜像

Compose 使用的三个步骤

  • 使用 Dockerfile 定义应用程序的环境。
  • 使用 docker-compose.yml 定义构成应用程序的服务,这样它们可以在隔离环境中一起运行。
  • 最后,执行 docker-compose up 命令来启动并运行整个应用程序。

Docker Compose 的主要命令包括:
- docker-compose up:启动并运行你的应用
- docker-compose down:停止并移除你的应用
- docker-compose build:构建或重新构建服务
- docker-compose ps:列出你的应用的状态
- docker-compose pull:拉取服务依赖的镜像

构建基本java应用程序

1.、创建一个Dockerfile:在您的项目根目录下创建一个名为Dockerfile的文件。在dockerfile中定义父镜像,工作目录,工作用户,要执行的命令,端口号,挂在点等信息。

2、导航到包含Dockerfile的项目根目录,使用docker build命令来构建出镜像文件

3、使用docker run命令来根据镜像文件生成容器和启动容器

容器之间怎么共享数据

数据卷容器:创建一个专门用于存储数据的容器,然后多个容器通过挂载该容器的卷来共享数据。

数据卷:在宿主机上创建一个可以由多个容器共享的卷,通过将卷挂载到多个容器中,实现数据共享。

通过网络共享:多个容器可以使用同一网络,通过网络共享数据

对于跨宿主机的数据共享,可以使用网络共享存储系统,使得不同宿主机上的容器可以通过挂载相同的网络存储路径来实现数据的共享。

数据卷

指的是宿主机中的一个目录或文件,可以被一个或多个容器所挂载使用

特点:

  1. 持久化:数据卷的生命周期独立于容器的生存周期。即使容器被删除,数据卷中的数据仍然会保留在宿主机上,从而实现了数据的持久化保存。
  2. 共享性:一个数据卷可以同时被多个容器挂载,这样多个容器就可以共享同一份数据。
  3. 双向绑定:容器内对数据卷的修改会立即反映到宿主机上,反之亦然。

Docker数据卷的类型包括匿名卷、命名卷和绑定挂载。匿名卷在创建容器时自动创建,没有特定的名称;命名卷则通过特定的命令创建,具有明确的名称,方便管理和共享;绑定挂载则是将宿主机上的文件或目录直接挂载到容器中。

  1. 匿名卷:
    • 在使用docker run命令创建容器时,如果不指定数据卷的名称和具体的挂载路径,Docker会自动为容器创建匿名卷。例如,使用命令docker run -v /container/path myapp,Docker会在宿主机的某个位置自动创建一个卷,并将其挂载到容器的/container/path路径下。这种自动创建的卷就是匿名卷。
  2. 命名卷:
    • 命名卷是通过在docker run命令中使用-v--volume选项并指定卷名来创建的。例如,命令docker run -v myVolume:/container/path myapp会创建一个名为myVolume的命名卷,并将其挂载到容器的/container/path路径下。命名卷具有明确的名称,方便管理和跨多个容器共享。
    • 另外,也可以在Dockerfile中使用VOLUME指令来指定命名数据卷的名称和数据路径的挂载关系,从而创建命名数据卷。
  3. 绑定挂载:
    • 绑定挂载是通过在docker run命令中使用-v--volume选项,并指定宿主机上的目录或文件以及容器内的挂载路径来创建的。例如,命令docker run -v /host/path:/container/path myapp会将宿主机的/host/path目录或文件挂载到容器的/container/path路径下。这种方式实现了容器与宿主机文件系统之间的直接挂载。

数据卷容器

数据卷容器的概念是指,创建一个容器,该容器的主要作用就是挂载数据卷,并不运行任何应用程序。然后,其他的容器可以挂载这个数据卷容器,从而实现数据共享。

主要作用是通过挂载其他容器来获得其他容器所拥有的数据卷,实现数据共享。当一个容器挂载了数据卷,其他容器可以通过挂载这个容器(父容器)来实现数据共享。这样,数据卷容器就能够在多个容器之间共享数据,提供数据持久化的功能。

 

创建数据卷容器:先创建或拉取一个不运行任何应用镜像。使用docker run命令创建一个容器,使用-v--mount选项来指定数据卷。

其他容器可以通过挂载这个数据卷容器来访问和共享数据。这可以通过在创建这些容器时,使用-v--volumes-from选项来指定要挂载的数据卷容器来实现。

--volumes-from 选项允许你将一个已经存在的容器的数据卷挂载到新的容器中。如

docker run -d --name myappcontainer --volumes-from datavolume myapp

我们根据myapp镜像创建了一个新的容器 myappcontainer,并使用 --volumes-from datavolume 将 datavolume 容器的数据卷挂载到 myappcontainer 容器中。

网络模式

  1. Host模式:在此模式下,容器将直接加入主机的网络栈,与主机共享网络资源。容器将直接使用主机的网络接口和IP地址。这种模式适用于需要容器与主机共享网络资源或容器需要快速访问主机网络服务的场景。这种模式下的安全性较低,因为容器和主机之间的隔离程度较低。
  2. Bridge模式:这是Docker的默认网络模式。它使用一个Docker内置的网桥(如Docker0)作为容器的网络接口。容器之间互相隔离,但可以通过网络互相通信。Bridge模式为每个容器分配Network Namespace子系统,并自动为每个容器虚拟出自己的网卡、IP、网关、路由等信息。因为Bridge模式会为每个容器分配一个虚拟的IP地址,并将其连接到Docker内部的虚拟网桥上,但外部网络并不知道这个内部虚拟IP地址的存在,所以无法直接访问外网
  3. Container模式:在此模式下,多个容器共享同一个网络命名空间。这意味着这些容器可以使用相同的IP地址和端口,它们可以直接通过本地主机名相互通信,就像它们在同一个主机上一样。
  4. None模式:在None模式下,容器没有任何网络接口,也无法与外部网络或其他容器通信。这适用于需要完全隔离的场景。容器之间互相隔离,需要进行端口映射才能访问。

此外,Docker还支持自定义网络模式,允许用户创建和管理自己的网络。

docker network create my_network
docker run --network=my_network -tid -p 8000:8000 image_name

host模式可以直接访问外网

bridge模式需要可以通过配置端口映射来访问外部网络。否则不能访问外网

Container模式和none模式不能访问外网

Harbor

可以使用harbor搭建镜像仓库使用

Docker Hub

是一个由Docker公司负责维护的公共镜像仓库

Docker Swarm

跟k8s一样都是容器编排工具

k8s

是一个开源的容器编排和管理平台,使用k8s可以对容器进行自动化部署、资源调度,扩展/缩减实例数量,负载均衡,快速运维等

使用k8s可以方便的管理docker容器(包括创建、启动、停止、调度、监控、调整容器数量、设置端口映射等操作。)

容器编排:提供了一种声明式的方式来描述应用程序的期望状态,例如定义应用程序的副本数量、资源需求、网络配置等。它们负责将这些声明转化为实际的容器部署和管理操作,包括创建、启动、停止、扩展、监控和自动恢复等。‘简化容器的管理工作,避免人为错误情况。

k8s核心资源对象

Deployment、Service、Pod是k8s最核心的3个资源对象。

pod(容器组)

Pod是Kubernetes中运行容器以及调度的最小单位,同一个Pod可以同时运行多个容器。Pod中的容器共享网络和存储资源,并且它们可以通过本地的localhost进行通信。

Deployment

Deployment用于定义应用程序的部署方式。它可以指定要运行的Pod副本数量,并可以自动进行滚动更新和回滚操作。Deployment还可以定义应用程序的更新策略和健康检查。

Service

定义了一组Pod的访问方式,用于服务发现和服务访问。其他应用程序可以通过Service来访问后端的Pod实例。当创建一个Service时,Kubernetes会为该Service分配一个唯一的虚拟IP地址和端口号。其他应用程序可以通过该虚拟IP地址和端口号来访问该Service。

K8s的Service主要关注于在Kubernetes集群内部实现服务的发现和负载均衡,而Nacos则更侧重于在分布式系统中实现服务的注册、发现和配置管理。

posted @ 2024-03-28 01:20  星光闪闪  阅读(570)  评论(0)    收藏  举报