Standard Kubernetes Resources

Example of using standard Kubernetes resources

This example demonstrates using standard Kubernetes resources, in conjunction with OAM resources, to define and deploy an application. Several standard Kubernetes resources are used in this example, both as workloads and traits.

  • Deployment is used as a workload within a Component.
  • Service is used as a workload within a Component.
  • Ingress is used as a trait within an ApplicationConfiguration.

Before you begin

Install Verrazzano by following the installation instructions.

Grant permissions

The oam-kubernetes-runtime is not installed with privileges that allow it to create the Kubernetes Ingress resource used in this example. The following steps create a role that allows Ingress resource creation and binds that role to the oam-kubernetes-runtime service account. For this example to work, your cluster admin will need to run the following steps to create the ClusterRole and ClusterRoleBinding.

$ kubectl apply -f - <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: oam-kubernetes-runtime-ingresses
rules:
  - apiGroups:
    - networking.k8s.io
    - extensions
    resources:
    - ingresses
    verbs:
    - create
    - delete
    - get
    - list
    - patch
    - update
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: oam-kubernetes-runtime-ingresses
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: oam-kubernetes-runtime-ingresses
subjects:
  - kind: ServiceAccount
    name: oam-kubernetes-runtime
    namespace: verrazzano-system
EOF

Deploy the application

This example provides a web application using a common example application image. When accessed, the application returns the configured text.

  1. Create the application namespace and add a label identifying the namespace as managed by Verrazzano.

     $ kubectl create namespace oam-kube
     $ kubectl label namespace oam-kube verrazzano-managed=true istio-injection=enabled
    

  2. Create a Component containing a Deployment workload.

     $ kubectl apply -f - <<EOF
     apiVersion: core.oam.dev/v1alpha2
     kind: Component
     metadata:
       name: oam-kube-dep-comp
       namespace: oam-kube
     spec:
       workload:
         kind: Deployment
         apiVersion: apps/v1
         name: oam-kube-dep
         spec:
           replicas: 1
           selector:
             matchLabels:
               app: oam-kube-app
           template:
             metadata:
               labels:
                 app: oam-kube-app
             spec:
               containers:
                 - name: oam-kube-cnt
                   image: hashicorp/http-echo
                   args:
                     - "-text=hello"
     EOF
    

  3. Create a Component containing a Service workload.

      $ kubectl apply -f - <<EOF
      apiVersion: core.oam.dev/v1alpha2
      kind: Component
      metadata:
        name: oam-kube-svc-comp
        namespace: oam-kube
      spec:
        workload:
          kind: Service
          apiVersion: v1
          metadata:
            name: oam-kube-svc
          spec:
            selector:
              app: oam-kube-app
            ports:
            - port: 5678 # Default port for image
      EOF
    

  4. Create an ApplicationConfiguration referencing both Components and configuring an ingress trait.

      $ kubectl apply -f - <<EOF
      apiVersion: core.oam.dev/v1alpha2
      kind: ApplicationConfiguration
      metadata:
        name: oam-kube-appconf
        namespace: oam-kube
      spec:
        components:
          - componentName: oam-kube-dep-comp
          - componentName: oam-kube-svc-comp
            traits:
              - trait:
                  apiVersion: networking.k8s.io/v1beta1
                  kind: Ingress
                  metadata:
                    name: oam-kube-ing
                    annotations:
                      kubernetes.io/ingress.class: istio
                  spec:
                    rules:
                    - host: oam-kube-app.example.com
                      http:
                        paths:
                          - path: /example
                            backend:
                              serviceName: oam-kube-svc
                              servicePort: 5678
      EOF
    

Explore the application

  1. Get the host name for the application.

    $ export HOST=$(kubectl get ingress \
        -n oam-kube oam-kube-ing \
        -o jsonpath='{.spec.rules[0].host}')
    $ echo "HOST=${HOST}"
    

  2. Get the load balancer address of the ingress gateway.

    $ export LOADBALANCER=$(kubectl get ingress \
        -n oam-kube oam-kube-ing \
        -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
    $ echo "LOADBALANCER=${LOADBALANCER}"
    

  3. Access the application.

    $ curl http://${HOST}/example --resolve ${HOST}:80:${LOADBALANCER}
    
    # Expected response
    hello
    

Undeploy the application

To undeploy the application, delete the namespace created. This will result in the deletion of all explicitly and implicitly created resources in the namespace.

$ kubectl delete namespace oam-kube

If desired, the cluster admin also can remove the created ClusterRole and ClusterRoleBinding.

$ kubectl delete ClusterRoleBinding oam-kubernetes-runtime-ingresses
$ kubectl delete ClusterRole oam-kubernetes-runtime-ingresses