OpenKruise 是阿里云开源的大规模应用自动化管理引擎,在功能上对标了 Kubernetes 原生的 Deployment / StatefulSet 等控制器,但 OpenKruise 提供了更多的增强功能如:优雅原地升级、发布优先级/打散策略、多可用区workload抽象管理、统一 sidecar 容器注入管理等,都是经历了阿里巴巴超大规模应用场景打磨出的核心能力。这些 feature 帮助我们应对更加多样化的部署环境和需求、为集群维护者和应用开发者带来更加灵活的部署发布组合策略。

CRD

Kruise 是 cruise的谐音,’k’ for Kubernetes. 字面意义巡航,豪华游艇。寓意Kubernetes上应用的自动巡航,满载阿里巴巴多年应用部署管理经验。

Kruise 提供了以下 5 个 workload 控制器:

  • CloneSet: 提供了更加高效、确定可控的应用管理和部署能力,支持优雅原地升级、指定删除、发布顺序可配置、并行/灰度发布等丰富的策略,可以满足更多样化的应用场景。
  • Advanced StatefulSet: 基于原生 StatefulSet 之上的增强版本,默认行为与原生完全一致,在此之外提供了原地升级、并行发布(最大不可用)、发布暂停等功能。
  • SidecarSet: 对 sidecar 容器做统一管理,在满足 selector 条件的 Pod 中注入指定的 sidecar 容器。
  • UnitedDeployment: 通过多个 subset workload 将应用部署到多个可用区。
  • BroadcastJob: 配置一个 job,在集群中所有满足条件的 Node 上都跑一个 Pod 任务。

安装

前置检查

使用 Kruise 需要在 kube-apiserver 启用一些 feature-gate 比如 MutatingAdmissionWebhook、ValidatingAdmissionWebhook (K8s 1.12以上默认开启)。 如果你的 K8s 版本低于 1.12,需要先执行以下命令来验证是否支持:

sh -c "$(curl -fsSL https://raw.githubusercontent.com/openkruise/kruise/master/scripts/check_for_installation.sh)"(源文件在代码的scripts目录下)

helm安装

推荐使用 helm v3 安装 Kruise,helm 是一个简单的命令行工具可以从这里了解。

helm install kruise https://github.com/openkruise/kruise/releases/download/v0.5.0/kruise-chart.tgz

注意直接安装 chart 会使用默认的 template values,你也可以根据你的集群情况指定一些特殊配置,比如修改 resources 限制或者只启用某些特定的控制器能力。

yaml安装

# Install CRDs(源文件在代码的config目录下)
kubectl apply -f https://raw.githubusercontent.com/kruiseio/kruise/master/config/crds/apps_v1alpha1_broadcastjob.yaml
kubectl apply -f https://raw.githubusercontent.com/kruiseio/kruise/master/config/crds/apps_v1alpha1_sidecarset.yaml
kubectl apply -f https://raw.githubusercontent.com/kruiseio/kruise/master/config/crds/apps_v1alpha1_statefulset.yaml
kubectl apply -f https://raw.githubusercontent.com/kruiseio/kruise/master/config/crds/apps_v1alpha1_uniteddeployment.yaml
kubectl apply -f https://raw.githubusercontent.com/kruiseio/kruise/master/config/crds/apps_v1alpha1_cloneset.yaml

# Install kruise-controller-manager
kubectl apply -f https://raw.githubusercontent.com/kruiseio/kruise/master/config/manager/all_in_one.yaml

注意 all_in_one.yaml 中包含的 Kruise-manager 镜像是每天周期性从 master 分支打出来的,无法保证功能的稳定性。 所以你可以通过 YAML 部署到测试集群做验证,但不推荐在生产环境使用。

部分安装

如果你只需要使用某些 Kruise 中的控制器并关闭其他的控制器,你可以做以下两个方式或同时做:

1、只安装你需要使用的 CRD。

2、在 kruise-manager 容器中设置 CUSTOM_RESOURCE_ENABLE 环境变量,配置需要启用的功能,比如 CUSTOM_RESOURCE_ENABLE=CloneSet,StatefulSet。

如果使用 helm chart 安装,可以通过以下参数来生效这个配置:

helm install kruise https://github.com/openkruise/kruise/releases/download/v0.5.0/kruise-chart.tgz --set manager.custom_resou

卸载

卸载会导致所有 Kruise 下的资源都会删除掉,包括 webhook configurations, services, namespace, CRDs, CR instances 以及所有 Kruise workload 下的 Pod。 请务必谨慎操作!

卸载使用 helm chart 安装的 Kruise:

helm uninstall kruise

卸载使用 YAML files 安装的 Kruise:

sh -c "$(curl -fsSL https://raw.githubusercontent.com/kruiseio/kruise/master/scripts/uninstall.sh)"

使用

cloneset

使用cloneset来创建Guestbook应用

1、安装redis

# install Redis by CloneSet
$ kubectl apply -f https://raw.githubusercontent.com/kruiseio/kruise/master/docs/tutorial/v1/cloneset-redis.yaml
service/redis-master created
service/redis-slave created
cloneset.apps.kruise.io/redis-master created
cloneset.apps.kruise.io/redis-slave created

2、安装Guestbook

# install Guestbook by CloneSet
$ kubectl apply -f https://raw.githubusercontent.com/kruiseio/kruise/master/docs/tutorial/v1/cloneset-guestbook.yaml
service/guestbook-clone-svc created
cloneset.apps.kruise.io/guestbook-clone created

3、查看创建的cloneset

MacBook-Pro:yaml chunyinjiang$ kubectl get pod
NAME                    READY   STATUS    RESTARTS   AGE
guestbook-clone-2rrv5   1/1     Running   0          17s
guestbook-clone-6dwl2   1/1     Running   0          17s
guestbook-clone-c2hhc   1/1     Running   0          17s
guestbook-clone-cbp59   1/1     Running   0          17s
guestbook-clone-dncmh   1/1     Running   0          17s
guestbook-clone-hl9jk   1/1     Running   0          17s
guestbook-clone-j94s9   1/1     Running   0          16s
guestbook-clone-k9j5g   1/1     Running   0          16s
guestbook-clone-nvst8   1/1     Running   0          16s
guestbook-clone-p9k65   1/1     Running   0          16s
guestbook-clone-p9tf8   1/1     Running   0          16s
guestbook-clone-q9dvt   1/1     Running   0          16s
guestbook-clone-qfbx6   1/1     Running   0          16s
guestbook-clone-rvjww   1/1     Running   0          16s
guestbook-clone-w675b   1/1     Running   0          16s
guestbook-clone-whgf4   1/1     Running   0          16s
guestbook-clone-x7gg7   1/1     Running   0          16s
guestbook-clone-xrg9p   1/1     Running   0          16s
guestbook-clone-xxwmn   1/1     Running   0          16s
guestbook-clone-xzxw9   1/1     Running   0          16s
redis-master-fq8vp      1/1     Running   0          5m9s
redis-slave-srgsc       1/1     Running   0          5m9s
redis-slave-vglqg       1/1     Running   0          5m9s


MacBook-Pro:yaml chunyinjiang$ kubectl get clonesets.apps.kruise.io
NAME              DESIRED   UPDATED   UPDATED_READY   READY   TOTAL   AGE
guestbook-clone   20        20        20              20      20      82s
redis-master      1         1         1               1       1       12m
redis-slave       2         2         2               2       2       12m

MacBook-Pro:yaml chunyinjiang$ kubectl get svc
NAME                  TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)                         AGE
guestbook-clone-svc   LoadBalancer   10.103.56.2    <pending>     3000:31496/TCP,4000:32724/TCP   118s
kubernetes            ClusterIP      10.96.0.1      <none>        443/TCP                         7d6h
redis-master          ClusterIP      10.103.204.4   <none>        6379/TCP                        13m
redis-slave           ClusterIP      10.105.86.31   <none>        6379/TCP                        13m

5、扩容

$ kubectl scale --replicas=25 clone guestbook-clone
cloneset.apps.kruise.io/guestbook-clone scaled

6、指定pod缩容

kubectl edit clonesets.apps.kruise.io guestbook-clone
spec:
  replicas: 22
  scaleStrategy:
    podsToDelete:
    - guestbook-clone-k9796
    - guestbook-clone-nkn52
    - guestbook-clone-w9qgl

7、灰度升级

spec:
  # ...
  template:
    spec:
      containers:
      - name: guestbook
        image: openkruise/guestbook:v2
      # ...
  updateStrategy:
    partition: 15

8、实际场景

目前有openkruise/guestbook:v1的pod为10个。

MacBook-Pro:iamges chunyinjiang$ kubectl get clonesets.apps.kruise.io guestbook-clone
NAME              DESIRED   UPDATED   UPDATED_READY   READY   TOTAL   AGE
guestbook-clone   10        10        10              10      10      23h
MacBook-Pro:iamges chunyinjiang$ kubectl get pods -o jsonpath="{.items[*].spec.containers[*].image}"| tr -s '[[:space:]]' '\n' |sort |uniq -c | grep  openkruise
  10 openkruise/guestbook:v1

需要想其中五个升级为版本v2。

MacBook-Pro:iamges chunyinjiang$ kubectl edit clonesets.apps.kruise.io guestbook-clone

    spec:
      containers:
      - image: openkruise/guestbook:v2
        imagePullPolicy: IfNotPresent
        name: guestbook
        ports:
        - containerPort: 3000
          name: http-server
          protocol: TCP
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
  updateStrategy:
    inPlaceUpdateStrategy: {}
    maxSurge: 0
    maxUnavailable: 3
    partition: 5
    type: InPlaceIfPossible

MacBook-Pro:iamges chunyinjiang$ kubectl edit clonesets.apps.kruise.io guestbook-clone
cloneset.apps.kruise.io/guestbook-clone edited

查看

MacBook-Pro:iamges chunyinjiang$ kubectl get clonesets.apps.kruise.io guestbook-clone
NAME              DESIRED   UPDATED   UPDATED_READY   READY   TOTAL   AGE
guestbook-clone   10        5         5               10      10      23h
MacBook-Pro:iamges chunyinjiang$ kubectl get pods -o jsonpath="{.items[*].spec.containers[*].image}"| tr -s '[[:space:]]' '\n' |sort |uniq -c | grep  openkruise
   5 openkruise/guestbook:v1
   5 openkruise/guestbook:v2

现在又需要给v1版本和v2版本同时扩容,每个新增5个

先在v2版本的情况下直接将replicas重10改成15,应该会新增5个v2的版本

spec:
  replicas: 15

MacBook-Pro:iamges chunyinjiang$ kubectl edit clonesets.apps.kruise.io guestbook-clone
cloneset.apps.kruise.io/guestbook-clone edited

查看

MacBook-Pro:iamges chunyinjiang$ kubectl get clonesets.apps.kruise.io guestbook-clone
NAME              DESIRED   UPDATED   UPDATED_READY   READY   TOTAL   AGE
guestbook-clone   15        10        10              15      15      23h
MacBook-Pro:iamges chunyinjiang$ kubectl get pods -o jsonpath="{.items[*].spec.containers[*].image}"| tr -s '[[:space:]]' '\n' |sort |uniq -c | grep  openkruise
   5 openkruise/guestbook:v1
  10 openkruise/guestbook:v2

然后给版本切换到v1,同时要修改对应的partion到10,才能不更新

MacBook-Pro:iamges chunyinjiang$ kubectl get pods -o jsonpath="{.items[*].spec.containers[*].image}"| tr -s '[[:space:]]' '\n' |sort |uniq -c | grep  openkruise
   5 openkruise/guestbook:v1
  10 openkruise/guestbook:v2

然后在v2版本的情况下直接将replicas重15改成20,应该会新增5个v1的版本

MacBook-Pro:iamges chunyinjiang$ kubectl get pods -o jsonpath="{.items[*].spec.containers[*].image}"| tr -s '[[:space:]]' '\n' |sort |uniq -c | grep  openkruise
  10 openkruise/guestbook:v1
  10 openkruise/guestbook:v2

下面根据升级情况来设置v1和v2版本。

cloneset对比deployment

cloneset可以说是deployment的增强版本。