ArgoCD Vulnerable to Use of Risky or Missing Cryptographic Algorithms in Redis Cache
Description
Argo CD is a declarative, GitOps continuous delivery tool for Kubernetes. It has been discovered that an unprivileged pod in a different namespace on the same cluster could connect to the Redis server on port 6379. Despite having installed the latest version of the VPC CNI plugin on the EKS cluster, it requires manual enablement through configuration to enforce network policies. This raises concerns that many clients might unknowingly have open access to their Redis servers. This vulnerability could lead to Privilege Escalation to the level of cluster controller, or to information leakage, affecting anyone who does not have strict access controls on their Redis instance. This issue has been patched in version(s) 2.8.19, 2.9.15 and 2.10.10.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
github.com/argoproj/argo-cd/v2Go | < 2.8.19 | 2.8.19 |
github.com/argoproj/argo-cd/v2Go | >= 2.9.0-rc1, < 2.9.15 | 2.9.15 |
github.com/argoproj/argo-cd/v2Go | >= 2.10.0-rc1, < 2.10.10 | 2.10.10 |
github.com/argoproj/argo-cd/v2Go | >= 2.11.0-rc1, < 2.11.1 | 2.11.1 |
github.com/argoproj/argo-cdGo | <= 1.8.7 | — |
Affected products
1Patches
84e2fe302c335Merge pull request from GHSA-9766-5277-j5hr
9552034a8007Merge pull request from GHSA-9766-5277-j5hr
2de0ceade243Merge pull request from GHSA-9766-5277-j5hr
6ef7b62a0f67Merge pull request from GHSA-9766-5277-j5hr
bdd889d43969Merge pull request from GHSA-9766-5277-j5hr
27 files changed · +883 −116
cmd/argocd/commands/admin/admin.go+1 −0 modified@@ -141,6 +141,7 @@ $ argocd admin initial-password reset command.AddCommand(NewDashboardCommand(clientOpts)) command.AddCommand(NewNotificationsCommand()) command.AddCommand(NewInitialPasswordCommand()) + command.AddCommand(NewRedisInitialPasswordCommand()) command.Flags().StringVar(&cmdutil.LogFormat, "logformat", "text", "Set the logging format. One of: text|json") command.Flags().StringVar(&cmdutil.LogLevel, "loglevel", "info", "Set the logging level. One of: debug|info|warn|error")
cmd/argocd/commands/admin/redis_initial_password.go+98 −0 added@@ -0,0 +1,98 @@ +package admin + +import ( + "context" + "crypto/rand" + "fmt" + "math/big" + + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/cli" + apierr "k8s.io/apimachinery/pkg/api/errors" + + "github.com/argoproj/argo-cd/v2/util/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/tools/clientcmd" + + "github.com/spf13/cobra" + corev1 "k8s.io/api/core/v1" +) + +const defaulRedisInitialPasswordSecretName = "argocd-redis" +const defaultResisInitialPasswordKey = "auth" + +func generateRandomPassword() (string, error) { + const initialPasswordLength = 16 + const letters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-" + randBytes := make([]byte, initialPasswordLength) + for i := 0; i < initialPasswordLength; i++ { + num, err := rand.Int(rand.Reader, big.NewInt(int64(len(letters)))) + if err != nil { + return "", err + } + randBytes[i] = letters[num.Int64()] + } + initialPassword := string(randBytes) + return initialPassword, nil +} + +// NewRedisInitialPasswordCommand defines a new command to ensure Argo CD Redis password secret exists. +func NewRedisInitialPasswordCommand() *cobra.Command { + var ( + clientConfig clientcmd.ClientConfig + ) + var command = cobra.Command{ + Use: "redis-initial-password", + Short: "Ensure the Redis password exists, creating a new one if necessary.", + Run: func(c *cobra.Command, args []string) { + namespace, _, err := clientConfig.Namespace() + errors.CheckError(err) + + redisInitialPasswordSecretName := defaulRedisInitialPasswordSecretName + redisInitialPasswordKey := defaultResisInitialPasswordKey + fmt.Printf("Checking for initial Redis password in secret %s/%s at key %s. \n", namespace, redisInitialPasswordSecretName, redisInitialPasswordKey) + + config, err := clientConfig.ClientConfig() + errors.CheckError(err) + errors.CheckError(v1alpha1.SetK8SConfigDefaults(config)) + + kubeClientset := kubernetes.NewForConfigOrDie(config) + + randomPassword, err := generateRandomPassword() + errors.CheckError(err) + + data := map[string][]byte{ + redisInitialPasswordKey: []byte(randomPassword), + } + secret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: redisInitialPasswordSecretName, + Namespace: namespace, + }, + Data: data, + Type: corev1.SecretTypeOpaque, + } + _, err = kubeClientset.CoreV1().Secrets(namespace).Create(context.Background(), secret, metav1.CreateOptions{}) + if err != nil && !apierr.IsAlreadyExists(err) { + errors.CheckError(err) + } + + fmt.Println("Argo CD Redis secret state confirmed: secret name argocd-redis.") + secret, err = kubeClientset.CoreV1().Secrets(namespace).Get(context.Background(), redisInitialPasswordSecretName, v1.GetOptions{}) + errors.CheckError(err) + + if _, ok := secret.Data[redisInitialPasswordKey]; ok { + fmt.Println("Password secret is configured properly.") + } else { + err := fmt.Errorf("key %s doesn't exist in secret %s. \n", redisInitialPasswordKey, redisInitialPasswordSecretName) + errors.CheckError(err) + } + }, + } + + clientConfig = cli.AddKubectlFlagsToCmd(&command) + + return &command +}
docs/faq.md+42 −0 modified@@ -268,3 +268,45 @@ The most common instance of this error is with `env:` fields for `containers`. !!! note "Dynamic applications" It's possible that your application is being generated by a tool in which case the duplication might not be evident within the scope of a single file. If you have trouble debugging this problem, consider filing a ticket to the owner of the generator tool asking them to improve its validation and error reporting. + +## How to rotate Redis secret? +* Delete `argocd-redis` secret in the namespace where Argo CD is installed. +```bash +kubectl delete secret argocd-redis -n <argocd namesapce> +``` +* If you are running Redis in HA mode, restart Redis in HA. +```bash +kubectl rollout restart deployment argocd-redis-ha-haproxy +kubectl rollout restart statefulset argocd-redis-ha-server +``` +* If you are running Redis in non-HA mode, restart Redis. +```bash +kubectl rollout restart deployment argocd-redis +``` +* Restart other components. +```bash +kubectl rollout restart deployment argocd-server argocd-repo-server +kubectl rollout restart statefulset argocd-application-controller +``` + +## How to turn off Redis auth if users really want to? + +Argo CD default installation is now configured automatically enable Redis authentication. +If for some reason authenticated Redis does not work for you and you want to use non-authenticated Redis, here are the steps: + +* You need to have your own Redis installation. +* Configure Argo CD to use your own Redis instance. See this [doc](https://argo-cd.readthedocs.io/en/stable/operator-manual/argocd-cmd-params-cm-yaml/) for the Argo CD configuration. +* If you already installed Redis shipped with Argo CD, you also need to clean up the existing components: + * When HA Redis is used: + * kubectl delete deployment argocd-redis-ha-haproxy + * kubectl delete statefulset argocd-redis-ha-server + * When non-HA Redis is used: + * kubectl delete deployment argocd-redis +* Remove environment variable `REDIS_PASSWORD` from the following manifests + * Deployment: argocd-repo-server: + * Deployment: argocd-server + * StatefulSet: argocd-application-controller + +## How do I provide my own Redis credentials? +The Redis password is stored in Kubernetes secret `argocd-redis` with key `auth` in the namespace where Argo CD is installed. +You can config your secret provider to generate Kubernetes secret accordingly. \ No newline at end of file
docs/getting_started.md+3 −0 modified@@ -38,6 +38,9 @@ Do one of: Use `argocd login --core` to [configure](./user-guide/commands/argocd_login.md) CLI access and skip steps 3-5. +!!! note + This default installation for Redis is using password authentication. The Redis password is stored in Kubernetes secret `argocd-redis` with key `auth` in the namespace where Argo CD is installed. + ## 2. Download Argo CD CLI Download the latest Argo CD version from [https://github.com/argoproj/argo-cd/releases/latest](https://github.com/argoproj/argo-cd/releases/latest). More detailed installation instructions can be found via the [CLI installation documentation](cli_installation.md).
docs/user-guide/commands/argocd_admin.md+1 −0 modified@@ -139,6 +139,7 @@ $ argocd admin initial-password reset * [argocd admin initial-password](argocd_admin_initial-password.md) - Prints initial password to log in to Argo CD for the first time * [argocd admin notifications](argocd_admin_notifications.md) - Set of CLI commands that helps manage notifications settings * [argocd admin proj](argocd_admin_proj.md) - Manage projects configuration +* [argocd admin redis-initial-password](argocd_admin_redis-initial-password.md) - Ensure the Redis password exists, creating a new one if necessary. * [argocd admin repo](argocd_admin_repo.md) - Manage repositories configuration * [argocd admin settings](argocd_admin_settings.md) - Provides set of commands for settings validation and troubleshooting
docs/user-guide/commands/argocd_admin_redis-initial-password.md+67 −0 added@@ -0,0 +1,67 @@ +# `argocd admin redis-initial-password` Command Reference + +## argocd admin redis-initial-password + +Ensure the Redis password exists, creating a new one if necessary. + +``` +argocd admin redis-initial-password [flags] +``` + +### Options + +``` + --as string Username to impersonate for the operation + --as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --as-uid string UID to impersonate for the operation + --certificate-authority string Path to a cert file for the certificate authority + --client-certificate string Path to a client certificate file for TLS + --client-key string Path to a client key file for TLS + --cluster string The name of the kubeconfig cluster to use + --context string The name of the kubeconfig context to use + --disable-compression If true, opt-out of response compression for all requests to the server + -h, --help help for redis-initial-password + --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kubeconfig string Path to a kube config. Only required if out-of-cluster + -n, --namespace string If present, the namespace scope for this CLI request + --password string Password for basic authentication to the API server + --proxy-url string If provided, this URL will be used to connect via proxy + --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") + --server string The address and port of the Kubernetes API server + --tls-server-name string If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used. + --token string Bearer token for authentication to the API server + --user string The name of the kubeconfig user to use + --username string Username for basic authentication to the API server +``` + +### Options inherited from parent commands + +``` + --auth-token string Authentication token + --client-crt string Client certificate file + --client-crt-key string Client certificate key file + --config string Path to Argo CD config (default "/home/user/.config/argocd/config") + --controller-name string Name of the Argo CD Application controller; set this or the ARGOCD_APPLICATION_CONTROLLER_NAME environment variable when the controller's name label differs from the default, for example when installing via the Helm chart (default "argocd-application-controller") + --core If set to true then CLI talks directly to Kubernetes instead of talking to Argo CD API server + --grpc-web Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. + --grpc-web-root-path string Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. Set web root. + -H, --header strings Sets additional header to all requests made by Argo CD CLI. (Can be repeated multiple times to add multiple headers, also supports comma separated headers) + --http-retry-max int Maximum number of retries to establish http connection to Argo CD server + --insecure Skip server certificate and domain verification + --kube-context string Directs the command to the given kube-context + --logformat string Set the logging format. One of: text|json (default "text") + --loglevel string Set the logging level. One of: debug|info|warn|error (default "info") + --plaintext Disable TLS + --port-forward Connect to a random argocd-server port using port forwarding + --port-forward-namespace string Namespace name which should be used for port forwarding + --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") + --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") + --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") + --server-crt string Server certificate file + --server-name string Name of the Argo CD API server; set this or the ARGOCD_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-server") +``` + +### SEE ALSO + +* [argocd admin](argocd_admin.md) - Contains a set of commands useful for Argo CD administrators and requires direct Kubernetes access +
manifests/base/application-controller/argocd-application-controller-statefulset.yaml+5 −0 modified@@ -21,6 +21,11 @@ spec: - args: - /usr/local/bin/argocd-application-controller env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_CONTROLLER_REPLICAS value: "1" - name: ARGOCD_RECONCILIATION_TIMEOUT
manifests/base/application-controller-deployment/argocd-application-controller-deployment.yaml+5 −0 modified@@ -20,6 +20,11 @@ spec: - args: - /usr/local/bin/argocd-application-controller env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_RECONCILIATION_TIMEOUT valueFrom: configMapKeyRef:
manifests/base/redis/argocd-redis-deployment.yaml+24 −0 modified@@ -15,6 +15,23 @@ spec: labels: app.kubernetes.io/name: argocd-redis spec: + initContainers: + - command: + - argocd + - admin + - redis-initial-password + image: quay.io/argoproj/argocd:latest + imagePullPolicy: IfNotPresent + name: secret-init + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault securityContext: runAsNonRoot: true runAsUser: 999 @@ -30,6 +47,13 @@ spec: - "" - "--appendonly" - "no" + - --requirepass $(REDIS_PASSWORD) + env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis ports: - containerPort: 6379 securityContext:
manifests/base/redis/argocd-redis-rolebinding.yaml+15 −0 added@@ -0,0 +1,15 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: argocd-redis +subjects: + - kind: ServiceAccount + name: argocd-redis \ No newline at end of file
manifests/base/redis/argocd-redis-role.yaml+23 −0 added@@ -0,0 +1,23 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +rules: + - apiGroups: + - "" + resources: + - secrets + resourceNames: + - argocd-redis + verbs: + - get + - apiGroups: + - "" + resources: + - secrets + verbs: + - create \ No newline at end of file
manifests/base/redis/kustomization.yaml+2 −0 modified@@ -6,3 +6,5 @@ resources: - argocd-redis-sa.yaml - argocd-redis-service.yaml - argocd-redis-network-policy.yaml +- argocd-redis-role.yaml +- argocd-redis-rolebinding.yaml
manifests/base/repo-server/argocd-repo-server-deployment.yaml+5 −0 modified@@ -24,6 +24,11 @@ spec: args: - /usr/local/bin/argocd-repo-server env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_RECONCILIATION_TIMEOUT valueFrom: configMapKeyRef:
manifests/base/server/argocd-server-deployment.yaml+5 −0 modified@@ -23,6 +23,11 @@ spec: args: - /usr/local/bin/argocd-server env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_SERVER_INSECURE valueFrom: configMapKeyRef:
manifests/core-install.yaml+74 −0 modified@@ -20652,6 +20652,30 @@ rules: - watch --- apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +rules: +- apiGroups: + - "" + resourceNames: + - argocd-redis + resources: + - secrets + verbs: + - get +- apiGroups: + - "" + resources: + - secrets + verbs: + - create +--- +apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: labels: @@ -20704,6 +20728,22 @@ subjects: name: argocd-applicationset-controller --- apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: argocd-redis +subjects: +- kind: ServiceAccount + name: argocd-redis +--- +apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: labels: @@ -21115,6 +21155,13 @@ spec: - "" - --appendonly - "no" + - --requirepass $(REDIS_PASSWORD) + env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis image: redis:7.0.15-alpine imagePullPolicy: Always name: redis @@ -21126,6 +21173,23 @@ spec: drop: - ALL readOnlyRootFilesystem: true + initContainers: + - command: + - argocd + - admin + - redis-initial-password + image: quay.io/argoproj/argocd:latest + imagePullPolicy: IfNotPresent + name: secret-init + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault securityContext: runAsNonRoot: true runAsUser: 999 @@ -21170,6 +21234,11 @@ spec: - args: - /usr/local/bin/argocd-repo-server env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_RECONCILIATION_TIMEOUT valueFrom: configMapKeyRef: @@ -21481,6 +21550,11 @@ spec: - args: - /usr/local/bin/argocd-application-controller env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_CONTROLLER_REPLICAS value: "1" - name: ARGOCD_RECONCILIATION_TIMEOUT
manifests/ha/base/redis-ha/chart/requirements.lock+3 −3 modified@@ -1,6 +1,6 @@ dependencies: - name: redis-ha repository: https://dandydeveloper.github.io/charts - version: 4.22.3 -digest: sha256:ae773caf65b172bdd2216072c03ba76ef3c0383dbd1e2478934a67b9455f6a2e -generated: "2022-11-02T16:57:25.047025473-07:00" + version: 4.26.6 +digest: sha256:c363f48ea8339c4bdb7c8a2cca62aa487b69d0a52a6fe6267fbbbbc07e468abd +generated: "2024-04-10T11:02:32.957812-07:00"
manifests/ha/base/redis-ha/chart/requirements.yaml+1 −1 modified@@ -1,4 +1,4 @@ dependencies: - name: redis-ha - version: 4.22.3 + version: 4.26.6 repository: https://dandydeveloper.github.io/charts
manifests/ha/base/redis-ha/chart/upstream.yaml+78 −44 modified@@ -9,8 +9,10 @@ metadata: labels: heritage: Helm release: argocd - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 app: argocd-redis-ha +secrets: +- name: argocd-redis --- # Source: redis-ha/charts/redis-ha/templates/redis-haproxy-serviceaccount.yaml apiVersion: v1 @@ -21,7 +23,7 @@ metadata: labels: heritage: Helm release: argocd - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 app: argocd-redis-ha --- # Source: redis-ha/charts/redis-ha/templates/redis-ha-configmap.yaml @@ -33,7 +35,7 @@ metadata: labels: heritage: Helm release: argocd - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 app: argocd-redis-ha data: redis.conf: | @@ -50,6 +52,8 @@ data: rdbcompression yes repl-diskless-sync yes save "" + requirepass replace-default-auth + masterauth replace-default-auth sentinel.conf: | dir "/data" @@ -59,6 +63,7 @@ data: sentinel failover-timeout argocd 180000 maxclients 10000 sentinel parallel-syncs argocd 5 + sentinel auth-pass argocd replace-default-auth init.sh: | echo "$(date) Start..." @@ -82,7 +87,7 @@ data: sentinel_get_master() { set +e if [ "$SENTINEL_PORT" -eq 0 ]; then - redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ + redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ grep -E '((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?s*$))' else redis-cli -h "${SERVICE}" -p "${SENTINEL_PORT}" sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ @@ -191,9 +196,9 @@ data: redis_ping() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - redis-cli -h "${MASTER}" -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping else - redis-cli -h "${MASTER}" -p "${REDIS_PORT}" ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" ping fi set -e } @@ -226,7 +231,7 @@ data: if [ "$SENTINEL_PORT" -eq 0 ]; then echo " on sentinel (${SERVICE}:${SENTINEL_TLS_PORT}), sentinel grp (${MASTER_GROUP})" - if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then + if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then echo " $(date) Failover returned with 'NOGOODSLAVE'" echo "Setting defaults for this pod.." setup_defaults @@ -345,7 +350,7 @@ data: sentinel_get_master() { set +e if [ "$SENTINEL_PORT" -eq 0 ]; then - redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ + redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ grep -E '((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?s*$))' else redis-cli -h "${SERVICE}" -p "${SENTINEL_PORT}" sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ @@ -454,9 +459,9 @@ data: redis_ping() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - redis-cli -h "${MASTER}" -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping else - redis-cli -h "${MASTER}" -p "${REDIS_PORT}" ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" ping fi set -e } @@ -489,7 +494,7 @@ data: if [ "$SENTINEL_PORT" -eq 0 ]; then echo " on sentinel (${SERVICE}:${SENTINEL_TLS_PORT}), sentinel grp (${MASTER_GROUP})" - if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then + if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then echo " $(date) Failover returned with 'NOGOODSLAVE'" echo "Setting defaults for this pod.." setup_defaults @@ -554,19 +559,19 @@ data: redis_role() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - ROLE=$(redis-cli -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep role | sed 's/role://' | sed 's/\r//') + ROLE=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep role | sed 's/role://' | sed 's/\r//') else - ROLE=$(redis-cli -p "${REDIS_PORT}" info | grep role | sed 's/role://' | sed 's/\r//') + ROLE=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" info | grep role | sed 's/role://' | sed 's/\r//') fi set -e } identify_redis_master() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - REDIS_MASTER=$(redis-cli -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep master_host | sed 's/master_host://' | sed 's/\r//') + REDIS_MASTER=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep master_host | sed 's/master_host://' | sed 's/\r//') else - REDIS_MASTER=$(redis-cli -p "${REDIS_PORT}" info | grep master_host | sed 's/master_host://' | sed 's/\r//') + REDIS_MASTER=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" info | grep master_host | sed 's/master_host://' | sed 's/\r//') fi set -e } @@ -576,9 +581,9 @@ data: sh /readonly-config/init.sh if [ "$REDIS_PORT" -eq 0 ]; then - echo "shutdown" | redis-cli -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key + echo "shutdown" | redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key else - echo "shutdown" | redis-cli -p "${REDIS_PORT}" + echo "shutdown" | redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" fi set -e } @@ -591,6 +596,7 @@ data: identify_announce_ip done + trap "exit 0" TERM while true; do sleep 60 @@ -674,6 +680,8 @@ data: mode tcp option tcp-check tcp-check connect + tcp-check send "AUTH ${AUTH}"\r\n + tcp-check expect string +OK tcp-check send PING\r\n tcp-check expect string +PONG tcp-check send info\ replication\r\n @@ -730,6 +738,7 @@ data: get_redis_role() { is_master=$( redis-cli \ + -a "${AUTH}" --no-auth-warning \ -h localhost \ -p 6379 \ info | grep -c 'role:master' || true @@ -766,12 +775,13 @@ metadata: labels: heritage: Helm release: argocd - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 app: argocd-redis-ha data: redis_liveness.sh: | response=$( redis-cli \ + -a "${AUTH}" --no-auth-warning \ -h localhost \ -p 6379 \ ping @@ -784,6 +794,7 @@ data: redis_readiness.sh: | response=$( redis-cli \ + -a "${AUTH}" --no-auth-warning \ -h localhost \ -p 6379 \ ping @@ -816,7 +827,7 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 rules: - apiGroups: - "" @@ -835,7 +846,7 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 component: argocd-redis-ha-haproxy rules: - apiGroups: @@ -855,7 +866,7 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 subjects: - kind: ServiceAccount name: argocd-redis-ha @@ -874,7 +885,7 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 component: argocd-redis-ha-haproxy subjects: - kind: ServiceAccount @@ -894,9 +905,8 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 annotations: - service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" spec: publishNotReadyAddresses: true type: ClusterIP @@ -924,9 +934,8 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 annotations: - service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" spec: publishNotReadyAddresses: true type: ClusterIP @@ -954,9 +963,8 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 annotations: - service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" spec: publishNotReadyAddresses: true type: ClusterIP @@ -984,7 +992,7 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 annotations: spec: type: ClusterIP @@ -1012,7 +1020,7 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 component: argocd-redis-ha-haproxy annotations: spec: @@ -1040,7 +1048,7 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 spec: strategy: type: RollingUpdate @@ -1056,12 +1064,11 @@ spec: labels: app: redis-ha-haproxy release: argocd - revision: "1" annotations: prometheus.io/port: "9101" prometheus.io/scrape: "true" prometheus.io/path: "/metrics" - checksum/config: 492a6adabb741e0cee39be9aa5155c41a4456629f862d0006a2d892dbecfbcae + checksum/config: e34e8124c38bcfd2f16e75620bbde30158686692b13bc449eecc44c51b207d54 spec: # Needed when using unmodified rbac-setup.yml @@ -1081,11 +1088,10 @@ spec: matchLabels: app: redis-ha-haproxy release: argocd - revision: "1" topologyKey: kubernetes.io/hostname initContainers: - name: config-init - image: haproxy:2.6.14-alpine + image: public.ecr.aws/docker/library/haproxy:2.6.14-alpine imagePullPolicy: IfNotPresent resources: {} @@ -1109,7 +1115,7 @@ spec: mountPath: /data containers: - name: haproxy - image: haproxy:2.6.14-alpine + image: public.ecr.aws/docker/library/haproxy:2.6.14-alpine imagePullPolicy: IfNotPresent securityContext: allowPrivilegeEscalation: false @@ -1119,6 +1125,12 @@ spec: runAsNonRoot: true seccompProfile: type: RuntimeDefault + env: + - name: AUTH + valueFrom: + secretKeyRef: + name: argocd-redis + key: auth livenessProbe: httpGet: path: /healthz @@ -1167,7 +1179,7 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 annotations: {} spec: @@ -1183,7 +1195,7 @@ spec: template: metadata: annotations: - checksum/init-config: 69130412bda04eacad3530cb7bcf26cf121401e725e15d0959dd71a7380afe75 + checksum/init-config: 9d3c019a5ea1fd98ab5cde397d8eecd351da884f15e6ba346c607cb2446c2198 labels: release: argocd app: redis-ha @@ -1207,7 +1219,7 @@ spec: automountServiceAccountToken: false initContainers: - name: config-init - image: redis:7.0.15-alpine + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent resources: {} @@ -1231,6 +1243,11 @@ spec: value: 40000915ab58c3fa8fd888fb8b24711944e6cbb4 - name: SENTINEL_ID_2 value: 2bbec7894d954a8af3bb54d13eaec53cb024e2ca + - name: AUTH + valueFrom: + secretKeyRef: + name: argocd-redis + key: auth volumeMounts: - name: config mountPath: /readonly-config @@ -1241,12 +1258,12 @@ spec: containers: - name: redis - image: redis:7.0.15-alpine + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent command: - - redis-server + - redis-server args: - - /data/conf/redis.conf + - /data/conf/redis.conf securityContext: allowPrivilegeEscalation: false capabilities: @@ -1256,6 +1273,12 @@ spec: runAsUser: 1000 seccompProfile: type: RuntimeDefault + env: + - name: AUTH + valueFrom: + secretKeyRef: + name: argocd-redis + key: auth livenessProbe: initialDelaySeconds: 30 periodSeconds: 15 @@ -1298,7 +1321,7 @@ spec: - /bin/sh - /readonly-config/trigger-failover-if-master.sh - name: sentinel - image: redis:7.0.15-alpine + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent command: - redis-sentinel @@ -1313,6 +1336,12 @@ spec: runAsUser: 1000 seccompProfile: type: RuntimeDefault + env: + - name: AUTH + valueFrom: + secretKeyRef: + name: argocd-redis + key: auth livenessProbe: initialDelaySeconds: 30 periodSeconds: 15 @@ -1349,7 +1378,7 @@ spec: {} - name: split-brain-fix - image: redis:7.0.15-alpine + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent command: - sh @@ -1371,6 +1400,11 @@ spec: value: 40000915ab58c3fa8fd888fb8b24711944e6cbb4 - name: SENTINEL_ID_2 value: 2bbec7894d954a8af3bb54d13eaec53cb024e2ca + - name: AUTH + valueFrom: + secretKeyRef: + name: argocd-redis + key: auth resources: {} volumeMounts:
manifests/ha/base/redis-ha/chart/values.yaml+3 −0 modified@@ -1,4 +1,7 @@ redis-ha: + auth: true + authKey: auth + existingSecret: argocd-redis persistentVolume: enabled: false redis:
manifests/ha/base/redis-ha/kustomization.yaml+17 −5 modified@@ -20,7 +20,7 @@ patches: kind: ConfigMap name: argocd-redis-ha-configmap namespace: argocd - path: overlays/remove-namespace.yaml + path: overlays/remove-namespace.yaml - target: version: v1 group: "" @@ -34,28 +34,28 @@ patches: kind: ServiceAccount name: argocd-redis-ha-haproxy namespace: argocd - path: overlays/remove-namespace.yaml + path: overlays/remove-namespace.yaml - target: group: rbac.authorization.k8s.io version: v1 kind: Role name: argocd-redis-ha namespace: argocd - path: overlays/remove-namespace.yaml + path: overlays/remove-namespace.yaml - target: group: rbac.authorization.k8s.io version: v1 kind: Role name: argocd-redis-ha-haproxy namespace: argocd - path: overlays/remove-namespace.yaml + path: overlays/remove-namespace.yaml - target: group: rbac.authorization.k8s.io version: v1 kind: RoleBinding name: argocd-redis-ha namespace: argocd - path: overlays/remove-namespace.yaml + path: overlays/remove-namespace.yaml - target: group: rbac.authorization.k8s.io version: v1 @@ -294,3 +294,15 @@ patches: kind: StatefulSet name: argocd-redis-ha-server path: overlays/statefulset-containers-securityContext.yaml +- target: + group: rbac.authorization.k8s.io + version: v1 + kind: Role + name: argocd-redis-ha-haproxy + path: overlays/haproxy-role.yaml +- target: + group: apps + version: v1 + kind: Deployment + name: argocd-redis-ha-haproxy + path: overlays/deployment-initContainers.yaml \ No newline at end of file
manifests/ha/base/redis-ha/overlays/deployment-initContainers.yaml+16 −0 added@@ -0,0 +1,16 @@ +- op: add + path: /spec/template/spec/initContainers/0 + value: + name: secret-init + command: [ 'argocd', 'admin', 'redis-initial-password' ] + image: quay.io/argoproj/argocd:latest + imagePullPolicy: IfNotPresent + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault \ No newline at end of file
manifests/ha/base/redis-ha/overlays/haproxy-role.yaml+20 −0 added@@ -0,0 +1,20 @@ +- op: add + path: /rules/0 + value: + apiGroups: + - "" + resources: + - secrets + resourceNames: + - argocd-redis + verbs: + - get +- op: add + path: /rules/0 + value: + apiGroups: + - "" + resources: + - secrets + verbs: + - create \ No newline at end of file
manifests/ha/install.yaml+108 −31 modified@@ -20546,6 +20546,8 @@ metadata: app.kubernetes.io/name: argocd-redis-ha app.kubernetes.io/part-of: argocd name: argocd-redis-ha +secrets: +- name: argocd-redis --- apiVersion: v1 kind: ServiceAccount @@ -20776,6 +20778,20 @@ metadata: app.kubernetes.io/part-of: argocd name: argocd-redis-ha-haproxy rules: +- apiGroups: + - "" + resources: + - secrets + verbs: + - create +- apiGroups: + - "" + resourceNames: + - argocd-redis + resources: + - secrets + verbs: + - get - apiGroups: - "" resources: @@ -21220,7 +21236,7 @@ data: sentinel_get_master() { set +e if [ "$SENTINEL_PORT" -eq 0 ]; then - redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ + redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ grep -E '((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?s*$))' else redis-cli -h "${SERVICE}" -p "${SENTINEL_PORT}" sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ @@ -21329,9 +21345,9 @@ data: redis_ping() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - redis-cli -h "${MASTER}" -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping else - redis-cli -h "${MASTER}" -p "${REDIS_PORT}" ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" ping fi set -e } @@ -21364,7 +21380,7 @@ data: if [ "$SENTINEL_PORT" -eq 0 ]; then echo " on sentinel (${SERVICE}:${SENTINEL_TLS_PORT}), sentinel grp (${MASTER_GROUP})" - if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then + if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then echo " $(date) Failover returned with 'NOGOODSLAVE'" echo "Setting defaults for this pod.." setup_defaults @@ -21429,19 +21445,19 @@ data: redis_role() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - ROLE=$(redis-cli -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep role | sed 's/role://' | sed 's/\r//') + ROLE=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep role | sed 's/role://' | sed 's/\r//') else - ROLE=$(redis-cli -p "${REDIS_PORT}" info | grep role | sed 's/role://' | sed 's/\r//') + ROLE=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" info | grep role | sed 's/role://' | sed 's/\r//') fi set -e } identify_redis_master() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - REDIS_MASTER=$(redis-cli -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep master_host | sed 's/master_host://' | sed 's/\r//') + REDIS_MASTER=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep master_host | sed 's/master_host://' | sed 's/\r//') else - REDIS_MASTER=$(redis-cli -p "${REDIS_PORT}" info | grep master_host | sed 's/master_host://' | sed 's/\r//') + REDIS_MASTER=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" info | grep master_host | sed 's/master_host://' | sed 's/\r//') fi set -e } @@ -21451,9 +21467,9 @@ data: sh /readonly-config/init.sh if [ "$REDIS_PORT" -eq 0 ]; then - echo "shutdown" | redis-cli -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key + echo "shutdown" | redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key else - echo "shutdown" | redis-cli -p "${REDIS_PORT}" + echo "shutdown" | redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" fi set -e } @@ -21466,6 +21482,7 @@ data: identify_announce_ip done + trap "exit 0" TERM while true; do sleep 60 @@ -21508,9 +21525,10 @@ data: decide redis backend to use\n#master\nfrontend ft_redis_master\n bind :6379 \n \ use_backend bk_redis_master\n# Check all redis servers to see if they think they are master\nbackend bk_redis_master\n mode tcp\n option tcp-check\n tcp-check - connect\n tcp-check send PING\\r\\n\n tcp-check expect string +PONG\n tcp-check - send info\\ replication\\r\\n\n tcp-check expect string role:master\n tcp-check - send QUIT\\r\\n\n tcp-check expect string +OK\n use-server R0 if { srv_is_up(R0) + connect\n tcp-check send \"AUTH ${AUTH}\"\\r\\n\n tcp-check expect string +OK\n + \ tcp-check send PING\\r\\n\n tcp-check expect string +PONG\n tcp-check send + info\\ replication\\r\\n\n tcp-check expect string role:master\n tcp-check send + QUIT\\r\\n\n tcp-check expect string +OK\n use-server R0 if { srv_is_up(R0) } { nbsrv(check_if_redis_is_master_0) ge 2 }\n server R0 argocd-redis-ha-announce-0:6379 check inter 3s fall 1 rise 1\n use-server R1 if { srv_is_up(R1) } { nbsrv(check_if_redis_is_master_1) ge 2 }\n server R1 argocd-redis-ha-announce-1:6379 check inter 3s fall 1 rise @@ -21573,7 +21591,7 @@ data: sentinel_get_master() { set +e if [ "$SENTINEL_PORT" -eq 0 ]; then - redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ + redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ grep -E '((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?s*$))' else redis-cli -h "${SERVICE}" -p "${SENTINEL_PORT}" sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ @@ -21682,9 +21700,9 @@ data: redis_ping() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - redis-cli -h "${MASTER}" -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping else - redis-cli -h "${MASTER}" -p "${REDIS_PORT}" ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" ping fi set -e } @@ -21717,7 +21735,7 @@ data: if [ "$SENTINEL_PORT" -eq 0 ]; then echo " on sentinel (${SERVICE}:${SENTINEL_TLS_PORT}), sentinel grp (${MASTER_GROUP})" - if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then + if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then echo " $(date) Failover returned with 'NOGOODSLAVE'" echo "Setting defaults for this pod.." setup_defaults @@ -21825,6 +21843,8 @@ data: rdbcompression yes repl-diskless-sync yes save "" + requirepass replace-default-auth + masterauth replace-default-auth sentinel.conf: | dir "/data" port 26379 @@ -21833,10 +21853,12 @@ data: sentinel failover-timeout argocd 180000 maxclients 10000 sentinel parallel-syncs argocd 5 + sentinel auth-pass argocd replace-default-auth trigger-failover-if-master.sh: | get_redis_role() { is_master=$( redis-cli \ + -a "${AUTH}" --no-auth-warning \ -h localhost \ -p 6379 \ info | grep -c 'role:master' || true @@ -21876,6 +21898,7 @@ data: redis_liveness.sh: | response=$( redis-cli \ + -a "${AUTH}" --no-auth-warning \ -h localhost \ -p 6379 \ ping @@ -21888,6 +21911,7 @@ data: redis_readiness.sh: | response=$( redis-cli \ + -a "${AUTH}" --no-auth-warning \ -h localhost \ -p 6379 \ ping @@ -22076,8 +22100,6 @@ spec: apiVersion: v1 kind: Service metadata: - annotations: - service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" labels: app.kubernetes.io/component: redis app.kubernetes.io/name: argocd-redis-ha @@ -22102,8 +22124,6 @@ spec: apiVersion: v1 kind: Service metadata: - annotations: - service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" labels: app.kubernetes.io/component: redis app.kubernetes.io/name: argocd-redis-ha @@ -22128,8 +22148,6 @@ spec: apiVersion: v1 kind: Service metadata: - annotations: - service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" labels: app.kubernetes.io/component: redis app.kubernetes.io/name: argocd-redis-ha @@ -22646,7 +22664,7 @@ spec: template: metadata: annotations: - checksum/config: 492a6adabb741e0cee39be9aa5155c41a4456629f862d0006a2d892dbecfbcae + checksum/config: e34e8124c38bcfd2f16e75620bbde30158686692b13bc449eecc44c51b207d54 prometheus.io/path: /metrics prometheus.io/port: "9101" prometheus.io/scrape: "true" @@ -22662,7 +22680,13 @@ spec: app.kubernetes.io/name: argocd-redis-ha-haproxy topologyKey: kubernetes.io/hostname containers: - - image: haproxy:2.6.14-alpine + - env: + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/haproxy:2.6.14-alpine imagePullPolicy: IfNotPresent lifecycle: {} livenessProbe: @@ -22697,11 +22721,27 @@ spec: - mountPath: /run/haproxy name: shared-socket initContainers: + - command: + - argocd + - admin + - redis-initial-password + image: quay.io/argoproj/argocd:latest + imagePullPolicy: IfNotPresent + name: secret-init + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault - args: - /readonly/haproxy_init.sh command: - sh - image: haproxy:2.6.14-alpine + image: public.ecr.aws/docker/library/haproxy:2.6.14-alpine imagePullPolicy: IfNotPresent name: config-init securityContext: @@ -22769,6 +22809,11 @@ spec: - args: - /usr/local/bin/argocd-repo-server env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_RECONCILIATION_TIMEOUT valueFrom: configMapKeyRef: @@ -23080,6 +23125,11 @@ spec: env: - name: ARGOCD_API_SERVER_REPLICAS value: "2" + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_SERVER_INSECURE valueFrom: configMapKeyRef: @@ -23426,6 +23476,11 @@ spec: - args: - /usr/local/bin/argocd-application-controller env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_CONTROLLER_REPLICAS value: "1" - name: ARGOCD_RECONCILIATION_TIMEOUT @@ -23668,7 +23723,7 @@ spec: template: metadata: annotations: - checksum/init-config: 69130412bda04eacad3530cb7bcf26cf121401e725e15d0959dd71a7380afe75 + checksum/init-config: 9d3c019a5ea1fd98ab5cde397d8eecd351da884f15e6ba346c607cb2446c2198 labels: app.kubernetes.io/name: argocd-redis-ha spec: @@ -23685,7 +23740,13 @@ spec: - /data/conf/redis.conf command: - redis-server - image: redis:7.0.15-alpine + env: + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent lifecycle: preStop: @@ -23739,7 +23800,13 @@ spec: - /data/conf/sentinel.conf command: - redis-sentinel - image: redis:7.0.15-alpine + env: + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent lifecycle: {} livenessProbe: @@ -23792,7 +23859,12 @@ spec: value: 40000915ab58c3fa8fd888fb8b24711944e6cbb4 - name: SENTINEL_ID_2 value: 2bbec7894d954a8af3bb54d13eaec53cb024e2ca - image: redis:7.0.15-alpine + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent name: split-brain-fix resources: {} @@ -23822,7 +23894,12 @@ spec: value: 40000915ab58c3fa8fd888fb8b24711944e6cbb4 - name: SENTINEL_ID_2 value: 2bbec7894d954a8af3bb54d13eaec53cb024e2ca - image: redis:7.0.15-alpine + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent name: config-init securityContext:
manifests/ha/namespace-install.yaml+108 −31 modified@@ -43,6 +43,8 @@ metadata: app.kubernetes.io/name: argocd-redis-ha app.kubernetes.io/part-of: argocd name: argocd-redis-ha +secrets: +- name: argocd-redis --- apiVersion: v1 kind: ServiceAccount @@ -273,6 +275,20 @@ metadata: app.kubernetes.io/part-of: argocd name: argocd-redis-ha-haproxy rules: +- apiGroups: + - "" + resources: + - secrets + verbs: + - create +- apiGroups: + - "" + resourceNames: + - argocd-redis + resources: + - secrets + verbs: + - get - apiGroups: - "" resources: @@ -505,7 +521,7 @@ data: sentinel_get_master() { set +e if [ "$SENTINEL_PORT" -eq 0 ]; then - redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ + redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ grep -E '((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?s*$))' else redis-cli -h "${SERVICE}" -p "${SENTINEL_PORT}" sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ @@ -614,9 +630,9 @@ data: redis_ping() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - redis-cli -h "${MASTER}" -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping else - redis-cli -h "${MASTER}" -p "${REDIS_PORT}" ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" ping fi set -e } @@ -649,7 +665,7 @@ data: if [ "$SENTINEL_PORT" -eq 0 ]; then echo " on sentinel (${SERVICE}:${SENTINEL_TLS_PORT}), sentinel grp (${MASTER_GROUP})" - if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then + if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then echo " $(date) Failover returned with 'NOGOODSLAVE'" echo "Setting defaults for this pod.." setup_defaults @@ -714,19 +730,19 @@ data: redis_role() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - ROLE=$(redis-cli -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep role | sed 's/role://' | sed 's/\r//') + ROLE=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep role | sed 's/role://' | sed 's/\r//') else - ROLE=$(redis-cli -p "${REDIS_PORT}" info | grep role | sed 's/role://' | sed 's/\r//') + ROLE=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" info | grep role | sed 's/role://' | sed 's/\r//') fi set -e } identify_redis_master() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - REDIS_MASTER=$(redis-cli -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep master_host | sed 's/master_host://' | sed 's/\r//') + REDIS_MASTER=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep master_host | sed 's/master_host://' | sed 's/\r//') else - REDIS_MASTER=$(redis-cli -p "${REDIS_PORT}" info | grep master_host | sed 's/master_host://' | sed 's/\r//') + REDIS_MASTER=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" info | grep master_host | sed 's/master_host://' | sed 's/\r//') fi set -e } @@ -736,9 +752,9 @@ data: sh /readonly-config/init.sh if [ "$REDIS_PORT" -eq 0 ]; then - echo "shutdown" | redis-cli -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key + echo "shutdown" | redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key else - echo "shutdown" | redis-cli -p "${REDIS_PORT}" + echo "shutdown" | redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" fi set -e } @@ -751,6 +767,7 @@ data: identify_announce_ip done + trap "exit 0" TERM while true; do sleep 60 @@ -793,9 +810,10 @@ data: decide redis backend to use\n#master\nfrontend ft_redis_master\n bind :6379 \n \ use_backend bk_redis_master\n# Check all redis servers to see if they think they are master\nbackend bk_redis_master\n mode tcp\n option tcp-check\n tcp-check - connect\n tcp-check send PING\\r\\n\n tcp-check expect string +PONG\n tcp-check - send info\\ replication\\r\\n\n tcp-check expect string role:master\n tcp-check - send QUIT\\r\\n\n tcp-check expect string +OK\n use-server R0 if { srv_is_up(R0) + connect\n tcp-check send \"AUTH ${AUTH}\"\\r\\n\n tcp-check expect string +OK\n + \ tcp-check send PING\\r\\n\n tcp-check expect string +PONG\n tcp-check send + info\\ replication\\r\\n\n tcp-check expect string role:master\n tcp-check send + QUIT\\r\\n\n tcp-check expect string +OK\n use-server R0 if { srv_is_up(R0) } { nbsrv(check_if_redis_is_master_0) ge 2 }\n server R0 argocd-redis-ha-announce-0:6379 check inter 3s fall 1 rise 1\n use-server R1 if { srv_is_up(R1) } { nbsrv(check_if_redis_is_master_1) ge 2 }\n server R1 argocd-redis-ha-announce-1:6379 check inter 3s fall 1 rise @@ -858,7 +876,7 @@ data: sentinel_get_master() { set +e if [ "$SENTINEL_PORT" -eq 0 ]; then - redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ + redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ grep -E '((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?s*$))' else redis-cli -h "${SERVICE}" -p "${SENTINEL_PORT}" sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ @@ -967,9 +985,9 @@ data: redis_ping() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - redis-cli -h "${MASTER}" -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping else - redis-cli -h "${MASTER}" -p "${REDIS_PORT}" ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" ping fi set -e } @@ -1002,7 +1020,7 @@ data: if [ "$SENTINEL_PORT" -eq 0 ]; then echo " on sentinel (${SERVICE}:${SENTINEL_TLS_PORT}), sentinel grp (${MASTER_GROUP})" - if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then + if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then echo " $(date) Failover returned with 'NOGOODSLAVE'" echo "Setting defaults for this pod.." setup_defaults @@ -1110,6 +1128,8 @@ data: rdbcompression yes repl-diskless-sync yes save "" + requirepass replace-default-auth + masterauth replace-default-auth sentinel.conf: | dir "/data" port 26379 @@ -1118,10 +1138,12 @@ data: sentinel failover-timeout argocd 180000 maxclients 10000 sentinel parallel-syncs argocd 5 + sentinel auth-pass argocd replace-default-auth trigger-failover-if-master.sh: | get_redis_role() { is_master=$( redis-cli \ + -a "${AUTH}" --no-auth-warning \ -h localhost \ -p 6379 \ info | grep -c 'role:master' || true @@ -1161,6 +1183,7 @@ data: redis_liveness.sh: | response=$( redis-cli \ + -a "${AUTH}" --no-auth-warning \ -h localhost \ -p 6379 \ ping @@ -1173,6 +1196,7 @@ data: redis_readiness.sh: | response=$( redis-cli \ + -a "${AUTH}" --no-auth-warning \ -h localhost \ -p 6379 \ ping @@ -1361,8 +1385,6 @@ spec: apiVersion: v1 kind: Service metadata: - annotations: - service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" labels: app.kubernetes.io/component: redis app.kubernetes.io/name: argocd-redis-ha @@ -1387,8 +1409,6 @@ spec: apiVersion: v1 kind: Service metadata: - annotations: - service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" labels: app.kubernetes.io/component: redis app.kubernetes.io/name: argocd-redis-ha @@ -1413,8 +1433,6 @@ spec: apiVersion: v1 kind: Service metadata: - annotations: - service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" labels: app.kubernetes.io/component: redis app.kubernetes.io/name: argocd-redis-ha @@ -1931,7 +1949,7 @@ spec: template: metadata: annotations: - checksum/config: 492a6adabb741e0cee39be9aa5155c41a4456629f862d0006a2d892dbecfbcae + checksum/config: e34e8124c38bcfd2f16e75620bbde30158686692b13bc449eecc44c51b207d54 prometheus.io/path: /metrics prometheus.io/port: "9101" prometheus.io/scrape: "true" @@ -1947,7 +1965,13 @@ spec: app.kubernetes.io/name: argocd-redis-ha-haproxy topologyKey: kubernetes.io/hostname containers: - - image: haproxy:2.6.14-alpine + - env: + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/haproxy:2.6.14-alpine imagePullPolicy: IfNotPresent lifecycle: {} livenessProbe: @@ -1982,11 +2006,27 @@ spec: - mountPath: /run/haproxy name: shared-socket initContainers: + - command: + - argocd + - admin + - redis-initial-password + image: quay.io/argoproj/argocd:latest + imagePullPolicy: IfNotPresent + name: secret-init + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault - args: - /readonly/haproxy_init.sh command: - sh - image: haproxy:2.6.14-alpine + image: public.ecr.aws/docker/library/haproxy:2.6.14-alpine imagePullPolicy: IfNotPresent name: config-init securityContext: @@ -2054,6 +2094,11 @@ spec: - args: - /usr/local/bin/argocd-repo-server env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_RECONCILIATION_TIMEOUT valueFrom: configMapKeyRef: @@ -2365,6 +2410,11 @@ spec: env: - name: ARGOCD_API_SERVER_REPLICAS value: "2" + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_SERVER_INSECURE valueFrom: configMapKeyRef: @@ -2711,6 +2761,11 @@ spec: - args: - /usr/local/bin/argocd-application-controller env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_CONTROLLER_REPLICAS value: "1" - name: ARGOCD_RECONCILIATION_TIMEOUT @@ -2953,7 +3008,7 @@ spec: template: metadata: annotations: - checksum/init-config: 69130412bda04eacad3530cb7bcf26cf121401e725e15d0959dd71a7380afe75 + checksum/init-config: 9d3c019a5ea1fd98ab5cde397d8eecd351da884f15e6ba346c607cb2446c2198 labels: app.kubernetes.io/name: argocd-redis-ha spec: @@ -2970,7 +3025,13 @@ spec: - /data/conf/redis.conf command: - redis-server - image: redis:7.0.15-alpine + env: + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent lifecycle: preStop: @@ -3024,7 +3085,13 @@ spec: - /data/conf/sentinel.conf command: - redis-sentinel - image: redis:7.0.15-alpine + env: + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent lifecycle: {} livenessProbe: @@ -3077,7 +3144,12 @@ spec: value: 40000915ab58c3fa8fd888fb8b24711944e6cbb4 - name: SENTINEL_ID_2 value: 2bbec7894d954a8af3bb54d13eaec53cb024e2ca - image: redis:7.0.15-alpine + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent name: split-brain-fix resources: {} @@ -3107,7 +3179,12 @@ spec: value: 40000915ab58c3fa8fd888fb8b24711944e6cbb4 - name: SENTINEL_ID_2 value: 2bbec7894d954a8af3bb54d13eaec53cb024e2ca - image: redis:7.0.15-alpine + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent name: config-init securityContext:
manifests/install.yaml+79 −0 modified@@ -20744,6 +20744,30 @@ rules: --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +rules: +- apiGroups: + - "" + resourceNames: + - argocd-redis + resources: + - secrets + verbs: + - get +- apiGroups: + - "" + resources: + - secrets + verbs: + - create +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role metadata: labels: app.kubernetes.io/component: server @@ -21013,6 +21037,22 @@ subjects: --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: argocd-redis +subjects: +- kind: ServiceAccount + name: argocd-redis +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding metadata: labels: app.kubernetes.io/component: server @@ -21760,6 +21800,13 @@ spec: - "" - --appendonly - "no" + - --requirepass $(REDIS_PASSWORD) + env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis image: redis:7.0.15-alpine imagePullPolicy: Always name: redis @@ -21771,6 +21818,23 @@ spec: drop: - ALL readOnlyRootFilesystem: true + initContainers: + - command: + - argocd + - admin + - redis-initial-password + image: quay.io/argoproj/argocd:latest + imagePullPolicy: IfNotPresent + name: secret-init + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault securityContext: runAsNonRoot: true runAsUser: 999 @@ -21815,6 +21879,11 @@ spec: - args: - /usr/local/bin/argocd-repo-server env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_RECONCILIATION_TIMEOUT valueFrom: configMapKeyRef: @@ -22124,6 +22193,11 @@ spec: - args: - /usr/local/bin/argocd-server env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_SERVER_INSECURE valueFrom: configMapKeyRef: @@ -22470,6 +22544,11 @@ spec: - args: - /usr/local/bin/argocd-application-controller env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_CONTROLLER_REPLICAS value: "1" - name: ARGOCD_RECONCILIATION_TIMEOUT
manifests/namespace-install.yaml+79 −0 modified@@ -241,6 +241,30 @@ rules: --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +rules: +- apiGroups: + - "" + resourceNames: + - argocd-redis + resources: + - secrets + verbs: + - get +- apiGroups: + - "" + resources: + - secrets + verbs: + - create +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role metadata: labels: app.kubernetes.io/component: server @@ -349,6 +373,22 @@ subjects: --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: argocd-redis +subjects: +- kind: ServiceAccount + name: argocd-redis +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding metadata: labels: app.kubernetes.io/component: server @@ -1045,6 +1085,13 @@ spec: - "" - --appendonly - "no" + - --requirepass $(REDIS_PASSWORD) + env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis image: redis:7.0.15-alpine imagePullPolicy: Always name: redis @@ -1056,6 +1103,23 @@ spec: drop: - ALL readOnlyRootFilesystem: true + initContainers: + - command: + - argocd + - admin + - redis-initial-password + image: quay.io/argoproj/argocd:latest + imagePullPolicy: IfNotPresent + name: secret-init + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault securityContext: runAsNonRoot: true runAsUser: 999 @@ -1100,6 +1164,11 @@ spec: - args: - /usr/local/bin/argocd-repo-server env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_RECONCILIATION_TIMEOUT valueFrom: configMapKeyRef: @@ -1409,6 +1478,11 @@ spec: - args: - /usr/local/bin/argocd-server env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_SERVER_INSECURE valueFrom: configMapKeyRef: @@ -1755,6 +1829,11 @@ spec: - args: - /usr/local/bin/argocd-application-controller env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_CONTROLLER_REPLICAS value: "1" - name: ARGOCD_RECONCILIATION_TIMEOUT
reposerver/repository/repository_test.go+1 −1 modified@@ -199,7 +199,7 @@ func TestGenerateYamlManifestInDir(t *testing.T) { } // update this value if we add/remove manifests - const countOfManifests = 48 + const countOfManifests = 50 res1, err := service.GenerateManifest(context.Background(), &q)
35a7d6c7fa15Merge pull request from GHSA-9766-5277-j5hr
26 files changed · +887 −116
cmd/argocd/commands/admin/admin.go+1 −0 modified@@ -59,6 +59,7 @@ func NewAdminCommand() *cobra.Command { command.AddCommand(NewDashboardCommand()) command.AddCommand(NewNotificationsCommand()) command.AddCommand(NewInitialPasswordCommand()) + command.AddCommand(NewRedisInitialPasswordCommand()) command.Flags().StringVar(&cmdutil.LogFormat, "logformat", "text", "Set the logging format. One of: text|json") command.Flags().StringVar(&cmdutil.LogLevel, "loglevel", "info", "Set the logging level. One of: debug|info|warn|error")
cmd/argocd/commands/admin/redis_initial_password.go+98 −0 added@@ -0,0 +1,98 @@ +package admin + +import ( + "context" + "crypto/rand" + "fmt" + "math/big" + + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/cli" + apierr "k8s.io/apimachinery/pkg/api/errors" + + "github.com/argoproj/argo-cd/v2/util/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/tools/clientcmd" + + "github.com/spf13/cobra" + corev1 "k8s.io/api/core/v1" +) + +const defaulRedisInitialPasswordSecretName = "argocd-redis" +const defaultResisInitialPasswordKey = "auth" + +func generateRandomPassword() (string, error) { + const initialPasswordLength = 16 + const letters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-" + randBytes := make([]byte, initialPasswordLength) + for i := 0; i < initialPasswordLength; i++ { + num, err := rand.Int(rand.Reader, big.NewInt(int64(len(letters)))) + if err != nil { + return "", err + } + randBytes[i] = letters[num.Int64()] + } + initialPassword := string(randBytes) + return initialPassword, nil +} + +// NewRedisInitialPasswordCommand defines a new command to ensure Argo CD Redis password secret exists. +func NewRedisInitialPasswordCommand() *cobra.Command { + var ( + clientConfig clientcmd.ClientConfig + ) + var command = cobra.Command{ + Use: "redis-initial-password", + Short: "Ensure the Redis password exists, creating a new one if necessary.", + Run: func(c *cobra.Command, args []string) { + namespace, _, err := clientConfig.Namespace() + errors.CheckError(err) + + redisInitialPasswordSecretName := defaulRedisInitialPasswordSecretName + redisInitialPasswordKey := defaultResisInitialPasswordKey + fmt.Printf("Checking for initial Redis password in secret %s/%s at key %s. \n", namespace, redisInitialPasswordSecretName, redisInitialPasswordKey) + + config, err := clientConfig.ClientConfig() + errors.CheckError(err) + errors.CheckError(v1alpha1.SetK8SConfigDefaults(config)) + + kubeClientset := kubernetes.NewForConfigOrDie(config) + + randomPassword, err := generateRandomPassword() + errors.CheckError(err) + + data := map[string][]byte{ + redisInitialPasswordKey: []byte(randomPassword), + } + secret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: redisInitialPasswordSecretName, + Namespace: namespace, + }, + Data: data, + Type: corev1.SecretTypeOpaque, + } + _, err = kubeClientset.CoreV1().Secrets(namespace).Create(context.Background(), secret, metav1.CreateOptions{}) + if err != nil && !apierr.IsAlreadyExists(err) { + errors.CheckError(err) + } + + fmt.Println("Argo CD Redis secret state confirmed: secret name argocd-redis.") + secret, err = kubeClientset.CoreV1().Secrets(namespace).Get(context.Background(), redisInitialPasswordSecretName, v1.GetOptions{}) + errors.CheckError(err) + + if _, ok := secret.Data[redisInitialPasswordKey]; ok { + fmt.Println("Password secret is configured properly.") + } else { + err := fmt.Errorf("key %s doesn't exist in secret %s. \n", redisInitialPasswordKey, redisInitialPasswordSecretName) + errors.CheckError(err) + } + }, + } + + clientConfig = cli.AddKubectlFlagsToCmd(&command) + + return &command +}
docs/faq.md+42 −0 modified@@ -259,3 +259,45 @@ The most common instance of this error is with `env:` fields for `containers`. !!! note "Dynamic applications" It's possible that your application is being generated by a tool in which case the duplication might not be evident within the scope of a single file. If you have trouble debugging this problem, consider filing a ticket to the owner of the generator tool asking them to improve its validation and error reporting. + +## How to rotate Redis secret? +* Delete `argocd-redis` secret in the namespace where Argo CD is installed. +```bash +kubectl delete secret argocd-redis -n <argocd namesapce> +``` +* If you are running Redis in HA mode, restart Redis in HA. +```bash +kubectl rollout restart deployment argocd-redis-ha-haproxy +kubectl rollout restart statefulset argocd-redis-ha-server +``` +* If you are running Redis in non-HA mode, restart Redis. +```bash +kubectl rollout restart deployment argocd-redis +``` +* Restart other components. +```bash +kubectl rollout restart deployment argocd-server argocd-repo-server +kubectl rollout restart statefulset argocd-application-controller +``` + +## How to turn off Redis auth if users really want to? + +Argo CD default installation is now configured automatically enable Redis authentication. +If for some reason authenticated Redis does not work for you and you want to use non-authenticated Redis, here are the steps: + +* You need to have your own Redis installation. +* Configure Argo CD to use your own Redis instance. See this [doc](https://argo-cd.readthedocs.io/en/stable/operator-manual/argocd-cmd-params-cm-yaml/) for the Argo CD configuration. +* If you already installed Redis shipped with Argo CD, you also need to clean up the existing components: + * When HA Redis is used: + * kubectl delete deployment argocd-redis-ha-haproxy + * kubectl delete statefulset argocd-redis-ha-server + * When non-HA Redis is used: + * kubectl delete deployment argocd-redis +* Remove environment variable `REDIS_PASSWORD` from the following manifests + * Deployment: argocd-repo-server: + * Deployment: argocd-server + * StatefulSet: argocd-application-controller + +## How do I provide my own Redis credentials? +The Redis password is stored in Kubernetes secret `argocd-redis` with key `auth` in the namespace where Argo CD is installed. +You can config your secret provider to generate Kubernetes secret accordingly. \ No newline at end of file
docs/getting_started.md+3 −0 modified@@ -38,6 +38,9 @@ Do one of: Use `argocd login --core` to [configure](./user-guide/commands/argocd_login.md) CLI access and skip steps 3-5. +!!! note + This default installation for Redis is using password authentication. The Redis password is stored in Kubernetes secret `argocd-redis` with key `auth` in the namespace where Argo CD is installed. + ## 2. Download Argo CD CLI Download the latest Argo CD version from [https://github.com/argoproj/argo-cd/releases/latest](https://github.com/argoproj/argo-cd/releases/latest). More detailed installation instructions can be found via the [CLI installation documentation](cli_installation.md).
docs/user-guide/commands/argocd_admin.md+1 −0 modified@@ -46,6 +46,7 @@ argocd admin [flags] * [argocd admin initial-password](argocd_admin_initial-password.md) - Prints initial password to log in to Argo CD for the first time * [argocd admin notifications](argocd_admin_notifications.md) - Set of CLI commands that helps manage notifications settings * [argocd admin proj](argocd_admin_proj.md) - Manage projects configuration +* [argocd admin redis-initial-password](argocd_admin_redis-initial-password.md) - Ensure the Redis password exists, creating a new one if necessary. * [argocd admin repo](argocd_admin_repo.md) - Manage repositories configuration * [argocd admin settings](argocd_admin_settings.md) - Provides set of commands for settings validation and troubleshooting
docs/user-guide/commands/argocd_admin_redis-initial-password.md+67 −0 added@@ -0,0 +1,67 @@ +# `argocd admin redis-initial-password` Command Reference + +## argocd admin redis-initial-password + +Ensure the Redis password exists, creating a new one if necessary. + +``` +argocd admin redis-initial-password [flags] +``` + +### Options + +``` + --as string Username to impersonate for the operation + --as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --as-uid string UID to impersonate for the operation + --certificate-authority string Path to a cert file for the certificate authority + --client-certificate string Path to a client certificate file for TLS + --client-key string Path to a client key file for TLS + --cluster string The name of the kubeconfig cluster to use + --context string The name of the kubeconfig context to use + --disable-compression If true, opt-out of response compression for all requests to the server + -h, --help help for redis-initial-password + --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kubeconfig string Path to a kube config. Only required if out-of-cluster + -n, --namespace string If present, the namespace scope for this CLI request + --password string Password for basic authentication to the API server + --proxy-url string If provided, this URL will be used to connect via proxy + --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") + --server string The address and port of the Kubernetes API server + --tls-server-name string If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used. + --token string Bearer token for authentication to the API server + --user string The name of the kubeconfig user to use + --username string Username for basic authentication to the API server +``` + +### Options inherited from parent commands + +``` + --auth-token string Authentication token + --client-crt string Client certificate file + --client-crt-key string Client certificate key file + --config string Path to Argo CD config (default "/home/user/.config/argocd/config") + --controller-name string Name of the Argo CD Application controller; set this or the ARGOCD_APPLICATION_CONTROLLER_NAME environment variable when the controller's name label differs from the default, for example when installing via the Helm chart (default "argocd-application-controller") + --core If set to true then CLI talks directly to Kubernetes instead of talking to Argo CD API server + --grpc-web Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. + --grpc-web-root-path string Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. Set web root. + -H, --header strings Sets additional header to all requests made by Argo CD CLI. (Can be repeated multiple times to add multiple headers, also supports comma separated headers) + --http-retry-max int Maximum number of retries to establish http connection to Argo CD server + --insecure Skip server certificate and domain verification + --kube-context string Directs the command to the given kube-context + --logformat string Set the logging format. One of: text|json (default "text") + --loglevel string Set the logging level. One of: debug|info|warn|error (default "info") + --plaintext Disable TLS + --port-forward Connect to a random argocd-server port using port forwarding + --port-forward-namespace string Namespace name which should be used for port forwarding + --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") + --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") + --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") + --server-crt string Server certificate file + --server-name string Name of the Argo CD API server; set this or the ARGOCD_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-server") +``` + +### SEE ALSO + +* [argocd admin](argocd_admin.md) - Contains a set of commands useful for Argo CD administrators and requires direct Kubernetes access +
manifests/base/application-controller/argocd-application-controller-statefulset.yaml+5 −0 modified@@ -21,6 +21,11 @@ spec: - args: - /usr/local/bin/argocd-application-controller env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_CONTROLLER_REPLICAS value: "1" - name: ARGOCD_RECONCILIATION_TIMEOUT
manifests/base/redis/argocd-redis-deployment.yaml+24 −0 modified@@ -15,6 +15,23 @@ spec: labels: app.kubernetes.io/name: argocd-redis spec: + initContainers: + - command: + - argocd + - admin + - redis-initial-password + image: quay.io/argoproj/argocd:latest + imagePullPolicy: IfNotPresent + name: secret-init + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault securityContext: runAsNonRoot: true runAsUser: 999 @@ -30,6 +47,13 @@ spec: - "" - "--appendonly" - "no" + - --requirepass $(REDIS_PASSWORD) + env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis ports: - containerPort: 6379 securityContext:
manifests/base/redis/argocd-redis-rolebinding.yaml+15 −0 added@@ -0,0 +1,15 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: argocd-redis +subjects: + - kind: ServiceAccount + name: argocd-redis \ No newline at end of file
manifests/base/redis/argocd-redis-role.yaml+23 −0 added@@ -0,0 +1,23 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +rules: + - apiGroups: + - "" + resources: + - secrets + resourceNames: + - argocd-redis + verbs: + - get + - apiGroups: + - "" + resources: + - secrets + verbs: + - create \ No newline at end of file
manifests/base/redis/kustomization.yaml+2 −0 modified@@ -6,3 +6,5 @@ resources: - argocd-redis-sa.yaml - argocd-redis-service.yaml - argocd-redis-network-policy.yaml +- argocd-redis-role.yaml +- argocd-redis-rolebinding.yaml
manifests/base/repo-server/argocd-repo-server-deployment.yaml+5 −0 modified@@ -24,6 +24,11 @@ spec: args: - /usr/local/bin/argocd-repo-server env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_RECONCILIATION_TIMEOUT valueFrom: configMapKeyRef:
manifests/base/server/argocd-server-deployment.yaml+5 −0 modified@@ -23,6 +23,11 @@ spec: args: - /usr/local/bin/argocd-server env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_SERVER_INSECURE valueFrom: configMapKeyRef:
manifests/core-install.yaml+74 −0 modified@@ -18524,6 +18524,30 @@ rules: - watch --- apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +rules: +- apiGroups: + - "" + resourceNames: + - argocd-redis + resources: + - secrets + verbs: + - get +- apiGroups: + - "" + resources: + - secrets + verbs: + - create +--- +apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: labels: @@ -18576,6 +18600,22 @@ subjects: name: argocd-applicationset-controller --- apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: argocd-redis +subjects: +- kind: ServiceAccount + name: argocd-redis +--- +apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: labels: @@ -18969,6 +19009,13 @@ spec: - "" - --appendonly - "no" + - --requirepass $(REDIS_PASSWORD) + env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis image: redis:7.0.15-alpine imagePullPolicy: Always name: redis @@ -18980,6 +19027,23 @@ spec: drop: - ALL readOnlyRootFilesystem: true + initContainers: + - command: + - argocd + - admin + - redis-initial-password + image: quay.io/argoproj/argocd:latest + imagePullPolicy: IfNotPresent + name: secret-init + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault securityContext: runAsNonRoot: true runAsUser: 999 @@ -19024,6 +19088,11 @@ spec: - args: - /usr/local/bin/argocd-repo-server env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_RECONCILIATION_TIMEOUT valueFrom: configMapKeyRef: @@ -19311,6 +19380,11 @@ spec: - args: - /usr/local/bin/argocd-application-controller env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_CONTROLLER_REPLICAS value: "1" - name: ARGOCD_RECONCILIATION_TIMEOUT
manifests/ha/base/redis-ha/chart/requirements.lock+3 −3 modified@@ -1,6 +1,6 @@ dependencies: - name: redis-ha repository: https://dandydeveloper.github.io/charts - version: 4.22.3 -digest: sha256:ae773caf65b172bdd2216072c03ba76ef3c0383dbd1e2478934a67b9455f6a2e -generated: "2022-11-02T16:57:25.047025473-07:00" + version: 4.26.6 +digest: sha256:c363f48ea8339c4bdb7c8a2cca62aa487b69d0a52a6fe6267fbbbbc07e468abd +generated: "2024-04-10T11:02:32.957812-07:00"
manifests/ha/base/redis-ha/chart/requirements.yaml+1 −1 modified@@ -1,4 +1,4 @@ dependencies: - name: redis-ha - version: 4.22.3 + version: 4.26.6 repository: https://dandydeveloper.github.io/charts
manifests/ha/base/redis-ha/chart/upstream.yaml+81 −44 modified@@ -9,8 +9,10 @@ metadata: labels: heritage: Helm release: argocd - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 app: argocd-redis-ha +secrets: +- name: argocd-redis --- # Source: redis-ha/charts/redis-ha/templates/redis-haproxy-serviceaccount.yaml apiVersion: v1 @@ -21,7 +23,7 @@ metadata: labels: heritage: Helm release: argocd - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 app: argocd-redis-ha --- # Source: redis-ha/charts/redis-ha/templates/redis-ha-configmap.yaml @@ -33,7 +35,7 @@ metadata: labels: heritage: Helm release: argocd - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 app: argocd-redis-ha data: redis.conf: | @@ -50,6 +52,8 @@ data: rdbcompression yes repl-diskless-sync yes save "" + requirepass replace-default-auth + masterauth replace-default-auth sentinel.conf: | dir "/data" @@ -59,6 +63,7 @@ data: sentinel failover-timeout argocd 180000 maxclients 10000 sentinel parallel-syncs argocd 5 + sentinel auth-pass argocd replace-default-auth init.sh: | echo "$(date) Start..." @@ -82,7 +87,7 @@ data: sentinel_get_master() { set +e if [ "$SENTINEL_PORT" -eq 0 ]; then - redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ + redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ grep -E '((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?s*$))' else redis-cli -h "${SERVICE}" -p "${SENTINEL_PORT}" sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ @@ -191,9 +196,9 @@ data: redis_ping() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - redis-cli -h "${MASTER}" -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping else - redis-cli -h "${MASTER}" -p "${REDIS_PORT}" ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" ping fi set -e } @@ -226,7 +231,7 @@ data: if [ "$SENTINEL_PORT" -eq 0 ]; then echo " on sentinel (${SERVICE}:${SENTINEL_TLS_PORT}), sentinel grp (${MASTER_GROUP})" - if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then + if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then echo " $(date) Failover returned with 'NOGOODSLAVE'" echo "Setting defaults for this pod.." setup_defaults @@ -345,7 +350,7 @@ data: sentinel_get_master() { set +e if [ "$SENTINEL_PORT" -eq 0 ]; then - redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ + redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ grep -E '((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?s*$))' else redis-cli -h "${SERVICE}" -p "${SENTINEL_PORT}" sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ @@ -454,9 +459,9 @@ data: redis_ping() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - redis-cli -h "${MASTER}" -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping else - redis-cli -h "${MASTER}" -p "${REDIS_PORT}" ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" ping fi set -e } @@ -489,7 +494,7 @@ data: if [ "$SENTINEL_PORT" -eq 0 ]; then echo " on sentinel (${SERVICE}:${SENTINEL_TLS_PORT}), sentinel grp (${MASTER_GROUP})" - if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then + if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then echo " $(date) Failover returned with 'NOGOODSLAVE'" echo "Setting defaults for this pod.." setup_defaults @@ -554,19 +559,19 @@ data: redis_role() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - ROLE=$(redis-cli -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep role | sed 's/role://' | sed 's/\r//') + ROLE=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep role | sed 's/role://' | sed 's/\r//') else - ROLE=$(redis-cli -p "${REDIS_PORT}" info | grep role | sed 's/role://' | sed 's/\r//') + ROLE=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" info | grep role | sed 's/role://' | sed 's/\r//') fi set -e } identify_redis_master() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - REDIS_MASTER=$(redis-cli -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep master_host | sed 's/master_host://' | sed 's/\r//') + REDIS_MASTER=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep master_host | sed 's/master_host://' | sed 's/\r//') else - REDIS_MASTER=$(redis-cli -p "${REDIS_PORT}" info | grep master_host | sed 's/master_host://' | sed 's/\r//') + REDIS_MASTER=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" info | grep master_host | sed 's/master_host://' | sed 's/\r//') fi set -e } @@ -576,9 +581,9 @@ data: sh /readonly-config/init.sh if [ "$REDIS_PORT" -eq 0 ]; then - echo "shutdown" | redis-cli -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key + echo "shutdown" | redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key else - echo "shutdown" | redis-cli -p "${REDIS_PORT}" + echo "shutdown" | redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" fi set -e } @@ -591,6 +596,7 @@ data: identify_announce_ip done + trap "exit 0" TERM while true; do sleep 60 @@ -674,6 +680,8 @@ data: mode tcp option tcp-check tcp-check connect + tcp-check send "AUTH ${AUTH}"\r\n + tcp-check expect string +OK tcp-check send PING\r\n tcp-check expect string +PONG tcp-check send info\ replication\r\n @@ -723,6 +731,7 @@ data: get_redis_role() { is_master=$( redis-cli \ + -a "${AUTH}" --no-auth-warning \ -h localhost \ -p 6379 \ info | grep -c 'role:master' || true @@ -759,12 +768,13 @@ metadata: labels: heritage: Helm release: argocd - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 app: argocd-redis-ha data: redis_liveness.sh: | response=$( redis-cli \ + -a "${AUTH}" --no-auth-warning \ -h localhost \ -p 6379 \ ping @@ -777,6 +787,7 @@ data: redis_readiness.sh: | response=$( redis-cli \ + -a "${AUTH}" --no-auth-warning \ -h localhost \ -p 6379 \ ping @@ -809,7 +820,7 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 rules: - apiGroups: - "" @@ -828,7 +839,7 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 component: argocd-redis-ha-haproxy rules: - apiGroups: @@ -848,7 +859,7 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 subjects: - kind: ServiceAccount name: argocd-redis-ha @@ -867,7 +878,7 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 component: argocd-redis-ha-haproxy subjects: - kind: ServiceAccount @@ -887,9 +898,8 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 annotations: - service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" spec: publishNotReadyAddresses: true type: ClusterIP @@ -917,9 +927,8 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 annotations: - service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" spec: publishNotReadyAddresses: true type: ClusterIP @@ -947,9 +956,8 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 annotations: - service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" spec: publishNotReadyAddresses: true type: ClusterIP @@ -977,7 +985,7 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 annotations: spec: type: ClusterIP @@ -1005,7 +1013,7 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 component: argocd-redis-ha-haproxy annotations: spec: @@ -1029,7 +1037,7 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 spec: strategy: type: RollingUpdate @@ -1045,9 +1053,11 @@ spec: labels: app: redis-ha-haproxy release: argocd - revision: "1" annotations: - checksum/config: 718bbb277da8610063a7c0fd810984577c2e8ab215815a71211dfa6e20f67321 + prometheus.io/port: "9101" + prometheus.io/scrape: "true" + prometheus.io/path: "/metrics" + checksum/config: e34e8124c38bcfd2f16e75620bbde30158686692b13bc449eecc44c51b207d54 spec: # Needed when using unmodified rbac-setup.yml @@ -1067,11 +1077,10 @@ spec: matchLabels: app: redis-ha-haproxy release: argocd - revision: "1" topologyKey: kubernetes.io/hostname initContainers: - name: config-init - image: haproxy:2.6.14-alpine + image: public.ecr.aws/docker/library/haproxy:2.6.14-alpine imagePullPolicy: IfNotPresent resources: {} @@ -1095,7 +1104,7 @@ spec: mountPath: /data containers: - name: haproxy - image: haproxy:2.6.14-alpine + image: public.ecr.aws/docker/library/haproxy:2.6.14-alpine imagePullPolicy: IfNotPresent securityContext: allowPrivilegeEscalation: false @@ -1105,6 +1114,12 @@ spec: runAsNonRoot: true seccompProfile: type: RuntimeDefault + env: + - name: AUTH + valueFrom: + secretKeyRef: + name: argocd-redis + key: auth livenessProbe: httpGet: path: /healthz @@ -1151,7 +1166,7 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 annotations: {} spec: @@ -1167,7 +1182,7 @@ spec: template: metadata: annotations: - checksum/init-config: 69130412bda04eacad3530cb7bcf26cf121401e725e15d0959dd71a7380afe75 + checksum/init-config: 9d3c019a5ea1fd98ab5cde397d8eecd351da884f15e6ba346c607cb2446c2198 labels: release: argocd app: redis-ha @@ -1191,7 +1206,7 @@ spec: automountServiceAccountToken: false initContainers: - name: config-init - image: redis:7.0.15-alpine + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent resources: {} @@ -1215,6 +1230,11 @@ spec: value: 40000915ab58c3fa8fd888fb8b24711944e6cbb4 - name: SENTINEL_ID_2 value: 2bbec7894d954a8af3bb54d13eaec53cb024e2ca + - name: AUTH + valueFrom: + secretKeyRef: + name: argocd-redis + key: auth volumeMounts: - name: config mountPath: /readonly-config @@ -1225,12 +1245,12 @@ spec: containers: - name: redis - image: redis:7.0.15-alpine + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent command: - - redis-server + - redis-server args: - - /data/conf/redis.conf + - /data/conf/redis.conf securityContext: allowPrivilegeEscalation: false capabilities: @@ -1240,6 +1260,12 @@ spec: runAsUser: 1000 seccompProfile: type: RuntimeDefault + env: + - name: AUTH + valueFrom: + secretKeyRef: + name: argocd-redis + key: auth livenessProbe: initialDelaySeconds: 30 periodSeconds: 15 @@ -1282,7 +1308,7 @@ spec: - /bin/sh - /readonly-config/trigger-failover-if-master.sh - name: sentinel - image: redis:7.0.15-alpine + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent command: - redis-sentinel @@ -1297,6 +1323,12 @@ spec: runAsUser: 1000 seccompProfile: type: RuntimeDefault + env: + - name: AUTH + valueFrom: + secretKeyRef: + name: argocd-redis + key: auth livenessProbe: initialDelaySeconds: 30 periodSeconds: 15 @@ -1333,7 +1365,7 @@ spec: {} - name: split-brain-fix - image: redis:7.0.15-alpine + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent command: - sh @@ -1355,6 +1387,11 @@ spec: value: 40000915ab58c3fa8fd888fb8b24711944e6cbb4 - name: SENTINEL_ID_2 value: 2bbec7894d954a8af3bb54d13eaec53cb024e2ca + - name: AUTH + valueFrom: + secretKeyRef: + name: argocd-redis + key: auth resources: {} volumeMounts:
manifests/ha/base/redis-ha/chart/values.yaml+3 −0 modified@@ -1,4 +1,7 @@ redis-ha: + auth: true + authKey: auth + existingSecret: argocd-redis persistentVolume: enabled: false redis:
manifests/ha/base/redis-ha/kustomization.yaml+17 −5 modified@@ -20,7 +20,7 @@ patches: kind: ConfigMap name: argocd-redis-ha-configmap namespace: argocd - path: overlays/remove-namespace.yaml + path: overlays/remove-namespace.yaml - target: version: v1 group: "" @@ -34,28 +34,28 @@ patches: kind: ServiceAccount name: argocd-redis-ha-haproxy namespace: argocd - path: overlays/remove-namespace.yaml + path: overlays/remove-namespace.yaml - target: group: rbac.authorization.k8s.io version: v1 kind: Role name: argocd-redis-ha namespace: argocd - path: overlays/remove-namespace.yaml + path: overlays/remove-namespace.yaml - target: group: rbac.authorization.k8s.io version: v1 kind: Role name: argocd-redis-ha-haproxy namespace: argocd - path: overlays/remove-namespace.yaml + path: overlays/remove-namespace.yaml - target: group: rbac.authorization.k8s.io version: v1 kind: RoleBinding name: argocd-redis-ha namespace: argocd - path: overlays/remove-namespace.yaml + path: overlays/remove-namespace.yaml - target: group: rbac.authorization.k8s.io version: v1 @@ -294,3 +294,15 @@ patches: kind: StatefulSet name: argocd-redis-ha-server path: overlays/statefulset-containers-securityContext.yaml +- target: + group: rbac.authorization.k8s.io + version: v1 + kind: Role + name: argocd-redis-ha-haproxy + path: overlays/haproxy-role.yaml +- target: + group: apps + version: v1 + kind: Deployment + name: argocd-redis-ha-haproxy + path: overlays/deployment-initContainers.yaml \ No newline at end of file
manifests/ha/base/redis-ha/overlays/deployment-initContainers.yaml+16 −0 added@@ -0,0 +1,16 @@ +- op: add + path: /spec/template/spec/initContainers/0 + value: + name: secret-init + command: [ 'argocd', 'admin', 'redis-initial-password' ] + image: quay.io/argoproj/argocd:latest + imagePullPolicy: IfNotPresent + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault \ No newline at end of file
manifests/ha/base/redis-ha/overlays/haproxy-role.yaml+20 −0 added@@ -0,0 +1,20 @@ +- op: add + path: /rules/0 + value: + apiGroups: + - "" + resources: + - secrets + resourceNames: + - argocd-redis + verbs: + - get +- op: add + path: /rules/0 + value: + apiGroups: + - "" + resources: + - secrets + verbs: + - create \ No newline at end of file
manifests/ha/install.yaml+111 −31 modified@@ -18426,6 +18426,8 @@ metadata: app.kubernetes.io/name: argocd-redis-ha app.kubernetes.io/part-of: argocd name: argocd-redis-ha +secrets: +- name: argocd-redis --- apiVersion: v1 kind: ServiceAccount @@ -18648,6 +18650,20 @@ metadata: app.kubernetes.io/part-of: argocd name: argocd-redis-ha-haproxy rules: +- apiGroups: + - "" + resources: + - secrets + verbs: + - create +- apiGroups: + - "" + resourceNames: + - argocd-redis + resources: + - secrets + verbs: + - get - apiGroups: - "" resources: @@ -18985,7 +19001,7 @@ data: sentinel_get_master() { set +e if [ "$SENTINEL_PORT" -eq 0 ]; then - redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ + redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ grep -E '((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?s*$))' else redis-cli -h "${SERVICE}" -p "${SENTINEL_PORT}" sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ @@ -19094,9 +19110,9 @@ data: redis_ping() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - redis-cli -h "${MASTER}" -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping else - redis-cli -h "${MASTER}" -p "${REDIS_PORT}" ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" ping fi set -e } @@ -19129,7 +19145,7 @@ data: if [ "$SENTINEL_PORT" -eq 0 ]; then echo " on sentinel (${SERVICE}:${SENTINEL_TLS_PORT}), sentinel grp (${MASTER_GROUP})" - if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then + if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then echo " $(date) Failover returned with 'NOGOODSLAVE'" echo "Setting defaults for this pod.." setup_defaults @@ -19194,19 +19210,19 @@ data: redis_role() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - ROLE=$(redis-cli -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep role | sed 's/role://' | sed 's/\r//') + ROLE=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep role | sed 's/role://' | sed 's/\r//') else - ROLE=$(redis-cli -p "${REDIS_PORT}" info | grep role | sed 's/role://' | sed 's/\r//') + ROLE=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" info | grep role | sed 's/role://' | sed 's/\r//') fi set -e } identify_redis_master() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - REDIS_MASTER=$(redis-cli -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep master_host | sed 's/master_host://' | sed 's/\r//') + REDIS_MASTER=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep master_host | sed 's/master_host://' | sed 's/\r//') else - REDIS_MASTER=$(redis-cli -p "${REDIS_PORT}" info | grep master_host | sed 's/master_host://' | sed 's/\r//') + REDIS_MASTER=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" info | grep master_host | sed 's/master_host://' | sed 's/\r//') fi set -e } @@ -19216,9 +19232,9 @@ data: sh /readonly-config/init.sh if [ "$REDIS_PORT" -eq 0 ]; then - echo "shutdown" | redis-cli -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key + echo "shutdown" | redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key else - echo "shutdown" | redis-cli -p "${REDIS_PORT}" + echo "shutdown" | redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" fi set -e } @@ -19231,6 +19247,7 @@ data: identify_announce_ip done + trap "exit 0" TERM while true; do sleep 60 @@ -19273,9 +19290,10 @@ data: decide redis backend to use\n#master\nfrontend ft_redis_master\n bind :6379 \n \ use_backend bk_redis_master\n# Check all redis servers to see if they think they are master\nbackend bk_redis_master\n mode tcp\n option tcp-check\n tcp-check - connect\n tcp-check send PING\\r\\n\n tcp-check expect string +PONG\n tcp-check - send info\\ replication\\r\\n\n tcp-check expect string role:master\n tcp-check - send QUIT\\r\\n\n tcp-check expect string +OK\n use-server R0 if { srv_is_up(R0) + connect\n tcp-check send \"AUTH ${AUTH}\"\\r\\n\n tcp-check expect string +OK\n + \ tcp-check send PING\\r\\n\n tcp-check expect string +PONG\n tcp-check send + info\\ replication\\r\\n\n tcp-check expect string role:master\n tcp-check send + QUIT\\r\\n\n tcp-check expect string +OK\n use-server R0 if { srv_is_up(R0) } { nbsrv(check_if_redis_is_master_0) ge 2 }\n server R0 argocd-redis-ha-announce-0:6379 check inter 3s fall 1 rise 1\n use-server R1 if { srv_is_up(R1) } { nbsrv(check_if_redis_is_master_1) ge 2 }\n server R1 argocd-redis-ha-announce-1:6379 check inter 3s fall 1 rise @@ -19336,7 +19354,7 @@ data: sentinel_get_master() { set +e if [ "$SENTINEL_PORT" -eq 0 ]; then - redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ + redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ grep -E '((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?s*$))' else redis-cli -h "${SERVICE}" -p "${SENTINEL_PORT}" sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ @@ -19445,9 +19463,9 @@ data: redis_ping() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - redis-cli -h "${MASTER}" -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping else - redis-cli -h "${MASTER}" -p "${REDIS_PORT}" ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" ping fi set -e } @@ -19480,7 +19498,7 @@ data: if [ "$SENTINEL_PORT" -eq 0 ]; then echo " on sentinel (${SERVICE}:${SENTINEL_TLS_PORT}), sentinel grp (${MASTER_GROUP})" - if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then + if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then echo " $(date) Failover returned with 'NOGOODSLAVE'" echo "Setting defaults for this pod.." setup_defaults @@ -19588,6 +19606,8 @@ data: rdbcompression yes repl-diskless-sync yes save "" + requirepass replace-default-auth + masterauth replace-default-auth sentinel.conf: | dir "/data" port 26379 @@ -19596,10 +19616,12 @@ data: sentinel failover-timeout argocd 180000 maxclients 10000 sentinel parallel-syncs argocd 5 + sentinel auth-pass argocd replace-default-auth trigger-failover-if-master.sh: | get_redis_role() { is_master=$( redis-cli \ + -a "${AUTH}" --no-auth-warning \ -h localhost \ -p 6379 \ info | grep -c 'role:master' || true @@ -19639,6 +19661,7 @@ data: redis_liveness.sh: | response=$( redis-cli \ + -a "${AUTH}" --no-auth-warning \ -h localhost \ -p 6379 \ ping @@ -19651,6 +19674,7 @@ data: redis_readiness.sh: | response=$( redis-cli \ + -a "${AUTH}" --no-auth-warning \ -h localhost \ -p 6379 \ ping @@ -19838,8 +19862,6 @@ spec: apiVersion: v1 kind: Service metadata: - annotations: - service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" labels: app.kubernetes.io/component: redis app.kubernetes.io/name: argocd-redis-ha @@ -19864,8 +19886,6 @@ spec: apiVersion: v1 kind: Service metadata: - annotations: - service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" labels: app.kubernetes.io/component: redis app.kubernetes.io/name: argocd-redis-ha @@ -19890,8 +19910,6 @@ spec: apiVersion: v1 kind: Service metadata: - annotations: - service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" labels: app.kubernetes.io/component: redis app.kubernetes.io/name: argocd-redis-ha @@ -20380,7 +20398,10 @@ spec: template: metadata: annotations: - checksum/config: 718bbb277da8610063a7c0fd810984577c2e8ab215815a71211dfa6e20f67321 + checksum/config: e34e8124c38bcfd2f16e75620bbde30158686692b13bc449eecc44c51b207d54 + prometheus.io/path: /metrics + prometheus.io/port: "9101" + prometheus.io/scrape: "true" labels: app.kubernetes.io/name: argocd-redis-ha-haproxy name: argocd-redis-ha-haproxy @@ -20393,7 +20414,13 @@ spec: app.kubernetes.io/name: argocd-redis-ha-haproxy topologyKey: kubernetes.io/hostname containers: - - image: haproxy:2.6.14-alpine + - env: + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/haproxy:2.6.14-alpine imagePullPolicy: IfNotPresent lifecycle: {} livenessProbe: @@ -20426,11 +20453,27 @@ spec: - mountPath: /run/haproxy name: shared-socket initContainers: + - command: + - argocd + - admin + - redis-initial-password + image: quay.io/argoproj/argocd:latest + imagePullPolicy: IfNotPresent + name: secret-init + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault - args: - /readonly/haproxy_init.sh command: - sh - image: haproxy:2.6.14-alpine + image: public.ecr.aws/docker/library/haproxy:2.6.14-alpine imagePullPolicy: IfNotPresent name: config-init securityContext: @@ -20498,6 +20541,11 @@ spec: - args: - /usr/local/bin/argocd-repo-server env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_RECONCILIATION_TIMEOUT valueFrom: configMapKeyRef: @@ -20785,6 +20833,11 @@ spec: env: - name: ARGOCD_API_SERVER_REPLICAS value: "2" + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_SERVER_INSECURE valueFrom: configMapKeyRef: @@ -21107,6 +21160,11 @@ spec: - args: - /usr/local/bin/argocd-application-controller env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_CONTROLLER_REPLICAS value: "1" - name: ARGOCD_RECONCILIATION_TIMEOUT @@ -21307,7 +21365,7 @@ spec: template: metadata: annotations: - checksum/init-config: 69130412bda04eacad3530cb7bcf26cf121401e725e15d0959dd71a7380afe75 + checksum/init-config: 9d3c019a5ea1fd98ab5cde397d8eecd351da884f15e6ba346c607cb2446c2198 labels: app.kubernetes.io/name: argocd-redis-ha spec: @@ -21324,7 +21382,13 @@ spec: - /data/conf/redis.conf command: - redis-server - image: redis:7.0.15-alpine + env: + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent lifecycle: preStop: @@ -21378,7 +21442,13 @@ spec: - /data/conf/sentinel.conf command: - redis-sentinel - image: redis:7.0.15-alpine + env: + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent lifecycle: {} livenessProbe: @@ -21431,7 +21501,12 @@ spec: value: 40000915ab58c3fa8fd888fb8b24711944e6cbb4 - name: SENTINEL_ID_2 value: 2bbec7894d954a8af3bb54d13eaec53cb024e2ca - image: redis:7.0.15-alpine + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent name: split-brain-fix resources: {} @@ -21461,7 +21536,12 @@ spec: value: 40000915ab58c3fa8fd888fb8b24711944e6cbb4 - name: SENTINEL_ID_2 value: 2bbec7894d954a8af3bb54d13eaec53cb024e2ca - image: redis:7.0.15-alpine + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent name: config-init securityContext:
manifests/ha/namespace-install.yaml+111 −31 modified@@ -43,6 +43,8 @@ metadata: app.kubernetes.io/name: argocd-redis-ha app.kubernetes.io/part-of: argocd name: argocd-redis-ha +secrets: +- name: argocd-redis --- apiVersion: v1 kind: ServiceAccount @@ -265,6 +267,20 @@ metadata: app.kubernetes.io/part-of: argocd name: argocd-redis-ha-haproxy rules: +- apiGroups: + - "" + resources: + - secrets + verbs: + - create +- apiGroups: + - "" + resourceNames: + - argocd-redis + resources: + - secrets + verbs: + - get - apiGroups: - "" resources: @@ -497,7 +513,7 @@ data: sentinel_get_master() { set +e if [ "$SENTINEL_PORT" -eq 0 ]; then - redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ + redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ grep -E '((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?s*$))' else redis-cli -h "${SERVICE}" -p "${SENTINEL_PORT}" sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ @@ -606,9 +622,9 @@ data: redis_ping() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - redis-cli -h "${MASTER}" -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping else - redis-cli -h "${MASTER}" -p "${REDIS_PORT}" ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" ping fi set -e } @@ -641,7 +657,7 @@ data: if [ "$SENTINEL_PORT" -eq 0 ]; then echo " on sentinel (${SERVICE}:${SENTINEL_TLS_PORT}), sentinel grp (${MASTER_GROUP})" - if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then + if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then echo " $(date) Failover returned with 'NOGOODSLAVE'" echo "Setting defaults for this pod.." setup_defaults @@ -706,19 +722,19 @@ data: redis_role() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - ROLE=$(redis-cli -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep role | sed 's/role://' | sed 's/\r//') + ROLE=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep role | sed 's/role://' | sed 's/\r//') else - ROLE=$(redis-cli -p "${REDIS_PORT}" info | grep role | sed 's/role://' | sed 's/\r//') + ROLE=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" info | grep role | sed 's/role://' | sed 's/\r//') fi set -e } identify_redis_master() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - REDIS_MASTER=$(redis-cli -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep master_host | sed 's/master_host://' | sed 's/\r//') + REDIS_MASTER=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep master_host | sed 's/master_host://' | sed 's/\r//') else - REDIS_MASTER=$(redis-cli -p "${REDIS_PORT}" info | grep master_host | sed 's/master_host://' | sed 's/\r//') + REDIS_MASTER=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" info | grep master_host | sed 's/master_host://' | sed 's/\r//') fi set -e } @@ -728,9 +744,9 @@ data: sh /readonly-config/init.sh if [ "$REDIS_PORT" -eq 0 ]; then - echo "shutdown" | redis-cli -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key + echo "shutdown" | redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key else - echo "shutdown" | redis-cli -p "${REDIS_PORT}" + echo "shutdown" | redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" fi set -e } @@ -743,6 +759,7 @@ data: identify_announce_ip done + trap "exit 0" TERM while true; do sleep 60 @@ -785,9 +802,10 @@ data: decide redis backend to use\n#master\nfrontend ft_redis_master\n bind :6379 \n \ use_backend bk_redis_master\n# Check all redis servers to see if they think they are master\nbackend bk_redis_master\n mode tcp\n option tcp-check\n tcp-check - connect\n tcp-check send PING\\r\\n\n tcp-check expect string +PONG\n tcp-check - send info\\ replication\\r\\n\n tcp-check expect string role:master\n tcp-check - send QUIT\\r\\n\n tcp-check expect string +OK\n use-server R0 if { srv_is_up(R0) + connect\n tcp-check send \"AUTH ${AUTH}\"\\r\\n\n tcp-check expect string +OK\n + \ tcp-check send PING\\r\\n\n tcp-check expect string +PONG\n tcp-check send + info\\ replication\\r\\n\n tcp-check expect string role:master\n tcp-check send + QUIT\\r\\n\n tcp-check expect string +OK\n use-server R0 if { srv_is_up(R0) } { nbsrv(check_if_redis_is_master_0) ge 2 }\n server R0 argocd-redis-ha-announce-0:6379 check inter 3s fall 1 rise 1\n use-server R1 if { srv_is_up(R1) } { nbsrv(check_if_redis_is_master_1) ge 2 }\n server R1 argocd-redis-ha-announce-1:6379 check inter 3s fall 1 rise @@ -848,7 +866,7 @@ data: sentinel_get_master() { set +e if [ "$SENTINEL_PORT" -eq 0 ]; then - redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ + redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ grep -E '((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?s*$))' else redis-cli -h "${SERVICE}" -p "${SENTINEL_PORT}" sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ @@ -957,9 +975,9 @@ data: redis_ping() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - redis-cli -h "${MASTER}" -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping else - redis-cli -h "${MASTER}" -p "${REDIS_PORT}" ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" ping fi set -e } @@ -992,7 +1010,7 @@ data: if [ "$SENTINEL_PORT" -eq 0 ]; then echo " on sentinel (${SERVICE}:${SENTINEL_TLS_PORT}), sentinel grp (${MASTER_GROUP})" - if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then + if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then echo " $(date) Failover returned with 'NOGOODSLAVE'" echo "Setting defaults for this pod.." setup_defaults @@ -1100,6 +1118,8 @@ data: rdbcompression yes repl-diskless-sync yes save "" + requirepass replace-default-auth + masterauth replace-default-auth sentinel.conf: | dir "/data" port 26379 @@ -1108,10 +1128,12 @@ data: sentinel failover-timeout argocd 180000 maxclients 10000 sentinel parallel-syncs argocd 5 + sentinel auth-pass argocd replace-default-auth trigger-failover-if-master.sh: | get_redis_role() { is_master=$( redis-cli \ + -a "${AUTH}" --no-auth-warning \ -h localhost \ -p 6379 \ info | grep -c 'role:master' || true @@ -1151,6 +1173,7 @@ data: redis_liveness.sh: | response=$( redis-cli \ + -a "${AUTH}" --no-auth-warning \ -h localhost \ -p 6379 \ ping @@ -1163,6 +1186,7 @@ data: redis_readiness.sh: | response=$( redis-cli \ + -a "${AUTH}" --no-auth-warning \ -h localhost \ -p 6379 \ ping @@ -1350,8 +1374,6 @@ spec: apiVersion: v1 kind: Service metadata: - annotations: - service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" labels: app.kubernetes.io/component: redis app.kubernetes.io/name: argocd-redis-ha @@ -1376,8 +1398,6 @@ spec: apiVersion: v1 kind: Service metadata: - annotations: - service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" labels: app.kubernetes.io/component: redis app.kubernetes.io/name: argocd-redis-ha @@ -1402,8 +1422,6 @@ spec: apiVersion: v1 kind: Service metadata: - annotations: - service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" labels: app.kubernetes.io/component: redis app.kubernetes.io/name: argocd-redis-ha @@ -1892,7 +1910,10 @@ spec: template: metadata: annotations: - checksum/config: 718bbb277da8610063a7c0fd810984577c2e8ab215815a71211dfa6e20f67321 + checksum/config: e34e8124c38bcfd2f16e75620bbde30158686692b13bc449eecc44c51b207d54 + prometheus.io/path: /metrics + prometheus.io/port: "9101" + prometheus.io/scrape: "true" labels: app.kubernetes.io/name: argocd-redis-ha-haproxy name: argocd-redis-ha-haproxy @@ -1905,7 +1926,13 @@ spec: app.kubernetes.io/name: argocd-redis-ha-haproxy topologyKey: kubernetes.io/hostname containers: - - image: haproxy:2.6.14-alpine + - env: + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/haproxy:2.6.14-alpine imagePullPolicy: IfNotPresent lifecycle: {} livenessProbe: @@ -1938,11 +1965,27 @@ spec: - mountPath: /run/haproxy name: shared-socket initContainers: + - command: + - argocd + - admin + - redis-initial-password + image: quay.io/argoproj/argocd:latest + imagePullPolicy: IfNotPresent + name: secret-init + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault - args: - /readonly/haproxy_init.sh command: - sh - image: haproxy:2.6.14-alpine + image: public.ecr.aws/docker/library/haproxy:2.6.14-alpine imagePullPolicy: IfNotPresent name: config-init securityContext: @@ -2010,6 +2053,11 @@ spec: - args: - /usr/local/bin/argocd-repo-server env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_RECONCILIATION_TIMEOUT valueFrom: configMapKeyRef: @@ -2297,6 +2345,11 @@ spec: env: - name: ARGOCD_API_SERVER_REPLICAS value: "2" + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_SERVER_INSECURE valueFrom: configMapKeyRef: @@ -2619,6 +2672,11 @@ spec: - args: - /usr/local/bin/argocd-application-controller env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_CONTROLLER_REPLICAS value: "1" - name: ARGOCD_RECONCILIATION_TIMEOUT @@ -2819,7 +2877,7 @@ spec: template: metadata: annotations: - checksum/init-config: 69130412bda04eacad3530cb7bcf26cf121401e725e15d0959dd71a7380afe75 + checksum/init-config: 9d3c019a5ea1fd98ab5cde397d8eecd351da884f15e6ba346c607cb2446c2198 labels: app.kubernetes.io/name: argocd-redis-ha spec: @@ -2836,7 +2894,13 @@ spec: - /data/conf/redis.conf command: - redis-server - image: redis:7.0.15-alpine + env: + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent lifecycle: preStop: @@ -2890,7 +2954,13 @@ spec: - /data/conf/sentinel.conf command: - redis-sentinel - image: redis:7.0.15-alpine + env: + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent lifecycle: {} livenessProbe: @@ -2943,7 +3013,12 @@ spec: value: 40000915ab58c3fa8fd888fb8b24711944e6cbb4 - name: SENTINEL_ID_2 value: 2bbec7894d954a8af3bb54d13eaec53cb024e2ca - image: redis:7.0.15-alpine + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent name: split-brain-fix resources: {} @@ -2973,7 +3048,12 @@ spec: value: 40000915ab58c3fa8fd888fb8b24711944e6cbb4 - name: SENTINEL_ID_2 value: 2bbec7894d954a8af3bb54d13eaec53cb024e2ca - image: redis:7.0.15-alpine + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent name: config-init securityContext:
manifests/install.yaml+79 −0 modified@@ -18616,6 +18616,30 @@ rules: --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +rules: +- apiGroups: + - "" + resourceNames: + - argocd-redis + resources: + - secrets + verbs: + - get +- apiGroups: + - "" + resources: + - secrets + verbs: + - create +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role metadata: labels: app.kubernetes.io/component: server @@ -18795,6 +18819,22 @@ subjects: --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: argocd-redis +subjects: +- kind: ServiceAccount + name: argocd-redis +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding metadata: labels: app.kubernetes.io/component: server @@ -19500,6 +19540,13 @@ spec: - "" - --appendonly - "no" + - --requirepass $(REDIS_PASSWORD) + env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis image: redis:7.0.15-alpine imagePullPolicy: Always name: redis @@ -19511,6 +19558,23 @@ spec: drop: - ALL readOnlyRootFilesystem: true + initContainers: + - command: + - argocd + - admin + - redis-initial-password + image: quay.io/argoproj/argocd:latest + imagePullPolicy: IfNotPresent + name: secret-init + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault securityContext: runAsNonRoot: true runAsUser: 999 @@ -19555,6 +19619,11 @@ spec: - args: - /usr/local/bin/argocd-repo-server env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_RECONCILIATION_TIMEOUT valueFrom: configMapKeyRef: @@ -19840,6 +19909,11 @@ spec: - args: - /usr/local/bin/argocd-server env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_SERVER_INSECURE valueFrom: configMapKeyRef: @@ -20162,6 +20236,11 @@ spec: - args: - /usr/local/bin/argocd-application-controller env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_CONTROLLER_REPLICAS value: "1" - name: ARGOCD_RECONCILIATION_TIMEOUT
manifests/namespace-install.yaml+79 −0 modified@@ -233,6 +233,30 @@ rules: --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +rules: +- apiGroups: + - "" + resourceNames: + - argocd-redis + resources: + - secrets + verbs: + - get +- apiGroups: + - "" + resources: + - secrets + verbs: + - create +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role metadata: labels: app.kubernetes.io/component: server @@ -341,6 +365,22 @@ subjects: --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: argocd-redis +subjects: +- kind: ServiceAccount + name: argocd-redis +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding metadata: labels: app.kubernetes.io/component: server @@ -1012,6 +1052,13 @@ spec: - "" - --appendonly - "no" + - --requirepass $(REDIS_PASSWORD) + env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis image: redis:7.0.15-alpine imagePullPolicy: Always name: redis @@ -1023,6 +1070,23 @@ spec: drop: - ALL readOnlyRootFilesystem: true + initContainers: + - command: + - argocd + - admin + - redis-initial-password + image: quay.io/argoproj/argocd:latest + imagePullPolicy: IfNotPresent + name: secret-init + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault securityContext: runAsNonRoot: true runAsUser: 999 @@ -1067,6 +1131,11 @@ spec: - args: - /usr/local/bin/argocd-repo-server env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_RECONCILIATION_TIMEOUT valueFrom: configMapKeyRef: @@ -1352,6 +1421,11 @@ spec: - args: - /usr/local/bin/argocd-server env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_SERVER_INSECURE valueFrom: configMapKeyRef: @@ -1674,6 +1748,11 @@ spec: - args: - /usr/local/bin/argocd-application-controller env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_CONTROLLER_REPLICAS value: "1" - name: ARGOCD_RECONCILIATION_TIMEOUT
reposerver/repository/repository_test.go+1 −1 modified@@ -159,7 +159,7 @@ func TestGenerateYamlManifestInDir(t *testing.T) { } // update this value if we add/remove manifests - const countOfManifests = 48 + const countOfManifests = 50 res1, err := service.GenerateManifest(context.Background(), &q)
f1a449e83ee7Merge pull request from GHSA-9766-5277-j5hr
27 files changed · +886 −119
cmd/argocd/commands/admin/admin.go+1 −0 modified@@ -66,6 +66,7 @@ $ argocd admin initial-password reset command.AddCommand(NewDashboardCommand(clientOpts)) command.AddCommand(NewNotificationsCommand()) command.AddCommand(NewInitialPasswordCommand()) + command.AddCommand(NewRedisInitialPasswordCommand()) command.Flags().StringVar(&cmdutil.LogFormat, "logformat", "text", "Set the logging format. One of: text|json") command.Flags().StringVar(&cmdutil.LogLevel, "loglevel", "info", "Set the logging level. One of: debug|info|warn|error")
cmd/argocd/commands/admin/redis_initial_password.go+98 −0 added@@ -0,0 +1,98 @@ +package admin + +import ( + "context" + "crypto/rand" + "fmt" + "math/big" + + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/cli" + apierr "k8s.io/apimachinery/pkg/api/errors" + + "github.com/argoproj/argo-cd/v2/util/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/tools/clientcmd" + + "github.com/spf13/cobra" + corev1 "k8s.io/api/core/v1" +) + +const defaulRedisInitialPasswordSecretName = "argocd-redis" +const defaultResisInitialPasswordKey = "auth" + +func generateRandomPassword() (string, error) { + const initialPasswordLength = 16 + const letters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-" + randBytes := make([]byte, initialPasswordLength) + for i := 0; i < initialPasswordLength; i++ { + num, err := rand.Int(rand.Reader, big.NewInt(int64(len(letters)))) + if err != nil { + return "", err + } + randBytes[i] = letters[num.Int64()] + } + initialPassword := string(randBytes) + return initialPassword, nil +} + +// NewRedisInitialPasswordCommand defines a new command to ensure Argo CD Redis password secret exists. +func NewRedisInitialPasswordCommand() *cobra.Command { + var ( + clientConfig clientcmd.ClientConfig + ) + var command = cobra.Command{ + Use: "redis-initial-password", + Short: "Ensure the Redis password exists, creating a new one if necessary.", + Run: func(c *cobra.Command, args []string) { + namespace, _, err := clientConfig.Namespace() + errors.CheckError(err) + + redisInitialPasswordSecretName := defaulRedisInitialPasswordSecretName + redisInitialPasswordKey := defaultResisInitialPasswordKey + fmt.Printf("Checking for initial Redis password in secret %s/%s at key %s. \n", namespace, redisInitialPasswordSecretName, redisInitialPasswordKey) + + config, err := clientConfig.ClientConfig() + errors.CheckError(err) + errors.CheckError(v1alpha1.SetK8SConfigDefaults(config)) + + kubeClientset := kubernetes.NewForConfigOrDie(config) + + randomPassword, err := generateRandomPassword() + errors.CheckError(err) + + data := map[string][]byte{ + redisInitialPasswordKey: []byte(randomPassword), + } + secret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: redisInitialPasswordSecretName, + Namespace: namespace, + }, + Data: data, + Type: corev1.SecretTypeOpaque, + } + _, err = kubeClientset.CoreV1().Secrets(namespace).Create(context.Background(), secret, metav1.CreateOptions{}) + if err != nil && !apierr.IsAlreadyExists(err) { + errors.CheckError(err) + } + + fmt.Println("Argo CD Redis secret state confirmed: secret name argocd-redis.") + secret, err = kubeClientset.CoreV1().Secrets(namespace).Get(context.Background(), redisInitialPasswordSecretName, v1.GetOptions{}) + errors.CheckError(err) + + if _, ok := secret.Data[redisInitialPasswordKey]; ok { + fmt.Println("Password secret is configured properly.") + } else { + err := fmt.Errorf("key %s doesn't exist in secret %s. \n", redisInitialPasswordKey, redisInitialPasswordSecretName) + errors.CheckError(err) + } + }, + } + + clientConfig = cli.AddKubectlFlagsToCmd(&command) + + return &command +}
docs/faq.md+42 −0 modified@@ -268,3 +268,45 @@ The most common instance of this error is with `env:` fields for `containers`. !!! note "Dynamic applications" It's possible that your application is being generated by a tool in which case the duplication might not be evident within the scope of a single file. If you have trouble debugging this problem, consider filing a ticket to the owner of the generator tool asking them to improve its validation and error reporting. + +## How to rotate Redis secret? +* Delete `argocd-redis` secret in the namespace where Argo CD is installed. +```bash +kubectl delete secret argocd-redis -n <argocd namesapce> +``` +* If you are running Redis in HA mode, restart Redis in HA. +```bash +kubectl rollout restart deployment argocd-redis-ha-haproxy +kubectl rollout restart statefulset argocd-redis-ha-server +``` +* If you are running Redis in non-HA mode, restart Redis. +```bash +kubectl rollout restart deployment argocd-redis +``` +* Restart other components. +```bash +kubectl rollout restart deployment argocd-server argocd-repo-server +kubectl rollout restart statefulset argocd-application-controller +``` + +## How to turn off Redis auth if users really want to? + +Argo CD default installation is now configured automatically enable Redis authentication. +If for some reason authenticated Redis does not work for you and you want to use non-authenticated Redis, here are the steps: + +* You need to have your own Redis installation. +* Configure Argo CD to use your own Redis instance. See this [doc](https://argo-cd.readthedocs.io/en/stable/operator-manual/argocd-cmd-params-cm-yaml/) for the Argo CD configuration. +* If you already installed Redis shipped with Argo CD, you also need to clean up the existing components: + * When HA Redis is used: + * kubectl delete deployment argocd-redis-ha-haproxy + * kubectl delete statefulset argocd-redis-ha-server + * When non-HA Redis is used: + * kubectl delete deployment argocd-redis +* Remove environment variable `REDIS_PASSWORD` from the following manifests + * Deployment: argocd-repo-server: + * Deployment: argocd-server + * StatefulSet: argocd-application-controller + +## How do I provide my own Redis credentials? +The Redis password is stored in Kubernetes secret `argocd-redis` with key `auth` in the namespace where Argo CD is installed. +You can config your secret provider to generate Kubernetes secret accordingly. \ No newline at end of file
docs/getting_started.md+3 −0 modified@@ -40,6 +40,9 @@ Do one of: Use `argocd login --core` to [configure](./user-guide/commands/argocd_login.md) CLI access and skip steps 3-5. +!!! note + This default installation for Redis is using password authentication. The Redis password is stored in Kubernetes secret `argocd-redis` with key `auth` in the namespace where Argo CD is installed. + ## 2. Download Argo CD CLI Download the latest Argo CD version from [https://github.com/argoproj/argo-cd/releases/latest](https://github.com/argoproj/argo-cd/releases/latest). More detailed installation instructions can be found via the [CLI installation documentation](cli_installation.md).
docs/user-guide/commands/argocd_admin.md+1 −0 modified@@ -64,6 +64,7 @@ $ argocd admin initial-password reset * [argocd admin initial-password](argocd_admin_initial-password.md) - Prints initial password to log in to Argo CD for the first time * [argocd admin notifications](argocd_admin_notifications.md) - Set of CLI commands that helps manage notifications settings * [argocd admin proj](argocd_admin_proj.md) - Manage projects configuration +* [argocd admin redis-initial-password](argocd_admin_redis-initial-password.md) - Ensure the Redis password exists, creating a new one if necessary. * [argocd admin repo](argocd_admin_repo.md) - Manage repositories configuration * [argocd admin settings](argocd_admin_settings.md) - Provides set of commands for settings validation and troubleshooting
docs/user-guide/commands/argocd_admin_redis-initial-password.md+67 −0 added@@ -0,0 +1,67 @@ +# `argocd admin redis-initial-password` Command Reference + +## argocd admin redis-initial-password + +Ensure the Redis password exists, creating a new one if necessary. + +``` +argocd admin redis-initial-password [flags] +``` + +### Options + +``` + --as string Username to impersonate for the operation + --as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --as-uid string UID to impersonate for the operation + --certificate-authority string Path to a cert file for the certificate authority + --client-certificate string Path to a client certificate file for TLS + --client-key string Path to a client key file for TLS + --cluster string The name of the kubeconfig cluster to use + --context string The name of the kubeconfig context to use + --disable-compression If true, opt-out of response compression for all requests to the server + -h, --help help for redis-initial-password + --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kubeconfig string Path to a kube config. Only required if out-of-cluster + -n, --namespace string If present, the namespace scope for this CLI request + --password string Password for basic authentication to the API server + --proxy-url string If provided, this URL will be used to connect via proxy + --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") + --server string The address and port of the Kubernetes API server + --tls-server-name string If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used. + --token string Bearer token for authentication to the API server + --user string The name of the kubeconfig user to use + --username string Username for basic authentication to the API server +``` + +### Options inherited from parent commands + +``` + --auth-token string Authentication token + --client-crt string Client certificate file + --client-crt-key string Client certificate key file + --config string Path to Argo CD config (default "/home/user/.config/argocd/config") + --controller-name string Name of the Argo CD Application controller; set this or the ARGOCD_APPLICATION_CONTROLLER_NAME environment variable when the controller's name label differs from the default, for example when installing via the Helm chart (default "argocd-application-controller") + --core If set to true then CLI talks directly to Kubernetes instead of talking to Argo CD API server + --grpc-web Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. + --grpc-web-root-path string Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. Set web root. + -H, --header strings Sets additional header to all requests made by Argo CD CLI. (Can be repeated multiple times to add multiple headers, also supports comma separated headers) + --http-retry-max int Maximum number of retries to establish http connection to Argo CD server + --insecure Skip server certificate and domain verification + --kube-context string Directs the command to the given kube-context + --logformat string Set the logging format. One of: text|json (default "text") + --loglevel string Set the logging level. One of: debug|info|warn|error (default "info") + --plaintext Disable TLS + --port-forward Connect to a random argocd-server port using port forwarding + --port-forward-namespace string Namespace name which should be used for port forwarding + --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") + --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") + --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") + --server-crt string Server certificate file + --server-name string Name of the Argo CD API server; set this or the ARGOCD_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-server") +``` + +### SEE ALSO + +* [argocd admin](argocd_admin.md) - Contains a set of commands useful for Argo CD administrators and requires direct Kubernetes access +
manifests/base/application-controller/argocd-application-controller-statefulset.yaml+5 −0 modified@@ -21,6 +21,11 @@ spec: - args: - /usr/local/bin/argocd-application-controller env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_CONTROLLER_REPLICAS value: "1" - name: ARGOCD_RECONCILIATION_TIMEOUT
manifests/base/application-controller-deployment/argocd-application-controller-deployment.yaml+5 −0 modified@@ -20,6 +20,11 @@ spec: - args: - /usr/local/bin/argocd-application-controller env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_RECONCILIATION_TIMEOUT valueFrom: configMapKeyRef:
manifests/base/redis/argocd-redis-deployment.yaml+24 −0 modified@@ -15,6 +15,23 @@ spec: labels: app.kubernetes.io/name: argocd-redis spec: + initContainers: + - command: + - argocd + - admin + - redis-initial-password + image: quay.io/argoproj/argocd:latest + imagePullPolicy: IfNotPresent + name: secret-init + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault securityContext: runAsNonRoot: true runAsUser: 999 @@ -30,6 +47,13 @@ spec: - "" - "--appendonly" - "no" + - --requirepass $(REDIS_PASSWORD) + env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis ports: - containerPort: 6379 securityContext:
manifests/base/redis/argocd-redis-rolebinding.yaml+15 −0 added@@ -0,0 +1,15 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: argocd-redis +subjects: + - kind: ServiceAccount + name: argocd-redis \ No newline at end of file
manifests/base/redis/argocd-redis-role.yaml+23 −0 added@@ -0,0 +1,23 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +rules: + - apiGroups: + - "" + resources: + - secrets + resourceNames: + - argocd-redis + verbs: + - get + - apiGroups: + - "" + resources: + - secrets + verbs: + - create \ No newline at end of file
manifests/base/redis/kustomization.yaml+2 −0 modified@@ -6,3 +6,5 @@ resources: - argocd-redis-sa.yaml - argocd-redis-service.yaml - argocd-redis-network-policy.yaml +- argocd-redis-role.yaml +- argocd-redis-rolebinding.yaml
manifests/base/repo-server/argocd-repo-server-deployment.yaml+5 −0 modified@@ -24,6 +24,11 @@ spec: args: - /usr/local/bin/argocd-repo-server env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_RECONCILIATION_TIMEOUT valueFrom: configMapKeyRef:
manifests/base/server/argocd-server-deployment.yaml+5 −0 modified@@ -23,6 +23,11 @@ spec: args: - /usr/local/bin/argocd-server env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_SERVER_INSECURE valueFrom: configMapKeyRef:
manifests/core-install.yaml+75 −1 modified@@ -20816,6 +20816,30 @@ rules: - watch --- apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +rules: +- apiGroups: + - "" + resourceNames: + - argocd-redis + resources: + - secrets + verbs: + - get +- apiGroups: + - "" + resources: + - secrets + verbs: + - create +--- +apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: labels: @@ -20868,6 +20892,22 @@ subjects: name: argocd-applicationset-controller --- apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: argocd-redis +subjects: +- kind: ServiceAccount + name: argocd-redis +--- +apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: labels: @@ -21279,7 +21319,14 @@ spec: - "" - --appendonly - "no" - image: redis:7.0.14-alpine + - --requirepass $(REDIS_PASSWORD) + env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: redis:7.0.15-alpine imagePullPolicy: Always name: redis ports: @@ -21290,6 +21337,23 @@ spec: drop: - ALL readOnlyRootFilesystem: true + initContainers: + - command: + - argocd + - admin + - redis-initial-password + image: quay.io/argoproj/argocd:latest + imagePullPolicy: IfNotPresent + name: secret-init + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault securityContext: runAsNonRoot: true runAsUser: 999 @@ -21334,6 +21398,11 @@ spec: - args: - /usr/local/bin/argocd-repo-server env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_RECONCILIATION_TIMEOUT valueFrom: configMapKeyRef: @@ -21651,6 +21720,11 @@ spec: - args: - /usr/local/bin/argocd-application-controller env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_CONTROLLER_REPLICAS value: "1" - name: ARGOCD_RECONCILIATION_TIMEOUT
manifests/ha/base/redis-ha/chart/requirements.lock+3 −3 modified@@ -1,6 +1,6 @@ dependencies: - name: redis-ha repository: https://dandydeveloper.github.io/charts - version: 4.22.3 -digest: sha256:ae773caf65b172bdd2216072c03ba76ef3c0383dbd1e2478934a67b9455f6a2e -generated: "2022-11-02T16:57:25.047025473-07:00" + version: 4.26.6 +digest: sha256:c363f48ea8339c4bdb7c8a2cca62aa487b69d0a52a6fe6267fbbbbc07e468abd +generated: "2024-04-10T11:02:32.957812-07:00"
manifests/ha/base/redis-ha/chart/requirements.yaml+1 −1 modified@@ -1,4 +1,4 @@ dependencies: - name: redis-ha - version: 4.22.3 + version: 4.26.6 repository: https://dandydeveloper.github.io/charts
manifests/ha/base/redis-ha/chart/upstream.yaml+78 −44 modified@@ -9,8 +9,10 @@ metadata: labels: heritage: Helm release: argocd - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 app: argocd-redis-ha +secrets: +- name: argocd-redis --- # Source: redis-ha/charts/redis-ha/templates/redis-haproxy-serviceaccount.yaml apiVersion: v1 @@ -21,7 +23,7 @@ metadata: labels: heritage: Helm release: argocd - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 app: argocd-redis-ha --- # Source: redis-ha/charts/redis-ha/templates/redis-ha-configmap.yaml @@ -33,7 +35,7 @@ metadata: labels: heritage: Helm release: argocd - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 app: argocd-redis-ha data: redis.conf: | @@ -50,6 +52,8 @@ data: rdbcompression yes repl-diskless-sync yes save "" + requirepass replace-default-auth + masterauth replace-default-auth sentinel.conf: | dir "/data" @@ -59,6 +63,7 @@ data: sentinel failover-timeout argocd 180000 maxclients 10000 sentinel parallel-syncs argocd 5 + sentinel auth-pass argocd replace-default-auth init.sh: | echo "$(date) Start..." @@ -82,7 +87,7 @@ data: sentinel_get_master() { set +e if [ "$SENTINEL_PORT" -eq 0 ]; then - redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ + redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ grep -E '((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?s*$))' else redis-cli -h "${SERVICE}" -p "${SENTINEL_PORT}" sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ @@ -191,9 +196,9 @@ data: redis_ping() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - redis-cli -h "${MASTER}" -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping else - redis-cli -h "${MASTER}" -p "${REDIS_PORT}" ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" ping fi set -e } @@ -226,7 +231,7 @@ data: if [ "$SENTINEL_PORT" -eq 0 ]; then echo " on sentinel (${SERVICE}:${SENTINEL_TLS_PORT}), sentinel grp (${MASTER_GROUP})" - if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then + if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then echo " $(date) Failover returned with 'NOGOODSLAVE'" echo "Setting defaults for this pod.." setup_defaults @@ -345,7 +350,7 @@ data: sentinel_get_master() { set +e if [ "$SENTINEL_PORT" -eq 0 ]; then - redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ + redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ grep -E '((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?s*$))' else redis-cli -h "${SERVICE}" -p "${SENTINEL_PORT}" sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ @@ -454,9 +459,9 @@ data: redis_ping() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - redis-cli -h "${MASTER}" -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping else - redis-cli -h "${MASTER}" -p "${REDIS_PORT}" ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" ping fi set -e } @@ -489,7 +494,7 @@ data: if [ "$SENTINEL_PORT" -eq 0 ]; then echo " on sentinel (${SERVICE}:${SENTINEL_TLS_PORT}), sentinel grp (${MASTER_GROUP})" - if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then + if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then echo " $(date) Failover returned with 'NOGOODSLAVE'" echo "Setting defaults for this pod.." setup_defaults @@ -554,19 +559,19 @@ data: redis_role() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - ROLE=$(redis-cli -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep role | sed 's/role://' | sed 's/\r//') + ROLE=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep role | sed 's/role://' | sed 's/\r//') else - ROLE=$(redis-cli -p "${REDIS_PORT}" info | grep role | sed 's/role://' | sed 's/\r//') + ROLE=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" info | grep role | sed 's/role://' | sed 's/\r//') fi set -e } identify_redis_master() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - REDIS_MASTER=$(redis-cli -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep master_host | sed 's/master_host://' | sed 's/\r//') + REDIS_MASTER=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep master_host | sed 's/master_host://' | sed 's/\r//') else - REDIS_MASTER=$(redis-cli -p "${REDIS_PORT}" info | grep master_host | sed 's/master_host://' | sed 's/\r//') + REDIS_MASTER=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" info | grep master_host | sed 's/master_host://' | sed 's/\r//') fi set -e } @@ -576,9 +581,9 @@ data: sh /readonly-config/init.sh if [ "$REDIS_PORT" -eq 0 ]; then - echo "shutdown" | redis-cli -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key + echo "shutdown" | redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key else - echo "shutdown" | redis-cli -p "${REDIS_PORT}" + echo "shutdown" | redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" fi set -e } @@ -591,6 +596,7 @@ data: identify_announce_ip done + trap "exit 0" TERM while true; do sleep 60 @@ -674,6 +680,8 @@ data: mode tcp option tcp-check tcp-check connect + tcp-check send "AUTH ${AUTH}"\r\n + tcp-check expect string +OK tcp-check send PING\r\n tcp-check expect string +PONG tcp-check send info\ replication\r\n @@ -730,6 +738,7 @@ data: get_redis_role() { is_master=$( redis-cli \ + -a "${AUTH}" --no-auth-warning \ -h localhost \ -p 6379 \ info | grep -c 'role:master' || true @@ -766,12 +775,13 @@ metadata: labels: heritage: Helm release: argocd - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 app: argocd-redis-ha data: redis_liveness.sh: | response=$( redis-cli \ + -a "${AUTH}" --no-auth-warning \ -h localhost \ -p 6379 \ ping @@ -784,6 +794,7 @@ data: redis_readiness.sh: | response=$( redis-cli \ + -a "${AUTH}" --no-auth-warning \ -h localhost \ -p 6379 \ ping @@ -816,7 +827,7 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 rules: - apiGroups: - "" @@ -835,7 +846,7 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 component: argocd-redis-ha-haproxy rules: - apiGroups: @@ -855,7 +866,7 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 subjects: - kind: ServiceAccount name: argocd-redis-ha @@ -874,7 +885,7 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 component: argocd-redis-ha-haproxy subjects: - kind: ServiceAccount @@ -894,9 +905,8 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 annotations: - service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" spec: publishNotReadyAddresses: true type: ClusterIP @@ -924,9 +934,8 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 annotations: - service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" spec: publishNotReadyAddresses: true type: ClusterIP @@ -954,9 +963,8 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 annotations: - service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" spec: publishNotReadyAddresses: true type: ClusterIP @@ -984,7 +992,7 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 annotations: spec: type: ClusterIP @@ -1012,7 +1020,7 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 component: argocd-redis-ha-haproxy annotations: spec: @@ -1040,7 +1048,7 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 spec: strategy: type: RollingUpdate @@ -1056,12 +1064,11 @@ spec: labels: app: redis-ha-haproxy release: argocd - revision: "1" annotations: prometheus.io/port: "9101" prometheus.io/scrape: "true" prometheus.io/path: "/metrics" - checksum/config: 492a6adabb741e0cee39be9aa5155c41a4456629f862d0006a2d892dbecfbcae + checksum/config: e34e8124c38bcfd2f16e75620bbde30158686692b13bc449eecc44c51b207d54 spec: # Needed when using unmodified rbac-setup.yml @@ -1081,11 +1088,10 @@ spec: matchLabels: app: redis-ha-haproxy release: argocd - revision: "1" topologyKey: kubernetes.io/hostname initContainers: - name: config-init - image: haproxy:2.6.14-alpine + image: public.ecr.aws/docker/library/haproxy:2.6.14-alpine imagePullPolicy: IfNotPresent resources: {} @@ -1109,7 +1115,7 @@ spec: mountPath: /data containers: - name: haproxy - image: haproxy:2.6.14-alpine + image: public.ecr.aws/docker/library/haproxy:2.6.14-alpine imagePullPolicy: IfNotPresent securityContext: allowPrivilegeEscalation: false @@ -1119,6 +1125,12 @@ spec: runAsNonRoot: true seccompProfile: type: RuntimeDefault + env: + - name: AUTH + valueFrom: + secretKeyRef: + name: argocd-redis + key: auth livenessProbe: httpGet: path: /healthz @@ -1167,7 +1179,7 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 annotations: {} spec: @@ -1183,7 +1195,7 @@ spec: template: metadata: annotations: - checksum/init-config: 69130412bda04eacad3530cb7bcf26cf121401e725e15d0959dd71a7380afe75 + checksum/init-config: 9d3c019a5ea1fd98ab5cde397d8eecd351da884f15e6ba346c607cb2446c2198 labels: release: argocd app: redis-ha @@ -1207,7 +1219,7 @@ spec: automountServiceAccountToken: false initContainers: - name: config-init - image: redis:7.0.14-alpine + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent resources: {} @@ -1231,6 +1243,11 @@ spec: value: 40000915ab58c3fa8fd888fb8b24711944e6cbb4 - name: SENTINEL_ID_2 value: 2bbec7894d954a8af3bb54d13eaec53cb024e2ca + - name: AUTH + valueFrom: + secretKeyRef: + name: argocd-redis + key: auth volumeMounts: - name: config mountPath: /readonly-config @@ -1241,12 +1258,12 @@ spec: containers: - name: redis - image: redis:7.0.14-alpine + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent command: - - redis-server + - redis-server args: - - /data/conf/redis.conf + - /data/conf/redis.conf securityContext: allowPrivilegeEscalation: false capabilities: @@ -1256,6 +1273,12 @@ spec: runAsUser: 1000 seccompProfile: type: RuntimeDefault + env: + - name: AUTH + valueFrom: + secretKeyRef: + name: argocd-redis + key: auth livenessProbe: initialDelaySeconds: 30 periodSeconds: 15 @@ -1298,7 +1321,7 @@ spec: - /bin/sh - /readonly-config/trigger-failover-if-master.sh - name: sentinel - image: redis:7.0.14-alpine + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent command: - redis-sentinel @@ -1313,6 +1336,12 @@ spec: runAsUser: 1000 seccompProfile: type: RuntimeDefault + env: + - name: AUTH + valueFrom: + secretKeyRef: + name: argocd-redis + key: auth livenessProbe: initialDelaySeconds: 30 periodSeconds: 15 @@ -1349,7 +1378,7 @@ spec: {} - name: split-brain-fix - image: redis:7.0.14-alpine + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent command: - sh @@ -1371,6 +1400,11 @@ spec: value: 40000915ab58c3fa8fd888fb8b24711944e6cbb4 - name: SENTINEL_ID_2 value: 2bbec7894d954a8af3bb54d13eaec53cb024e2ca + - name: AUTH + valueFrom: + secretKeyRef: + name: argocd-redis + key: auth resources: {} volumeMounts:
manifests/ha/base/redis-ha/chart/values.yaml+3 −0 modified@@ -1,4 +1,7 @@ redis-ha: + auth: true + authKey: auth + existingSecret: argocd-redis persistentVolume: enabled: false redis:
manifests/ha/base/redis-ha/kustomization.yaml+17 −5 modified@@ -20,7 +20,7 @@ patches: kind: ConfigMap name: argocd-redis-ha-configmap namespace: argocd - path: overlays/remove-namespace.yaml + path: overlays/remove-namespace.yaml - target: version: v1 group: "" @@ -34,28 +34,28 @@ patches: kind: ServiceAccount name: argocd-redis-ha-haproxy namespace: argocd - path: overlays/remove-namespace.yaml + path: overlays/remove-namespace.yaml - target: group: rbac.authorization.k8s.io version: v1 kind: Role name: argocd-redis-ha namespace: argocd - path: overlays/remove-namespace.yaml + path: overlays/remove-namespace.yaml - target: group: rbac.authorization.k8s.io version: v1 kind: Role name: argocd-redis-ha-haproxy namespace: argocd - path: overlays/remove-namespace.yaml + path: overlays/remove-namespace.yaml - target: group: rbac.authorization.k8s.io version: v1 kind: RoleBinding name: argocd-redis-ha namespace: argocd - path: overlays/remove-namespace.yaml + path: overlays/remove-namespace.yaml - target: group: rbac.authorization.k8s.io version: v1 @@ -294,3 +294,15 @@ patches: kind: StatefulSet name: argocd-redis-ha-server path: overlays/statefulset-containers-securityContext.yaml +- target: + group: rbac.authorization.k8s.io + version: v1 + kind: Role + name: argocd-redis-ha-haproxy + path: overlays/haproxy-role.yaml +- target: + group: apps + version: v1 + kind: Deployment + name: argocd-redis-ha-haproxy + path: overlays/deployment-initContainers.yaml \ No newline at end of file
manifests/ha/base/redis-ha/overlays/deployment-initContainers.yaml+16 −0 added@@ -0,0 +1,16 @@ +- op: add + path: /spec/template/spec/initContainers/0 + value: + name: secret-init + command: [ 'argocd', 'admin', 'redis-initial-password' ] + image: quay.io/argoproj/argocd:latest + imagePullPolicy: IfNotPresent + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault \ No newline at end of file
manifests/ha/base/redis-ha/overlays/haproxy-role.yaml+20 −0 added@@ -0,0 +1,20 @@ +- op: add + path: /rules/0 + value: + apiGroups: + - "" + resources: + - secrets + resourceNames: + - argocd-redis + verbs: + - get +- op: add + path: /rules/0 + value: + apiGroups: + - "" + resources: + - secrets + verbs: + - create \ No newline at end of file
manifests/ha/install.yaml+108 −31 modified@@ -20710,6 +20710,8 @@ metadata: app.kubernetes.io/name: argocd-redis-ha app.kubernetes.io/part-of: argocd name: argocd-redis-ha +secrets: +- name: argocd-redis --- apiVersion: v1 kind: ServiceAccount @@ -20940,6 +20942,20 @@ metadata: app.kubernetes.io/part-of: argocd name: argocd-redis-ha-haproxy rules: +- apiGroups: + - "" + resources: + - secrets + verbs: + - create +- apiGroups: + - "" + resourceNames: + - argocd-redis + resources: + - secrets + verbs: + - get - apiGroups: - "" resources: @@ -21384,7 +21400,7 @@ data: sentinel_get_master() { set +e if [ "$SENTINEL_PORT" -eq 0 ]; then - redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ + redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ grep -E '((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?s*$))' else redis-cli -h "${SERVICE}" -p "${SENTINEL_PORT}" sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ @@ -21493,9 +21509,9 @@ data: redis_ping() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - redis-cli -h "${MASTER}" -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping else - redis-cli -h "${MASTER}" -p "${REDIS_PORT}" ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" ping fi set -e } @@ -21528,7 +21544,7 @@ data: if [ "$SENTINEL_PORT" -eq 0 ]; then echo " on sentinel (${SERVICE}:${SENTINEL_TLS_PORT}), sentinel grp (${MASTER_GROUP})" - if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then + if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then echo " $(date) Failover returned with 'NOGOODSLAVE'" echo "Setting defaults for this pod.." setup_defaults @@ -21593,19 +21609,19 @@ data: redis_role() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - ROLE=$(redis-cli -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep role | sed 's/role://' | sed 's/\r//') + ROLE=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep role | sed 's/role://' | sed 's/\r//') else - ROLE=$(redis-cli -p "${REDIS_PORT}" info | grep role | sed 's/role://' | sed 's/\r//') + ROLE=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" info | grep role | sed 's/role://' | sed 's/\r//') fi set -e } identify_redis_master() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - REDIS_MASTER=$(redis-cli -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep master_host | sed 's/master_host://' | sed 's/\r//') + REDIS_MASTER=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep master_host | sed 's/master_host://' | sed 's/\r//') else - REDIS_MASTER=$(redis-cli -p "${REDIS_PORT}" info | grep master_host | sed 's/master_host://' | sed 's/\r//') + REDIS_MASTER=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" info | grep master_host | sed 's/master_host://' | sed 's/\r//') fi set -e } @@ -21615,9 +21631,9 @@ data: sh /readonly-config/init.sh if [ "$REDIS_PORT" -eq 0 ]; then - echo "shutdown" | redis-cli -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key + echo "shutdown" | redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key else - echo "shutdown" | redis-cli -p "${REDIS_PORT}" + echo "shutdown" | redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" fi set -e } @@ -21630,6 +21646,7 @@ data: identify_announce_ip done + trap "exit 0" TERM while true; do sleep 60 @@ -21672,9 +21689,10 @@ data: decide redis backend to use\n#master\nfrontend ft_redis_master\n bind :6379 \n \ use_backend bk_redis_master\n# Check all redis servers to see if they think they are master\nbackend bk_redis_master\n mode tcp\n option tcp-check\n tcp-check - connect\n tcp-check send PING\\r\\n\n tcp-check expect string +PONG\n tcp-check - send info\\ replication\\r\\n\n tcp-check expect string role:master\n tcp-check - send QUIT\\r\\n\n tcp-check expect string +OK\n use-server R0 if { srv_is_up(R0) + connect\n tcp-check send \"AUTH ${AUTH}\"\\r\\n\n tcp-check expect string +OK\n + \ tcp-check send PING\\r\\n\n tcp-check expect string +PONG\n tcp-check send + info\\ replication\\r\\n\n tcp-check expect string role:master\n tcp-check send + QUIT\\r\\n\n tcp-check expect string +OK\n use-server R0 if { srv_is_up(R0) } { nbsrv(check_if_redis_is_master_0) ge 2 }\n server R0 argocd-redis-ha-announce-0:6379 check inter 3s fall 1 rise 1\n use-server R1 if { srv_is_up(R1) } { nbsrv(check_if_redis_is_master_1) ge 2 }\n server R1 argocd-redis-ha-announce-1:6379 check inter 3s fall 1 rise @@ -21737,7 +21755,7 @@ data: sentinel_get_master() { set +e if [ "$SENTINEL_PORT" -eq 0 ]; then - redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ + redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ grep -E '((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?s*$))' else redis-cli -h "${SERVICE}" -p "${SENTINEL_PORT}" sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ @@ -21846,9 +21864,9 @@ data: redis_ping() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - redis-cli -h "${MASTER}" -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping else - redis-cli -h "${MASTER}" -p "${REDIS_PORT}" ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" ping fi set -e } @@ -21881,7 +21899,7 @@ data: if [ "$SENTINEL_PORT" -eq 0 ]; then echo " on sentinel (${SERVICE}:${SENTINEL_TLS_PORT}), sentinel grp (${MASTER_GROUP})" - if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then + if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then echo " $(date) Failover returned with 'NOGOODSLAVE'" echo "Setting defaults for this pod.." setup_defaults @@ -21989,6 +22007,8 @@ data: rdbcompression yes repl-diskless-sync yes save "" + requirepass replace-default-auth + masterauth replace-default-auth sentinel.conf: | dir "/data" port 26379 @@ -21997,10 +22017,12 @@ data: sentinel failover-timeout argocd 180000 maxclients 10000 sentinel parallel-syncs argocd 5 + sentinel auth-pass argocd replace-default-auth trigger-failover-if-master.sh: | get_redis_role() { is_master=$( redis-cli \ + -a "${AUTH}" --no-auth-warning \ -h localhost \ -p 6379 \ info | grep -c 'role:master' || true @@ -22040,6 +22062,7 @@ data: redis_liveness.sh: | response=$( redis-cli \ + -a "${AUTH}" --no-auth-warning \ -h localhost \ -p 6379 \ ping @@ -22052,6 +22075,7 @@ data: redis_readiness.sh: | response=$( redis-cli \ + -a "${AUTH}" --no-auth-warning \ -h localhost \ -p 6379 \ ping @@ -22240,8 +22264,6 @@ spec: apiVersion: v1 kind: Service metadata: - annotations: - service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" labels: app.kubernetes.io/component: redis app.kubernetes.io/name: argocd-redis-ha @@ -22266,8 +22288,6 @@ spec: apiVersion: v1 kind: Service metadata: - annotations: - service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" labels: app.kubernetes.io/component: redis app.kubernetes.io/name: argocd-redis-ha @@ -22292,8 +22312,6 @@ spec: apiVersion: v1 kind: Service metadata: - annotations: - service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" labels: app.kubernetes.io/component: redis app.kubernetes.io/name: argocd-redis-ha @@ -22810,7 +22828,7 @@ spec: template: metadata: annotations: - checksum/config: 492a6adabb741e0cee39be9aa5155c41a4456629f862d0006a2d892dbecfbcae + checksum/config: e34e8124c38bcfd2f16e75620bbde30158686692b13bc449eecc44c51b207d54 prometheus.io/path: /metrics prometheus.io/port: "9101" prometheus.io/scrape: "true" @@ -22826,7 +22844,13 @@ spec: app.kubernetes.io/name: argocd-redis-ha-haproxy topologyKey: kubernetes.io/hostname containers: - - image: haproxy:2.6.14-alpine + - env: + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/haproxy:2.6.14-alpine imagePullPolicy: IfNotPresent lifecycle: {} livenessProbe: @@ -22861,11 +22885,27 @@ spec: - mountPath: /run/haproxy name: shared-socket initContainers: + - command: + - argocd + - admin + - redis-initial-password + image: quay.io/argoproj/argocd:latest + imagePullPolicy: IfNotPresent + name: secret-init + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault - args: - /readonly/haproxy_init.sh command: - sh - image: haproxy:2.6.14-alpine + image: public.ecr.aws/docker/library/haproxy:2.6.14-alpine imagePullPolicy: IfNotPresent name: config-init securityContext: @@ -22933,6 +22973,11 @@ spec: - args: - /usr/local/bin/argocd-repo-server env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_RECONCILIATION_TIMEOUT valueFrom: configMapKeyRef: @@ -23250,6 +23295,11 @@ spec: env: - name: ARGOCD_API_SERVER_REPLICAS value: "2" + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_SERVER_INSECURE valueFrom: configMapKeyRef: @@ -23596,6 +23646,11 @@ spec: - args: - /usr/local/bin/argocd-application-controller env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_CONTROLLER_REPLICAS value: "1" - name: ARGOCD_RECONCILIATION_TIMEOUT @@ -23838,7 +23893,7 @@ spec: template: metadata: annotations: - checksum/init-config: 69130412bda04eacad3530cb7bcf26cf121401e725e15d0959dd71a7380afe75 + checksum/init-config: 9d3c019a5ea1fd98ab5cde397d8eecd351da884f15e6ba346c607cb2446c2198 labels: app.kubernetes.io/name: argocd-redis-ha spec: @@ -23855,7 +23910,13 @@ spec: - /data/conf/redis.conf command: - redis-server - image: redis:7.0.14-alpine + env: + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent lifecycle: preStop: @@ -23909,7 +23970,13 @@ spec: - /data/conf/sentinel.conf command: - redis-sentinel - image: redis:7.0.14-alpine + env: + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent lifecycle: {} livenessProbe: @@ -23962,7 +24029,12 @@ spec: value: 40000915ab58c3fa8fd888fb8b24711944e6cbb4 - name: SENTINEL_ID_2 value: 2bbec7894d954a8af3bb54d13eaec53cb024e2ca - image: redis:7.0.14-alpine + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent name: split-brain-fix resources: {} @@ -23992,7 +24064,12 @@ spec: value: 40000915ab58c3fa8fd888fb8b24711944e6cbb4 - name: SENTINEL_ID_2 value: 2bbec7894d954a8af3bb54d13eaec53cb024e2ca - image: redis:7.0.14-alpine + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent name: config-init securityContext:
manifests/ha/namespace-install.yaml+108 −31 modified@@ -43,6 +43,8 @@ metadata: app.kubernetes.io/name: argocd-redis-ha app.kubernetes.io/part-of: argocd name: argocd-redis-ha +secrets: +- name: argocd-redis --- apiVersion: v1 kind: ServiceAccount @@ -273,6 +275,20 @@ metadata: app.kubernetes.io/part-of: argocd name: argocd-redis-ha-haproxy rules: +- apiGroups: + - "" + resources: + - secrets + verbs: + - create +- apiGroups: + - "" + resourceNames: + - argocd-redis + resources: + - secrets + verbs: + - get - apiGroups: - "" resources: @@ -505,7 +521,7 @@ data: sentinel_get_master() { set +e if [ "$SENTINEL_PORT" -eq 0 ]; then - redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ + redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ grep -E '((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?s*$))' else redis-cli -h "${SERVICE}" -p "${SENTINEL_PORT}" sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ @@ -614,9 +630,9 @@ data: redis_ping() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - redis-cli -h "${MASTER}" -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping else - redis-cli -h "${MASTER}" -p "${REDIS_PORT}" ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" ping fi set -e } @@ -649,7 +665,7 @@ data: if [ "$SENTINEL_PORT" -eq 0 ]; then echo " on sentinel (${SERVICE}:${SENTINEL_TLS_PORT}), sentinel grp (${MASTER_GROUP})" - if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then + if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then echo " $(date) Failover returned with 'NOGOODSLAVE'" echo "Setting defaults for this pod.." setup_defaults @@ -714,19 +730,19 @@ data: redis_role() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - ROLE=$(redis-cli -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep role | sed 's/role://' | sed 's/\r//') + ROLE=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep role | sed 's/role://' | sed 's/\r//') else - ROLE=$(redis-cli -p "${REDIS_PORT}" info | grep role | sed 's/role://' | sed 's/\r//') + ROLE=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" info | grep role | sed 's/role://' | sed 's/\r//') fi set -e } identify_redis_master() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - REDIS_MASTER=$(redis-cli -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep master_host | sed 's/master_host://' | sed 's/\r//') + REDIS_MASTER=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep master_host | sed 's/master_host://' | sed 's/\r//') else - REDIS_MASTER=$(redis-cli -p "${REDIS_PORT}" info | grep master_host | sed 's/master_host://' | sed 's/\r//') + REDIS_MASTER=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" info | grep master_host | sed 's/master_host://' | sed 's/\r//') fi set -e } @@ -736,9 +752,9 @@ data: sh /readonly-config/init.sh if [ "$REDIS_PORT" -eq 0 ]; then - echo "shutdown" | redis-cli -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key + echo "shutdown" | redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key else - echo "shutdown" | redis-cli -p "${REDIS_PORT}" + echo "shutdown" | redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" fi set -e } @@ -751,6 +767,7 @@ data: identify_announce_ip done + trap "exit 0" TERM while true; do sleep 60 @@ -793,9 +810,10 @@ data: decide redis backend to use\n#master\nfrontend ft_redis_master\n bind :6379 \n \ use_backend bk_redis_master\n# Check all redis servers to see if they think they are master\nbackend bk_redis_master\n mode tcp\n option tcp-check\n tcp-check - connect\n tcp-check send PING\\r\\n\n tcp-check expect string +PONG\n tcp-check - send info\\ replication\\r\\n\n tcp-check expect string role:master\n tcp-check - send QUIT\\r\\n\n tcp-check expect string +OK\n use-server R0 if { srv_is_up(R0) + connect\n tcp-check send \"AUTH ${AUTH}\"\\r\\n\n tcp-check expect string +OK\n + \ tcp-check send PING\\r\\n\n tcp-check expect string +PONG\n tcp-check send + info\\ replication\\r\\n\n tcp-check expect string role:master\n tcp-check send + QUIT\\r\\n\n tcp-check expect string +OK\n use-server R0 if { srv_is_up(R0) } { nbsrv(check_if_redis_is_master_0) ge 2 }\n server R0 argocd-redis-ha-announce-0:6379 check inter 3s fall 1 rise 1\n use-server R1 if { srv_is_up(R1) } { nbsrv(check_if_redis_is_master_1) ge 2 }\n server R1 argocd-redis-ha-announce-1:6379 check inter 3s fall 1 rise @@ -858,7 +876,7 @@ data: sentinel_get_master() { set +e if [ "$SENTINEL_PORT" -eq 0 ]; then - redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ + redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ grep -E '((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?s*$))' else redis-cli -h "${SERVICE}" -p "${SENTINEL_PORT}" sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ @@ -967,9 +985,9 @@ data: redis_ping() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - redis-cli -h "${MASTER}" -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping else - redis-cli -h "${MASTER}" -p "${REDIS_PORT}" ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" ping fi set -e } @@ -1002,7 +1020,7 @@ data: if [ "$SENTINEL_PORT" -eq 0 ]; then echo " on sentinel (${SERVICE}:${SENTINEL_TLS_PORT}), sentinel grp (${MASTER_GROUP})" - if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then + if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then echo " $(date) Failover returned with 'NOGOODSLAVE'" echo "Setting defaults for this pod.." setup_defaults @@ -1110,6 +1128,8 @@ data: rdbcompression yes repl-diskless-sync yes save "" + requirepass replace-default-auth + masterauth replace-default-auth sentinel.conf: | dir "/data" port 26379 @@ -1118,10 +1138,12 @@ data: sentinel failover-timeout argocd 180000 maxclients 10000 sentinel parallel-syncs argocd 5 + sentinel auth-pass argocd replace-default-auth trigger-failover-if-master.sh: | get_redis_role() { is_master=$( redis-cli \ + -a "${AUTH}" --no-auth-warning \ -h localhost \ -p 6379 \ info | grep -c 'role:master' || true @@ -1161,6 +1183,7 @@ data: redis_liveness.sh: | response=$( redis-cli \ + -a "${AUTH}" --no-auth-warning \ -h localhost \ -p 6379 \ ping @@ -1173,6 +1196,7 @@ data: redis_readiness.sh: | response=$( redis-cli \ + -a "${AUTH}" --no-auth-warning \ -h localhost \ -p 6379 \ ping @@ -1361,8 +1385,6 @@ spec: apiVersion: v1 kind: Service metadata: - annotations: - service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" labels: app.kubernetes.io/component: redis app.kubernetes.io/name: argocd-redis-ha @@ -1387,8 +1409,6 @@ spec: apiVersion: v1 kind: Service metadata: - annotations: - service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" labels: app.kubernetes.io/component: redis app.kubernetes.io/name: argocd-redis-ha @@ -1413,8 +1433,6 @@ spec: apiVersion: v1 kind: Service metadata: - annotations: - service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" labels: app.kubernetes.io/component: redis app.kubernetes.io/name: argocd-redis-ha @@ -1931,7 +1949,7 @@ spec: template: metadata: annotations: - checksum/config: 492a6adabb741e0cee39be9aa5155c41a4456629f862d0006a2d892dbecfbcae + checksum/config: e34e8124c38bcfd2f16e75620bbde30158686692b13bc449eecc44c51b207d54 prometheus.io/path: /metrics prometheus.io/port: "9101" prometheus.io/scrape: "true" @@ -1947,7 +1965,13 @@ spec: app.kubernetes.io/name: argocd-redis-ha-haproxy topologyKey: kubernetes.io/hostname containers: - - image: haproxy:2.6.14-alpine + - env: + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/haproxy:2.6.14-alpine imagePullPolicy: IfNotPresent lifecycle: {} livenessProbe: @@ -1982,11 +2006,27 @@ spec: - mountPath: /run/haproxy name: shared-socket initContainers: + - command: + - argocd + - admin + - redis-initial-password + image: quay.io/argoproj/argocd:latest + imagePullPolicy: IfNotPresent + name: secret-init + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault - args: - /readonly/haproxy_init.sh command: - sh - image: haproxy:2.6.14-alpine + image: public.ecr.aws/docker/library/haproxy:2.6.14-alpine imagePullPolicy: IfNotPresent name: config-init securityContext: @@ -2054,6 +2094,11 @@ spec: - args: - /usr/local/bin/argocd-repo-server env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_RECONCILIATION_TIMEOUT valueFrom: configMapKeyRef: @@ -2371,6 +2416,11 @@ spec: env: - name: ARGOCD_API_SERVER_REPLICAS value: "2" + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_SERVER_INSECURE valueFrom: configMapKeyRef: @@ -2717,6 +2767,11 @@ spec: - args: - /usr/local/bin/argocd-application-controller env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_CONTROLLER_REPLICAS value: "1" - name: ARGOCD_RECONCILIATION_TIMEOUT @@ -2959,7 +3014,7 @@ spec: template: metadata: annotations: - checksum/init-config: 69130412bda04eacad3530cb7bcf26cf121401e725e15d0959dd71a7380afe75 + checksum/init-config: 9d3c019a5ea1fd98ab5cde397d8eecd351da884f15e6ba346c607cb2446c2198 labels: app.kubernetes.io/name: argocd-redis-ha spec: @@ -2976,7 +3031,13 @@ spec: - /data/conf/redis.conf command: - redis-server - image: redis:7.0.14-alpine + env: + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent lifecycle: preStop: @@ -3030,7 +3091,13 @@ spec: - /data/conf/sentinel.conf command: - redis-sentinel - image: redis:7.0.14-alpine + env: + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent lifecycle: {} livenessProbe: @@ -3083,7 +3150,12 @@ spec: value: 40000915ab58c3fa8fd888fb8b24711944e6cbb4 - name: SENTINEL_ID_2 value: 2bbec7894d954a8af3bb54d13eaec53cb024e2ca - image: redis:7.0.14-alpine + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent name: split-brain-fix resources: {} @@ -3113,7 +3185,12 @@ spec: value: 40000915ab58c3fa8fd888fb8b24711944e6cbb4 - name: SENTINEL_ID_2 value: 2bbec7894d954a8af3bb54d13eaec53cb024e2ca - image: redis:7.0.14-alpine + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent name: config-init securityContext:
manifests/install.yaml+80 −1 modified@@ -20908,6 +20908,30 @@ rules: --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +rules: +- apiGroups: + - "" + resourceNames: + - argocd-redis + resources: + - secrets + verbs: + - get +- apiGroups: + - "" + resources: + - secrets + verbs: + - create +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role metadata: labels: app.kubernetes.io/component: server @@ -21177,6 +21201,22 @@ subjects: --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: argocd-redis +subjects: +- kind: ServiceAccount + name: argocd-redis +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding metadata: labels: app.kubernetes.io/component: server @@ -21924,7 +21964,14 @@ spec: - "" - --appendonly - "no" - image: redis:7.0.14-alpine + - --requirepass $(REDIS_PASSWORD) + env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: redis:7.0.15-alpine imagePullPolicy: Always name: redis ports: @@ -21935,6 +21982,23 @@ spec: drop: - ALL readOnlyRootFilesystem: true + initContainers: + - command: + - argocd + - admin + - redis-initial-password + image: quay.io/argoproj/argocd:latest + imagePullPolicy: IfNotPresent + name: secret-init + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault securityContext: runAsNonRoot: true runAsUser: 999 @@ -21979,6 +22043,11 @@ spec: - args: - /usr/local/bin/argocd-repo-server env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_RECONCILIATION_TIMEOUT valueFrom: configMapKeyRef: @@ -22294,6 +22363,11 @@ spec: - args: - /usr/local/bin/argocd-server env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_SERVER_INSECURE valueFrom: configMapKeyRef: @@ -22640,6 +22714,11 @@ spec: - args: - /usr/local/bin/argocd-application-controller env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_CONTROLLER_REPLICAS value: "1" - name: ARGOCD_RECONCILIATION_TIMEOUT
manifests/namespace-install.yaml+80 −1 modified@@ -241,6 +241,30 @@ rules: --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +rules: +- apiGroups: + - "" + resourceNames: + - argocd-redis + resources: + - secrets + verbs: + - get +- apiGroups: + - "" + resources: + - secrets + verbs: + - create +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role metadata: labels: app.kubernetes.io/component: server @@ -349,6 +373,22 @@ subjects: --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: argocd-redis +subjects: +- kind: ServiceAccount + name: argocd-redis +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding metadata: labels: app.kubernetes.io/component: server @@ -1045,7 +1085,14 @@ spec: - "" - --appendonly - "no" - image: redis:7.0.14-alpine + - --requirepass $(REDIS_PASSWORD) + env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: redis:7.0.15-alpine imagePullPolicy: Always name: redis ports: @@ -1056,6 +1103,23 @@ spec: drop: - ALL readOnlyRootFilesystem: true + initContainers: + - command: + - argocd + - admin + - redis-initial-password + image: quay.io/argoproj/argocd:latest + imagePullPolicy: IfNotPresent + name: secret-init + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault securityContext: runAsNonRoot: true runAsUser: 999 @@ -1100,6 +1164,11 @@ spec: - args: - /usr/local/bin/argocd-repo-server env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_RECONCILIATION_TIMEOUT valueFrom: configMapKeyRef: @@ -1415,6 +1484,11 @@ spec: - args: - /usr/local/bin/argocd-server env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_SERVER_INSECURE valueFrom: configMapKeyRef: @@ -1761,6 +1835,11 @@ spec: - args: - /usr/local/bin/argocd-application-controller env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_CONTROLLER_REPLICAS value: "1" - name: ARGOCD_RECONCILIATION_TIMEOUT
reposerver/repository/repository_test.go+1 −1 modified@@ -205,7 +205,7 @@ func TestGenerateYamlManifestInDir(t *testing.T) { } // update this value if we add/remove manifests - const countOfManifests = 48 + const countOfManifests = 50 res1, err := service.GenerateManifest(context.Background(), &q)
53570cbd143bMerge pull request from GHSA-9766-5277-j5hr
27 files changed · +884 −117
cmd/argocd/commands/admin/admin.go+1 −0 modified@@ -60,6 +60,7 @@ func NewAdminCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { command.AddCommand(NewDashboardCommand(clientOpts)) command.AddCommand(NewNotificationsCommand()) command.AddCommand(NewInitialPasswordCommand()) + command.AddCommand(NewRedisInitialPasswordCommand()) command.Flags().StringVar(&cmdutil.LogFormat, "logformat", "text", "Set the logging format. One of: text|json") command.Flags().StringVar(&cmdutil.LogLevel, "loglevel", "info", "Set the logging level. One of: debug|info|warn|error")
cmd/argocd/commands/admin/redis_initial_password.go+98 −0 added@@ -0,0 +1,98 @@ +package admin + +import ( + "context" + "crypto/rand" + "fmt" + "math/big" + + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/cli" + apierr "k8s.io/apimachinery/pkg/api/errors" + + "github.com/argoproj/argo-cd/v2/util/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/tools/clientcmd" + + "github.com/spf13/cobra" + corev1 "k8s.io/api/core/v1" +) + +const defaulRedisInitialPasswordSecretName = "argocd-redis" +const defaultResisInitialPasswordKey = "auth" + +func generateRandomPassword() (string, error) { + const initialPasswordLength = 16 + const letters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-" + randBytes := make([]byte, initialPasswordLength) + for i := 0; i < initialPasswordLength; i++ { + num, err := rand.Int(rand.Reader, big.NewInt(int64(len(letters)))) + if err != nil { + return "", err + } + randBytes[i] = letters[num.Int64()] + } + initialPassword := string(randBytes) + return initialPassword, nil +} + +// NewRedisInitialPasswordCommand defines a new command to ensure Argo CD Redis password secret exists. +func NewRedisInitialPasswordCommand() *cobra.Command { + var ( + clientConfig clientcmd.ClientConfig + ) + var command = cobra.Command{ + Use: "redis-initial-password", + Short: "Ensure the Redis password exists, creating a new one if necessary.", + Run: func(c *cobra.Command, args []string) { + namespace, _, err := clientConfig.Namespace() + errors.CheckError(err) + + redisInitialPasswordSecretName := defaulRedisInitialPasswordSecretName + redisInitialPasswordKey := defaultResisInitialPasswordKey + fmt.Printf("Checking for initial Redis password in secret %s/%s at key %s. \n", namespace, redisInitialPasswordSecretName, redisInitialPasswordKey) + + config, err := clientConfig.ClientConfig() + errors.CheckError(err) + errors.CheckError(v1alpha1.SetK8SConfigDefaults(config)) + + kubeClientset := kubernetes.NewForConfigOrDie(config) + + randomPassword, err := generateRandomPassword() + errors.CheckError(err) + + data := map[string][]byte{ + redisInitialPasswordKey: []byte(randomPassword), + } + secret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: redisInitialPasswordSecretName, + Namespace: namespace, + }, + Data: data, + Type: corev1.SecretTypeOpaque, + } + _, err = kubeClientset.CoreV1().Secrets(namespace).Create(context.Background(), secret, metav1.CreateOptions{}) + if err != nil && !apierr.IsAlreadyExists(err) { + errors.CheckError(err) + } + + fmt.Println("Argo CD Redis secret state confirmed: secret name argocd-redis.") + secret, err = kubeClientset.CoreV1().Secrets(namespace).Get(context.Background(), redisInitialPasswordSecretName, v1.GetOptions{}) + errors.CheckError(err) + + if _, ok := secret.Data[redisInitialPasswordKey]; ok { + fmt.Println("Password secret is configured properly.") + } else { + err := fmt.Errorf("key %s doesn't exist in secret %s. \n", redisInitialPasswordKey, redisInitialPasswordSecretName) + errors.CheckError(err) + } + }, + } + + clientConfig = cli.AddKubectlFlagsToCmd(&command) + + return &command +}
docs/faq.md+42 −0 modified@@ -259,3 +259,45 @@ The most common instance of this error is with `env:` fields for `containers`. !!! note "Dynamic applications" It's possible that your application is being generated by a tool in which case the duplication might not be evident within the scope of a single file. If you have trouble debugging this problem, consider filing a ticket to the owner of the generator tool asking them to improve its validation and error reporting. + +## How to rotate Redis secret? +* Delete `argocd-redis` secret in the namespace where Argo CD is installed. +```bash +kubectl delete secret argocd-redis -n <argocd namesapce> +``` +* If you are running Redis in HA mode, restart Redis in HA. +```bash +kubectl rollout restart deployment argocd-redis-ha-haproxy +kubectl rollout restart statefulset argocd-redis-ha-server +``` +* If you are running Redis in non-HA mode, restart Redis. +```bash +kubectl rollout restart deployment argocd-redis +``` +* Restart other components. +```bash +kubectl rollout restart deployment argocd-server argocd-repo-server +kubectl rollout restart statefulset argocd-application-controller +``` + +## How to turn off Redis auth if users really want to? + +Argo CD default installation is now configured automatically enable Redis authentication. +If for some reason authenticated Redis does not work for you and you want to use non-authenticated Redis, here are the steps: + +* You need to have your own Redis installation. +* Configure Argo CD to use your own Redis instance. See this [doc](https://argo-cd.readthedocs.io/en/stable/operator-manual/argocd-cmd-params-cm-yaml/) for the Argo CD configuration. +* If you already installed Redis shipped with Argo CD, you also need to clean up the existing components: + * When HA Redis is used: + * kubectl delete deployment argocd-redis-ha-haproxy + * kubectl delete statefulset argocd-redis-ha-server + * When non-HA Redis is used: + * kubectl delete deployment argocd-redis +* Remove environment variable `REDIS_PASSWORD` from the following manifests + * Deployment: argocd-repo-server: + * Deployment: argocd-server + * StatefulSet: argocd-application-controller + +## How do I provide my own Redis credentials? +The Redis password is stored in Kubernetes secret `argocd-redis` with key `auth` in the namespace where Argo CD is installed. +You can config your secret provider to generate Kubernetes secret accordingly. \ No newline at end of file
docs/getting_started.md+3 −0 modified@@ -38,6 +38,9 @@ Do one of: Use `argocd login --core` to [configure](./user-guide/commands/argocd_login.md) CLI access and skip steps 3-5. +!!! note + This default installation for Redis is using password authentication. The Redis password is stored in Kubernetes secret `argocd-redis` with key `auth` in the namespace where Argo CD is installed. + ## 2. Download Argo CD CLI Download the latest Argo CD version from [https://github.com/argoproj/argo-cd/releases/latest](https://github.com/argoproj/argo-cd/releases/latest). More detailed installation instructions can be found via the [CLI installation documentation](cli_installation.md).
docs/user-guide/commands/argocd_admin.md+1 −0 modified@@ -53,6 +53,7 @@ argocd admin [flags] * [argocd admin initial-password](argocd_admin_initial-password.md) - Prints initial password to log in to Argo CD for the first time * [argocd admin notifications](argocd_admin_notifications.md) - Set of CLI commands that helps manage notifications settings * [argocd admin proj](argocd_admin_proj.md) - Manage projects configuration +* [argocd admin redis-initial-password](argocd_admin_redis-initial-password.md) - Ensure the Redis password exists, creating a new one if necessary. * [argocd admin repo](argocd_admin_repo.md) - Manage repositories configuration * [argocd admin settings](argocd_admin_settings.md) - Provides set of commands for settings validation and troubleshooting
docs/user-guide/commands/argocd_admin_redis-initial-password.md+67 −0 added@@ -0,0 +1,67 @@ +# `argocd admin redis-initial-password` Command Reference + +## argocd admin redis-initial-password + +Ensure the Redis password exists, creating a new one if necessary. + +``` +argocd admin redis-initial-password [flags] +``` + +### Options + +``` + --as string Username to impersonate for the operation + --as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --as-uid string UID to impersonate for the operation + --certificate-authority string Path to a cert file for the certificate authority + --client-certificate string Path to a client certificate file for TLS + --client-key string Path to a client key file for TLS + --cluster string The name of the kubeconfig cluster to use + --context string The name of the kubeconfig context to use + --disable-compression If true, opt-out of response compression for all requests to the server + -h, --help help for redis-initial-password + --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kubeconfig string Path to a kube config. Only required if out-of-cluster + -n, --namespace string If present, the namespace scope for this CLI request + --password string Password for basic authentication to the API server + --proxy-url string If provided, this URL will be used to connect via proxy + --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") + --server string The address and port of the Kubernetes API server + --tls-server-name string If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used. + --token string Bearer token for authentication to the API server + --user string The name of the kubeconfig user to use + --username string Username for basic authentication to the API server +``` + +### Options inherited from parent commands + +``` + --auth-token string Authentication token + --client-crt string Client certificate file + --client-crt-key string Client certificate key file + --config string Path to Argo CD config (default "/home/user/.config/argocd/config") + --controller-name string Name of the Argo CD Application controller; set this or the ARGOCD_APPLICATION_CONTROLLER_NAME environment variable when the controller's name label differs from the default, for example when installing via the Helm chart (default "argocd-application-controller") + --core If set to true then CLI talks directly to Kubernetes instead of talking to Argo CD API server + --grpc-web Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. + --grpc-web-root-path string Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. Set web root. + -H, --header strings Sets additional header to all requests made by Argo CD CLI. (Can be repeated multiple times to add multiple headers, also supports comma separated headers) + --http-retry-max int Maximum number of retries to establish http connection to Argo CD server + --insecure Skip server certificate and domain verification + --kube-context string Directs the command to the given kube-context + --logformat string Set the logging format. One of: text|json (default "text") + --loglevel string Set the logging level. One of: debug|info|warn|error (default "info") + --plaintext Disable TLS + --port-forward Connect to a random argocd-server port using port forwarding + --port-forward-namespace string Namespace name which should be used for port forwarding + --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") + --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") + --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") + --server-crt string Server certificate file + --server-name string Name of the Argo CD API server; set this or the ARGOCD_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-server") +``` + +### SEE ALSO + +* [argocd admin](argocd_admin.md) - Contains a set of commands useful for Argo CD administrators and requires direct Kubernetes access +
manifests/base/application-controller/argocd-application-controller-statefulset.yaml+5 −0 modified@@ -21,6 +21,11 @@ spec: - args: - /usr/local/bin/argocd-application-controller env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_CONTROLLER_REPLICAS value: "1" - name: ARGOCD_RECONCILIATION_TIMEOUT
manifests/base/application-controller-deployment/argocd-application-controller-deployment.yaml+6 −1 modified@@ -22,6 +22,11 @@ spec: env: - name: ARGOCD_CONTROLLER_REPLICAS value: "1" + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_RECONCILIATION_TIMEOUT valueFrom: configMapKeyRef: @@ -215,4 +220,4 @@ spec: - key: tls.key path: tls.key - key: ca.crt - path: ca.crt \ No newline at end of file + path: ca.crt
manifests/base/redis/argocd-redis-deployment.yaml+24 −0 modified@@ -15,6 +15,23 @@ spec: labels: app.kubernetes.io/name: argocd-redis spec: + initContainers: + - command: + - argocd + - admin + - redis-initial-password + image: quay.io/argoproj/argocd:latest + imagePullPolicy: IfNotPresent + name: secret-init + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault securityContext: runAsNonRoot: true runAsUser: 999 @@ -30,6 +47,13 @@ spec: - "" - "--appendonly" - "no" + - --requirepass $(REDIS_PASSWORD) + env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis ports: - containerPort: 6379 securityContext:
manifests/base/redis/argocd-redis-rolebinding.yaml+15 −0 added@@ -0,0 +1,15 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: argocd-redis +subjects: + - kind: ServiceAccount + name: argocd-redis \ No newline at end of file
manifests/base/redis/argocd-redis-role.yaml+23 −0 added@@ -0,0 +1,23 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +rules: + - apiGroups: + - "" + resources: + - secrets + resourceNames: + - argocd-redis + verbs: + - get + - apiGroups: + - "" + resources: + - secrets + verbs: + - create \ No newline at end of file
manifests/base/redis/kustomization.yaml+2 −0 modified@@ -6,3 +6,5 @@ resources: - argocd-redis-sa.yaml - argocd-redis-service.yaml - argocd-redis-network-policy.yaml +- argocd-redis-role.yaml +- argocd-redis-rolebinding.yaml
manifests/base/repo-server/argocd-repo-server-deployment.yaml+5 −0 modified@@ -24,6 +24,11 @@ spec: args: - /usr/local/bin/argocd-repo-server env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_RECONCILIATION_TIMEOUT valueFrom: configMapKeyRef:
manifests/base/server/argocd-server-deployment.yaml+5 −0 modified@@ -23,6 +23,11 @@ spec: args: - /usr/local/bin/argocd-server env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_SERVER_INSECURE valueFrom: configMapKeyRef:
manifests/core-install.yaml+74 −0 modified@@ -20382,6 +20382,30 @@ rules: - watch --- apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +rules: +- apiGroups: + - "" + resourceNames: + - argocd-redis + resources: + - secrets + verbs: + - get +- apiGroups: + - "" + resources: + - secrets + verbs: + - create +--- +apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: labels: @@ -20434,6 +20458,22 @@ subjects: name: argocd-applicationset-controller --- apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: argocd-redis +subjects: +- kind: ServiceAccount + name: argocd-redis +--- +apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: labels: @@ -20839,6 +20879,13 @@ spec: - "" - --appendonly - "no" + - --requirepass $(REDIS_PASSWORD) + env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis image: redis:7.0.15-alpine imagePullPolicy: Always name: redis @@ -20850,6 +20897,23 @@ spec: drop: - ALL readOnlyRootFilesystem: true + initContainers: + - command: + - argocd + - admin + - redis-initial-password + image: quay.io/argoproj/argocd:latest + imagePullPolicy: IfNotPresent + name: secret-init + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault securityContext: runAsNonRoot: true runAsUser: 999 @@ -20894,6 +20958,11 @@ spec: - args: - /usr/local/bin/argocd-repo-server env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_RECONCILIATION_TIMEOUT valueFrom: configMapKeyRef: @@ -21181,6 +21250,11 @@ spec: - args: - /usr/local/bin/argocd-application-controller env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_CONTROLLER_REPLICAS value: "1" - name: ARGOCD_RECONCILIATION_TIMEOUT
manifests/ha/base/redis-ha/chart/requirements.lock+3 −3 modified@@ -1,6 +1,6 @@ dependencies: - name: redis-ha repository: https://dandydeveloper.github.io/charts - version: 4.22.3 -digest: sha256:ae773caf65b172bdd2216072c03ba76ef3c0383dbd1e2478934a67b9455f6a2e -generated: "2022-11-02T16:57:25.047025473-07:00" + version: 4.26.6 +digest: sha256:c363f48ea8339c4bdb7c8a2cca62aa487b69d0a52a6fe6267fbbbbc07e468abd +generated: "2024-04-10T11:02:32.957812-07:00"
manifests/ha/base/redis-ha/chart/requirements.yaml+1 −1 modified@@ -1,4 +1,4 @@ dependencies: - name: redis-ha - version: 4.22.3 + version: 4.26.6 repository: https://dandydeveloper.github.io/charts
manifests/ha/base/redis-ha/chart/upstream.yaml+78 −44 modified@@ -9,8 +9,10 @@ metadata: labels: heritage: Helm release: argocd - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 app: argocd-redis-ha +secrets: +- name: argocd-redis --- # Source: redis-ha/charts/redis-ha/templates/redis-haproxy-serviceaccount.yaml apiVersion: v1 @@ -21,7 +23,7 @@ metadata: labels: heritage: Helm release: argocd - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 app: argocd-redis-ha --- # Source: redis-ha/charts/redis-ha/templates/redis-ha-configmap.yaml @@ -33,7 +35,7 @@ metadata: labels: heritage: Helm release: argocd - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 app: argocd-redis-ha data: redis.conf: | @@ -50,6 +52,8 @@ data: rdbcompression yes repl-diskless-sync yes save "" + requirepass replace-default-auth + masterauth replace-default-auth sentinel.conf: | dir "/data" @@ -59,6 +63,7 @@ data: sentinel failover-timeout argocd 180000 maxclients 10000 sentinel parallel-syncs argocd 5 + sentinel auth-pass argocd replace-default-auth init.sh: | echo "$(date) Start..." @@ -82,7 +87,7 @@ data: sentinel_get_master() { set +e if [ "$SENTINEL_PORT" -eq 0 ]; then - redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ + redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ grep -E '((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?s*$))' else redis-cli -h "${SERVICE}" -p "${SENTINEL_PORT}" sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ @@ -191,9 +196,9 @@ data: redis_ping() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - redis-cli -h "${MASTER}" -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping else - redis-cli -h "${MASTER}" -p "${REDIS_PORT}" ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" ping fi set -e } @@ -226,7 +231,7 @@ data: if [ "$SENTINEL_PORT" -eq 0 ]; then echo " on sentinel (${SERVICE}:${SENTINEL_TLS_PORT}), sentinel grp (${MASTER_GROUP})" - if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then + if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then echo " $(date) Failover returned with 'NOGOODSLAVE'" echo "Setting defaults for this pod.." setup_defaults @@ -345,7 +350,7 @@ data: sentinel_get_master() { set +e if [ "$SENTINEL_PORT" -eq 0 ]; then - redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ + redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ grep -E '((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?s*$))' else redis-cli -h "${SERVICE}" -p "${SENTINEL_PORT}" sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ @@ -454,9 +459,9 @@ data: redis_ping() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - redis-cli -h "${MASTER}" -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping else - redis-cli -h "${MASTER}" -p "${REDIS_PORT}" ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" ping fi set -e } @@ -489,7 +494,7 @@ data: if [ "$SENTINEL_PORT" -eq 0 ]; then echo " on sentinel (${SERVICE}:${SENTINEL_TLS_PORT}), sentinel grp (${MASTER_GROUP})" - if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then + if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then echo " $(date) Failover returned with 'NOGOODSLAVE'" echo "Setting defaults for this pod.." setup_defaults @@ -554,19 +559,19 @@ data: redis_role() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - ROLE=$(redis-cli -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep role | sed 's/role://' | sed 's/\r//') + ROLE=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep role | sed 's/role://' | sed 's/\r//') else - ROLE=$(redis-cli -p "${REDIS_PORT}" info | grep role | sed 's/role://' | sed 's/\r//') + ROLE=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" info | grep role | sed 's/role://' | sed 's/\r//') fi set -e } identify_redis_master() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - REDIS_MASTER=$(redis-cli -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep master_host | sed 's/master_host://' | sed 's/\r//') + REDIS_MASTER=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep master_host | sed 's/master_host://' | sed 's/\r//') else - REDIS_MASTER=$(redis-cli -p "${REDIS_PORT}" info | grep master_host | sed 's/master_host://' | sed 's/\r//') + REDIS_MASTER=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" info | grep master_host | sed 's/master_host://' | sed 's/\r//') fi set -e } @@ -576,9 +581,9 @@ data: sh /readonly-config/init.sh if [ "$REDIS_PORT" -eq 0 ]; then - echo "shutdown" | redis-cli -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key + echo "shutdown" | redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key else - echo "shutdown" | redis-cli -p "${REDIS_PORT}" + echo "shutdown" | redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" fi set -e } @@ -591,6 +596,7 @@ data: identify_announce_ip done + trap "exit 0" TERM while true; do sleep 60 @@ -674,6 +680,8 @@ data: mode tcp option tcp-check tcp-check connect + tcp-check send "AUTH ${AUTH}"\r\n + tcp-check expect string +OK tcp-check send PING\r\n tcp-check expect string +PONG tcp-check send info\ replication\r\n @@ -730,6 +738,7 @@ data: get_redis_role() { is_master=$( redis-cli \ + -a "${AUTH}" --no-auth-warning \ -h localhost \ -p 6379 \ info | grep -c 'role:master' || true @@ -766,12 +775,13 @@ metadata: labels: heritage: Helm release: argocd - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 app: argocd-redis-ha data: redis_liveness.sh: | response=$( redis-cli \ + -a "${AUTH}" --no-auth-warning \ -h localhost \ -p 6379 \ ping @@ -784,6 +794,7 @@ data: redis_readiness.sh: | response=$( redis-cli \ + -a "${AUTH}" --no-auth-warning \ -h localhost \ -p 6379 \ ping @@ -816,7 +827,7 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 rules: - apiGroups: - "" @@ -835,7 +846,7 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 component: argocd-redis-ha-haproxy rules: - apiGroups: @@ -855,7 +866,7 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 subjects: - kind: ServiceAccount name: argocd-redis-ha @@ -874,7 +885,7 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 component: argocd-redis-ha-haproxy subjects: - kind: ServiceAccount @@ -894,9 +905,8 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 annotations: - service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" spec: publishNotReadyAddresses: true type: ClusterIP @@ -924,9 +934,8 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 annotations: - service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" spec: publishNotReadyAddresses: true type: ClusterIP @@ -954,9 +963,8 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 annotations: - service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" spec: publishNotReadyAddresses: true type: ClusterIP @@ -984,7 +992,7 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 annotations: spec: type: ClusterIP @@ -1012,7 +1020,7 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 component: argocd-redis-ha-haproxy annotations: spec: @@ -1040,7 +1048,7 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 spec: strategy: type: RollingUpdate @@ -1056,12 +1064,11 @@ spec: labels: app: redis-ha-haproxy release: argocd - revision: "1" annotations: prometheus.io/port: "9101" prometheus.io/scrape: "true" prometheus.io/path: "/metrics" - checksum/config: 492a6adabb741e0cee39be9aa5155c41a4456629f862d0006a2d892dbecfbcae + checksum/config: e34e8124c38bcfd2f16e75620bbde30158686692b13bc449eecc44c51b207d54 spec: # Needed when using unmodified rbac-setup.yml @@ -1081,11 +1088,10 @@ spec: matchLabels: app: redis-ha-haproxy release: argocd - revision: "1" topologyKey: kubernetes.io/hostname initContainers: - name: config-init - image: haproxy:2.6.14-alpine + image: public.ecr.aws/docker/library/haproxy:2.6.14-alpine imagePullPolicy: IfNotPresent resources: {} @@ -1109,7 +1115,7 @@ spec: mountPath: /data containers: - name: haproxy - image: haproxy:2.6.14-alpine + image: public.ecr.aws/docker/library/haproxy:2.6.14-alpine imagePullPolicy: IfNotPresent securityContext: allowPrivilegeEscalation: false @@ -1119,6 +1125,12 @@ spec: runAsNonRoot: true seccompProfile: type: RuntimeDefault + env: + - name: AUTH + valueFrom: + secretKeyRef: + name: argocd-redis + key: auth livenessProbe: httpGet: path: /healthz @@ -1167,7 +1179,7 @@ metadata: app: redis-ha heritage: "Helm" release: "argocd" - chart: redis-ha-4.22.3 + chart: redis-ha-4.26.6 annotations: {} spec: @@ -1183,7 +1195,7 @@ spec: template: metadata: annotations: - checksum/init-config: 69130412bda04eacad3530cb7bcf26cf121401e725e15d0959dd71a7380afe75 + checksum/init-config: 9d3c019a5ea1fd98ab5cde397d8eecd351da884f15e6ba346c607cb2446c2198 labels: release: argocd app: redis-ha @@ -1207,7 +1219,7 @@ spec: automountServiceAccountToken: false initContainers: - name: config-init - image: redis:7.0.15-alpine + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent resources: {} @@ -1231,6 +1243,11 @@ spec: value: 40000915ab58c3fa8fd888fb8b24711944e6cbb4 - name: SENTINEL_ID_2 value: 2bbec7894d954a8af3bb54d13eaec53cb024e2ca + - name: AUTH + valueFrom: + secretKeyRef: + name: argocd-redis + key: auth volumeMounts: - name: config mountPath: /readonly-config @@ -1241,12 +1258,12 @@ spec: containers: - name: redis - image: redis:7.0.15-alpine + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent command: - - redis-server + - redis-server args: - - /data/conf/redis.conf + - /data/conf/redis.conf securityContext: allowPrivilegeEscalation: false capabilities: @@ -1256,6 +1273,12 @@ spec: runAsUser: 1000 seccompProfile: type: RuntimeDefault + env: + - name: AUTH + valueFrom: + secretKeyRef: + name: argocd-redis + key: auth livenessProbe: initialDelaySeconds: 30 periodSeconds: 15 @@ -1298,7 +1321,7 @@ spec: - /bin/sh - /readonly-config/trigger-failover-if-master.sh - name: sentinel - image: redis:7.0.15-alpine + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent command: - redis-sentinel @@ -1313,6 +1336,12 @@ spec: runAsUser: 1000 seccompProfile: type: RuntimeDefault + env: + - name: AUTH + valueFrom: + secretKeyRef: + name: argocd-redis + key: auth livenessProbe: initialDelaySeconds: 30 periodSeconds: 15 @@ -1349,7 +1378,7 @@ spec: {} - name: split-brain-fix - image: redis:7.0.15-alpine + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent command: - sh @@ -1371,6 +1400,11 @@ spec: value: 40000915ab58c3fa8fd888fb8b24711944e6cbb4 - name: SENTINEL_ID_2 value: 2bbec7894d954a8af3bb54d13eaec53cb024e2ca + - name: AUTH + valueFrom: + secretKeyRef: + name: argocd-redis + key: auth resources: {} volumeMounts:
manifests/ha/base/redis-ha/chart/values.yaml+3 −0 modified@@ -1,4 +1,7 @@ redis-ha: + auth: true + authKey: auth + existingSecret: argocd-redis persistentVolume: enabled: false redis:
manifests/ha/base/redis-ha/kustomization.yaml+17 −5 modified@@ -20,7 +20,7 @@ patches: kind: ConfigMap name: argocd-redis-ha-configmap namespace: argocd - path: overlays/remove-namespace.yaml + path: overlays/remove-namespace.yaml - target: version: v1 group: "" @@ -34,28 +34,28 @@ patches: kind: ServiceAccount name: argocd-redis-ha-haproxy namespace: argocd - path: overlays/remove-namespace.yaml + path: overlays/remove-namespace.yaml - target: group: rbac.authorization.k8s.io version: v1 kind: Role name: argocd-redis-ha namespace: argocd - path: overlays/remove-namespace.yaml + path: overlays/remove-namespace.yaml - target: group: rbac.authorization.k8s.io version: v1 kind: Role name: argocd-redis-ha-haproxy namespace: argocd - path: overlays/remove-namespace.yaml + path: overlays/remove-namespace.yaml - target: group: rbac.authorization.k8s.io version: v1 kind: RoleBinding name: argocd-redis-ha namespace: argocd - path: overlays/remove-namespace.yaml + path: overlays/remove-namespace.yaml - target: group: rbac.authorization.k8s.io version: v1 @@ -294,3 +294,15 @@ patches: kind: StatefulSet name: argocd-redis-ha-server path: overlays/statefulset-containers-securityContext.yaml +- target: + group: rbac.authorization.k8s.io + version: v1 + kind: Role + name: argocd-redis-ha-haproxy + path: overlays/haproxy-role.yaml +- target: + group: apps + version: v1 + kind: Deployment + name: argocd-redis-ha-haproxy + path: overlays/deployment-initContainers.yaml \ No newline at end of file
manifests/ha/base/redis-ha/overlays/deployment-initContainers.yaml+16 −0 added@@ -0,0 +1,16 @@ +- op: add + path: /spec/template/spec/initContainers/0 + value: + name: secret-init + command: [ 'argocd', 'admin', 'redis-initial-password' ] + image: quay.io/argoproj/argocd:latest + imagePullPolicy: IfNotPresent + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault \ No newline at end of file
manifests/ha/base/redis-ha/overlays/haproxy-role.yaml+20 −0 added@@ -0,0 +1,20 @@ +- op: add + path: /rules/0 + value: + apiGroups: + - "" + resources: + - secrets + resourceNames: + - argocd-redis + verbs: + - get +- op: add + path: /rules/0 + value: + apiGroups: + - "" + resources: + - secrets + verbs: + - create \ No newline at end of file
manifests/ha/install.yaml+108 −31 modified@@ -20276,6 +20276,8 @@ metadata: app.kubernetes.io/name: argocd-redis-ha app.kubernetes.io/part-of: argocd name: argocd-redis-ha +secrets: +- name: argocd-redis --- apiVersion: v1 kind: ServiceAccount @@ -20506,6 +20508,20 @@ metadata: app.kubernetes.io/part-of: argocd name: argocd-redis-ha-haproxy rules: +- apiGroups: + - "" + resources: + - secrets + verbs: + - create +- apiGroups: + - "" + resourceNames: + - argocd-redis + resources: + - secrets + verbs: + - get - apiGroups: - "" resources: @@ -20844,7 +20860,7 @@ data: sentinel_get_master() { set +e if [ "$SENTINEL_PORT" -eq 0 ]; then - redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ + redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ grep -E '((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?s*$))' else redis-cli -h "${SERVICE}" -p "${SENTINEL_PORT}" sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ @@ -20953,9 +20969,9 @@ data: redis_ping() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - redis-cli -h "${MASTER}" -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping else - redis-cli -h "${MASTER}" -p "${REDIS_PORT}" ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" ping fi set -e } @@ -20988,7 +21004,7 @@ data: if [ "$SENTINEL_PORT" -eq 0 ]; then echo " on sentinel (${SERVICE}:${SENTINEL_TLS_PORT}), sentinel grp (${MASTER_GROUP})" - if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then + if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then echo " $(date) Failover returned with 'NOGOODSLAVE'" echo "Setting defaults for this pod.." setup_defaults @@ -21053,19 +21069,19 @@ data: redis_role() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - ROLE=$(redis-cli -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep role | sed 's/role://' | sed 's/\r//') + ROLE=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep role | sed 's/role://' | sed 's/\r//') else - ROLE=$(redis-cli -p "${REDIS_PORT}" info | grep role | sed 's/role://' | sed 's/\r//') + ROLE=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" info | grep role | sed 's/role://' | sed 's/\r//') fi set -e } identify_redis_master() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - REDIS_MASTER=$(redis-cli -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep master_host | sed 's/master_host://' | sed 's/\r//') + REDIS_MASTER=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep master_host | sed 's/master_host://' | sed 's/\r//') else - REDIS_MASTER=$(redis-cli -p "${REDIS_PORT}" info | grep master_host | sed 's/master_host://' | sed 's/\r//') + REDIS_MASTER=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" info | grep master_host | sed 's/master_host://' | sed 's/\r//') fi set -e } @@ -21075,9 +21091,9 @@ data: sh /readonly-config/init.sh if [ "$REDIS_PORT" -eq 0 ]; then - echo "shutdown" | redis-cli -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key + echo "shutdown" | redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key else - echo "shutdown" | redis-cli -p "${REDIS_PORT}" + echo "shutdown" | redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" fi set -e } @@ -21090,6 +21106,7 @@ data: identify_announce_ip done + trap "exit 0" TERM while true; do sleep 60 @@ -21132,9 +21149,10 @@ data: decide redis backend to use\n#master\nfrontend ft_redis_master\n bind :6379 \n \ use_backend bk_redis_master\n# Check all redis servers to see if they think they are master\nbackend bk_redis_master\n mode tcp\n option tcp-check\n tcp-check - connect\n tcp-check send PING\\r\\n\n tcp-check expect string +PONG\n tcp-check - send info\\ replication\\r\\n\n tcp-check expect string role:master\n tcp-check - send QUIT\\r\\n\n tcp-check expect string +OK\n use-server R0 if { srv_is_up(R0) + connect\n tcp-check send \"AUTH ${AUTH}\"\\r\\n\n tcp-check expect string +OK\n + \ tcp-check send PING\\r\\n\n tcp-check expect string +PONG\n tcp-check send + info\\ replication\\r\\n\n tcp-check expect string role:master\n tcp-check send + QUIT\\r\\n\n tcp-check expect string +OK\n use-server R0 if { srv_is_up(R0) } { nbsrv(check_if_redis_is_master_0) ge 2 }\n server R0 argocd-redis-ha-announce-0:6379 check inter 3s fall 1 rise 1\n use-server R1 if { srv_is_up(R1) } { nbsrv(check_if_redis_is_master_1) ge 2 }\n server R1 argocd-redis-ha-announce-1:6379 check inter 3s fall 1 rise @@ -21197,7 +21215,7 @@ data: sentinel_get_master() { set +e if [ "$SENTINEL_PORT" -eq 0 ]; then - redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ + redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ grep -E '((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?s*$))' else redis-cli -h "${SERVICE}" -p "${SENTINEL_PORT}" sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ @@ -21306,9 +21324,9 @@ data: redis_ping() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - redis-cli -h "${MASTER}" -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping else - redis-cli -h "${MASTER}" -p "${REDIS_PORT}" ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" ping fi set -e } @@ -21341,7 +21359,7 @@ data: if [ "$SENTINEL_PORT" -eq 0 ]; then echo " on sentinel (${SERVICE}:${SENTINEL_TLS_PORT}), sentinel grp (${MASTER_GROUP})" - if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then + if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then echo " $(date) Failover returned with 'NOGOODSLAVE'" echo "Setting defaults for this pod.." setup_defaults @@ -21449,6 +21467,8 @@ data: rdbcompression yes repl-diskless-sync yes save "" + requirepass replace-default-auth + masterauth replace-default-auth sentinel.conf: | dir "/data" port 26379 @@ -21457,10 +21477,12 @@ data: sentinel failover-timeout argocd 180000 maxclients 10000 sentinel parallel-syncs argocd 5 + sentinel auth-pass argocd replace-default-auth trigger-failover-if-master.sh: | get_redis_role() { is_master=$( redis-cli \ + -a "${AUTH}" --no-auth-warning \ -h localhost \ -p 6379 \ info | grep -c 'role:master' || true @@ -21500,6 +21522,7 @@ data: redis_liveness.sh: | response=$( redis-cli \ + -a "${AUTH}" --no-auth-warning \ -h localhost \ -p 6379 \ ping @@ -21512,6 +21535,7 @@ data: redis_readiness.sh: | response=$( redis-cli \ + -a "${AUTH}" --no-auth-warning \ -h localhost \ -p 6379 \ ping @@ -21700,8 +21724,6 @@ spec: apiVersion: v1 kind: Service metadata: - annotations: - service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" labels: app.kubernetes.io/component: redis app.kubernetes.io/name: argocd-redis-ha @@ -21726,8 +21748,6 @@ spec: apiVersion: v1 kind: Service metadata: - annotations: - service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" labels: app.kubernetes.io/component: redis app.kubernetes.io/name: argocd-redis-ha @@ -21752,8 +21772,6 @@ spec: apiVersion: v1 kind: Service metadata: - annotations: - service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" labels: app.kubernetes.io/component: redis app.kubernetes.io/name: argocd-redis-ha @@ -22258,7 +22276,7 @@ spec: template: metadata: annotations: - checksum/config: 492a6adabb741e0cee39be9aa5155c41a4456629f862d0006a2d892dbecfbcae + checksum/config: e34e8124c38bcfd2f16e75620bbde30158686692b13bc449eecc44c51b207d54 prometheus.io/path: /metrics prometheus.io/port: "9101" prometheus.io/scrape: "true" @@ -22274,7 +22292,13 @@ spec: app.kubernetes.io/name: argocd-redis-ha-haproxy topologyKey: kubernetes.io/hostname containers: - - image: haproxy:2.6.14-alpine + - env: + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/haproxy:2.6.14-alpine imagePullPolicy: IfNotPresent lifecycle: {} livenessProbe: @@ -22309,11 +22333,27 @@ spec: - mountPath: /run/haproxy name: shared-socket initContainers: + - command: + - argocd + - admin + - redis-initial-password + image: quay.io/argoproj/argocd:latest + imagePullPolicy: IfNotPresent + name: secret-init + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault - args: - /readonly/haproxy_init.sh command: - sh - image: haproxy:2.6.14-alpine + image: public.ecr.aws/docker/library/haproxy:2.6.14-alpine imagePullPolicy: IfNotPresent name: config-init securityContext: @@ -22381,6 +22421,11 @@ spec: - args: - /usr/local/bin/argocd-repo-server env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_RECONCILIATION_TIMEOUT valueFrom: configMapKeyRef: @@ -22668,6 +22713,11 @@ spec: env: - name: ARGOCD_API_SERVER_REPLICAS value: "2" + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_SERVER_INSECURE valueFrom: configMapKeyRef: @@ -22990,6 +23040,11 @@ spec: - args: - /usr/local/bin/argocd-application-controller env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_CONTROLLER_REPLICAS value: "1" - name: ARGOCD_RECONCILIATION_TIMEOUT @@ -23190,7 +23245,7 @@ spec: template: metadata: annotations: - checksum/init-config: 69130412bda04eacad3530cb7bcf26cf121401e725e15d0959dd71a7380afe75 + checksum/init-config: 9d3c019a5ea1fd98ab5cde397d8eecd351da884f15e6ba346c607cb2446c2198 labels: app.kubernetes.io/name: argocd-redis-ha spec: @@ -23207,7 +23262,13 @@ spec: - /data/conf/redis.conf command: - redis-server - image: redis:7.0.15-alpine + env: + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent lifecycle: preStop: @@ -23261,7 +23322,13 @@ spec: - /data/conf/sentinel.conf command: - redis-sentinel - image: redis:7.0.15-alpine + env: + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent lifecycle: {} livenessProbe: @@ -23314,7 +23381,12 @@ spec: value: 40000915ab58c3fa8fd888fb8b24711944e6cbb4 - name: SENTINEL_ID_2 value: 2bbec7894d954a8af3bb54d13eaec53cb024e2ca - image: redis:7.0.15-alpine + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent name: split-brain-fix resources: {} @@ -23344,7 +23416,12 @@ spec: value: 40000915ab58c3fa8fd888fb8b24711944e6cbb4 - name: SENTINEL_ID_2 value: 2bbec7894d954a8af3bb54d13eaec53cb024e2ca - image: redis:7.0.15-alpine + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent name: config-init securityContext:
manifests/ha/namespace-install.yaml+108 −31 modified@@ -43,6 +43,8 @@ metadata: app.kubernetes.io/name: argocd-redis-ha app.kubernetes.io/part-of: argocd name: argocd-redis-ha +secrets: +- name: argocd-redis --- apiVersion: v1 kind: ServiceAccount @@ -273,6 +275,20 @@ metadata: app.kubernetes.io/part-of: argocd name: argocd-redis-ha-haproxy rules: +- apiGroups: + - "" + resources: + - secrets + verbs: + - create +- apiGroups: + - "" + resourceNames: + - argocd-redis + resources: + - secrets + verbs: + - get - apiGroups: - "" resources: @@ -505,7 +521,7 @@ data: sentinel_get_master() { set +e if [ "$SENTINEL_PORT" -eq 0 ]; then - redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ + redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ grep -E '((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?s*$))' else redis-cli -h "${SERVICE}" -p "${SENTINEL_PORT}" sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ @@ -614,9 +630,9 @@ data: redis_ping() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - redis-cli -h "${MASTER}" -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping else - redis-cli -h "${MASTER}" -p "${REDIS_PORT}" ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" ping fi set -e } @@ -649,7 +665,7 @@ data: if [ "$SENTINEL_PORT" -eq 0 ]; then echo " on sentinel (${SERVICE}:${SENTINEL_TLS_PORT}), sentinel grp (${MASTER_GROUP})" - if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then + if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then echo " $(date) Failover returned with 'NOGOODSLAVE'" echo "Setting defaults for this pod.." setup_defaults @@ -714,19 +730,19 @@ data: redis_role() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - ROLE=$(redis-cli -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep role | sed 's/role://' | sed 's/\r//') + ROLE=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep role | sed 's/role://' | sed 's/\r//') else - ROLE=$(redis-cli -p "${REDIS_PORT}" info | grep role | sed 's/role://' | sed 's/\r//') + ROLE=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" info | grep role | sed 's/role://' | sed 's/\r//') fi set -e } identify_redis_master() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - REDIS_MASTER=$(redis-cli -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep master_host | sed 's/master_host://' | sed 's/\r//') + REDIS_MASTER=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep master_host | sed 's/master_host://' | sed 's/\r//') else - REDIS_MASTER=$(redis-cli -p "${REDIS_PORT}" info | grep master_host | sed 's/master_host://' | sed 's/\r//') + REDIS_MASTER=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" info | grep master_host | sed 's/master_host://' | sed 's/\r//') fi set -e } @@ -736,9 +752,9 @@ data: sh /readonly-config/init.sh if [ "$REDIS_PORT" -eq 0 ]; then - echo "shutdown" | redis-cli -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key + echo "shutdown" | redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key else - echo "shutdown" | redis-cli -p "${REDIS_PORT}" + echo "shutdown" | redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" fi set -e } @@ -751,6 +767,7 @@ data: identify_announce_ip done + trap "exit 0" TERM while true; do sleep 60 @@ -793,9 +810,10 @@ data: decide redis backend to use\n#master\nfrontend ft_redis_master\n bind :6379 \n \ use_backend bk_redis_master\n# Check all redis servers to see if they think they are master\nbackend bk_redis_master\n mode tcp\n option tcp-check\n tcp-check - connect\n tcp-check send PING\\r\\n\n tcp-check expect string +PONG\n tcp-check - send info\\ replication\\r\\n\n tcp-check expect string role:master\n tcp-check - send QUIT\\r\\n\n tcp-check expect string +OK\n use-server R0 if { srv_is_up(R0) + connect\n tcp-check send \"AUTH ${AUTH}\"\\r\\n\n tcp-check expect string +OK\n + \ tcp-check send PING\\r\\n\n tcp-check expect string +PONG\n tcp-check send + info\\ replication\\r\\n\n tcp-check expect string role:master\n tcp-check send + QUIT\\r\\n\n tcp-check expect string +OK\n use-server R0 if { srv_is_up(R0) } { nbsrv(check_if_redis_is_master_0) ge 2 }\n server R0 argocd-redis-ha-announce-0:6379 check inter 3s fall 1 rise 1\n use-server R1 if { srv_is_up(R1) } { nbsrv(check_if_redis_is_master_1) ge 2 }\n server R1 argocd-redis-ha-announce-1:6379 check inter 3s fall 1 rise @@ -858,7 +876,7 @@ data: sentinel_get_master() { set +e if [ "$SENTINEL_PORT" -eq 0 ]; then - redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ + redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ grep -E '((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?s*$))' else redis-cli -h "${SERVICE}" -p "${SENTINEL_PORT}" sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ @@ -967,9 +985,9 @@ data: redis_ping() { set +e if [ "$REDIS_PORT" -eq 0 ]; then - redis-cli -h "${MASTER}" -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping else - redis-cli -h "${MASTER}" -p "${REDIS_PORT}" ping + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" ping fi set -e } @@ -1002,7 +1020,7 @@ data: if [ "$SENTINEL_PORT" -eq 0 ]; then echo " on sentinel (${SERVICE}:${SENTINEL_TLS_PORT}), sentinel grp (${MASTER_GROUP})" - if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then + if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then echo " $(date) Failover returned with 'NOGOODSLAVE'" echo "Setting defaults for this pod.." setup_defaults @@ -1110,6 +1128,8 @@ data: rdbcompression yes repl-diskless-sync yes save "" + requirepass replace-default-auth + masterauth replace-default-auth sentinel.conf: | dir "/data" port 26379 @@ -1118,10 +1138,12 @@ data: sentinel failover-timeout argocd 180000 maxclients 10000 sentinel parallel-syncs argocd 5 + sentinel auth-pass argocd replace-default-auth trigger-failover-if-master.sh: | get_redis_role() { is_master=$( redis-cli \ + -a "${AUTH}" --no-auth-warning \ -h localhost \ -p 6379 \ info | grep -c 'role:master' || true @@ -1161,6 +1183,7 @@ data: redis_liveness.sh: | response=$( redis-cli \ + -a "${AUTH}" --no-auth-warning \ -h localhost \ -p 6379 \ ping @@ -1173,6 +1196,7 @@ data: redis_readiness.sh: | response=$( redis-cli \ + -a "${AUTH}" --no-auth-warning \ -h localhost \ -p 6379 \ ping @@ -1361,8 +1385,6 @@ spec: apiVersion: v1 kind: Service metadata: - annotations: - service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" labels: app.kubernetes.io/component: redis app.kubernetes.io/name: argocd-redis-ha @@ -1387,8 +1409,6 @@ spec: apiVersion: v1 kind: Service metadata: - annotations: - service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" labels: app.kubernetes.io/component: redis app.kubernetes.io/name: argocd-redis-ha @@ -1413,8 +1433,6 @@ spec: apiVersion: v1 kind: Service metadata: - annotations: - service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" labels: app.kubernetes.io/component: redis app.kubernetes.io/name: argocd-redis-ha @@ -1919,7 +1937,7 @@ spec: template: metadata: annotations: - checksum/config: 492a6adabb741e0cee39be9aa5155c41a4456629f862d0006a2d892dbecfbcae + checksum/config: e34e8124c38bcfd2f16e75620bbde30158686692b13bc449eecc44c51b207d54 prometheus.io/path: /metrics prometheus.io/port: "9101" prometheus.io/scrape: "true" @@ -1935,7 +1953,13 @@ spec: app.kubernetes.io/name: argocd-redis-ha-haproxy topologyKey: kubernetes.io/hostname containers: - - image: haproxy:2.6.14-alpine + - env: + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/haproxy:2.6.14-alpine imagePullPolicy: IfNotPresent lifecycle: {} livenessProbe: @@ -1970,11 +1994,27 @@ spec: - mountPath: /run/haproxy name: shared-socket initContainers: + - command: + - argocd + - admin + - redis-initial-password + image: quay.io/argoproj/argocd:latest + imagePullPolicy: IfNotPresent + name: secret-init + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault - args: - /readonly/haproxy_init.sh command: - sh - image: haproxy:2.6.14-alpine + image: public.ecr.aws/docker/library/haproxy:2.6.14-alpine imagePullPolicy: IfNotPresent name: config-init securityContext: @@ -2042,6 +2082,11 @@ spec: - args: - /usr/local/bin/argocd-repo-server env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_RECONCILIATION_TIMEOUT valueFrom: configMapKeyRef: @@ -2329,6 +2374,11 @@ spec: env: - name: ARGOCD_API_SERVER_REPLICAS value: "2" + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_SERVER_INSECURE valueFrom: configMapKeyRef: @@ -2651,6 +2701,11 @@ spec: - args: - /usr/local/bin/argocd-application-controller env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_CONTROLLER_REPLICAS value: "1" - name: ARGOCD_RECONCILIATION_TIMEOUT @@ -2851,7 +2906,7 @@ spec: template: metadata: annotations: - checksum/init-config: 69130412bda04eacad3530cb7bcf26cf121401e725e15d0959dd71a7380afe75 + checksum/init-config: 9d3c019a5ea1fd98ab5cde397d8eecd351da884f15e6ba346c607cb2446c2198 labels: app.kubernetes.io/name: argocd-redis-ha spec: @@ -2868,7 +2923,13 @@ spec: - /data/conf/redis.conf command: - redis-server - image: redis:7.0.15-alpine + env: + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent lifecycle: preStop: @@ -2922,7 +2983,13 @@ spec: - /data/conf/sentinel.conf command: - redis-sentinel - image: redis:7.0.15-alpine + env: + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent lifecycle: {} livenessProbe: @@ -2975,7 +3042,12 @@ spec: value: 40000915ab58c3fa8fd888fb8b24711944e6cbb4 - name: SENTINEL_ID_2 value: 2bbec7894d954a8af3bb54d13eaec53cb024e2ca - image: redis:7.0.15-alpine + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent name: split-brain-fix resources: {} @@ -3005,7 +3077,12 @@ spec: value: 40000915ab58c3fa8fd888fb8b24711944e6cbb4 - name: SENTINEL_ID_2 value: 2bbec7894d954a8af3bb54d13eaec53cb024e2ca - image: redis:7.0.15-alpine + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent name: config-init securityContext:
manifests/install.yaml+79 −0 modified@@ -20474,6 +20474,30 @@ rules: --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +rules: +- apiGroups: + - "" + resourceNames: + - argocd-redis + resources: + - secrets + verbs: + - get +- apiGroups: + - "" + resources: + - secrets + verbs: + - create +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role metadata: labels: app.kubernetes.io/component: server @@ -20654,6 +20678,22 @@ subjects: --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: argocd-redis +subjects: +- kind: ServiceAccount + name: argocd-redis +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding metadata: labels: app.kubernetes.io/component: server @@ -21372,6 +21412,13 @@ spec: - "" - --appendonly - "no" + - --requirepass $(REDIS_PASSWORD) + env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis image: redis:7.0.15-alpine imagePullPolicy: Always name: redis @@ -21383,6 +21430,23 @@ spec: drop: - ALL readOnlyRootFilesystem: true + initContainers: + - command: + - argocd + - admin + - redis-initial-password + image: quay.io/argoproj/argocd:latest + imagePullPolicy: IfNotPresent + name: secret-init + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault securityContext: runAsNonRoot: true runAsUser: 999 @@ -21427,6 +21491,11 @@ spec: - args: - /usr/local/bin/argocd-repo-server env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_RECONCILIATION_TIMEOUT valueFrom: configMapKeyRef: @@ -21712,6 +21781,11 @@ spec: - args: - /usr/local/bin/argocd-server env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_SERVER_INSECURE valueFrom: configMapKeyRef: @@ -22034,6 +22108,11 @@ spec: - args: - /usr/local/bin/argocd-application-controller env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_CONTROLLER_REPLICAS value: "1" - name: ARGOCD_RECONCILIATION_TIMEOUT
manifests/namespace-install.yaml+79 −0 modified@@ -241,6 +241,30 @@ rules: --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +rules: +- apiGroups: + - "" + resourceNames: + - argocd-redis + resources: + - secrets + verbs: + - get +- apiGroups: + - "" + resources: + - secrets + verbs: + - create +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role metadata: labels: app.kubernetes.io/component: server @@ -349,6 +373,22 @@ subjects: --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: argocd-redis +subjects: +- kind: ServiceAccount + name: argocd-redis +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding metadata: labels: app.kubernetes.io/component: server @@ -1033,6 +1073,13 @@ spec: - "" - --appendonly - "no" + - --requirepass $(REDIS_PASSWORD) + env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis image: redis:7.0.15-alpine imagePullPolicy: Always name: redis @@ -1044,6 +1091,23 @@ spec: drop: - ALL readOnlyRootFilesystem: true + initContainers: + - command: + - argocd + - admin + - redis-initial-password + image: quay.io/argoproj/argocd:latest + imagePullPolicy: IfNotPresent + name: secret-init + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault securityContext: runAsNonRoot: true runAsUser: 999 @@ -1088,6 +1152,11 @@ spec: - args: - /usr/local/bin/argocd-repo-server env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_RECONCILIATION_TIMEOUT valueFrom: configMapKeyRef: @@ -1373,6 +1442,11 @@ spec: - args: - /usr/local/bin/argocd-server env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_SERVER_INSECURE valueFrom: configMapKeyRef: @@ -1695,6 +1769,11 @@ spec: - args: - /usr/local/bin/argocd-application-controller env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis - name: ARGOCD_CONTROLLER_REPLICAS value: "1" - name: ARGOCD_RECONCILIATION_TIMEOUT
reposerver/repository/repository_test.go+1 −1 modified@@ -199,7 +199,7 @@ func TestGenerateYamlManifestInDir(t *testing.T) { } // update this value if we add/remove manifests - const countOfManifests = 48 + const countOfManifests = 50 res1, err := service.GenerateManifest(context.Background(), &q)
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
11- github.com/advisories/GHSA-9766-5277-j5hrghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2024-31989ghsaADVISORY
- github.com/argoproj/argo-cd/commit/2de0ceade243039c120c28374016c04ff9590d1dghsax_refsource_MISCWEB
- github.com/argoproj/argo-cd/commit/35a7d6c7fa1534aceba763d6a68697f36c12e678ghsax_refsource_MISCWEB
- github.com/argoproj/argo-cd/commit/4e2fe302c3352a0012ecbe7f03476b0e07f7fc6cghsax_refsource_MISCWEB
- github.com/argoproj/argo-cd/commit/53570cbd143bced49d4376d6e31bd9c7bd2659ffghsax_refsource_MISCWEB
- github.com/argoproj/argo-cd/commit/6ef7b62a0f67e74b4aac2aee31c98ae49dd95d12ghsax_refsource_MISCWEB
- github.com/argoproj/argo-cd/commit/9552034a80070a93a161bfa330359585f3b85f07ghsax_refsource_MISCWEB
- github.com/argoproj/argo-cd/commit/bdd889d43969ba738ddd15e1f674d27964048994ghsax_refsource_MISCWEB
- github.com/argoproj/argo-cd/commit/f1a449e83ee73f8f14d441563b6a31b504f8d8b0ghsax_refsource_MISCWEB
- github.com/argoproj/argo-cd/security/advisories/GHSA-9766-5277-j5hrghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.