diff --git a/README.md b/README.md index 59ba6a1..813585a 100644 --- a/README.md +++ b/README.md @@ -57,10 +57,10 @@ To only disable comparing the variable file to the template, set To run only the tasks related to some of the services, this way doing a partial deployment, you can set the `TAGS` environment variable before calling -`make`. For example, to run only the tasks to deploy Redis and Redis +`make`. For example, to run only the tasks to deploy Redict and Redis Commander, run: - $ DEPLOYMENT=dev TAGS="redis,redis-commander" make deploy + $ DEPLOYMENT=dev TAGS="redict,redis-commander" make deploy Use `make tags` to list the currently available tags. diff --git a/docs/deployment/specifics/redict.md b/docs/deployment/specifics/redict.md new file mode 100644 index 0000000..29a563e --- /dev/null +++ b/docs/deployment/specifics/redict.md @@ -0,0 +1,71 @@ +--- +title: Redict +--- + +## Seamless migration between providers + +We have tested a seamless migration from Redis to Redict on our production +deployment. To reproduce: + +1. We have deployed Redict to our production cluster. + + - Defaults have been changed to: + + ```yaml + with_redis: false + with_redict: true + ``` + + These can be changed in their respective `vars/` files. + + - Run + + ``` + DEPLOYMENT=prod TAGS=redict make deploy + ``` + +2. Using remote shell and `redict-cli` run: + + ```sh + replicaof redis 6379 + ``` + + This converts the Redict instance into a read-only replica of the Redis. + +3. After the data exchange is done, change **all** references in variables to + redis to point to the new hostname, in this case `redis → redict`. + + - Run + + ``` + DEPLOYMENT=prod TAGS=packit-service-beat,fedmsg,packit-worker,packit-service make deploy + ``` + +4. Simultaneously run the deployment with the changed hostnames and via + `redict-cli` run: + + ```sh + replicaof no one + ``` + + to make the redict deployment the primary one. + +5. (optional) For safety reasons and easier rollback, it's possible to convert + the former Redis deployment into a replica of Redict, just in case it needs + to be reverted without loss of data. For this you can run in `redis-cli`: + + ```sh + replicaof redict 6379 + ``` + +:::warning References to Redis + +Redis is being referenced from: + +- `packit-service` (API endpoint) +- `packit-service-fedmsg` (Fedora Messaging listener) +- `packit-service-beat` (triggers periodic tasks) +- `packit-worker` (runs the jobs provided by API, Fedora Messaging and “beat”) +- `flower` (monitoring of the Celery queues) + +::: diff --git a/openshift/flower.yml.j2 b/openshift/flower.yml.j2 index 5f01fa5..a1c566b 100644 --- a/openshift/flower.yml.j2 +++ b/openshift/flower.yml.j2 @@ -23,7 +23,7 @@ spec: image: quay.io/packit/flower env: - name: CELERY_BROKER_URL - value: redis://redis:6379/0 + value: redis://{{ redis_hostname }}:6379/0 - name: FLOWER_PORT value: "5555" ports: diff --git a/openshift/packit-service-beat.yml.j2 b/openshift/packit-service-beat.yml.j2 index afca64e..c2a23e0 100644 --- a/openshift/packit-service-beat.yml.j2 +++ b/openshift/packit-service-beat.yml.j2 @@ -41,7 +41,7 @@ spec: - name: APP value: {{ celery_app }} - name: REDIS_SERVICE_HOST - value: redis + value: {{ redis_hostname }} - name: POSTGRESQL_USER valueFrom: {secretKeyRef: {name: postgres-secret, key: database-user}} - name: POSTGRESQL_PASSWORD diff --git a/openshift/packit-service-fedmsg.yml.j2 b/openshift/packit-service-fedmsg.yml.j2 index 61bf6d6..871dab0 100644 --- a/openshift/packit-service-fedmsg.yml.j2 +++ b/openshift/packit-service-fedmsg.yml.j2 @@ -33,7 +33,7 @@ spec: - name: FEDORA_MESSAGING_CONF value: /home/packit/.config/fedora.toml - name: REDIS_SERVICE_HOST - value: redis + value: {{ redis_hostname }} - name: PROJECT value: {{ project }} - name: DEPLOYMENT diff --git a/openshift/packit-service.yml.j2 b/openshift/packit-service.yml.j2 index c136ddc..fd2b0e2 100644 --- a/openshift/packit-service.yml.j2 +++ b/openshift/packit-service.yml.j2 @@ -52,7 +52,7 @@ spec: - name: DISTGIT_NAMESPACE value: {{ distgit_namespace }} - name: REDIS_SERVICE_HOST - value: redis + value: {{ redis_hostname }} - name: POSTGRESQL_USER valueFrom: {secretKeyRef: {name: postgres-secret, key: database-user}} - name: POSTGRESQL_PASSWORD diff --git a/openshift/packit-worker.yml.j2 b/openshift/packit-worker.yml.j2 index a4fbe3b..8e299b4 100644 --- a/openshift/packit-worker.yml.j2 +++ b/openshift/packit-worker.yml.j2 @@ -86,7 +86,7 @@ spec: - name: APP value: {{ celery_app }} - name: REDIS_SERVICE_HOST - value: redis + value: {{ redis_hostname }} - name: POSTGRESQL_USER valueFrom: {secretKeyRef: {name: postgres-secret, key: database-user}} - name: POSTGRESQL_PASSWORD diff --git a/openshift/redict.yml.j2 b/openshift/redict.yml.j2 new file mode 100644 index 0000000..6486950 --- /dev/null +++ b/openshift/redict.yml.j2 @@ -0,0 +1,79 @@ +# Copyright Contributors to the Packit project. +# SPDX-License-Identifier: MIT + +--- +kind: Deployment +apiVersion: apps/v1 +metadata: + name: redict +spec: + selector: + matchLabels: + component: redict + template: + metadata: + labels: + component: redict +{% if managed_platform %} + paas.redhat.com/appcode: {{ appcode }} +{% endif %} + spec: + containers: + - name: redict + image: registry.redict.io/redict:7 + ports: + - containerPort: 6379 + volumeMounts: + - mountPath: /data + name: redict-pv + resources: + # requests and limits have to be the same to have Guaranteed QoS + requests: + memory: "128Mi" + cpu: "10m" + limits: + memory: "256Mi" + cpu: "10m" + volumes: + - name: redict-pv + persistentVolumeClaim: + claimName: redict-pvc + replicas: 1 + strategy: + type: Recreate +--- +apiVersion: v1 +kind: Service +metadata: + name: redict +{% if managed_platform %} + labels: + paas.redhat.com/appcode: {{ appcode }} +{% endif %} +spec: + ports: + - name: "6379" + port: 6379 + targetPort: 6379 + selector: + component: redict +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: redict-pvc +{% if managed_platform %} + labels: + paas.redhat.com/appcode: {{ appcode }} + annotations: + kubernetes.io/reclaimPolicy: Delete +{% endif %} +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi +{% if managed_platform %} + storageClassName: aws-ebs +{% endif %} diff --git a/openshift/redis-commander.yml.j2 b/openshift/redis-commander.yml.j2 index da30abc..608abf2 100644 --- a/openshift/redis-commander.yml.j2 +++ b/openshift/redis-commander.yml.j2 @@ -23,7 +23,7 @@ spec: image: rediscommander/redis-commander env: - name: REDIS_HOST - value: redis + value: {{ redis_hostname }} - name: REDIS_PORT value: "6379" - name: HTTP_USER diff --git a/playbooks/deploy.yml b/playbooks/deploy.yml index ad02028..61b6285 100644 --- a/playbooks/deploy.yml +++ b/playbooks/deploy.yml @@ -12,6 +12,8 @@ tenant: packit # MP+ tenant with_tokman: true with_fedmsg: true + with_redis: false + with_redict: true with_redis_commander: false with_flower: false with_dashboard: true @@ -183,9 +185,20 @@ ansible.builtin.include_tasks: tasks/k8s.yml loop: - "{{ lookup('template', '{{ project_dir }}/openshift/redis.yml.j2') }}" + when: with_redis tags: - redis + - name: Deploy redict + vars: + k8s_apply: true + ansible.builtin.include_tasks: tasks/k8s.yml + loop: + - "{{ lookup('template', '{{ project_dir }}/openshift/redict.yml.j2') }}" + when: with_redict + tags: + - redict + - name: Deploy fluentd image stream and config ansible.builtin.include_tasks: tasks/k8s.yml loop: diff --git a/playbooks/tasks/set-deployment-facts.yml b/playbooks/tasks/set-deployment-facts.yml index 64238a7..10987dc 100644 --- a/playbooks/tasks/set-deployment-facts.yml +++ b/playbooks/tasks/set-deployment-facts.yml @@ -9,10 +9,10 @@ ansible.builtin.set_fact: mandatory_deploymentconfigs: - postgres-{{ postgres_version }} - - redis - packit-service tags: - always + - name: Set optional_deploymentconfigs fact ansible.builtin.set_fact: optional_deploymentconfigs: @@ -22,8 +22,11 @@ packit-dashboard: "{{ with_dashboard }}" pushgateway: "{{ with_pushgateway }}" nginx: "{{ with_pushgateway }}" + redis: "{{ with_redis }}" + redict: "{{ with_redict }}" tags: - always + - name: Set deploymentconfigs fact ansible.builtin.set_fact: # To know what DCs rollouts to wait for and also to check in tests diff --git a/playbooks/tasks/set-facts.yml b/playbooks/tasks/set-facts.yml index 120bd3c..8110128 100644 --- a/playbooks/tasks/set-facts.yml +++ b/playbooks/tasks/set-facts.yml @@ -27,3 +27,31 @@ ansible.builtin.set_fact: sandbox_namespace: "{{ service }}-{{ deployment }}-sandbox" when: not managed_platform + +- name: Set Redis-like hostname + tags: + - always + block: + # Needed for nice message of the sanity check + - name: Set default for the hostname + ansible.builtin.set_fact: + redis_hostname: None + + - name: Set Redict as the hostname + ansible.builtin.set_fact: + redis_hostname: redict + when: with_redict + + - name: Set Redis as the hostname (backward compatibility) + ansible.builtin.set_fact: + redis_hostname: redis + when: with_redis + + - name: Sanity check for deploying exactly one of Redis or Redict + ansible.builtin.assert: + that: with_redict != with_redis + success_msg: | + [INFO] Deploying {{ redis_hostname }} + fail_msg: | + [FAIL] Check vars (‹with_redict› and ‹with_redis›). + Cannot deploy none or both of Redis and Redict!