IAM, VPC, Transit Gateway 및 DNS를 사용한 팀 기반 격리
이 튜토리얼에서는 비용이 발생할 수 있습니다. Cost Estimator를 사용하여 예상 사용량을 기반으로 비용 추정값을 생성하십시오.
마이크로서비스는 엔터프라이즈에서 개발 팀이 제공하는 서비스를 중심으로 개발 팀을 구성할 수 있도록 하여 널리 사용되고 있습니다. 이 튜토리얼에서는 IBM Cloud® Virtual Private Cloud 기반 마이크로서비스 아키텍처를 위한 인프라를 만드는 단계를 안내합니다 (VPC) 기반 마이크로서비스 아키텍처를 위한 인프라를 만드는 단계를 안내합니다. 이 아키텍처에서 VPC는 IBM Cloud® Transit Gateway를 사용하여 서로 연결됩니다. 공유 마이크로서비스 집합은 IBM Cloud® DNS Services 등록된 호스트 이름을 통해 액세스할 수 있습니다. 각 VPC는 IBM Cloud® Identity and Access Management로 격리된 개별 팀에 의해 관리됩니다. 선택적으로 IBM Cloud® Load Balancer 사용하여 공유 마이크로서비스를 확장할 수 있습니다.
목표
- IAM 및 리소스 그룹을 사용하여 인프라를 격리하는 방법을 알아봅니다.
- VPC, 그리고 서브넷, 네트워크 ACL, 보안 그룹, 인스턴스와 같은 연관된 리소스를 작성합니다.
- DNS Services 사용하여 DNS 이름 확인을 통해 마이크로서비스에 주소를 지정합니다.
- Transit Gateway를 통해 VPC를 연결합니다.
- 애플리케이션의 Load Balancer를 투명하게 구성합니다.
추상 아키텍처:
위 다이어그램에서는 일반 사용자가 애플리케이션에 액세스하고 있습니다. 애플리케이션은 공유 마이크로서비스를 활용하고 있습니다. 회사에는 application1, application2 및 shared를 소유한 개별 DevOps 팀이 있습니다. 네트워킹 팀은 연결 및 네트워크 보안에 집중합니다. DevOps 팀은 자신이 작성하고 지원하는 서비스를 구현하는 데 사용되는 가상 서비스 인스턴스(VSI)를 관리합니다.
구체적 아키텍처
다음 아키텍처는 회사에서 설정한 격리 및 연결 요구사항을 구현합니다. application1, shared 및 application2는 VPC인 것을 볼 수 있습니다. 각 VPC의 단일 구역 및 서브넷은 시간 경과에 따라 더 복잡한 다중 구역 구현으로 확장될 수 있습니다.
시작하기 전에
이 튜토리얼에는 다음 항목이 필요합니다.
- 다음 플러그인이 있는 IBM Cloud CLI:
- Transit Gateway (
tg) - IBM Cloud VPC (
vpc-infrastructure) - DNS Services (
dns)
- Transit Gateway (
git: 소스 코드 저장소를 복제함terraform를 사용하여 Terraform 명령을 실행합니다.
솔루션 시작하기 튜토리얼 가이드에서 운영 환경에 맞는 이러한 도구를 다운로드하고 설치하는 방법을 찾을 수 있습니다.
또한 다음을 확인하십시오.
Identity and Access Management 환경 계획
admin 팀은 다른 팀이 가능한 한 해당 팀의 리소스를 관리할 수 있도록 합니다. admin 팀은 사용자를 관리하고 액세스를 제어하지만 아키텍처 다이어그램에 표시된 리소스를 작성하거나 영구 삭제하지는 않습니다.
편집자, 운영자, 뷰어 및 관리자(Manager)는 IAM 액세스 역할입니다. 각 서비스는 이러한 역할의 정확한 의미 및 연관된 조치를 정의합니다.
팀:
- admin - 리소스 그룹, 액세스 그룹, 사용자, 역할과 같은 계정 구조를 정의합니다.
- network - DNS Services, Transit Gateway 서비스, VPC 및 서브넷과 같은 네트워크 리소스를 작성합니다.
- shared - shared VPC에 VSI 및 블록 디바이스를 작성합니다. shared 서비스에 대한 DNS 레코드를 작성합니다.
- application1 - application1 VPC에 VSI 및 블록 디바이스를 작성합니다.
- application2 - application2 VPC에 VSI 및 블록 디바이스를 작성합니다.
개념적 IAM
network 팀
개념적인 팀 소유권 모델이 구현되었습니다. 네트워크 팀은 모든 네트워크 자원을 관리하므로 다이어그램에 표시되는 대부분의 자원을 관리합니다.
shared 팀
shared 팀은 격리된 VPC에 VSI를 작성합니다. 또한 VSI의 IP 주소는 생성 시점에 결정되므로 팀은 DNS 서비스에 레코드를 작성해야 합니다. VSI를 작성하려면 VPC, 서브넷 및 보안 그룹에 대한 운영자 액세스 권한이 필요합니다.
애플리케이션 팀은 DNS Services에 대한 관리자 액세스를 제외하고 공유 팀과 동일한 액세스 권한이 필요합니다.
application 팀 액세스 권한:
IAM 아키텍처
리소스 그룹 및 IAM 액세스 그룹을 잘 이해하고 있는 경우에는 이 절을 빠르게 훑어보고 리소스 작성 단계를 시작할 수 있습니다.
액세스 그룹
각 팀에 대해 액세스 그룹이 작성됩니다. 액세스 정책이 액세스 그룹에 추가되며, 그 후 사용자(팀 구성원)가 액세스 권한을 제공하기 위해 액세스 그룹에 추가됩니다.
Transit Gateway 서비스 인스턴스는 network 팀에서 독점 관리합니다. 작성하려면 편집자 액세스 권한이 필요합니다. 작성된 인스턴스에 대한 관리자(Manager) 액세스 권한은 VPC를 Transit Gateway에 연결할 수 있도록 합니다.
이 예제에서는 단일 DNS widgets.example.com 생성되고 모든 VPC에 DNS 영역에 대한 액세스가 허용됩니다. DNS 서비스 인스턴스는 network 팀(편집자 역할)에 의해 작성되며 구역 허용에는 관리자(Manager) 역할이 필요합니다. VPC에 있는 인스턴스에서의 런타임 시 DNS 해석은 IAM 액세스 권한을 필요로 하지 않습니다. shared 팀은 DNS 인스턴스를 나열(뷰어 역할)하고 A 또는 CNAME 레코드를 추가(관리자 역할)해야 합니다.
VPC 인프라 서비스(IS)는 서로 다른 15개의 서비스 유형으로 구성됩니다. 네트워크 ACL(액세스 제어 목록)과 같이 네트워크 팀만 관심을 갖는 것도 있습니다. VSI 인스턴스처럼 마이크로서비스 팀만 관심을 갖는 것도 있습니다. 하지만 서브넷과 같이 네트워크 팀에서 편집하고 마이크로서비스 팀에서 운영하는 것도 있습니다. 네트워크 팀이 서브넷을 생성하고 마이크로서비스 팀이 서브넷에 인스턴스를 생성합니다. 이 튜토리얼을 위한 각 액세스 그룹의 VPC IS 서비스 유형, Transit Gateway 및 DNS는 아래 표에 요약되어 있습니다. 표의 컨텐츠는 필수 역할입니다.
| Service | 네트워크 | 공유 | 애플리케이션 |
|---|---|---|---|
| Transit Gateway | 편집자, 관리자 | ||
| DNS | 편집자, 관리자 | 뷰어, 관리자(Manager) | |
| IS: 네트워크 ACL | 편집자 | ||
| IS: 인스턴스, 볼륨, 유동 IP, SSH 키, 이미지, 로드 밸런서 | 편집자 | 편집자 | |
| IS: VPC, 서브넷, 보안 그룹 | 편집자 | 운영자 | 운영자 |
리소스 그룹
이제 shared 팀과 network 팀이 보기 좋게 분리되었습니다. 그러나 application1은 shared 및 application2와 어떻게 격리될까요? 이들은 동일한 서비스 유형에 대한 편집자입니다.
이 부분이 리소스 그룹에서 도움을 줄 수 있는 부분입니다. 각 서비스 인스턴스(즉, 리소스)에는 생성 시 초기화되며 변경할 수 없는 리소스 그룹 속성이 있습니다. 즉, 각 리소스는 하나의 리소스 그룹에 속합니다.
자원 그룹 다이어그램:
각 마이크로서비스 팀에는 해당 리소스 그룹에서 액세스 권한이 허용됩니다. 네트워크 팀은 이러한 모든 자원 그룹에 액세스할 수 있습니다.
네트워크 자원 그룹에는 Transit Gateway 및 DNS 서비스가 포함됩니다. 네트워크 팀은 이러한 자원에 액세스할 수 있습니다. 공유 팀은 DNS 서비스에 대한 관리자 액세스 권한을 갖게 됩니다. shared 팀은 공유 서비스에 대한 DNS 항목을 작성해야 합니다.
튜토리얼 뒷부분에서 모든 리소스를 생성한 후 IBM Cloud 콘솔에서 리소스 목록을 여는 것이 도움이 될 수 있습니다. 자원 그룹을 필터링할 수 있습니다.
로컬 작업 환경 작성
모든 작업은 bash 셸에서 terraform 및 ibmcloud 명령을 사용하여 수행됩니다. 솔루션 시작하기 튜토리얼 가이드에서 운영 환경에 맞는 이러한 도구를 다운로드하고 설치하는 방법을 찾을 수 있습니다.
-
Git 는 다음 저장소를 복제합니다.
git clone https://github.com/IBM-Cloud/vpc-tg-dns-iam cd vpc-tg-dns-iam각 팀에 대한 디렉토리가 있는지 확인하십시오(지금은 application2를 건너뜀).
- admin/
- 네트워크/
- shared/
- application1/
-
terraform.tfvars파일을 작성하십시오.cp terraform.tfvars.template terraform.tfvars그런 다음
terraform.tfvars를 편집하여 다음 변수를 설정하십시오.- ssh_key_name- 위의 시작하기 전에 섹션에서 지정한 대로 ibm_지역에 기존 SSH 키를 지정해야 합니다.
- ibm_region- 필요한 경우 기본값인 us-south를 대체합니다. CLI 명령
ibmcloud regions는 가능한 모든 지역을 표시합니다. - 기본 이름- 필요한 경우 기본값인 widget0 7자 이하의 이름으로 바꿉니다. 작성되는 대부분의 리소스는 이를 이름 접두부로 사용합니다.
- 지금은
transit_gateway또는shared_lb을(를) 주석 해제하지 마십시오.
-
Windows 사용자만 해당: Windows 컴퓨터에서 git이 심볼릭 링크를 만들지 않는 경우 파일 내용을 팀 폴더에 복사해야 합니다:
cp variables.tf terraform.tfvars admin cp variables.tf terraform.tfvars network cp variables.tf terraform.tfvars shared cp variables.tf terraform.tfvars application1
팀 구성원이 되는 데 대한 참고
각 팀의 액세스 그룹을 사용자로 채울 수 있습니다. 하지만 이 튜토리얼에서는 사용자를 만드는 대신 각 팀의 액세스 그룹에 서비스 ID를 만들 것입니다. 사용자는 관리자이며 팀의 서비스 ID에 대한 API 키를 사용하여 다른 액세스 그룹의 구성원이 됩니다. 서비스 ID 이름은 ${basename}-x이며, 여기서 x는 network, shared, application1 및
application2입니다. 나중에는 각 팀의 디렉토리에 있는 local.env 파일을 다음과 같은 컨텐츠로 채웁니다.
export TF_VAR_ibmcloud_api_key=0thisIsNotARealKeyALX0vkLNSUFC7rMLEWYpVtyZaS9
In each step when you cd into a team directory you will be reminded to execute: source local.env
Terraform은 리소스를 작성하는 데 사용됩니다. admin/main.tf를 열고 provider ibm 절과 환경 변수로부터 초기화되는 ibmcloud_api_key에 대한 참조를 보십시오.
provider ibm {
ibmcloud_api_key = var.ibmcloud_api_key # initialized with the TF_VAR_ibmcloud_api_key
}
IBM Cloud 사용해야 하는 경우 CLI를 팀원으로 사용해야 하는 경우:
ibmcloud login --apikey $TF_VAR_ibmcloud_api_key
IAM 사용 리소스 작성(admin 팀)
admin 팀은 이 튜토리얼에서 사용되는 계정에 있는 IAM 사용 리소스에 대한 관리자 액세스 권한이 있어야 합니다. 계정 관리자로서 사용자에게 전체 액세스 권한을 지정하는 방법은 무엇입니까?를 참조하십시오. admin 팀은 IAM 리소스를 작성해야 합니다. 아래 지시사항은 admin의 API 키를 작성하는
데 ibmcloud iam api-key-create 명령을 사용합니다. 이 API 키는 사용자를 대신하여 태스크를 수행하기 위해 Terraform이 사용합니다.
PI 키는 계정의 비밀번호와 동일합니다. API 키를 안전하게 보관하십시오.
-
basename 쉘 변수를 초기화하고 확인하십시오. 이것이 terraform.tfvars 파일에 있는 basename과 일치하는지 확인하십시오.
eval $(grep basename terraform.tfvars | sed -e 's/ *//g' -e 's/#.*//') echo basename=$basename -
디렉토리를 변경하고, local.env에서 개인 API 키를 생성한 후 확보하십시오. Terraform이 호출되면 이것이 곧 사용자가 됩니다. Terraform이 관리자 역할을 수행합니다.
cd admin echo export TF_VAR_ibmcloud_api_key=$(ibmcloud iam api-key-create $basename-admin --output json | jq .apikey) > local.env cat local.env source local.env -
Apply of the
main.tfTerraform configuration file creates the following resources:- 각 팀의 리소스 그룹
- 각 팀의 액세스 그룹 및 각 액세스 그룹의 서비스 ID
- 리소스 그룹에 대한 액세스 그룹 정책
- 리소스에 대한 액세스 그룹 정책
terraform init terraform apply -
자원이 작성되었는지 확인하십시오.
ibmcloud resource groups | grep $basenameibmcloud iam access-groups | grep $basenameibmcloud iam service-ids | grep $basenameibmcloud iam access-group-policies $basename-network출력은 다음과 유사합니다.
$ ibmcloud resource groups | grep $basename widget0-application2 36b06a303f224f28ad42aebbb491cc44 false ACTIVE widget0-shared 91518c45e47a427fa4f63edb58e4f227 false ACTIVE widget0-network bf6e75cd71854576a31056abced2abf0 false ACTIVE widget0-application1 db2f3dc8aacf4a6aa2d2fa07e795cb57 false ACTIVE $ ibmcloud iam access-groups | grep $basename widget0-application1 AccessGroupId-26b7ef37-78db-4a2c-a2af-7f6591e73c15 application1 administrators widget0-application2 AccessGroupId-8afdec20-f760-4a15-8f3e-296d81818028 application2 administrators widget0-network AccessGroupId-d50b129d-9adc-4fc4-b297-487b3f938ec5 network administrators widget0-shared AccessGroupId-30d73f44-5602-47a7-846e-e6480c9dceff shared administrators $ ibmcloud iam service-ids | grep $basename ServiceId-5e919b97-380c-4343-a337-3901cafbd956 widget0-application2 2020-07-15T21:25+0000 2020-07-15T22:03+0000 application 2 service id false ServiceId-307df062-f4b7-45f8-8ec8-94ad1ed61730 widget0-network 2020-07-15T21:49+0000 2020-07-15T22:03+0000 network service id false $ ibmcloud iam access-group-policies $basename-network Retrieving all policies of access group widget0-network under account 8675309 as jenny@example.com OK Policy ID: 00ceb354-7360-4ad5-9fda-5c03e462c5c0 Roles: Editor Resources: Resource Group ID 91518c45e47a427fa4f63edb58e4f227 Resource Group Name widget0-shared Service Name is flowLogCollectorId * Memo Policy applies to the resource(s) within the resource group Policy ID: 115ebe9f-eea0-4308-9e7f-bb887d64426b Roles: Editor Resources: Resource Group ID db2f3dc8aacf4a6aa2d2fa07e795cb57 Resource Group Name widget0-application1 Service Name is vpnGatewayId * Memo Policy applies to the resource(s) within the resource group ... -
선택 사항으로 리소스 그룹 계정으로 이동하여 리소스 그룹을 찾습니다.
-
원하는 경우 액세스 그룹으로 이동하여 액세스 그룹을 보고 액세스 그룹을 클릭한 다음 상단의 서비스 ID 패널을 클릭하여 생성된 서비스 ID를 확인합니다.
VPC 및 DNS 작성(network 팀)
network 팀은 연결 목표를 만족시키고 팀이 각자의 VPC에 격리되도록 하기 위해 아키텍처에 맞는 네트워크 리소스를 작성합니다. 이들이 VPC 인스턴스의 세부사항을 제어하지는 않습니다. 애플리케이션의 수, 컴퓨터의 크기, 마이크로서비스용 DNS 레코드 등은 네트워크 팀의 관심사가 아니라 지속적으로 유동적일 가능성이 높습니다.
admin 팀에서는 VPC is 리소스, DNS Services 및 Transit Gateway 서비스를 작성할 수 있을 정도의 권한만 제공합니다.
-
디렉터리를 변경하고
local.envAPI 키를 생성한 후 네트워크 액세스 그룹의 멤버가 됩니다:team=network cd ../$team echo export TF_VAR_ibmcloud_api_key=$(ibmcloud iam service-api-key-create $team $basename-$team --output json | jq .apikey) > local.env cat local.env source local.env -
선택 사항으로
variables_network.tf파일을 열고 CIDR 블록 사양과 영역 레이아웃을 확인합니다. 아래 스니펫에서 공유 및 application1 중복되는 IP 주소 없이 지정되어 있음을 확인할 수 있습니다:variable network_architecture { default = { shared = { cidr = "10.0.0.0/16" cidr_remote = "10.0.0.0/8" zones = { z1 = { zone_id = "1", cidr = "10.0.0.0/24", } z2 = { zone_id = "2", cidr = "10.0.1.0/24", ... application1 = { cidr = "10.1.0.0/16" cidr_remote = "0.0.0.0" zones = { z1 = { zone_id = "1", cidr = "10.1.0.0/24", } z2 = { zone_id = "2", cidr = "10.1.1.0/24", ...Transit Gateway 에는 각 VPC에 대한 연결이 있으며 CIDR 범위를 기반으로 트래픽을 라우팅합니다. 따라서 겹침을 방지하면 성공을 보장할 수 있습니다.
-
리소스를 작성하십시오.
terraform init terraform apply -
VPC 리소스를 나열하십시오.
작성된 VPC 리소스는 아래 표시되어 있으며 간결함을 위해 편집된, subnets 명령의 출력에 의해 요약됩니다. 세 개의 VPC, 겹치지 않는 CIDR 블록, 리소스 그룹 멤버십에 주목하세요:
ibmcloud target -r $(grep ibm_region terraform.tfvars | sed -e 's/ *//g' -e 's/#.*//' -e 's/.*=//' -e 's/"//g') ibmcloud is subnets --all-resource-groups | grep $basename출력은 다음과 비슷합니다.
$ ibmcloud is subnets --all-resource-groups | grep $basename widget0-shared-z1 available 10.0.0.0/24 widget0-shared us-south-1 widget0-shared widget0-shared-z2 available 10.0.1.0/24 widget0-shared us-south-2 widget0-shared widget0-shared-z3 available 10.0.2.0/24 widget0-shared us-south-3 widget0-shared widget0-application1-z1 available 10.1.0.0/24 widget0-application1 us-south-1 widget0-application1 widget0-application1-z2 available 10.1.1.0/24 widget0-application1 us-south-2 widget0-application1 widget0-application1-z3 available 10.1.2.0/24 widget0-application1 us-south-3 widget0-application1 widget0-application2-z1 available 10.2.0.0/24 widget0-application2 us-south-1 widget0-application2 widget0-application2-z2 available 10.2.1.0/24 widget0-application2 us-south-2 widget0-application2 widget0-application2-z3 available 10.2.2.0/24 widget0-application2 us-south-3 widget0-application2 -
원하는 경우 가상 사설 클라우드로 이동하여 위에서 생성한 VPC, 서브넷 및 기타 모든 리소스를 찾습니다.
-
선택 사항으로,
main.tfTerraform 구성을 조사하여 DNS Services 초기화를 이해합니다. DNS Services 인스턴스 및 구역이 Terraform 스니펫으로 작성되었습니다.resource "ibm_resource_instance" "dns" { name = "${var.basename}-dns" resource_group_id = data.ibm_resource_group.shared.id location = "global" service = "dns-svcs" plan = "standard-dns" } resource "ibm_dns_zone" "widgets_example_com" { name = "widgets.example.com" instance_id = ibm_resource_instance.dns.guid description = "this is a description" label = "this-is-a-label" }그 후 구역이 허용된 네트워크로서 VPC에 추가되었습니다.
resource "ibm_dns_permitted_network" "shared" { instance_id = ibm_resource_instance.dns.guid zone_id = ibm_dns_zone.widgets_example_com.zone_id vpc_crn = module.vpc_shared.vpc.crn type = "vpc" } -
DNS 구성을 나열하십시오. DNS Services 인스턴스가 작성되었습니다. widgets.example.com 영역이 생성되었습니다. 마지막으로 모든 VPC에 영역이 추가되었습니다.
ibmcloud dns instancesibmcloud dns zones -i $basename-dnszone_id=$(ibmcloud dns zones -i $basename-dns --output json | jq -r '.[] | .id') ibmcloud dns permitted-networks $zone_id -i $basename-dns출력은 다음과 비슷합니다:
$ ibmcloud dns instances Retrieving service instances for service 'dns-svcs' ... OK Name ID Location State Service Name widget0-dns 3b0d5546-5999-4c7e-a757-f5fd21dd44ed global active dns-svcs $ ibmcloud dns zones -i $basename-dns Listing zones for service instance 'widget0-dns' ... OK ID Name Status 5a1a2295-1c38-49dd-9809-aaaf5a127e79c1b widgets.example.com ACTIVE $ zone_id=$(ibmcloud dns zones -i $basename-dns --output json | jq -r '.[] | .id') $ ibmcloud dns permitted-networks $zone_id -i $basename-dns Listing permitted networks for zone '5a1a2295-1c38-49dd-9809-f5a127e79c1b' ... OK Name ID Type VPC_CRN State widget0-shared r006-353208ab-4e95-46fb-934b-b5566cde8975 vpc crn:v1:bluemix:public:is:us-south:a/713c783d9a507a53135fe6793c37cc74::vpc:r006-353208ab-4e95-46fb-934b-b5566cde8975 ACTIVE widget0-application1 r006-287258c6-2eb3-4908-b326-6f03c3e47aa6 vpc crn:v1:bluemix:public:is:us-south:a/713c783d9a507a53135fe6793c37cc74::vpc:r006-287258c6-2eb3-4908-b326-6f03c3e47aa6 ACTIVE widget0-application2 r006-fa51e99e-bd93-4451-a4eb-76eed9939d3c vpc crn:v1:bluemix:public:is:us-south:a/713c783d9a507a53135fe6793c37cc74::vpc:r006-fa51e99e-bd93-4451-a4eb-76eed9939d3c ACTIVE -
원하는 경우 리소스 목록으로 이동하여 DNS Services 찾아 클릭한 후 조사합니다.
애플리케이션을 위한 공개용 마이크로서비스 만들기Application1 팀)
-
디렉토리를 변경하고, local.env에서 API 키를 생성하고 application1 액세스 그룹의 구성원이 되십시오.
team=application1 cd ../$team echo export TF_VAR_ibmcloud_api_key=$(ibmcloud iam service-api-key-create $team $basename-$team --output json | jq .apikey) > local.env cat local.env source local.envapplication1 팀 리소스는 shared 팀의 리소스와 매우 유사합니다. 실제로 DNS Services 레코드를 넣을 필요가 없으므로 조금 더 간단합니다. 애플리케이션은
http://shared.widgets.example.com사용하여 공유 마이크로서비스에 액세스합니다. -
선택 사항으로 CentOS 인스턴스를 초기화하는 소스 코드를 조사합니다. 이 탐색 단계에서 모든 팀이 공유하는 테라폼 모듈에 캡처되었습니다.
../common/user_data_app/main.tf:
locals { shared_app_user_data_centos = <<EOS #!/bin/sh curl -sL https://rpm.nodesource.com/setup_20.x | sudo bash - yum install nodejs -y cat > /app.js << 'EOF' ${file("${path.module}/app.js")} EOF cat > /lib/systemd/system/a-app.service << 'EOF' ${file("${path.module}/a-app.service")} EOF systemctl daemon-reload systemctl start a-app EOS } output user_data_centos { value = replace(local.shared_app_user_data_centos, "REMOTE_IP", var.remote_ip) }자세한 설명:
- nodejs는
curl및yum명령으로 설치됩니다. - nodejs 애플리케이션은 /app.js에 삽입됩니다.
- app.js에 대해 systemctl 서비스가 작성됩니다.
- 서비스가 시작됩니다.
- nodejs는
-
선택적으로 app.js 컨텐츠를 살펴보십시오. 여기에는 특히 주목할 만한 두 개의 섹션이 있습니다. 먼저 앱을 실행하는 인스턴스에 대한 설명을 반환하는 /info 링크가 있습니다. ../common/user_data_app/app.js:
const server = http.createServer((req, res) => { switch(req.url) { case '/info': res.statusCode = 200; res.setHeader('Content-Type', 'application/json'); res.end(JSON.stringify({ req_url: req.url, os_hostname: os.hostname(), ipArrays: ips() }, null, 3)); break case '/remote': getRemote(req, res) break둘째, /remote 링크는 원격 서버 IP로 호출하여 해당 원격에 대한 설명과 함께 원격에 액세스하는 데 사용된 remote_url 및 remote_ip 주소를 반환합니다.
const IP='REMOTE_IP' function getRemote(req, res) { path = '/info' remote_url = 'http://' + IP + ':3000' + path http.get(remote_url, (resp) => { let rawData = ''; resp.on('data', (chunk) => { rawData += chunk; }); resp.on('end', () => { try { console.log(rawData) rawObj = JSON.parse(rawData) res.statusCode = 200; res.end(JSON.stringify({remote_url: remote_url, remote_ip: resp.connection.remoteAddress, remote_info: rawObj}, null, 3))저희의 경우 common/user_data_app/main.tf: 다음 때문에 REMOTE_IP는
shared.widgets.example.com됩니다:output user_data_centos { value = replace(local.shared_app_user_data_centos, "REMOTE_IP", var.remote_ip) }application1/main.tf의 다음 항목 또한 그 이유입니다.
module user_data_app { source = "../common/user_data_app" remote_ip = "shared.widgets.example.com" } -
리소스를 작성하십시오.
terraform init terraform apply결과는 다음과 같습니다.
$ terraform apply ... Apply complete! Resources: 2 added, 0 changed, 0 destroyed. Outputs: ibm1_private_ip = "10.1.0.4" ibm1_public_ip = "52.116.140.202" test_info = "curl 52.116.140.202:3000/info" test_remote = "curl 52.116.140.202:3000/remote"위에서 제안된 두 개의 curl 명령 (test_info, test_remote) 을 시도하십시오. 출력에서 명령문을 복사하십시오.
curl 52.116.140.202:3000/info첫 번째 항목은 아래에 캡처된 것과 같은 결과를 가져옵니다.
{ "req_url": "/info", "os_hostname": "widget0-application1-vsi", "ipArrays": [ [ "10.1.0.4" ] ] }그런 다음 출력에서 두 번째 명령을 시도하십시오.
curl 52.116.140.202:3000/remote여기서 두 번째 curl 명령이 작동하지 않은 것을 볼 수 있습니다. 다음 단계에서 이를 수정하십시오. 이 컬 명령을 기억해두면 곧 다시 사용하게 될 것입니다.
Transit Gateway 작성
{{{site.data.keyword.tg_full_notm}} IBM Cloud 상호 연결하는 데 사용되는 네트워크 서비스입니다 동적 확장성, 고가용성, 데이터가 공용 인터넷을 통과하지 않으므로 안심할 수 있는 VPC 리소스를 제공합니다. 앞부분에서 각 VPC의 CIDR 블록은 Transit Gateway가 IP 주소를 사용해 패킷을 라우팅할 수 있도록 서로 겹치지 않게 선택되었습니다.
-
디렉토리를 변경하고 network 그룹의 구성원이 되십시오(기존 API 키 사용).
cd ../network source local.env -
선택적으로 Terraform 파일을 살펴보십시오. main.tf 파일을 열면 Transit Gateway 리소스(ibm_tg)를 볼 수 있습니다. 각각에는
count = var.transit_gateway ? 1 : 0이(가) 있습니다. 이는transit_gateway의 값에 따라 길이가 1 또는 0인 리소스 배열을 작성하는 Terraform 구조체입니다. 길이가 0인 배열의 경우에는 리소스가 작성되지 않습니다. 예를 들어, 다음과 같습니다.resource "ibm_tg_gateway" "tgw"{ count = var.transit_gateway ? 1 : 0 name = "${var.basename}-tgw" location = var.ibm_region global = false resource_group = data.ibm_resource_group.network.id } -
Edit the
terraform.tfvarsfile and uncomment the linetransit_gateway = trueto enable the provisioning of Transit Gateway. -
변경사항을 적용하십시오.
terraform apply -
아래 명령을 사용하여 Transit Gateway를 출력하십시오.
ibmcloud tg gateways GATEWAY_ID=$(ibmcloud tg gateways --output json | sed -e '/^OK$/d' | jq -r '.[]|select(.name=="'$basename-tgw'")|.id') ibmcloud tg connections $GATEWAY_ID출력에 세 개의 VPC 연결이 있는 것을 볼 수 있습니다. 이는 다음과 같습니다.
$ ibmcloud tg gateways Listing gateways under account OK GatewayID e2801c16-1a6d-4d47-9c58-1a3b3c1d9b1b CRN crn:v1:bluemix:public:transit:us-south:a/86785309::gateway:e2801c16-1a6d-4d47-9c58-1a3b3c1d9b1b Name widget0-tgw Routing local Location us-south Created 2020-07-16T09:09:38.048-07:00 Resource group ID bf6e75cd71854576a31056abced2abf0 Status available $ GATEWAY_ID=$(ibmcloud tg gateways --output json | sed -e '/^OK$/d' | jq -r '.[]|select(.name=="'$basename-tgw'")|.id') $ ibmcloud tg connections $GATEWAY_ID Listing connections for gateway e2801c16-1a6d-4d47-9c58-1a3b3c1d9b1b under account OK Name widget0-shared Network Type vpc Connection ID dff6ecfd-388d-471a-908a-98880426fbee Status attached Default Prefix Filter permit NetworkID crn:v1:bluemix:public:is:us-south:a/86785309::vpc:r006-b08a7c2c-c0ea-4908-b0ab-b96cd8ba221a Name widget0-application1 Network Type vpc Connection ID bbce29f9-9ce4-47d4-911d-5341601cea07 Status attached Default Prefix Filter permit NetworkID crn:v1:bluemix:public:is:us-south:a/86785309::vpc:r006-8fdc0e7e-3a98-4f6b-93e0-505c61e3faac Name widget0-application2 Network Type vpc Connection ID 208c00cc-aee2-498e-8b1c-37ddc276f200 Status attached Default Prefix Filter permit NetworkID crn:v1:bluemix:public:is:us-south:a/86785309::vpc:r006-fa80afa7-b16b-4db7-95dd-69a558db4285 -
선택 사항으로 Transit Gateway 탐색하여 위에서 만든 게이트웨이를 찾습니다.
-
앞서 실패한 위에서 curl 명령을 실행하여 application1 VPC에서 공유 VPC까지의 경로가 있는지 확인합니다. 이는 다음과 같습니다.
$ curl 169.48.152.220:3000/remote { "remote_url": "http://shared.widgets.example.com:3000/info", "remote_ip": "10.0.0.4", "remote_info": { "req_url": "/info", "os_hostname": "widget0-shared-vsi", "ipArrays": [ [ "10.0.0.4" ] ] } }
애플리케이션을 위한 공개용 마이크로서비스 만들기Application2 팀)
두 번째 application 팀 환경은 첫 번째 팀의 환경과 동일합니다. 선택 사항으로 application1 수정하여 application2 만듭니다.
-
./application1 디렉토리로 이동하여 application2 디렉토리를 작성하십시오.
cd ../application1 mkdir ../application2 sed -e 's/application1/application2/g' main.tf > ../application2/main.tf cp terraform.tfvars variables.tf versions.tf ../application2 -
디렉터리를 변경하고
local.envAPI 키를 생성한 다음 application2 액세스 그룹의 멤버가 됩니다:team=application2 cd ../$team echo export TF_VAR_ibmcloud_api_key=$(ibmcloud iam service-api-key-create $team $basename-$team --output json | jq .apikey) > local.env cat local.env source local.env -
리소스를 작성하십시오.
terraform init terraform apply -
curl 명령을 테스트하십시오.
자원 제거
-
리소스를 영구 삭제하십시오.
cd를 순서대로 팀 디렉터리로 변경하고source local.env; terraform destroy실행할 수 있습니다. 순서는 application2, application1, shared, network, admin입니다. 이를 대신 수행해 주는 스크립트도 있습니다.cd .. ./bin/destroy.sh
튜토리얼 확장
기타 고려사항
- application 팀은 유동 IP 주소를 통해 애플리케이션에 대한 액세스를 제공하고 있습니다. 이를 IBM Cloud Internet Services에 연결하는 것을 고려하십시오. 이는 공용 DNS를 관리하고 보안을 제공할 수 있습니다. 여러 위치 및 구역에 격리된 워크로드 배치에 이에 대한 예가 있습니다.
- 애플리케이션 팀은 공유 팀과 같은 부하 분산 장치를 사용하여 수평적으로 확장할 수 있습니다.
- 공유 팀은
shared/main.tf인스턴스를 추가하여 로드 밸런서에 인스턴스를 추가할 수 있습니다. - 공유 팀은 구현 플랫폼을 Kubernetes 전환할 수 있습니다.
Continuous Delivery
- 현재 소프트웨어 설치는 VPC 인스턴스가 작성될 때 수행됩니다. 프로덕션 환경에 새 소프트웨어 버전을 전달하는 것은 아직 고려되지 않았습니다.
- 공유 마이크로서비스의 경우 새 버전으로 새 VSI를 생성하고 확인 후 DNS를 조정하거나 공유 로드밸런서를 사용하여 새 버전으로 전환할 수 있습니다.
자동화, 스테이징 및 개발
- 프로덕션의 경우 팀은 각각 고유한 Schematics 작업 공간을 가질 수 있습니다. Schematics를 사용하면 상태 및 출력을 공유할 수 있는 클라우드에서 직접 Terraform 구성을 실행할 수 있습니다.
- Terraform 스크립트는 스테이징 및 개발 환경을 허용하도록 조정할 수 있습니다. 이러한 환경을 새 계정에 배치하십시오.
- 코드 및 환경이 개발, 스테이징을 거쳐 프로덕션 단계로 이동하도록 지속적 배치 환경을 구성할 수 있습니다. 롤백이 필요하십니까? 이는 어떻게 수행할 수 있을까요?
결론
시스템의 아키텍처는 클라우드 리소스의 제약 및 소유권에 영향을 받습니다. 모든 시스템 요소의 설계자가 각자의 관심사를 아키텍처에 기여하는 것이 중요합니다. 각 팀은 자신이 작성하고 릴리스하는 리소스를 제어할 수 있어야 합니다. 격리는 문제점이 발생할 가능성과 문제점이 발생하는 경우의 영향 범위를 줄입니다.