Hướng dẫn chạy Buildah bên trong container

Vẻ đẹp của việc tách thời gian chạy vùng chứa thành các thành phần công cụ riêng biệt là gì? Đặc biệt, những công cụ này có thể bắt đầu được kết hợp với nhau để bảo vệ lẫn nhau.

Hướng dẫn chạy Buildah bên trong container

Nhiều người bị thu hút bởi ý tưởng xây dựng các hình ảnh OCI được chứa trong Kubernetes hoặc hệ thống tương tự. Giả sử chúng ta có CI/CD liên tục thu thập hình ảnh, sau đó đại loại như Red Hat OpenShift/Kubernetes sẽ khá hữu ích về mặt cân bằng tải trong quá trình xây dựng. Cho đến gần đây, hầu hết mọi người chỉ cấp cho các container quyền truy cập vào Docker socket và cho phép chúng chạy lệnh docker build. Cách đây vài năm chúng tôi đã cho thấyrằng điều này rất không an toàn, trên thực tế, nó còn tệ hơn cả việc cấp root hoặc sudo không mật khẩu.

Đó là lý do tại sao mọi người liên tục cố gắng chạy Buildah trong vùng chứa. Nói tóm lại, chúng tôi đã tạo ra Ví dụ Theo ý kiến ​​​​của chúng tôi, cách tốt nhất để chạy Buildah bên trong một thùng chứa và đăng các hình ảnh tương ứng lên quay.io/buildah. Bắt đầu nào...

điều chỉnh

Những hình ảnh này được xây dựng từ Dockerfiles, có thể tìm thấy trong kho Buildah trong thư mục hình ảnh xây dựng.
Ở đây chúng tôi sẽ xem xét phiên bản ổn định của Dockerfile.

# stable/Dockerfile
#
# Build a Buildah container image from the latest
# stable version of Buildah on the Fedoras Updates System.
# https://bodhi.fedoraproject.org/updates/?search=buildah
# This image can be used to create a secured container
# that runs safely with privileges within the container.
#
FROM fedora:latest

# Don't include container-selinux and remove
# directories used by dnf that are just taking
# up space.
RUN yum -y install buildah fuse-overlayfs --exclude container-selinux; rm -rf /var/cache /var/log/dnf* /var/log/yum.*

# Adjust storage.conf to enable Fuse storage.
RUN sed -i -e 's|^#mount_program|mount_program|g' -e '/additionalimage.*/a "/var/lib/shared",' /etc/containers/storage.conf

Thay vì OverlayFS, được triển khai ở cấp nhân Linux máy chủ, chúng tôi sử dụng chương trình bên trong vùng chứa lớp phủ cầu chì, vì hiện tại OverlayFS chỉ có thể gắn kết nếu bạn cấp cho nó quyền SYS_ADMIN bằng các khả năng của Linux. Và chúng tôi muốn chạy các thùng chứa Buildah mà không cần bất kỳ quyền root nào. Fuse-overlay hoạt động khá nhanh và có hiệu suất tốt hơn trình điều khiển lưu trữ VFS. Xin lưu ý rằng khi chạy bộ chứa Buildah sử dụng Fuse, bạn phải cung cấp thiết bị /dev/fuse.

podman run --device /dev/fuse quay.io/buildahctr ...
RUN mkdir -p /var/lib/shared/overlay-images /var/lib/shared/overlay-layers; touch /var/lib/shared/overlay-images/images.lock; touch /var/lib/shared/overlay-layers/layers.lock

Tiếp theo chúng ta tạo một thư mục để lưu trữ bổ sung. Thùng chứa/lưu trữ hỗ trợ khái niệm kết nối các cửa hàng hình ảnh chỉ đọc bổ sung. Ví dụ: bạn có thể định cấu hình vùng lưu trữ lớp phủ trên một máy, sau đó sử dụng NFS để gắn bộ lưu trữ này trên một máy khác và sử dụng hình ảnh từ nó mà không cần tải xuống qua kéo. Chúng tôi cần bộ lưu trữ này để có thể kết nối một số bộ lưu trữ hình ảnh từ máy chủ dưới dạng ổ đĩa và sử dụng nó bên trong vùng chứa.

# Set up environment variables to note that this is
# not starting with user namespace and default to
# isolate the filesystem with chroot.
ENV _BUILDAH_STARTED_IN_USERNS="" BUILDAH_ISOLATION=chroot

Cuối cùng, bằng cách sử dụng biến môi trường BUILDAH_ISOLATION, chúng tôi đang yêu cầu bộ chứa Buildah chạy với chế độ cách ly chroot theo mặc định. Ở đây không cần cách nhiệt bổ sung vì chúng tôi đang làm việc trong một thùng chứa. Để Buildah tạo các vùng chứa được phân tách bằng không gian tên của riêng mình, cần có đặc quyền SYS_ADMIN, đặc quyền này sẽ yêu cầu nới lỏng các quy tắc SELinux và SECCOMP của vùng chứa, điều này trái với ưu tiên của chúng tôi là xây dựng từ một vùng chứa an toàn.

Chạy Buildah bên trong container

Sơ đồ hình ảnh vùng chứa Buildah được thảo luận ở trên cho phép bạn thay đổi linh hoạt các phương pháp khởi chạy các vùng chứa đó.

Tốc độ so với an toàn

Bảo mật máy tính luôn là sự thỏa hiệp giữa tốc độ của quá trình và mức độ bảo vệ được bao bọc xung quanh nó. Tuyên bố này cũng đúng khi lắp ráp các thùng chứa, vì vậy dưới đây chúng tôi sẽ xem xét các phương án cho sự thỏa hiệp như vậy.

Hình ảnh vùng chứa được thảo luận ở trên sẽ lưu trữ trong /var/lib/containers. Vì vậy chúng ta cần mount nội dung vào thư mục này và cách chúng ta thực hiện sẽ ảnh hưởng rất lớn đến tốc độ build container image.

Hãy xem xét ba lựa chọn.

Tùy chọn 1. Nếu cần bảo mật tối đa thì đối với mỗi vùng chứa, bạn có thể tạo thư mục riêng cho vùng chứa/hình ảnh và kết nối nó với vùng chứa thông qua ổ đĩa. Và bên cạnh đó, hãy đặt thư mục ngữ cảnh vào chính vùng chứa, trong thư mục /build:

# mkdir /var/lib/containers1
# podman run -v ./build:/build:z -v /var/lib/containers1:/var/lib/containers:Z quay.io/buildah/stable
buildah  -t image1 bud /build
# podman run -v /var/lib/containers1:/var/lib/containers:Z quay.io/buildah/stable buildah  push  image1 registry.company.com/myuser
# rm -rf /var/lib/containers1

An ninh. Buildah chạy trong một thùng chứa như vậy có độ bảo mật tối đa: nó không được cấp bất kỳ đặc quyền root nào khi sử dụng các khả năng và tất cả các hạn chế của SECOMP và SELinux đều áp dụng cho nó. Một thùng chứa như vậy thậm chí có thể được chạy với tính năng cách ly Không gian tên người dùng bằng cách thêm một tùy chọn như —uidmap 0: 100000:10000.

Hiệu suất. Nhưng hiệu suất ở đây là tối thiểu, vì mọi hình ảnh từ cơ quan đăng ký vùng chứa đều được sao chép vào máy chủ mọi lúc và bộ nhớ đệm hoàn toàn không hoạt động. Khi hoàn thành công việc của mình, bộ chứa Buildah phải gửi hình ảnh đến cơ quan đăng ký và hủy nội dung trên máy chủ. Lần tiếp theo hình ảnh vùng chứa được tạo, nó sẽ phải được tải xuống lại từ sổ đăng ký, vì lúc đó sẽ không còn gì trên máy chủ.

Tùy chọn 2. Nếu cần hiệu năng ở cấp độ Docker, bạn có thể gắn trực tiếp vùng chứa/bộ lưu trữ máy chủ vào vùng chứa.

# podman run -v ./build:/build:z -v /var/lib/containers:/var/lib/containers --security-opt label:disabled quay.io/buildah/stable buildah  -t image2 bud /build
# podman run -v /var/lib/containers:/var/lib/containers --security-opt label:disabled  quay.io/buildah/stable buildah push image2 registry.company.com/myuser

An ninh. Đây là cách kém an toàn nhất để xây dựng vùng chứa vì nó cho phép vùng chứa sửa đổi bộ nhớ trên máy chủ và có khả năng cung cấp cho Podman hoặc CRI-O một hình ảnh độc hại. Ngoài ra, bạn sẽ cần phải tắt tính năng phân tách SELinux để các tiến trình trong bộ chứa Buildah có thể tương tác với bộ lưu trữ trên máy chủ. Lưu ý rằng tùy chọn này vẫn tốt hơn so với ổ cắm Docker vì vùng chứa bị khóa bởi các tính năng bảo mật còn lại và không thể đơn giản chạy vùng chứa trên máy chủ.

Hiệu suất. Đây là mức tối đa vì bộ nhớ đệm được sử dụng đầy đủ. Nếu Podman hoặc CRI-O đã tải hình ảnh được yêu cầu xuống máy chủ thì quy trình Buildah bên trong vùng chứa sẽ không phải tải xuống lại và các bản dựng tiếp theo dựa trên hình ảnh này cũng sẽ có thể lấy những gì chúng cần từ bộ đệm .

Tùy chọn 3. Bản chất của phương pháp này là kết hợp nhiều hình ảnh vào một dự án với một thư mục chung để chứa các hình ảnh.

# mkdir /var/lib/project3
# podman run --security-opt label_level=s0:C100, C200 -v ./build:/build:z 
-v /var/lib/project3:/var/lib/containers:Z quay.io/buildah/stable buildah  -t image3 bud /build
# podman run --security-opt label_level=s0:C100, C200 
-v /var/lib/project3:/var/lib/containers quay.io/buildah/stable buildah push image3  registry.company.com/myuser

Trong ví dụ này, chúng tôi không xóa thư mục dự án (/var/lib/project3) giữa các lần chạy, vì vậy tất cả các bản dựng tiếp theo trong dự án đều được hưởng lợi từ bộ nhớ đệm.

An ninh. Điều gì đó ở giữa tùy chọn 1 và 2. Một mặt, vùng chứa không có quyền truy cập vào nội dung trên máy chủ và do đó, không thể đưa thứ gì đó xấu vào bộ lưu trữ hình ảnh Podman/CRI-O. Mặt khác, như một phần trong thiết kế của nó, thùng chứa có thể cản trở việc lắp ráp các thùng chứa khác.

Hiệu suất. Ở đây còn tệ hơn khi sử dụng bộ nhớ đệm dùng chung ở cấp máy chủ, vì bạn không thể sử dụng hình ảnh đã được tải xuống bằng Podman/CRI-O. Tuy nhiên, sau khi Buildah tải hình ảnh xuống, hình ảnh đó có thể được sử dụng trong mọi bản dựng tiếp theo trong dự án.

Bộ nhớ bổ sung

У thùng chứa/lưu trữ Có một điều thú vị là các cửa hàng bổ sung (các cửa hàng bổ sung), nhờ đó khi khởi chạy và xây dựng các container, công cụ chứa có thể sử dụng các kho hình ảnh bên ngoài ở chế độ lớp phủ chỉ đọc. Về cơ bản, bạn có thể thêm một hoặc nhiều kho lưu trữ chỉ đọc vào tệp storage.conf để khi bạn khởi động vùng chứa, công cụ vùng chứa sẽ tìm kiếm hình ảnh mong muốn trong đó. Hơn nữa, nó sẽ chỉ tải xuống hình ảnh từ sổ đăng ký nếu nó không tìm thấy nó trong bất kỳ kho lưu trữ nào trong số này. Công cụ chứa sẽ chỉ có thể ghi vào bộ lưu trữ có thể ghi...

Nếu bạn cuộn lên và nhìn vào Dockerfile mà chúng ta sử dụng để xây dựng image quay.io/buildah/stable, sẽ có những dòng như thế này:

# Adjust storage.conf to enable Fuse storage.
RUN sed -i -e 's|^#mount_program|mount_program|g' -e '/additionalimage.*/a "/var/lib/shared",' /etc/containers/storage.conf
RUN mkdir -p /var/lib/shared/overlay-images /var/lib/shared/overlay-layers; touch /var/lib/shared/overlay-images/images.lock; touch /var/lib/shared/overlay-layers/layers.lock

Trong dòng đầu tiên, chúng tôi sửa đổi /etc/containers/storage.conf bên trong hình ảnh vùng chứa, yêu cầu trình điều khiển lưu trữ sử dụng “bổ sung hình ảnh” trong thư mục /var/lib/shared. Và trong dòng tiếp theo, chúng tôi tạo một thư mục dùng chung và thêm một vài tệp khóa để không bị lạm dụng từ vùng chứa/bộ lưu trữ. Về cơ bản, chúng tôi chỉ đơn giản là tạo một kho lưu trữ hình ảnh vùng chứa trống.

Nếu bạn gắn vùng chứa/bộ lưu trữ ở cấp cao hơn thư mục này, Buildah sẽ có thể sử dụng hình ảnh.

Bây giờ, hãy quay lại Tùy chọn 2 đã thảo luận ở trên, khi vùng chứa Buildah có thể đọc và ghi vào vùng chứa/lưu trữ trên máy chủ và theo đó, có hiệu suất tối đa do lưu hình ảnh vào bộ nhớ đệm ở cấp độ Podman/CRI-O, nhưng cung cấp mức độ bảo mật tối thiểu vì nó có thể ghi trực tiếp vào bộ lưu trữ. Bây giờ, hãy thêm dung lượng lưu trữ bổ sung ở đây và tận dụng tối đa cả hai thế giới.

# mkdir /var/lib/containers4
# podman run -v ./build:/build:z -v /var/lib/containers/storage:/var/lib/shared:ro -v  /var/lib/containers4:/var/lib/containers:Z  quay.io/buildah/stable 
 buildah  -t image4 bud /build
# podman run -v /var/lib/containers/storage:/var/lib/shared:ro  
-v >/var/lib/containers4:/var/lib/containers:Z quay.io/buildah/stable buildah push image4  registry.company.com/myuser
# rm -rf /var/lib/continers4

Lưu ý rằng /var/lib/containers/storage của Máy chủ được gắn vào /var/lib/shared bên trong vùng chứa ở chế độ chỉ đọc. Do đó, khi làm việc trong vùng chứa, Buildah có thể sử dụng bất kỳ hình ảnh nào đã được tải xuống trước đó bằng Podman/CRI-O (xin chào, tốc độ), nhưng chỉ có thể ghi vào bộ nhớ riêng của nó (xin chào, bảo mật). Cũng lưu ý rằng việc này được thực hiện mà không vô hiệu hóa tính năng phân tách SELinux cho vùng chứa.

Sắc thái quan trọng

Trong mọi trường hợp, bạn không nên xóa bất kỳ hình ảnh nào khỏi kho lưu trữ cơ bản. Nếu không, vùng chứa Buildah có thể bị lỗi.

Và đây không phải là tất cả những lợi thế

Khả năng lưu trữ bổ sung không bị giới hạn trong kịch bản trên. Ví dụ: bạn có thể đặt tất cả hình ảnh vùng chứa trên bộ lưu trữ mạng dùng chung và cấp quyền truy cập vào nó cho tất cả các vùng chứa Buildah. Giả sử chúng tôi có hàng trăm hình ảnh mà hệ thống CI/CD của chúng tôi thường xuyên sử dụng để tạo hình ảnh vùng chứa. Chúng tôi tập trung tất cả những hình ảnh này vào một máy chủ lưu trữ, sau đó bằng cách sử dụng các công cụ lưu trữ mạng ưa thích (NFS, Gluster, Ceph, ISCSI, S3...), chúng tôi mở quyền truy cập chung vào bộ lưu trữ này cho tất cả các nút Buildah hoặc Kubernetes.

Bây giờ, chỉ cần gắn bộ lưu trữ mạng này vào bộ chứa Buildah trên /var/lib/shared là đủ và thế là xong - Bộ chứa Buildah không còn phải tải xuống hình ảnh thông qua thao tác kéo. Vì vậy, chúng tôi loại bỏ giai đoạn tiền dân số và ngay lập tức sẵn sàng tung ra các thùng chứa.

Và tất nhiên, điều này có thể được sử dụng trong hệ thống Kubernetes trực tiếp hoặc cơ sở hạ tầng vùng chứa để khởi chạy và chạy các vùng chứa ở bất cứ đâu mà không cần tải xuống hình ảnh. Hơn nữa, cơ quan đăng ký vùng chứa, khi nhận được yêu cầu đẩy để tải hình ảnh cập nhật lên nó, có thể tự động gửi hình ảnh này đến bộ lưu trữ mạng dùng chung, nơi nó ngay lập tức có sẵn cho tất cả các nút.

Hình ảnh vùng chứa đôi khi có thể đạt tới kích thước nhiều gigabyte. Chức năng của bộ nhớ bổ sung cho phép bạn tránh sao chép những hình ảnh như vậy trên các nút và khiến việc khởi chạy các vùng chứa gần như ngay lập tức.

Ngoài ra, chúng tôi hiện đang nghiên cứu một tính năng mới gọi là gắn kết khối lượng lớp phủ, tính năng này sẽ giúp việc xây dựng các thùng chứa nhanh hơn nữa.

Kết luận

Chạy Buildah bên trong container trong Kubernetes/CRI-O, Podman hoặc thậm chí Docker là khả thi, đơn giản và an toàn hơn nhiều so với sử dụng docker.socket. Chúng tôi đã tăng cường đáng kể tính linh hoạt khi làm việc với hình ảnh, do đó bạn có thể chạy chúng theo nhiều cách khác nhau nhằm tối ưu hóa sự cân bằng giữa bảo mật và hiệu suất.

Chức năng lưu trữ bổ sung cho phép bạn tăng tốc hoặc thậm chí loại bỏ hoàn toàn việc tải hình ảnh xuống các nút.

Nguồn: www.habr.com

Thêm một lời nhận xét