1
0
Fork 0
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:
Adam Janikowski 2020-03-11 08:57:03 +01:00 committed by GitHub
parent 7c649303d0
commit 221d9d1b7f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 95 additions and 7 deletions

View file

@ -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

View file

@ -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
View 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`

View 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"
)

View file

@ -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

View file

@ -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
})

View file

@ -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 {