Kasten k10 提高系列 01 - 用对象选择器触发与注入 Kanister Sidecar

1.前言

在日常 Kubernetes 的构建与运维的过程中,存储的使用通常是混合模式。也就是K8S 管理者,既会使用支持云原生存储模式,象是 flexvolumeCSI - Container Storage Interface 的存储方式,又会使用一些非云原生的存储(例如,本地 SSDNAS等),这时我们应意识到,有些存储类是不支持快照功能在线容量扩展的。如果要对部署在非云原生的存储上的应用进行应保护,那么我们应该采用什么的方式去实现呢?利用 Kasten K10 的通用存储备份与恢复功能,我们可以通过极小的应用程序修改,以高效和透明的方式对应用进行备份、恢复和迁移的数据操作,而不必去考虑复杂的存储环境。

在之前的实战系列中我们曾经提供了一个完整的示例,该示例说明了如何使用 Kasten 的通用卷备份实现通用的云原生应用备份,Kasten k10 将向您的现有的应用程序部署的 Pod 中添加一个 Kanister sidecarSidecar 可以挂载应用程序数据卷,以实现数据操作的能力。详细情况见如下文档:

Kasten K10 实战系列 11 - Kasten K10 通用存储备份和恢复方法
https://www.data2clouds.com/?p=80

我们发现日常运维过程中,有些时候只用 Namespace 做为标签还是有些不方便,比如客户的系统中有几百个 ServicesPods 是通过不同的 Deployments 来部署的。使用 Namespace将会造成大范围的作用域。如何进行细粒度的选择,而缩小作用域的范围呢?这时就可以利用 ObjectSelector 参数, 使用这个方法我们可以轻松的实现动态的将 Kanister sidecar 注入到生产的 Pod 中,从而避免对整个、 Namespace 中的所有 Pod 注入 Sidecar 的麻烦。

2. 用对象选择器部署 Kanister Sidecar

2.1. 方法1: 在 K10 部署时选择 key=vaule 的形式

在K10部署时选择 key=vaule 的形式,注意以下文中的k10backup=true 是可以自行定义的,关于参数如下:

--set injectKanisterSidecar.enabled=true
--set-string injectKanisterSidecar.objectSelector.matchLabels.k10backup=true

$ helm install k10 k10-4.0.11.tgz --namespace kasten-io --set global.airgapped.repository=ccr.ccs.tencentyun.com/kasten-k10  \
   --set auth.basicAuth.enabled=true \
   --set auth.basicAuth.htpasswd='mars:$apr1$Cgu1sGVZ$w/8aLHZkVT73OqYZ06C0v.' \
   --set metering.mode=airgap \
   --set injectKanisterSidecar.enabled=true \
   --set-string injectKanisterSidecar.objectSelector.matchLabels.k10backup=true \
   --set prometheus.server.persistentVolume.enabled=false \
   --set ingress.create=true \
   --set ingress.class=nginx \
   --set global.persistence.storageClass=csi-hostpath-sc

2.2. 方法2: helm upgrade 更新现有参数

用 helm 升级的现有参数的方法如下:

# 导出当前配置
$ helm get values k10 --output yaml --namespace=kasten-io > k10_val.yaml
# 加入升级的配置
$ helm upgrade k10 k10-4.0.11.tgz --namespace=kasten-io -f k10_val.yaml \
  --set-string injectKanisterSidecar.objectSelector.matchLabels.k10backup=true

3. 动态部署 Kanister Sidecar 到现有的应用

  1. 我们以一个 Alpine 应用为例,查看当前环境,当前 Pod 中 只有一个 Contianer
$ kubectl get po -n alpine
NAME                        READY   STATUS    RESTARTS   AGE
demo-app-696f676d47-lqcsb   1/1     Running   0          7s
  1. 查看 K10 的参数,确认 objectSelector 方式已经被启用
$ helm get values k10 -n kasten-io
USER-SUPPLIED VALUES:
auth:
  basicAuth:
    enabled: true
    htpasswd: mars:$apr1$Cgu1sGVZ$w/8aLHZkVT73OqYZ06C0v.
global:
  airgapped:
    repository: ccr.ccs.tencentyun.com/kasten-k10
  persistence:
    storageClass: csi-hostpath-sc
ingress:
  class: nginx
  create: true
injectKanisterSidecar:
  enabled: true
  objectSelector:
    matchLabels:
      k10backup: "true"
metering:
  mode: airgap
prometheus:
  server:
    persistentVolume:
      enabled: false
  1. 查看当前的 Deployment
$ kubectl get deployment -n alpine 
NAME       READY   UP-TO-DATE   AVAILABLE   AGE
demo-app   1/1     1            1           43s

4. Label 当前的 Deployment 触发 Sidecar 注入的机制

$ kubectl label deployment demo-app k10backup=true -n alpine
deployment.apps/demo-app labeled
  1. 动态观察当前的 NamespacePod 状态

label 后触发了 Sidecar 注入的机制,这时 K8S 会启动一个新的 Pod 包括原有容器与Sidecar,接着 K8S 会Terminate 原有的 Pod,形成滚动发布的方式。

# label 后触发了 Sidecar 注入的机制,k8s 启动了一个新的 Pod 包括 Sidecar, 并
$ kubectl get po -n alpine
NAME                        READY   STATUS        RESTARTS   AGE
demo-app-66dbf75795-tkx2t   2/2     Running       0          4s
demo-app-696f676d47-lqcsb   1/1     Terminating   0          81s
# 
$ kubectl get po -n alpine
NAME                        READY   STATUS    RESTARTS   AGE
demo-app-66dbf75795-tkx2t   2/2     Running   0          61s
  1. 确认 Kansiter sidecar 已经注入成功
$ kubectl describe po demo-app-66dbf75795-tkx2t -n alpine
Name:         demo-app-66dbf75795-tkx2t
Namespace:    alpine
Priority:     0
Node:         minikube/192.168.99.103
Start Time:   Tue, 21 Sep 2021 16:20:49 +0800
Labels:       app=demo
              pod-template-hash=66dbf75795
Annotations:  <none>
Status:       Running
IP:           172.17.0.31
IPs:
  IP:           172.17.0.31
Controlled By:  ReplicaSet/demo-app-66dbf75795
Containers:
  demo-container:
    Container ID:  docker://1666bf583534940bfd508085701a2c2daf3c0fdcb3d38349a4cc01517833ec5f
    Image:         alpine:3.7
    Image ID:      docker-pullable://alpine@sha256:8421d9a84432575381bfabd248f1eb56f3aa21d9d7cd2511583c68c9b7511d10
    Port:          <none>
    Host Port:     <none>
    Command:
      tail
    Args:
      -f
      /dev/null
    State:          Running
      Started:      Tue, 21 Sep 2021 16:20:51 +0800
    Ready:          True
    Restart Count:  0
    Requests:
      cpu:        100m
      memory:     256Mi
    Environment:  <none>
    Mounts:
      /data from data (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-4v77s (ro)
  kanister-sidecar:
    Container ID:  docker://1ac8759bdd026b0565d539c26178157417df3c966509c91bee8eace7466c738a
    Image:         ccr.ccs.tencentyun.com/kasten-k10/kanister-tools:k10-0.66.0
    Image ID:      docker-pullable://ccr.ccs.tencentyun.com/kasten-k10/kanister-tools@sha256:0c8568439d2e928366193fb11b62e9a19887107eb26c0dfd5fcc61e8b539ce47
    Port:          <none>
    Host Port:     <none>
    Command:
      bash
      -c
    Args:
      tail -f /dev/null
    State:          Running
      Started:      Tue, 21 Sep 2021 16:20:51 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /data/data from data (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-4v77s (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
Volumes:
  data:
    Type:       PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
    ClaimName:  demo-pvc
    ReadOnly:   false
  kube-api-access-4v77s:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   Burstable
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:                      <none>

4. 总结

本文通过一个简单的实验,说明了 Kasten K10 用对象选择器部署 Kanister sidecar 的方式,比起用 NameSpace 的方式,能更加灵活的触发 Sidecar 的注入,从而利用 Kasten K10 的通用存储备份与恢复功能,以高效和透明的方式对应用进行备份、恢复和迁移的数据操作。

5. 参考链接

Kasten Generic Storage Backup and Restore
https://docs.kasten.io/latest/install/generic.html

Alpine Quick reference
https://hub.docker.com/_/alpine

Kasten K10 实战系列 11 - Kasten K10 通用存储备份和恢复方法
https://www.data2clouds.com/?p=80

6. 欢迎关注

MarsZhang @ 云端数据管理
www.data2.clouds.com

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注