kubernetes - 部署rabbitmq集群
2019-08-30 / 5 min read
author: caijunhui
date: 2019-08-29
本文介绍如何在k8s环境下部署rabbitmq
镜像使用rabbitmq:3.7-management-alpine,从3.7.0开始rabbitmq使用了peer discovery, 不使用autoscale。
-
创建rabbitmq的namespce
apiVersion: v1 kind: Namespace metadata: name: rabbitmq
-
rdbc
--- apiVersion: v1 kind: ServiceAccount metadata: name: rabbitmq namespace: rabbitmq --- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: Role metadata: name: endpoint-reader namespace: rabbitmq rules: - apiGroups: [""] resources: ["endpoints"] verbs: ["get"] --- kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: name: endpoint-reader namespace: rabbitmq subjects: - kind: ServiceAccount name: rabbitmq roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: endpoint-reader
-
rabbitmq数据持久化
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: rabbitmq-pvc namespace: rabbitmq spec: accessModes: - ReadWriteMany resources: requests: storage: 5Gi storageClassName: managed-nfs-storage
-
Deploy
# NodePort Servce,以便通过集群节点访问rabbitmq kind: Service apiVersion: v1 metadata: namespace: rabbitmq name: rabbitmq-svc labels: app: rabbitmq type: LoadBalancer spec: type: NodePort ports: - name: rabbitmq-mgmt-port protocol: TCP port: 15672 targetPort: 15672 nodePort: 31672 - name: rabbitmq-amqp-port protocol: TCP port: 5672 targetPort: 5672 nodePort: 30672 selector: app: rabbitmq --- apiVersion: v1 kind: Service metadata: name: rabbitmq namespace: rabbitmq labels: app: rabbitmq spec: clusterIP: None #用Headless Service去做Pod的hostname访问,需要等Pod和Service都启动后才能访问,而readiness探针还没等DNS正常就去探查服务是否可用,所以才会误认为服务不可达,最终无法启动Pod。解决办法是给Headless Service设置publishNotReadyAddresses: true publishNotReadyAddresses: true ports: - port: 5672 protocol: TCP name: amqp - port: 4369 name: epmd - port: 15672 protocol: TCP name: http selector: app: rabbitmq --- apiVersion: v1 kind: ConfigMap metadata: name: rabbitmq-cm namespace: rabbitmq data: enabled_plugins: | [rabbitmq_management,rabbitmq_peer_discovery_k8s]. rabbitmq.conf: | ## Cluster formation. See https://www.rabbitmq.com/cluster-formation.html to learn more. cluster_formation.peer_discovery_backend = rabbit_peer_discovery_k8s cluster_formation.k8s.host = kubernetes.default.svc.cluster.local # 必须设置service_name,否则Pod无法正常启动,这里设置后可以不设置statefulset下env中的K8S_SERVICE_NAME变量 cluster_formation.k8s.service_name = rabbitmq # 必须设置hostname_suffix,否则节点不能成为集群 cluster_formation.k8s.hostname_suffix = .rabbitmq.rabbitmq.svc.cluster.local ## Should RabbitMQ node name be computed from the pod's hostname or IP address? ## IP addresses are not stable, so using [stable] hostnames is recommended when possible. ## Set to "hostname" to use pod hostnames. ## When this value is changed, so should the variable used to set the RABBITMQ_NODENAME ## environment variable. ## hostname or ip cluster_formation.k8s.address_type = hostname ## How often should node cleanup checks run? cluster_formation.node_cleanup.interval = 30 cluster_formation.randomized_startup_delay_range.min = 0 cluster_formation.randomized_startup_delay_range.max = 2 ## Set to false if automatic removal of unknown/absent nodes ## is desired. This can be dangerous, see ## * https://www.rabbitmq.com/cluster-formation.html#node-health-checks-and-cleanup ## * https://groups.google.com/forum/#!msg/rabbitmq-users/wuOfzEywHXo/k8z_HWIkBgAJ cluster_formation.node_cleanup.only_log_warning = true cluster_partition_handling = autoheal ## See https://www.rabbitmq.com/ha.html#master-migration-data-locality queue_master_locator=min-masters ## See https://www.rabbitmq.com/access-control.html#loopback-users loopback_users.guest = false --- apiVersion: apps/v1beta1 kind: StatefulSet metadata: name: rabbitmq namespace: rabbitmq spec: serviceName: rabbitmq selector: matchLabels: app: rabbitmq replicas: 3 template: metadata: labels: app: rabbitmq annotations: scheduler.alpha.kubernetes.io/affinity: > { "podAntiAffinity": { "requiredDuringSchedulingIgnoredDuringExecution": [{ "labelSelector": { "matchExpressions": [{ "key": "app", "operator": "In", "values": ["rabbitmq"] }] }, "topologyKey": "kubernetes.io/hostname" }] } } spec: serviceAccountName: rabbitmq terminationGracePeriodSeconds: 10 containers: - name: rabbitmq-k8s image: rabbitmq:3.7-management-alpine imagePullPolicy: IfNotPresent volumeMounts: - name: config-volume mountPath: /etc/rabbitmq - name: rabbitmq-data mountPath: /var/lib/rabbitmq/data ports: - name: http protocol: TCP containerPort: 15672 - name: amqp protocol: TCP containerPort: 5672 - containerPort: 4369 - containerPort: 25672 livenessProbe: exec: command: ["rabbitmqctl", "status"] initialDelaySeconds: 60 # See https://www.rabbitmq.com/monitoring.html for monitoring frequency recommendations. periodSeconds: 60 timeoutSeconds: 15 readinessProbe: exec: command: ["rabbitmqctl", "status"] initialDelaySeconds: 20 periodSeconds: 60 timeoutSeconds: 10 env: - name: MY_POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: MY_POD_IP valueFrom: fieldRef: fieldPath: status.podIP - name: RABBITMQ_USE_LONGNAME value: "true" # - name: K8S_SERVICE_NAME # value: "rabbitmq" # See a note on cluster_formation.k8s.address_type in the config file section - name: RABBITMQ_NODENAME value: "rabbit@$(MY_POD_NAME).rabbitmq.rabbitmq.svc.cluster.local" - name: RABBITMQ_ERLANG_COOKIE value: "Zk93VStwK0g3ZE5KNkxlT0lRQ0V2S3BTNXBockk0UU9QeVNrSXdRSGM0RT0K" # valueFrom: # secretKeyRef: # name: erlang.cookie # key: erlang.cookie volumes: - name: config-volume configMap: name: rabbitmq-cm items: - key: rabbitmq.conf path: rabbitmq.conf - key: enabled_plugins path: enabled_plugins - name: rabbitmq-data persistentVolumeClaim: claimName: rabbitmq-pvc