Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Doc-734 k8s ingress #1476

Merged
merged 30 commits into from
Aug 18, 2021
Merged
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
9662e84
intro
kaitlynmichael Jul 29, 2021
9ffca73
HAProxy step 1-6
kaitlynmichael Aug 5, 2021
28b4f4d
hostname section + step 7
kaitlynmichael Aug 5, 2021
878cc42
edits
kaitlynmichael Aug 5, 2021
8f2a8a9
nginx step 1-6
kaitlynmichael Aug 5, 2021
981db4e
step 9
kaitlynmichael Aug 5, 2021
c360904
remove ldr from examples
kaitlynmichael Aug 9, 2021
e7afac5
removed unnecessary info
kaitlynmichael Aug 10, 2021
d07f54b
prereq rewrite
kaitlynmichael Aug 10, 2021
4a3311c
relref reformat
kaitlynmichael Aug 10, 2021
003de7e
ingress resource and ssl passthrough details
kaitlynmichael Aug 10, 2021
da05eab
revised background info section
kaitlynmichael Aug 10, 2021
e33f72d
small format change
kaitlynmichael Aug 10, 2021
c120863
get hostname
kaitlynmichael Aug 11, 2021
fe1789e
remove unnecessary detail, reword
kaitlynmichael Aug 11, 2021
15d2e5a
reword
kaitlynmichael Aug 11, 2021
148ff48
reword
kaitlynmichael Aug 11, 2021
b41d787
Merge branch 'master' into DOC-734
kaitlynmichael Aug 12, 2021
91b1409
added test your access
kaitlynmichael Aug 12, 2021
41a2dc0
review feedback changes
kaitlynmichael Aug 13, 2021
7fbbbf8
Update content/platforms/kubernetes/tasks/set-up-ingress-controller.md
kaitlynmichael Aug 16, 2021
b3ac767
Update content/platforms/kubernetes/tasks/set-up-ingress-controller.md
kaitlynmichael Aug 16, 2021
2cb6283
Update content/platforms/kubernetes/tasks/set-up-ingress-controller.md
kaitlynmichael Aug 16, 2021
67243c2
new steps for hostname and DNS, editorial changes
kaitlynmichael Aug 17, 2021
0fcb3af
text box spacing
kaitlynmichael Aug 17, 2021
bfe4095
remove code fences
kaitlynmichael Aug 18, 2021
835fc7e
description
kaitlynmichael Aug 18, 2021
6bb10ab
Merge branch 'master' into DOC-734
kaitlynmichael Aug 18, 2021
a27491c
remove namespace argument
kaitlynmichael Aug 18, 2021
53562e0
remove fences, only indents
kaitlynmichael Aug 18, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 137 additions & 0 deletions content/platforms/kubernetes/tasks/set-up-ingress-controller.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
---
Title: Establish external routing with an ingress controller
linkTitle: Configure ingress
description: Configure an ingress controller to access your Redis Enterprise databases from outside the Kubernetes cluster.
weight: 25
alwaysopen: false
categories: [""]
aliases:
---

Every time a Redis Enterprise Database (REDB) is created in a Kubernetes (K8s) environment, a [service](https://kubernetes.io/docs/concepts/services-networking/service/) is created that allows requests to be routed to that database. Redis Enterprise supports three [types of services](https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types) for accessing databases: `ClusterIP`, `headless`, or `LoadBalancer`.

By default, REDB creates a `ClusterIP` type service, which exposes a cluster-internal IP and can only be accessed from within the K8s cluster. For requests to be routed to the REDB from outside the K8s cluster, you need an [ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/) controller.

Redis Enterprise Software on Kubernetes supports two ingress controllers, [HAProxy](https://haproxy-ingress.github.io/) and [NGINX](https://kubernetes.github.io/ingress-nginx/).

## Prerequisites

### Redis Enterprise database (REDB)

Create a Redis Enterprise database with "TLS for all communication" enabled and "client authentication" disabled.

The YAML to create this REDB must include `tlsMode: enabled` as shown in this example:

apiVersion: app.redislabs.com/v1alpha1
kind: RedisEnterpriseDatabase
metadata:
name: <your-db-name>
spec:
tlsMode: enabled

##### If you choose to use a previously created database:

If you are using an existing REDB that was created with a YAML file, you cannot make edits to that database in the Redis Enterprise UI. All changes need to be made in the YAML file.

If you are using an existing database that is managed from the UI, see [Enable TLS for client connections]({{< relref "content/rs/security/tls-ssl.md" >}}) for more information on these security settings.

### Ingress controller

Install one of the supported ingress controllers:

- [NGINX Ingress Controller Installation Guide](https://kubernetes.github.io/ingress-nginx/deploy/)
- [HAProxy Ingress Getting Started](https://haproxy-ingress.github.io/docs/getting-started/)

{{< warning >}}You'll need to make sure `ssl-passthrough` is enabled. It's enabled by default for HAProxy, but disabled by default for NGINX. See the [NGINX User Guide](https://kubernetes.github.io/ingress-nginx/user-guide/tls/#ssl-passthrough) for details. {{< /warning >}}

## Create ingress resource

1. Retrieve the hostname of your ingress controller's `LoadBalancer` service with `kubectl get svc <ingress-cntrl>-ingress -n ingress-controller`.

$ kubectl get svc <haproxy-ingress | ingress-ngnix-controller> -n

Below is example output for an HAProxy ingress controller running on a K8s cluster hosted by AWS.


NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
haproxy-ingress LoadBalancer 10.43.62.53 a56e24df8c6173b79a63d5da54fd9cff-676486416.us-east-1.elb.amazonaws.com 80:30610/TCP,443:31597/TCP 21m

1. Choose the hostname you will use to access your database (this value will be represented in this article with `<my-db-hostname>`).

1. Create a DNS entry that resolves your chosen database hostname to the IP address for the ingress controller's LoadBalancer.

1. Create the ingress resource YAML file.

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: rec-ingress
annotations:
<controller-specific-annotations-below>
spec:
rules:
- host: <my-db-hostname>
http:
paths:
- path: /
backend:
serviceName: <db-name>
servicePort: 443


For HAProxy, insert the following into the `annotations` section:

haproxy.ingress.kubernetes.io/ssl-passthrough: "true"
kubernetes.io/ingress.class: haproxy

For NGINX, insert the following into the `annotations` section:

nginx.ingress.kubernetes.io/ssl-passthrough: "true"

The `ssl-passthrough` annotation is required to allow access to the database. The specific format changes depending on which ingress controller you have. See [NGINX Configuration annotations](https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/) and [HAProxy Ingress Options](https://www.haproxy.com/documentation/kubernetes/latest/configuration/ingress/) for updated annotation formats.

## Test your external access

To test your external access to the database, you need a client that supports [TLS](https://en.wikipedia.org/wiki/Transport_Layer_Security) and [SNI](https://en.wikipedia.org/wiki/Server_Name_Indication).

#### Test your access with Openssl

1. Get the default CA certificate from the `redis-enterprise-node` container on any of the Redis Enterprise pods.

kubectl exec -it <pod-name> -c redis-enterprise-node -- cat /etc/opt/redislabs/proxy_cert.pem

1. Run the following `openssl` command, substituting your own values for `<my-db-hostname>`.

openssl s_client \
-connect <my-db-hostname>:443 \
-crlf -CAfile ./proxy_cert.pem \
-servername <my-db-hostname>

If you are connected to the database, you will receive `PONG` back, as shown below:

...
Verify return code: 0 (ok)
---

PING
+PONG

#### Test your access with Python

You can use the code below to test your access with Python, substituting your own values for `<my-db-hostname>` and `<file-path>`.

import redis

r = redis.StrictRedis(host='<my-db-hostname>',
port=443, db=0, ssl=True,
ssl_ca_certs='/<file-path>/proxy_cert.pem')


print(r.info())

Your output should look something like this:

/Users/example-user/Documents/Projects/test_client/venv3.7/bin/python /Users/example-user/Documents/Projects/test_client/test_ssl.py
{'redis_version': '5.0.5', 'redis_git_sha1': 0, 'redis_git_dirty': 0, 'redis_build_id': 0, 'redis_mode': 'standalone', 'os': 'Linux 4.14.154-128.181.amzn2.x86_64 x86_64', 'arch_bits': 64, 'multiplexing_api': 'epoll', 'gcc_version': '7.4.0', 'process_id': 1, 'run_id': '3ce7721b096517057d28791aab555ed8ac02e1de', 'tcp_port': 10811, 'uptime_in_seconds': 316467, 'uptime_in_days': 3, 'hz': 10, 'lru_clock': 0, 'config_file': '', 'connected_clients': 1, 'client_longest_output_list': 0, 'client_biggest_input_buf': 0, 'blocked_clients': 0, 'used_memory': 12680016, 'used_memory_human': '12.9M', 'used_memory_rss': 12680016, 'used_memory_peak': 13452496, 'used_memory_peak_human': '12.82M', 'used_memory_lua': 151552, 'mem_fragmentation_ratio': 1, 'mem_allocator': 'jemalloc-5.1.0', 'loading': 0, 'rdb_changes_since_last_save': 0, 'rdb_bgsave_in_progress': 0, 'rdb_last_save_time': 1577753916, 'rdb_last_bgsave_status': 'ok', 'rdb_last_bgsave_time_sec': 0, 'rdb_current_bgsave_time_sec': -1, 'aof_enabled': 0, 'aof_rewrite_in_progress': 0, 'aof_rewrite_scheduled': 0, 'aof_last_rewrite_time_sec': -1, 'aof_current_rewrite_time_sec': -1, 'aof_last_bgrewrite_status': 'ok', 'aof_last_write_status': 'ok', 'total_connections_received': 4, 'total_commands_processed': 6, 'instantaneous_ops_per_sec': 14, 'total_net_input_bytes': 0, 'total_net_output_bytes': 0, 'instantaneous_input_kbps': 0.0, 'instantaneous_output_kbps': 0.0, 'rejected_connections': 0, 'sync_full': 1, 'sync_partial_ok': 0, 'sync_partial_err': 0, 'expired_keys': 0, 'evicted_keys': 0, 'keyspace_hits': 0, 'keyspace_misses': 0, 'pubsub_channels': 0, 'pubsub_patterns': 0, 'latest_fork_usec': 0, 'migrate_cached_sockets': 0, 'role': 'master', 'connected_slaves': 1, 'slave0': {'ip': '0.0.0.0', 'port': 0, 'state': 'online', 'offset': 0, 'lag': 0}, 'master_repl_offset': 0, 'repl_backlog_active': 0, 'repl_backlog_size': 1048576, 'repl_backlog_first_byte_offset': 0, 'repl_backlog_histlen': 0, 'used_cpu_sys': 0.0, 'used_cpu_user': 0.0, 'used_cpu_sys_children': 0.0, 'used_cpu_user_children': 0.0, 'cluster_enabled': 0}

Process finished with exit code 0