편집

다음을 통해 공유


다중 테넌트 컨트롤 플레인에 대한 고려 사항

Azure

다중 테넌트 솔루션에는 여러 평면이 있으며 각 평면에는 고유한 책임이 있습니다. 데이터 평면 을 사용하면 최종 사용자 및 클라이언트가 시스템과 상호 작용할 수 있습니다. 컨트롤 플레인은 플랫폼 관리자의 작업을 지원하기 위해 액세스 제어, 프로비전 및 시스템 유지 관리와 같은 모든 테넌트에서 상위 수준 작업을 관리하는 구성 요소입니다.

이 문서에서는 컨트롤 플레인의 책임 및 요구 사항에 맞는 컨트롤 플레인을 디자인하는 방법에 대한 정보를 제공합니다.

논리적 시스템 디자인을 보여 주는 다이어그램 단일 컨트롤 플레인은 여러 테넌트별 데이터 평면에서 관리를 제공합니다.

예를 들어 재무 레코드를 관리하기 위한 부기 시스템을 고려해 보세요. 여러 테넌트가 시스템에 재무 기록을 저장합니다. 최종 사용자가 시스템에 액세스하여 재무 기록을 보고 입력하면 데이터 평면을 사용합니다. 데이터 평면은 솔루션의 기본 애플리케이션 구성 요소일 가능성이 높습니다. 테넌트는 아마도 의도한 목적을 위해 시스템을 사용하는 방법으로 생각할 것입니다. 반면, 컨트롤 플레인은 새 테넌트를 온보딩하고, 각 테넌트에 대한 데이터베이스를 만들고, 다른 관리 및 유지 관리 작업을 수행하는 구성 요소입니다. 시스템에 컨트롤 플레인이 없는 경우 관리자는 많은 수동 프로세스를 실행해야 합니다. 또는 데이터 평면과 컨트롤 플레인 작업이 함께 혼합되어 솔루션을 과도하게 컴파일합니다.

많은 복잡한 시스템에는 컨트롤 플레인이 포함됩니다. 예를 들어 Azure 컨트롤 플레인 Azure Resource Manager는 Azure 리소스 배포 및 구성을 담당하는 API, 도구 및 백 엔드 구성 요소 집합입니다. Kubernetes 컨트롤 플레인작업자 노드에 Kubernetes Pod를 배치하는 것과 같은 많은 작업을 관리합니다. 거의 모든 SaaS(Software as a Service) 솔루션에는 테넌트 간 작업을 처리하는 컨트롤 플레인이 있습니다.

다중 테넌트 솔루션을 디자인할 때는 컨트롤 플레인을 고려해야 합니다. 다음 섹션에서는 컨트롤 플레인의 범위를 지정하고 디자인하는 데 필요한 세부 정보를 제공합니다.

컨트롤 플레인의 책임

컨트롤 플레인 또는 해당 책임에 대한 템플릿은 하나도 없습니다. 솔루션의 요구 사항 및 아키텍처는 컨트롤 플레인에서 수행해야 하는 작업을 결정합니다. 일부 다중 테넌트 솔루션에서 컨트롤 플레인은 광범위한 책임을 가지며 그 자체로 복잡한 시스템입니다. 다른 다중 테넌트 솔루션에서 컨트롤 플레인에는 기본적인 책임만 있습니다.

일반적으로 컨트롤 플레인에는 다음과 같은 많은 핵심 책임이 있을 수 있습니다.

  • 리소스 관리: 테넌트별 리소스를 포함하여 시스템에서 워크로드를 처리하는 데 필요한 시스템 리소스를 프로비전하고 관리합니다. 컨트롤 플레인 은 배포를 담당하는 배포 파이프라인 을 호출하고 오케스트레이션하거나 배포 작업 자체를 실행할 수 있습니다.
  • 리소스 구성: 새 테넌트에 대해 인식하도록 공유 리소스를 다시 구성합니다. 예를 들어 컨트롤 플레인은 들어오는 트래픽이 올바른 테넌트의 리소스에 매핑되도록 네트워크 라우팅을 구성하거나 리소스 용량을 조정해야 할 수 있습니다.
  • 테넌트 구성: 각 테넌트 구성을 저장하고 관리합니다.
  • 테넌트 수명 주기 관리: 테넌트 온보딩, 이동 및 오프보딩을 포함하여 테넌트 수명 주기 이벤트를 처리합니다.
  • 원격 분석: 각 테넌트의 기능 사용 및 시스템 성능을 추적합니다.
  • 소비량 추적: 각 테넌트의 시스템 리소스 소비 량을 측정합니다. 소비 메트릭은 청구 시스템에 알리거나 리소스 거버넌스에 사용될 수 있습니다.

완전 다중 테넌트 테넌트 모델을 사용하고 테넌트별 리소스를 배포하지 않는 경우 기본 컨트롤 플레인은 테넌트 및 관련 메타데이터만 추적할 수 있습니다. 예를 들어 새 테넌트가 서비스에 등록할 때마다 컨트롤 플레인은 데이터베이스의 적절한 레코드를 업데이트하여 나머지 시스템이 새 테넌트의 요청을 처리할 수 있도록 할 수 있습니다.

반면, 솔루션이 자동화된 단일 테넌트 모델과 같은 테넌트별 인프라가 필요한 배포 모델을 사용한다고 가정합니다. 이 시나리오에서 컨트롤 플레인은 새 테넌트를 온보딩할 때마다 Azure 인프라 배포 또는 재구성과 같은 더 많은 책임이 있을 수 있습니다. 이러한 종류의 솔루션에서 컨트롤 플레인은 Azure Resource Manager 또는 Kubernetes 컨트롤 플레인과 같이 사용하는 서비스 및 기술에 대한 컨트롤 플레인과 상호 작용해야 할 수 있습니다.

고급 제어 평면은 더 많은 책임을 맡을 수도 있습니다.

  • 자동화된 유지 관리 작업 수행: 일반적인 유지 관리 작업에는 이전 데이터 삭제 또는 보관, 데이터베이스 인덱스 만들기 및 관리, 비밀 및 암호화 인증서 회전이 포함됩니다.
  • 테넌트 배치: 기존 배포 또는 스탬프에 테넌트를 할당합니다. 스탬프 사용률 목표, 테넌트 요구 사항 및 bin 압축 전략을 비롯한 다양한 조건을 기반으로 할 수 있습니다.
  • 테넌트 리밸런싱: 사용률이 변경됨에 따라 배포 스탬프 간에 기존 테넌트 균형을 조정합니다.
  • 고객 활동 추적: Microsoft Dynamics 365와 같은 외부 고객 관리 솔루션과 통합하여 고객 활동을 추적합니다.

컨트롤 플레인 범위 지정

솔루션에 대한 컨트롤 플레인을 빌드하는 데 얼마나 많은 노력을 기울여야 하는지 신중하게 고려해야 합니다. 컨트롤 플레인 자체는 즉각적인 고객 가치를 제공하지 않으므로 고품질 컨트롤 플레인을 설계하고 빌드하는 데 필요한 엔지니어링 노력을 정당화하기가 쉽지 않을 수 있습니다. 그러나 시스템이 성장하고 확장됨에 따라 성장을 따라잡기 위해 자동화된 관리 및 운영이 점점 더 필요합니다.

특정 상황에서는 모든 제어 평면이 필요하지 않을 수 있습니다. 시스템에 약 5-10개 미만의 테넌트가 있는 경우 이 상황이 적용될 수 있습니다. 대신 팀은 제어 평면의 책임을 맡을 수 있으며 수동 작업 및 프로세스를 사용하여 테넌트를 온보딩하고 관리할 수 있습니다. 그러나 테넌트 및 해당 구성을 추적하는 프로세스와 중앙 위치는 여전히 있어야 합니다.

전체 제어 평면을 만들지 않기로 결정한 경우 관리 절차에 대해 체계적으로 관리하는 것이 좋습니다.

  • 프로세스를 철저히 문서화합니다.
  • 가능한 경우 관리 작업에 대한 스크립트를 만들고 다시 사용합니다.

나중에 프로세스를 자동화해야 하는 경우 설명서와 스크립트가 컨트롤 플레인의 기초를 형성할 수 있습니다.

몇 개의 테넌트를 넘어 성장하면 각 테넌트를 추적하고 리소스 및 테넌트 전체에서 모니터링을 적용하는 방법을 활용할 수 있습니다. 또한 팀에서 테넌트 관리에 점점 더 많은 시간과 노력을 소비하는 것을 알 수 있습니다. 또는 팀 구성원이 관리 작업을 수행하는 방식의 불일치로 인해 버그 또는 운영 문제가 발생할 수 있습니다. 이러한 상황이 발생하면 이러한 책임을 맡을 보다 포괄적인 컨트롤 플레인을 빌드하는 것이 좋습니다.

참고 항목

셀프 서비스 테넌트 관리를 제공하는 경우 여행 초기에 컨트롤 플레인이 필요합니다. 기본 컨트롤 플레인을 만들고 가장 일반적으로 사용되는 기능 중 일부만 자동화하도록 선택할 수 있습니다. 시간이 지남에 따라 더 많은 기능을 점진적으로 추가할 수 있습니다.

컨트롤 플레인 디자인

컨트롤 플레인의 요구 사항 및 범위를 결정한 후에는 컨트롤 플레인을 설계하고 설계해야 합니다. 컨트롤 플레인은 중요한 구성 요소입니다. 시스템의 다른 요소를 계획하는 것처럼 신중하게 계획해야 합니다.

잘 설계된 컨트롤 플레인

컨트롤 플레인은 자체 시스템이므로 디자인할 때 Azure Well-Architected Framework5가지 핵심 요소를 모두 고려하는 것이 중요합니다. 다음 섹션에서는 중점해야 할 특정 영역을 강조 표시합니다.

안정성

컨트롤 플레인은 종종 중요 업무용 구성 요소입니다. 컨트롤 플레인에 필요한 복원력 및 안정성 수준을 계획하는 것이 중요합니다.

컨트롤 플레인을 사용할 수 없는 경우 어떻게 되는지 고려합니다. 극단적인 경우 컨트롤 플레인 중단으로 인해 전체 솔루션을 사용할 수 없게 될 수 있습니다. 컨트롤 플레인이 단일 실패 지점이 아니더라도 중단은 다음과 같은 영향을 줄 수 있습니다.

  • 시스템에서 새 테넌트에 등록할 수 없으므로 판매 및 비즈니스 성장에 영향을 줄 수 있습니다.
  • 시스템에서 기존 테넌트는 관리할 수 없으므로 지원 팀에 더 많은 호출이 발생합니다.
  • 테넌트의 소비량을 측정하거나 사용량에 대해 청구할 수 없으므로 수익 손실이 발생합니다.
  • 테넌트를 사용하지 않도록 설정하거나 다시 구성하여 보안 인시던트에 대응할 수 없습니다.
  • 유지 관리 부채가 누적되어 시스템에 장기적인 손상을 입힙니다. 예를 들어 솔루션에 오래된 데이터를 야간 정리해야 하는 경우 디스크가 채워지거나 성능이 저하됩니다.

가용성 목표, RTO(복구 시간 목표) 및 RPO(복구 지점 목표)를 포함하여 제어 평면에 대한 서비스 수준 목표를 정의합니다. 컨트롤 플레인에 대해 설정한 목표가 고객에게 제공하는 목표와 다를 수 있습니다.

제어 평면을 포함하여 시스템 전체에서 신뢰할 수 있는 솔루션을 빌드하기 위한 Azure Well-Architected Framework 지침을 따릅니다.

보안

컨트롤 플레인은 종종 높은 권한이 있는 시스템입니다. 컨트롤 플레인 내의 보안 문제는 치명적인 결과를 초래할 수 있습니다. 디자인 및 기능에 따라 컨트롤 플레인은 다음을 포함하여 다양한 유형의 공격에 취약할 수 있습니다.

  • 컨트롤 플레인은 모든 테넌트에 대한 키 및 비밀에 액세스할 수 있습니다. 컨트롤 플레인에 액세스할 수 있는 공격자는 테넌트의 데이터 또는 리소스에 액세스할 수 있습니다.
  • 컨트롤 플레인은 종종 Azure에 새 리소스를 배포할 수 있습니다. 공격자는 컨트롤 플레인을 악용하여 자신의 리소스를 구독에 배포할 수 있으며, 이로 인해 광범위한 요금이 발생할 수 있습니다.
  • 공격자가 성공적으로 컨트롤 플레인을 오프라인으로 전환하면 시스템 및 비즈니스에 즉각적이고 장기적인 손상이 있을 수 있습니다. 컨트롤 플레인을 사용할 수 없는 경우의 예를 들어 안정성을 참조하세요.

컨트롤 플레인을 디자인하고 구현하는 경우 보안 모범 사례를 따르고 포괄적인 위협 모델을 만들어 솔루션의 잠재적 위협 및 보안 문제를 문서화하고 완화하는 것이 중요합니다. 자세한 내용은 보안 솔루션을 빌드하기 위한 Azure Well-Architected Framework 지침을 참조하세요.

운영 우수성

컨트롤 플레인은 중요한 구성 요소이므로 프로덕션 환경에서 배포하고 작동하는 방법을 신중하게 고려해야 합니다.

솔루션의 다른 부분과 마찬가지로 해당 기능을 철저히 테스트할 수 있도록 컨트롤 플레인의 비프로덕션 인스턴스를 배포해야 합니다. 컨트롤 플레인에서 배포 작업을 수행하는 경우 비프로덕션 제어 평면이 Azure 환경과 상호 작용하는 방식과 비프로덕션 리소스를 배포하는 Azure 구독을 고려합니다. 또한 실수로 요금이 누적되지 않도록 테스트 리소스를 신속하게 정리하는 방법을 계획합니다.

또한 컨트롤 플레인에 대한 팀의 액세스를 관리하는 방법을 계획해야 합니다. 팀 구성원이 업무를 수행하는 데 필요한 권한만 부여하기 위한 모범 사례를 따릅니다. 이 방법은 보안 인시던트 방지 외에도 우발적인 잘못된 구성의 영향을 줄이는 데 도움이 됩니다.

구성 요소

컨트롤 플레인에 대한 템플릿이 하나도 없으며 디자인하고 빌드하는 구성 요소는 요구 사항에 따라 달라집니다. 일반적으로 컨트롤 플레인은 API 및 백그라운드 작업자 구성 요소로 구성됩니다. 일부 솔루션에서는 컨트롤 플레인에 사용자 인터페이스가 포함될 수 있으며 팀 또는 고객도 사용할 수 있습니다.

테넌트 워크로드에서 컨트롤 플레인 격리

컨트롤 플레인의 리소스를 테넌트의 데이터 평면을 제공하는 데 사용되는 리소스와 분리하는 것이 좋습니다. 예를 들어 별도의 데이터베이스 서버, 애플리케이션 서버 및 기타 구성 요소를 사용하는 것이 좋습니다. 컨트롤 플레인의 리소스를 테넌트별 리소스가 포함된 리소스와 별도의 Azure 리소스 그룹에 유지하는 것이 좋습니다.

테넌트의 워크로드에서 컨트롤 플레인을 격리하면 다음과 같은 몇 가지 이점이 있습니다.

  • 크기 조정을 별도로 구성할 수 있습니다. 예를 들어 컨트롤 플레인에는 일관된 리소스 요구 사항이 있을 수 있으며 테넌트의 리소스는 필요에 따라 탄력적으로 확장될 수 있습니다.
  • 컨트롤과 데이터 평면 사이에는 노이즈 네이버 문제가 솔루션의 평면 간에 확산되는 것을 방지하는 데 도움이 되는 격벽이 있습니다.
  • 컨트롤 플레인은 일반적으로 높은 수준의 액세스 권한을 가진 높은 권한이 있는 시스템입니다. 컨트롤 플레인을 데이터 평면에서 분리하면 보안 취약성으로 인해 공격자가 전체 시스템에서 권한을 상승시킬 가능성을 줄일 수 있습니다.
  • 별도의 네트워킹 및 방화벽 구성을 배포할 수 있습니다. 데이터 평면 및 제어 평면에는 일반적으로 다양한 유형의 네트워크 액세스가 필요합니다.

장기 실행 작업의 시퀀스 오케스트레이션

컨트롤 플레인에서 수행하는 작업은 종종 장기 실행되며 여러 시스템 간의 조정이 포함됩니다. 작업에는 복잡한 오류 모드가 있을 수도 있습니다. 컨트롤 플레인을 디자인할 때는 장기 실행 작업 또는 워크플로를 조정하는 데 적합한 기술을 사용하는 것이 중요합니다.

예를 들어 새 테넌트를 온보딩할 때 컨트롤 플레인은 다음 작업을 순서대로 실행한다고 가정합니다.

  1. 새 데이터베이스를 배포합니다. 이 작업은 Azure 배포 작업입니다. 완료하는 데 몇 분 정도 걸릴 수 있습니다.
  2. 테넌트 메타데이터 카탈로그를 업데이트합니다. 이 작업에는 Azure SQL 데이터베이스에 대한 명령 실행이 포함될 수 있습니다.
  3. 새 테넌트에 환영 전자 메일을 보냅니다. 이 작업은 타사 API를 호출하여 이메일을 보냅니다.
  4. 새 테넌트에 대한 청구서를 준비하도록 청구 시스템을 업데이트합니다. 이 작업은 타사 API를 호출합니다. 간헐적으로 실패하는 것을 발견했습니다.
  5. 새 테넌트 추적을 위해 CRM(고객 관계 관리) 시스템을 업데이트합니다. 이 작업은 타사 API를 호출합니다.

시퀀스의 단계가 실패하는 경우 다음과 같은 작업을 고려해야 합니다.

  • 실패한 작업을 다시 시도합니다. 예를 들어 2단계의 Azure SQL 명령이 일시적인 오류로 실패하는 경우 다시 시도할 수 있습니다.
  • 다음 단계를 계속 진행합니다. 예를 들어 판매 팀이 나중에 고객을 수동으로 추가할 수 있으므로 청구 시스템에 대한 업데이트가 실패할 경우 허용되는지 결정할 수 있습니다.
  • 워크플로를 포기하고 수동 복구 프로세스를 트리거합니다.

또한 각 실패 시나리오에 대해 사용자 환경이 어떤 것인지 고려해야 합니다.

공유 구성 요소 관리

컨트롤 플레인은 특정 테넌트에 전용되지 않고 대신 공유되는 모든 구성 요소를 알고 있어야 합니다. 일부 구성 요소는 스탬프 내의 모든 테넌트 간에 공유될 수 있습니다. 다른 구성 요소는 지역의 모든 스탬프 간에 공유되거나 모든 지역 및 스탬프에서 전역적으로 공유될 수도 있습니다. 테넌트가 온보딩, 다시 구성 또는 오프보딩될 때마다 컨트롤 플레인은 이러한 공유 구성 요소로 수행할 작업을 알고 있어야 합니다.

테넌트가 추가되거나 제거될 때마다 일부 공유 구성 요소를 다시 구성해야 할 수 있습니다. 예를 들어 전역적으로 공유되는 Azure Front Door 프로필이 있다고 가정해 보겠습니다. 사용자 지정 도메인 이름을 가진 테넌트를 추가하는 경우 컨트롤 플레인은 해당 도메인 이름에 대한 요청을 올바른 애플리케이션으로 라우팅하도록 프로필의 구성을 업데이트해야 할 수 있습니다. 마찬가지로 테넌트가 오프보딩되면 하위 도메인 인수 공격을 방지하기 위해 컨트롤 플레인이 Azure Front Door 프로필에서 사용자 지정 도메인 이름을 제거해야 할 수 있습니다.

공유 구성 요소에는 컨트롤 플레인에서 따라야 하는 복잡한 크기 조정 규칙이 있을 수 있습니다. 예를 들어 bin 압축 방법을 따라 테넌트의 데이터베이스를 배포한다고 가정해 보겠습니다. 새 테넌트가 온보딩되면 해당 테넌트에 대한 새 Azure SQL 데이터베이스를 추가한 다음 Azure SQL 탄력적 풀에 할당합니다. 추가하는 10번째 데이터베이스마다 풀에 할당된 리소스를 늘려야 한다고 판단했을 수 있습니다. 테넌트를 추가하거나 제거할 때 컨트롤 플레인은 풀의 구성을 다시 평가하고 풀의 리소스를 변경할지 여부를 결정해야 합니다. 단일 탄력적 풀에 할당할 수 있는 최대 데이터베이스 수에 도달하면 새 풀을 만들고 새 테넌트 데이터베이스에 해당 풀을 사용하기 시작해야 합니다. 컨트롤 플레인은 이러한 공유 구성 요소 각각을 관리하고, 변경될 때마다 크기를 조정하고 다시 구성해야 합니다.

컨트롤 플레인에서 공유 구성 요소를 관리하는 경우 여러 작업이 병렬로 발생할 때 발생할 수 있는 경합 상태를 인식하는 것이 중요합니다. 예를 들어 다른 테넌트를 오프보딩하는 동시에 새 테넌트를 온보딩하는 경우 최종 최종 상태가 일관되고 크기 조정 요구 사항을 충족하는지 확인해야 합니다.

여러 컨트롤 플레인 사용

복잡한 환경에서는 각각 서로 다른 책임 영역이 있는 여러 컨트롤 플레인을 사용해야 할 수 있습니다. 많은 다중 테넌트 솔루션은 여러 스탬프에서 배포 스탬프 패턴 및 분할 테넌트를 따릅니다. 이 패턴을 사용하는 경우 전역 및 스탬프 책임을 위한 별도의 컨트롤 플레인을 만들 수 있습니다.

여러 컨트롤 플레인의 조정은 복잡하므로 빌드하는 컨트롤 플레인의 수를 최소화해 보세요. 대부분의 솔루션에는 하나의 컨트롤 플레인만 필요합니다.

전역 컨트롤 플레인

전역 컨트롤 플레인은 일반적으로 테넌트 전체 관리 및 추적을 담당합니다. 전역 컨트롤 플레인에는 다음과 같은 책임이 있을 수 있습니다.

  • 테넌트 배치. 전역 컨트롤 플레인은 테넌트가 사용해야 하는 스탬프를 결정합니다. 테넌트 지역, 각 스탬프의 용량 사용률 및 테넌트의 서비스 수준 요구 사항과 같은 요인에 따라 이 결정을 내릴 수 있습니다.
  • 테넌트 온보딩 및 수명 주기 관리. 이러한 책임에는 모든 배포에서 모든 테넌트 추적이 포함됩니다.

스탬프 컨트롤 플레인

스탬프 제어 평면은 각 배포 스탬프에 배포되며 해당 스탬프에 할당된 테넌트 및 리소스를 담당합니다. 스탬프 컨트롤 플레인에는 다음과 같은 책임이 있을 수 있습니다.

  • 스탬프 내에서 데이터베이스 및 스토리지 컨테이너와 같은 테넌트별 리소스를 만들고 관리합니다.
  • 공유 리소스의 소비를 모니터링하고 최대 용량에 근접할 때 새 인스턴스를 배포하는 등 공유 리소스를 관리합니다.
  • 데이터베이스 인덱스 관리 및 정리 작업과 같이 스탬프 내에서 유지 관리 작업을 수행합니다.

각 스탬프의 컨트롤 플레인은 전역 컨트롤 플레인과 좌표입니다. 예를 들어 새 테넌트가 등록한다고 가정합니다. 전역 컨트롤 플레인은 처음에 테넌트의 리소스에 대한 스탬프를 선택해야 합니다. 그런 다음 전역 컨트롤 플레인은 스탬프의 컨트롤 플레인에 테넌트에 필요한 리소스를 만들라는 메시지를 표시합니다.

다음 다이어그램은 두 컨트롤 플레인이 단일 시스템에서 공존하는 방법의 예를 보여줍니다.

논리적 시스템 디자인을 보여 주는 다이어그램 디자인에는 전역 컨트롤 플레인과 스탬프 컨트롤 플레인이 있습니다.

테넌트 제어 평면

테넌트는 테넌트 수준 컨트롤 플레인을 사용하여 자체 논리 또는 물리적 리소스를 관리할 수 있습니다. 테넌트 컨트롤 플레인에는 다음과 같은 책임이 있을 수 있습니다.

  • 사용자 액세스와 같은 테넌트별 구성 관리
  • 데이터 백업 또는 이전 백업 다운로드와 같은 테넌트 시작 유지 관리 작업
  • 테넌트가 애플리케이션에 대한 자체 업데이트를 제어할 수 있도록 허용하는 경우 업데이트 관리

다음 다이어그램은 전역 제어 평면, 스탬프 제어 평면 및 각 테넌트에 대한 컨트롤 플레인을 포함하는 복잡한 시스템을 보여줍니다.

논리적 시스템 디자인을 보여 주는 다이어그램 디자인에는 전역 컨트롤 플레인, 스탬프 컨트롤 플레인 및 각 테넌트에 대한 컨트롤 플레인이 있습니다.

참가자

Microsoft에서 이 문서를 유지 관리합니다. 원래 다음 기여자가 작성했습니다.

보안 주체 작성자:

  • John Downs | 주요 소프트웨어 엔지니어

기타 기여자:

비공개 LinkedIn 프로필을 보려면 LinkedIn에 로그인하세요.

다음 단계