1.容器与docker
1.什么是容器?
容器是一种轻量级的,可移植的软件运行环境。它将软件程序本身及软件依赖库打包在一起。可以在不同平台和系统上运行。
2.什么是LXC
LXC就是Linux container,。LXC是一种虚拟化技术,可以在操作系统层级上为应用 程序提供虚拟的运行环境,内含应用程序本身的代码、所需要的操作系统kernel和依赖的库文件,这个 虚拟的运行环境就是一个容器
3.容器的特点
1.轻量级:容器共享宿主机,内部只有需要的软件和安装软件所需的依赖库。
2.可移植:容器可以被打包在其他平台使用
3.隔离性:每个容器之间资源都是独立,互不影响
4.快速启动:启动速度比在虚拟机快速
4.容器和虚拟机的区别
容器共享主机内核,内部只有软件本身和软件安装的依赖库,每个虚拟机需要完整的操作系统,容器启动更加快;容器的隔离性相对弱于虚拟机,容器的安全性弱于虚拟机;容器占用资源比虚拟机少,所以容器更加轻量级。容器启动更加快;
2.docker是什么?
Docker 是一个开源的容器化平台,它允许开发者和系统管理员打包、运行、管理和部署应用程序及其依赖项。 docker的核心就是容器。由go语言开发实现,内部使用namespace,cgroup等技术对进程进行封装隔离的虚拟化技术。
runc是命令行工具,用于创建和运行容器。
containerd是一个守护进程,管理容器的生命周期。
1.docker的架构
Docker 的架构设计是围绕容器技术构建的,旨在提供一个轻量级、可移植且高效的运行环境。以下是 Docker 架构的主要组成部分:
-
Docker 守护进程(Docker Daemon):
-
也称为
dockerd
,是 Docker 的后台服务,负责管理 Docker 对象,如镜像、容器、网络和卷。 -
它监听 Docker 客户端的请求,执行这些请求,并返回响应。
-
-
Docker 客户端(Docker Client):
-
也称为
docker
命令行工具,是用户与 Docker 守护进程交互的方式。 -
客户端发送请求到守护进程,并显示守护进程返回的结果。
-
-
Docker 镜像(Images):
-
镜像是 Docker 世界的静态构建,它们是只读的模板,用于创建容器。
-
镜像由一系列层组成,每一层代表 Dockerfile 中的一个指令。
-
-
Docker 容器(Containers):
-
容器是镜像的运行实例,是 Docker 架构中的运行时组件。
-
容器在隔离的环境中运行,并且拥有自己的文件系统、网络配置和进程空间。
-
-
Docker Registry:
-
是存储 Docker 镜像的服务。最知名的公共 Registry 是 Docker Hub,但用户也可以设置私有 Registry。
-
Docker 守护进程在需要时会从 Registry 下载镜像,并在本地机器上运行。
-
-
Dockerfile:
-
是一个文本文件,包含了一系列的指令,用于自动化创建 Docker 镜像。
-
开发者可以使用 Dockerfile 来定义他们的应用环境。
-
-
Docker Compose:
-
是一个工具,用于定义和运行多容器 Docker 应用程序。
-
使用 YAML 文件来配置应用程序的服务,然后使用一个单独的命令即可启动和停止所有服务。
-
-
Docker 卷(Volumes):
-
用于持久化数据,独立于容器的生命周期。
-
卷可以被多个容器访问,并且可以在容器之间共享数据。
-
-
Docker 网络(Networks):
-
允许容器之间以及容器与外部世界之间进行通信。
-
Docker 提供了多种网络驱动,允许用户创建自定义网络。
-
-
Docker 插件(Plugins):
-
Docker 插件是一种扩展机制,允许用户扩展 Docker 的功能。
-
插件可以用于各种目的,如网络、卷、认证等。
-
-
Docker Swarm:
-
是 Docker 自带的容器编排工具,用于管理多个 Docker 主机上的容器。
-
Docker Swarm 允许用户创建一个容器集群,并且可以自动分发容器跨多个主机。
-
-
Docker API:
-
Docker 守护进程提供了一个 RESTful API,允许用户和工具与 Docker 守护进程交互。
-
Docker 客户端实际上是对 Docker API 的包装。
-
Docker 架构的设计目标是提供一个简单、灵活且可扩展的平台,用于开发、交付和部署应用程序。通过容器化技术,Docker 使得应用程序的部署、扩展和管理变得更加高效和可靠。
2.docker的三大组件
Docker有三个重要的概念:仓库、镜像和容器 ,它们是Docker的三大基础组件。
Docker 镜像是一个特殊的文件系统,镜像是Docker中的一个只读模板,它包含了运行一个应用所需的所有内容——代码、运行时、库、环境变量和配置文件。镜像是容器运行的基础,容器是镜像的运行实例 。镜像不包含任何动态数 据,其内容在构建之后也不会被改变。
容器就是运行的镜像,它的实质就是进程,,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的命名空间。
仓库用来保存镜像,可以理解为代码控制中的“代码仓库”。最常用的公开仓库是 Docker Hub,用户可以在其中找到并使用别人创建的镜像,也可以将自己创建的镜像推送到仓库中供其他人使用。 每个仓库可以包含多个 标签(Tag);每 个标签对应一个镜像。
3.docker容器实现原理
利用namespace实现资源隔离,通过cgroup实现资源限制,利用联合文件系统实现文件系统隔离。
4.docker基础命令
1.docker安装
yum -y install yum-utils
yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager --add-repo https://mirrors.aliyun.com/docker
ce/linux/centos/docker-ce.repo
yum install -y docker-ce docker-ce-cli containerd.io
# 这条命令安装 Docker 社区版(docker-ce)、Docker 命令行接口(docker-ce-cli)和 Docker 运行时(containerd.io)。
systemctl start docker
2.docker命令
镜像操作:
检索: docker search image_name
eg:
docker search nginx
下载:docker pull images_name:[tag] 没加tag,默认拉取最新版
eg:
docker pull nginx
# docker pull 下来的命令都默认存在/var/lib/docker/文件夹下。
列表:docker images
docker images
删除:docker rmi -f [强制删除] image_Id # 先停只容器在删除
容器:
docker run image # 运行容器
[-d # 后台运行]
[--name #自定义容器名称 ]
[-p 宿主机端口:容器端口的映射]
docker stop container_id # 停止某个容器
docker start container_id # 启动容器
docker restart container_id # 重启容器
docker exec -it container_Id /bin/bash # 进入容器内部打开新的终端
docker attech container_id # 直接进入容器启动命令的终端,不会启动新的进程
docker rm container_id # 删除容器
docker cp 容器id:路径 宿主机路径
docker cp 宿主机路径 容器id:路径
docker stats container_id
# docker stats 是 Docker 提供的一个命令,用于实时显示容器的资源使用情况,包括 CPU 使用率、内存使用量、网络 I/O 等。如果你想要查看特定容器的资源使用情况,你可以使用容器的 ID 或名称作为参数。
保存:
docker commit :
[root@localhost ~]# docker commit 6d78a3b28c1e mynginx:v1.0
sha256:aae038db1e88b3084b1fd24e2c01b59ca041b52e05b78dad6a31fe100307e762
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mynginx v1.0 aae038db1e88 9 seconds ago 192MB
nginx latest 7f553e8bbc89 11 days ago 192MB
hello-world latest d2c94e258dcb 17 months ago 13.3kB
docker save -o name.tar container_id # 将container保存为压缩文件
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mynginx v1.0 aae038db1e88 9 seconds ago 192MB
[root@localhost ~]# docker save -o my_nginx.tar mynginx:v1.0
[root@localhost ~]# ls
my_nginx.tar
docker load < name.tar # 将压缩包导入images
保存先commit,然后save
Docker 的目录挂载和卷映射是两种不同的数据持久化和共享机制,它们各自有不同的特点和适用场景。
-
目录挂载(Bind Mounts):
-
目录挂载是将宿主机上的一个目录挂载到容器内部的目录。这种方式使得容器可以访问和修改宿主机上的实际文件系统。
-
目录挂载的命令通常是使用
-v
参数,格式为-v /宿主机目录:/容器目录
。 -
例如,将宿主机的
/home/user/data
目录挂载到容器的/data
目录中,可以使用命令:docker run -v /home/user/data:/data image_name
。 -
目录挂载适合于开发和测试环境,以及需要将宿主机上的代码或配置文件挂载到容器内进行快速修改和测试的场景。
-
需要注意的是,容器内部默认使用 root 用户运行,如果挂载的目录在宿主机上的权限不是 root,可能会导致权限问题。解决这个问题的一种方法是使用
--user
参数指定容器内部的用户和组的 ID,或者在宿主机上调整目录的权限 。
-
-
卷映射(Volumes):
-
卷映射是 Docker 管理的一种数据持久化机制,它创建了一个独立的存储区域,可以被多个容器挂载和共享数据。
-
卷映射的命令也是使用
-v
参数,但通常需要先创建一个卷,格式为-v 卷名称:/容器目录
。 -
例如,创建一个名为
myvolume
的卷,并将其挂载到容器的/usr/share/nginx/html
目录中,可以使用命令:docker volume create myvolume
和docker run -d --name web -v myvolume:/usr/share/nginx/html nginx:latest
。 -
卷映射适合于生产环境和需要持久化存储的场景,如数据库数据、应用程序日志等。它提供了更好的数据安全性和独立性,并且可以在多个容器之间共享数据。
-
Docker 卷是由 Docker 管理的,存储在 Docker 的数据目录中,通常是
/var/lib/docker/volumes/
。这意味着即使容器被删除,卷中的数据也不会丢失 。
-
总结来说,目录挂载提供了一种直接在宿主机和容器之间共享文件系统的方法,而卷映射则提供了一种由 Docker 管理的数据持久化和共享机制。根据具体的应用场景和需求,可以选择适合的挂载方式。
docker run -d -v /root/docker_mount/index.html:/usr/share/nginx/html/index.html -p 85:80 nginx
3.docker核心技术
1.namespace
Mount Namespace 用来隔离文件系统的挂载点,不同的 Mount namespace 拥有各自独立的挂载点信 息。 UTS Namespace 用来隔离系统的主机名、hostname和NIS 域名。 IPC 就是在不同进程间传递和交换信息。IPC Namespace 使得容器内的所有进程,进行的数据传输、共享数据、通知、资源共享等范围控制在所属容器内部,宿主机和其他容器没有干扰。 PID namespaces用来隔离进程的 ID 空间,使得不同容器里的进程 ID 可以重复,相互不影响 Network namespace 用来隔离网络,每个 namespace 可以有自己独立的网络栈,路由表,防火墙规则等 查看namespace # 进入/proc/目录 cd /pro # 查看当前目录下有哪些文件或目录 ls # 随便进入一个以数字(进程号)命名的目录,比如1 cd 1 # 查看ns(Namespace)目录下的内容 ls -al ns
2.cgroup
CGroup 是用来对进程进行资源管理的,因此 CGroup 需要考虑如何抽象这两种概念:进程和资源,同时如何组织自己的结构。
3.容器运行时
容器运行时是指管理容器的一系列软件,提供管理的环境和隔离,包括容器的创建,启动,停止和销毁等生命周期管理任务,以及与宿主的交互。
4.文件联合系统
Docker 的文件联合系统(Union File System)是 Docker 镜像和容器实现其轻量级和快速特性的关键技术之一。它允许多个文件系统层(Layers)合并为一个单一的文件系统视图。这种技术允许 Docker 镜像被构建为一系列只读层,然后在运行容器时添加一个可写层。 以下是 Docker 文件联合系统的主要特点和工作原理:
-
镜像层的堆叠:
-
Docker 镜像由多个只读层组成,每一层代表 Dockerfile 中的一个指令(例如,基于基础镜像的层、复制文件的层、执行命令的层等)。
-
这些层被堆叠在一起,每一层都建立在前一层之上,形成一个完整的文件系统。
-
-
联合挂载(Union Mount):
-
当 Docker 启动一个容器时,它会在镜像层的顶部添加一个空的可写层,这通常被称为“容器层”或“OverlayFS”层。
-
联合挂载将这些层合并为一个单一的文件系统,使得容器看起来像是在操作一个完整的文件系统,而实际上它是多个层的组合。
-
-
文件查找机制:
-
当容器尝试访问文件或目录时,Docker 文件联合系统会从顶层(容器层)开始查找。
-
如果文件在顶层不存在,系统会向下查找到下一层,依此类推,直到找到文件为止。
-
-
写入操作:
-
当容器需要修改或创建文件时,由于所有底层都是只读的,这些更改只能在最顶层(容器层)进行。
-
这意味着任何对文件的更改或新文件的创建都会发生在容器层,而不会影响下面的只读层。
-
-
删除操作:
-
删除操作在 Docker 文件联合系统中稍微复杂一些。当删除容器层的文件时,实际上文件并没有被删除,而是在该层创建了一个“白出”(whiteout)文件,用于标记该文件已被删除。
-
白出文件是一种特殊的文件,用于指示原本的文件已被删除,但这个操作只影响当前层,不影响下面的层。
-
-
性能和空间效率:
-
文件联合系统使得 Docker 镜像非常高效,因为多个容器可以共享相同的只读层,只有修改的部分需要额外的空间。
-
这种设计减少了存储空间的使用,并提高了性能,因为容器可以利用现有的只读层,而不需要复制整个文件系统。
-
-
支持的文件系统:
-
Docker 支持多种文件系统来实现联合挂载,包括 AUFS、OverlayFS、Overlay2(OverlayFS 的改进版)和 Btrfs 等。
-
这些文件系统在不同的内核版本和不同的 Linux 发行版中可用,Docker 会根据宿主机的环境自动选择最合适的文件系统。
-
5.镜像制作(docker file)
[root@localhost ~]# cat docker_mount/dockerfile1
# 使用官方 CentOS 8 基础镜像
FROM nginx
# 使用 LABEL 替代 MAINTAINER
LABEL maintainer="charlotte <2974282783@qq.com>"
# 设置环境变量
ENV MYPATH=/usr/local/
# 设置工作目录
WORKDIR $MYPATH
# 复制 index.html 文件到 Nginx 目录
ADD index.html /usr/share/nginx/html/
# 暴露 80 端口
EXPOSE 80
在 Docker 中,CMD
、RUN
和 ENTRYPOINT
是 Dockerfile 中的三个不同的指令,它们各自有不同的用途和行为:
CMD
-
用途:提供了容器启动时默认执行的命令和参数。
-
行为:如果容器没有指定运行命令,
CMD
指定的命令会被执行。如果指定了运行命令,CMD
指令的内容会被忽略。 -
格式:可以是 shell 命令或 exec 形式。
-
示例:
CMD ["nginx", "-g", "daemon off;"]
或者
CMD nginx -g daemon off;
-
特点:
CMD
指令可以被docker run
命令行中指定的参数覆盖。
RUN
-
用途:用于在构建镜像时执行命令,比如安装软件包、编译代码等。
-
行为:
RUN
指令执行的命令会在 Dockerfile 构建过程中执行,并创建新的镜像层。 -
格式:可以是 shell 命令或 exec 形式。
-
示例:
RUN apt-get update && apt-get install -y nginx
或者
RUN ["apt-get", "update"] RUN ["apt-get", "install", "-y", "nginx"]
-
特点:
RUN
指令的输出会保存在新创建的镜像层中,不会在容器运行时执行。
ENTRYPOINT
-
用途:指定容器启动时执行的可执行文件或脚本。
-
行为:
ENTRYPOINT
指令指定的命令会在容器启动时执行,并且可以接收CMD
指令或docker run
命令行参数作为参数。 -
格式:通常是 exec 形式。
-
示例:
ENTRYPOINT ["nginx", "-g", "daemon off;"]
-
特点:
ENTRYPOINT
指令不会被docker run
命令行参数覆盖,除非使用--entrypoint
选项。
区别总结:
-
执行时机:
-
RUN
:在构建镜像时执行。 -
CMD
和ENTRYPOINT
:在容器启动时执行。
-
-
是否可覆盖:
-
CMD
:可以被docker run
命令行参数覆盖。 -
ENTRYPOINT
:不会被docker run
命令行参数覆盖,除非使用--entrypoint
选项。
-
-
默认行为:
-
CMD
:如果没有指定运行命令,CMD
提供默认的运行命令。 -
ENTRYPOINT
:容器启动时必须执行的命令。
-
-
格式:
-
CMD
和ENTRYPOINT
:可以是 shell 命令或 exec 形式. -
RUN
:通常是 shell 命令,用于构建过程中的命令执行。
-
理解这些指令的不同用途和行为对于编写有效的 Dockerfile 和管理容器的生命周期至关重要。
6.docker网络
1.bridge桥接模式
1.1 docker默认桥接
Docker默认使用birdge桥接方式与容器通信,启动 Docker后,宿主机上会产生docker0这样一个虚拟网络接口, docker0不是一个普通的网络接口, 它是 一个虚拟的以太网桥,可以为绑定到docker0上面的网络接口自动转发数据包,这样可以使容器与宿主 机之间相互通信。如图:b1和b2是默认桥接,只能ping ip。
1.2 docker自定义桥接
ping 测试过程中,输入的并不是 IP,而是容器名。 在自定义网桥中,容器名会在需要的时候自动解析到对应的 IP,也解决了容器重启可能导致 IP 变动的 问题。
2.host模式
host 模式下的容器与宿主机共享同一个网络环境,容器可以使用宿主机的网卡和外界的通信,不需要转 发拆包,性能好。但 host 模式也有非常严重的缺点:容器没有隔离的网络,会与其他服务竞争宿主机的 网络,导致宿主机网络状态不可控,因此无法用在生产环境 。
docker run -d -t --network host --name h0 nginx
3.container模式
与 host 模式类似,container 模式可以使一个容器共享另一个已存在容器的网络,此时这两个容器共同 使用同一网卡、主机名、IP 地址,容器间通讯可直接通过本地回环 lo 接口通讯。
docker run -d -t --name n0 nginx
docker run -d -t --network container:n0 --name n0-net centos
7.docker compose
Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。它使用一个 YAML 文件来配置应用程序的服务、网络和卷。这个 YAML 文件通常被称为 docker-compose.yml
文件。
使用 Docker Compose,你可以用一个单独的命令来启动和停止所有服务,而不需要分别使用 Docker 命令来操作每个容器。这使得管理多容器应用程序变得简单和高效。
语法:
name: myblog
services:
mysql123:
container_name: mysql
image: mysql:8.0
ports:
- "9999:3306"
environment:
- MYSQL_ROOT_PASSWORD=123456
- MYSQL_DATABASE=wordpress
volumes:
- mysql-data:/var/lib/mysql
- /app/myconf:/etc/mysql/conf.d
restart: always
networks:
- blog
wordpress:
image: wordpress
ports:
- "9991:80"
environment:
WORDPRESS_DB_HOST: mysql
WORDPRESS_DB_USER: root
WORDPRESS_DB_PASSWORD: 123456
WORDPRESS_DB_NAME: wordpress
volumes:
- wordpress:/var/www/html
restart: always
depends_on:
- mysql123
networks:
- blog
volumes: # 如果是卷映射,需要在此声明
mysql-data:
wordpress:
networks:
blog:
docker compose up -d
docker compose ps
docker compose top