使用reloader实现k8s热更新配置

在kubernetes中如果配置发生变化,我们如何做到无感知的配置热更新是重要的,下面我以stakater/Reloader为例解决这个问题。

Reloader是一个开源的Kubernetes工具,它可以观察 ConfigMap 和 Secret 中的变化,并对 pod 及其关联的 DeploymentConfigsDeploymentsDaemonsetsStatefulsets 和 Rollouts进行滚动升级。

原理

  • 当 Reloader 检测到 ConfigMap 发生变化的时候,会使用 SHA1 计算 ConfigMap 的哈希值(使用 SHA1 是因为它高效且不易发生冲突),计算完哈希值之后,Reloader 获取所有的 DeploymentsDaemonsetsStatefulsets 和 Rollouts 列表,并查找其 anotations 中是否配置了 Reloader 相关的注解(见下面)

  • Reloader 会查找配置了 Reloader 相关 annotations 的 DeploymentsDaemonsetsStatefulsets 中一个特殊的环境变量。

  • 如果找到这个环境变量,则获取其值并将其与前面计算的新 ConfigMap 哈希值进行比较,如果环境变量中的旧值与新哈希值不同,则 Reloader 会更新环境变量。

  • 如果环境变量不存在,那么它会从 ConfigMap 创建一个具有最新哈希值的新环境变量并更新相关的deploymentdaemonset或者statefulset

  • k8s 检测到这个环境变量发生变化,则会触发 pod 关联的 deploymentdaemonset或者statefulset 的滚动升级。

部署Reloader

kubectl apply -f https://raw.githubusercontent.com/stakater/Reloader/master/deployments/kubernetes/reloader.yaml

或者直接使用这个

---
# Source: reloader/templates/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  annotations:
    meta.helm.sh/release-namespace: "default"
    meta.helm.sh/release-name: "reloader"
  labels:
    app: reloader-reloader
    chart: "reloader-1.0.29"
    release: "reloader"
    heritage: "Helm"
    app.kubernetes.io/managed-by: "Helm"
  name: reloader-reloader
  namespace: default
---
# Source: reloader/templates/clusterrole.yaml
apiVersion: rbac.authorization.k8s.io/v1

kind: ClusterRole
metadata:
  annotations:
    meta.helm.sh/release-namespace: "default"
    meta.helm.sh/release-name: "reloader"
  labels:
    app: reloader-reloader
    chart: "reloader-1.0.29"
    release: "reloader"
    heritage: "Helm"
    app.kubernetes.io/managed-by: "Helm"
  name: reloader-reloader-role
rules:
  - apiGroups:
      - ""
    resources:
      - secrets
      - configmaps
    verbs:
      - list
      - get
      - watch
  - apiGroups:
      - "apps"
    resources:
      - deployments
      - daemonsets
      - statefulsets
    verbs:
      - list
      - get
      - update
      - patch
  - apiGroups:
      - "extensions"
    resources:
      - deployments
      - daemonsets
    verbs:
      - list
      - get
      - update
      - patch
  - apiGroups:
      - ""
    resources:
      - events
    verbs:
      - create
      - patch
---
# Source: reloader/templates/clusterrolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1

kind: ClusterRoleBinding
metadata:
  annotations:
    meta.helm.sh/release-namespace: "default"
    meta.helm.sh/release-name: "reloader"
  labels:
    app: reloader-reloader
    chart: "reloader-1.0.29"
    release: "reloader"
    heritage: "Helm"
    app.kubernetes.io/managed-by: "Helm"
  name: reloader-reloader-role-binding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: reloader-reloader-role
subjects:
  - kind: ServiceAccount
    name: reloader-reloader
    namespace: default
---
# Source: reloader/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    meta.helm.sh/release-namespace: "default"
    meta.helm.sh/release-name: "reloader"
  labels:
    app: reloader-reloader
    chart: "reloader-1.0.29"
    release: "reloader"
    heritage: "Helm"
    app.kubernetes.io/managed-by: "Helm"
    group: com.stakater.platform
    provider: stakater
    version: v1.0.29
  name: reloader-reloader
  namespace: default
spec:
  replicas: 1
  revisionHistoryLimit: 2
  selector:
    matchLabels:
      app: reloader-reloader
      release: "reloader"
  template:
    metadata:
      labels:
        app: reloader-reloader
        chart: "reloader-1.0.29"
        release: "reloader"
        heritage: "Helm"
        app.kubernetes.io/managed-by: "Helm"
        group: com.stakater.platform
        provider: stakater
        version: v1.0.29
    spec:
      containers:
      - image: "ghcr.io/stakater/reloader:v1.0.29"
        imagePullPolicy: IfNotPresent
        name: reloader-reloader

        ports:
        - name: http
          containerPort: 9090
        livenessProbe:
          httpGet:
            path: /live
            port: http
          timeoutSeconds: 5
          failureThreshold: 5
          periodSeconds: 10
          successThreshold: 1
          initialDelaySeconds: 10
        readinessProbe:
          httpGet:
            path: /metrics
            port: http
          timeoutSeconds: 5
          failureThreshold: 5
          periodSeconds: 10
          successThreshold: 1
          initialDelaySeconds: 10

        securityContext:
          {}
      securityContext:
        runAsNonRoot: true
        runAsUser: 65534
      serviceAccountName: reloader-reloader

ConfigMap

编辑我们的deployment加上如下注解:

kind: Deployment
metadata:
  annotations:
    configmap.reloader.stakater.com/reload: "foo-configmap,bar-configmap,baz-configmap"
spec:
  template: 
    metadata:

Secret

编辑我们的deployment加上如下注解:

kind: Deployment
metadata:
  annotations:
    secret.reloader.stakater.com/reload: "foo-secret,bar-secret,baz-secret"
spec:
  template: 
    metadata:

  

posted @ 2024-02-27 09:51  陶清刚  阅读(296)  评论(0)    收藏  举报