K8S笔记-容器和镜像

以上是Docker官网架构图。

  • 用户通过 Client(客户端)发送命令(如 build, pull, run),与运行在 DOCKER_HOST 上的 Docker daemon(守护进程)交互。
  • Daemon 是核心,负责管理本地的 Images(镜像)和 Containers(容器),并与远端的 Registry(镜像仓库)通信,完成镜像的拉取和推送。

容器

  • 是一个特殊的隔离环境,让进程可以看到环境里的有限信息,不能对外界环境施加影响
  • 通过容器, 可以将引应用程序运行在一个有严密防护的 沙盒 环境中
  • 容器技术的另一个本领就是为应用程序加上资源隔离,在系统里切分出一部分资源,让它只能使用指定的配额

容器与虚拟机的对比

虚拟机通过虚拟化硬件 ,在上面安装完整的操作系统后才能运行应用。这种方式会消耗大量的CPU、内存和硬盘等系统资源 ,但这些资源消耗主要用于运行额外的操作系统,并没有直接为应用带来价值。虚拟机的优点是隔离程度非常高 ,每个虚拟机之间可以做到完全无干扰

优势

  • 容器直接使用下层硬件和操作系统内核,无需额外的操作系统层,节约了CPU和内存资源,显得非常轻量级。
  • 启动速度更快
  • 资源利用率更高
  • 镜像体积更小
劣势
  • 隔离程度相对较低
    • 虽然容器提供了良好的隔离环境,但相比虚拟机的完全隔离,容器在安全性方面仍有差距,多容器共享同一操作系统内核可能带来潜在的安全风险。

容器隔离的实现原理

容器技术通过以下三种主要机制实现隔离:

1. namespace

  • 创建出独立的文件系统、主机名、进程号、网络等资源空间
  • 实现了系统全局资源和进程局部资源的隔离
  • Linux提供了多种namespace类型:PID(进程)、NET(网络)、IPC(进程间通信)、MNT(挂载点)、UTS(主机名)等

2. cgroup

  • 控制组(control groups)实现对进程的CPU、内存等资源的优先级和配额限制
  • 防止单个容器消耗所有系统资源
  • 允许精细化的资源分配和管理
  • 可以限制内存使用量、CPU份额、设备访问等

3. chroot

  • 更改进程的根目录,限制其对文件系统的访问范围
  • 提供文件系统级别的隔离
  • 确保容器只能访问指定的文件和目录

Docker镜像

镜像不仅包含基本的可执行文件,还包括应用运行时的整个系统环境 (依赖库、配置文件、环境变量等)。这种设计让镜像具有非常好的跨平台便携性和兼容性 ,真正实现了"一次构建,到处运行"。
Docker指令访问官方文档(科学上网)

容器运行示例

当执行一条Docker命令时:

bash 复制代码
docker run busybox echo hello world

Docker会执行以下步骤:

  1. 检查本地是否有busybox镜像,如果没有则从镜像仓库下载
  2. 提取镜像里的各种信息
  3. 运用namespace、cgroup、chroot技术创建出隔离环境
  4. 在隔离环境中运行busybox的echo命令
  5. 输出"hello world"字符串

镜像名称结构

Docker镜像名称由两部分组成:镜像名和标签,中间用冒号连接:

复制代码
镜像名:标签

例如:

  • ubuntu:20.04 - 指定版本的Ubuntu镜像
  • nginx:latest - 最新的Nginx镜像(默认标签)
  • my-app:v1.2.3 - 自定义应用的版本化镜像

容器化应用

应用程序不再直接和操作系统打交道,而是封装成镜像,再交给容器环境去运行。

优势

  • 环境一致性:开发、测试、生产环境使用完全相同的镜像
  • 版本控制:镜像版本可以追踪和管理
  • 快速扩展:基于镜像可以快速创建多个容器实例

Dockerfile

Dockerfile是一个纯文本文件 ,里面记录了一系列的构建指令。每个指令都会生成一个镜像层(Layer),Docker会顺序执行这个文件里的所有步骤,最后创建出一个新的镜像。这种分层结构让镜像构建更加高效,且便于共享和存储。

RUN指令

RUN指令用于在镜像构建过程中执行任意的Shell命令

用途

  • 安装应用程序依赖
  • 下载文件
  • 创建目录结构
  • 编译程序代码

换行符编写

当需要执行多个命令时,一行放不下就需要引入换行符

  • 每行的末尾使用续行符 \,命令之间用 && 来连接
dockerfile 复制代码
# 不推荐的方式
RUN apt-get update && apt-get install -y git wget curl && rm -rf /var/lib/apt/lists/*

# 推荐的方式
RUN apt-get update \
    && apt-get install -y \
        git \
        wget \
        curl \
    && rm -rf /var/lib/apt/lists/*

使用脚本文件

对于复杂的命令序列,可以创建脚本文件并在Dockerfile中使用

  1. 创建安装脚本 install-dependencies.sh
bash 复制代码
#!/bin/bash
apt-get update
apt-get install -y git wget curl
rm -rf /var/lib/apt/lists/*
  1. 在Dockerfile中使用:
dockerfile 复制代码
COPY install-dependencies.sh /tmp/
RUN chmod +x /tmp/install-dependencies.sh \
    && /tmp/install-dependencies.sh \
    && rm /tmp/install-dependencies.sh

ARG、ENV和EXPOSE指令详解

ARG指令

ARG指令用于定义在构建过程中使用的变量,这些变量只在镜像构建过程中可见,容器运行时不可见。

dockerfile 复制代码
# 定义构建参数
ARG APP_VERSION=1.0.0
ARG BUILD_ENV=production

# 使用构建参数
RUN echo "Building version ${APP_VERSION} for ${BUILD_ENV} environment"

ENV指令

ENV指令用于设置环境变量,这些变量不仅在构建过程中可用,在容器运行时也会作为环境变量被应用程序使用。

dockerfile 复制代码
# 设置环境变量
ENV NODE_ENV=production
ENV APP_PORT=3000
ENV DB_HOST=database

# 使用环境变量
EXPOSE ${APP_PORT}
CMD ["node", "app.js"]

EXPOSE指令

EXPOSE指令用于声明容器运行时监听的端口,这只是一个文档化的指令,并不会实际发布端口。

dockerfile 复制代码
# 声明容器监听端口
EXPOSE 80/tcp
EXPOSE 443/tcp
EXPOSE 3000/udp

# 实际发布端口需要在运行容器时使用-p参数
# docker run -p 8080:80 my-app

完整示例

下面是一个完整的Node.js应用Dockerfile示例,展示了各种指令的使用:

dockerfile 复制代码
# 使用官方Node.js运行时作为父镜像
FROM node:16-alpine

# 设置构建参数
ARG APP_VERSION=1.0.0
ARG NPM_REGISTRY=https://registry.npmjs.org/

# 设置环境变量
ENV NODE_ENV=production
ENV APP_PORT=3000
ENV APP_VERSION=${APP_VERSION}

# 设置工作目录
WORKDIR /app

# 复制package.json和package-lock.json
COPY package*.json ./

# 设置npm注册表并安装依赖
RUN npm config set registry ${NPM_REGISTRY} \
    && npm ci --only=production \
    && npm cache clean --force

# 复制应用程序源代码
COPY . .

# 创建非root用户运行应用(安全最佳实践)
RUN addgroup -g 1001 -S nodejs \
    && adduser -S nextjs -u 1001

# 更改文件所有权
RUN chown -R nextjs:nodejs /app

# 切换到非root用户
USER nextjs

# 暴露应用程序端口
EXPOSE ${APP_PORT}

# 定义健康检查
HEALTHCHECK --interval=30s --timeout=3s \
  CMD curl -f http://localhost:${APP_PORT}/health || exit 1

# 启动应用程序
CMD ["npm", "start"]

构建和运行示例

构建镜像

使用以下命令构建Docker镜像:

bash 复制代码
docker build -t my-node-app:1.0.0 .

运行容器

运行构建的镜像:

bash 复制代码
docker run -d \
  --name my-app \
  -p 3000:3000 \
  -e NODE_ENV=development \
  my-node-app:1.0.0

查看运行状态

检查容器运行状态:

bash 复制代码
docker ps
docker logs my-app

总结

容器技术通过namespace、cgroup和chroot实现了进程的隔离和资源限制,提供了轻量级的虚拟化解决方案。Docker作为最流行的容器平台,通过镜像和Dockerfile使应用打包和分发变得简单高效

相关推荐
微笑伴你而行8 小时前
小土堆目标检测笔记
笔记·目标检测·目标跟踪
qq_339191149 小时前
docker 启动一个clickhouse , docker 创建ck数据库
clickhouse·docker·容器
一枝小雨12 小时前
【C++】编写通用模板代码的重要技巧:T()
开发语言·c++·笔记·学习笔记
天若有情67312 小时前
《JAVA EE企业级应用开发》第一课笔记
java·笔记·后端·java-ee·javaee
白菜帮张同学13 小时前
LP嵌入式软件/驱动开发笔试/面试总结
数据结构·驱动开发·经验分享·笔记·学习·算法·面试
喜欢你,还有大家15 小时前
Linux笔记14——shell编程基础-8
linux·前端·笔记
吐个泡泡v15 小时前
Portainer:Docker可视化管理神器部署与使用攻略
运维·docker·容器·portainer
逾非时16 小时前
nacos微服务介绍及环境搭建
docker·微服务·云原生·架构
Britz_Kevin16 小时前
从零开始的云计算生活——第五十六天,临深履薄,kubernetes模块之etcd备份恢复和集群升级指南
kubernetes·生活·etcd