1
0
Fork 0
mirror of https://github.com/arangodb/kube-arangodb.git synced 2024-12-14 11:57:37 +00:00

[Feature] [Scheduler] Shutdown Integration (#1777)

This commit is contained in:
Adam Janikowski 2024-12-06 12:16:20 +01:00 committed by GitHub
parent 9f1bd2bc7e
commit 6f713a85e9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 122 additions and 18 deletions

View file

@ -30,6 +30,7 @@
- (Improvement) Drop slash requirement from ArangoRoute - (Improvement) Drop slash requirement from ArangoRoute
- (Feature) (Networking) Pass through Server Header - (Feature) (Networking) Pass through Server Header
- (Feature) (Platform) Shutdown migration to CE - (Feature) (Platform) Shutdown migration to CE
- (Feature) (Scheduler) Shutdown Integration
## [1.2.43](https://github.com/arangodb/kube-arangodb/tree/1.2.43) (2024-10-14) ## [1.2.43](https://github.com/arangodb/kube-arangodb/tree/1.2.43) (2024-10-14)
- (Feature) ArangoRoute CRD - (Feature) ArangoRoute CRD

View file

@ -1,5 +1,5 @@
ARG IMAGE=ubuntu:24.04 ARG IMAGE=ubuntu:24.04
ARG ENVOY_IMAGE=envoyproxy/envoy:v1.31.0 ARG ENVOY_IMAGE=envoyproxy/envoy:v1.32.1
# Build Steps # Build Steps

View file

@ -87,6 +87,18 @@ metadata:
integration.profiles.arangodb.com/storage: v2 integration.profiles.arangodb.com/storage: v2
``` ```
#### [Shutdown V1](/docs/integration/shutdown.v1.md)
Shutdown Integration Sidecar
To enable:
```yaml
metadata:
labels:
integration.profiles.arangodb.com/shutdown: v1
```
### Envs ### Envs
#### INTEGRATION_API_ADDRESS #### INTEGRATION_API_ADDRESS

View file

@ -0,0 +1,32 @@
---
layout: page
title: Authentication V1
parent: ArangoDBPlatform
---
# Shutdown V1
Definitions:
- [Service](../../integrations/shutdown/v1/definition/definition.proto)
Operator will send shutdown request once all containers marked with annotation are stopped.
Example:
```yaml
metadata:
annotations:
core.shutdown.arangodb.com/app: "true"
core.shutdown.arangodb.com/app2: "true"
container.shutdown.arangodb.com/app3: port1
spec:
containers:
- name: app
- name: app2
- name: app3
ports:
name: port1
```
Pod will receive shutdown request on port `port1` if containers `app` and `app2` will be in non running state.

View file

@ -66,7 +66,7 @@ func (d DeniedResponse) GetCheckResponse() (*pbEnvoyAuthV3.CheckResponse, error)
resp.Body = string(z) resp.Body = string(z)
resp.Headers = append(resp.Headers, &corev3.HeaderValueOption{ resp.Headers = append(resp.Headers, &corev3.HeaderValueOption{
Header: &corev3.HeaderValue{ Header: &corev3.HeaderValue{
Key: "content/type", Key: "content-type",
Value: "application/json", Value: "application/json",
}, },
AppendAction: corev3.HeaderValueOption_OVERWRITE_IF_EXISTS_OR_ADD, AppendAction: corev3.HeaderValueOption_OVERWRITE_IF_EXISTS_OR_ADD,

View file

@ -153,6 +153,7 @@ func (r *Resources) EnsureArangoProfiles(ctx context.Context, cachedStatus inspe
Spec: spec, Spec: spec,
DeploymentName: apiObject.GetName(), DeploymentName: apiObject.GetName(),
})), })),
gen(constants.ProfilesIntegrationShutdown, constants.ProfilesIntegrationV1, always(sidecar.IntegrationShutdownV1{})),
gen(constants.ProfilesIntegrationEnvoy, constants.ProfilesIntegrationV3, always(sidecar.IntegrationEnvoyV3{Spec: spec})), gen(constants.ProfilesIntegrationEnvoy, constants.ProfilesIntegrationV3, always(sidecar.IntegrationEnvoyV3{Spec: spec})),
gen(constants.ProfilesIntegrationStorage, constants.ProfilesIntegrationV2, func() (sidecar.Integration, bool) { gen(constants.ProfilesIntegrationStorage, constants.ProfilesIntegrationV2, func() (sidecar.Integration, bool) {
if v, err := cachedStatus.ArangoPlatformStorage().V1Alpha1(); err == nil { if v, err := cachedStatus.ArangoPlatformStorage().V1Alpha1(); err == nil {

View file

@ -29,14 +29,6 @@ const (
ListenPortHealthName = "health" ListenPortHealthName = "health"
) )
type Integration interface {
Name() []string
Envs() ([]core.EnvVar, error)
GlobalEnvs() ([]core.EnvVar, error)
Volumes() ([]core.Volume, []core.VolumeMount, error)
Validate() error
}
func NewShutdownAnnotations(coreContainers []string) *schedulerApi.ProfileTemplate { func NewShutdownAnnotations(coreContainers []string) *schedulerApi.ProfileTemplate {
pt := schedulerApi.ProfileTemplate{ pt := schedulerApi.ProfileTemplate{
Pod: &schedulerPodApi.Pod{ Pod: &schedulerPodApi.Pod{
@ -57,6 +49,7 @@ func NewIntegrationEnablement(integrations ...Integration) (*schedulerApi.Profil
var envs, gEnvs []core.EnvVar var envs, gEnvs []core.EnvVar
var volumes []core.Volume var volumes []core.Volume
var volumeMounts []core.VolumeMount var volumeMounts []core.VolumeMount
var annotations = map[string]string{}
for _, integration := range integrations { for _, integration := range integrations {
name := strings.Join(integration.Name(), "/") name := strings.Join(integration.Name(), "/")
@ -72,6 +65,14 @@ func NewIntegrationEnablement(integrations ...Integration) (*schedulerApi.Profil
volumeMounts = append(volumeMounts, lvolumeMounts...) volumeMounts = append(volumeMounts, lvolumeMounts...)
} }
if anns, err := getIntegrationAnnotations(integration); err != nil {
return nil, errors.Wrapf(err, "Failure in annotations %s", name)
} else {
for k, v := range anns {
annotations[k] = v
}
}
if lenvs, err := integration.Envs(); err != nil { if lenvs, err := integration.Envs(); err != nil {
return nil, errors.Wrapf(err, "Failure in envs %s", name) return nil, errors.Wrapf(err, "Failure in envs %s", name)
} else if len(lenvs) > 0 { } else if len(lenvs) > 0 {
@ -92,6 +93,9 @@ func NewIntegrationEnablement(integrations ...Integration) (*schedulerApi.Profil
return &schedulerApi.ProfileTemplate{ return &schedulerApi.ProfileTemplate{
Priority: util.NewType(127), Priority: util.NewType(127),
Pod: &schedulerPodApi.Pod{ Pod: &schedulerPodApi.Pod{
Metadata: &schedulerPodResourcesApi.Metadata{
Annotations: annotations,
},
Volumes: &schedulerPodResourcesApi.Volumes{ Volumes: &schedulerPodResourcesApi.Volumes{
Volumes: volumes, Volumes: volumes,
}, },
@ -205,9 +209,6 @@ func NewIntegration(image *schedulerContainerResourcesApi.Image, integration *sc
}, },
} }
pt.Pod.Metadata.Annotations[fmt.Sprintf("%s/%s", constants.AnnotationShutdownContainer, ContainerName)] = ListenPortHealthName
pt.Pod.Metadata.Annotations[constants.AnnotationShutdownManagedContainer] = "true"
pt.Container.All.Environments = &schedulerContainerResourcesApi.Environments{ pt.Container.All.Environments = &schedulerContainerResourcesApi.Environments{
Env: envs, Env: envs,
} }

View file

@ -21,13 +21,24 @@
package sidecar package sidecar
import ( import (
"fmt"
core "k8s.io/api/core/v1" core "k8s.io/api/core/v1"
"github.com/arangodb/kube-arangodb/pkg/util/constants"
) )
type IntegrationShutdownV1 struct { type IntegrationShutdownV1 struct {
Core *Core Core *Core
} }
func (i IntegrationShutdownV1) Annotations() (map[string]string, error) {
return map[string]string{
fmt.Sprintf("%s/%s", constants.AnnotationShutdownContainer, ContainerName): ListenPortHealthName,
constants.AnnotationShutdownManagedContainer: "true",
}, nil
}
func (i IntegrationShutdownV1) Name() []string { func (i IntegrationShutdownV1) Name() []string {
return []string{"SHUTDOWN", "V1"} return []string{"SHUTDOWN", "V1"}
} }

View file

@ -0,0 +1,45 @@
//
// DISCLAIMER
//
// Copyright 2024 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 sidecar
import core "k8s.io/api/core/v1"
type Integration interface {
Name() []string
Envs() ([]core.EnvVar, error)
GlobalEnvs() ([]core.EnvVar, error)
Volumes() ([]core.Volume, []core.VolumeMount, error)
Validate() error
}
type IntegrationAnnotations interface {
Integration
Annotations() (map[string]string, error)
}
func getIntegrationAnnotations(int Integration) (map[string]string, error) {
if v, ok := int.(IntegrationAnnotations); ok {
return v.Annotations()
}
return nil, nil
}

View file

@ -28,11 +28,12 @@ const ProfilesDeployment = ProfileGroup + "/deployment"
const ProfilesIntegrationPrefix = "integration." + ProfileGroup const ProfilesIntegrationPrefix = "integration." + ProfileGroup
const ( const (
ProfilesIntegrationAuthn = "authn" ProfilesIntegrationAuthn = "authn"
ProfilesIntegrationAuthz = "authz" ProfilesIntegrationAuthz = "authz"
ProfilesIntegrationSched = "sched" ProfilesIntegrationSched = "sched"
ProfilesIntegrationEnvoy = "envoy" ProfilesIntegrationEnvoy = "envoy"
ProfilesIntegrationStorage = "storage" ProfilesIntegrationStorage = "storage"
ProfilesIntegrationShutdown = "shutdown"
) )
const ( const (