My first CRD deployment with CIS

Summary

F5 Container Ingress Services (CIS) now supports the use of Custom Resource Definitions (CRD's) in Kubernetes (K8s) as a method for configuring services on the BIG-IP. This article walks through my first time deploying and what I learned.

Goal of this article

The goal of this article is to demonstrate that you can easily configure services on BIG-IP using CRD's, and this makes the configuration of services on F5 BIG-IP feel like a native Kubernetes experience, since you are creating Kubernetes resources.

Other ways to configure BIG-IP from K8s

Before F5 CIS supported CRD's, you could already use Ingress resources or ConfigMap resources to create VIPs and pool members on F5. Using CRD's now gives us a new way.

As I found in my first deployment, the advantage of CRDs over Ingress resources is that F5 can develop their own CRD and have more attributes that can map to configurations in BIG-IP. And again based on my first impressions, the advantage of CRDs over ConfigMaps is that you don't need to create an AS3 declaration yourself. You now get to do that via a Kubernetes resource. This table summarizes my opinion only:

Overview of my demo architecture

Here's an image of the cloud infrastructure I built. Basically I have a pair of BIG-IP devices in Active/Standby config, and the K8s cluster is integrated via CIS.

Here's a more application-focused image of what is deployed. NGINX Ingress Controller (open source version) is used here as an ingress controller running inside Kubernetes.


What is this resource of kind VirtualServer doing?

Here is the definition of my VirtualServer resource and the related TLSProfile resource:


apiVersion: "cis.f5.com/v1"
kind: VirtualServer
metadata:
  name: hello-world-virtual-server
  namespace: nginx-ingress
  labels:
    f5cr: "true"
spec:
  tlsProfileName: hello-world-tls  # --> This will attach hello-world-tls TLSProfile
  virtualServerAddress: "10.0.2.100"
  pools:
  - path: /
    service: nginx-ingress
    servicePort: 80
    monitor:
      type: http
      interval: 10
      timeout: 31
      send: "/"
---
 apiVersion: cis.f5.com/v1
 kind: TLSProfile
 metadata:
   name: hello-world-tls
   namespace: nginx-ingress
   labels:
     f5cr: "true"
 spec:
   tls:
     termination: edge
     clientSSL: /Common/clientssl
     reference: bigip             # --> reference profiles created in BIG-IP by User
   hosts:
   - hello-world.example.com

Now, the above resources will create objects in the BIG-IP config. I'll take a screenshot of what's created in BIG-IP and highlight some fields that you can see were configured by the resources above.



Run this demo yourself (code not supported)

Here's a link to my Github repo if you want to see the resources created. I've included instructions for deploying this demo environment, for educational purposes only. I'll use this as a tool for showing others but this will not be a supported solution long term.


Conclusion

You can use CRD's to configure F5 services from within Kubernetes. This means the Kubernetes admins can configure BIG-IP themselves, without the traditional network admin who normally "owns" F5 being involved. This was possible before CRD's (with Ingress, ConfigMap, or Routes in OpenShift) but with CRD's we have a more native-feeling resource that F5 can now extend with future CIS development.



Published Jan 26, 2021
Version 1.0
  • I want try this azure demo.

    But I get the following error while running Terraform: Unable to create a BIG-IP virtual machine.

    ----snip---

    module.aks.azurerm_kubernetes_cluster.akscluster1: Still creating... [3m50s elapsed]

    module.aks.azurerm_kubernetes_cluster.akscluster1: Still creating... [4m0s elapsed]

    module.aks.azurerm_kubernetes_cluster.akscluster1: Still creating... [4m10s elapsed]

    module.aks.azurerm_kubernetes_cluster.akscluster1: Creation complete after 4m11s [id=/subscriptions/xxxxxx-xxxx-xxx-xxxx-xxxx/resourcegroups/mydemo-rg/providers/Microsoft.ContainerService/managedClusters/mydemo-akscluster1]

    module.aks.null_resource.dependency_setter: Creating...

    module.aks.null_resource.dependency_setter: Creation complete after 0s [id=521882686397236009]

    local_file.kube_config: Creating...

    local_file.kube_config: Creation complete after 0s [id=378cb3a8c750d235cc12596f53c44dd14ef140aa]

    Error: compute.VirtualMachinesClient#CreateOrUpdate: Failure sending request: StatusCode=400 -- Original Error: Code="ResourcePurchaseValidationFailed" Message="User failed validation to purchase resources. Error message: 'You have not accepted the legal terms on this subscription: 'xxxxxx-xxxx-xxx-xxxx-xxxx' for this plan. Before the subscription can be used, you need to accept the legal terms of the image. To read and accept legal terms, use the Azure CLI commands described at https://go.microsoft.com/fwlink/?linkid=2110637 or the PowerShell commands available at https://go.microsoft.com/fwlink/?linkid=862451. Alternatively, deploying via the Azure portal provides a UI experience for reading and accepting the legal terms. Offer details: publisher='f5-networks' offer = 'f5-big-ip-best', sku = 'f5-bigip-virtual-edition-25m-best-hourly', Correlation Id: 'e106abe7-5091-4674-bf6b-ba70ca63d32f'.'"

     on bigip/bigip.tf line 392, in resource "azurerm_virtual_machine" "f5vm01":

     392: resource "azurerm_virtual_machine" "f5vm01" {

    ------------------------

    So, I apply to following azure cli command.​

    # az vm image terms accept --urn f5-networks:f5-big-ip-best:f5-bigip-virtual-edition-25m-best-hourly:latest

    {

     "accepted": true,

     "id": "/subscriptions/xxxxxx-xxxx-xxx-xxxx-xxxx/providers/Microsoft.MarketplaceOrdering/offerTypes/VirtualMachine/publishers/f5-networks/offers/f5-big-ip-best/plans/f5-bigip-virtual-edition-25m-best-hourly/agreements/current",

     "licenseTextLink": "https://storelegalterms.blob.core.windows.net/legalterms/.......ONAYGP36CIIPCICJX3ZZ7PA.txt",

     "name": "f5-bigip-virtual-edition-25m-best-hourly",

     "plan": "f5-bigip-virtual-edition-25m-best-hourly",

     "privacyPolicyLink": "https://www.f5.com/company/policies/privacy-policy",

     "product": "f5-big-ip-best",

     "publisher": "f5-networks",

     "retrieveDatetime": "2021-01-30T21:37:58.6548819Z",

     "signature": "XXXXXXXXXXXXXXXXXXXXXXXXXNJUVJXKAMIQ6O4E7AO5UXDTEBR4R2S4BSN3E3CWUR5HJHWGGVRV5HKGBX3JKUYQ",

     "

    -----------------------------------

    But, I can't seem to get rid of the error.

    ---------------------------------------------------------------

    Error: compute.VirtualMachinesClient#CreateOrUpdate: Failure sending request: StatusCode=400 -- Original Error: Code="ResourcePurchaseValidationFailed" Message="User failed validation to purchase resources. Error message: 'Offer with PublisherId: 'f5-networks', OfferId: 'f5-big-ip-best' cannot be purchased due to validation errors. For more information see details. Correlation Id: '4b93dfeb-a33d-481d-9650-13e67f9e1abb' The 'unknown' payment instrument(s) is not supported for offer with OfferId: 'f5-big-ip-best', PlanId 'f5-bigip-virtual-edition-25m-best-hourly'. Correlation Id '4b93dfeb-a33d-481d-9650-13e67f9e1abb'.'"

     

     on bigip/bigip.tf line 392, in resource "azurerm_virtual_machine" "f5vm01":

     392: resource "azurerm_virtual_machine" "f5vm01" {

    ---------------------------------------------------------------

     

    Do you know of any solution?

  • Hi Shingo!

    Thanks for trying this out. You have a clue in this part of your error message: User failed validation to purchase resources. Error message: 'You have not accepted the legal terms on this subscription: 'xxxxxx-xxxx-xxx-xxxx-xxxx' for this plan

     

    The problem is that you need to accept the marketplace image terms for this subscription. This is a once-off only thing you'll need to do per subscription. You can do this in a few ways.

    1) you can use Powershell, and the instructions to do this are in the error message, or

    2) you can just deploy this image once via the Azure portal: f5-bigip-virtual-edition-25m-best-hourly'

     

    Option #2 is probably easiest. If you need help with this, let me know and/or email or message me directly, thanks!

  • Hi Michael !

    Thanks for the advice. I was able to confirm that the NGINX Hello-World App was displayed via LB and BIGIP's Virtual Server.

    Where is the association between VirtualServer and NginxIngress tied?

    # cat ingress/cis/crd/virtualserver.yaml
    apiVersion: "cis.f5.com/v1"
    kind: VirtualServer
    metadata:
      name: hello-world-virtual-server
      namespace: nginx-ingress
      labels:
        f5cr: "true"
    spec:
      tlsProfileName: hello-world-tls  
      virtualServerAddress: "20.0.2.100"
      pools:
      - path: /
        service: nginx-ingress      #  ---->> Is This ingress/nginx/service/service.yaml ?
        servicePort: 80
        monitor:
          type: http
          interval: 10
          timeout: 31
          send: "/"
  • Hi Shingo. Great to hear. I think you put a question in line 14 above and you are correct. The service called nginx-ingress is referenced there. Nice work.