shell-operator 配置 K8s Pod 保护策略

保障 Pod 高可用分为以下几个方面

  • 资源池划分 :打污点、独占、隔离
  • Qos 分级 & 优先级:按应用等级保障稳定性
  • 自动弹性伸缩 HPA
  • Pod 干扰预算 PDB

本篇主要介绍第四点:巧用 Shell-operator 配置 K8s Pod 保护策略

什么是 Shell-operator?

Shell-operator 是一个在 Kubernetes 集群中运行事件驱动脚本的工具。

该操作器不是针对特定软件产品的操作器,例如 prometheus-operator 或 kafka-operator。Shell-operator 通过将脚本视为由事件触发的钩子,提供了 Kubernetes 集群事件和 Shell 脚本之间的集成层。您可以将其视为 operator-sdk,但用于脚本。

Shell-operator 用作更高级的 addon-operator 的基础,该 operator 支持 Helm charts 和值存储。

Shell-operator 提供了以下功能:

  • Kubernetes 集群的简易管理:使用运维人员熟悉的工具。可以是 bash、python、kubectl 等,真是运维人的实用工具。
  • Kubernetes 对象事件:钩子可以由添加、更新或删除事件触发。
  • 对象选择器和属性过滤器:shell-operator 可以监视特定的对象集,并检测其属性的更改。
  • 简单的配置:钩子绑定定义是脚本的标准输出中的 JSON 或 YAML 文档。
  • 验证 Webhook 机制:钩子可以处理 Kubernetes 资源的验证。
  • 转换 Webhook 机制:钩子可以处理 Kubernetes 资源的版本转换。

借助 Shell-operator 配置 PDB

配置 PDB 需要用到便签选择器 selector,示例中选择 AppID 作为标签匹配 Shell-operator 需要监控一个对象的事件,来更新 PDB 的状态,示例中选择 rollouts.argoproj.io 对象 namespace 选择 prod

1.创建基础模版 pdb-init.sh

bash 复制代码
#!/usr/bin/env bash

NAMESPACE="prod"

pdb_templates() {
  cat <<EOF
apiVersion: policy/v1beta1
kind: PodDisruptionBudget
metadata:
  name: clay-test
  namespace: ${NAMESPACE}
spec:
  minAvailable: 1
  selector:
    matchLabels:
      appid: clay-test
EOF
}

replace_or_create() {
  object=$(cat)

  if ! kubectl get -f - <<< "$object" >/dev/null 2>/dev/null; then
    kubectl create -f - <<< "$object" >/dev/null
  else
    kubectl replace --force -f - <<< "$object" >/dev/null
  fi
}

init() {
  echo "Init PDB templates"
  pdb_templates | replace_or_create
  for resourceName in $(kubectl -n ${NAMESPACE} get rollouts.argoproj.io | grep default | awk '{print $1}'); do
    appid=${resourceName%-default} 
    echo "Init Add PDB '${appid}'"
    kubectl -n ${NAMESPACE} get pdb clay-test -o json | \
      jq -r ".metadata.name="${appid}" | .spec.selector.matchLabels["appid"]="${appid}" |
              .metadata |= with_entries(select([.key] | inside(["name", "namespace", "labels"])))" \
      | replace_or_create
  done
}

init "$@"

2.编写钩子脚本pdb-hooks.sh

bash 复制代码
#!/usr/bin/env bash  
  
NAMESPACE="prod"  
ARRAY_COUNT=$(jq -r '. | length-1' $BINDING_CONTEXT_PATH)  
  
run_hook() {  
  if [[ $1 == "--config" ]] ; then  
    config  
  else  
    trigger  
  fi  
}  
  
config() {  
  cat <<EOF  
configVersion: v1  
kubernetes:  
- apiVersion: argoproj.io/v1alpha1  
  kind: Rollout  
  executeHookOnEvent:  
  - Added  
  - Deleted  
  namespace:  
    nameSelector:  
      matchNames:  
      - ${NAMESPACE}  
EOF  
}  
  
trigger() {  
  for IND in `seq 0 $ARRAY_COUNT`; do  
    resourceEvent=$(jq -r ".[$IND].watchEvent" $BINDING_CONTEXT_PATH)  
    resourceName=$(jq -r ".[$IND].object.metadata.name" $BINDING_CONTEXT_PATH)  
    appid=${resourceName%-default}  
    if [[ $resourceEvent == "Added" ]] ; then  
      echo "Add PDB '${appid}'"  
      kubectl -n ${NAMESPACE} get pdb clay-test -o json | \  
        jq -r ".metadata.name=\"${appid}\" | .spec.selector.matchLabels[\"appid\"]=\"${appid}\" |  
                .metadata |= with_entries(select([.key] | inside([\"name\", \"namespace\", \"labels\"])))" \  
        | replace_or_create  
    elif [[ $resourceEvent == "Deleted" ]]; then  
      echo "Delete PDB '${appid}'"  
      kubectl -n ${NAMESPACE} delete pdb ${appid}  
    else  
      echo "Do nothing"  
    fi  
  done  
}  
  
replace_or_create() {  
  object=$(cat)  
  
  if ! kubectl get -f - <<< "$object" >/dev/null 2>/dev/null; then  
    kubectl create -f - <<< "$object" >/dev/null  
  else  
    kubectl replace --force -f - <<< "$object" >/dev/null  
  fi  
}  
  
run_hook "$@"

3.打包镜像,Dockerfile 如下

Dockerfile 复制代码
FROM ghcr.io/flant/shell-operator:latest

ADD pdb-hooks.sh /hooks

4.编写 RBAC、Deployment等shell-operator-pdb.yaml,部署到 K8s 集群中

yaml 复制代码
apiVersion: v1  
kind: ServiceAccount  
metadata:  
  name: shell-operator-pdb  
  namespace: monitor  
  labels:  
    app: shell-operator-pdb  
    appid: shell-operator-pdb  
  
  
---  
apiVersion: rbac.authorization.k8s.io/v1  
kind: ClusterRole  
metadata:  
  labels:  
    app: shell-operator-pdb  
    appid: shell-operator-pdb  
  name: shell-operator-pdb  
rules:  
- apiGroups:  
  - ""  
  resources:  
  - pods  
  verbs:  
  - get  
  - watch  
  - list  
- apiGroups:  
  - argoproj.io  
  resources:  
  - '*'  
  verbs:  
  - get  
  - list  
  - watch  
- apiGroups:  
  - policy  
  resources:  
  - poddisruptionbudgets  
  verbs:  
  - get  
  - create  
  - patch  
  - update  
  - delete  
  
  
---  
apiVersion: rbac.authorization.k8s.io/v1  
kind: ClusterRoleBinding  
metadata:  
  name: shell-operator-pdb  
  labels:  
    app: shell-operator-pdb  
    appid: shell-operator-pdb  
roleRef:  
  apiGroup: rbac.authorization.k8s.io  
  kind: ClusterRole  
  name: shell-operator-pdb  
subjects:  
- kind: ServiceAccount  
  name: shell-operator-pdb  
  namespace: monitor  
  
  
---  
apiVersion: apps/v1  
kind: Deployment  
metadata:  
  name: shell-operator-pdb  
  labels:  
    app: shell-operator-pdb  
    appid: shell-operator-pdb  
  namespace: monitor  
spec:  
  replicas: 1  
  selector:  
    matchLabels:  
      app: shell-operator-pdb  
  strategy:  
    rollingUpdate:  
      maxSurge: 25%  
      maxUnavailable: 1  
    type: RollingUpdate  
  template:  
    metadata:  
      labels:  
        app: shell-operator-pdb  
        appid: shell-operator-pdb  
    spec:  
      containers:  
      - image: wangzhichidocker/shell-operator-pdb:v1.0  
        imagePullPolicy: IfNotPresent  
        name: shell-operator-pdb  
        resources:  
          limits:  
            cpu: 500m  
            memory: 1000Mi  
          requests:  
            cpu: 100m  
            memory: 200Mi  
      dnsPolicy: ClusterFirst  
      nodeSelector:  
        kubernetes.io/os: linux  
      serviceAccountName: shell-operator-pdb
bash 复制代码
# 部署
kubectl apply -f deploy/shell-operator-pdb.yaml

快速体验

bash 复制代码
git clone https://github.com/clay-wangzhi/shell-operator-pdb  
bash pdb-init.sh  
kubectl apply -f deploy/shell-operator-pdb.yaml

详见:github.com/clay-wangzh... 参考链接:

相关推荐
weixin_4539650010 分钟前
[单master节点k8s部署]31.ceph分布式存储(二)
分布式·ceph·kubernetes
大G哥3 小时前
记一次K8S 环境应用nginx stable-alpine 解析内部域名失败排查思路
运维·nginx·云原生·容器·kubernetes
妍妍的宝贝3 小时前
k8s 中微服务之 MetailLB 搭配 ingress-nginx 实现七层负载
nginx·微服务·kubernetes
福大大架构师每日一题5 小时前
23.1 k8s监控中标签relabel的应用和原理
java·容器·kubernetes
程序那点事儿5 小时前
k8s 之动态创建pv失败(踩坑)
云原生·容器·kubernetes
唐大爹17 小时前
项目实战:k8s部署考试系统
云原生·容器·kubernetes
Zl1597531597531 天前
k8s基础环境部署
云原生·容器·kubernetes
花酒锄作田1 天前
[kubernetes]二进制方式部署单机k8s-v1.30.5
kubernetes
陌殇殇殇1 天前
使用GitLab CI构建持续集成案例
运维·ci/cd·云原生·容器·kubernetes·gitlab
daxian_am4611 天前
k8s image error
java·数据库·kubernetes