【云原生】Kubernetes CEL 速查表

以下是一份 Kubernetes CEL 速查表(Cheat Sheet),涵盖了常见的语法、宏、标准函数和一些在 Kubernetes 中常见的使用示例。可在编写或调试 CEL 表达式时用作快速参考。


1. 基础概念

概念 说明
语言特点 无副作用、逐渐类型化(Gradual Typing)、无循环、短小单行表达式
常见用法 - CRD 校验(selfoldSelf 变量) - Admission 策略(objectrequest 变量)
关键变量 - self:当前资源对象 - oldSelf:更新前的资源对象 - object:Admission 请求中的对象 - request:Admission 请求信息等
错误处理 无法捕捉错误;遇到运算错误直接结束(部分逻辑运算可"吸收"错误见 ||、&&)
常见库 - K8s 列表库 - K8s 正则库 - K8s URL 库 - K8s 鉴权库 - K8s 数量库

2. 语法与操作符

2.1 操作符优先级(从高到低)

  1. . / [] / () 成员访问、索引、函数调用
  2. 一元运算-(取负)、!(逻辑非)
  3. */%
  4. +-
  5. 比较<><=>===!=in
  6. 逻辑与&&
  7. 逻辑或\|\|
  8. 三元运算?:

2.2 标识符转义

当字段名含 -./、保留关键字等,需要使用以下转义:

转义序列 实际含义 示例
__underscores__ __ redact__dredact__underscores__d
__dot__ .
__dash__ - x__dash__prop 表示字段 x-prop
__slash__ /
__{keyword}__ 关键字转义 __namespace__ 表示字段 namespace

3. 常用宏(Macros)

语法 描述
has(e.f) has(e.f) 判断 fe 中是否被"设置"。e 可为 map 或 proto message。
all(x, predicate) list.all(x, p) map.all(x, p) 列表/Map 所有元素/键都满足 p 时返回 true;否则 false
exists(x, predicate) list.exists(x, p) map.exists(x, p) 列表/Map 中是否存在任意一个元素满足 p
exists_one(x, predicate) list.exists_one(x, p) map.exists_one(x, p) 是否恰好只有一个元素满足 p
filter(x, predicate) list.filter(x, p) map.filter(x, p) 返回过滤后的子集(列表)。map 时返回满足 p 的键的列表。
map(x, transform) list.map(x, expr) map.map(x, expr) 遍历列表/Map,对元素/键执行 expr,返回列表。
map(x, filter_expr, transform) 同上,多一个先过滤再变换的逻辑。

常见示例

cel 复制代码
[1, 2, 3].all(x, x > 0)          // true
[1, 2, 3].exists(x, x == 2)      // true
[1, 2, 3].filter(x, x > 1)       // [2, 3]
[1, 2, 3].map(x, x * 2)          // [2, 4, 6]
has(object.metadata.name)        // 是否设置了 name 字段

4. 逻辑与条件

运算符 含义 示例
&& 逻辑与(可"吸收"错误) 只有当无法确定结果时才会抛出错误 true && error => error false && error => false
` `
? : 条件(三元运算符) (cond) ? exprTrue : exprFalse true ? error : 1 => error

5. 常用运算符与函数

5.1 等值与比较

运算 签名 备注
==, != 同类型或数值跨类型(int,uint,double)比较 对 PB message 则比较字段逐一相等,NaN == NaN => false
<,>,<=,>= 同类型(或跨数值)、string/bytes/Timestamp/Duration 字符串/bytes 按字典序;bool 有序:false < true

5.2 算术

运算 签名 说明
+ int + int、double + double、string + string、list + list、timestamp + duration ... 数字相加 / 字符串拼接 / 列表拼接 / 时间加法
- int - int、timestamp - timestamp、duration - duration ... 数字相减 / 时间差
*/% 数值运算(整型或浮点,不混用) 无自动提升,需显式转换

5.3 列表与 Map

表达式 示例 说明
list[index] [1,2,3][1] -> 2 越界时报错
map[key] {"a":1}["a"] -> 1 不存在 key 时报错
x in list / x in map 2 in [1,2,3] -> true "a" in {"a":10} -> true 是否存在(对 map 判断的是 key)
list.size() [1,2,3].size() -> 3 获取元素数量
map.size() {"a":1,"b":2}.size() -> 2 获取键数量

5.4 字符串、Bytes、正则

函数 签名 示例
size() string.size() bytes.size() "abc".size() => 3 b"abc".size() => 3
contains(sub) string.contains(string) "hello".contains("ll") => true
startsWith(pre) string.startsWith(string) "hello".startsWith("he") => true
endsWith(suf) string.endsWith(string) "hello".endsWith("lo") => true
matches(regex) string.matches(string) "abc".matches("^a.*") => true
find(regex) findAll(regex) (K8s 扩展) string.find(string) string.findAll(string) "abc 123".find("[0-9]+") => "123" "1,2".findAll("[0-9]+") => ["1","2"]

5.5 时间与 Duration

用法 示例 说明
解析 timestamp("2023-01-01T00:00:00Z") duration("1h") 将字符串解析为 TimestampDuration 对象
运算 timestamp("2023-01-01T00:00:00Z") + duration("1h") timestamp("2023-01-02T00:00:00Z") - timestamp("2023-01-01T00:00:00Z") 时间加减;支持比较运算 <,>
提取 ts.getDate(), ts.getMonth(), ts.getFullYear(), ts.getDayOfWeek(), ts.getHours(), ts.getMinutes() ... 可带时区字符串,默认 UTC

5.6 类型转换

函数 示例 说明
int(x)uint(x) int(3.14) -> 3 uint("123") -> 123u 超出范围会报错
double(x) double("2.5") => 2.5
string(x) string(3) => "3" string(duration("1s")) => "1s" 对 bytes 尝试按 UTF-8 解码,失败报错
timestamp(x) timestamp("2023-08-26T12:00:00Z") 按 RFC3339 解析
duration(x) duration("1h30m") 解析为 Duration
quantity(x) (K8s) quantity("1Gi").add(quantity("500Mi")) 在 v1.29+ 中可用,用于 ResourceQuantity

6. Kubernetes 额外扩展

6.1 列表库(min、max、sum、isSorted 等)

cel 复制代码
list.min()     
list.max()     
list.sum()     
list.isSorted() 
list.indexOf(x)
list.lastIndexOf(x)

6.2 正则库(find, findAll

cel 复制代码
"abc 123".find("[0-9]+")  // "123"
"1,2,3".findAll("[0-9]+") // ["1","2","3"]

6.3 URL 库(isURL, url(...)

cel 复制代码
isURL("https://example.com")          
url("https://example.com").getHost()  

6.4 数量库(quantity(...)

cel 复制代码
isQuantity("50Mi")               
quantity("50Mi").isInteger()     
quantity("50Mi").add(10).asInteger() 

6.5 鉴权库(authorizer 变量)

cel 复制代码
authorizer.group('').resource('pods').namespace('default').check('create').allowed()
authorizer.serviceAccount('default','mysa').resource('deployments').check('delete').allowed()

7. 常见示例

  1. CRD 校验副本数关系

    cel 复制代码
    self.minReplicas <= self.replicas && self.replicas <= self.maxReplicas
  2. 检查字段是否存在

    cel 复制代码
    has(self.expired) && self.created + self.ttl < self.expired
  3. 两个列表不同时为空

    cel 复制代码
    (self.list1.size() == 0) != (self.list2.size() == 0)
  4. Map 必须包含键 'Available'

    cel 复制代码
    'Available' in self.stateCounts
  5. 检查某 listMap 项的值

    cel 复制代码
    self.envars.filter(e, e.name == 'MY_ENV').all(e, e.value.matches('^[a-zA-Z]*$'))
  6. ListSet 不相交

    cel 复制代码
    self.set1.all(e, !(e in self.set2))
  7. 对 URL 字段解析

    cel 复制代码
    isURL(self.url) && url(self.url).getHost() == "example.com"

8. 注意事项与小贴士

  1. 防止溢出:int/uint/double 运算可能产生溢出报错,duration/timestamp 超过范围也会报错。
  2. 逻辑运算符短路吸收错误true \|\| error => truefalse && error => false。但要注意顺序不固定。
  3. 正则与字符串 :正则复杂度约为 O(len(regex) * len(input)),写表达式时需留意性能。
  4. K8s Schema 集成 :CRD 中的 x-kubernetes-* 属性会影响 list、map、int-or-string 等在 CEL 中的行为,如 set/map 列表的比较、键名是否互斥等。
  5. 表达式长度与预算:Kubernetes 会对表达式做静态与运行时的资源开销评估,过大或过于复杂的表达式可能被拒绝写入或执行。

参考链接

速查表只是简要概览,完整细节请参考 Kubernetes/CEL 官方文档。

相关推荐
MickeyCV4 小时前
使用Docker部署MySQL&Redis容器与常见命令
redis·mysql·docker·容器·wsl·镜像
藥瓿亭6 小时前
K8S认证|CKS题库+答案| 6. 创建 Secret
运维·ubuntu·docker·云原生·容器·kubernetes·cks
2302_809798326 小时前
【JavaWeb】Docker项目部署
java·运维·后端·青少年编程·docker·容器
嵌入式大圣6 小时前
Neko虚拟浏览器远程协作方案:Docker+内网穿透技术部署实践
运维·docker·容器
孔令飞6 小时前
Kubernetes 节点自动伸缩(Cluster Autoscaler)原理与实践
ai·云原生·容器·golang·kubernetes
极简网络科技8 小时前
Docker、Wsl 打包迁移环境
运维·docker·容器
江湖有缘8 小时前
【Docker管理工具】部署Docker可视化管理面板Dpanel
运维·docker·容器
猫咪老师199510 小时前
多系统一键打包docker compose下所有镜像并且使用
java·docker·容器
Nazi610 小时前
docker数据管理
运维·docker·容器
孔令飞13 小时前
Go 为何天生适合云原生?
ai·云原生·容器·golang·kubernetes