Everywhere to OpenStack: Clustering compute node by host aggregate

Đây lại là một phần nữa mà mình thấy cực kỳ cần thiết khi thiết kế một cụm OpenStack Cloud với khả năng mở rộng dễ dàng trong tương lai (Not only production-ready but also scalability-ready)

By the way, nếu cụm Cloud của bạn có các compute đồng nhất về mặt CPU model, về kết nối tới các hệ thống storage cũng như mặt kết nối tới các hệ thống bên ngoài và sẽ mãi như vậy thì bài này có lẽ không thực sự cần thiết!

Ví dụ các port trên switch đều tag VLAN giống nhau cho tất cả compute

Ví dụ các compute đều kết nối tới tất cả SAN Storage thông qua các SAN Switch

Ví dụ CPU model của các compute đều tương tự nhau hoặc bạn không quan tâm tới việc ứng dụng cần chạy trên dòng CPU nào với CINT bao nhiêu

Lại là một mẩu chuyện nữa, à đâu, một chuỗi chuyện mẩu chuyện giống nhau trong suốt quá trình chuyển dịch lên OpenStack Cloud. Chả là như này, những ngày đầu, cụm Cloud bên mình có độ vài ba chục compute node giống nhau, có một cặp SAN Switch, một cụm Ceph, một con SAN Storage của HP. Mình cứ triển khai bình thường, không host aggregate cũng chẳng unify CPU model gì cả (trong lúc này mình đang phát triển công cụ cắt chuyển từ các hạ tầng lên Cloud cộng với áp lực số lượng cắt chuyển làm mình chẳng kịp nghĩ nhiều).

Mọi chuyện nó cứ như mối tình đầu vậy, thật đẹp đẽ và trôi chảy cho tới một ngày những kẻ khác xuất hiện. Thật vậy, một thời gian ngắn sau, bên mình nhận được một loạt compute node mới, SAN Storage và cả đống compute node của hạ tầng ảo hóa cũ. Vấn đề ở đây là gì?

  • Các compute node mới (cũ người mới ta, có cả mới thật với cả đống mới "free" từ đâu đó đem đến) có CPU model khác với đống hiện tại
  • Một số ứng dụng đòi hỏi các dòng CPU đời mới hay các flag đặc biệt trong CPU
  • Không phải tất cả compute node đều kết nối được tới tất cả SAN Storage (Mặc dù đã sử dụng isl trunking để mở rộng nhưng nhiều cặp SW nó lại nằm ở các rack khác nhau và đi kèm với tủ đĩa tương ứng)
  • ...

Ý tưởng thì rất đơn giản, chúng ta phải gom nhóm các compute node với các Storage tương ứng để các máy ảo nhảy nhót trong "cluster" đó đảm bảo các yếu tố sau:

  • Đều có CPU model giống nhau, phục vụ cho live migration (CPU resource perspective)
  • Đều có kết nối tới storage chung (storage perspective)
  • Đều cho phép máy ảo sử dụng IP trên một tập các dải mạng chung (network perspective)

Cuối cùng, mình đã giải quyết từng vấn đề như sau

  • Nhất quán CPU model cho các cluster có CPU giống hoặc gần giống nhau

Tại sao mình nói là gần giống nhau? Trong thực tế, cùng một dòng CPU nhưng các flag hoàn toàn có thể khác nhau hay việc nâng cấp BIOS hay Firmware đều có thể sinh ra thêm các flag trong CPU, vì vậy, chúng ta cần thống nhất chúng!

    • Các đường gạch ngang biểu thị một CPU model được định nghĩa trong /usr/share/libvirt/cpu_map.xml 
    • + cpu_model_extra_flags là các flag chung của các compute node có thể gom nhóm được

    • Cấu hình trong nova.conf của compute node:
[libvirt]
cpu_mode = custom
cpu_model = IvyBridge
cpu_model_extra_flags = pcid
  • Gom nhóm các compute thành các host aggregate và sử dụng flavor properties để đảm bảo quá trình live migrate không bị schedule nhầm hosts
    • Khởi tạo host aggregate với metadata tự định nghĩa

    • Mỗi khi tạo flavor cho máy ảo, thêm thuộc tính cho flavor

openstack flavor set FLAVOR_NAME

    --property aggregate_instance_extra_specs:cpu_model=Custom_IvyBridge

Vậy nên, ngay từ khi triển khai, chúng ta nên có thiết kế, naming,... để đảm bảo hạ tầng từ đầu, sẵn sàng cho việc mở rộng hay tích hợp tùm lum thêm sau này!

Appendix: Với mấy chục compute cũ mình đã làm gì?

  • Thêm flavor properties cho flavor của các máy ảo và live migrate sang cluster có CPU model cao hơn (Vì máy ảo lúc này có CPU model mặc định theo KVM vì vậy chỉ có thể live migrate sang compute node có CPU model cao hơn hoặc bằng)
  • Tạo host aggregate mới cho nhóm compute cũ
Posted on