OpenKruise
[
1]
是阿里云开源的云原生应用自动化管理套件,也是当前托管在 Cloud Native Computing Foundation (CNCF) 下的孵化项目。它来自阿里巴巴多年来容器化、云原生的技术沉淀,是阿里内部生产环境大规模应用的基于 Kubernetes 之上的标准扩展组件,也是紧贴上游社区标准、适应互联网规模化场景的技术理念与最佳实践。
OpenKruise 在 2024.8 发布了最新的 v1.7 版本(ChangeLog
[
2]
),本文对新版本的核心特性做整体介绍。
OpenKruise 中会引用 K8S 代码库作为工作负载的字段,比如:
PodTemplateSpec。
此次升级 K8S 依赖到 1.28 有如下益处:
-
SidecarSet、CloneSet、Advanced StatefulSet 能够配置 K8S 原生的 Sidecar 容器。
-
为 CloneSet、Advanced Statefulset 支持 Resources 原地 VPA 奠定了基础,我们将在后面的版本支持该特性,最大化的释放 K8S 社区的红利。
-
基于社区上游版本,重构了 Advanced StatefulSet 控制器 updateStatefulSet 方法,提升了代码的可读性。
🔔 注意:
此次 K8S 依赖升级到 1.28 并不意味着 OpenKruise 只能部署在 K8S 版本 >= 1.28 的集群,OpenKruise 依旧支持部署在 K8S 版本 >= 1.18 的集群。只不过,你如果想使用 K8S 上述高级特性,还需要升级 OpenKruise 版本到 1.7。
SidecarSet 支持 K8S 原生 Sidecar 容器
Kubernetes 从 1.28 版本通过 initContainers[x].restartPolicy=Always 的方式支持 Sidecar Containers
[
3]
。
该方式有如下优势:
-
Sidecar 容器保证在业务主容器启动之前 Ready
,比如:日志采集容器已经准备就绪,业务主容器启动 Crash 的日志也能够及时采集上来。
-
Job类型的 Pod,
主容器执行完成之后,Sidecar 容器也会自行退出不会阻塞 Job 的完成。
apiVersion: apps.kruise.io/v1alpha1
kind: SidecarSet
metadata:
name: test-sidecarset
spec:
selector:
matchLabels:
app: sample
updateStrategy:
type: NotUpdate
initContainers:
- name: sidecar
image: nginx:alpine
restartPolicy: Always
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "sleep 10"]
🔔 注意:
当前版本只支持 Sidecar 容器自动注入,暂时还不支持原地升级能力。
此外,如果 K8S 版本 < 1.28 也有上述 Sidecar 容器先于主容器 Ready 和 Job 类型 Pod Sidecar 容器能够及时退出的诉求,也可以使用 OpenKruise 提供的 Job Sidecar Terminator 和 Container Launch Priority 能力,如下在 Sidecar 容器配置环境变量 KRUISE_TERMINATE_SIDECAR_WHEN_JOB_EXIT 和 KRUISE_CONTAINER_PRIORITY 即可达到上述效果:
apiVersion: v1
kind: Pod
spec:
template:
spec:
containers:
- name: sidecar
env:
- name: KRUISE_TERMINATE_SIDECAR_WHEN_JOB_EXIT
value: "true"
- name: KRUISE_CONTAINER_PRIORITY
value: "1"
- name: main
image: centos:6.7
Advanced StatefulSet 支持起始序号
Pod 起始序号默认都是从 0 开始的,此外,你也可以通过设置
.spec.ordinals.start
字段来设置 Pod 起始序号。
使用该能力,你需要开启 FeatureGate
StatefulSetStartOrdinal=true
。
spec.ordinals.start:如果 .spec.ordinals.start 字段被设置,则 Pod 将被分配从 .spec.ordinals.start 到 .spec.ordinals.start + .spec.replicas - 1 的序号。比如:replicas=5、ordinals.start=3,Pod 序号 = [3, 7]。
apiVersion: apps.kruise.io/v1beta1
kind: StatefulSet
metadata:
name: sample
spec:
replicas: 5
ordinals:
start: 3
serviceName: fake-service
selector:
matchLabels:
app: sample
template:
metadata:
labels:
app: sample
spec:
containers:
- name: main
image: nginx:alpine
从 Kubernetes v1.20 开始,kubelet 可以使用 exec 插件动态获得针对某容器镜像库的凭据,参考社区文档
[
4]
。
有如下场景时,建议你使用该能力:
-
需要调用云厂商的 API 来进行镜像仓库身份认证。
-
-
将镜像仓库凭据存储在磁盘或者 imagePullSecret 是不可接受的。
OpenKruise 也支持类似的方式来进行镜像预热,步骤如下:
-
节点上面安装云厂商的凭据提供插件,比如:AWS
[
5]
。
-
配置凭据提供插件的配置文件,如下:
apiVersion: v1
kind: ConfigMap
metadata:
name: credential-provider-config
namespace: kruise-system
data:
CredentialProviderPlugin.yaml: |
apiVersion: kubelet.config.k8s.io/v1
kind: CredentialProviderConfig
providers:
- name: ecr-credential-provider
matchImages:
- "*.dkr.ecr.*.amazonaws.com"
- "*.dkr.ecr.*.amazonaws.com.cn"
- "*.dkr.ecr-fips.*.amazonaws.com"
- "*.dkr.ecr.us-iso-east-1.c2s.ic.gov"
- "*.dkr.ecr.us-isob-east-1.sc2s.sgov.gov"
defaultCacheDuration: "12h"
apiVersion: credentialprovider.kubelet.k8s.io/v1
env:
- name: AWS_PROFILE
value: temp
-
凭据提供插件需要身份认证来请求云厂商获取镜像仓库临时凭证。如下是 AWS 共享凭证文件方式:
helm install kruise https://... --set installation.createNamespace=false --set daemon.credentialProvider.enable=true --set daemon.credentialProvider.hostPath=/etc/eks/image-credential-provider --set daemon.credentialProvider.configmap=credential-provider-config --set daemon.credentialProvider.awsCredentialsDir=/root/.aws
-
创建 ImagePullJob,通过上述插件进行镜像仓库认证,完成镜像预热。
支持第三方工具(Cert-Manager)
注入 Kruise Webhook CA
OpenKruise 需要 CA 证书来实现 webhook 认证。
默认情况下,Kruise 会生成自签名 CA 证书。
此外,也可以通过第三方工具来注入和管理,进而满足部分企业严格、统一管理凭证的诉求。
如下:
-
安装第三方 CA 管理工具,比如:Cert-Manager。
-
创建 issuer 和 certificate 资源:
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: kruise-webhook-certs
namespace: kruise-system
spec:
secretName: kruise-webhook-certs
dnsNames:
- kruise-webhook-service.kruise-system.svc
- localhost
issuerRef:
name: selfsigned-kruise
kind: Issuer
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: selfsigned-kruise
namespace: kruise-system
spec:
selfSigned: {}
3. OpenKruise 需要开启
featureGates=EnableExternalCerts=true
,并在 webhookConfiguration 和 CRD 注入对应的 cert annotations。
helm install kruise https://... --set featureGates="EnableExternalCerts=true" --set-json externalCerts.annotations='{"cert-manager.io/inject-ca-from":"kruise-system/kruise-webhook-certs"}'
日志是可观察性的一个重要方面,也是调试的重要工具。
但是 OpenKruise 日志传统上是非结构化的字符串,因此很难进行自动解析,以及任何可靠的后续处理、分析或查询。
从 OpenKruise 1.17 版本开始,我们增加了结构化日志的支持,该日志本身支持(键,值)对和对象引用。为了保持向后兼容性,结构化日志仍将作为字符串输出,其中该字符串包含这些“键” =“值”对的表示。也可以通过设置
helm install ... --set manager.loggingFormat=json
以 json 格式输出。如下 InfoS 调用:
klog.V(3).InfoS("SidecarSet updated status success", "sidecarSet", klog.KObj(sidecarSet), "matchedPods", status.MatchedPods,
"updatedPods", status.UpdatedPods, "readyPods", status.ReadyPods, "updateReadyPods", status.UpdatedReadyPods)
将得到下面的日志输出: