Kontainer CI / CD sederhana dalam AWS

14

Saya menggunakan AWS Code Pipeline, Code Build untuk membuat wadah Docker baru dan mendorongnya ke ECR.

Aplikasi saya adalah wadah tunggal lurus ke depan sederhana. Apa yang akan menjadi pendekatan gesekan kurang untuk menarik Kontainer berjalan saat ini dan meluncurkan kembali Kontainer baru dari registri ECS (output dari Code Build melalui Code Pipeline).

Saya mencoba CloudFormation dengan data pengguna EC2, skrip khusus di satu sisi dan CloudFormation dengan ECS dengan definisi tugas di sisi lain (belum berhasil). Saya sangat merasa harus ada pendekatan yang lebih jelas dan sederhana.

Naveen Vijay
sumber

Jawaban:

16

Saya akan menyimpan instance kontainer ECS (saya berbicara tentang host Docker - Saya tidak suka terminologi AWS di sini) dan penyebarannya sebagai dua hal yang terpisah.

Susun dan jalankan ECS Anda. Anda dapat mengelolanya melalui grup CloudFormation dan Auto-scaling, itu bagus. Hanya berpikir cluster Anda sebagai platform di mana Anda akan menyebarkan ke , bukan sesuatu yang perlu redeploy .

Kemudian, untuk CD, metode termudah sejauh ini adalah memperbarui definisi layanan untuk menggunakan definisi tugas baru dan membiarkan ECS bergulir memperbarui wadah untuk Anda.

Setiap kali memulai tugas, ECS akan menjalankan docker pull image: tag meskipun memiliki gambar secara lokal untuk memastikan ia memiliki versi terbaru dari gambar itu: tag. Jadi tag gambar yang Anda gunakan benar-benar tidak masalah (tidak perlu mengubah tag pada setiap build).

Itu berarti bahwa Anda dapat membangun myimage: terbaru berulang kali untuk menyebarkannya dengan mudah.

Yang Anda butuhkan adalah definisi tugas di mana gambar = myimage: terbaru. Buat layanan dengan definisi tugas itu dan setiap kali ECS memulai tugas (contoh dari layanan Anda), itu akan menjadi "myimage: latest" terbaru yang Anda buat.

Dari sana, Anda hanya kehilangan satu bagian dalam teka-teki, dari CodeDeploy, Anda dapat memanggil sesuatu, mungkin fungsi lambda, untuk membuat revisi baru dari definisi tugas Anda dan memperbarui layanan Anda dan ECS secara otomatis akan membuat tugas-tugas baru untuk revisi itu dan hapus tugas-tugas lama.

Sebuah contoh:

Anggap Anda telah membuat layanan yang disebut MyService. Bahwa Anda telah mengkonfigurasi layanan itu untuk menjalankan 2 tugas untuk definisi tugas MyTaskDefinition: 1 (revisi 1). Dalam definisi tugas itu, Anda memiliki satu definisi wadah yang gambarnya diatur ke "myimage: latest".

  1. Kemarin Anda telah membangun myimage: terbaru yang memiliki ID (SHA) 365d8f7bf565.
  2. Contoh wadah Anda ABC menjalankan tugas bernama MyTaskDefinition- 1 -containerName-someLongId. ketika Anda memeriksa wadah itu, itu menjalankan gambar "sha256: 365d8f7bf565 .........."
  3. DEF wadah Anda yang lain sedang menjalankan tugas lain. Ini memiliki nama yang mirip (hanya ID yang berbeda), tetapi menjalankan gambar yang sama.
  4. Anda mendorong perubahan ke repo Anda.
  5. CodePipeline mengambil perubahan itu, membangun dan menerbitkan gambar ke ECR.
  6. Gambar Docker baru itu juga myimage: terbaru, tetapi ID-nya (SHA) adalah f7ec5e54ac96
  7. Sekarang Anda perlu menambahkan langkah ke pipeline Anda untuk menggunakan fungsi Lambda dan AWS NodeJS SDK untuk melakukan beberapa panggilan ke cluster Anda:
    1. Buat definisi tugas baru (yang akan persis sama seperti sebelumnya). Itu akan menjadi MyTaskDefinition: 2
    2. Perbarui MyService Anda untuk menggunakan MyTaskDefinition: 2 (bukan 1)
  8. ECS akan membuat tugas baru. Nama-nama wadah akan MyTaskDefinition- 2 -containerName-someLongId. Ketika Anda memeriksa wadah itu, Anda akan melihat bahwa mereka akan menjalankan "sha256: f7ec5e54ac96 .......". Mungkin Anda akan memiliki 2 tugas pada contoh wadah ABC, mungkin mereka akan disemprotkan (itu tergantung pada konfigurasi layanan Anda)
  9. Setelah beberapa waktu, ECS akan menghapus tugas lama MyTaskDefinition-1-containerName-someLongId dari ABC dan DEF.

Catatan: Anda sebenarnya tidak perlu membuat definisi tugas baru. Jika mau, Anda bisa mengambil daftar tugas layanan dan menghentikannya secara manual satu per satu. Anda harus menunggu ECS memulai kembali tugas sebelum menghentikan yang baru (yaitu: hentikan wadah pertama, tunggu ECS untuk menggantinya, hentikan wadah kedua). Ketika ECS me-restart wadah, itu akan mengambil myimage terbaru: terbaru dibangun, seperti dijelaskan sebelumnya. Saya hanya berpikir membuat definisi tugas baru lebih mudah dan lebih sedikit kesalahan rawan (tidak perlu logika untuk menunggu dan memeriksa, ECS akan menangani pembaruan bergulir untuk Anda jika Anda memiliki definisi tugas baru).

Alexandre
sumber
Luar biasa - Saya akan menyebut jawaban Anda sebagai manual yang hilang untuk CI / CD untuk buruh pelabuhan. Terima kasih.
Naveen Vijay
3

Untuk kasus penggunaan sederhana yang dijelaskan, saya akan menyarankan untuk memeriksa Elastic Beanstalk untuk Docker, ini bukan solusi minimal seperti penggunaan ECS telanjang, tetapi Anda dapat memanfaatkan layanan yang dikelola dan dikonfigurasikan secara otomatis seperti ELB, EC2 AutoScale, pemantauan kesehatan, dan banyak lagi.

Ringkasan tingkat tinggi:

  1. Konfigurasikan Pohon Kacang Elastis untuk menggunakan tag myimage tertentu: diuji
  2. Gunakan Kode Pipa / Bangun untuk membangun, menguji, dan mempromosikan tag "teruji"
  3. Trigger Elastic Beanstalk deployment, yang akan menarik myimage gambar yang dipromosikan: diuji untuk semua contoh, berbagai strategi penyebaran yang tersedia.

Pendekatan ini didasarkan pada penggunaan kembali tag yang sama, pendekatan alternatif akan menghasilkan tag dengan build id, misalnya myimage: diuji-42, ini akan memerlukan pembaruan Elastic Beanstalk setiap kali dengan tag baru, tetapi memberikan lebih banyak kontrol granular pada revisi yang digunakan.

Rombob
sumber
0

Saya kedua kacang elastis untuk kesederhanaannya; sangat mudah untuk mengatur dan menggunakan.

Jika Anda terbiasa dengan docker-compose, pendekatan lain adalah mendefinisikan docker-compose.yml dan langsung menggunakan ECS dengan ecs-cli.

AnthonyC
sumber