【问题标题】:Assign unique tokens to each node in a DaemonSet为 DaemonSet 中的每个节点分配唯一令牌
【发布时间】:2020-08-22 05:02:36
【问题描述】:

我有一组令牌,我需要将它们分发到 DaemonSet 中的每个 pod。令牌不能在运行时生成,而是提前生成的。

这种分布很容易用 StatefulSets 来完成——它可以用 volumeClaimTemplate 来完成,但我目前使用的机制是将所有令牌存储在一个秘密中,然后我从 pod 中获取后缀name 选择要读取的令牌。

但是 StatefulSet 会触发集群自动扩缩器。如果我使用反亲和确保每个节点只有一个pod,然后将副本数设置为集群中的最大节点数,会导致集群自动扩缩器扩展到最大节点数并停留在那里。

对于我正在尝试做的事情(每个节点一个 pod)来说,DaemonSet 是更好的模型,这就是为什么我按照我的方式来表达这个问题,但使用 StatefulSets 或其他任何东西的解决方案也可以接受。

【问题讨论】:

  • 您是否考虑过一个initContainer:,它可以执行您希望的任何计算并将令牌发送到它与主container: 之间共享的emptyDir: {} 卷?
  • 令牌是一个预共享密钥,不能通过计算创建。

标签: kubernetes


【解决方案1】:

kubectl annotate secret foo --resource-version=X --overwrite 可以用作锁定机制。阅读注释,确定它是否可用,然后注释它是否可用。如果您的注释成功,您将获得锁定。如果它不尝试不同的秘密。

这是我为此编写的脚本。

#!/usr/bin/env bash

set -e -u -o pipefail
shopt -s inherit_errexit
#set -x

## START CONFIGURATION

KUBECTL="kubectl --context green -n foo"
ANNOTATION=foo
VALUE=node/$HOSTNAME

# returns in OBJECTS and VALID_VALUES constants
function readValues() {
    # this order is important.   The reverse will have a race condition
    OBJECTS=$($KUBECTL get secrets -l locktest=1 -o json | jq -r ".items[] | @base64")
    # read -p "Press enter to give chance to fake a race condition"
    VALID_VALUES=$($KUBECTL get nodes -o name)
}

## END CONFIGURATION

# returns via stdout kind/name of locked object
# returns via $?: 0 found, 1 not found
function isLockedAlready() {
    for obj in $OBJECTS; do
        json=$(echo "$obj" | base64 -d)
        value=$(echo $json | jq -r ".metadata.annotations.${ANNOTATION}")
        if [[ $value == $VALUE ]] ; then
            # echo $name is already locked
            name=$(echo "$json" | jq -r ".metadata.name")
            kind=$(echo "$json" | jq -r ".kind")
            echo $kind/$name
            return  0
        fi
    done
    return 1
}

# returns via stdout the base64 json of an object that's not in listValidValues
# returns via $?: 0 found, 1 not found
function findCandidate() {
    for obj in $OBJECTS; do
        json=$(echo "$obj" | base64 -d)
        value=$(echo $json | jq -r ".metadata.annotations.${ANNOTATION}")
        name=$(echo $json | jq -r ".metadata.name")
        valid=0
        for v in $VALID_VALUES ; do
            if [[ $value == $v ]] ; then
                # echo $name has valid value $v
                valid=1
                # else # echo $name value $value is not $v
            fi
        done
        if [[ $valid == 0 ]]; then
            # echo $name is available
            echo $obj
            return 0
            # else # echo $name is not available
        fi
    done
    return 1
}

# $1: the object to lock (as base64 json)
# return in $?:  0==success
function lock() {
    name=$(echo "$1" | base64 -d | jq -r ".metadata.name")
    kind=$(echo "$1" | base64 -d | jq -r ".kind")
    resource_version=$(echo "$1" | base64 -d | jq -r ".metadata.resourceVersion")
    if $KUBECTL annotate $kind $name $ANNOTATION=$VALUE --resource-version=$resource_version --overwrite > /dev/null; then
        echo $kind/$name
        return 0
    else
        # echo "ANNOTATION FAILED!  RETRY"
        return 1
    fi
}

for retry in 1 2 3 ; do
    readValues
    if isLockedAlready ; then
        exit 0
    elif obj=$(findCandidate) ; then
        if lock "$obj" ; then
            exit 0
        fi
    fi
    sleep 20
    # echo retry
done

exit 1

【讨论】:

    【解决方案2】:

    如果您没有自动扩缩器,那么到目前为止,使用具有反关联性的 StatefulSet 来为每个节点获取一个 pod 是一种更简单的解决方案。只需使用 volumeClaimTemplates,然后将令牌放入后续卷中。

    或者如果令牌在秘密中,那么您可以将所有秘密挂载在每个 pod 中,然后从$POD_NAME 末尾获取数字以了解实际使用哪个秘密。

    【讨论】:

      猜你喜欢
      • 2011-04-25
      • 1970-01-01
      • 1970-01-01
      • 2023-03-26
      • 1970-01-01
      • 2017-07-10
      • 2021-06-12
      • 2019-09-19
      • 2019-03-17
      相关资源
      最近更新 更多