Sử dụng docker multi-stage để xây dựng image windows

Chào mọi người! Tên tôi là Andrey và tôi làm kỹ sư DevOps tại Exness trong nhóm phát triển. Hoạt động chính của tôi liên quan đến việc xây dựng, triển khai và hỗ trợ các ứng dụng trên docker trên hệ điều hành Linux (sau đây gọi tắt là OS). Cách đây không lâu, tôi có một nhiệm vụ có hoạt động tương tự, nhưng hệ điều hành mục tiêu của dự án là Windows Server và một bộ dự án C++. Đối với tôi, đây là lần tương tác chặt chẽ đầu tiên với các bộ chứa docker trong hệ điều hành Windows và nói chung là với các ứng dụng C++. Nhờ đó, tôi đã có được trải nghiệm thú vị và tìm hiểu được một số điều phức tạp trong việc chứa các ứng dụng trong Windows.

Sử dụng docker multi-stage để xây dựng image windows

Trong bài viết này, tôi muốn kể cho bạn nghe những khó khăn mà tôi đã gặp phải và cách tôi giải quyết chúng. Tôi hy vọng điều này hữu ích cho những thách thức hiện tại và tương lai của bạn. Thích đọc sách!

Tại sao lại là container?

Công ty có cơ sở hạ tầng hiện có cho bộ điều phối container Hashicorp Nomad và các thành phần liên quan - Consul và Vault. Do đó, việc chứa ứng dụng được chọn làm phương pháp thống nhất để cung cấp một giải pháp hoàn chỉnh. Do cơ sở hạ tầng của dự án chứa các máy chủ docker với Windows Server Core OS phiên bản 1803 và 1809, nên cần phải xây dựng các phiên bản riêng biệt của hình ảnh docker cho 1803 và 1809. Trong phiên bản 1803, điều quan trọng cần nhớ là số sửa đổi của máy chủ docker bản dựng phải khớp với số sửa đổi của hình ảnh docker cơ sở và máy chủ nơi vùng chứa từ hình ảnh này sẽ được khởi chạy. Phiên bản 1809 không có nhược điểm đó. Bạn có thể đọc thêm đây.

Tại sao nhiều giai đoạn?

Các kỹ sư của nhóm phát triển không có hoặc có rất ít quyền truy cập vào máy chủ xây dựng; không có cách nào để quản lý nhanh chóng bộ thành phần để xây dựng ứng dụng trên các máy chủ này, chẳng hạn như cài đặt bộ công cụ hoặc khối lượng công việc bổ sung cho Visual Studio. Do đó, chúng tôi đã quyết định cài đặt tất cả các thành phần cần thiết để xây dựng ứng dụng vào build Docker image. Nếu cần, bạn có thể nhanh chóng chỉ thay đổi dockerfile và khởi chạy quy trình tạo hình ảnh này.

Từ lý thuyết đến hành động

Trong bản dựng hình ảnh nhiều giai đoạn Docker lý tưởng, môi trường xây dựng ứng dụng được chuẩn bị theo cùng một tập lệnh Dockerfile như chính ứng dụng được xây dựng. Nhưng trong trường hợp của chúng tôi, một liên kết trung gian đã được thêm vào, cụ thể là bước tạo sơ bộ hình ảnh docker với mọi thứ cần thiết để xây dựng ứng dụng. Điều này được thực hiện vì tôi muốn sử dụng tính năng bộ đệm của docker để giảm thời gian cài đặt của tất cả các phần phụ thuộc.

Chúng ta hãy xem những điểm chính của tập lệnh dockerfile để tạo hình ảnh này.

Để tạo hình ảnh của các phiên bản hệ điều hành khác nhau, bạn có thể xác định một đối số trong dockerfile mà qua đó số phiên bản được chuyển trong quá trình xây dựng và đó cũng là thẻ của hình ảnh cơ sở.

Có thể tìm thấy danh sách đầy đủ các thẻ hình ảnh Microsoft Windows Server đây.

ARG WINDOWS_OS_VERSION=1809
FROM mcr.microsoft.com/windows/servercore:$WINDOWS_OS_VERSION

Theo mặc định các lệnh trong hướng dẫn RUN bên trong dockerfile trên hệ điều hành Windows, chúng được thực thi trong bảng điều khiển cmd.exe. Để thuận tiện cho việc viết script và mở rộng chức năng của các lệnh được sử dụng, chúng tôi sẽ xác định lại bảng điều khiển thực thi lệnh trong Powershell thông qua hướng dẫn SHELL.

SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop';"]

Bước tiếp theo là cài đặt trình quản lý gói sô cô la và các gói cần thiết:

COPY chocolatey.pkg.config .
RUN Set-ExecutionPolicy Bypass -Scope Process -Force ;
    [System.Net.ServicePointManager]::SecurityProtocol = 
    [System.Net.ServicePointManager]::SecurityProtocol -bor 3072 ;
    $env:chocolateyUseWindowsCompression = 'true' ;
    iex ((New-Object System.Net.WebClient).DownloadString( 
      'https://chocolatey.org/install.ps1')) ;
    choco install chocolatey.pkg.config -y --ignore-detected-reboot ;
    if ( @(0, 1605, 1614, 1641, 3010) -contains $LASTEXITCODE ) { 
      refreshenv; } else { exit $LASTEXITCODE; } ;
    Remove-Item 'chocolatey.pkg.config'

Để cài đặt các gói bằng chocolatey, bạn chỉ cần chuyển chúng dưới dạng danh sách hoặc cài đặt từng gói một nếu bạn cần chuyển các tham số duy nhất cho mỗi gói. Trong trường hợp của chúng tôi, chúng tôi đã sử dụng tệp kê khai ở định dạng XML, tệp này chứa danh sách các gói bắt buộc và tham số của chúng. Nội dung của nó trông như thế này:

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="python" version="3.8.2"/>
  <package id="nuget.commandline" version="5.5.1"/>
  <package id="git" version="2.26.2"/>
</packages>

Tiếp theo, chúng ta cài đặt môi trường xây dựng ứng dụng, cụ thể là MS Build Tools 2019 - đây là phiên bản nhẹ của Visual Studio 2019, chứa bộ thành phần cần thiết tối thiểu để biên dịch mã.
Để làm việc hoàn toàn với dự án C++ của chúng ta, chúng ta sẽ cần các thành phần bổ sung, cụ thể là:

  • Công cụ C++ khối lượng công việc
  • Bộ công cụ v141
  • SDK Windows 10 (10.0.17134.0)

Bạn có thể tự động cài đặt một bộ công cụ mở rộng bằng cách sử dụng tệp cấu hình ở định dạng JSON. Nội dung tập tin cấu hình:

Danh sách đầy đủ các thành phần có sẵn có thể được tìm thấy trên trang tài liệu Microsoft Visual Studio.

{
  "version": "1.0",
  "components": [
    "Microsoft.Component.MSBuild",
    "Microsoft.VisualStudio.Workload.VCTools;includeRecommended",
    "Microsoft.VisualStudio.Component.VC.v141.x86.x64",
    "Microsoft.VisualStudio.Component.Windows10SDK.17134"
  ]
}

Dockerfile chạy tập lệnh cài đặt và để thuận tiện, thêm đường dẫn đến các tệp thực thi của công cụ xây dựng vào biến môi trường PATH. Cũng nên loại bỏ các tập tin và thư mục không cần thiết để giảm kích thước của hình ảnh.

COPY buildtools.config.json .
RUN Invoke-WebRequest 'https://aka.ms/vs/16/release/vs_BuildTools.exe' 
      -OutFile '.vs_buildtools.exe' -UseBasicParsing ;
    Start-Process -FilePath '.vs_buildtools.exe' -Wait -ArgumentList 
      '--quiet --norestart --nocache --config C:buildtools.config.json' ;
    Remove-Item '.vs_buildtools.exe' ;
    Remove-Item '.buildtools.config.json' ;
    Remove-Item -Force -Recurse 
      'C:Program Files (x86)Microsoft Visual StudioInstaller' ;
    $env:PATH = 'C:Program Files (x86)Microsoft Visual Studio2019BuildToolsMSBuildCurrentBin;' + $env:PATH; 
    [Environment]::SetEnvironmentVariable('PATH', $env:PATH, 
      [EnvironmentVariableTarget]::Machine)

Ở giai đoạn này, hình ảnh biên dịch ứng dụng C++ của chúng tôi đã sẵn sàng và chúng tôi có thể tiến hành trực tiếp để tạo bản dựng ứng dụng nhiều giai đoạn docker.

Hoạt động nhiều giai đoạn

Chúng tôi sẽ sử dụng hình ảnh đã tạo với tất cả các công cụ có sẵn làm hình ảnh bản dựng. Như trong tập lệnh dockerfile trước, chúng tôi sẽ thêm khả năng chỉ định động số phiên bản/thẻ hình ảnh để dễ dàng sử dụng lại mã. Điều quan trọng là phải thêm nhãn as builder vào hình ảnh lắp ráp trong hướng dẫn FROM.

ARG WINDOWS_OS_VERSION=1809
FROM buildtools:$WINDOWS_OS_VERSION as builder

Bây giờ là lúc xây dựng ứng dụng. Mọi thứ ở đây khá đơn giản: sao chép mã nguồn và mọi thứ liên quan đến nó, rồi bắt đầu quá trình biên dịch.

COPY myapp .
RUN nuget restore myapp.sln ;
    msbuild myapp.sln /t:myapp /p:Configuration=Release

Giai đoạn cuối cùng của việc tạo hình ảnh cuối cùng là chỉ định hình ảnh cơ sở của ứng dụng, nơi sẽ đặt tất cả các tạo phẩm biên dịch và tệp cấu hình. Để sao chép các tập tin đã biên dịch từ tập hợp ảnh trung gian, bạn phải chỉ định tham số --from=builder trong hướng dẫn COPY.

FROM mcr.microsoft.com/windows/servercore:$WINDOWS_OS_VERSION

COPY --from=builder C:/x64/Release/myapp/ ./
COPY ./configs ./

Bây giờ tất cả những gì còn lại là thêm các phụ thuộc cần thiết để ứng dụng của chúng ta hoạt động và chỉ định lệnh khởi chạy thông qua hướng dẫn ENTRYPOINT hoặc CMD.

Kết luận

Trong bài viết này, tôi đã nói về cách tạo môi trường biên dịch chính thức cho các ứng dụng C++ bên trong một vùng chứa trong Windows và cách sử dụng các khả năng của các bản dựng nhiều giai đoạn docker để tạo hình ảnh chính thức cho ứng dụng của chúng ta.

Nguồn: www.habr.com

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