Bộ chứa CI / CD đơn giản trong AWS


14

Tôi đang sử dụng AWS Code Pipeline, Code Build để tạo một Docker mới và đẩy nó lên ECR.

Ứng dụng của tôi là một container đơn giản chuyển tiếp đơn giản dựa trên. Điều gì sẽ là cách tiếp cận ít ma sát hơn để kéo xuống Container đang chạy hiện tại và khởi chạy lại Container mới từ sổ đăng ký ECS (đầu ra của Đường ống xây dựng mã thông qua Code Build).

Tôi đã thử CloudFormation với dữ liệu người dùng EC2, các tập lệnh tùy chỉnh ở một bên và CloudFormation với ECS với định nghĩa tác vụ ở phía bên kia (chưa thành công). Tôi cảm thấy mạnh mẽ phải có cách tiếp cận rõ ràng và đơn giản hơn.

Câu trả lời:


16

Tôi sẽ giữ các phiên bản chứa ECS (Tôi đang nói về các máy chủ Docker - Tôi không thích thuật ngữ AWS ở đây) và việc triển khai như hai điều riêng biệt.

Nhận ECS của bạn chồng lên và chạy. Bạn có thể quản lý nó thông qua các nhóm CloudFormation và Auto-scale, điều đó tốt. Chỉ cần nghĩ về cluster của bạn như một nền tảng nơi bạn sẽ triển khai đến , không phải cái gì bạn cần phải redeploy .

Sau đó, đối với CD, phương pháp đơn giản nhất cho đến nay là cập nhật định nghĩa dịch vụ để sử dụng định nghĩa tác vụ mới và để ECS roll cập nhật các container cho bạn.

Mỗi khi nó bắt đầu một tác vụ, ECS sẽ chạy docker pull image: tag ngay cả khi nó có hình ảnh cục bộ để đảm bảo nó có phiên bản mới nhất của hình ảnh đó: tag. Vì vậy, thẻ hình ảnh bạn sử dụng thực sự không quan trọng (không cần thay đổi thẻ trên mỗi bản dựng).

Điều đó có nghĩa là bạn có thể xây dựng myimage: mới nhất nhiều lần để triển khai nó dễ dàng.

Những gì bạn cần là một định nghĩa nhiệm vụ trong đó hình ảnh = myimage: mới nhất. Tạo một dịch vụ với định nghĩa nhiệm vụ đó và mỗi khi ECS bắt đầu một nhiệm vụ (một phiên bản dịch vụ của bạn), đó sẽ là "myimage: mới nhất" mà bạn đã xây dựng.

Từ đó, bạn chỉ thiếu một mảnh trong câu đố, từ CodeDeploy, bạn có thể gọi một cái gì đó, có lẽ là hàm lambda, để tạo một bản sửa đổi mới của định nghĩa nhiệm vụ và cập nhật dịch vụ của bạn và ECS sẽ tự động tạo các tác vụ mới cho bản sửa đổi đó và loại bỏ các nhiệm vụ cũ.

Một ví dụ:

Giả sử bạn đã tạo một dịch vụ có tên MyService. Rằng bạn đã cấu hình dịch vụ đó để chạy 2 tác vụ cho định nghĩa tác vụ MyTaskDefDef: 1 (phiên bản 1). Trong định nghĩa tác vụ đó, bạn có một định nghĩa vùng chứa mà hình ảnh được đặt thành "myimage: mới nhất".

  1. Hôm qua bạn đã xây dựng myimage: mới nhất có ID (SHA) 365d8f7bf565.
  2. Ví dụ container ABC của bạn đang chạy một tác vụ có tên MyTaskDefDef- 1 -containerName -someLongId. Khi bạn kiểm tra container đó, nó sẽ chạy hình ảnh "sha256: 365d8f7bf565 .........."
  3. Ví dụ container khác DEF của bạn đang chạy một tác vụ khác. Nó có một tên tương tự (chỉ ID khác nhau), nhưng nó chạy cùng một hình ảnh.
  4. Bạn đẩy một sự thay đổi để repo của bạn.
  5. CodePipeline chọn ra sự thay đổi đó, xây dựng và xuất bản hình ảnh lên ECR.
  6. Hình ảnh Docker mới đó cũng là hình ảnh của tôi: mới nhất, nhưng ID của nó (SHA) là f7ec5e54ac96
  7. Bây giờ bạn cần thêm một bước vào đường ống của mình để sử dụng các hàm Lambda và SDK AWS NodeJS để thực hiện một số cuộc gọi đến cụm của bạn:
    1. Tạo một định nghĩa nhiệm vụ mới (sẽ hoàn toàn giống như trước đây). Đó sẽ là MyTaskDefDef: 2
    2. Cập nhật MyService của bạn để sử dụng MyTaskDefDef: 2 (thay vì 1)
  8. ECS sẽ tạo ra các nhiệm vụ mới. Tên container sẽ MyTaskDefDef- 2 -containerName -someLongId. Khi bạn kiểm tra các thùng chứa đó, bạn sẽ thấy rằng chúng sẽ chạy "sha256: f7ec5e54ac96 .......". Có lẽ bạn sẽ có 2 tác vụ trên ví dụ ABC, có lẽ chúng sẽ bị xóa (điều này phụ thuộc vào cấu hình dịch vụ của bạn)
  9. Sau một thời gian, ECS sẽ xóa tác vụ cũ MyTaskDefDef-1-containerName-someLongId khỏi ABC và DEF.

Lưu ý: bạn thực sự không cần phải tạo một định nghĩa nhiệm vụ mới. Thay vào đó, nếu bạn muốn, bạn có thể truy xuất danh sách nhiệm vụ của dịch vụ và tự dừng từng bước một. Bạn nên đợi ECS khởi động lại một tác vụ trước khi dừng một nhiệm vụ mới (nghĩa là: dừng container đầu tiên, đợi ECS thay thế nó, dừng container thứ hai). Khi ECS khởi động lại container, nó sẽ lấy myimage gần đây nhất: được xây dựng mới nhất, như đã giải thích trước đó. Tôi chỉ nghĩ rằng việc tạo một định nghĩa nhiệm vụ mới dễ dàng hơn và ít xảy ra lỗi hơn (không cần logic để chờ đợi và kiểm tra, ECS sẽ xử lý cập nhật cuộn cho bạn nếu bạn có định nghĩa nhiệm vụ mới).


Tuyệt vời - Tôi sẽ gọi câu trả lời của bạn là hướng dẫn còn thiếu cho CI / CD cho docker. Cảm ơn bạn.
Naveen Vijay

3

Đối với trường hợp sử dụng đơn giản được mô tả, tôi khuyên bạn nên kiểm tra Elastic Beanstalk cho Docker, đó không phải là giải pháp tối thiểu như sử dụng ECS ​​trần, nhưng bạn có thể hưởng lợi từ các dịch vụ được quản lý và cấu hình tự động như ELB, EC2 AutoScale, theo dõi sức khỏe và hơn thế nữa.

Tóm tắt cấp cao:

  1. Cấu hình đàn hồi Beanstalk để sử dụng thẻ myimage cụ thể: đã thử nghiệm
  2. Sử dụng Code Pipeline / Build để xây dựng, kiểm tra và quảng bá thẻ "đã kiểm tra"
  3. Việc kích hoạt triển khai Beanstalk đàn hồi, sẽ kéo theo hình ảnh quảng cáo: đã thử nghiệm cho tất cả các trường hợp, các chiến lược triển khai khác nhau có sẵn.

Cách tiếp cận này dựa trên việc sử dụng lại cùng một thẻ, cách tiếp cận thay thế sẽ tạo ra thẻ với id xây dựng, ví dụ myimage: tests-42, điều này sẽ yêu cầu cập nhật Elastic Beanstalk mỗi lần với thẻ mới, nhưng sẽ kiểm soát chi tiết hơn về sửa đổi được triển khai.


0

Tôi đậu thứ hai đàn hồi vì sự đơn giản của nó; nó rất dễ dàng để thiết lập và triển khai.

Nếu bạn đã quen thuộc với docker-compose, một cách tiếp cận khác sẽ là xác định docker-compose.yml và trực tiếp triển khai trên ECS với ecs-cli.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.