docker-学习-2

docker学习第二天

  • docker学习第二天
    • 1.docker和虚拟机的区别
    • 2.docker的底层隔离机制
      • [2.1 Namespaces(命名空间)](#2.1 Namespaces(命名空间))
        • [2.1.1 什么是命名空间](#2.1.1 什么是命名空间)
      • [2.2 Cgroups](#2.2 Cgroups)
      • [2.3 Union file systems](#2.3 Union file systems)
      • [2.4 Container format](#2.4 Container format)
      • [2.5 docker在底层如何做隔离的,如何进行资源限制的?](#2.5 docker在底层如何做隔离的,如何进行资源限制的?)
    • [3. docker命令](#3. docker命令)
      • [3.1 启动MySQL 容量限制cpu使用率为50% 内存为2G,如何看是否启用了限制?](#3.1 启动MySQL 容量限制cpu使用率为50% 内存为2G,如何看是否启用了限制?)
      • [3.2 docker top](#3.2 docker top)
      • [3.3 思考:如何限制容器使用网络带宽资源?](#3.3 思考:如何限制容器使用网络带宽资源?)
      • [3.4 细讲一下docker run](#3.4 细讲一下docker run)
      • [3.5 docker rm](#3.5 docker rm)
      • [3.6 docker rmi](#3.6 docker rmi)
      • [3.7 docker rm和rmi的区别](#3.7 docker rm和rmi的区别)
    • [4. 一些小知识点](#4. 一些小知识点)
      • [4.1 kernel的作用](#4.1 kernel的作用)
      • [4.2 假如我们不使用容器进程,我们想限制一个Linux操作系统里的进程使用多少cpu和多少内存?](#4.2 假如我们不使用容器进程,我们想限制一个Linux操作系统里的进程使用多少cpu和多少内存?)
      • [4.3 docker容器的三种状态](#4.3 docker容器的三种状态)
      • [4.4 小结一下](#4.4 小结一下)

docker学习第二天

1.docker和虚拟机的区别

2.docker的底层隔离机制

2.1 Namespaces(命名空间)

2.1.1 什么是命名空间

简单来讲:命名空间就是在内存中存放数据的空间(存放变量,函数,库等)

就相当于一块地盘,梁山!梁山上的一草一木都是你命名的,这块地盘归你管理!

Namespaces是Linux内核的一个特性,它可以为进程提供一个隔离的环境,使得进程和其他进程运行在不同的"空间"中。Docker使用了以下几种namespaces来隔离容器的运行环境

  • **PID Namespace:**隔离进程ID,每个容器都有自己的进程ID空间。
  • **NET Namespace:**隔离网络接口,每个容器都有自己的网络空间。
  • **IPC Namespace:**隔离System V IPC和POSIX message queues,每个容器都有自己的IPC空间。
  • **MNT Namespace:**隔离文件系统挂载点,每个容器都有自己的文件系统。
  • **UTS Namespace:**隔离hostname和domainname,每个容器都有自己的hostname。
  • **user Namespace: ** 用户命名空间。

我们每起一个容器就是在内存中开辟一块空间

同样的每一个容器也代表着一个进程

2.2 Cgroups

Cgroups(control groups)是Linux内核的一个特性,它可以限制、记录和隔离进程组所使用的物理资源,包括CPU、内存、磁盘I/O等。Docker使用cgroups来限制和控制容器对物理资源的使用。

2.3 Union file systems

Union file systems,或者叫unionfs,是一种文件系统服务,它可以将多个不同位置的目录合并到一个虚拟的文件系统中。Docker使用unionfs来支持镜像的层次结构,每一层都可以添加、修改或删除文件,而不影响其他层。

2.4 Container format

Docker使用自己的容器格式来打包和运行容器。这个格式定义了容器的内容和运行时的参数,包括容器使用的镜像、网络配置、环境变量等。

2.5 docker在底层如何做隔离的,如何进行资源限制的?

Namespaces和Cgroups联系起来进行隔离和资源限制

隔离 - Namespaces

Namespaces是Linux内核的一个特性,它可以为进程提供一个隔离的环境,使得进程和其他进程运行在不同的"空间"中。Docker使用了以下几种namespaces来隔离容器的运行环境:

  • PID Namespace:隔离进程ID,每个容器都有自己的进程ID空间。-->进程命名空间
  • NET Namespace:隔离网络接口,每个容器都有自己的网络空间。-->网络命名空间
  • IPC Namespace:隔离System V IPC和POSIX message queues,每个容器都有自己的IPC空间。类似于管道的作用。
  • MNT Namespace:隔离文件系统挂载点,每个容器都有自己的文件系统。
  • UTS Namespace:隔离hostname和domainname,每个容器都有自己的hostname。和时间相关。
  • user Namespace: 用户命名空间。

资源限制 - Cgroups

Cgroups(control groups)是Linux内核的一个特性,它可以限制、记录和隔离进程组所使用的物理资源,包括CPU、内存、磁盘I/O等。Docker使用cgroups来限制和控制容器对物理资源的使用。

例如,你可以设置一个容器只能使用1GB的内存和50%的CPU。当容器试图使用更多的资源时,cgroups会阻止它并可能杀死一些进程来保持资源使用在限制之内。

举个例子

悟空,八戒,嫦娥是不同的容器

👆图说明:不同的容器之间可以使用相同的命名空间

3. docker命令

3.1 启动MySQL 容量限制cpu使用率为50% 内存为2G,如何看是否启用了限制?

shell 复制代码
docker run -d --name sc-mysql-2 -p 3307:3306\
    --cpus=".5" \
    --memory="2g" \
    -e MYSQL_ROOT_PASSWORD='sc123456' \
    mysql:5.7.43
shell 复制代码
[root@docker-1 ~] docker stats
CONTAINER ID   NAME         CPU %     MEM USAGE / LIMIT     MEM %     NET I/O       BLOCK I/O         PIDS
168628a39c9b   sc-mysql-2   0.35%     205.2MiB / 2GiB       10.02%    656B / 0B     1.81MB / 583MB    27

该命令在Docker中启动了一个名为sc-mysql-2的MySQL容器实例,并设置了相关参数来控制资源和配置,具体的参数解释如下:

  • docker run: Docker的命令,用于创建并启动一个新的容器。

  • -d: 表示容器将在后台运行(detached mode),即容器启动后不会占用当前的命令行界面。

  • --name sc-mysql-2: 设置容器的名称为sc-mysql-2,方便后续的管理操作,如停止和删除容器。

  • -p 3307:3306: 端口映射参数。将容器内部的3306端口(MySQL默认端口)映射到宿主机的3307端口。这样,宿主机上的应用程序可以通过访问localhost:3307来与容器内的MySQL服务器通信。

  • --cpus=".5": 限制容器的CPU使用率。在这里,设置为0.5意味着容器最多可以使用50%的CPU资源。如果是多核CPU,这表示容器可以使用半核的CPU时间。

  • --memory="2g": 限制容器可以使用的最大内存量为2GB。如果容器试图使用超过这个限制的内存,可能会触发OOM(Out of Memory)管理机制,导致容器内的进程被终止。

  • -e MYSQL_ROOT_PASSWORD='sc123456': 通过环境变量设置MySQL的root用户密码。MYSQL_ROOT_PASSWORD是MySQL容器初次启动时必须设置的环境变量,用于定义root用户的密码。在这个例子中,密码被设置为sc123456

  • mysql:5.7.43: 指定使用的Docker镜像,这里使用的是MySQL的官方Docker镜像,版本是5.7.43

综上所述,这个命令将会在Docker中创建一个新的MySQL容器,该容器在后台运行,拥有2GB的内存限制和50%的CPU使用限制,其root用户的密码设置为sc123456。外部可以通过宿主机的3307端口与容器内的MySQL服务进行通信。

另一种方式

shell 复制代码
[root@docker-1 ~] docker run -d --name sc-mysql-3 -p 3308:3306 --cpu-shares 500 --cpus 2 --cpuset-cpus 0,1 -m 2000000000 --device-write-bps /dev/sda:20MB  -e MYSQL_ROOT_PASSWORD='sc123456'     mysql:5.7.43
938d53c057a172472fdde927f25d89c709e467d19eceebe2923d31f2e2907627

这条命令在Docker中启动了一个名为sc-mysql-3的MySQL容器实例,并配置了多个资源限制参数和环境变量。以下是该命令各个参数的详细解释:

  • docker run: Docker的命令,用于创建并启动一个新的容器实例。

  • -d: 表示容器将在后台运行(detached mode),即容器启动后不会占用当前的命令行界面。

  • --name sc-mysql-3: 指定了新容器的名称为sc-mysql-3

  • -p 3308:3306: 将容器内部的3306端口(MySQL默认端口)映射到宿主机的3308端口。这样,宿主机上的应用程序可以通过访问localhost:3308来与容器内的MySQL服务器通信。

  • --cpu-shares 500: 设置容器的CPU共享权重为500。在同一宿主机上,CPU资源将按照容器的权重被分配,权重越高的容器在CPU资源紧张时获得的份额越多。

  • --cpus 2: 限制容器可以使用的CPU核心数为2。这意味着容器可以使用两个CPU核心的全部性能。

  • --cpuset-cpus 0,1: 绑定容器到特定的CPU核心,只允许容器在CPU 0和CPU 1上运行。

  • -m 2000000000: 限制容器可以使用的内存为2GB。这里使用字节作为单位,2000000000字节等于大约2GB。

  • --device-write-bps /dev/sda:20MB: 限制容器对/dev/sda设备(通常是宿主机的硬盘)的写速度为每秒20MB。这可以防止容器占用过多的磁盘I/O资源。

  • -e MYSQL_ROOT_PASSWORD='sc123456': 通过环境变量设置MySQL的root用户密码。MYSQL_ROOT_PASSWORD是MySQL容器初次启动时必须设置的环境变量,用于定义root用户的密码。在这个例子中,密码被设置为sc123456

  • mysql:5.7.43: 指定使用的Docker镜像,这里使用的是MySQL的官方Docker镜像,版本是5.7.43

综上所述,这个命令将会在Docker中创建一个新的MySQL容器,该容器在后台运行,配置了CPU和内存的资源限制,并将容器的MySQL服务端口映射到宿主机的3308端口上。同时,还限制了容器对宿主机硬盘的写速度。

shell 复制代码
[root@docker-1 ~] docker stats
CONTAINER ID   NAME         CPU %     MEM USAGE / LIMIT     MEM %     NET I/O       BLOCK I/O         PIDS
938d53c057a1   sc-mysql-3   0.03%     205.2MiB / 1.863GiB   10.76%    656B / 0B     2.88MB / 583MB    27

3.2 docker top

查看容器内部的进程

shell 复制代码
[root@docker-1 ~] docker top sc-mysql-3
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
polkitd             5529                5509                0                   18:10               ?                   00:00:00            mysqld
[root@docker-1 ~]# 

一般容器里边只跑一个进程

3.3 思考:如何限制容器使用网络带宽资源?

Docker本身并没有直接提供限制容器网络带宽的选项,但是可以通过一些间接的方式来实现。其中一种常见的方法是使用tc(Traffic Control)工具,它是Linux内核的一部分,可以用来控制网络带宽。

然而,tc命令需要在容器启动后执行,而不能直接在docker run命令中设置。因此,你可能需要创建一个脚本来启动容器并设置网络带宽限制。

以下是一个简单的示例,首先启动容器,然后使用tc命令限制容器的出口带宽为1mbit/s:

bash 复制代码
# 启动容器
docker run -d --name sc-mysql-3 -p 3308:3306 --cpu-shares 500 --cpus 2 --cpuset-cpus 0,1 -m 2000000000 --device-write-bps /dev/sda:20MB  -e MYSQL_ROOT_PASSWORD='sc123456' mysql:5.7.43

# 获取容器的网络设备名
CONTAINER_PID=$(docker inspect -f '{{.State.Pid}}' sc-mysql-3)
NETWORK_INTERFACE=$(nsenter -t $CONTAINER_PID -n ip link | grep eth0 | awk '{print $2}' | tr -d ":")

# 限制容器的出口带宽为1mbit/s
tc qdisc add dev $NETWORK_INTERFACE root tbf rate 1mbit burst 32kbit latency 400ms

这个脚本首先启动了一个名为sc-mysql-3的MySQL容器,然后获取了容器的网络设备名,最后使用tc命令限制了容器的出口带宽为1mbit/s。

需要注意的是,这只是一个基本的示例,实际使用时可能需要根据你的具体需求进行调整。另外,tc命令的使用可能需要一定的网络知识,如果你不熟悉这个工具,可能需要花一些时间来学习。

3.4 细讲一下docker run

docker run的流程 👇

  1. 检查启动容器使用的镜像是否存在,如果不存在就先去pull镜像到本机,如果存在就创建容器

    docker pull 去拉mysql:5.7.43

  2. docker create ------>创建容器

  3. docker start ------>启动容器

bash 复制代码
# 删除镜像
[root@localhost ~] docker rmi busybox
Untagged: busybox:latest
Untagged: busybox@sha256:5acba83a746c7608ed544dc1533b87c737a0b0fb730301639a0179f9344b1678
Deleted: sha256:beae173ccac6ad749f76713cf4440fe3d21d1043fe616dfbe30775815d1d0f6a
Deleted: sha256:01fd6df81c8ec7dd24bbbd72342671f41813f992999a3471b9d9cbc44ad88374

↑ 如果正在使用,就先停止那个容器,然后rm删除容器,再rmi删除镜像

所以说,不需要 pull 创建之类的

直接 用run

3.5 docker rm

rm 是删容器的

3.6 docker rmi

rmi是删除镜像
一般是停止运行之后,先通过rm删除容器,然后通过rmi删除镜像

3.7 docker rm和rmi的区别

docker rmdocker rmi 是Docker命令行工具中的两个不同命令,分别用于删除容器和镜像。

docker rm

docker rm 命令用于删除一个或多个容器。当一个容器不再需要时,你可以使用此命令来清除它。需要注意的是,只有停止状态的容器才可以被删除。如果要删除正在运行的容器,需要先停止容器(使用docker stop命令),或者在使用docker rm命令时加上-f(--force)参数来强制删除。

基本使用格式如下:

bash 复制代码
docker rm [OPTIONS] CONTAINER [CONTAINER...]

例如,删除名为my_container的容器:

bash 复制代码
docker rm my_container

如果想要强制删除一个正在运行的容器,可以使用:

bash 复制代码
docker rm -f my_container

docker rmi

docker rmi 命令用于删除一个或多个Docker镜像。当你不再需要某个镜像,或者需要清理磁盘空间时,你可以使用这个命令。在删除镜像之前,需要确保没有任何容器(无论是运行中的还是已停止的)正在使用这个镜像。

基本使用格式如下:

bash 复制代码
docker rmi [OPTIONS] IMAGE [IMAGE...]

例如,删除名为mysql的镜像:

bash 复制代码
docker rmi mysql

如果一个镜像有多个标签,你可能需要删除所有相关的标签才能完全删除该镜像。

需要注意的是,如果其它镜像依赖于要删除的镜像的层,那么这些层不会被删除。只有当没有任何镜像使用这些层时,这些层才会从Docker主机上删除。

无论是使用docker rm还是docker rmi,都应谨慎操作,确保不会误删正在使用或需要保留的容器或镜像。

4. 一些小知识点

4.1 kernel的作用

Linux内核的作用是提供系统的核心功能,包括:

  • **进程管理:**调度进程、管理进程生命周期和状态。
  • **内存管理:**分配和回收内存、虚拟内存和交换空间的管理。
  • **文件系统:**管理数据存储、文件的创建、删除、读取和写入。
  • **设备驱动:**提供与硬件设备通信的接口和控制。
  • **网络功能:**实现网络协议栈,处理网络通信。
  • **安全:**提供用户权限控制、访问权限和安全机制。
  • **系统调用和接口:**提供用户空间程序与内核交互的接口。

4.2 假如我们不使用容器进程,我们想限制一个Linux操作系统里的进程使用多少cpu和多少内存?

使用cgroups技术去控制

https://pythonjishu.com/emkqvgkuoaalfkc/
操作系统内核里有个软件: LXC linux container技术

docker只是调用了LXC的库,实现了容器的应用

4.3 docker容器的三种状态

Docker容器的状态通常是通过docker psdocker inspect命令查看的,并且确实有几种主要状态,包括"Up"、"Exited"和"Created"。下面是对这三种状态的详细解释:

  1. Up(运行中) :当容器正在运行时,使用docker ps命令查看容器列表,会显示容器的状态为"Up"。这表示容器内的应用程序正在活动运行。"Up"状态后通常会跟随容器已运行的时间,例如"Up 2 hours"表示容器已经运行了两小时。

  2. Exited(已停止):当容器内的主进程已经终止时,容器的状态就变为"Exited"。这意味着容器已经停止运行,不再执行任何操作。"Exited"状态后通常会跟随一个退出代码,表示容器终止时的状态,例如"Exited (0) 5 minutes ago"表示容器在5分钟前正常退出,退出代码为0。

  3. Created(已创建) :当使用docker create命令创建一个容器但尚未启动它时,容器的状态是"Created"。这意味着容器的配置已经完成,包括文件系统的初始化,但是容器内的应用程序还没有开始运行。"Created"状态的容器需要通过docker start命令来启动。

这些状态帮助用户了解容器的生命周期和当前运行情况。使用docker ps -a命令会列出所有容器,包括未运行的容器,而使用docker ps命令默认只列出处于"Up"状态的运行中容器。

4.4 小结一下

docker run = docker pull+ docker create + docker start

docker rmi

docker top 查看容器里运行的进程,单进程思想,一个容器只跑一个进程

docker stats 查看运行的状态

docker network 查看容器里的网络

相关推荐
茯苓gao4 小时前
STM32G4 速度环开环,电流环闭环 IF模式建模
笔记·stm32·单片机·嵌入式硬件·学习
是誰萆微了承諾4 小时前
【golang学习笔记 gin 】1.2 redis 的使用
笔记·学习·golang
DKPT5 小时前
Java内存区域与内存溢出
java·开发语言·jvm·笔记·学习
aaaweiaaaaaa5 小时前
HTML和CSS学习
前端·css·学习·html
慕容晓开5 小时前
docker,本地目录挂载
docker
看海天一色听风起雨落6 小时前
Python学习之装饰器
开发语言·python·学习
speop7 小时前
llm的一点学习笔记
笔记·学习
非凡ghost7 小时前
FxSound:提升音频体验,让音乐更动听
前端·学习·音视频·生活·软件需求
Mr. Cao code7 小时前
Docker:颠覆传统虚拟化的轻量级革命
linux·运维·ubuntu·docker·容器
Dontla7 小时前
Docker多共享网络配置策略(Docker多网络、Docker networks、Docker Compose网络、Docker网络、Docker共享网络)
网络·docker·容器