High Availability CIS Default Mode – BIG-IP CIS Multi-Cluster 구성

High Availability CIS(Container Ingress Services)는 2개의 Kubernetes/OpenShift 클러스터에 CIS 인스턴스를 각각 배포하여 이중화된 Multi-Cluster 구성을 구현하는 방식입니다. Standalone CIS와 달리 각 클러스터에 CIS가 배포되므로, 단일 CIS 인스턴스 장애 시에도 다른 클러스터의 CIS가 BIG-IP 구성을 유지할 수 있어 높은 가용성을 확보할 수 있습니다.

이번 포스트에서는 서로 다른 버전의 OCP 클러스터 2개를 대상으로 High Availability CIS를 Default Mode로 구성하고, 두 클러스터의 Pod가 BIG-IP Pool Member로 정상 등록되는지 확인하는 과정을 살펴보겠습니다.

이번 포스트의 내용은 BIG-IP CIS의 Static Route를 통한 ClusterIP 모드로 구성되었습니다.

Standalone CIS를 Default Mode로 구성하는 방법은 Standalone CIS Default Mode – BIG-IP CIS Multi-Cluster 구성 포스트를 참고하세요.

목차

1. High Availability CIS Default Mode란?
  1-1. 동작 방식
2. 환경/버전 정보
3. High Availability CIS 구성 전 사전 준비
  3-1. Primary/Secondary 클러스터 접근을 위한 kubeconfig Secret 생성
  3-2. Default Mode Extended ConfigMap 생성
4. High Availability CIS – Default Mode 배포
5. VirtualServer 구성 및 BIG-IP Pool 확인
6. 결론

1. High Availability CIS Default Mode란?

High Availability CIS 구성
https://github.com/F5Networks/k8s-bigip-ctlr/blob/master/docs/config_examples/multicluster/images/haMultiCluster.png

High Availability CIS Default Mode는 Primary/Secondary 두 클러스터에 CIS 인스턴스를 각각 배포하여 이중화된 구성을 갖추는 방식입니다. Standalone CIS가 단일 CIS 인스턴스로 여러 클러스터를 관리하는 방식과 달리, HA 구성에서는 Primary CIS와 Secondary CIS가 서로의 역할을 인식하며 동작합니다.

HA CIS 구성에서는 하나의 클러스터 CIS가 Primary, 다른 클러스터 CIS가 Secondary 역할을 담당합니다. Primary CIS가 정상 동작 중일 때는 BIG-IP로의 AS3 선언 전송을 담당하며, Primary 클러스터에 장애가 발생하면 Secondary CIS가 이를 감지하고 BIG-IP 구성을 인계받아 서비스 연속성을 유지합니다.

CIS가 배포되는 클러스터는 Primary/Secondary 두 클러스터로 한정되며, 그 외 애플리케이션만 배포된 클러스터는 Extended ConfigMap의 externalClustersConfig를 통해 추가로 정의할 수 있습니다. 외부 클러스터로 정의된 클러스터에는 별도의 CIS 설치가 필요하지 않으며, 해당 클러스터의 Pod/노드도 BIG-IP Pool Member로 함께 등록할 수 있습니다.

이번 포스트에서는 Default Mode로 구성하여 두 클러스터의 Pod가 BIG-IP Pool Member로 정상 등록되는지 확인합니다.

1-1. 동작 방식

High Availability CIS Default Mode는 다음과 같은 방식으로 동작합니다.

  • Primary CIS는 1번 클러스터에, Secondary CIS는 2번 클러스터에 각각 Pod 형태로 배포됩니다. Primary CIS는 multi_cluster_mode: primary, Secondary CIS는 multi_cluster_mode: secondary 옵션으로 동작합니다.
  • Extended ConfigMap에 Primary/Secondary 클러스터 정보와 Primary 클러스터의 API 엔드포인트(primaryEndPoint)를 정의합니다. Secondary CIS는 primaryEndPoint를 주기적으로 probe(상태 확인)하여 Primary CIS의 상태를 감지하며, Primary가 정상일 때는 Primary CIS가, Primary가 다운되면 Secondary CIS가 BIG-IP로의 AS3 선언 전송을 담당합니다.
  • Primary CIS가 두 클러스터의 리소스를 조회하여 AS3 선언을 작성하고 BIG-IP에 전송합니다. Secondary CIS는 primaryEndPoint를 주기적으로 probe하며 대기하다가, Primary 장애 감지 시 AS3 선언 전송을 인계받습니다.
  • VirtualServer, TransportServer 등의 CIS 모니터링 리소스(CRD, ExtendedConfigMap 포함)는 Primary/Secondary 클러스터 양쪽에 동일하게 배포해야 합니다. Secondary 클러스터에 해당 리소스가 없으면 장애 발생 시 Secondary CIS가 이를 처리하지 못합니다.
  • BIG-IP는 Primary 또는 Secondary CIS로부터 수신한 AS3 선언을 기반으로 Pool Member를 구성하고 트래픽을 분배합니다.

2. 환경/버전 정보

구성 요소버전
Red Hat OpenShift Cluster 14.18.24
Red Hat OpenShift Cluster 24.21.6
CNIOVN-Kubernetes
F5 BIG-IP VE17.5.0
F5 Container Ingress Services Operatorv1.21.0
F5 BIG-IP CIS2.20.3
AS3(Application Services 3) Extensionv3.56.0

3. High Availability CIS 구성 전 사전 준비

High Availability CIS Default Mode 구성 전에 필요한 사전 준비를 진행합니다. Standalone CIS 구성과 달리 HA 구성에서는 각 클러스터가 서로의 kubeconfig를 참조해야 하므로, 1번 클러스터와 2번 클러스터 모두에 kubeconfig Secret을 생성합니다.

3-1. Primary/Secondary 클러스터 접근을 위한 kubeconfig Secret 생성

Standalone CIS 구성과 달리 HA 구성에서는 각 클러스터가 서로의 리소스를 조회할 수 있어야 합니다. Primary CIS(1번 클러스터)는 2번 클러스터의 리소스를 조회하고, Secondary CIS(2번 클러스터)는 장애 발생 시 1번 클러스터의 리소스를 조회하므로, 각 클러스터에 상대 클러스터의 kubeconfig Secret을 생성합니다.

우선 각 클러스터에 CIS 전용 ServiceAccount와 권한을 생성합니다. 아래 yaml을 1번, 2번 클러스터 모두에 적용합니다.

external-cluster-rbac.yaml
# for reference only
# Should be changed as per your cluster requirements
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: bigip-ctlr-clusterrole
rules:
- apiGroups: [""]
resources: ["nodes", "services", "endpoints", "namespaces", "pods"]
verbs: ["get", "list", "watch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: bigip-ctlr-clusterrole-binding
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: bigip-ctlr-clusterrole
subjects:
- apiGroup: ""
kind: ServiceAccount
name: bigip-ctlr
namespace: kube-system
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: bigip-ctlr
namespace: kube-system
$ oc apply -f external-cluster-rbac.yaml
clusterrole.rbac.authorization.k8s.io/bigip-ctlr-clusterrole created
clusterrolebinding.rbac.authorization.k8s.io/bigip-ctlr-clusterrole-binding created
serviceaccount/bigip-ctlr created

다음 yaml을 사용하여 생성한 ServiceAccount와 연결된 토큰을 생성합니다. 이 역시 1번, 2번 클러스터 모두에 적용합니다.

token-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: bigip-ctlr-token
namespace: kube-system
annotations:
kubernetes.io/service-account.name: bigip-ctlr
type: kubernetes.io/service-account-token
$ oc apply -f token-secret.yaml
secret/bigip-ctlr-token created

다음 스크립트를 사용하여 각 클러스터에서 kubeconfig 파일을 생성합니다. CLUSTER_NAME 변수를 각 클러스터에 맞게 변경하여 실행합니다.

create_kubeconfig.sh
#!/bin/bash
# 변수 설정
SA_NAME="bigip-ctlr"
NAMESPACE="kube-system"
CLUSTER_NAME="cluster1-1" # 클러스터에 맞게 변경 (cluster1-1 또는 cluster1-2)
FILE_NAME="${CLUSTER_NAME}-kubeconfig.yaml"
# API 서버 주소 추출 (현재 컨텍스트 기준)
SERVER_URL=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')
# CA 인증서 추출 (Base64 인코딩 상태 그대로 사용)
CA_CERT=$(kubectl get secret ${SA_NAME}-token -n ${NAMESPACE} -o jsonpath='{.data.ca\.crt}')
# SA 토큰 추출 (Base64 디코딩하여 사용)
TOKEN=$(kubectl get secret ${SA_NAME}-token -n ${NAMESPACE} -o jsonpath='{.data.token}' | base64 --decode)
# kubeconfig 파일 생성
cat <<EOF > ${FILE_NAME}
apiVersion: v1
kind: Config
clusters:
- name: ${CLUSTER_NAME}
cluster:
certificate-authority-data: ${CA_CERT}
server: ${SERVER_URL}
contexts:
- name: f5-cis-context
context:
cluster: ${CLUSTER_NAME}
namespace: ${NAMESPACE}
user: ${SA_NAME}
current-context: f5-cis-context
users:
- name: ${SA_NAME}
user:
token: ${TOKEN}
EOF
echo "${FILE_NAME} 파일이 성공적으로 생성되었습니다."

생성된 kubeconfig 파일을 사용하여 상대 클러스터에 Secret을 생성합니다.

# 1번 클러스터에서 실행 → 2번 클러스터의 kubeconfig Secret 생성
$ oc create secret generic kubeconfig-cluster1-2 -n kube-system \
--from-file=kubeconfig=cluster1-2-kubeconfig.yaml
secret/kubeconfig-cluster1-2 created
# 2번 클러스터에서 실행 → 1번 클러스터의 kubeconfig Secret 생성
$ oc create secret generic kubeconfig-cluster1-1 -n kube-system \
--from-file=kubeconfig=cluster1-1-kubeconfig.yaml
secret/kubeconfig-cluster1-1 created

3-2. High Availability CIS Default Mode Extended ConfigMap 생성

HA CIS 구성에서는 Standalone CIS와 달리 Extended ConfigMap에 highAvailabilityCIS 하위에 Primary/Secondary 클러스터 정보와 Primary 엔드포인트를 정의합니다. 이 ConfigMap은 두 클러스터 모두에 동일하게 생성합니다.

extended-config-ha.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: extended-spec-config
namespace: kube-system
data:
extendedSpec: |
mode: default
highAvailabilityCIS:
primaryEndPoint: tcp://api.cluster1-1.devopssong.site:6443
probeInterval: 30
retryInterval: 3
primaryCluster:
clusterName: cluster1-1
secret: kube-system/kubeconfig-cluster1-1
secondaryCluster:
clusterName: cluster1-2
secret: kube-system/kubeconfig-cluster1-2

각 필드의 의미는 다음과 같습니다.

  • mode: Multi-Cluster 구성 모드를 정의합니다. Default Mode이므로 default를 사용합니다.
  • primaryEndPoint: Secondary CIS가 Primary 클러스터의 상태를 감지하기 위한 엔드포인트입니다. TCP와 HTTP 프로토콜을 지원하며, Secondary CIS는 probeInterval마다 해당 엔드포인트를 확인하며, 응답이 없을 경우 retryInterval 간격으로 재시도합니다.
    본 포스트에서는 Primary 클러스터의 API 서버 엔드포인트를 tcp 프로토콜로 감지하도록 설정했습니다.
  • probeInterval: Primary 엔드포인트 상태 확인 주기(초)입니다. 기본값: 60
  • retryInterval: Primary 엔드포인트 응답 없을 시 재시도 간격(초)입니다. 기본값: 15
  • primaryCluster.clusterName: Primary 클러스터 이름입니다.
  • primaryCluster.secret: Primary 클러스터의 kubeconfig로 생성한 Secret의 네임스페이스/이름입니다.
  • secondaryCluster.clusterName: Secondary 클러스터 이름입니다.
  • secondaryCluster.secret: Secondary 클러스터의 kubeconfig로 생성한 Secret의 네임스페이스/이름입니다.
# 1번 클러스터에서 실행
$ oc apply -f extended-config-default.yaml
configmap/extended-spec-config created
# 2번 클러스터에서 실행
$ oc apply -f extended-config-default.yaml
configmap/extended-spec-config created
외부 클러스터 추가 구성 (선택)

HA 구성에서도 Primary/Secondary 클러스터 외에 CIS가 배포되지 않은 외부 클러스터를 추가로 관리할 수 있습니다. externalClustersConfig를 통해 외부 클러스터를 정의하면 해당 클러스터의 Pod도 BIG-IP Pool Member로 함께 등록할 수 있으며, 외부 클러스터에는 별도의 CIS 설치가 필요하지 않습니다.

단, HA 클러스터로 지정된 Primary/Secondary 클러스터를 externalClustersConfig에 중복 정의하지 않도록 주의합니다.

apiVersion: v1
kind: ConfigMap
metadata:
name: extended-spec-config
namespace: kube-system
data:
extendedSpec: |
mode: default
highAvailabilityCIS:
primaryEndPoint: tcp://api.cluster1-1.devopssong.site:6443
probeInterval: 30
retryInterval: 3
primaryCluster:
clusterName: cluster1-1
secret: kube-system/kubeconfig-cluster1-1
secondaryCluster:
clusterName: cluster1-2
secret: kube-system/kubeconfig-cluster1-2
externalClustersConfig: # CIS 미설치 외부 클러스터 추가 정의
- clusterName: cluster1-3
secret: kube-system/kubeconfig-cluster1-3
- clusterName: cluster1-4
secret: kube-system/kubeconfig-cluster1-4

4. High Availability CIS – Default Mode 배포

Primary CIS는 1번 클러스터에, Secondary CIS는 2번 클러스터에 각각 배포합니다. 두 방식 모두 Static Route를 활용한 ClusterIP 모드로 구성했으며 Pod CIDR이 중복되지 않도록 클러스터를 구성했습니다.

이번 구성에서 Primary CIS(1번 클러스터, OCP 4.18)는 OperatorHub를 통해 설치된 F5 Container Ingress Services Operator를 사용하여 배포했습니다. Secondary CIS가 배포되는 2번 클러스터(OCP 4.21)는 작성 시점 기준 CIS Operator가 아직 검증/인증되지 않아 OperatorHub에서 제공되지 않으므로, Helm을 사용하여 배포했습니다.

Primary CIS 배포 (1번 클러스터 – Operator)

f5bigipctlr-f5bigipctlr.yaml
kind: F5BigIpCtlr
apiVersion: cis.f5.com/v1
metadata:
name: f5bigipctlr
namespace: openshift-operators
spec:
args:
agent: as3
bigip_partition: ocp-cluster-1 # CIS 연동할 BIG-IP 파티션
bigip_url: 192.168.40.121 # BIG-IP VE IP
insecure: true
log_as3_response: true
log_level: INFO
manage_routes: false
manage_ingress: false
custom_resource_mode: true # Custom Resource 사용 모드 설정
### OpenShift OVN-K8s 사용 clusterIP, static routing 설정
pool_member_type: cluster
static_routing_mode: true
orchestration_cni: ovn-k8s
### CIS Multi-Cluster 설정
multi_cluster_mode: primary # Primary CIS 설정
local_cluster_name: cluster1-1 # Primary 클러스터 이름
extended_spec_configmap: kube-system/extended-spec-config # 앞서 생성한 Extended ConfigMap의 네임스페이스/이름
bigip_login_secret: f5-bigip-ctlr-login # BIG-IP 로그인 정보가 기록된 secret
image:
pullPolicy: Always
repo: k8s-bigip-ctlr
user: f5networks
ingressClass:
create: false
defaultController: false
ingressClassName: f5
namespace: kube-system
rbac:
create: true
resources: {}
serviceAccount:
create: true
version: latest

Secondary CIS 배포 (2번 클러스터 – Helm)

cis_values.yaml
# BIG-IP admin 권한 사용자 접속 정보
bigip_secret:
create: true
username: admin
password: "yourPassword"
rbac:
create: true
serviceAccount:
create: true
name: k8s-bigip-ctlr
namespace: kube-system
args:
bigip_url: 192.168.40.121
bigip_partition: ocp-cluster-1
log_level: INFO
pool_member_type: cluster
insecure: true
custom-resource-mode: true
static-routing-mode: true
orchestration-cni: ovn-k8s
log-as3-response: true
### CIS Multi-Cluster HA 설정
multi-cluster-mode: secondary # Secondary CIS 설정
local-cluster-name: cluster1-2 # Secondary 클러스터 이름
extended-spec-configmap: kube-system/extended-spec-config # 앞서 생성한 Extended ConfigMap의 네임스페이스/이름
image:
user: quay.io/f5networks
repo: k8s-bigip-ctlr
pullPolicy: Always
version: 2.20.3

Operator와 Helm의 일부 옵션 명칭 형식에 차이가 있습니다. Operator는 언더스코어(_)를 사용하고, Helm은 하이픈(-)을 사용합니다. 예: multi_cluster_mode(Operator) / multi-cluster-mode(Helm).

Helm value 전체 옵션은 링크에서 확인하세요.

배포가 완료된 후 각 클러스터의 CIS Pod 로그를 확인합니다.

# 1번 클러스터 - Primary CIS
$ oc get po -n kube-system
NAME READY STATUS RESTARTS AGE
f5bigipctlr-f5-bigip-ctlr-7f68664b9c-zrwjv 1/1 Running 0 64s
$ oc logs f5bigipctlr-f5-bigip-ctlr-7f68664b9c-zrwjv -n kube-system
2026/04/13 07:44:58 [INFO] [MultiCluster] CIS running with multi-cluster-mode: primary
2026/04/13 07:44:58 [INFO] [INIT] Starting: Container Ingress Services - Version: v2.20.3, BuildInfo: gitlab-16324349-acadb9e63a1117defbb70d6096950df1fe5db713
......
------
# 2번 클러스터 - Secondary CIS
$ oc get po -n kube-system
NAME READY STATUS RESTARTS AGE
cis-f5-bigip-ctlr-57678f4797-2c724 1/1 Running 0 118s
$ oc logs cis-f5-bigip-ctlr-57678f4797-2c724 -n kube-system
2026/04/13 07:45:10 [INFO] [MultiCluster] CIS running with multi-cluster-mode: secondary
2026/04/13 07:45:10 [INFO] [INIT] Starting: Container Ingress Services - Version: v2.20.3, BuildInfo: gitlab-16324349-acadb9e63a1117defbb70d6096950df1fe5db713
......

Primary CIS는 multi-cluster-mode: primary, Secondary CIS는 multi-cluster-mode: secondary로 동작 중임을 확인할 수 있습니다.

5. VirtualServer 구성 및 BIG-IP Pool 확인

High Availability CIS Default Mode 환경에서 각 클러스터에 동일한 애플리케이션의 Deployment/Service를 배포하고, CIS Custom Resource인 VirtualServer를 구성하여 각 클러스터의 Pod가 BIG-IP Pool로 구성되는 것을 확인하겠습니다.

백엔드 Pod를 생성하고 연결하기 위해 Deployment와 Service를 1번, 2번 클러스터의 default 네임스페이스에 모두 배포합니다.

coffee-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: coffee
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: coffee
template:
metadata:
labels:
app: coffee
spec:
containers:
- name: coffee
image: nginxdemos/hello
ports:
- containerPort: 80
coffee-service.yaml
apiVersion: v1
kind: Service
metadata:
name: coffee-svc
namespace: default
labels:
app: coffee-svc
spec:
ports:
- name: coffee-svc
port: 80
protocol: TCP
targetPort: 80
selector:
app: coffee
## cluster 1
$ oc get po,svc -n default -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/coffee-56b689cd7-5qbnq 1/1 Running 0 24s 10.128.0.114 c1-1-node <none> <none>
pod/coffee-56b689cd7-pcg8c 1/1 Running 0 24s 10.128.0.115 c1-1-node <none> <none>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/coffee-svc ClusterIP 172.30.250.59 <none> 80/TCP 20s app=coffee
service/kubernetes ClusterIP 172.30.0.1 <none> 443/TCP 12d <none>
service/openshift ExternalName <none> kubernetes.default.svc.cluster.local <none> 12d <none>
------
## cluster 2
$ oc get po,svc -n default -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/coffee-86f468ccd6-cgxkk 1/1 Running 0 57s 10.128.128.62 c1-2-node <none> <none>
pod/coffee-86f468ccd6-wztdf 1/1 Running 0 56s 10.128.128.63 c1-2-node <none> <none>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/coffee-svc ClusterIP 172.30.132.107 <none> 80/TCP 56s app=coffee
service/kubernetes ClusterIP 172.30.0.1 <none> 443/TCP 12d <none>
service/openshift ExternalName <none> kubernetes.default.svc.cluster.local <none> 12d <none>

배포한 Pod로 트래픽을 전달하기 위한 CIS의 VirtualServer 리소스를 1번, 2번 클러스터 양쪽에 동일하게 default 네임스페이스에 배포합니다.

cis-vs.yaml
apiVersion: "cis.f5.com/v1"
kind: VirtualServer
metadata:
name: cafe-coffee-vs
namespace: default
# CIS가 관리할 VirtualServer 리소스임을 식별하는 레이블
labels:
f5cr: "true"
spec:
virtualServerAddress: "192.168.40.230" # BIG-IP에 생성될 VIP
virtualServerName: "cafe_coffee_vs" # BIG-IP에 생성될 VirtualServer 이름
host: "cafeone.example.com"
pools:
- path: "/coffee"
# BIG-IP에 구성될 monitor 설정(Health Check)
monitor:
type: http
send: "GET /coffee HTTP/1.1\r\nHost: cafeone.example.com\r\nConnection: Close\r\n\r\n"
recv: ""
interval: 5
timeout: 16
# 멀티 클러스터 구성에서 트래픽을 전달할 클러스터 이름, 네임스페이스, 서비스 이름 및 포트 정보
multiClusterServices:
- clusterName: cluster1-1 # CIS 설정의 local_cluster_name
namespace: default
service: coffee-svc
servicePort: 80
- clusterName: cluster1-2 # Extended ConfigMap에 구성된 clusterName
namespace: default
service: coffee-svc
servicePort: 80

배포가 완료되고 CIS가 정상적으로 처리되면 아래와 같이 VirtualServer 상태를 확인할 수 있습니다. Primary CIS가 동작 중인 1번 클러스터에서는 IPAMVSADDRESSSTATUS가 정상적으로 표시되며, Secondary CIS가 대기 중인 2번 클러스터에서는 해당 필드가 표시되지 않습니다.

## cluster 1
$ oc get virtualservers.cis.f5.com -n default
NAME HOST TLSPROFILENAME HTTPTRAFFIC IPADDRESS IPAMLABEL IPAMVSADDRESS STATUS AGE
cafe-coffee-vs cafeone.example.com 192.168.40.230 192.168.40.230 OK 10m
## cluster 2
$ oc get virtualservers.cis.f5.com -n default
NAME HOST TLSPROFILENAME HTTPTRAFFIC IPADDRESS IPAMLABEL IPAMVSADDRESS STATUS AGE
cafe-coffee-vs cafeone.example.com 192.168.40.230 10

Primary CIS Pod의 로그를 확인하면 VirtualServer 구성에 기반한 설정을 BIG-IP로 전송하여 반영하는 것을 확인할 수 있습니다. Secondary CIS Pod의 로그에는 별도 Post 및 설정 생성 동작이 없는 것을 확인할 수 있습니다.

## cluster 1
$ oc logs f5bigipctlr-f5-bigip-ctlr-7f68664b9c-zrwjv -n kube-system
...
2026/04/13 08:09:19 [INFO] [Request: 4] cluster cluster1-2 requested CREATE in ENDPOINTS default/coffee-svc
2026/04/13 08:09:21 [INFO] [Request: 4][AS3] creating a new AS3 manifest
2026/04/13 08:09:21 [INFO] [Request: 4][AS3][BigIP] posting request to https://192.168.40.121 for tenants
2026/04/13 08:09:42 [INFO] [Request: 4][AS3][BigIP] post resulted in SUCCESS
2026/04/13 08:09:42 [INFO] [AS3][POST] SUCCESS: code: 200 --- tenant:ocp-cluster-1 --- message: success
2026/04/13 08:09:42 [INFO] Successfully updated status of VirtualServer:default/cafe-coffee-vs in Cluster cluster1-1
------
## cluster 2
$ oc logs cis-f5-bigip-ctlr-57678f4797-2c724 -n kube-system
...
2026/04/13 08:09:15 [INFO] [Request: 3] cluster cluster1-1 requested CREATE in ENDPOINTS default/coffee-svc

BIG-IP GUI에 접속하여, 좌측 메뉴 바의 Local Traffic > Virtual Servers 메뉴로 이동합니다.

우측 상단의 파티션 지정 메뉴에서 CIS와 연동된 파티션을 선택하면, 클러스터 내부에 배포한 VirtualServers 리소스를 통해 생성된 Virtual Server를 확인할 수 있습니다.

High Availability CIS VirtualServer

좌측 메뉴 바의 Local Traffic > Pools 메뉴로 이동하면 리스트에서 클러스터 별로 개별 Pool이 구성된 것을 확인할 수 있습니다.

High Availability CIS Pools

개별 Pool의 이름을 클릭하고, 상단의 Members 버튼을 클릭하면 개별 Pod를 확인할 수 있습니다. CIS를 NodePort 모드로 구성한 경우 노드가 member로 구성됩니다.

## cluster 1
$ oc get po -n default -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/coffee-56b689cd7-5qbnq 1/1 Running 0 24s 10.128.0.114 c1-1-node <none> <none>
pod/coffee-56b689cd7-pcg8c 1/1 Running 0 24s 10.128.0.115 c1-1-node <none> <none>
------
## cluster 2
$ oc get po -n default -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/coffee-86f468ccd6-cgxkk 1/1 Running 0 57s 10.128.128.62 c1-2-node <none> <none>
pod/coffee-86f468ccd6-wztdf 1/1 Running 0 56s 10.128.128.63 c1-2-node <none> <none>

High Availability CIS Default Mode 구성에서는 두 클러스터의 Pod가 각각 Pool Member로 등록되고, BIG-IP는 이를 단일 Virtual Server에서 통합적으로 로드밸런싱하게 됩니다.

6. 결론

이번 포스트에서는 High Availability CIS를 Default Mode로 구성하여 서로 다른 OpenShift 클러스터의 애플리케이션을 하나의 BIG-IP Virtual Server로 통합하는 방법을 확인했습니다.

Standalone CIS와의 주요 차이점은 각 클러스터에 Primary/Secondary 역할의 CIS를 별도로 배포한다는 점과, Extended ConfigMap에 highAvailabilityCIS 블록을 추가하여 Primary 엔드포인트 및 각 클러스터 정보를 정의한다는 점입니다. 이를 통해 단일 CIS 인스턴스에 장애가 발생하더라도 서비스 연속성을 유지할 수 있습니다.

BIG-IP CIS와 F5 NGINX Ingress Controller를 활용하여 Kubernetes/OpenShift 환경의 트래픽을 통합 관리하고 싶으시다면 NGINX STORE를 통해 문의하세요.

NGINX STORE를 통한 솔루션 도입 및 기술지원 무료 상담 신청

* indicates required