오랜만에 Windows Kernel에 대한 블로그가 올라와서 정리를 해 보았습니다.

One Windows Kernel

https://techcommunity.microsoft.com/t5/Windows-Kernel-Internals/One-Windows-Kernel/ba-p/267142


Windows는 x86, x64, ARM, ARM64를 지원하고 예전에는 Itanium, PowerPC, DEC Alpha, MIPS를 지원할 정도로 다양한 하드웨어를 지원하고 Data center, Laptop, xbox, phone, IOT device를 지원할 정도로 다양한 SKU를 가지고 있습니다.

아래 이미지는 896 코어에 1792 개의 logical processor와 2TB RAM을 지원하는 Windows DataCenter 버전의 작업 관리자 이미지 입니다. (저도 이렇게 큰 장비를 본 적은 없습니다. 대형 장비 이지만 Windows 10을 쓰는 방법과 거의 유사하게 시스템을 관리할 수 있어 금방 적응할 수 있습니다.)

TaskMgr.png


Windows refactoring 에 대해서 먼저 이야기 하고 있습니다. 다양한 SKU의 Windows을 동일한 DLL로 지원을 하지만 일부 코드를 다르게 구현할 수 있도록 API set (https://docs.microsoft.com/en-us/windows/desktop/apiindex/windows-apisets) 이라는 것을 만들었습니다. 예를 들면 kernel32.dll을 그대로 사용하면서 실제 구현은 다른 DLL에 되어 있는 것입니다. (저도 API set을 자세히 분석해 본 적은 아직 없어서 자세한 내용은 나중에 정리해 봐야 할것 같습니다.)


Kernel Components

Windows NT는 마이크로 커널 유형으로 되어 있습니다. (완전한 마이크로 커널은 아닙니다.) 코어 커널 모듈이 있고 실행부라는 영역이 커널에 존재 합니다. 커널은 스레드 디스패칭, 멀티프로세서 동기화, 하드웨어 예외 핸들링 등을 처리 하고 실행부에서는 IO, 객체 관리, 메모리 관리, 프로세스 서브 시스템 등을 담당합니다.

arch.png


윈도우 컴포넌트의 크기를 코드수로 보면 아래와 같습니다. 역시 메모리가 가장 많은 코드를 가지고 있고 커널 순으로 이어집니다. 좀 더 자세한 내용을 학고 싶으면 Windows Internals 책을 구입해서 읽어보면 됩니다. 

Kernel subsystems

Lines of code

Memory Manager

501, 000

Registry

211,000

Power

238,000

Executive

157,000

Security

135,000

Kernel

339,000

Process sub-system

116,000


Scheduler

스레드는 프로그램 코드가 실행되는 가장 기본 유닛으로 Windows 스케줄러가 스케줄 합니다. 윈도우 스케줄러는 스레드 우선순위에 따라서 높은 우선순위를 가진 스레드 부터 스케줄링 합니다. 스레드는 주어진 시간 (Quantum time) 동안 실행되고 다음 스레드가 실행됩니다. 만약 높은 우선순위를 가지고 있는 스레드가 계속 실행되고 있어서 낮은 우선 순위를 가지는 스레드가 실행될 기회를 얻지 못한다면 낮은 우선순위를 가진 스레드의 우선순위가 올라가게 됩니다. 

최초에 Windows 스케줄러는 하나의 레디큐를 가지고 있었습니다. 하지만 많은 프로세서를 지원하기 시작하면서 하나의 레디큐가 병목현상을 보이게 되었고 Windows Server 2003 에서 프로세서마다 하나의 레디큐를 가지게 디자인이 변경 되었습니다. 하나의 레디큐를 사용하면서 발생했던 글로벌 락 문제가 사라졌습니다. 가장 높은 우선순위를 가지는 스레드가 실행되는 것은 보장할 수 있지만 N 개의 core를 가지는 시스템에서 최대 N 개의 높은 우선순위를 가지는 스레드가 실행된다고 말 할 수는 없습니다. (현재 실행되는 스레드보다 높은 스레드가 다른 코어에 대기 상태로 있을 수 있습니다.) Windows가 laptop 이나 태블릿 같은 CPU 파워가 낮은 시스템에 적용되면서 UI가 느려지는 현상등이 발생하게 되었습니다. 그래서 Windows 8.1 에서 스케줄러가 프로세서당 레디큐를 가지는 것과 프로세서간 공유하는 레디큐를 가지는 하디브리드 형태로 변경 되었습니다. 다른 아키텍처의 변경이 있었기 때문에 스케줄로 변경으로 인한 성능 향상이 크게 보이지는 않았습니다.

Windows 7 에서 동적인 공정 공유 스케줄러 (Dynamic Fair Share Scheduler)가 도입되었습니다. 이 기능은 터미널 서버를 위해서 도입되었습니다. 하나의 터미널 세션이 과도한 CPU 자원을 사용해서 다른 터미널 세션에 영향을 주는 것을 방지하기 위해 도입 되었습니다. 기존의 스케줄링은 세션을 고려하지 않고 스레드 우선순위만 고려해서 스케줄링 했는데 이 기능이 도입 되어 다른 세션에 영향을 주지 않게 되었습니다. Linux의 Completely Fair Scheduler와 유사한 것 입니다. Windows 8 에서 이 개념이 스케줄러 그룹으로 일반화 되었고 각 세션마다 윈도우 스케줄러가 사용됩니다. 스케줄러 그룹은 스레드 우선순위에서도 2차 인덱스 역할을 해서 어떤 스레드가 다음에 실행될지를 결정 합니다. 터미널 세션에서 모든 스케줄러 그룹은 동일한 양의 스케줄링을 받게 됩니다. 그리고 Job 오브젝트가 향상되어 CPU rate control (https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-_jobobject_cpu_rate_control_information) 기능을 지원하게되어 프로세스가 사용할 수 있는 CPU 양의 hard cap과 soft cap을 제한할수 있습니다. 이 기능은 리눅스의 cgroups 과 유사 합니다.

Windows 7 이후 부터 Windows 서버는 64개 이상의 프로세서를 지원하게 됩니다. 많은 프로세서를 지원하기 위해 프로세서 그룹 이라는 개념이 도입되었습니다. 프로세서 그룹은 최대 64개 까지의 프로세서를 하나의 그룹으로 묶어서 하나의 스케줄링 단위로 만드는 것으로 부팅하는 시점에 커널에서 어떤 프로세서가 어떤 그룹에 설정될지를 결정 합니다. (64개 이하의 코어를 가질 경우 프로세서 그룹은 적합하지 않습니다.) 단일 프로세스 (SQL Server)는 프로세서 그룹에 확장될 수 있으나 개별 스레드는 하나의스케줄링 그룹에서만 실행될 수 있습니다. (응용 프로그램이 프로세서 그룹이나 NUMA에 적합하지 않을 경우 BIOS에서 프로세서를 하나의 그룹으로 인식 시킬 수 있습니다.)

64개 이상의 코어를 가지는 시스템에서 코어 수를 늘렸을 때 SQL server와 같은 제품에서 성능 향상이 많이 일어나지 않는 것이 확인 되었습니다. 코어 수가 늘어나면 디스패처 락 문제 때문에 성능 향상에 문제가 있는 것이 확인 되었습니다. 디스패처 락은 디스패치가 되는 오브젝트를 보호하는 락으로 스레드, 타이머, I/O 완료 포트, 동기화 객체 등을 보호 합니다. Windows 7 에서 디스패처 락을 제거하고 객체 별 락을 도입하였고 290%의 성능 향상을 보였습니다. 

Windows 10 (Windows Server 2016)에서는 CPU Sets이 추가 되었습니다. CPU Set은 프로세스가 시스템을 나눠서 프로세스가 특정 프로세서 그룹을 사용할 수 있게하고 다른 프로세스나 시스템이 할당된 프로세서 그룹을 사용하지 못하게 하는 것 입니다. 프로세서가 CPU set으로 설정되면 디바이스의 코드도 실행되지 않습니다. Windows 10의 Game Mode가 이 기능을 사용한다고 합니다. (https://www.windowscentral.com/windows-10-game-mode)

그 외에도 ARM 관련 내용이 일부 있습니다. 

Scheduler 라는 것이 일반 사용자나 개발자 모두에게 잘 보여지지 않는 내용인데 블로그를 통해서 간단하게나마 소개가 되었습니다. 하지만 깊이 있는 내용은 문서를 찾기 힘들고 이해 하기가 힘들기 때문에 이정도에서 마무리 하려고 합니다.






Windows Server 2019에 해당하는 Windows Server 2019 Insider Preview Build 17639가 공개 되었습니다.

이번에 공개된 것은 10년 기술지원을 받을 수 있는 LTSC 릴리즈이고 GUI를 이용하는 Desktop Experience와 Server Core 버전 입니다. (Nano server는 SAC 릴리즈만 제공됩니다.)


In-place upgrades

Windows Server 2012 R2와 2016에서 Windows Server 2019로 In-place upgrade를 지원 합니다.


Storage Migration Service

Windows Server에서는 데이터 마이그레이션 기능이 취약했었는데 Windows Server 2019에서 Storage Migration Service(SMS) 라는 롤이 추가 되었습니다. 기존 서버에서 데이터, 보안 설정, 네트워크 설정 등을 SMB 프로토콜을 사용해서 마이그레이션하는 기능으로 호놀룰루 기반의 그래픽 관리 시스템으로 되어 있습니다.


Storage Replica

Windows Server 2016 Datacenter 에서만 가능하던 Storage Replica 기능이 사용자들의 꾸준한 요청으로 Standard에서도 사용할 수 있게 되었습니다. Standard에서는 하나의 볼륨만 최대 2TB 까지 복제가 가능 합니다. 계속 요청을 등록하여 Storage Space Direct도 Standard에서 사용할 수 있게 되었으면 합니다.


참고) https://blogs.windows.com/windowsexperience/2018/04/10/announcing-windows-server-2019-insider-preview-build-17639/amp/?__twitter_impression=true


Windows Server 2003이 EOS 된 후 Technet 과 MSDN에 유지되던 이전 Windows 관련 문서들이 언젠가부터 사이트에서 사라지고 PDF 파일로 받게 변경되었었습니다. 문제는 PDF 파일이 엄청 커서 웹에서 보는 것 만큼 편하게 보기 힘들다는 것이었고 마이크로소프트의 정책 변경에 아쉬워했던 것이 사실 입니다.

Windows 문서의 경우 Windows 2000, 2003 에서 개발되어 해당 버전의 문서에서 내부 인터널한 내용을 많이 다룬 모듈들은 더 이상 새로운 버전의 문서에서 인터널한 내용을 다루지 않고 새로 추가된 기능만 설명하기 때문에 이전 버전의 문서를 손쉽게 검색해서 볼 수 없다는 것에 아쉬움이 많았습니다.


하지만 어제 마이크로소프트 PM인 Ned 의 트위터 좋은 소식이 들려 왔습니다.

Windows previous versions documentation

https://docs.microsoft.com/en-us/previous-versions/windows/


자그마치 Windows 2000 부터 문서가 등록되어 있습니다. 



Windows Team에서 Linux VM에 대한 지원을 향상시키고 있는 것으로 보입니다. 최근 Hyper-V를 서버로서 사용하는 시나리오보다 워크 스테이션으로 사용하여 개발자들의 개발 환경으로 선택 되게 하려는 움직임이 많이 보입니다.

이번에 가상화 팀에서 나온 블로그를 보면 Windows에서 RDP로 접속을 하거나 Enhanced mode 로 접속을 한 경우 Copy & Paste를 자유롭게 사용할 수 있는 기능을 Linux VM에도 적용하는 것으로 보입니다.

직접 개발한 것은 아닌 것으로 보이며 Microsoft의 RDP 프로토콜을 Linux에서 구현해주는 XRDP open source를 사용하여 Canonical과 함께 Ubuntu 18.04에 적용하는 것을 목표로 하고 있는 것으로 보입니다. 18.04에 기능을 넣기 전에 16.04에 설치해서 (Bug는 아직 있다고 합니다.) 미리 살펴볼 수 있다고 합니다. (Windows Insider Build 17063 을 사용해야 합니다.)


설치 방법은 Ubuntu 16.04를 설치한 후 아래 명령을 실행하면 됩니다.

#Get the scripts from GitHub
$ sudo apt-get update
$ sudo apt install git
$ git clone https://github.com/jterry75/xrdp-init.git ~/xrdp-init
$ cd ~/xrdp-init/ubuntu/16.04/

#Make the scripts executable and run them...
$ sudo chmod +x install.sh
$ sudo chmod +x config-user.sh
$ sudo ./install.sh


재부팅이 완료된 후 아래 명령을 다시 실행 합니다.

$ sudo ./config-user.sh


VM을 종료 한 후 PowerShell을 실행해서 RDP 관련 설정을 합니다.

Set-VM -VMName <your_vm_name>  -EnhancedSessionTransportType HvSocket


Linux VM을 실행한 후 Hyper-V connect를 통해서 연결을 하면 아래 기능들을 사용할 수 있습니다.

  • 향상된 마우스 기능
  • 클립보드 통합
  • 윈도우 크기 변경
  • 드라이브 리디렉션

이 기능에는 Hyper-V socket 이라는 것이 사용되는데 host 파티션과 guest VM 사이에 바이트 스트림 기반의 통신이 가능하게 해줍니다. TCP와 비슷한 것인데 VMBus를 사용하여 빠르게 VM과 Host 사이에 통신을 할 수 있게 됩니다.


참고 : https://blogs.technet.microsoft.com/virtualization/2018/02/28/sneak-peek-taking-a-spin-with-enhanced-linux-vms/

Windows Failover Cluster를 관리 하다보면 Domain과 너무 강하게 연결 되어 있다는 것을 알 수 있습니다. Windows Server 2016 이전에는 Failover Cluster를 구축할 때 Active Directory Domain이 꼭 필요 했었기 때문에 단순이 SQL Server Cluster를 만들기 위해서 Active Directory 서버가 필요했습니다. 그리고 Active Directory가 잘 관리 되지 않으면 Failover Cluster의 인증 문제나 Network Name 리소스에 문제가 생기기도 하였습니다.

Windows Server 2016 부터는 Multi-Cluster, Workgroup Cluster 가 나오면서 이 문제가 많이 해결되었습니다.

Windows Server, version 1709에서는 더 새로운 기능이 추가되었는데 Failover Cluster를 다른 도메인으로 이동할 수 있는 기능 입니다. Active Directory와 Failover Cluster 관계를 살펴 보면 Cluster 이름이 CNO라는 것으로 Active Directory에 등록되어 있고 각 리소스의 Network Name Resource가 VCO라는 것으로 Active Directory에 등록되어 있는 것입니다. CNO, VCO 그리고 각 노드의 Computer Object 들이 각각 권한 설정이 되어 있습니다.

Windows Server, version 1709에서는 아래 방법으로 Domain을 이동할 수 있습니다.

환경 : 모든 노드가 Windows Server, version 1709 Failover Cluster

        FS-CLUSTER 라는 파일 서버가 리소스로 등록되어 있습니다.


1. 모든 Cluster Network Name 리소스를 Offline으로 만듭니다.

2. Cluster 타입을 Workgroup으로 만듭니다.

   Remove-ClusterNameAccount -Cluster MyCluster -DeleteComputerAccounts

3. Active Directory Users and Computers 에서 CNO와 VCO가 삭제된 것을 확인합니다.

4. Cluster 서비스를 중지하고 시작 유형을 변경 합니다.

   Stop-Service -Name ClusSvc

   Set-Service -Name ClusSvc -StartupType Manual

5. Failover Cluster 노드를 Workgroup으로 변경한 후 다시 새로운 Domain에 join 합니다.

6. Cluster 서비스를 다시 시작하고 시작 유형을 변경합니다.

   Start-Service -Name ClusSvc

   Set-Service -Name ClusSvc -StartupType Automatic

7. Cluster 이름과  Network Name 리소스를 Online 시킵니다.

   Start-ClusterGroup -Name "Cluster Group"

   Start-ClusterResource -Name FS-Clus

8. 새로운 Domain에 등록 합니다. (Network Name 리소스는 꼭 Online 상태이어야 합니다.)

   New-ClusterNameAccount -Name MyCluster-Domain NewDomain.com -UpgradeVCOs

9. 새로운 도메인의 Active Directory Users and Computers 에서 새로 생성된 CNO, VCO를 확인합니다.

10. 파일 서버 리소스를 시작 합니다.

   Start-ClusterGroup -Name FS-Cluster


기업 환경에서는 Windows Server, version 1709를 아직은 적용하지 못할 것이기 때문에 이 기능을 사용할 수 없겠지만 Windows Server의 기능들이 빠르게 변화하고 있는 것을 확인할 수 있었습니다.


감사합니다.

+ Recent posts