# Ingress-Nginx in Kubernetes

## Prerequisites <a href="#prerequisites" id="prerequisites"></a>

* [`kubectl`should be installed](https://kubernetes.io/docs/tasks/tools/) in the local environment or the machine that will be used for the deployment.
* [Helm should be installed](https://helm.sh/docs/intro/install/) in the local environment or the machine that will be used for deployment.
* [Install Ingress-Nginx Controller](https://kubernetes.github.io/ingress-nginx/deploy/)

## Install Ingress-Nginx using a Helm chart (recommended)

### Configure the Helm Chart

1. Clone the GitHub repository containing the Helm charts from the [GitHub URL](https://github.com/e6x-labs/helm-charts) or the command provided below:

   `git clone git@github.com:e6x-labs/helm-charts.git`
2. **Customize Chart Values:** Navigate to the cloned Helm chart directory (`./charts/ingress/` ) and modify the values in the `values.yaml` file or create a custom value file.
   * This file contains configuration options that customize the behavior of the chart during deployment. You can adjust parameters such as the image version, service type, ingress settings, etc., based on your requirements.
   * It is mandatory to edit the following values in the `values.yaml` file:

```yaml
cloud: <CLOUD_PROVIDER>
alias: <ALIAS_NAME>
workspace: <WORKSPACE_NAME>
cluster: <CLUSTER_NAME>
```

### **Deploy the Helm Chart**

Use the `helm install` command to deploy the Helm chart. Provide a release name for the deployment and specify the path to the chart directory. For example:

`helm install <RELEASE_NAME> ./charts/ingress/`

The above command deploys the Helm chart with `<RELEASE_NAME>` using the configuration from the `./charts/ingress/` directory.

`<RELEASE_NAME>` can be set to any value.

### **Verify Deployment**

Use the following `kubectl` commands to verify that the Kubernetes resources (services & ingresses) have been created and are running as expected:

```bash
kubectl get services -n <E6DATA_NAMESPACE>
kubectl get ingress -n <E6DATA_NAMESPACE>
```

{% hint style="success" %}
If the Ingress resource has been set up correctly and the e6data engine is exposed externally, external tools & services can now connect to it using the configured hostname or IP address.

A [Personal Access Token](https://docs.e6data.com/product-documentation/~/revisions/W5MExJCuvHiG1ioEcgOy/connectors-and-drivers/configure-cluster-ingress/broken-reference) is required for authentication.
{% endhint %}

## Install Ingress-Nginx using kubectl

## Create Service

Create a service file, following the example below:

{% hint style="warning" %}
A separate Service should be created for each e6data cluster (if external access is required for multiple clusters).
{% endhint %}

{% file src="<https://3484040590-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeVBYKZm1xFKFFVzS0lRJ%2Fuploads%2Fag3FMst5z0733GA2v85m%2Fe6data-ext-access-service-ingress-nginx.yaml?alt=media&token=87ccf375-22b7-4b37-91f7-d6352a65ce05>" %}
Download the Ingress-Nginx service file template
{% endfile %}

<details>

<summary>Sample e6data-ext-access-service-ingress-nginx.yaml</summary>

<pre class="language-yaml" data-title="e6data-ext-access-service.yaml"><code class="lang-yaml">apiVersion: v1
kind: Service
metadata:
  name: e6data-ext-access-cluster1  # edit as required
  namespace: e6data # change to e6data workspace namespace
  labels:
    cloud: &#x3C;CLOUD_PROVIDER>
    alias: &#x3C;ALIAS>
    workspace: &#x3C;WORKSPACE_NAME>
    cluster: &#x3C;CLUSTER_NAME>
  annotations:
    nginx.ingress.kubernetes.io/whitelist-source-range: "&#x3C;IP(S)_TO_BE_ALLOWLISTED>"
<strong>    nginx.ingress.kubernetes.io/ssl-certificate: "&#x3C;CERT(S)_SECRET_NAME>"
</strong>spec:
  type: ClusterIP
  selector:
    cloud: &#x3C;CLOUD_PROVIDER>
    alias: &#x3C;ALIAS>
    workspace: &#x3C;WORKSPACE_NAME>
    cluster: &#x3C;CLUSTER_NAME>
  ports:
  - protocol: TCP
    port: 9000                  # external access port, edit as required
    targetPort: http            # change to HTTPS if SSL certificate is used
    name: http                  # change to HTTPS if SSL certificate is used
</code></pre>

</details>

To create the Service, apply the manifest to the cluster by running this command:

`kubectl apply -f e6data-ext-access-service.yaml`

{% hint style="info" %}
To enable access to multiple clusters, please repeat[ the steps above](#create-service) to create a separate service file for each cluster.
{% endhint %}

## Create Ingress

{% hint style="info" %}

* To expose a single cluster; one service file & one ingress file is required.
* To expose multiple clusters; multiple service files (for each cluster) & one ingress file with multiple paths are required.
  {% endhint %}

Create the ingress file following the examples below:

#### Expose a Single Cluster

{% file src="<https://3484040590-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeVBYKZm1xFKFFVzS0lRJ%2Fuploads%2FuS86OSFrwJ6wXd9yzmvg%2Fe6data-ingress-nginx-single-cluster.yaml?alt=media&token=9c79ad11-3575-4af1-a553-1a972d317192>" %}
Download the Ingress-Nginx ingress file template for single cluster scenarios
{% endfile %}

<details>

<summary>Sample e6data-ingress-nginx-single-cluster.yaml</summary>

{% code title="e6data-ingress-nginx-single-cluster.yaml" %}

```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: e6data-ext-access
  namespace: default
  labels:
    cloud: <CLOUD_PROVIDER>
    alias: <ALIAS>
    workspace: <WORKSPACE_NAME>
    cluster: <CLUSTER_NAME>
  #annotations:                          # Uncomment for GKE Ingress Controller
    #kubernetes.io/ingress.class: "nginx"
spec:
  ingressClassName: nginx                # Comment out for GKE Ingress Controller
  rules:
    - host: ""                           # optional, domain name
      http:
        paths:
          - path: /
            pathType: ImplementationSpecific  
            backend:
              service:
                name: e6data-ext-access-cluster1  # match the service name
                port:
                  number: 9000
```

{% endcode %}

</details>

#### Expose Multiple Clusters

{% file src="<https://3484040590-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeVBYKZm1xFKFFVzS0lRJ%2Fuploads%2FXMTWbd0s1kY9yodJpnmM%2Fe6data-ingress-nginx-multiple-clusters.yaml?alt=media&token=268d6b95-a1da-423d-8e3d-fb028fbe4fa9>" %}
Download the Ingress-Nginx ingress file template for multiple cluster scenarios
{% endfile %}

<details>

<summary>Sample e6data-ingress-nginx-multiple-clusters.yaml</summary>

{% code title="e6data-ingress-nginx-multiple-clusters.yaml" %}

```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: e6data-ext-access
  namespace: e6data
  labels:
    cloud: <CLOUD_PROVIDER>
    cluster: [<CLUSTER1_NAME>,[<CLUSTER2_NAME>]
    alias: <ALIAS>
    workspace: [<WORKSPACE1>,<WORKSPACE2>]
spec:
  ingressClassName: nginx
  rules:
    - host: ""                                    # optional, domain name
      http:
        paths:
          - path: /<CLUSTER1_NAME>                # edit as required
            pathType: ImplementationSpecific  
            backend:
              service:
                name: e6data-ext-access-cluster1  # match the service name
                port:
                  number: 9000
          - path: /<CLUSTER2_NAME>                # edit as required
            pathType: ImplementationSpecific  
            backend:
              service:
                name: e6data-ext-access-cluster2  # match the service name
                port:
                  number: 9000
```

{% endcode %}

</details>

To create the Ingress resource, apply the manifest to the cluster:

`kubectl apply -f e6data-ingress.yaml`

### Expose Ports Externally

There are three steps required to externally expose a TCP port:

1. Create a ConfigMap.
2. If TCP proxy support is used, then those ports need to be exposed in the Service defined for the Ingress.
3. Add the ConfigMap to the Ingress Controller's deployment arguments.

Please refer to the [official Ingress-Nginx documentation](https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/exposing-tcp-udp-services.md) for detailed instructions to externally expose a TCP port according to your requirements.

A sample ConfigMap is provided below:

{% code title="e6data-ingress-configmap.yaml" %}

```json
apiVersion: v1
kind: ConfigMap
metadata:
  name: e6data-ext-tcp
  namespace: <E6DATA_K8_NAMESPACE>
data:
  9000: "<E6DATA_K8_NAMESPACE>/<SERVICE_NAME>:9000" # replace default with the e6data k8s namespace
```

{% endcode %}

After the required port is externally exposed, the process is complete.

{% hint style="success" %}
Ingress has now been created and external tools will be able to access the e6data cluster using the configured port/s (9000 in this example).
{% endhint %}
