copyright | lastupdated | ||
---|---|---|---|
|
2018-04-11 |
{:new_window: target="_blank"} {:shortdesc: .shortdesc} {:screen: .screen} {:pre: .pre} {:table: .aria-labeledby="caption"} {:codeblock: .codeblock} {:tip: .tip} {:download: .download}
{: #ingress}
Expose multiple apps in your Kubernetes cluster by creating Ingress resources that are managed by the IBM-provided application load balancer in {{site.data.keyword.containerlong}}. {:shortdesc}
{: #planning}
Ingress is a Kubernetes service that balances network traffic workloads in your cluster by forwarding public or private requests to your apps. You can use Ingress to expose multiple app services to the public or to a private network by using a unique public or private route. {:shortdesc}
Ingress consists of two components:
- Application load balancer
- The application load balancer (ALB) is an external load balancer that listens for incoming HTTP, HTTPS, TCP, or UDP service requests and forwards requests to the appropriate app pod. When you create a standard cluster, {{site.data.keyword.containershort_notm}} automatically creates a highly available ALB for your cluster and assigns a unique public route to it. The public route is linked to a portable public IP address that is provisioned into your IBM Cloud infrastructure (SoftLayer) account during cluster creation. A default private ALB is also automatically created, but is not automatically enabled.
- Ingress resource
- To expose an app by using Ingress, you must create a Kubernetes service for your app and register this service with the ALB by defining an Ingress resource. The Ingress resource is a Kubernetes resource that defines the rules for how to route incoming requests for an app. The Ingress resource also specifies the path to your app service, which is appended to the public route to form a unique app URL such as `mycluster.us-south.containers.mybluemix.net/myapp`.
The following diagram shows how Ingress directs communication from the internet to an app:
-
A user sends a request to your app by accessing your app's URL. This URL is the public URL for your exposed app with the Ingress resource path appended to it, such as
mycluster.us-south.containers.mybluemix.net/myapp
. -
A DNS system service that acts as the global load balancer resolves the URL to the portable public IP address of the default public ALB in the cluster.
-
kube-proxy
routes the request to the Kubernetes ALB service for the app. -
The Kubernetes service routes the request to the ALB.
-
The ALB checks if a routing rule for the
myapp
path in the cluster exists. If a matching rule is found, the request is forwarded according to the rules that you defined in the Ingress resource to the pod where the app is deployed. If multiple app instances are deployed in the cluster, the ALB load balances the requests between the app pods.
Note: Ingress is available for standard clusters only and requires at least two worker nodes in the cluster to ensure high availability and that periodic updates are applied. Setting up Ingress requires an Administrator access policy. Verify your current access policy.
To choose the best configuration for Ingress, you can follow this decision tree:
{: #ingress_expose_public}
When you create a standard cluster, an IBM-provided application load balancer (ALB) is automatically enabled and is assigned a portable public IP address and a public route. {:shortdesc}
Every app that is exposed to the public via Ingress is assigned a unique path that is appended to the public route, so that you can use a unique URL to access an app publicly in your cluster. To expose your app to the public, you can configure Ingress for the following scenarios.
- Publicly expose apps using the IBM-provided domain without TLS
- Publicly expose apps using the IBM-provided domain with TLS
- Publicly expose apps using a custom domain with TLS
- Publicly expose apps that are outside your cluster using the IBM-provided or a custom domain with TLS
{: #ibm_domain}
You can configure the ALB to load balance incoming HTTP network traffic to the apps in your cluster and use the IBM-provided domain to access your apps from the internet. {:shortdesc}
Before you begin:
- If you do not have one already, create a standard cluster.
- Target your CLI to your cluster to run
kubectl
commands.
To expose an app by using the IBM-provided domain:
-
Deploy your app to the cluster. Ensure that you add a label to your deployment in the metadata section of your configuration file, such as
app: code
. This label is needed to identify all pods where your app is running so that the pods can be included in the Ingress load balancing. -
Create a Kubernetes service for the app that you want to expose. Your app must be exposed by a Kubernetes service to be included by the cluster ALB in the Ingress load balancing.
-
Open your preferred editor and create a service configuration file that is named, for example,
myservice.yaml
. -
Define a service for the app that the ALB will expose to the public.
apiVersion: v1 kind: Service metadata: name: <myservice> spec: selector: <selectorkey>: <selectorvalue> ports: - protocol: TCP port: 8080
{: codeblock}
Understanding the ALB service file components -
Save your changes.
-
Create the service in your cluster.
kubectl apply -f myservice.yaml
{: pre}
-
Repeat these steps for every app that you want to expose to the public.
-
-
Get the details for your cluster to view the IBM-provided domain. Replace <mycluster> with the name of the cluster where the app is deployed that you want to expose to the public.
bx cs cluster-get <mycluster>
{: pre}
Your CLI output looks similar to the following.
Retrieving cluster <mycluster>... OK Name: <mycluster> ID: b9c6b00dc0aa487f97123440b4895f2d State: normal Created: 2017-04-26T19:47:08+0000 Location: dal10 Master URL: https://169.57.40.165:1931 Ingress subdomain: <ibmdomain> Ingress secret: <ibmtlssecret> Workers: 3 Version: 1.8.8
{: screen}
You can see the IBM-provided domain in the Ingress subdomain field.
-
Create an Ingress resource. Ingress resources define the routing rules for the Kubernetes service that you created for your app and are used by the ALB to route incoming network traffic to the service. You must use one Ingress resource to define routing rules for multiple apps if every app is exposed via a Kubernetes service inside the cluster.
-
Open your preferred editor and create an Ingress configuration file that is named, for example,
myingress.yaml
. -
Define an Ingress resource in your configuration file that uses the IBM-provided domain to route incoming network traffic to the services that you created earlier.
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: <myingressname> spec: rules: - host: <ibmdomain> http: paths: - path: /<myservicepath1> backend: serviceName: <myservice1> servicePort: 80 - path: /<myservicepath2> backend: serviceName: <myservice2> servicePort: 80
{: codeblock}
Understanding the Ingress resource file components Understanding the YAML file components name
Replace <myingressname> with a name for your Ingress resource. host
Replace <ibmdomain> with the IBM-provided Ingress subdomain name from the previous step.
Note: Do not use * for your host or leave the host property empty to avoid failures during Ingress creation.path
Replace <myservicepath1> with a slash or the unique path that your app is listening on so that network traffic can be forwarded to the app.
For every Kubernetes service, you can define an individual path that is appended to the IBM-provided domain to create a unique path to your app; for exampleingress_domain/myservicepath1
. When you enter this route into a web browser, network traffic is routed to the ALB. The ALB looks up the associated service sends network traffic to the service. The service then forwards the traffic to the pods where the app is running. The app must be set up to listen on this path to receive incoming network traffic.
Many apps do not listen on a specific path, but use the root path and a specific port. In this case, define the root path as/
and do not specify an individual path for your app.
Examples:- For
http://ingress_host_name/
, enter/
as the path. - For
http://ingress_host_name/myservicepath
, enter/myservicepath
as the path.
Tip: To configure Ingress to listen on a path that is different than the path that your app listens on, you can use the rewrite annotation to establish proper routing to your app.serviceName
Replace <myservice1> with the name of the service that you used when you created the Kubernetes service for your app. servicePort
The port that your service listens to. Use the same port that you defined when you created the Kubernetes service for your app. - For
-
Create the Ingress resource for your cluster.
kubectl apply -f myingress.yaml
{: pre}
-
-
Verify that the Ingress resource was created successfully. Replace <myingressname> with the name of the Ingress resource that you created earlier.
kubectl describe ingress <myingressname>
{: pre}
- If messages in the events describe an error in your resource configuration, change the values in your resource file and reapply the file for the resource.
-
In a web browser, enter the URL of the app service to access.
https://<ibmdomain>/<myservicepath1>
{: codeblock}
{: #ibm_domain_cert}
You can configure the Ingress ALB to manage incoming TLS connections for your apps, decrypt the network traffic by using the IBM-provided TLS certificate, and forward the decrypted request to the apps that are exposed in your cluster. {:shortdesc}
Before you begin:
- If you do not have one already, create a standard cluster.
- Target your CLI to your cluster to run
kubectl
commands.
To expose an app by using the IBM-provided domain with TLS:
-
Deploy your app to the cluster. Ensure that you add a label to your deployment in the metadata section of your configuration file, such as
app: code
. This label is needed to identify all pods where your app is running so that the pods can be included in the Ingress load balancing. -
Create a Kubernetes service for the app that you want to expose. Your app must be exposed by a Kubernetes service to be included by the cluster ALB in the Ingress load balancing.
-
Open your preferred editor and create a service configuration file that is named, for example,
myservice.yaml
. -
Define a service for the app that the ALB will expose to the public.
apiVersion: v1 kind: Service metadata: name: <myservice> spec: selector: <selectorkey>: <selectorvalue> ports: - protocol: TCP port: 8080
{: codeblock}
Understanding the ALB service file components -
Save your changes.
-
Create the service in your cluster.
kubectl apply -f myservice.yaml
{: pre}
-
Repeat these steps for every app that you want to expose to the public.
-
-
View the IBM-provided domain and TLS certificate. Replace <mycluster> with the name of the cluster where the app is deployed.
bx cs cluster-get <mycluster>
{: pre}
Your CLI output looks similar to the following.
bx cs cluster-get <mycluster> Retrieving cluster <mycluster>... OK Name: <mycluster> ID: b9c6b00dc0aa487f97123440b4895f2d State: normal Created: 2017-04-26T19:47:08+0000 Location: dal10 Master URL: https://169.57.40.165:1931 Ingress subdomain: <ibmdomain> Ingress secret: <ibmtlssecret> Workers: 3 Version: 1.8.8
{: screen}
You can see the IBM-provided domain in the Ingress subdomain and the IBM-provided certificate in the Ingress secret fields.
-
Create an Ingress resource. Ingress resources define the routing rules for the Kubernetes service that you created for your app and are used by the ALB to route incoming network traffic to the service. You must use one Ingress resource to define routing rules for multiple apps if every app is exposed via a Kubernetes service inside the cluster.
-
Open your preferred editor and create an Ingress configuration file that is named, for example,
myingress.yaml
. -
Define an Ingress resource in your configuration file that uses the IBM-provided domain to route incoming network traffic to the services that you created earlier, and your custom certificate to manage the TLS termination.
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: <myingressname> spec: tls: - hosts: - <ibmdomain> secretName: <ibmtlssecret> rules: - host: <ibmdomain> http: paths: - path: /<myservicepath1> backend: serviceName: <myservice1> servicePort: 80 - path: /<myservicepath2> backend: serviceName: <myservice2> servicePort: 80
{: codeblock}
Understanding the Ingress resource file components -
Create the Ingress resource for your cluster.
kubectl apply -f myingress.yaml
{: pre}
-
-
Verify that the Ingress resource was created successfully. Replace <myingressname> with the name of the Ingress resource that you created earlier.
kubectl describe ingress <myingressname>
{: pre}
- If messages in the events describe an error in your resource configuration, change the values in your resource file and reapply the file for the resource.
-
In a web browser, enter the URL of the app service to access.
https://<ibmdomain>/<myservicepath1>
{: codeblock}
{: #custom_domain_cert}
You can configure the ALB to route incoming network traffic to the apps in your cluster and use your own TLS certificate to manage the TLS termination, while using your custom domain rather than the IBM-provided domain. {:shortdesc}
Before you begin:
- If you do not have one already, create a standard cluster.
- Target your CLI to your cluster to run
kubectl
commands.
To expose an app by using a custom domain with TLS:
-
Create a custom domain. To create a custom domain, work with your Domain Name Service (DNS) provider or {{site.data.keyword.Bluemix_notm}} to register your custom domain.
-
Configure your domain to route incoming network traffic to the IBM-provided ALB. Choose between these options:
- Define an alias for your custom domain by specifying the IBM-provided domain as a Canonical Name record (CNAME). To find the IBM-provided Ingress domain, run
bx cs cluster-get <mycluster>
and look for the Ingress subdomain field. - Map your custom domain to the portable public IP address of the IBM-provided ALB by adding the IP address as a record. To find the portable public IP address of the ALB, run
bx cs alb-get <public_alb_ID>
.
- Define an alias for your custom domain by specifying the IBM-provided domain as a Canonical Name record (CNAME). To find the IBM-provided Ingress domain, run
-
Either import or create a TLS certificate and key secret:
-
If a TLS certificate is stored in {{site.data.keyword.cloudcerts_long_notm}} that you want to use, you can import its associated secret into your cluster by running the following command:
bx cs alb-cert-deploy --secret-name <secret_name> --cluster <cluster_name_or_ID> --cert-crn <certificate_crn>
{: pre}
-
If you do not have a TLS certificate ready, follow these steps:
-
Create a TLS certificate and key for your domain that is encoded in PEM format.
-
Create a secret that uses your TLS certificate and key. Replace <mytlssecret> with a name for your Kubernetes secret, <tls_key_filepath> with the path to your custom TLS key file, and <tls_cert_filepath> with the path to your custom TLS certificate file.
kubectl create secret tls <mytlssecret> --key <tls_key_filepath> --cert <tls_cert_filepath>
{: pre}
-
-
-
Deploy your app to the cluster. Ensure that you add a label to your deployment in the metadata section of your configuration file, such as
app: code
. This label is needed to identify all pods where your app is running so that the pods can be included in the Ingress load balancing. -
Create a Kubernetes service for the app that you want to expose. Your app must be exposed by a Kubernetes service to be included by the cluster ALB in the Ingress load balancing.
-
Open your preferred editor and create a service configuration file that is named, for example,
myservice.yaml
. -
Define a service for the app that the ALB will expose to the public.
apiVersion: v1 kind: Service metadata: name: <myservice> spec: selector: <selectorkey>: <selectorvalue> ports: - protocol: TCP port: 8080
{: codeblock}
Understanding the ALB service file components -
Save your changes.
-
Create the service in your cluster.
kubectl apply -f myservice.yaml
{: pre}
-
Repeat these steps for every app that you want to expose to the public.
-
-
Create an Ingress resource. Ingress resources define the routing rules for the Kubernetes service that you created for your app and are used by the ALB to route incoming network traffic to the service. You must use one Ingress resource to define routing rules for multiple apps if every app is exposed via a Kubernetes service inside the cluster.
-
Open your preferred editor and create an Ingress configuration file that is named, for example,
myingress.yaml
. -
Define an Ingress resource in your configuration file that uses your custom domain to route incoming network traffic to your services, and your custom certificate to manage the TLS termination.
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: <myingressname> spec: tls: - hosts: - <mycustomdomain> secretName: <mytlssecret> rules: - host: <mycustomdomain> http: paths: - path: /<myservicepath1> backend: serviceName: <myservice1> servicePort: 80 - path: /<myservicepath2> backend: serviceName: <myservice2> servicePort: 80
{: codeblock}
Understanding the Ingress resource file components Understanding the YAML file components name
Replace <myingressname> with a name for your Ingress resource. tls/hosts
Replace <mycustomdomain> with our custom domain that you want to configure for TLS termination.
Note: Do not use * for your host or leave the host property empty to avoid failures during Ingress creation.tls/secretName
Replace <mytlssecret> with the name of the secret that you created earlier that holds your custom TLS certificate and key. If you imported a certificate from {{site.data.keyword.cloudcerts_short}}, you can run bx cs alb-cert-get --cluster --cert-crn
to see the secrets that are associated with a TLS certificate.host
Replace <mycustomdomain> with our custom domain that you want to configure for TLS termination.
Note: Do not use * for your host or leave the host property empty to avoid failures during Ingress creation.path
Replace <myservicepath1> with a slash or the unique path that your app is listening on so that network traffic can be forwarded to the app.
For every service, you can define an individual path that is appended to your custom domain to create a unique path to your app. When you enter this route into a web browser, network traffic is routed to the ALB. The ALB looks up the associated service and sends network traffic to the service. The service then forwards the traffic to the pods where the app is running. The app must be set up to listen on this path to receive incoming network traffic.
Many apps do not listen on a specific path, but use the root path and a specific port. In this case, define the root path as/
and do not specify an individual path for your app.
Examples:- For
https://mycustomdomain/
, enter/
as the path. - For
https://mycustomdomain/myservicepath
, enter/myservicepath
as the path.
serviceName
Replace <myservice1> with the name of the service that you used when you created the Kubernetes service for your app. servicePort
The port that your service listens to. Use the same port that you defined when you created the Kubernetes service for your app. - For
-
Save your changes.
-
Create the Ingress resource for your cluster.
kubectl apply -f myingress.yaml
{: pre}
-
-
Verify that the Ingress resource was created successfully. Replace <myingressname> with the name of the Ingress resource that you created earlier.
kubectl describe ingress <myingressname>
{: pre}
- If messages in the events describe an error in your resource configuration, change the values in your resource file and reapply the file for the resource.
-
In a web browser, enter the URL of the app service to access.
https://<mycustomdomain>/<myservicepath1>
{: codeblock}
Publicly expose apps that are outside your cluster using the IBM-provided or a custom domain with TLS
{: #external_endpoint}
You can configure the ALB to include apps that are located outside your cluster. Incoming requests on the IBM-provided or your custom domain are forwarded automatically to the external app. {:shortdesc}
Before you begin:
- If you do not have one already, create a standard cluster.
- Target your CLI to your cluster to run
kubectl
commands. - Ensure that the external app that you want to include into the cluster load balancing can be accessed by using a public IP address.
You can route incoming network traffic on the IBM-provided domain to apps that are located outside your cluster. If you want to use a custom domain and TLS certificate instead, replace the IBM-provided domain and TLS certificate with your custom domain and TLS certificate.
-
Create a Kubernetes service for your cluster that will forward incoming requests to an external endpoint that you will created.
-
Open your preferred editor and create a service configuration file that is named, for example,
myexternalservice.yaml
. -
Define the ALB service.
apiVersion: v1 kind: Service metadata: name: <myservicename> spec: ports: - protocol: TCP port: 8080
{: codeblock}
Understanding the ALB service file components Understanding the YAML file components metadata/name
Replace <myservicename> with a name for your service. port
The port that the service listens on. -
Save your changes.
-
Create the Kubernetes service for your cluster.
kubectl apply -f myexternalservice.yaml
{: pre}
-
-
Configure a Kubernetes endpoint that defines the external location of the app that you want to include into the cluster load balancing.
-
Open your preferred editor and create an endpoint configuration file that is named, for example,
myexternalendpoint.yaml
. -
Define your external endpoint. Include all public IP addresses and ports that you can use to access your external app.
kind: Endpoints apiVersion: v1 metadata: name: <myservicename> subsets: - addresses: - ip: <externalIP1> - ip: <externalIP2> ports: - port: <externalport>
{: codeblock}
-
Save your changes.
-
Create the Kubernetes endpoint for your cluster.
kubectl apply -f myexternalendpoint.yaml
{: pre}
-
-
View the IBM-provided domain and TLS certificate. Replace <mycluster> with the name of the cluster where the app is deployed.
bx cs cluster-get <mycluster>
{: pre}
Your CLI output looks similar to the following.
bx cs cluster-get <mycluster> Retrieving cluster <mycluster>... OK Name: <mycluster> ID: b9c6b00dc0aa487f97123440b4895f2d State: normal Created: 2017-04-26T19:47:08+0000 Location: dal10 Master URL: https://169.57.40.165:1931 Ingress subdomain: <ibmdomain> Ingress secret: <ibmtlssecret> Workers: 3 Version: 1.8.8
{: screen}
You can see the IBM-provided domain in the Ingress subdomain and the IBM-provided certificate in the Ingress secret fields.
-
Create an Ingress resource. Ingress resources define the routing rules for the Kubernetes service that you created for your app and are used by the ALB to route incoming network traffic to the service. You can use one Ingress resource to define routing rules for multiple external apps as long as every app is exposed with its external endpoint via a Kubernetes service inside the cluster.
-
Open your preferred editor and create an Ingress configuration file that is named, for example,
myexternalingress.yaml
. -
Define an Ingress resource in your configuration file that uses the IBM-provided domain and TLS certificate to route incoming network traffic to your external app by using the external endpoint that you defined earlier.
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: <myingressname> spec: tls: - hosts: - <ibmdomain> secretName: <ibmtlssecret> rules: - host: <ibmdomain> http: paths: - path: /<myexternalservicepath1> backend: serviceName: <myservice1> servicePort: 80 - path: /<myexternalservicepath2> backend: serviceName: <myexternalservice2> servicePort: 80
{: codeblock}
Understanding the Ingress resource file components Understanding the YAML file components name
Replace <myingressname> with the name for the Ingress resource. tls/hosts
Replace <ibmdomain> with the IBM-provided Ingress subdomain name from the previous step. This domain is configured for TLS termination.
Note: Do not use * for your host or leave the host property empty to avoid failures during Ingress creation.tls/secretName
Replace <ibmtlssecret> with the IBM-provided Ingress secret from the previous step. This certificate manages the TLS termination. rules/host
Replace <ibmdomain> with the IBM-provided Ingress subdomain name from the previous step. This domain is configured for TLS termination.
Note: Do not use * for your host or leave the host property empty to avoid failures during Ingress creation.path
Replace <myexternalservicepath> with a slash or the unique path that your external app is listening on, so that network traffic can be forwarded to the app.
For every service, you can define an individual path that is appended to the IBM-provided or custom domain to create a unique path to your app, for examplehttp://ibmdomain/myservicepath1
orhttp://customdomain/
. When you enter this route into a web browser, network traffic is routed to the ALB. The ALB looks up the associated service and sends network traffic to the service. The service the forwards traffic to the external app. The app must be set up to listen on this path to receive incoming network traffic.
Many apps do not listen on a specific path, but use the root path and a specific port. In this case, define the root path as/
and do not specify an individual path for your app.
Tip: To configure Ingress to listen on a path that is different than the path that your app listens on, you can use the rewrite annotation to establish proper routing to your app.serviceName
Replace <myexternalservice> with the name of the service that you used when you created the Kubernetes service for your external app. servicePort
The port that your service listens to. -
Save your changes.
-
Create the Ingress resource for your cluster.
kubectl apply -f myexternalingress.yaml
{: pre}
-
-
Verify that the Ingress resource was created successfully. Replace <myingressname> with the name of the Ingress resource that you created earlier.
kubectl describe ingress <myingressname>
{: pre}
- If messages in the events describe an error in your resource configuration, change the values in your resource file and reapply the file for the resource.
-
In a web browser, enter the URL of the app service to access.
https://<ibmdomain>/<myservicepath1>
{: codeblock}
{: #ingress_expose_private}
When you create a standard cluster, an IBM-provided application load balancer (ALB) is created and assigned a portable private IP address and a private route. However, the default private ALB is not automatically enabled. {:shortdesc}
To expose your app to private networks, first enable the default private application load balancer.
You can then configure Ingress for the following scenarios.
- Privately expose apps using a custom domain without TLS using an external DNS provider
- Privately expose apps using a custom domain with TLS using an external DNS provider
- Privately expose apps using an on-premises DNS service
{: #private_ingress}
Before you can use the default private ALB, you must enable it with either the IBM-provided portable private IP address or your own portable private IP address. {:shortdesc}
Note: If you used the --no-subnet
flag when you created the cluster, then you must add a portable private subnet or a user-managed subnet before you can enable the private ALB. For more information, see Requesting more subnets for your cluster.
Before you begin:
- If you do not have one already, create a standard cluster.
- Target your CLI to your cluster.
To enable the private ALB by using the pre-assigned, IBM-provided portable private IP address:
-
List the available ALBs in your cluster to get the ID of the private ALB. Replace <cluser_name> with the name of the cluster where the app that you want to expose is deployed.
bx cs albs --cluster <my_cluster>
{: pre}
The field Status for the private ALB is disabled.
ALB ID Enabled Status Type ALB IP private-cr6d779503319d419ea3b4ab171d12c3b8-alb1 false disabled private - public-cr6d779503319d419ea3b4ab171d12c3b8-alb1 true enabled public 169.46.63.150
{: screen}
-
Enable the private ALB. Replace <private_ALB_ID> with the ID for private ALB from the output in the previous step.
bx cs alb-configure --albID <private_ALB_ID> --enable
{: pre}
To enable the private ALB using your own portable private IP address:
-
Configure the user-managed subnet of your chosen IP address to route traffic on the private VLAN of your cluster. Replace <cluser_name> with the name or ID of the cluster where the app that you want to expose is deployed, <subnet_CIDR> with the CIDR of your user-managed subnet, and <private_VLAN> with an available private VLAN ID. You can find the ID of an available private VLAN by running
bx cs vlans
.bx cs cluster-user-subnet-add <cluster_name> <subnet_CIDR> <private_VLAN>
{: pre}
-
List the available ALBs in your cluster to get the ID of private ALB.
bx cs albs --cluster <my_cluster>
{: pre}
The field Status for the private ALB is disabled.
ALB ID Enabled Status Type ALB IP private-cr6d779503319d419ea3b4ab171d12c3b8-alb1 false disabled private - public-cr6d779503319d419ea3b4ab171d12c3b8-alb1 true enabled public 169.46.63.150
{: screen}
-
Enable the private ALB. Replace <private_ALB_ID> with the ID for private ALB from the output in the previous step and <user_ip> with the IP address from your user-managed subnet that you want to use.
bx cs alb-configure --albID <private_ALB_ID> --enable --user-ip <user_ip>
{: pre}
{: #private_ingress_no_tls}
You can configure the private ALB to route incoming network traffic to the apps in your cluster using a custom domain. {:shortdesc}
Before you begin:
- Enable the private application load balancer.
- If you have private worker nodes and want to use an external DNS provider, you must configure edge nodes with public access and configure a Vyatta Gateway Appliance . If you want to remain on a private network only, see Privately expose apps using an on-premises DNS service instead.
To privately expose an app by using a custom domain without TLS using an external DNS provider:
-
Create a custom domain. To create a custom domain, work with your Domain Name Service (DNS) provider or {{site.data.keyword.Bluemix_notm}} to register your custom domain.
-
Map your custom domain to the portable private IP address of the IBM-provided private ALB by adding the IP address as a record. To find the portable private IP address of the private ALB, run
bx cs albs --cluster <cluster_name>
. -
Deploy your app to the cluster. Ensure that you add a label to your deployment in the metadata section of your configuration file, such as
app: code
. This label is needed to identify all pods where your app is running so that the pods can be included in the Ingress load balancing. -
Create a Kubernetes service for the app that you want to expose. Your app must be exposed by a Kubernetes service to be included by the cluster ALB in the Ingress load balancing.
-
Open your preferred editor and create a service configuration file that is named, for example,
myservice.yaml
. -
Define a service for the app that the ALB will expose to the private network.
apiVersion: v1 kind: Service metadata: name: <myservice> spec: selector: <selectorkey>: <selectorvalue> ports: - protocol: TCP port: 8080
{: codeblock}
Understanding the ALB service file components -
Save your changes.
-
Create the service in your cluster.
kubectl apply -f myservice.yaml
{: pre}
-
Repeat these steps for every app that you want to expose to the private network.
-
-
Create an Ingress resource. Ingress resources define the routing rules for the Kubernetes service that you created for your app and are used by the ALB to route incoming network traffic to the service. You must use one Ingress resource to define routing rules for multiple apps if every app is exposed via a Kubernetes service inside the cluster.
-
Open your preferred editor and create an Ingress configuration file that is named, for example,
myingress.yaml
. -
Define an Ingress resource in your configuration file that uses your custom domain to route incoming network traffic to your services.
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: <myingressname> annotations: ingress.bluemix.net/ALB-ID: "<private_ALB_ID>" spec: rules: - host: <mycustomdomain> http: paths: - path: /<myservicepath1> backend: serviceName: <myservice1> servicePort: 80 - path: /<myservicepath2> backend: serviceName: <myservice2> servicePort: 80
{: codeblock}
Understanding the Ingress resource file components Understanding the YAML file components name
Replace <myingressname> with a name for your Ingress resource. ingress.bluemix.net/ALB-ID
Replace <private_ALB_ID> with the ID for your private ALB. Run bx cs albs --cluster
to find the ALB ID. For more information about this Ingress annotation, see [Private application load balancer routing](cs_annotations.html#alb-id).host
Replace <mycustomdomain> with your custom domain.
Note: Do not use * for your host or leave the host property empty to avoid failures during Ingress creation.path
Replace <myservicepath1> with a slash or the unique path that your app is listening on so that network traffic can be forwarded to the app.
For every service, you can define an individual path that is appended to your custom domain to create a unique path to your app. When you enter this route into a web browser, network traffic is routed to the ALB. The ALB looks up the associated service and sends network traffic to the service. The service then forwards the traffic to the pods where the app is running. The app must be set up to listen on this path to receive incoming network traffic.
Many apps do not listen on a specific path, but use the root path and a specific port. In this case, define the root path as/
and do not specify an individual path for your app.
Examples:- For
https://mycustomdomain/
, enter/
as the path. - For
https://mycustomdomain/myservicepath
, enter/myservicepath
as the path.
serviceName
Replace <myservice1> with the name of the service that you used when you created the Kubernetes service for your app. servicePort
The port that your service listens to. Use the same port that you defined when you created the Kubernetes service for your app. - For
-
Save your changes.
-
Create the Ingress resource for your cluster.
kubectl apply -f myingress.yaml
{: pre}
-
-
Verify that the Ingress resource was created successfully. Replace <myingressname> with the name of the Ingress resource that you created earlier.
kubectl describe ingress <myingressname>
{: pre}
- If messages in the events describe an error in your resource configuration, change the values in your resource file and reapply the file for the resource.
-
In a web browser, enter the URL of the app service to access.
https://<mycustomdomain>/<myservicepath1>
{: codeblock}
{: #private_ingress_tls}
You can use private ALBs to route incoming network traffic to apps in your cluster. Also, use your own TLS certificate to manage the TLS termination while using your custom domain. {:shortdesc}
Before you begin:
- Enable the private application load balancer.
- If you have private worker nodes and want to use an external DNS provider, you must configure edge nodes with public access and configure a Vyatta Gateway Appliance . If you want to remain on a private network only, see Privately expose apps using an on-premises DNS service instead.
To privately expose an app by using a custom domain with TLS using an external DNS provider:
-
Create a custom domain. To create a custom domain, work with your Domain Name Service (DNS) provider or {{site.data.keyword.Bluemix_notm}} to register your custom domain.
-
Map your custom domain to the portable private IP address of the IBM-provided private ALB by adding the IP address as a record. To find the portable private IP address of the private ALB, run
bx cs albs --cluster <cluster_name>
. -
Either import or create a TLS certificate and key secret:
- If a TLS certificate is stored in {{site.data.keyword.cloudcerts_long_notm}} that you want to use, you can import its associated secret into your cluster by running
bx cs alb-cert-deploy --secret-name <secret_name> --cluster <cluster_name_or_ID> --cert-crn <certificate_crn>
. - If you do not have a TLS certificate ready, follow these steps:
-
Create a TLS certificate and key for your domain that is encoded in PEM format.
-
Create a secret that uses your TLS certificate and key. Replace <mytlssecret> with a name for your Kubernetes secret, <tls_key_filepath> with the path to your custom TLS key file, and <tls_cert_filepath> with the path to your custom TLS certificate file.
kubectl create secret tls <mytlssecret> --key <tls_key_filepath> --cert <tls_cert_filepath>
{: pre}
-
- If a TLS certificate is stored in {{site.data.keyword.cloudcerts_long_notm}} that you want to use, you can import its associated secret into your cluster by running
-
Deploy your app to the cluster. Ensure that you add a label to your deployment in the metadata section of your configuration file, such as
app: code
. This label is needed to identify all pods where your app is running so that the pods can be included in the Ingress load balancing. -
Create a Kubernetes service for the app that you want to expose. Your app must be exposed by a Kubernetes service to be included by the cluster ALB in the Ingress load balancing.
-
Open your preferred editor and create a service configuration file that is named, for example,
myservice.yaml
. -
Define a service for the app that the ALB will expose to the private network.
apiVersion: v1 kind: Service metadata: name: <myservice> spec: selector: <selectorkey>: <selectorvalue> ports: - protocol: TCP port: 8080
{: codeblock}
Understanding the ALB service file components -
Save your changes.
-
Create the service in your cluster.
kubectl apply -f myservice.yaml
{: pre}
-
Repeat these steps for every app that you want to expose to the private network.
-
-
Create an Ingress resource. Ingress resources define the routing rules for the Kubernetes service that you created for your app and are used by the ALB to route incoming network traffic to the service. You must use one Ingress resource to define routing rules for multiple apps if every app is exposed via a Kubernetes service inside the cluster.
-
Open your preferred editor and create an Ingress configuration file that is named, for example,
myingress.yaml
. -
Define an Ingress resource in your configuration file that uses your custom domain to route incoming network traffic to your services, and your custom certificate to manage the TLS termination.
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: <myingressname> annotations: ingress.bluemix.net/ALB-ID: "<private_ALB_ID>" spec: tls: - hosts: - <mycustomdomain> secretName: <mytlssecret> rules: - host: <mycustomdomain> http: paths: - path: /<myservicepath1> backend: serviceName: <myservice1> servicePort: 80 - path: /<myservicepath2> backend: serviceName: <myservice2> servicePort: 80
{: pre}
Understanding the Ingress resource file components Understanding the YAML file components name
Replace <myingressname> with a name for your Ingress resource. ingress.bluemix.net/ALB-ID
Replace <private_ALB_ID> with the ID for your private ALB. Run bx cs albs --cluster
to find the ALB ID. For more information about this Ingress annotation, see [Private application load balancer routing (ALB-ID)](cs_annotations.html#alb-id).tls/hosts
Replace <mycustomdomain> with our custom domain that you want to configure for TLS termination.
Note: Do not use * for your host or leave the host property empty to avoid failures during Ingress creation.tls/secretName
Replace <mytlssecret> with the name of the secret that you created earlier and that holds your custom TLS certificate and key. If you imported a certificate from {{site.data.keyword.cloudcerts_short}}, you can run bx cs alb-cert-get --cluster --cert-crn
to see the secrets that are associated with a TLS certificate.host
Replace <mycustomdomain> with your custom domain that you want to configure for TLS termination.
Note: Do not use * for your host or leave the host property empty to avoid failures during Ingress creation.path
Replace <myservicepath1> with a slash or the unique path that your app is listening on so that network traffic can be forwarded to the app.
For every service, you can define an individual path that is appended to your custom domain to create a unique path to your app. When you enter this route into a web browser, network traffic is routed to the ALB. The ALB looks up the associated service, and sends network traffic to the service and to the pods where the app is running by using the same path. The app must be set up to listen on this path to receive incoming network traffic.
Many apps do not listen on a specific path, but use the root path and a specific port. In this case, define the root path as/
and do not specify an individual path for your app.
Examples:- For
https://mycustomdomain/
, enter/
as the path. - For
https://mycustomdomain/myservicepath
, enter/myservicepath
as the path.
serviceName
Replace <myservice1> with the name of the service that you used when you created the Kubernetes service for your app. servicePort
The port that your service listens to. Use the same port that you defined when you created the Kubernetes service for your app. - For
-
Save your changes.
-
Create the Ingress resource for your cluster.
kubectl apply -f myingress.yaml
{: pre}
-
-
Verify that the Ingress resource was created successfully. Replace <myingressname> with the name of the Ingress resource that you created earlier.
kubectl describe ingress <myingressname>
{: pre}
- If messages in the events describe an error in your resource configuration, change the values in your resource file and reapply the file for the resource.
-
In a web browser, enter the URL of the app service to access.
https://<mycustomdomain>/<myservicepath1>
{: codeblock}
For a comprehensive tutorial on how to secure microservice-to-microservice communication across your clusters by using the private ALB with TLS, check out [this blog post ]](https://medium.com/ibm-cloud/secure-microservice-to-microservice-communication-across-kubernetes-clusters-using-a-private-ecbe2a8d4fe2).
{: #private_ingress_onprem_dns}
You can configure the private ALB to route incoming network traffic to the apps in your cluster using a custom domain. When you have private worker nodes and want to remain on a private network only, you can use a private, on-premises DNS to resolve URL requests to your apps. {:shortdesc}
-
To allow your private worker nodes to communicate with the Kubernetes master, set up VPN connectivity.
-
Create a custom domain and register it with your DNS service.
-
Map your custom domain to the portable private IP address of the IBM-provided private ALB by adding the IP address as a record. To find the portable private IP address of the private ALB, run
bx cs albs --cluster <cluster_name>
. -
Deploy your app to the cluster. Ensure that you add a label to your deployment in the metadata section of your configuration file, such as
app: code
. This label is needed to identify all pods where your app is running so that the pods can be included in the Ingress load balancing. -
Create a Kubernetes service for the app that you want to expose. Your app must be exposed by a Kubernetes service to be included by the cluster ALB in the Ingress load balancing.
-
Open your preferred editor and create a service configuration file that is named, for example,
myservice.yaml
. -
Define a service for the app that the ALB will expose to the private network.
apiVersion: v1 kind: Service metadata: name: <myservice> spec: selector: <selectorkey>: <selectorvalue> ports: - protocol: TCP port: 8080
{: codeblock}
Understanding the ALB service file components -
Save your changes.
-
Create the service in your cluster.
kubectl apply -f myservice.yaml
{: pre}
-
Repeat these steps for every app that you want to expose to the private network.
-
-
Create an Ingress resource. Ingress resources define the routing rules for the Kubernetes service that you created for your app and are used by the ALB to route incoming network traffic to the service. You must use one Ingress resource to define routing rules for multiple apps if every app is exposed via a Kubernetes service inside the cluster.
-
Open your preferred editor and create an Ingress configuration file that is named, for example,
myingress.yaml
. -
Define an Ingress resource in your configuration file that uses your custom domain to route incoming network traffic to your services.
**Note**: If you do not want to use TLS, remove the `tls` section from the following example.
```
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: <myingressname>
annotations:
ingress.bluemix.net/ALB-ID: "<private_ALB_ID>"
spec:
tls:
- hosts:
- <mycustomdomain>
secretName: <mytlssecret>
rules:
- host: <mycustomdomain>
http:
paths:
- path: /<myservicepath1>
backend:
serviceName: <myservice1>
servicePort: 80
- path: /<myservicepath2>
backend:
serviceName: <myservice2>
servicePort: 80
```
{: codeblock}
<table>
<caption>Understanding the Ingress resource file components</caption>
<thead>
<th colspan=2><img src="images/idea.png" alt="Idea icon"/> Understanding the YAML file components</th>
</thead>
<tbody>
<tr>
<td><code>name</code></td>
<td>Replace <em><myingressname></em> with a name for your Ingress resource.</td>
</tr>
<tr>
<td><code>ingress.bluemix.net/ALB-ID</code></td>
<td>Replace <em><private_ALB_ID></em> with the ID for your private ALB. Run <code>bx cs albs --cluster <my_cluster></code> to find the ALB ID. For more information about this Ingress annotation, see [Private application load balancer routing (ALB-ID)](cs_annotations.html#alb-id).</td>
</tr>
<tr>
<td><code>tls/hosts</code></td>
<td>If you are using the `tls` section, replace <em><mycustomdomain></em> with our custom domain that you want to configure for TLS termination.
</br></br>
<strong>Note:</strong> Do not use * for your host or leave the host property empty to avoid failures during Ingress creation. </td>
</tr>
<tr>
<td><code>tls/secretName</code></td>
<td>If you are using the `tls` section, replace <em><mytlssecret></em> with the name of the secret that you created earlier and that holds your custom TLS certificate and key. If you imported a certificate from {{site.data.keyword.cloudcerts_short}}, you can run <code>bx cs alb-cert-get --cluster <cluster_name_or_ID> --cert-crn <certificate_crn></code> to see the secrets that are associated with a TLS certificate.
</tr>
<tr>
<td><code>host</code></td>
<td>Replace <em><mycustomdomain></em> with your custom domain that you want to configure for TLS termination.
</br></br>
<strong>Note:</strong> Do not use * for your host or leave the host property empty to avoid failures during Ingress creation.
</td>
</tr>
<tr>
<td><code>path</code></td>
<td>Replace <em><myservicepath1></em> with a slash or the unique path that your app is listening on so that network traffic can be forwarded to the app.
</br>
For every service, you can define an individual path that is appended to your custom domain to create a unique path to your app. When you enter this route into a web browser, network traffic is routed to the ALB. The ALB looks up the associated service, and sends network traffic to the service and to the pods where the app is running by using the same path. The app must be set up to listen on this path to receive incoming network traffic.
</br>
Many apps do not listen on a specific path, but use the root path and a specific port. In this case, define the root path as <code>/</code> and do not specify an individual path for your app.
</br></br>
Examples: <ul><li>For <code>https://mycustomdomain/</code>, enter <code>/</code> as the path.</li><li>For <code>https://mycustomdomain/myservicepath</code>, enter <code>/myservicepath</code> as the path.</li></ul>
<strong>Tip:</strong> To configure Ingress to listen on a path that is different than the path that your app listens on, you can use the [rewrite annotation](cs_annotations.html#rewrite-path) to establish proper routing to your app.
</td>
</tr>
<tr>
<td><code>serviceName</code></td>
<td>Replace <em><myservice1></em> with the name of the service that you used when you created the Kubernetes service for your app.</td>
</tr>
<tr>
<td><code>servicePort</code></td>
<td>The port that your service listens to. Use the same port that you defined when you created the Kubernetes service for your app.</td>
</tr>
</tbody></table>
-
Save your changes.
-
Create the Ingress resource for your cluster.
kubectl apply -f myingress.yaml
{: pre}
-
Verify that the Ingress resource was created successfully. Replace <myingressname> with the name of the Ingress resource that you created earlier.
kubectl describe ingress <myingressname>
{: pre}
- If messages in the events describe an error in your resource configuration, change the values in your resource file and reapply the file for the resource.
-
In a web browser, enter the URL of the app service to access.
https://<mycustomdomain>/<myservicepath1>
{: codeblock}
{: #configure_alb}
You can further configure an application load balancer with the following options.
- Opening ports in the Ingress application load balancer
- Configuring SSL protocols and SSL ciphers at the HTTP level
- Customizing your application load balancer with annotations {: #ingress_annotation}
{: #opening_ingress_ports}
By default, only ports 80 and 443 are exposed in the Ingress ALB. To expose other ports, you can edit the ibm-cloud-provider-ingress-cm
configmap resource.
{:shortdesc}
-
Create and open a local version of the configuration file for the
ibm-cloud-provider-ingress-cm
configmap resource.kubectl edit cm ibm-cloud-provider-ingress-cm -n kube-system
{: pre}
-
Add a
data
section and specify public ports80
,443
, and any other ports you want to expose separated by a semi-colon (;).Note: When specifying the ports, 80 and 443 must also be included to keep those ports open. Any port that is not specified is closed.
apiVersion: v1 data: public-ports: "80;443;<port3>" kind: ConfigMap metadata: name: ibm-cloud-provider-ingress-cm namespace: kube-system
{: pre}
Example:
apiVersion: v1 data: public-ports: "80;443;9443" kind: ConfigMap metadata: name: ibm-cloud-provider-ingress-cm namespace: kube-system
{: screen}
-
Save the configuration file.
-
Verify that the configmap changes were applied.
kubectl get cm ibm-cloud-provider-ingress-cm -n kube-system -o yaml
{: pre}
Output:
Name: ibm-cloud-provider-ingress-cm
Namespace: kube-system
Labels: <none>
Annotations: <none>
Data
====
public-ports: "80;443;<port3>"
{: screen}
For more information about configmap resources, see the Kubernetes documentation.
{: #ssl_protocols_ciphers}
Enable SSL protocols and ciphers at the global HTTP level by editing the ibm-cloud-provider-ingress-cm
configmap.
{:shortdesc}
Note: When you specify the enabled protocols for all hosts, the TLSv1.1 and TLSv1.2 parameters (1.1.13, 1.0.12) work only when OpenSSL 1.0.1 or higher is used. The TLSv1.3 parameter (1.13.0) works only when OpenSSL 1.1.1 built with TLSv1.3 support is used.
To edit the configmap to enable SSL protocols and ciphers:
-
Create and open a local version of the configuration file for the
ibm-cloud-provider-ingress-cm
configmap resource.kubectl edit cm ibm-cloud-provider-ingress-cm -n kube-system
{: pre}
-
Add the SSL protocols and ciphers. Format ciphers according to the OpenSSL library cipher list format .
apiVersion: v1 data: ssl-protocols: "TLSv1 TLSv1.1 TLSv1.2" ssl-ciphers: "HIGH:!aNULL:!MD5" kind: ConfigMap metadata: name: ibm-cloud-provider-ingress-cm namespace: kube-system
{: codeblock}
-
Save the configuration file.
-
Verify that the configmap changes were applied.
kubectl get cm ibm-cloud-provider-ingress-cm -n kube-system -o yaml
{: pre}
Output:
Name: ibm-cloud-provider-ingress-cm Namespace: kube-system Labels: <none> Annotations: <none> Data ==== ssl-protocols: "TLSv1 TLSv1.1 TLSv1.2" ssl-ciphers: "HIGH:!aNULL:!MD5"
{: screen}
{: #ingress_log_format}
You can customize the content and format of logs that are collected for the Ingress ALB. {:shortdesc}
By default, Ingress logs are formatted in JSON and display common log fields. However, you can also create a custom log format. To choose which log components are forwarded and how they are arranged in the log output:
-
Create and open a local version of the configuration file for the
ibm-cloud-provider-ingress-cm
configmap resource.kubectl edit cm ibm-cloud-provider-ingress-cm -n kube-system
{: pre}
-
Add a
data
section. Add thelog-format
field and, optionally, thelog-format-escape-json
field.apiVersion: v1 data: log-format: '{<key1>: <logvariable1>, <key2>: <logvariable2>, <key3>: <logvariable3>}' log-format-escape-json: "true" kind: ConfigMap metadata: name: ibm-cloud-provider-ingress-cm namespace: kube-system
{: pre}
Understanding the log-format configuration log-format
Replace <key>
with the name for the log component and<logvariable>
with a variable for the log component that you want to collect in log entries. You can include text and punctuation that you want the log entry to contain, such as quotation marks around string values and commas to separate log components. For example, formatting a component likerequest: "$request",
generates the following in a log entry:request: "GET / HTTP/1.1",
. For a list of all the variables you can use, see the Nginx variable index.
To log an additional header such as x-custom-ID, add the following key-value pair to the custom log content:customID: $http_x_custom_id
Note that hyphens (-
) are converted to underscores (_
) and that$http_
must be prepended to the custom header name.log-format-escape-json
Optional: By default, logs are generated in text format. To generate logs in JSON format, add the log-format-escape-json
field and use valuetrue
.For example, your log format might contain the following variables:
apiVersion: v1 data: log-format: '{remote_address: $remote_addr, remote_user: "$remote_user", time_date: [$time_local], request: "$request", status: $status, http_referer: "$http_referer", http_user_agent: "$http_user_agent", request_id: $request_id}' kind: ConfigMap metadata: name: ibm-cloud-provider-ingress-cm namespace: kube-system
{: screen}
A log entry according to this format looks like the following:
remote_address: 127.0.0.1, remote_user: "dbmanager", time_date: [30/Mar/2018:18:52:17 +0000], request: "GET / HTTP/1.1", status: 401, http_referer: "-", http_user_agent: "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:47.0) Gecko/20100101 Firefox/47.0", request_id: a02b2dea9cf06344a25611c1d7ad72db
{: screen}
If you want to create a custom log format that is based on the default format for ALB logs, you can add the following section to your configmap and modify it as needed:
apiVersion: v1 data: log-format: '{"time_date": "$time_iso8601", "client": "$remote_addr", "host": "$http_host", "scheme": "$scheme", "request_method": "$request_method", "request_uri": "$uri", "request_id": "$request_id", "status": $status, "upstream_addr": "$upstream_addr", "upstream_status": $upstream_status, "request_time": $request_time, "upstream_response_time": $upstream_response_time, "upstream_connect_time": $upstream_connect_time, "upstream_header_time": $upstream_header_time}' log-format-escape-json: "true" kind: ConfigMap metadata: name: ibm-cloud-provider-ingress-cm namespace: kube-system
{: pre}
-
Save the configuration file.
-
Verify that the configmap changes were applied.
kubectl get cm ibm-cloud-provider-ingress-cm -n kube-system -o yaml
{: pre}
Example output:
Name: ibm-cloud-provider-ingress-cm
Namespace: kube-system
Labels: <none>
Annotations: <none>
Data
====
log-format: '{remote_address: $remote_addr, remote_user: "$remote_user", time_date: [$time_local], request: "$request", status: $status, http_referer: "$http_referer", http_user_agent: "$http_user_agent", request_id: $request_id}'
log-format-escape-json: "true"
{: screen}
- To view the Ingress ALB logs, create a logging configuration for the Ingress service in your cluster.