Runner CI được khởi tạo và hủy chỉ trong vài phút, container không có ổ đĩa cố định và thường cũng không có IP cố định, trong khi proxy bên ngoài phải được kết nối lại ở mỗi lần chạy — làm thủ công qua ứng dụng desktop sẽ không khả thi. Bài viết này giải thích cách truyền proxy vào container và pipeline đúng cách: không để thông tin đăng nhập trong image, tính đến địa chỉ thay đổi của runner, đồng thời kiểm soát lưu lượng và sự cô lập giữa các job chạy song song.

Truyền tham số qua biến môi trường

Cách chuẩn để truyền proxy vào container và vào một bước của pipeline là dùng các biến HTTP_PROXY, HTTPS_PROXY và NO_PROXY (cùng các biến tương ứng viết thường, mà một số thư viện đọc thay cho biến viết hoa). Giá trị là chuỗi kết nối gồm tên đăng nhập và mật khẩu: giao thức, thông tin xác thực, máy chủ, cổng. Hầu hết ứng dụng khách HTTP, trình quản lý gói và công cụ dòng lệnh đều tự động nhận các biến này mà không cần sửa mã ứng dụng.

NO_PROXY liệt kê riêng những địa chỉ và tên miền được gọi trực tiếp: các dịch vụ nội bộ trong mạng container, kho lưu trữ image cục bộ, các địa chỉ dùng chung giữa các bước của cùng một pipeline. Nếu không cấu hình NO_PROXY đúng, lưu lượng nội bộ cũng đi qua proxy bên ngoài, làm tăng chi phí và độ trễ mà chẳng có lợi ích gì. Nên đặt biến ở cấp từng bước chứ không phải toàn bộ pipeline khi các tác vụ khác nhau cần địa chỉ khác nhau — bước build chạy trực tiếp, còn bước kiểm tra bên ngoài đi qua kênh có vị trí địa lý phù hợp.

Vì sao không nên nhúng thông tin đăng nhập vào image

Container được xây dựng theo từng lớp, và mỗi lớp đều được đưa lên kho lưu trữ image rồi nằm lại đó, kể cả khi bí mật đã bị xóa ở lớp tiếp theo — nếu một lệnh thêm tên đăng nhập và mật khẩu vào biến môi trường ở giai đoạn build, thông tin đó vẫn đọc được qua lịch sử các lớp, dù lệnh ngay sau đó có xóa chúng đi. Các công cụ quét bí mật trong image tìm ra những thông tin này chỉ trong vài giây, cả ở kho công khai lẫn kho riêng tư — kho riêng tư không đồng nghĩa với an toàn.

Cách làm đúng là đưa bí mật vào lúc chạy chứ không phải lúc build: dùng biến môi trường, kho lưu trữ được mã hóa của pipeline hoặc volume được gắn khi khởi động và không nằm trong bất kỳ lớp nào của image. Bản thân image giữ nguyên cho mọi môi trường, chỉ có giá trị do hệ thống CI cung cấp khi bắt đầu job là thay đổi.

Whitelist IP không hiệu quả với runner có địa chỉ thay đổi

Cho phép truy cập theo địa chỉ IP của runner chỉ là giải pháp khả thi với hạ tầng riêng có địa chỉ cố định. Runner đám mây nhận container từ một nhóm dùng chung ở mỗi lần chạy, IP bên ngoài thay đổi từ job này sang job khác, đôi khi còn đổi ngay giữa một bước khi node được tạo lại — địa chỉ đã ghim trong whitelist sẽ hết hiệu lực ngay ở lần chạy kế tiếp, và quyền truy cập sẽ lỗi mà không có nguyên nhân rõ ràng trong chính mã nguồn.

Giải pháp ổn định duy nhất ở đây là xác thực bằng cặp tên đăng nhập và mật khẩu gắn với tài khoản chứ không gắn với địa chỉ. Đây cũng là nguyên tắc như với ứng dụng khách trên desktop: chuỗi kết nối chứa thông tin xác thực, thay vì dựa vào danh sách địa chỉ được phép cố định mà runner không thể đảm bảo. Cách xoay vòng các địa chỉ được cấp khi dùng kiểu xác thực này được trình bày trong bài về xoay IP qua API.

Lưu lượng trong CI và cách giới hạn

Pipeline gọi proxy bên ngoài ở mọi bước của mọi lần chạy sẽ tích lũy lưu lượng nhanh hơn dự tính ban đầu: một nghìn lượt kiểm tra trang có hình ảnh đã tốn 3–5 GB, còn lượt chạy hằng ngày trên một trăm địa chỉ trong hệ thống giám sát tạo ra khoảng 1,5–3 GB mỗi tháng cho một kịch bản, và đó là chưa tính các lần chạy lại khi một bước không ổn định.

Có ba cách giúp giảm mức tiêu thụ: lưu đệm (cache) các phụ thuộc và artifact của quá trình build để chỉ những lệnh gọi thực sự ra bên ngoài mới đi ra ngoài, thay vì build lại cùng một thứ ở mỗi lần chạy; tắt tải nội dung đa phương tiện khi kịch bản chỉ cần văn bản hoặc phản hồi API; và dùng địa chỉ datacenter với giá cố định theo tháng cho những tác vụ không phụ thuộc vị trí địa lý — loại này không tính phí theo lưu lượng, nên các lần chạy thử không làm tăng hóa đơn theo gigabyte. Nguyên tắc tiết kiệm được phân tích kỹ hơn trong bài proxy rẻ so với proxy đắt.

Cô lập giữa các tác vụ chạy song song

Pipeline có các job chạy song song — kịch bản điển hình của CI — không nên dẫn tất cả nhánh qua cùng một địa chỉ được cấp: nếu một bước bị trang đích chặn vì uy tín hoặc bị hiện captcha, toàn bộ các job song song dùng chung IP đó đều bị ảnh hưởng, kể cả những job không liên quan.

Giải pháp thực tế là dùng một phiên riêng hoặc một phân đoạn thông tin xác thực riêng cho mỗi nhánh song song, với định danh là số của job hoặc của bước. Với các kênh cấp địa chỉ theo từng phiên, điều này nghĩa là mỗi tác vụ tự động nhận một IP riêng, miễn là định danh phiên thực sự là duy nhất ở mỗi lần chạy chứ không bị gán cứng một giá trị cho cả pipeline.

Câu hỏi thường gặp

Có thể dùng cùng một tài khoản proxy cho nhiều pipeline cùng lúc không?

Về mặt kỹ thuật là được, nhưng trên kênh có giới hạn chung về số phiên song song, điều này gây tranh chấp phiên giữa các pipeline không liên quan: pipeline này chiếm phiên của pipeline kia vào lúc tải cao điểm. Với nhiều pipeline đang hoạt động, nên tách chúng thành các phân đoạn thông tin xác thực riêng, ngay cả khi cùng một gói cước.

Làm thế nào để truyền proxy vào container nếu công cụ bên trong không hỗ trợ biến môi trường?

Một số tiện ích bỏ qua HTTP_PROXY và yêu cầu địa chỉ trong tệp cấu hình hoặc cờ dòng lệnh riêng — khi đó chuỗi kết nối được truyền tường minh lúc gọi công cụ, đọc từ chính biến đó ở cấp script bao bọc của bước.

Có cần giới hạn proxy chỉ cho các tên miền bên ngoài mà pipeline thực sự truy cập không?

Có, nếu tài khoản hỗ trợ cấu hình này — việc đó không chỉ tiết kiệm lưu lượng mà còn loại bỏ các lượt truy cập nhầm vào địa chỉ nội bộ và địa chỉ dùng chung do lỗi trong NO_PROXY, những lỗi mà nếu không sẽ không bị phát hiện cho đến khi xem lại nhật ký.

Proxy xác thực bằng tên đăng nhập và mật khẩu cho CI, sẵn sàng truyền qua biến môi trường mà không phụ thuộc vào địa chỉ của runner, có trong mục proxy. Tài liệu về tích hợp và giới hạn có trong API proxy.