Penggunaan Kubernet yang berbenturan, CPU & Docker Container Metrics

9

Kami baru-baru ini mengalihkan lingkungan produksi kami ke Kubernetes. Saya ingin menegakkan batas CPU pada wadah. Saya mendapatkan metrik CPU yang saling bertentangan yang tidak cocok bersama. Inilah pengaturan saya:

  • Agen DataDog berjalan sebagai Daemonset
  • Aplikasi yang ada berjalan tanpa Batas CPU
  • Kontainer yang dimaksud adalah aplikasi Ruby multi-threaded
  • Dua metrik: kubernetes.cpu.usage.{avg,max}dandocker.cpu.usage
  • c4.xlarge node cluster (4 vCPUs atau 4000m dalam istilah Kubernetes)

kubernetes.cpu.usage.maxmelaporkan ~ 600m untuk kontainer yang dimaksud. docker.cpu.usagelaporan ~ 60%. Maka batas CPU 1000m akan lebih dari cukup kapasitas dalam operasi normal.

Saya menetapkan batas ke 1000m. Kemudian docker.container.throttlesnaik secara signifikan sementara kubernetes.cpu.usage.maxdan docker.cpu.usagetetap sama. Sistem semua jatuh ke lututnya selama ini. Ini tidak masuk akal bagi saya.

Saya meneliti statistik Docker. Tampaknya docker stats(dan API yang mendasarinya) menormalkan beban menurut inti CPU. Jadi dalam kasus saya, docker.cpu.usage60% (4000m * 0,60) hingga 2400m dalam istilah Kubernetes. Namun ini tidak berkorelasi dengan angka Kubernetes apa pun. Saya melakukan percobaan lain untuk menguji hipotesis saya bahwa angka Kubernetes salah. Saya menetapkan batas ke 2600m (untuk beberapa ruang kepala tambahan). Ini tidak menghasilkan throttle. Namun Kubernetes mengamati penggunaan CPU tidak berubah. Ini membuat saya bingung.

Jadi pertanyaan saya adalah:

  • Apakah ini terasa seperti bug di Kubernetes (atau sesuatu di stack?)
  • Apakah pemahaman saya benar?

Pertanyaan tindak lanjut saya berkaitan dengan cara menentukan dengan benar CPU untuk aplikasi Ruby. Satu wadah menggunakan Puma. Ini adalah server web multi-utas dengan jumlah utas yang dapat dikonfigurasi. Permintaan HTTP ditangani oleh salah satu utas. Aplikasi kedua adalah server hemat menggunakan server berulir. Setiap koneksi TCP yang masuk ditangani oleh utasnya sendiri. Utas keluar saat koneksi ditutup. Ruby sebagai GIL (Global Interpreter Lock) sehingga hanya satu utas yang dapat mengeksekusi kode Ruby sekaligus. Itu memungkinkan beberapa thread menjalankan IO dan hal-hal seperti itu.

Saya pikir pendekatan terbaik adalah membatasi jumlah utas yang berjalan di setiap aplikasi dan mendekati batas CPU Kubernet berdasarkan jumlah utas. Prosesnya tidak forking sehingga total penggunaan CPU lebih sulit diprediksi.

Pertanyaannya di sini adalah: bagaimana cara memprediksi penggunaan dan batasan CPU dengan benar untuk aplikasi ini?

ahawkins
sumber
Apakah Anda mencoba pada simpul 1cpu dan simpul 2 cpu untuk melihat bagaimana angka tersebut berkorelasi (atau tidak)?
Tensibai

Jawaban:

4

Banyak hal di sini:

  1. Anda berada di AWS ec2, maka apa pun yang Anda lakukan pada instance Anda untuk mengukur CPU menghitung CPU pada level hypervisor dan bukan level instance. Untuk ini, jalankan uji beban apa pun dan periksa iostat -ct 1 dan penggunaan CPU di cloudwatch. Penggunaan CPU di cloudwatch selalu 10-20% lebih besar dari apa yang akan dilaporkan iostat dan itu karena iostat akan memberikan penggunaan CPU pada tingkat hypervisor.

  2. Sebagai buruh pelabuhan untuk melihat bagaimana kubernet dan metrik buruh pelabuhan membandingkan, saya sarankan untuk menjalankan kontainer dengan --cpuset = 1 atau angka apa pun untuk memungkinkan semua kontainer menggunakan hanya satu vCPU.

  3. Juga di AWS 1 CPU = 2vcpu. Ini adalah hyperthreaded ke 2. Anda mungkin dapat mempertimbangkan ini saat menghitung.

  4. Akhirnya metrik terbaik untuk digunakan untuk melihat penggunaan CPU untuk aplikasi tertentu adalah menggunakan htop dan berkorelasi dengan metrik cloudwatch Anda.

  5. Saya juga mengamati kadang-kadang docker daemon menyematkan dirinya ke salah satu CPU virtual dan karenanya ketika Anda menguranginya menjadi 1000m, mungkin seluruh pengaturan menjadi lambat karena pengurangan terjadi pada salah satu vpcus. Anda dapat menggunakan mpstat untuk masuk ke detail ini.

  6. Terakhir pada level host Anda dapat menyematkan docker ke satu CPU dan mengamati lebih banyak.

Semoga ini membuat Anda sedikit lebih dekat. Perbarui saya jika Anda sudah menemukan solusi.

lakshayk
sumber