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使应用打包和分发变得简单高效

相关推荐
栈溢出了2 小时前
Redis 分片集群与哈希槽笔记
java·redis·笔记·spring
我命由我123452 小时前
复利极简理解
经验分享·笔记·学习·职场和发展·求职招聘·职场发展·学习方法
AOwhisky3 小时前
Python 学习笔记(第三期)——流程控制核心知识点自测与详解
开发语言·笔记·python·学习·云原生·运维开发·流程控制
欢醉4 小时前
k8s调用服务异常cannot allocate memory
kubernetes·k8s
我命由我123454 小时前
72 法则极简理解
经验分享·笔记·学习·职场和发展·求职招聘·职场发展·学习方法
阿里云云原生4 小时前
AgenticOps 已来:运维智能体如何落进生产环境
云原生
扶疏5255 小时前
Kubernetes Dashboard、动态卷供应、StatefulSet
容器·kubernetes
xian_wwq5 小时前
【学习笔记】OpenAI 兼容 API 服务化:从协议到 LLM Gateway(19/35)
笔记·学习
阿里云云原生6 小时前
告别 Token 计量的混乱:AI 网关如何通过 Credits 统一度量实现跨模型配额管理?
云原生
leijiwen6 小时前
LinkLifeVerse OS :数字经济时代的产业价值操作系统(Industry Value Operating System)
人工智能·云原生·saas·paas