Technical Articles
Kyma Hands-On – Part 2
Welcome to the second part of the Kyma Hands-On series.
This series shares the learning outcomes of exploring Kyma first-hand. It aims to enable anyone interested in Kyma by sharing the steps I took, the lessons I learned, and the tips I gathered.
If you haven’t already, please also check out the Kyma Hands-On — Part 1.”
Kyma Hands-On
In the previous post, I went through the steps of installing and deploying a sample application to test out Kyma’s authentication functionality.
This time, I’m going to take a look at one of the key components: Application Connector.
Application Connector is a custom-built component of Kyma that allows you to connect with external applications running in any environment as long as it follows the REST principles. By connecting your monolith or microservice with Kyma using the Application Connector, its APIs and event catalogs become available in the Kyma’s Service Catalog.
There are two main benefits of the Application Connector that I see already: first, the registered APIs and event catalogs are provisioned once and available to be used by any application running in the cluster. Second, by leveraging the Application Connector, it allows developers the flexibility to extend the functionality of an external application without modifying the actual application code. I’ll dig deeper into these within this article.
Use Application Connector to Register an External APIs/Events in the Service Catalog
The Kyma project’s official site is organized by component and each component includes tutorials you can run to aid your exploration. Also, you can find blog posts that focus on use cases for Kyma. Using both resources, I was able to find out how Application Connector works. The tutorial goes through the steps programmatically and the blog post goes through the steps through the console. I recommend checking out both resources to get familiar with both approaches and to check out different ways of connecting the external application to Kyma.
A high-level overview of the steps I took for the Application Connector tutorial are listed below
1. Create an Application
2. Create a TokenRequest
3. Generate a key and retrieve cert file
4. Register a service with a template
5. Create an ApplicationMapping
6. Create a simple Deployment
(see below for code)
7. Create a ServiceBinding
(see below for code)
8. Create a ServiceBindingUsage
(see below for code)
A high-level overview of the steps I took for the Build a cloud-native extension for WordPress are listed below
1. WordPress installation
2. Kyma plugin for WordPress
3. Connect WordPress to Kyma
4. Disable SSL
5. Enable WordPress Events and APIs in the default Namespace
6. Create a simple Deployment
(see below for code)
7. Bind a sample application to the WordPress service instance
While going through both, you’ll notice that it actually covers more steps than the ones I listed above. For this post, I decided to intentionally leave out steps related to serverless functions and event-driven triggers so that it can be covered all on its own in the future post. As an alternative to those steps, I created a simple Deployment
and tested out that the gateway endpoint was automatically added to the container. To help you to achieve the same testing, code has been provided below.
In addition to the code below, please make sure to read through the ? tips section for help with troubleshooting when going through the tutorials.
# Create a sample Deployment
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: annajung/nginx-with-curl:0.0.1
ports:
- containerPort: 80
EOF
# Create a Service Binding
cat <<EOF | kubectl apply -f -
apiVersion: servicecatalog.k8s.io/v1beta1
kind: ServiceBinding
metadata:
name: nginx-binding
spec:
instanceRef:
name: sample-app
EOF
# Create a Service Binding Usage
cat <<EOF | kubectl apply -f -
apiVersion: servicecatalog.kyma-project.io/v1alpha1
kind: ServiceBindingUsage
metadata:
name: nginx-binding-usagee
spec:
serviceBindingRef:
name: nginx-binding
usedBy:
kind: deployment
name: nginx
EOF
# Retrieve pod name
NGINX_POD_NAME=$(kubectl get pod -l app=nginx \
-o jsonpath={.items[0].metadata.name})
# Search for GATEWAY_URL env variable that has been added automatically
kubectl exec -it $NGINX_POD_NAME -c nginx -- env | grep GATEWAY_URL
?Lessons Learned
What does exposing a service in the service catalog tell us?
Kyma Application Connector Components
1. Application Connector is made up of five main components running in the kyma-integration
namespace: Application Broker, Application Operator, Application Registry, Connection Token Handler, and Connector Service. Using these components, it manages a secure connection, traffic, and events to/from the external application to/from Kyma.
2. According to the documentation, when an Application
custom resource is created, Application Operator provisions an Application Gateway and an Event Service for the application. However, there are a lot more resources provisioned at the same time which might be the reason why it takes a bit for the status
field to show up. All components related to the Application
exists in the kyma-integration
namespace.
- Application Gateway proxies the request from functions and services in Kyma to external APIs registered with the Application Registry
- Event Service sends events to the Event Mesh
3. Connection Token Handler listens for TokenRequest
custom resource then retrieves the configuration from the Connector Service. Once the configuration has been received, it updates the existing TokenRequest
with a status
field that contains a token and a Connector Service info endpoint. This is the reason why you have to output the TokenRequest
after creating to grab the URL.
4. Connector Service generates client certificates based on Certificate Signing Request and provides endpoints to the Application Registry and the Event Service. This is the component that allows a secure connection between Kyma and external Applications by provisioning, rotating, and revoking certificates.
5. Application Registry stores data of all registered services and enables registration of APIs and event catalogs of the service. This is the component used to register a service by passing in the authentication method, API spec, and documentation which are all used for Service Catalog.
6. Application Broker watches for Application
and ApplicationMapping
custom resources to create a Service Broker called application-broker
. Once application-broker
resource has been created, Service Catalog components recognize that there is a new broker and creates a ServiceClass
for each service exposed by the broker. Only when the Service Class has been created for the Application, you can create a ServiceInstance
to provision it to be used by any application running inside your cluster.
7. When you want to use the ServiceInstance
, you have to bind it to either a function or a service running in the cluster. When that binding is established, a Secret
is created that contains a GATEWAY_URL
variable which is the endpoint used to connect to the Application
. One of the really nice things about the Secret
is that it gets automatically injected into the service/function that is bound to and the management of the Secret
(connection to the Application) stays separated from the service lifecycle.
8. When deploying the WordPress application, I noticed that Kyma has some trouble with redirects. When exposing WordPress application using an APIRule
custom resource, I wasn’t able to successfully access the main page without listing the full path it redirects to. To get around this issue, I had to use port-forward
or use a non-Kyma environment to access WordPress application.
9. Application Connector connection can be made with a URL provided by Kyma after creating an Application
. However, the external application must be able to understand how to utilize the connection in the correct way. This means that additional code for a plugin for Kyma is required for the external application. As shown in the WordPress tutorial, the steps to achieve a connection with Kyma are to download and install a WordPress specific connector. This approach also means that the connection is managed outside of Kyma, which may be favorable or not depending on your use case.
10. There seems to be a few connectors available in the Kyma Incubator repository for people to look at, but I could not find any template or an easy way to create a connector for an application.
?Tips
- When creating Kubernetes resources, Kyma requires the name to match the name of the Application. This is not apparent; I recommend using the Application name for all resources.
- All resources created by the
Application
custom resource can be viewed by running the following command
kubectl get all -n kyma-integration | grep $APP_NAME
- When generating a CSR, use the following commands to avoid
Invalid Org Unit
error. The error is thrown when youcurl
the configuration URL with the token due to mismatch ofOU=OrgUnit and O=Organization
- GitHub issue is open to address this bug
openssl genrsa -out generated.key 2048
# Remember to replace {APP_NAME} with the actual app name
openssl req -new -sha256 -out generated.csr -key generated.key -subj "/OU=OrgUnit/O=Organization/L=Waldorf/ST=Waldorf/C=DE/CN={APP_NAME}"
openssl base64 -in generated.csr
- Use the following command to remove the new lines from
generated.csr
openssl base64 -in generated.csr | tr -d '\n'
- When calling the metadata endpoint,
--cert
flag takes base64 decodedclientCrt
.
export CERT_FILE_NAME=clientCrtDecoded
export KEY_FILE_NAME=generated
export CLUSTER_DOMAIN=kyma.local
curl -X POST -H "Content-Type: application/json" -d '{"csr": "${BASE64_ENCODED_CSR}"}' ${CSR_SIGNING_URL_WITH_TOKEN} | jq . > clientcertificate.json
jq .clientCrt -r clientcertificate.json > clientCrt
cat clientCrt | base64 -d > ${CERT_FILE_NAME}.crt
curl https://gateway.${CLUSTER_DOMAIN}/v1/applications/management/info --cert ${CERT_FILE_NAME}.crt --key ${KEY_FILE_NAME}.key -k
- When registering a service in the Application Registry, you can pass the API specification in either JSON format under
api.spec
or a URL underapi.SpecificationUrl
. However, OData APIs are only supported usingapi.SpecificationUrl
. - There are only three fields that are required in the API request to register a service.
provider
,name
, anddescription
. But you should define eitherapi
orevents
depending on which you want the application to expose. Whenapi
is defined,api.targetUrl
is required. Whenevents
is defined,events.spec
is required. - You can pass in a
json
file intocurl
command by following the below
curl -X POST -d '@api.json' https://gateway.kyma.local/{APP_NAME}/v1/metadata/services --cert clientCrtDecoded.crt --key generated.key -k
- The command used for installing WordPress will throw an error
no matches for kind "Api" in version "gateway.kyma-project.io/v1alpha2"
. This is because Kyma no longer supports anAPI
custom resource and supportAPIRule
custom resource instead. To get around this issue, run the following. However, as mentioned in the “lessons learned” section, I had problems accessing WordPress application and this could be because of how I defined theAPIRule
. I also started a conversation in Slack #general channel to speak with Kyma colleagues about the problem I am running into. If you’re interested, please follow the conversation there!
# Create an APIRule for WordPress
cat <<EOF | kubectl apply -f -
apiVersion: gateway.kyma-project.io/v1alpha1
kind: APIRule
metadata:
name: wordpress
namespace: wordpress
spec:
gateway: kyma-gateway.kyma-system.svc.cluster.local
rules:
- accessStrategies:
- config: {}
handler: noop
methods:
- GET
- POST
- PUT
- PATCH
- DELETE
- HEAD
path: /.*
service:
host: wordpress.kyma.local
name: wordpress
port: 80
EOF
—
Wow, this post became a lot longer than I originally intended. It goes to show that there are a lot of components in play that makes Kyma what it is.
?What Have I Learned So Far?
As I put my learnings from this and last post together, I would define Kyma as a service that configures multiple cloud-native components together to give you an out of box production-grade environment and empowers you to use or extend any services running outside of the cluster by bringing in the APIs and Events as a service inside the cluster,
What I am also noticing is that Kyma seems to advocate for software best practices by offering the ability to add authentication, managing the dependency lifecycle separate from the application, and enabling reusability of services across multiple applications.
Again, this is an iterative process for me. As I explore more, my perspective on what Kyma is and does will evolve.
I hope you came to similar conclusions as I have. If you have any feedback on my insights or want to share your own insights, I would love to hear from you!
See you in the next post! ?