CRI-O 解析与实践(半成品)

CRI-O 解析与实践(半成品)

本文整合了 CRI-O 核心概念与实操流程,从理论原理到环境搭建、实战操作逐步讲解,帮助你全面理解并掌握 CRI-O 的使用。

一、CRI-O 核心概念解析

CRI-O 是专为 Kubernetes(K8s) 设计的轻量级开源容器运行时,核心定位是实现 K8s 的容器运行时接口(CRI),同时兼容开放容器计划(OCI)标准,是 Docker、containerd 的轻量化替代方案。

1.1 核心背景与版本特性

  • 起源与演进:2016 年始于 K8s 孵化器项目,初名为“开放容器倡议守护进程(OCID)”,2017 年发布 1.0.0 正式版。
  • 版本对齐规则:严格遵循 K8s 发布周期,确保版本兼容性(如 K8s 1.15 可安全搭配 CRI-O 1.15),降低生产环境适配风险。
  • 核心优势:专注于实现 CRI 这一单一核心任务,无冗余功能,资源占用更低,适合生产环境中 K8s 工作负载的轻量化部署。

1.2 技术架构与工作原理

CRI-O 遵循 UNIX“单一职责”理念,架构分为三层,各组件分工明确:

架构层级核心组件功能作用
前端(API 层)gRPC API 服务对外提供 CRI 接口,接收 K8s 或 crictl 的请求
中间层(协调层)CRI-O 主程序 + 核心库协调前后端交互,依赖 containers/storage(容器存储)、containers/image(镜像管理)等库处理核心逻辑
后端(执行层)runc基于 OCI 标准的底层容器运行时,负责容器的创建、启动、停止等基础管理操作

二、CRI-O 实操环境准备

我们本章不讲制作镜像,可以使用大佬已经制作好的镜像:panzhongxian/crio-playground

通过 podman 启动特权容器(需特权模式以支持容器内嵌套容器),命令如下:

sudo podman run --privileged -h crio-playground -it panzhongxian/crio-playground
  • --privileged:赋予容器特权,允许其管理宿主机级别的资源(如网络、存储),满足 CRI-O 运行需求;
  • -h crio-playground:设置容器主机名为 crio-playground,便于识别;
  • -it:以交互模式启动,支持后续命令输入。

顺手再安装下vim:

apt update -y

apt install vim

三、CRI-O 核心操作

在 Kubernetes 世界中,K8s工作负载的运行依赖“沙箱(PodSandbox) + 工作容器”的组合:沙箱提供隔离环境(如网络、PID 命名空间),工作容器则运行实际业务负载(如 Nginx)。以下是完整操作流程。

3.1 步骤 1:创建 Pod 沙箱(PodSandbox)

沙箱是 Pod 的基础隔离环境,内部默认运行 pause 进程(用于维持沙箱存活、统一管理容器信号)。

3.1.1 沙箱配置文件(sandbox.yml)

在容器中工作目录放置了一个sandbox.yml文件,核心配置如下(定义沙箱名称、命名空间和 DNS 服务器):

metadata:
  name: sandbox  # 沙箱名称
  namespace: default  # 所属命名空间(与 K8s 命名空间概念一致)
dns_config:
  servers:
    - 8.8.8.8  # DNS 服务器,确保容器可解析域名
3.1.2 创建沙箱并保存 ID

使用 crictl runprunp = run pod sandbox)命令创建沙箱,设置 30 秒超时避免镜像拉取失败:

# 创建沙箱,返回沙箱 ID(示例:1d1a9a66b433399a4cd24a77ae7dc56ba68915baf058df26b40078e56b216eb9)
crictl --timeout=30s runp sandbox.yml

# 将沙箱 ID 存入环境变量 $POD_ID,方便后续使用
export POD_ID=1d1a9a66b433399a4cd24a77ae7dc56ba68915baf058df26b40078e56b216eb9
3.1.3 验证沙箱状态

通过 crictl pods 查看沙箱列表,结合 transpose 工具优化输出格式:

crictl pods | transpose
         POD ID: 1d1a9a66b4333
        CREATED: 37 seconds ago
          STATE: Ready  # 沙箱已就绪
           NAME: sandbox
      NAMESPACE: default
        ATTEMPT: 0
        RUNTIME: (default)
3.1.4 深入查看沙箱内部(runc 工具)

沙箱本质是由 runc 管理的容器,可通过 runc 查看其进程、存储路径等细节:

# 查看沙箱进程列表(仅运行 /pause 进程)
root@crio-playground:~# runc ps $POD_ID
UID          PID    PPID  C STIME TTY          TIME CMD
root          87      79  0 11:57 ?        00:00:00 /pause

# 查看沙箱的运行状态(含 PID、存储路径等)
root@crio-playground:~# runc list | transpose
             ID: 1d1a9a66b433399a4cd24a77ae7dc56ba68915baf058df26b40078e56b216eb9
            PID: 87  # 沙箱在宿主机(此处指 playground 容器)中的 PID
         STATUS: running
         BUNDLE: /run/containers/storage/vfs-containers/[沙箱ID]/userdata  # 沙箱存储路径
        CREATED: 2023-11-02T11:57:36.139619785Z
          OWNER: root

3.2 步骤 2:运行工作容器(以 Nginx 为例)

工作容器依赖沙箱的隔离环境运行,需先拉取镜像,再通过配置文件定义容器,最后关联到沙箱并启动。

3.2.1 拉取 Nginx 镜像

使用 crictl pull 拉取轻量级的 nginx:alpine 镜像(适合测试):

root@crio-playground:~# crictl pull nginx:alpine
Image is up to date for docker.io/library/nginx@sha256:7e528502b614e1ed9f88e495f2af843c255905e0e549b935fdedd95336e6de8d

验证镜像是否拉取成功:

root@crio-playground:~# crictl images
REPOSITORY          TAG       IMAGE ID        SIZE
docker.io/library/nginx   alpine    sha256:7e52...   40.7MB
3.2.2 容器配置文件(container.yml)

预设在容器工作目录,定义容器名称和使用的镜像:

metadata:
  name: container  # 容器名称
image:
  image: nginx:alpine  # 容器使用的镜像
3.2.3 创建容器并关联沙箱

使用 crictl create 命令创建容器,需指定 沙箱 ID容器配置文件沙箱配置文件(确保容器与沙箱关联):

# 创建容器,返回容器 ID(示例:a2431ece5c7707f796898a887a636b1e31f69de6d71144ed97c7a97afd05d743)
root@crio-playground:~# crictl create $POD_ID container.yml sandbox.yml

# 将容器 ID 存入环境变量 $CONTAINER_ID
root@crio-playground:~# export CONTAINER_ID=a2431ece5c7707f796898a887a636b1e31f69de6d71144ed97c7a97afd05d743
3.2.4 启动容器并验证状态
  1. 启动容器:使用 crictl start 启动容器(创建后默认处于 Created 状态,需手动启动):

    root@crio-playground:~# crictl start $CONTAINER_ID
    a2431ece5c7707f796898a887a636b1e31f69de6d71144ed97c7a97afd05d743
    
  2. 验证容器状态:通过 crictl ps 查看运行中的容器,通过 runc ps 查看容器内进程:

    # 查看容器状态(已变为 Running)
    root@crio-playground:~# crictl ps | transpose
      CONTAINER: a2431ece5c770
          IMAGE: nginx:alpine
        CREATED: 2 minutes ago
          STATE: Running
           NAME: container
        ATTEMPT: 0
         POD ID: 1d1a9a66b4333
            POD: unknown
    
    # 查看容器内进程(Nginx 主进程 + 工作进程)
    root@crio-playground:~# runc ps $CONTAINER_ID
    UID          PID    PPID  C STIME TTY          TIME CMD
    root         198     190  0 12:08 ?        00:00:00 nginx: master process nginx -g daemon off;
    systemd+     273     198  0 12:11 ?        00:00:00 nginx: worker process
    

3.3 步骤 3:访问工作容器(Nginx 服务)

容器默认通过 桥接网络 与外部通信(CRI-O 已预设桥接配置),需先获取容器的内部 IP,再通过 curl 访问服务。

3.3.1 查看容器网络配置

CRI-O 的网络配置位于以下路径,核心是通过 CNI(容器网络接口)实现桥接:

  • 网络配置目录:/etc/crio/crio.conf(配置 net.d 目录路径);
  • 桥接配置文件:/etc/cni/net.d/10-crio-bridge.conf(指定网络类型为 bridge)。
3.3.2 获取容器内部 IP

通过 crictl exec 进入容器,执行 ip addr 查看网络接口(eth0 为容器的默认网卡):

root@crio-playground:~# crictl exec $CONTAINER_ID ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
3: eth0@if4: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
    link/ether 02:85:47:19:10:2d brd ff:ff:ff:ff:ff:ff
    inet 172.0.0.2/16 brd 172.0.255.255 scope global eth0  # 容器内部 IP
       valid_lft forever preferred_lft forever
3.3.3 访问 Nginx 服务

使用 curl 访问容器内部 IP,验证 Nginx 是否正常运行:

root@crio-playground:~# curl 172.0.0.2 2>/dev/null | head -5
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
  • 2>/dev/null:忽略错误输出;
  • head -5:仅显示前 5 行内容,快速验证服务可用性。

四、核心关系梳理:宿主机、Playground 容器、沙箱、工作容器

通过实操,我们在 未运行 K8s 的情况下,成功通过 CRI-O 运行了 K8s 工作负载,四层结构的关系如下:

┌──────────────────────── 宿主机(Host) ─────────────────────────┐
│                                                                │
│  ┌───────────── 特权容器(panzhongxian/crio-playground) ─────┐ │
│  │                                                           │ │
│  │  ┌───────── Pod 沙箱(sandbox,由 runc 管理) ─────────┐   │ │
│  │  │  运行进程:/pause(维持沙箱存活)                    │   │ │
│  │  │  网络:桥接网络(与工作容器共享)                     │   │ │
│  │  │                                                    │   │ │
│  │  │  ┌───── 工作容器(nginx:alpine,由 runc 管理)   ──┐ │   │ │
│  │  │  │  运行进程:nginx 主进程 + 工作进程               │ │  │ │
│  │  │  │  网络:使用沙箱的桥接网络(IP:172.0.0.2)       │ │   │ │
│  │  │  └───────────────────────────────────────────────┘ │   │ │
│  │  └─────────────────────────────────────────────────────┘  │ │
│  │                                                           │ │
│  └───────────────────────────────────────────────────────────┘ │
│                                                                │
└────────────────────────────────────────────────────────────────┘

五、总结

  1. CRI-O 定位:专为 K8s 设计的轻量级 CRI 实现,兼容 OCI 标准,适合替代 Docker/containerd 降低资源占用;
  2. 实操关键:通过“沙箱 + 工作容器”的组合运行负载,沙箱提供隔离环境,工作容器运行业务逻辑;
  3. 环境优化:自定义 panzhongxian/crio-playground 镜像解决国内环境痛点,简化操作流程;
  4. 核心工具crictl 用于与 CRI-O 交互(创建沙箱/容器、查看状态),runc 用于底层容器管理。

通过以上步骤,可在无 K8s 的环境中快速验证 CRI-O 的核心能力,为后续 K8s 集群中集成 CRI-O 奠定基础。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值