View in English

  • Apple Developer
    • 시작하기

    시작하기 탐색

    • 개요
    • 알아보기
    • Apple Developer Program

    알림 받기

    • 최신 뉴스
    • Hello Developer
    • 플랫폼

    플랫폼 탐색

    • Apple 플랫폼
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    • App Store

    피처링

    • 디자인
    • 배포
    • 게임
    • 액세서리
    • 웹
    • 홈
    • CarPlay
    • 기술

    기술 탐색

    • 개요
    • Xcode
    • Swift
    • SwiftUI

    피처링

    • 손쉬운 사용
    • 앱 인텐트
    • Apple Intelligence
    • 게임
    • 머신 러닝 및 AI
    • 보안
    • Xcode Cloud
    • 커뮤니티

    커뮤니티 탐색

    • 개요
    • Apple과의 만남 이벤트
    • 커뮤니티 주도 이벤트
    • 개발자 포럼
    • 오픈 소스

    피처링

    • WWDC
    • Swift Student Challenge
    • 개발자 이야기
    • App Store 어워드
    • Apple 디자인 어워드
    • 문서

    문서 탐색

    • 문서 라이브러리
    • 기술 개요
    • 샘플 코드
    • 휴먼 인터페이스 가이드라인
    • 비디오

    릴리즈 노트

    • 피처링 업데이트
    • iOS
    • iPadOS
    • macOS
    • watchOS
    • visionOS
    • tvOS
    • Xcode
    • 다운로드

    다운로드 탐색

    • 모든 다운로드
    • 운영 체제
    • 애플리케이션
    • 디자인 리소스

    피처링

    • Xcode
    • TestFlight
    • 서체
    • SF Symbols
    • Icon Composer
    • 지원

    지원 탐색

    • 개요
    • 도움말
    • 개발자 포럼
    • 피드백 지원
    • 문의하기

    피처링

    • 계정 도움말
    • 앱 심사 지침
    • App Store Connect 도움말
    • 새로 추가될 요구 사항
    • 계약 및 지침
    • 시스템 상태
  • 빠른 링크

    • 이벤트
    • 뉴스
    • 포럼
    • 샘플 코드
    • 비디오
 

비디오

메뉴 열기 메뉴 닫기
  • 컬렉션
  • 전체 비디오
  • 소개

더 많은 비디오

  • 소개
  • 요약
  • 자막 전문
  • 코드
  • 가상화 앱의 기능 확장하기

    macOS 27의 강력한 새 기능을 가상화 앱에 도입하세요. 최초 부팅 시 사용자 계정 설정을 통해 macOS 게스트의 설정을 자동화하는 방법을 알아보세요. 가상 머신에 대한 USB 액세서리의 패스스루와 관련된 첨단 워크플로뿐만 아니라, 맞춤형 네트워크 토폴로지 및 포트 포워딩을 살펴봅니다. 또한 앱의 가상 머신 실행 경험을 풍부하게 만들어 줄 수 있는 최근 개선 사항에 대해서도 알아봅니다.

    챕터

    • 0:01 - Introduction
    • 1:04 - macOS guest provisioning
    • 4:34 - Accessory Access
    • 8:26 - Advanced network topologies
    • 11:35 - DiskImageKit
    • 15:57 - Custom Virtio

    리소스

    • DiskImageKit
    • Accessory Access
    • vmnet
    • Virtual I/O Device (VIRTIO) Version 1.4
    • Virtualization
      • HD 비디오
      • SD 비디오

    관련 비디오

    WWDC26

    • 컨테이너 머신 살펴보기
  • 비디오 검색…

    안녕하세요!

    저는 Virtualization 팀의 Ronnie Misra입니다 이번 세션에서는 고급 기능을 추가하는 방법을 Virtualization 앱에 구현하는 법을 알아보겠습니다 Virtualization 프레임워크를 사용하면 완전한 데스크탑 환경을 구동하거나 정교한 개발자 워크플로를 지원하는 앱을 만들 수 있습니다 예를 들어 협업 Mac 앱 테스트나 장치 간 네트워킹 같은 작업이 가능합니다 또한 커맨드 라인 도구와 자동화도 구축할 수 있어 통제된 환경에서 일관된 테스트를 진행할 수 있습니다 오늘은 새로운 API와 기존 API를 살펴보며 Virtualization 앱을 더욱 강력하게 만드는 방법을 소개합니다 다룰 내용은 가상 Mac 설정 자동화 그리고 가상 머신에 USB 장치 연결 Accessory Access 프레임워크를 활용한 방법입니다 또한 고급 네트워크 토폴로지 구성 방법과 고성능 디스크 이미지를 만드는 방법 그리고 DiskImageKit 프레임워크를 활용한 효율적인 구성도 살펴봅니다 마지막으로 커스텀 고성능 Virtio 기반 가상 장치 생성 방법도 다룹니다

    먼저 Virtualization을 통해 어떻게 macOS 게스트 프로비저닝을 자동화하는지 보여드리겠습니다 가상 Mac에 macOS를 설치한 후에는 물리적 Mac을 설정하는 것과 동일한 방식으로 구성할 수 있습니다 이미 익숙한 설정 도우미를 그대로 사용하세요 이를 통해 사용자 계정을 쉽게 만들고 일반 설정을 구성할 수 있습니다 하지만 자동화 사용 사례에서는 가상 Mac을 프로그래밍 방식으로 설정할 수 있으면 편리합니다 Virtualization 프레임워크는 이제 앱이 프로비저닝 옵션을 지정할 수 있게 합니다 가상 Mac이 시작될 때 적용됩니다 전체 이름, 사용자 이름, 비밀번호를 제공하고 필요에 따라 자동 로그인이나 SSH 원격 로그인을 활성화할 수 있습니다 게스트가 처음 부팅될 때 이러한 매개변수가 자동으로 설정 도우미에 전달됩니다 지정된 자격증명으로 사용자가 생성되고 요청한 경우 자동 로그인과 원격 로그인이 활성화됩니다 macOS 게스트 프로비저닝 API를 사용하려면 먼저 원하는 설정으로 VZMacGuestProvisioningOptions 객체를 생성합니다 여기서 저는 사용자 계정을 생성하는 provisioningOptions를 만들었습니다 자동 로그인과 SSH도 활성화합니다 그런 다음 VZMacOSVirtualMachineStartOptions 객체를 생성하고 게스트 프로비저닝을 방금 만든 provisioningOptions로 설정합니다 마지막으로 이 startOptions를 사용해 가상 Mac을 시작합니다 게스트가 부팅되면 이 프로비저닝 옵션이 가상 Mac의 자동 프로비저닝에 사용됩니다 이제 실제 동작을 보여드리겠습니다 앞서 보여드린 macOS 가상 머신 샘플 앱을 수정해 macOS 게스트 프로비저닝 API를 사용하도록 했습니다 이미 새 가상 Mac에 macOS를 설치했지만 아직 부팅하지 않았습니다 앱을 더블 클릭해 가상 Mac을 처음으로 부팅하겠습니다

    앱이 프로비저닝 옵션을 묻는 메시지를 표시합니다 이전에 이 앱을 실행한 적이 있어서 기본 프로비저닝 옵션을 기억하고 있습니다 Jane Appleseed 사용자를 생성하고 자동 로그인과 원격 로그인을 활성화하는 옵션입니다 이제 확인을 클릭해 해당 설정을 적용하겠습니다

    앱이 해당 프로비저닝 옵션으로 가상 Mac을 시작했습니다 Virtualization 프레임워크가 해당 옵션을 게스트에 전달하므로 설정 도우미를 수동으로 진행할 필요가 없습니다 설정 도우미가 자동으로 새 사용자를 생성합니다 설정 도우미가 이제 새 계정을 생성했습니다 프로비저닝 옵션에 자동 로그인 활성화가 지정되어 있어 게스트가 계정에 로그인했습니다 이제 가상 Mac에서 Finder 윈도우를 열겠습니다

    사이드바에 jappleseed라는 사용자 이름이 표시됩니다 제가 입력한 사용자 이름과 일치합니다 이제 시스템 설정을 열어 원격 로그인 공유 설정으로 이동하겠습니다

    시스템 설정에서 원격 로그인이 활성화되었음을 확인할 수 있습니다 가상 Mac이 이제 사용 준비가 됐습니다! 부팅만 하면 됐습니다 이 설정들은 게스트가 아직 설정되지 않은 경우에만 적용됩니다 게스트에 이미 사용자가 생성된 경우 이후 부팅 시 전달된 프로비저닝 옵션은 무시됩니다 이 API를 사용할 때는 비밀번호 처리 방식을 신중하게 고려하고 앱의 보안 영향도 검토하세요 예를 들어 코드에 비밀번호를 하드코딩하는 대신

    Keychain에서 읽어오거나 구성 파일이나 환경 변수를 사용하는 것이 좋습니다 다음으로 Accessory Access를 사용해 USB 액세서리를 연결하는 방법에 대해 알아보겠습니다

    일부 가상 머신 사용 사례에서는 호스트에 연결된 USB 액세서리에 게스트가 접근할 수 있어야 합니다 예를 들어 가상 머신 내부에서 USB 드라이브를 사용하고 싶은 경우가 있습니다 동시에 사용자는 자신의 장치를 계속 제어할 수 있어야 합니다 Accessory Access는 이를 지원하기 위해 설계된 새 프레임워크로 macOS 및 Linux 가상 머신에서 USB 장치를 사용할 수 있게 합니다 Accessory Access의 핵심 원칙은 사용자가 명시적으로 제어할 수 있어야 한다는 것입니다 어떤 장치가 어떤 앱에 연결되는지를요 사용자는 어떤 앱이 자신의 장치를 사용하는지 볼 수 있고 언제든지 장치를 연결하거나 분리할 수 있습니다 Accessory Access는 장치 핫 플러깅을 지원합니다 누군가가 앱에 장치 접근 권한을 부여하면 런타임에 가상 머신에 연결할 수 있습니다 VM의 정적 구성을 변경하지 않고도 가능합니다 자세한 내용을 살펴보기 전에 Accessory Access 동작을 먼저 보겠습니다 앞서 보여드린 macOS 가상 머신 샘플 앱을 실행 중입니다 이제 Mac에 USB 드라이브를 연결하겠습니다

    드라이브 아이콘이 데스크탑에 나타났습니다 또한 가상 머신 앱이 실행 중이고 스토리지 장치에 관심이 있다고 표시했기 때문에 메뉴 막대에 액세서리 아이콘이 나타났습니다 이제 액세서리 메뉴에서 디스크를 선택하겠습니다 앱에 연결하겠습니다

    이 드라이브를 가상 Mac에 연결했기 때문에 호스트에서 드라이브가 마운트 해제되고 게스트에서 마운트되었습니다 이제 가상 Mac 내부에서 드라이브를 안전하게 꺼내겠습니다

    그런 다음 액세서리 메뉴를 사용해 드라이브를 호스트에 반환하겠습니다

    드라이브를 호스트에 반환했으므로 호스트에서 드라이브가 다시 마운트되었습니다 이것이 Accessory Access를 통해 USB 액세서리를 쉽게 사용하는 방법입니다 가상 머신에서 바로 사용할 수 있습니다 Accessory Access를 사용하려면 앱이 매칭 기준과 함께 리스너를 등록합니다 관심 있는 장치 유형을 설명하는 기준입니다 장치 클래스와 서브클래스로 필터링할 수 있고 벤더 ID와 제품 ID 또는 다른 기준으로도 가능합니다 일치하는 장치가 Mac에 연결되면 Accessory Access 메뉴 확장이 나타납니다 여기서 사용자가 장치를 앱에 연결할지 결정할 수 있습니다 장치가 앱에 연결되면 앱의 리스너 객체가 새로 연결된 장치에 대한 알림을 받습니다 Accessory Access를 사용하려면 먼저 AAUSBAccessoryMatchingCriteria 객체의 배열을 생성합니다 관심 있는 장치 유형을 설명하는 배열입니다 빈 배열을 사용하면 모든 USB 장치에 관심이 있다고 표현할 수 있습니다 그런 다음 AAUSBAccessoryManager를 사용해 리스너를 등록합니다 이 리스너는 AAUSBAccessoryListener 프로토콜을 구현해야 합니다 registerListener는 이전에 연결된 액세서리를 반환합니다 애플리케이션에 이전에 연결되었던 액세서리들을요 누군가가 앱에 장치를 연결하면 리스너의 usbAccessoryDidConnect 함수가 호출됩니다 이 함수에서 장치를 가상 머신에 연결할 수 있습니다 VZVirtualMachine은 수정이 자체 큐에서 이루어져야 합니다 해당 큐에서 VZUSBPassthroughDeviceConfiguration 클래스를 사용하여 VZUSBPassthroughDevice를 생성하고 이 장치를 가상 머신의 USB 컨트롤러 중 하나에 연결할 수 있습니다

    앱에서 Accessory Access를 사용하려면 Xcode 타깃의 기능에 Claim USB Accessory 기능을 추가하세요 사용자는 언제든지 앱에서 장치를 연결하거나 분리할 수 있음을 기억하세요 앱은 이러한 이벤트를 적절히 처리해야 합니다 지원되는 장치 유형에 대한 자세한 내용은 Accessory Access 문서를 참조하세요

    macOS 26 이상에서는 앱이 vmnet 프레임워크를 사용해 가상 네트워크 인터페이스를 구성할 수 있습니다 Virtualization 프레임워크를 사용하면 격리된 가상 머신을 쉽게 구성할 수 있습니다 기본 NAT 또는 브리지 네트워킹으로 구성할 수 있습니다 하지만 더 고급 사용 사례에서는 더 많은 제어가 필요할 수 있습니다 VM들이 서로 또는 외부 네트워크와 상호작용하는 방식에 대한 제어입니다 예를 들어 서버 가상 머신에 대한 연결을 테스트하고 싶을 수 있습니다 같은 네트워크 또는 다른 네트워크의 클라이언트에서의 연결을요 vmnet 프레임워크를 사용하면 커스텀 네트워크 토폴로지를 만들어 이러한 고급 사용 사례를 지원할 수 있습니다 vmnet 프레임워크를 사용하면 macOS 및 Linux VM에 대한 커스텀 네트워크 토폴로지를 만들 수 있습니다 vmnet을 사용하면 VM들이 서로 통신하는 방식을 제어할 수 있습니다 vmnet은 또한 커스텀 네트워크의 다양한 매개변수를 구성할 수도 있습니다 예를 들어 네트워크의 DHCP 설정을 구성하거나 TCP 또는 UDP 호스트 포트를 전달하는 규칙을 추가하여 특정 가상 머신에 연결할 수 있습니다 Virtualization 프레임워크와 함께 vmnet을 사용하려면 먼저 vmnet 네트워크 구성 객체를 생성합니다 그 구성을 사용해 vmnet 네트워크 객체를 구성합니다 그런 다음 해당 네트워크 객체를 사용해 네트워크 장치 연결을 구성합니다 이 네트워크 장치 연결은 네트워크 장치 구성에 연결되고 이는 다시 가상 머신 구성에 추가됩니다 마지막으로 해당 가상 머신 구성을 사용하여 가상 머신을 구성합니다 두 번째 가상 머신도 같은 vmnet 네트워크를 사용하게 하려면 동일한 단계를 따라 두 번째 가상 머신을 구성하되 같은 vmnet 네트워크 객체를 사용해야 합니다 이제 코드에서 이 단계를 보여드리겠습니다 먼저 vmnet 구성 객체를 생성합니다 vmnet_network_configuration_create를 사용합니다 vmnet은 네트워크를 커스터마이징하는 여러 함수를 제공합니다 예를 들어 네트워크의 DHCP 설정을 구성하거나 포트 포워딩을 활성화할 수 있습니다 네트워크 구성 객체가 준비되면 vmnet_network_create를 사용해 vmnet 네트워크 객체를 구성할 수 있습니다 그런 다음 VZVmnetNetworkDeviceAttachment를 구성합니다 Virtualization이 방금 만든 vmnet 네트워크를 사용할 수 있도록 합니다

    다음으로 VZVirtioNetworkDeviceConfiguration 객체에 연결을 설정합니다 이 networkDeviceConfiguration은 networkDevices 배열에 추가됩니다 VZVirtualMachineConfiguration 객체의 배열에요 마지막으로 이 구성을 사용해 VZVirtualMachine을 구성합니다 vmnet 네트워크 객체는 참조 카운트 Objective-C 객체입니다 마지막 참조가 해제되면 네트워크가 사라집니다 이는 vmnet 네트워크가 앱이 종료될 때 지속되지 않음을 의미합니다 일관된 네트워크 구성을 만들려면 앱이 vmnet 설정을 직접 저장해야 합니다 vmnet은 vmnet_network_copy_serialization과 vmnet_network_create_with_serialization API를 제공합니다 이를 통해 vmnet 네트워크를 XPC 연결을 통해 한 프로세스에서 다른 프로세스로 전달할 수 있습니다 여러 VM을 별도의 프로세스에서 실행하면서 같은 네트워크에 연결하려는 경우에 유용합니다 하지만 같은 네트워크에 연결하고 싶을 때입니다

    다음으로 DiskImageKit을 사용해 디스크 이미지를 효율적으로 다루는 방법을 알아보겠습니다 Virtualization 프레임워크는 표준 raw 디스크 이미지 파일을 지원합니다 가상 머신 디스크의 백업으로 사용할 수 있습니다 이 간단한 형식은 디스크 블록을 파일 블록에 일대일로 매핑합니다 이 단순함 덕분에 기존 소프트웨어에서 널리 지원됩니다 하지만 이 단순함에는 대가가 따릅니다 Raw 디스크 이미지는 기본적으로 희소성을 표현할 수 없습니다 예를 들어 100기가바이트 디스크는 100기가바이트 파일로 표현됩니다 이로 인해 스냅샷도 비용이 많이 듭니다 VM 디스크를 스냅샷하려면 전체 디스크를 복사해야 합니다

    DiskImageKit은 macOS 27의 새 프레임워크로 디스크 이미지 관리를 더 효율적으로 만들기 위해 설계되었습니다 macOS 26에서 도입된 Apple Sparse Image Format 즉 ASIF를 지원합니다 DiskImageKit을 사용하면 이미지 스택을 구성할 수 있습니다 오버레이 레이어에 쓰기를 허용하면서 베이스 레이어는 수정하지 않습니다 DiskImageKit은 raw 디스크 이미지도 지원합니다 스택 이미지를 구성할 때 DiskImageKit은 몇 가지 다른 유형의 레이어를 지원합니다 스택 이미지의 맨 아래 레이어를 베이스 레이어라고 합니다 이 레이어는 DiskImageKit에서 지원하는 어떤 형식도 가능합니다 상위 레이어는 항상 ASIF 이미지입니다 이 레이어는 캐시 또는 오버레이 레이어일 수 있습니다 캐시 레이어는 성능을 향상하는 데 사용할 수 있습니다 하위 레이어가 느린 스토리지에 있을 때 원격 네트워크 파일시스템 같은 경우입니다 읽기 요청을 처리할 때 캐시 레이어가 읽기를 처리하지 못하면 DiskImageKit이 하위 레이어에서 읽기를 처리하지만 데이터 복사본을 캐시 레이어에 저장합니다 같은 데이터의 이후 읽기는 캐시에서 읽힙니다

    오버레이 레이어는 스냅샷에 대한 copy-on-write 시맨틱을 구현하는 데 사용됩니다 레이어드 이미지에 쓸 때 DiskImageKit이 스택을 탐색하는 중 쓰기 가능한 오버레이를 발견하면 해당 레이어에 쓰기를 저장합니다

    DiskImageKit은 읽기 전용 레이어를 여러 동시 스택에서 공유할 수 있게 합니다 이를 통해 공유 콘텐츠를 효율적으로 재사용할 수 있습니다 여러 가상 머신 간에 독립적인 쓰기를 분리하면서 가능합니다

    ASIF 이미지는 희소합니다 ASIF 이미지는 논리적으로 더 많은 블록을 표현할 수 있습니다 실제로 이미지에 저장된 블록보다 더 많이요 ASIF 파일에서 읽을 때 이미지에 저장되지 않은 블록은 0으로 채워진 것처럼 처리됩니다

    예제 스택에 대한 읽기 및 쓰기 요청을 DiskImageKit이 처리하는 방법을 단계별로 설명하겠습니다 이 예에서 베이스 레이어는 블록 0, 1, 4에 대한 콘텐츠가 있습니다 캐시 레이어에는 어떤 블록에 대한 콘텐츠도 없습니다 오버레이 레이어에는 블록 4에 대한 업데이트된 콘텐츠가 있고 블록 5에 대한 콘텐츠도 있습니다 레이어는 위 또는 아래 레이어와 다른 논리적 크기를 가질 수 있습니다 위나 아래 레이어와 다를 수 있습니다 블록 0 읽기를 처리하기 위해 DiskImageKit은 스택 이미지의 레이어를 탐색합니다 이 블록의 콘텐츠가 있는 레이어를 찾을 때까지요 이 읽기는 베이스 레이어에서 처리됩니다 캐시 레이어가 있었기 때문에 DiskImageKit은 이 블록의 내용을 캐시합니다 그런 다음 호출자에게 내용을 반환합니다 같은 블록의 이후 읽기는 캐시 레이어에서 처리됩니다

    블록 2를 쓸 때 DiskImageKit은 최상위 레이어가 오버레이임을 발견하고 콘텐츠를 거기에 저장합니다

    Virtualization과 함께 DiskImageKit 이미지를 사용하려면 먼저 DiskImage 객체를 생성합니다

    레이어드 이미지를 사용하려면 여러 DiskImage 객체를 만들고 순서대로 추가합니다 그런 다음 stackedImage로부터 VZDiskImageStorageDeviceAttachment를 구성합니다 stackedImage로부터요 이는 storageDeviceConfiguration에 연결될 수 있습니다 예를 들어 VZVirtioBlockDeviceConfiguration입니다 이 storageDeviceConfiguration을 추가합니다 가상 머신 구성의 storageDevices에요 마지막으로 이 구성을 사용해 VZVirtualMachine을 생성합니다

    스택 이미지를 사용할 때 얕은 스택이 더 나은 성능을 발휘한다는 점을 알아두세요 성능 비용이 있습니다 디스크 이미지 스택의 깊이를 늘리면 발생합니다 가상 머신이 디스크 이미지 이외의 것들로도 구성된다는 점을 명심하세요 예를 들어 가상 Mac에는 보조 스토리지 파일이 있고 EFI 부트 로더를 사용하는 VM에는 EFI 변수 저장소 파일이 있습니다 VM을 복제하고 공유 베이스 레이어를 사용하려는 경우 다른 파일들을 반드시 복제해야 한다는 것을 기억하세요

    마지막으로 커스텀 Virtio API가 어떻게 커스텀 통신 채널을 구축할 수 있는지 보여드리겠습니다 앱과 Linux 가상 머신 사이에서요

    Virtualization 프레임워크는 이미 광범위한 표준 장치 클래스를 지원하지만 일부 사용 사례에서는 더 특화된 것이 필요할 수 있습니다 호스트와 게스트 간의 성능에 민감한 통신을 위해 커스텀 프로토콜을 구현하고 싶을 수 있습니다 또는 Virtio 암호화 장치 같은 코프로세서를 구현할 수도 있습니다 머신 러닝 가속기에 대한 효율적인 게스트 접근을 제공하고 싶을 수도 있습니다 바로 그때 커스텀 Virtio 장치 API가 유용합니다 Virtio는 반가상화 장치를 위한 업계 표준입니다 Virtualization의 많은 내장 장치를 구현하는 데 사용되는 프로토콜입니다 macOS 27에서 Virtualization 프레임워크는 자체 Virtio 장치를 구현할 수 있게 합니다 호스트 앱과 Linux 가상 머신 간의 커스텀 통신을 허용합니다 이는 특히 성능에 민감한 시나리오에 유용합니다 낮은 지연 시간과 높은 처리량의 통신이 필요한 경우입니다

    Virtio 프로토콜은 메모리 버퍼를 활용합니다 게스트와 호스트 간에 공유됩니다 이 버퍼는 Virtio 큐로 구성됩니다 Virtio는 게스트와 호스트 간의 컨텍스트 전환 횟수를 최소화하도록 설계되었습니다 게스트의 장치 드라이버는 데이터가 큐에 추가될 때 호스트에서 실행 중인 장치에 알립니다 마찬가지로 호스트는 인터럽트를 사용하여 큐에 추가된 데이터에 대해 게스트 드라이버에 알릴 수 있습니다

    macOS 27에서 VZCustomVirtioDevice 클래스를 사용해 커스텀 장치를 구현할 수 있습니다 앱은 장치에 델리게이트를 설정합니다 이 델리게이트는 게스트가 큐에 데이터를 추가할 때 알림을 받습니다 장치에 인터럽트를 트리거하여 게스트에서 활동을 시작할 수도 있습니다 커스텀 Virtio 장치 API를 사용하려면 먼저 VZCustomVirtioDeviceConfiguration 객체를 생성합니다 장치의 Virtio 장치 정체성으로 이 객체를 구성합니다 PCI 클래스와 서브클래스 그리고 장치가 사용하는 Virtio 큐 수를 설정합니다

    구성에 프로바이더도 설정합니다 VZCustomVirtioDeviceDelegateProvider는 델리게이트를 구성하는 데 사용됩니다 VZCustomVirtioDevice- ConfigurationDelegate 프로토콜을 구현하는 델리게이트입니다 그런 다음 이 deviceConfiguration을 virtualMachineConfiguration의 customVirtioDevices 배열에 추가하고 해당 구성을 사용해 VZVirtualMachine을 생성합니다

    가상 머신이 시작되면 VZCustomVirtioDevice 객체가 생성됩니다 구성 델리게이트의 didCreateDevice 함수가 호출됩니다 이 함수에서 장치의 델리게이트를 설정해야 합니다 이 델리게이트는 VZCustomVirtioDeviceDelegate 프로토콜을 구현해야 합니다 장치 자체를 보관해 둘 수도 있습니다 장치가 게스트 인터럽트를 트리거할 수 있도록요

    VZCustomVirtioDeviceDelegate 프로토콜에는 여러 함수가 있습니다 장치의 수명 주기를 모니터링하고 장치와 상호작용하는 데 사용됩니다 didReceiveNotificationFor 함수에서 로직을 구현합니다 장치의 큐에서 요소를 꺼내고 요소를 처리한 다음 큐에 반환합니다

    커스텀 장치에는 커스텀 드라이버가 필요합니다 게스트가 장치를 사용할 수 있도록 합니다 Virtio 큐는 효율적인 통신을 제공하도록 설계되었습니다 게스트와 호스트 간의 통신입니다 게스트 드라이버를 설계할 때 모범 사례를 따라 Virtio 큐를 최적으로 활용하세요 마무리 전에 Virtualization의 몇 가지 다른 발전 사항을 간략히 언급하겠습니다 앱을 더욱 빛나게 할 수 있는 기능들입니다

    iCloud 지원은 데스크탑 환경에서 특히 유용합니다 VM에서 iCloud 데이터 및 서비스에 접근할 수 있습니다 EFI Secure Boot는 최신 보안 기능으로 Linux VM을 강화합니다 macOS 게스트는 Metal의 인수 버퍼 같은 기능을 활용할 수 있습니다 그리고 간접 커맨드 버퍼도 사용할 수 있습니다

    이제 더 많은 기능을 추가할 준비가 됐습니다 Virtualization 앱에요 프로비저닝 옵션으로 구성하여 macOS 사용자 계정 설정을 자동화하세요 프로비저닝 옵션으로 구성합니다 Accessory Access 프레임워크를 사용해 USB 장치를 VM에 연결하세요 자체 네트워크 토폴로지를 구축하여 VM 네트워킹을 커스터마이징하고 포트 포워딩을 구성하세요 DiskImageKit 프레임워크를 사용해 효율적인 희소 디스크 이미지를 만드세요 Linux 게스트에서 커스텀 고성능 장치가 필요한 경우 Virtio로 커스텀 장치 생성을 고려해 보세요

    시청해 주셔서 감사합니다! 즐거운 WWDC 되세요

    • 1:57 - Provision a macOS guest

      import Virtualization
      
      let provisioningOptions = VZMacGuestProvisioningOptions()
      provisioningOptions.fullName = fullName
      provisioningOptions.username = username
      provisioningOptions.password = password
      provisioningOptions.logsInAutomatically = true
      provisioningOptions.enablesRemoteLogin = true
      
      let startOptions = VZMacOSVirtualMachineStartOptions()
      try startOptions.setGuestProvisioning(provisioningOptions)
      
      try await virtualMachine.start(options: startOptions)
    • 7:12 - Register an Accessory Access listener

      import AccessoryAccess
      
      let criteria: [AAUSBAccessoryMatchingCriteria] = []
      let accessories = try await AAUSBAccessoryManager.shared.registerListener(self, matchingCriteria: criteria)
      
      for accessory in accessories {
          // Handle previously attached accessories.
      }
    • 7:39 - Respond to USB accessory connection

      import AccessoryAccess
      import Virtualization
      
      class AccessoryListener: NSObject, AAUSBAccessoryListener {
          func usbAccessoryDidConnect(_ usbAccessory: AAUSBAccessory) {
              virtualMachine.queue.async {
                  do {
                      let configuration = VZUSBPassthroughDeviceConfiguration(device: usbAccessory)
                      let device = try VZUSBPassthroughDevice(configuration: configuration)
                      self.virtualMachine.usbControllers.first?.attach(device: device) { error in
                          // Handle error if necessary...
                      }
                  } catch {
                      // Handle error...
                  }
              }
          }
      }
    • 10:04 - Create a custom vmnet network

      import Virtualization
      import vmnet
      
      var status: vmnet_return_t = .VMNET_FAILURE
      guard let networkConfiguration =
          vmnet_network_configuration_create(.VMNET_SHARED_MODE, &status) else { ... }
      
      guard let network =
          vmnet_network_create(networkConfiguration, &status) else { ... }
      
      let attachment = VZVmnetNetworkDeviceAttachment(network: network)
      
      let networkDeviceConfiguration = VZVirtioNetworkDeviceConfiguration()
      networkDeviceConfiguration.attachment = attachment
      
      virtualMachineConfiguration.networkDevices = [networkDeviceConfiguration]
      
      let virtualMachine = VZVirtualMachine(configuration: virtualMachineConfiguration)
    • 14:54 - Use DiskImageKit with Virtualization

      import DiskImageKit
      import Virtualization
      
      let baseImage = try DiskImage(opening: .open(url: baseLayerURL, mode: .readOnly))
      let cacheImage = try baseImage.appending(.asifLayer(url: cacheLayerURL, type: .cache))
      let overlayImage = try DiskImage(opening: .open(url: overlayLayerURL))
      let stackedImage = try cacheImage.appending(overlayImage)
      
      let storageDeviceAttachment = try VZDiskImageStorageDeviceAttachment(diskImage: stackedImage)
      
      let storageDeviceConfiguration =
          VZVirtioBlockDeviceConfiguration(attachment: storageDeviceAttachment)
      
      virtualMachineConfiguration.storageDevices = [storageDeviceConfiguration]
      
      let virtualMachine = VZVirtualMachine(configuration: virtualMachineConfiguration)
    • 17:41 - Configure a custom Virtio device

      import Virtualization
      
      let deviceConfiguration = VZCustomVirtioDeviceConfiguration()
      
      // Virtio entropy device.
      deviceConfiguration.deviceID = 4
      // PCI class for crypto devices.
      deviceConfiguration.pciClassID = 0x10
      // PCI subclass for network and computing encryption controllers.
      deviceConfiguration.pciSubclassID = 0x00
      // An entropy device uses a single Virtio queue.
      deviceConfiguration.virtioQueueCount = 1
      
      deviceConfiguration.provider =
          VZCustomVirtioDeviceDelegateProvider(deviceQueue: deviceQueue, delegate: provider)
      
      virtualMachineConfiguration.customVirtioDevices = [deviceConfiguration]
      
      let virtualMachine = VZVirtualMachine(configuration: virtualMachineConfiguration)
    • 18:20 - Attach a delegate to a VZCustomVirtioDevice

      import Virtualization
      
      class DeviceConfigurationDelegate: NSObject, VZCustomVirtioDeviceConfigurationDelegate {
          func customVirtioConfiguration(_ deviceConfiguration: VZCustomVirtioDeviceConfiguration,
                                         didCreateDevice device: VZCustomVirtioDevice) {
              device.delegate = deviceDelegate
              self.device = device
          }
      }
    • 18:42 - Process Virtio queue elements

      import Virtualization
      
      class DeviceDelegate: NSObject, VZCustomVirtioDeviceDelegate {
          func customVirtioDevice(_ device: VZCustomVirtioDevice,
                                  didReceiveNotificationFor queue: VZVirtioQueue) {
              while let element = queue.nextElement() {
                  // Process element...
                  element.returnToQueue()
              }
          }
      }
    • 0:01 - Introduction
    • The advanced Virtualization capabilities ahead — automating Virtual Mac setup, attaching USB devices with the Accessory Access framework, configuring advanced networking, creating disk images with DiskImageKit, and building custom Virtio devices.

    • 1:04 - macOS guest provisioning
    • Automate the provisioning of user accounts in Setup Assistant for virtual Macs. Use the VZMacGuestProvisioningOptions API to set credentials and enable features like auto-login and SSH on first boot.

    • 4:34 - Accessory Access
    • Pass through USB accessories directly into virtual machines using the Accessory Access framework. This approach gives people explicit control over which physical devices, such as external drives, are passed through to the virtual machine.

    • 8:26 - Advanced network topologies
    • Configure complex network topologies by integrating the vmnet framework with Virtualization. You can create custom network architectures that define exactly how multiple virtual machines interact with each other and the host.

    • 11:35 - DiskImageKit
    • DiskImageKit is a new framework in macOS 27 designed for managing high-performance, space-efficient disk images. You can use layered disk images, including base layers, cache layers, and overlay layers, to share data efficiently across multiple virtual machines.

    • 15:57 - Custom Virtio
    • Define and implement custom paravirtualized devices using the industry-standard Virtio protocol. By using the VZCustomVirtioDevice API, you can enable specialized, high-performance communication between the host and custom drivers running in the virtual machine.

Developer Footer

  • 비디오
  • WWDC26
  • 가상화 앱의 기능 확장하기
  • 메뉴 열기 메뉴 닫기
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    메뉴 열기 메뉴 닫기
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • SF Symbols
    메뉴 열기 메뉴 닫기
    • 손쉬운 사용
    • 액세서리
    • Apple Intelligence
    • 앱 확장 프로그램
    • App Store
    • 오디오 및 비디오(영문)
    • 증강 현실
    • 디자인
    • 배포
    • 교육
    • 서체(영문)
    • 게임
    • 건강 및 피트니스
    • 앱 내 구입
    • 현지화
    • 지도 및 위치
    • 머신 러닝 및 AI
    • 오픈 소스(영문)
    • 보안
    • Safari 및 웹(영문)
    메뉴 열기 메뉴 닫기
    • 문서(영문)
    • 튜토리얼
    • 다운로드
    • 포럼(영문)
    • 비디오
    메뉴 열기 메뉴 닫기
    • 지원 문서
    • 문의하기
    • 버그 보고
    • 시스템 상태(영문)
    메뉴 열기 메뉴 닫기
    • Apple Developer
    • App Store Connect
    • 인증서, 식별자 및 프로파일(영문)
    • 피드백 지원
    메뉴 열기 메뉴 닫기
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program(영문)
    • Mini Apps Partner Program
    • News Partner Program(영문)
    • Video Partner Program(영문)
    • Security Bounty Program(영문)
    • Security Research Device Program(영문)
    메뉴 열기 메뉴 닫기
    • Apple과의 만남
    • Apple Developer Center
    • App Store 어워드(영문)
    • Apple 디자인 어워드
    • Apple Developer Academy(영문)
    • WWDC
    최신 뉴스 읽기.
    Apple Developer 앱 받기.
    Copyright © 2026 Apple Inc. 모든 권리 보유.
    약관 개인정보 처리방침 계약 및 지침