Thunder Kubernetes Connector with Thunder ADC

siddharthaasiddharthaa Member
edited March 2022 in DevOps

In this article, we will see how Thunder Kubernetes Connector (TKC) can dynamically configure the Thunder ADC for load-balancing traffic to a Kubernetes cluster.


Setup

The K8s cluster consists of:

  • Master: 172.16.1.12
  • Node: 172.16.1.13
  • Node: 172.16.1.14

 The Pod network is 192.168.0.0/16.



The K8s version is:

$ kubectl version
Client Version: version.Info{Major:"1", Minor:"21", GitVersion:"v1.21.2", GitCommit:"092fbfbf53427de67cac1e9fa54aaa09a28371d7", GitTreeState:"clean", BuildDate:"2021-06-16T12:59:11Z", GoVersion:"go1.16.5", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"21", GitVersion:"v1.21.2", GitCommit:"092fbfbf53427de67cac1e9fa54aaa09a28371d7", GitTreeState:"clean", BuildDate:"2021-06-16T12:53:14Z", GoVersion:"go1.16.5", Compiler:"gc", Platform:"linux/amd64"}


The Thunder ADC is running ACOS 5.2.1-p2 and has the interface ethernet 1 connected to the network 172.16.1.0/24:

interface ethernet 1
 enable
 ip address 172.16.1.10 255.255.255.0


Configuration

The Thunder Kubernetes Connector (TKC) will run as a Pod within the K8s cluster and will communicate with Thunder ADC on interface ethernet 1, and hence enable management access on that interface of the Thunder ADC:

 enable-management service https
 ethernet 1


In the K8s cluster, deploy a web service named web01, with Service type as NodePort:

$ cat a10-web01.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: webmap01
data:
  index.html: "<html><h1>This is web service web01</h1><html>"
---
apiVersion: v1
kind: Service
metadata:
  name: web01
spec:
  type: NodePort
  ports:
    - name: http-port
      protocol: TCP
      port: 8080
      targetPort: 80
  selector:
    app: web01
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web01
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web01
  template:
    metadata:
      labels:
        app: web01
    spec:
      volumes:
        - name: volmap
          configMap:
            name: webmap01
      containers:
        - name: nginx
          image: nginx:1.13
          ports:
            - containerPort: 80
          volumeMounts:
            - name: volmap
              mountPath: /usr/share/nginx/html/


$ kubectl apply -f a10-web01.yaml

$ kubectl get pods
NAME                                                READY   STATUS    RESTARTS   AGE
web01-68c59f6f4c-6cqzb                              1/1     Running   0          5d18h
web01-68c59f6f4c-722wm                              1/1     Running   0          5d18h
web01-68c59f6f4c-qgmv5                              1/1     Running   0          42d


Next, we will create a Secret object with base64 encoding of the default username/password for the Thunder ADC (admin/a10):

$ cat a10-secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: a10-secret
type: Opaque
data:
  username: YWRtaW4=
  password: YTEw


$ kubectl apply -f a10-secret.yaml


Deploy ServiceAccount, ClusterRole, and ClusterRoleBinding objects.

This ServiceAccount will subsequently be applied to the TKC, thereby granting the TKC the required permissions to access the various resources within the K8s cluster.

$ cat a10-rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
 name: a10-ingress
 namespace: default
---

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
 name: a10-ingress
rules:
 - apiGroups: [""]
  resources: ["pods", "nodes", "services", "endpoints", "secrets", "configmaps"]
  verbs: ["get", "list", "watch"]
 - apiGroups: ["extensions", "networking.k8s.io"]
  resources: ["ingresses"]
  verbs: ["get", "list", "watch"]
---

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
 name: a10-ingress
roleRef:
 apiGroup: rbac.authorization.k8s.io
 kind: ClusterRole
 name: a10-ingress
subjects:
 - kind: ServiceAccount
  name: a10-ingress
  namespace: default

$ kubectl apply -f a10-rbac.yaml


Now deploy an Ingress Resource with ingress class of a10-ext:

$ cat a10-ingress01.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: a10-ingress01
  namespace: default
  annotations:
    kubernetes.io/ingress.class: a10-ext
    acos.a10networks.com/health-monitors: '[{"name":"ws-mon-web01", "port":"80","type":"http"}]'
    web01.acos.a10networks.com/service-group: '{"name":"ws-sg-web01","protocol":"tcp","monitor":"ws-mon-web01","disableMonitor":false}'
    acos.a10networks.com/virtual-server: '{"name":"ws-vip-web01","vip":"172.16.1.251"}'
    acos.a10networks.com/virtual-ports: '[{"port":"80","protocol":"http","http2":false,"snat":true}]'
spec:
  rules:
  - host: web01.a10tests.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web01
            port:
              number: 8080


$ kubectl apply -f a10-ingress01.yaml

$ kubectl get ingress
NAME            CLASS    HOSTS                ADDRESS   PORTS   AGE
a10-ingress01   <none>   web01.a10tests.com             80      4d2h


Note that "web01" in:

web01.acos.a10networks.com/service-group: '{"name":"ws-sg-web01","protocol":"tcp","monitor":"ws-mon-web01","disableMonitor":false}'

should match the name of the web service deployed earlier.


To deploy the TKC, create the following file:

$ cat a10-tkc-v1.10.3.0.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: a10-thunder-kubernetes-connector
spec:
  replicas: 1
  selector:
    matchLabels:
      app: thunder-kubernetes-connector
  template:
    metadata:
      labels:
        app: thunder-kubernetes-connector
    spec:
      serviceAccountName: a10-ingress
      containers:
      - name: thunder-kubernetes-connector
        image: a10networks/a10-kubernetes-connector:1.10.3.0
        imagePullPolicy: IfNotPresent
        env:
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: WATCH_NAMESPACE
          value: default
        - name: CONTROLLER_URL
          value: https://172.16.1.10
        - name: ACOS_USERNAME_PASSWORD_SECRETNAME
          value: a10-secret
        - name: PARTITION
          value: shared
        args:
        - --watch-namespace=$(WATCH_NAMESPACE)
        - --use-node-external-ip=true
        - --patch-to-update=true
        - --safe-acos-delete=true
        - --use-ingress-class-only=true
        - --ingress-class=a10-ext



The value of CONTROLLER_URL is specified as 172.16.1.10, which is the IP address of interface ethernet 1 on the Thunder ADC.


Deploy the TKC:

$ kubectl apply -f a10-tkc.yaml

$ kubectl get pods
NAME                                                READY   STATUS    RESTARTS   AGE
a10-thunder-kubernetes-connector-797b545746-d2t6p   1/1     Running   0          113s
web01-68c59f6f4c-6cqzb                              1/1     Running   0          5d18h
web01-68c59f6f4c-722wm                              1/1     Running   0          5d18h
web01-68c59f6f4c-qgmv5                              1/1     Running   0          42d


On the Thunder ADC, you will see the following configuration has been added by the TKC:

health monitor ws-mon-web01
  method http port 32330 expect response-code 200 url GET /
!
slb server 172.16.1.13 172.16.1.13
  port 32330 tcp
!
slb server 172.16.1.14 172.16.1.14
  port 32330 tcp
!
slb service-group ws-sg-web01 tcp
  health-check ws-mon-web01
  member 172.16.1.13 32330
  member 172.16.1.14 32330
!
slb virtual-server ws-vip-web01 172.16.1.251
  port 80 http
    source-nat auto
    service-group ws-sg-web01


Verification

On the client machine we have a DNS entry for "web01.a10tests.com" mapped to the VIP on the Thunder ADC:

$ cat /etc/hosts
127.0.0.1  localhost localhost.localdomain localhost4 localhost4.localdomain4
::1     localhost localhost.localdomain localhost6 localhost6.localdomain6

172.16.1.251  web01.a10tests.com


Now you can access the website http://web01.a10tests.com from this client machine:



More Information

For more information see the webinar:

https://www.a10networks.com/webinars/advanced-application-access-for-kubernetes/

Sign In or Register to comment.