Skip to content

[Feature] Member Replace Operation #1817

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Feb 18, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -16,6 +16,7 @@
- (Feature) UpgradeByReplace Flow
- (Feature) (Platform) ArangoRoute Timeout option
- (Feature) Delay Action
- (Feature) MigrateMember Action

## [1.2.44](https://github.com/arangodb/kube-arangodb/tree/1.2.44) (2025-02-03)
- (Maintenance) Kubernetes 1.31.1 libraries
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -173,6 +173,7 @@ Flags:
--deployment.feature.local-volume-replacement-check Replace volume for local-storage if volume is unschedulable (ex. node is gone) - Required ArangoDB >= 3.8.0
--deployment.feature.random-pod-names Enables generating random pod names - Required ArangoDB >= 3.8.0
--deployment.feature.rebalancer-v2 Rebalancer V2 feature - Required ArangoDB >= 3.10.0
--deployment.feature.replace-migration During member replacement shards are migrated directly to the new server - Required ArangoDB >= 3.8.0 (default true)
--deployment.feature.restart-policy-always Allow to restart containers with always restart policy - Required ArangoDB >= 3.8.0
--deployment.feature.secured-containers Create server's containers with non root privileges. It enables 'ephemeral-volumes' feature implicitly - Required ArangoDB >= 3.8.0
--deployment.feature.sensitive-information-protection Hide sensitive information from metrics and logs - Required ArangoDB >= 3.8.0
1 change: 1 addition & 0 deletions docs/cli/arangodb_operator.md
Original file line number Diff line number Diff line change
@@ -57,6 +57,7 @@ Flags:
--deployment.feature.local-volume-replacement-check Replace volume for local-storage if volume is unschedulable (ex. node is gone) - Required ArangoDB >= 3.8.0
--deployment.feature.random-pod-names Enables generating random pod names - Required ArangoDB >= 3.8.0
--deployment.feature.rebalancer-v2 Rebalancer V2 feature - Required ArangoDB >= 3.10.0
--deployment.feature.replace-migration During member replacement shards are migrated directly to the new server - Required ArangoDB >= 3.8.0 (default true)
--deployment.feature.restart-policy-always Allow to restart containers with always restart policy - Required ArangoDB >= 3.8.0
--deployment.feature.secured-containers Create server's containers with non root privileges. It enables 'ephemeral-volumes' feature implicitly - Required ArangoDB >= 3.8.0
--deployment.feature.sensitive-information-protection Hide sensitive information from metrics and logs - Required ArangoDB >= 3.8.0
2 changes: 2 additions & 0 deletions docs/generated/actions.md
Original file line number Diff line number Diff line change
@@ -51,6 +51,7 @@ nav_order: 11
| MemberPhaseUpdate | no | 10m0s | no | Community & Enterprise | Change member phase |
| ~~MemberRIDUpdate~~ | no | 10m0s | no | Community & Enterprise | Update Run ID of member |
| MemberStatusSync | no | 10m0s | no | Community & Enterprise | Sync ArangoMember Status with ArangoDeployment Status, to keep Member information up to date |
| MigrateMember | no | 48h0m0s | yes | Community & Enterprise | Run the data movement actions on the member (migration) |
| PVCResize | no | 30m0s | no | Community & Enterprise | Start the resize procedure. Updates PVC Requests field |
| PVCResized | no | 15m0s | no | Community & Enterprise | Waits for PVC resize to be completed |
| PlaceHolder | no | 10m0s | no | Community & Enterprise | Empty placeholder action |
@@ -148,6 +149,7 @@ spec:
MemberPhaseUpdate: 10m0s
MemberRIDUpdate: 10m0s
MemberStatusSync: 10m0s
MigrateMember: 48h0m0s
PVCResize: 30m0s
PVCResized: 15m0s
PlaceHolder: 10m0s
4 changes: 4 additions & 0 deletions internal/actions.yaml
Original file line number Diff line number Diff line change
@@ -27,6 +27,10 @@ actions:
CleanOutMember:
description: Run the CleanOut job on member
timeout: 48h
MigrateMember:
description: Run the data movement actions on the member (migration)
timeout: 48h
optional: true
ShutdownMember:
description: Sends Shutdown requests and waits for container to be stopped
timeout: 30m
12 changes: 12 additions & 0 deletions pkg/apis/deployment/v1/actions.generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions pkg/apis/deployment/v2alpha1/actions.generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions pkg/deployment/agency/definitions.go
Original file line number Diff line number Diff line change
@@ -47,6 +47,7 @@ const (

SupervisionKey = "Supervision"
SupervisionMaintenanceKey = "Maintenance"
SupervisionHealthKey = "Health"

TargetJobToDoKey = "ToDo"
TargetJobPendingKey = "Pending"
@@ -74,6 +75,7 @@ func GetAgencyReadRequest(elements ...[]string) ReadRequest {
func GetAgencyReadRequestFields() ReadRequest {
return GetAgencyReadRequest([]string{
GetAgencyKey(ArangoKey, SupervisionKey, SupervisionMaintenanceKey),
GetAgencyKey(ArangoKey, SupervisionKey, SupervisionHealthKey),
GetAgencyKey(ArangoKey, PlanKey, PlanCollectionsKey),
GetAgencyKey(ArangoKey, PlanKey, PlanDatabasesKey),
GetAgencyKey(ArangoKey, PlanKey, PlanDBServersKey),
4 changes: 0 additions & 4 deletions pkg/deployment/agency/state/state.go
Original file line number Diff line number Diff line change
@@ -61,10 +61,6 @@ type Plan struct {
Coordinators ServerMap[string] `json:"Coordinators,omitempty"`
}

type Supervision struct {
Maintenance Timestamp `json:"Maintenance,omitempty"`
}

type ShardCountDetails struct {
Leader, Follower int
}
48 changes: 48 additions & 0 deletions pkg/deployment/agency/state/supervision.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
//
// DISCLAIMER
//
// Copyright 2025 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
//

package state

type Supervision struct {
Maintenance Timestamp `json:"Maintenance,omitempty"`

Health ServerMap[SupervisionHealthServer] `json:"Health,omitempty"`
}

type SupervisionHealthServerStatus string

const (
SupervisionHealthServerStatusGood SupervisionHealthServerStatus = "GOOD"
)

type SupervisionHealthServerSyncStatus string

const (
SupervisionHealthServerSyncStatusServing SupervisionHealthServerSyncStatus = "SERVING"
)

type SupervisionHealthServer struct {
Status SupervisionHealthServerStatus `json:"Status,omitempty"`
SyncStatus SupervisionHealthServerSyncStatus `json:"SyncStatus,omitempty"`
}

func (s SupervisionHealthServer) IsHealthy() bool {
return s.Status == SupervisionHealthServerStatusGood && s.SyncStatus == SupervisionHealthServerSyncStatusServing
}
83 changes: 83 additions & 0 deletions pkg/deployment/client/rebalance.execute.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
//
// DISCLAIMER
//
// Copyright 2025 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
//

package client

import (
"context"
"net/http"

"github.com/arangodb/kube-arangodb/pkg/util"
)

type RebalanceExecuteRequest struct {
Version int `json:"version"`

Moves RebalanceExecuteRequestMoves `json:"moves,omitempty"`
}

type RebalanceExecuteRequestMoves []RebalanceExecuteRequestMove

type RebalanceExecuteRequestMove struct {
Database string `json:"database"`
Collection string `json:"collection"`
Shard string `json:"shard"`

From string `json:"from"`
To string `json:"to"`

IsLeader bool `json:"isLeader"`
}

func (c *client) RebalanceExecuteMoves(ctx context.Context, moves ...RebalanceExecuteRequestMove) error {
return c.RebalanceExecute(ctx, &RebalanceExecuteRequest{
Version: 1,
Moves: moves,
})
}

func (c *client) RebalanceExecute(ctx context.Context, request *RebalanceExecuteRequest) error {
req, err := c.c.NewRequest(http.MethodPost, "/_admin/cluster/rebalance/execute")
if err != nil {
return err
}

request = util.InitType(request)

// Always set to 1
request.Version = 1

if r, err := req.SetBody(request); err != nil {
return err
} else {
req = r
}

resp, err := c.c.Do(ctx, req)
if err != nil {
return err
}

if err := resp.CheckStatus(http.StatusAccepted); err != nil {
return err
}

return nil
}
59 changes: 59 additions & 0 deletions pkg/deployment/client/rebalance.get.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
//
// DISCLAIMER
//
// Copyright 2025 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
//

package client

import (
"context"
"net/http"
)

type RebalanceGetResponse struct {
Result RebalanceGetResponseResult `json:"result,omitempty"`
}

type RebalanceGetResponseResult struct {
PendingMoveShards int `json:"pendingMoveShards"`
TodoMoveShards int `json:"todoMoveShards"`
}

func (c *client) RebalanceGet(ctx context.Context) (RebalanceGetResponse, error) {
req, err := c.c.NewRequest(http.MethodGet, "/_admin/cluster/rebalance")
if err != nil {
return RebalanceGetResponse{}, err
}

resp, err := c.c.Do(ctx, req)
if err != nil {
return RebalanceGetResponse{}, err
}

if err := resp.CheckStatus(http.StatusOK); err != nil {
return RebalanceGetResponse{}, err
}

var d RebalanceGetResponse

if err := resp.ParseBody("", &d); err != nil {
return RebalanceGetResponse{}, err
}

return d, nil
}
Loading