VMware Tanzu RabbitMQ on Kubernetes 4.2のHelm Chartをリロケートしてインストールするメモ
Warning
Work in Progress
cert-managerがインストール済みの状態を前提とします。
Helm Chartのリロケート
https://support.broadcom.com にログインして、"My Downloads"ページにアクセスし、"Registry Tokens"ボタンをクリック。

"Generate Registry Token"ボタンをクリックして、"Submit"ボタンをクリック。

生成されたトークンの"Copy Token"ボタンをクリックし、トークンをクリップボードにコピーします。

export BROADCOM_USERNAME=your-email-address@example.com
export BROADCOM_TOKEN=eyJ2ZXIiO.....
docker login rabbitmq-helmoci.packages.broadcom.com -u ${BROADCOM_USERNAME} -p ${BROADCOM_TOKEN}
docker login rabbitmq-operator.packages.broadcom.com -u ${BROADCOM_USERNAME} -p ${BROADCOM_TOKEN}
docker login rabbitmq.packages.broadcom.com -u ${BROADCOM_USERNAME} -p ${BROADCOM_TOKEN}
"Login Succeeded"と出力されればOKです。
Helmプラグインである"Distribution Tooling for Helm"を使います。
次のコマンドでインストールできます。
helm plugin install https://github.com/vmware-labs/distribution-tooling-for-helm
VMware Tanzu RabbitMQ on Kubernetesのダウンロードページにアクセスし、最新のバージョン(ここでは4.2.3)を確認します。
helm dt wrap oci://rabbitmq-helmoci.packages.broadcom.com/tanzu-rabbitmq-operators --version 4.2.3
次のように出力されればOKです。認証エラーになる場合は、docker loginが漏れています。

export REGISTRY_HOST=registry.example.com
export REGISTRY_USERNAME=changeme
export REGISTRY_PASSWORD=changeme
docker login ${REGISTRY_HOST} -u ${REGISTRY_USERNAME} -p ${REGISTRY_PASSWORD}
helm dt unwrap tanzu-rabbitmq-operators-4.2.3.wrap.tgz ${REGISTRY_HOST}/tanzu-rabbitmq --yes

$ helm show values oci://${REGISTRY_HOST}/tanzu-rabbitmq/tanzu-rabbitmq-operators | grep 'registry:' -A 1
Pulled: registry.example.com/tanzu-rabbitmq/tanzu-rabbitmq-operators:4.2.3
Digest: sha256:2faca9c439fe447f995285270c940c5a0930391bf7345bcc14872ae30f0d3b7b
registry: registry.example.com
repository: tanzu-rabbitmq/vmware-tanzu-rabbitmq
--
registry: registry.example.com
repository: tanzu-rabbitmq/default-user-credential-updater
--
registry: registry.example.com
repository: tanzu-rabbitmq/cluster-operator
--
registry: registry.example.com
repository: tanzu-rabbitmq/messaging-topology-operator
--
registry: registry.example.com
repository: tanzu-rabbitmq/audit-logger
kubectl create namespace rabbitmq-system
kubectl create secret docker-registry -n rabbitmq-system tanzu-rabbitmq-registry-creds \
--docker-server ${REGISTRY_HOST} \
--docker-username ${REGISTRY_USERNAME} \
--docker-password ${REGISTRY_PASSWORD}
RabbitMQ Opeartorのインストール
helm upgrade tanzu-rabbitmq oci://${REGISTRY_HOST}/tanzu-rabbitmq/tanzu-rabbitmq-operators -n rabbitmq-system --version 4.2.3 --install --wait
$ helm list -n rabbitmq-system
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
tanzu-rabbitmq rabbitmq-system 1 2026-02-10 12:55:23.896299 +0900 JST deployed tanzu-rabbitmq-operators-4.2.3 4.2.3
$ kubectl get pod -n rabbitmq-system
NAME READY STATUS RESTARTS AGE
messaging-topology-operator-7cdd799697-n97t7 1/1 Running 0 60s
rabbitmq-cluster-operator-6fdfbf966f-8mmtg 1/1 Running 0 60s
$ kubectl api-resources --api-group=rabbitmq.com
NAME SHORTNAMES APIVERSION NAMESPACED KIND
bindings rabbitmq.com/v1beta1 true Binding
exchanges rabbitmq.com/v1beta1 true Exchange
federations rabbitmq.com/v1beta1 true Federation
operatorpolicies rabbitmq.com/v1beta1 true OperatorPolicy
permissions rabbitmq.com/v1beta1 true Permission
policies rabbitmq.com/v1beta1 true Policy
queues rabbitmq.com/v1beta1 true Queue
rabbitmqclusters rmq rabbitmq.com/v1beta1 true RabbitmqCluster
schemareplications rabbitmq.com/v1beta1 true SchemaReplication
shovels rabbitmq.com/v1beta1 true Shovel
superstreams rabbitmq.com/v1alpha1 true SuperStream
topicpermissions rabbitmq.com/v1beta1 true TopicPermission
users rabbitmq.com/v1beta1 true User
vhosts rabbitmq.com/v1beta1 true Vhost
RabbitMQ Clusterの作成
kubectl create ns demo
kubectl create secret docker-registry -n demo tanzu-rabbitmq-registry-creds \
--docker-server ${REGISTRY_HOST} \
--docker-username ${REGISTRY_USERNAME} \
--docker-password ${REGISTRY_PASSWORD}
cat <<EOF > rabbitmq.yaml
apiVersion: rabbitmq.com/v1beta1
kind: RabbitmqCluster
metadata:
name: demo-rabbitmq
namespace: demo
spec:
imagePullSecrets:
- name: tanzu-rabbitmq-registry-creds
service:
type: LoadBalancer
replicas: 3
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app.kubernetes.io/name
operator: In
values:
- demo-rabbitmq
topologyKey: kubernetes.io/hostname
EOF
kubectl apply -f rabbitmq.yaml
作成されたリソースを確認します。
$ kubectl get pod,sts,rabbitmq,secret,svc -n demo -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/demo-rabbitmq-server-0 1/1 Running 0 70s 10.42.1.122 192.168.11.51 <none> <none>
pod/demo-rabbitmq-server-1 1/1 Running 0 70s 10.42.2.107 192.168.11.52 <none> <none>
pod/demo-rabbitmq-server-2 1/1 Running 0 70s 10.42.0.82 192.168.11.150 <none> <none>
NAME READY AGE CONTAINERS IMAGES
statefulset.apps/demo-rabbitmq-server 3/3 70s rabbitmq registry.example.com/tanzu-rabbitmq/vmware-tanzu-rabbitmq:4.2.3
NAME ALLREPLICASREADY RECONCILESUCCESS AGE
rabbitmqcluster.rabbitmq.com/demo-rabbitmq True Unknown 71s
NAME TYPE DATA AGE
secret/demo-rabbitmq-default-user Opaque 8 70s
secret/demo-rabbitmq-erlang-cookie Opaque 1 71s
secret/regsecret kubernetes.io/dockerconfigjson 1 48d
secret/tanzu-rabbitmq-registry-creds kubernetes.io/dockerconfigjson 1 6h16m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/demo-rabbitmq LoadBalancer 10.43.200.24 192.168.11.241 15692:31148/TCP,5672:31198/TCP,15672:32614/TCP 71s app.kubernetes.io/name=demo-rabbitmq
service/demo-rabbitmq-nodes ClusterIP None <none> 4369/TCP,25672/TCP 71s app.kubernetes.io/name=demo-rabbitmq
http://192.168.11.241:15672 で管理コンソールにアクセスできます。
ユーザー名とパスワードは次のコマンドで確認できます。
$ kubectl get secret -n demo demo-rabbitmq-default-user -ojson | jq '.data | map_values(@base64d)'
{
"default_user.conf": "default_user = default_user_UgZFbsYLfl9KZEyJnvM\ndefault_pass = wtlfnLKYTWLu4u4y31_vUDOfnrTuUfaI\n",
"host": "demo-rabbitmq.demo.svc",
"password": "wtlfnLKYTWLu4u4y31_vUDOfnrTuUfaI",
"port": "5672",
"provider": "rabbitmq",
"type": "rabbitmq",
"username": "default_user_UgZFbsYLfl9KZEyJnvM"
}

Tip
Management Consoleへのアクセスをsticky sessionにしたい場合。Ingress ControllerにTraefikを使う場合は、rabbitmq.yamlを以下のように修正する
apiVersion: rabbitmq.com/v1beta1
kind: RabbitmqCluster
metadata:
name: demo-rabbitmq
namespace: demo
spec:
imagePullSecrets:
- name: tanzu-rabbitmq-registry-creds
service:
type: LoadBalancer
annotations:
#! 追加
traefik.ingress.kubernetes.io/service.sticky.cookie: "true"
traefik.ingress.kubernetes.io/service.sticky.cookie.name: X-Traefik-Session-Affinity
replicas: 3
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app.kubernetes.io/name
operator: In
values:
- demo-rabbitmq
topologyKey: kubernetes.io/hostname
そして次のようなIngressを作成する。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: demo-rabbitmq-management
namespace: demo
annotations:
cert-manager.io/cluster-issuer: letsencrypt
spec:
rules:
- host: demo-rabbitmq-management.lan.ik.am
http:
paths:
- backend:
service:
name: demo-rabbitmq
port:
name: management
path: /
pathType: Prefix
tls:
- hosts:
- demo-rabbitmq-management.lan.ik.am
secretName: demo-rabbitmq-management-tls
受信アプリのデプロイ
cat <<EOF > demo-rabbitmq-receiver.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-rabbitmq-receiver
labels:
app: demo-rabbitmq-receiver
app.kubernetes.io/part-of: demo-rabbitmq-receiver
spec:
replicas: 2
selector:
matchLabels:
app: demo-rabbitmq-receiver
template:
metadata:
annotations:
prometheus.io/path: /actuator/prometheus
prometheus.io/port: "8081"
prometheus.io/scrape: "true"
labels:
app: demo-rabbitmq-receiver
app.kubernetes.io/part-of: demo-rabbitmq-receiver
spec:
containers:
- name: workload
image: ghcr.io/making/demo-rabbitmq-receiver:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
name: user-port
protocol: TCP
resources:
limits:
cpu: "1"
memory: 1Gi
requests:
cpu: "1"
memory: 1Gi
env:
- name: JAVA_TOOL_OPTIONS
value: -Duser.country=JP -Duser.language=ja -Duser.timezone=Asia/Tokyo -Dfile.encoding=UTF-8 -Dmanagement.endpoint.health.probes.add-additional-paths=true -Dmanagement.endpoint.health.show-details=always -Dmanagement.endpoints.web.base-path=/actuator -Dmanagement.endpoints.web.exposure.include="*" -Dmanagement.health.probes.enabled=true -Dmanagement.server.port=8081 -Dserver.port=8080
- name: SERVICE_BINDING_ROOT
value: /bindings
volumeMounts:
- name: rabbitmq
mountPath: /bindings/rabbitmq
readOnly: true
livenessProbe:
failureThreshold: 5
httpGet:
path: /livez
port: 8080
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
readinessProbe:
httpGet:
path: /readyz
port: 8080
scheme: HTTP
startupProbe:
httpGet:
path: /readyz
port: 8080
scheme: HTTP
failureThreshold: 20
periodSeconds: 5
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
runAsNonRoot: true
runAsUser: 1002
seccompProfile:
type: RuntimeDefault
volumes:
- name: rabbitmq
secret:
secretName: demo-rabbitmq-default-user
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- podAffinityTerm:
labelSelector:
matchLabels:
app: demo-rabbitmq-receiver
topologyKey: kubernetes.io/hostname
weight: 1
EOF
kubectl apply -f demo-rabbitmq-receiver.yaml -n demo
送信アプリのデプロイ
cat <<EOF > demo-rabbitmq-sender.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-rabbitmq-sender
labels:
app: demo-rabbitmq-sender
app.kubernetes.io/part-of: demo-rabbitmq-sender
spec:
replicas: 1
selector:
matchLabels:
app: demo-rabbitmq-sender
template:
metadata:
annotations:
prometheus.io/path: /actuator/prometheus
prometheus.io/port: "8081"
prometheus.io/scrape: "true"
labels:
app: demo-rabbitmq-sender
app.kubernetes.io/part-of: demo-rabbitmq-sender
spec:
containers:
- name: workload
image: ghcr.io/making/demo-rabbitmq-sender:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
name: user-port
protocol: TCP
resources:
limits:
cpu: "1"
memory: 1Gi
requests:
cpu: "1"
memory: 1Gi
env:
- name: JAVA_TOOL_OPTIONS
value: -Duser.country=JP -Duser.language=ja -Duser.timezone=Asia/Tokyo -Dfile.encoding=UTF-8 -Dmanagement.endpoint.health.probes.add-additional-paths=true -Dmanagement.endpoint.health.show-details=always -Dmanagement.endpoints.web.base-path=/actuator -Dmanagement.endpoints.web.exposure.include="*" -Dmanagement.health.probes.enabled=true -Dmanagement.server.port=8081 -Dserver.port=8080
- name: SERVICE_BINDING_ROOT
value: /bindings
volumeMounts:
- name: rabbitmq
mountPath: /bindings/rabbitmq
readOnly: true
livenessProbe:
failureThreshold: 5
httpGet:
path: /livez
port: 8080
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
readinessProbe:
httpGet:
path: /readyz
port: 8080
scheme: HTTP
startupProbe:
httpGet:
path: /readyz
port: 8080
scheme: HTTP
failureThreshold: 20
periodSeconds: 5
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
runAsNonRoot: true
runAsUser: 1002
seccompProfile:
type: RuntimeDefault
volumes:
- name: rabbitmq
secret:
secretName: demo-rabbitmq-default-user
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- podAffinityTerm:
labelSelector:
matchLabels:
app: demo-rabbitmq-sender
topologyKey: kubernetes.io/hostname
weight: 1
EOF
kubectl apply -f demo-rabbitmq-sender.yaml -n demo

