基於openkruise實現容器應用固定id


背景說明

我們在業務上容器的過程中遇到了如下問題:

  1. 以deployment部署的應用pod,由於id經常變更,服務重啟,監控變得難以維護。這里只是以監控為切入點,事實上,還有諸多應用需要與id強綁定。
  2. statefulset可以解決上面的問題,但是引入一個新的問題就是statefulset本身為了維護有狀態的應用,所有的應用Pod啟動是有嚴格的先后順序,也就是串行啟動,對於大規模的應用pod來講,啟動消耗時間太長,這是無法忍受的。

為解決以上問題,我們在容器平台當中引入了openkruise。

openkruise簡介

項目地址: https://github.com/openkruise/kruise

詳細的說明可以參考這篇文章: 《OpenKruise - 雲原生應用自動化引擎正式開源》

從當前github上的文檔來看,目前OpenKruise支持五種改進的控制器:

  • CloneSet: CloneSet is a workload that mainly focuses on managing stateless applications. It provides full features for more efficient, deterministic and controlled deployment, such as inplace update, specified pod deletion, configurable priority/scatter update, preUpdate/postUpdate hooks.

  • Advanced StatefulSet: An enhanced version of default StatefulSet with extra functionalities such as inplace-update, pause and MaxUnavailable.

  • SidecarSet: A controller that injects sidecar containers into the Pod spec based on selectors and also is able to upgrade the sidecar containers.

  • UnitedDeployment: This controller manages application pods spread in multiple fault domains by using multiple workloads.

  • BroadcastJob: A job that runs Pods to completion across all the nodes in the cluster.

UnitedDeployment是在StatefulSet基礎上的更高級抽象,通過一個資源描述可以管理多個StatefulSet的實例組,可實現多實例組的灰度發布與滾動升級。

Broadcast Job實際上就是以DaemonSet的方式在所有節點上運行一次性Job

SidercarSet用於Sidercar注入及管理

而我們要使用到的正是其Advanced StatefulSet的特性。關於Advanced StatefulSet更詳細的描述如下:

  • 在kubernetes官方的statefulSet上做了功能擴展,更新策略由原來的只支持recreate,擴展為同時支持recreate和rollingupdate。rollingupdate還支持兩種策略,一種是InPlaceIfPossible,另一種是InPlaceOnly。InPlaceIfPossible會盡可能的保證應用在原地升級(只支持鏡像的升級,如果修改了yaml中的其他配置項,則無法保證);InPlaceOnly會保證應用一定在原地升級,但是它也只支持鏡像的升級,如果修改了yaml中的其他配置項,會直接拋出異常。另外,原生的StatefulSet只能做到串行啟動,Advanced StatefulSet可以做到並行啟動。

部署openkruise

官方的安裝文檔可以直接參考這里:
https://github.com/openkruise/kruise/tree/master/docs/tutorial

我簡單寫下安裝步驟:

wget https://github.com/openkruise/kruise/releases/download/v0.4.0/kruise-chart.tgz

tar xf kruise-chart.tgz

cd kruise

helm install openkruise ./ -n kube-system 

目前openkruise已經更新到了v0.5.0的版本。也可以直接通過阿里雲的應用目錄來完成其安裝。

下面說一下更詳細的安裝過程:

  1. 獲取helm包

helm repo add incubator  http://aliacs-k8s-cn-beijing.oss-cn-beijing.aliyuncs.com/app/charts-incubator/

helm search repo ack-kruise

helm fetch incubator/ack-kruise

tar xf ack-kruise-0.5.0.tgz

cd ack-kruise

修改values.yml文件如下:

# Default values for kruise.

revisionHistoryLimit: 3

manager:
  # settings for log print
  log:
    # log level for kruise-manager
    level: "4"

  # image settings
  image:
    # repository for kruise-manager image
    repository: hub.example.com/library/kruise-manager
    # tag for kruise-manager image
    tag: v0.5.0

  # resources of kruise-manager container
  resources:
    limits:
      cpu: 500m
      memory: 1Gi
    requests:
      cpu: 500m
      memory: 1Gi

  metrics:
    addr: localhost
    port: 8080
    
  custom_resource_enable: StatefulSet

其實這里就改了兩個東西:

  • image:默認是docker hub上的地址,我這里改到了私有鏡像倉庫
  • custom_resource_enable:用於指定啟用哪幾種資源,如果不指定的話,openkruise支持的五種資源會全部啟用,我這里只用到了StatefulSet,所以這里只啟用了這一種資源

然后執行安裝操作:

helm install ack-kruise -n kube-system ./

安裝完后,會生成以下五種crd:

# kubectl get crds |grep kruise
broadcastjobs.apps.kruise.io            2020-04-26T10:29:28Z
clonesets.apps.kruise.io                2020-04-26T10:29:28Z
sidecarsets.apps.kruise.io              2020-04-26T10:29:28Z
statefulsets.apps.kruise.io             2020-04-26T10:29:28Z
uniteddeployments.apps.kruise.io        2020-04-26T10:29:28Z

同時會創建一個kruise-system的命名空間,並在里面生成一個pod:

# kubectl get pods -n kruise-system 
NAME                          READY   STATUS    RESTARTS   AGE
kruise-controller-manager-0   1/1     Running   0          55m

驗證statefulset資源的webhook是否被正常創建:

# kubectl get mutatingwebhookconfiguration -o yaml

apiVersion: v1
items:
- apiVersion: admissionregistration.k8s.io/v1
  kind: MutatingWebhookConfiguration
  metadata:
    creationTimestamp: "2020-04-26T10:29:28Z"
    generation: 3
    name: kruise-mutating-webhook-configuration
    resourceVersion: "622944921"
    selfLink: /apis/admissionregistration.k8s.io/v1/mutatingwebhookconfigurations/kruise-mutating-webhook-configuration
    uid: 303a7b7f-3a62-49d7-8ef6-082ea288eeb2
  webhooks:
  - admissionReviewVersions:
    - v1beta1
    clientConfig:
      caBundle: xxxxx
      service:
        name: kruise-webhook-server-service
        namespace: kruise-system
        path: /mutating-create-update-statefulset
        port: 443
    failurePolicy: Fail
    matchPolicy: Exact
    name: mutating-create-update-statefulset.kruise.io
    namespaceSelector:
      matchExpressions:
      - key: control-plane
        operator: DoesNotExist
    objectSelector: {}
    reinvocationPolicy: Never
    rules:
    - apiGroups:
      - apps.kruise.io
      apiVersions:
      - v1alpha1
      operations:
      - CREATE
      - UPDATE
      resources:
      - statefulsets
      scope: '*'
    sideEffects: Unknown
    timeoutSeconds: 30
......

也是確保其他未用到的相關mutatingwebhook是關閉的。。在實際測試中,SidecarSet資源的mutatingwebhook可能會導致創建的pod出不來。

這些webhook本質上都是kubernetes的admissioncontrol,只要你安裝了,哪怕沒有使用,當你在執行相關操作時,都需要被所有的adminssioncontrol檢測,如果admissioncontrol本身出了問題,就會導致請求無法響應的狀態。同時這些webhook類型的adminssioncontrol也會拖慢響應速度。

用法示例

下面是官方提供的一個基於openkruise提供的statefulset資源的部署文件示例:

apiVersion: apps.kruise.io/v1alpha1
kind: StatefulSet
metadata:
  name: demo-v1-guestbook-kruise
  labels:
    app.kubernetes.io/name: guestbook-kruise
    app.kubernetes.io/instance: demo-v1
spec:
  replicas: 3
  serviceName: demo-v1-guestbook-kruise
  selector:
    matchLabels:
      app.kubernetes.io/name: guestbook-kruise
      app.kubernetes.io/instance: demo-v1
  template:
    metadata:
      labels:
        app.kubernetes.io/name: guestbook-kruise
        app.kubernetes.io/instance: demo-v1
    spec:
      readinessGates:
        # A new condition that ensures the pod remains at NotReady state while the in-place update is happening
      - conditionType: InPlaceUpdateReady
      containers:
      - name: guestbook-kruise
        image: openkruise/guestbook:v1
        imagePullPolicy: Always
        ports:
        - name: http-server
          containerPort: 3000
  podManagementPolicy: Parallel  # allow parallel updates, works together with maxUnavailable
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      # Do in-place update if possible, currently only image update is supported for in-place update
      podUpdatePolicy: InPlaceIfPossible
      # Allow parallel updates with max number of unavailable instances equals to 2
      maxUnavailable: 3

執行部署之后,啟動pod示例如下:

# kubectl get pods  |grep demo-v1
demo-v1-guestbook-kruise-0                                 1/1     Running   0          62s
demo-v1-guestbook-kruise-1                                 1/1     Running   0          62s
demo-v1-guestbook-kruise-2                                 1/1     Running   0          62s

也可通過如下操作查看資源狀態:

# kubectl get sts.apps.kruise.io 
NAME                       DESIRED   CURRENT   UPDATED   READY   AGE
demo-v1-guestbook-kruise   3         3         3         3       56s

openkruise提供的statefulset的資源名為sts.apps.kruise.io

更詳細的用法可參考:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM