mirror of
https://github.com/arangodb/kube-arangodb.git
synced 2024-12-14 11:57:37 +00:00
Feature/add rotate annotation (#530)
This commit is contained in:
parent
7c649303d0
commit
221d9d1b7f
7 changed files with 95 additions and 7 deletions
|
@ -1,6 +1,7 @@
|
|||
# Change Log
|
||||
|
||||
## [master](https://github.com/arangodb/kube-arangodb/tree/master) (N/A)
|
||||
- Added annotation to rotate ArangoDeployment in secure way
|
||||
|
||||
## [1.0.0](https://github.com/arangodb/kube-arangodb/tree/1.0.0) (2020-03-03)
|
||||
- Removal of v1alpha support for ArangoDeployment, ArangoDeploymentReplication, ArangoBackup
|
||||
|
|
|
@ -8,4 +8,5 @@
|
|||
- [Scaling](./scaling.md)
|
||||
- [Status](./status.md)
|
||||
- [Upgrading](./upgrading.md)
|
||||
- [Rotating Pods](./rotating.md)
|
||||
- [Maintenance](./maintenance.md)
|
13
docs/design/rotating.md
Normal file
13
docs/design/rotating.md
Normal file
|
@ -0,0 +1,13 @@
|
|||
# Rotation
|
||||
|
||||
## ArangoDeployment
|
||||
|
||||
Rotation of ArangoDeployment Pods can be triggered by Pod deletion or by annotation (safe way).
|
||||
|
||||
Using annotation Pods gonna be rotated one-by-one which will keep cluster alive.
|
||||
|
||||
Key: `deployment.arangodb.com/rotation`
|
||||
Value: `true`
|
||||
|
||||
To rotate ArangoDeployment Pod kubectl command can be used:
|
||||
`kubectl annotate pod arango-pod deployment.arangodb.com/rotation=true`
|
29
pkg/apis/deployment/annotations.go
Normal file
29
pkg/apis/deployment/annotations.go
Normal file
|
@ -0,0 +1,29 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2020 ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
// Author Adam Janikowski
|
||||
//
|
||||
|
||||
package deployment
|
||||
|
||||
const (
|
||||
ArangoDeploymentAnnotationPrefix = "deployment.arangodb.com"
|
||||
ArangoDeploymentPodMaintenanceAnnotation = ArangoDeploymentAnnotationPrefix + "/maintenance"
|
||||
ArangoDeploymentPodRotateAnnotation = ArangoDeploymentAnnotationPrefix + "/rotate"
|
||||
)
|
|
@ -26,6 +26,8 @@ import (
|
|||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/arangodb/kube-arangodb/pkg/apis/deployment"
|
||||
|
||||
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
|
||||
"github.com/arangodb/kube-arangodb/pkg/metrics"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util"
|
||||
|
@ -37,10 +39,6 @@ var (
|
|||
inspectDeploymentDurationGauges = metrics.MustRegisterGaugeVec(metricsComponent, "inspect_deployment_duration", "Amount of time taken by a single inspection of a deployment (in sec)", metrics.DeploymentName)
|
||||
)
|
||||
|
||||
const (
|
||||
arangoDeploymentMaintenanceAnnotation = "deployment.arangodb.com/maintenance"
|
||||
)
|
||||
|
||||
// inspectDeployment inspects the entire deployment, creates
|
||||
// a plan to update if needed and inspects underlying resources.
|
||||
// This function should be called when:
|
||||
|
@ -74,7 +72,7 @@ func (d *Deployment) inspectDeployment(lastInterval util.Interval) util.Interval
|
|||
} else {
|
||||
// Check if maintenance annotation is set
|
||||
if updated != nil && updated.Annotations != nil {
|
||||
if v, ok := updated.Annotations[arangoDeploymentMaintenanceAnnotation]; ok && v == "true" {
|
||||
if v, ok := updated.Annotations[deployment.ArangoDeploymentPodMaintenanceAnnotation]; ok && v == "true" {
|
||||
// Disable checks if we will enter maintenance mode
|
||||
log.Info().Str("deployment", deploymentName).Msg("Deployment in maintenance mode")
|
||||
return nextInterval
|
||||
|
|
|
@ -26,6 +26,9 @@ import (
|
|||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/arangodb/kube-arangodb/pkg/apis/deployment"
|
||||
"github.com/arangodb/kube-arangodb/pkg/deployment/pod"
|
||||
|
||||
"github.com/arangodb/kube-arangodb/pkg/deployment/pod"
|
||||
|
||||
"github.com/arangodb/go-driver"
|
||||
|
@ -87,6 +90,17 @@ func createRotateOrUpgradePlan(log zerolog.Logger, apiObject k8sutil.APIObject,
|
|||
newPlan = createRotateMemberPlan(log, m, group, reason)
|
||||
}
|
||||
}
|
||||
|
||||
if !newPlan.IsEmpty() {
|
||||
// Only rotate/upgrade 1 pod at a time
|
||||
continue
|
||||
}
|
||||
|
||||
if pod.Annotations != nil {
|
||||
if _, ok := pod.Annotations[deployment.ArangoDeploymentPodRotateAnnotation]; ok {
|
||||
newPlan = createRotateMemberPlan(log, m, group, "Rotation flag present")
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
|
|
@ -22,11 +22,15 @@
|
|||
|
||||
package k8sutil
|
||||
|
||||
import "regexp"
|
||||
import (
|
||||
"regexp"
|
||||
|
||||
"github.com/arangodb/kube-arangodb/pkg/apis/deployment"
|
||||
)
|
||||
|
||||
const (
|
||||
kubernetesAnnotationMatch = ".*kubernetes\\.io/.*"
|
||||
arangoAnnotationMatch = ".*arangodb\\.com/"
|
||||
arangoAnnotationMatch = ".*arangodb\\.com/.*"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -50,6 +54,29 @@ func init() {
|
|||
arangoAnnotationRegex = r
|
||||
}
|
||||
|
||||
func isFilteredBlockedAnnotation(key string) bool {
|
||||
switch key {
|
||||
case deployment.ArangoDeploymentPodRotateAnnotation:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func filterBlockedAnnotations(m map[string]string) map[string]string {
|
||||
n := map[string]string{}
|
||||
|
||||
for key, value := range m {
|
||||
if isFilteredBlockedAnnotation(key) {
|
||||
continue
|
||||
}
|
||||
|
||||
n[key] = value
|
||||
}
|
||||
|
||||
return n
|
||||
}
|
||||
|
||||
// MergeAnnotations into one annotations map
|
||||
func MergeAnnotations(annotations ...map[string]string) map[string]string {
|
||||
ret := map[string]string{}
|
||||
|
@ -114,7 +141,12 @@ func filterActualAnnotations(actual, expected map[string]string) map[string]stri
|
|||
|
||||
// CompareAnnotations will compare annotations, but will ignore secured annotations which are present in
|
||||
// actual but not specified in expected map
|
||||
// It will also filter out blocked annotations
|
||||
func CompareAnnotations(actual, expected map[string]string) bool {
|
||||
return compareAnnotations(filterBlockedAnnotations(actual), filterBlockedAnnotations(expected))
|
||||
}
|
||||
|
||||
func compareAnnotations(actual, expected map[string]string) bool {
|
||||
actualFiltered := filterActualAnnotations(actual, expected)
|
||||
|
||||
if actualFiltered == nil && expected == nil {
|
||||
|
|
Loading…
Reference in a new issue