Skip to content

Commit

Permalink
feat: prepare production readiness (#10)
Browse files Browse the repository at this point in the history
* feat: add a confirmation to not forget to disable ArgoCD autosync

* feat: add a guard to prevent to start the migration when the targeted
label is the only one.

* docs: start the analyze of resource
  • Loading branch information
Tchoupinax authored Apr 16, 2024
1 parent 384adf7 commit f31362f
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 8 deletions.
20 changes: 12 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,12 @@ We have a deployment called `api` with labels `app=api` and `kubernetes.io/name=
6. **Wait all pods are ready**: we repeat the operation about the new deployment.
7. **Remove temporary deployment**: now that the deployment is ready, we can cut the temporary one and leaves in place the new deployment with modified label.
8. **[Optional] Add the label to service selector**: some labels are recommenced by Kubernetes to be present as default label and thoses labels might be added to the service selector. That means we are making the matching set stronger.
- See [documentation](https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/)
- For the moment, only `kubernetes.io/name` is considered to be added to the service
- See [documentation](https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/)
- For the moment, only `kubernetes.io/name` is considered to be added to the service

Additional documentations:

- [Service is not the only resource that target pods](docs/resources-targeting-pods.md )

## Zero downtime testing

Expand Down Expand Up @@ -102,11 +106,11 @@ echo 'GET YOUR_URL' | \
## Roadmap

1.0.0
- [ ] Sucessful migration in production with relatively high volume
- [ ] Handle the fact the edited label is the only one used for the service
- [ ] Documentation about potentials issues from scale (DB)
- [ ] Better handling of labels added to the service and well understand of K8S's good pratices

0.1.0
- [x] Successful test with zero downtime
- [x] Basic documentation
- [x] Successful test with zero downtime
- [ ] All resources that match pod are managed
- [ ] Better handling of labels added to the service and well understand of K8S's good pratices
- [ ] Documentation about potentials issues from scale (DB)
- [ ] Handle the fact the edited label is the only one used for the service
- [ ] Successful migration in production with relatively high volume
19 changes: 19 additions & 0 deletions checks.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package main

import (
"context"

v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
)

func isTheEditedLabelTheOnlyOne(
namespace string,
clientset *kubernetes.Clientset,
deploymentName string,
changingLabelKey string,
) bool {
deployment, _ := clientset.AppsV1().Deployments(namespace).Get(context.TODO(), deploymentName, v1.GetOptions{})
labels := deployment.Spec.Template.ObjectMeta.Labels
return len(labels) == 1 && labels[changingLabelKey] != ""
}
33 changes: 33 additions & 0 deletions docs/resources-targeting-pods.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Service is not the only resource that target pods

We did the base migration considering pods are matched by service. But for a complexe app, there is a lot of resources that can match pods.

## Identify resources

- Kubernetes
- PodDisruptionBudget

- Keda
- ❌ ScaledObject: — `.spec.scaleTargetRef.name` (equal to the deployment name)
- ➡️ It is acceptable to not manage this as the migration will be fast.
- Istio
- AuthorizationPolicy
- RequestAuthentication
- DestinationRule
- Virtual service (host match the DNS name, means it match the deployment name [docs](https://istio.io/latest/docs/reference/config/networking/virtual-service/#VirtualService))
- Monitoring
- PrometheusRule (rules could match pod or deployment in the query)
- PodMonitor — `.spec.selector.matchLabels`

## Tips

```bash
# Display existing resources in the cluster
kubectl api-resources --verbs=list --namespaced -o name
```

export KUBERNETES_RESOURCE=ScaledObject
export NAME=
export NAMESPACE=

kubectl get $KUBERNETES_RESOURCE $NAME -n $NAMESPACE -o yaml | yq '.spec.selector.matchLabels'
17 changes: 17 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package main

import (
"flag"
"fmt"
"os"

"k8s.io/client-go/kubernetes"
Expand Down Expand Up @@ -48,6 +49,17 @@ func main() {
os.Exit(1)
}

onlyOneLabel := isTheEditedLabelTheOnlyOne(
namespace,
clientset,
deploymentName,
labelToChangeKey,
)
if onlyOneLabel {
logError(fmt.Sprintf("The label \"%s\" can not be edited because it's the only one in the matching set.", labelToChangeKey))
os.Exit(1)
}

displaySummary(
namespace,
deploymentName,
Expand All @@ -61,6 +73,11 @@ func main() {
logInfo("Operation aborted by the user")
os.Exit(0)
}
c2 := askForConfirmation("I confirm that I have no gitops tool overriding my config (e.g. ArgoCD auto-sync)")
if !c2 {
logInfo("Operation aborted by the user")
os.Exit(0)
}

MigrationWorkflow(
namespace,
Expand Down

0 comments on commit f31362f

Please sign in to comment.