Fargate 및 CodePipeline을 통해 CI/CD 환경을 구성하였습니다. 이번 글에서는 Fargate Task 배포시에 기존에는 사용하던 Rolling Update 옵션에서 Blue/Green Deployments 옵션으로 배포하는 구성을 하였습니다.

Blue/Green Deployments?

Blue/Green Deployments는 무중단 배포의 한 방식으로 기존 버전과 새버전이 공존하는 Rolling Update와는 달리 아래 그림과 기존 버전과 새버전이 별도로 존재하는 배포 형태를 말합니다. Blue/Green Deployments의 이점은 Rolling Update 대비 두가지 버전이 공존하면서 생기는 문제가 발생하지 않으며, 배포후에도 기존 버전이 일정시간 유지를 할 수 있어 새로운 버전의 배포가 문제가 있을 경우 더 빠른 Roll-back이 가능합니다. 



전체적인 작업 요약

  • Fargate 서비스 재구성

    1. CodeDeploy 에서 사용할 IAM Role 설정

    2. 로드 밸런서 재생성

    3. BuildArtifacts files 작성

    4. Fargate 서비스 생성
  • AWS CodePipeline을 통해 파이프라인 구성

    1. CodePipeline 기본설정

    2. Source 스테이지 구성 - CodeCommit 

    3. Build 스테이지 구성 - CodeBuild 선택

    4. Deploy 스테이지 구성 - Fargate ECS(블루/그린)으로 배포 구성

작업 시작

Fargate 서비스 재구성

1. CodeDeploy 에서 사용할 IAM Role 설정

ECS 배포에 Blue/Green Deployments을 사용하는 경우는 CodeDeploy에서 배포를 처리하는 도중 ECS 및 로드 밸런서, CloudWatch등에 관하여 수정, 처리를 하기 때문에 특정 권한이 필요 합니다. 이를 위해서 IAM Role을 생성해 줍니다.


IAM 콘솔을 통해 ecsCodeDeployRole을 만들고 다음의 정책을 연결합니다.



2. 로드 밸런서 생성

지난글에서 생성했던 ECS Fargate 서비스는 배포 옵션이 Rolling Update로 설정되어 새로운 개정으로 업데이트를 하여도 배포버전을 바꿀 수는 없습니다. 그래서  Blue/Green Deployments 배포 옵션을 위해서는 기존의 서비스가 아닌 새로운 서비스를 생성해야 합니다.

새로운 서비스를 만드는 만큼 서비스에 사용되는 Application Load Balancer도 새로 생성합니다.


[1. 로드 밸런서 구성]에서 ALB 생성시 이름은 helloapp-alb로 생성합니다. 

[3. 보안 그룹 구성]에서 배포중에 테스트로 사용할 포트에 대한 anywhere (0.0.0.0/0)로 부터의 TCP port 8080 연결을 허용하는 보안 그룹을 생성 또는 기존 보안 그룹을 연결합니다.

[4. 라우팅 구성]에서 helloap-tg1과 같이 번호로 식별할 수 있는 이름과 타겟 대상은 IP Address로 설정한 타겟 그룹을 생성합니다. Fargate Blue/Green Deployments은 2개의 타겟 그룹을 이용하여 2가지 버전을 연결하기 때문입니다.

[6. 검토] 후에 [생성]을 클릭하여 로그밸런서를 생성합니다.


3. BuildArtifacts files 작성

지난 CodePipeline과 단순 ECS 배포에서는 Pipeline의 구성 할때 CodeBuild에서 SourceArtifacts를 참조하여 빌드를 하였지만 CodeDeploy에서는 별다른 Artifacts설정없이 빌드중에 생성한 imagedefinitions.json를 참조하여 Deploy가 되었다면 Blue/Green Deployments에서는 실제 Deploy에도 Artifacts 설정을 해야 합니다.
Artfacts 입력을 위해 소스 root 디렉토리에 taskdef.json, appspec.yml 파일을 생성 후 아래 내용을 입력 및 저장합니다. 추가로 기존  buildspec.yml 파일 역시 입력 받은 taskdef.json, appspec.yml을 다시 BuildArtifacts로 내보내기 위해 하단 artifacts 항목을 수정합니다. 

# taskdef.json
{
"executionRoleArn": "arn:aws:iam::01234567890:role/ecsTaskExecutionRole",
"containerDefinitions": [{
"name": "helloapp",
"image": "01234567890.dkr.ecr.ap-northeast-2.amazonaws.com/fargatedemo/helloapp",
"essential": true,
"portMappings": [{
"hostPort": 80,
"protocol": "tcp",
"containerPort": 80
}]
}],
"requiresCompatibilities": [
"FARGATE"
],
"networkMode": "awsvpc",
"cpu": "256",
"memory": "512",
"family": "helloapp"
}

# appspec.yml
version: 0.0
Resources:
- TargetService:
Type: AWS::ECS::Service
Properties:
TaskDefinition: "arn:aws:ecs:ap-northeast-2:01234567890:task-definition/helloapp"
LoadBalancerInfo:
ContainerName: "helloapp"
ContainerPort: 80

# buildspec.yml
...(중략)...
artifacts:
files:
- imagedefinitions.json
- taskdef.json
- appspec.yml
discard-paths: yes


수정 및 추가된 파일을 CodeCommit Repository에 업데이트 합니다.

user:~/hello_app$ git add .

user:~/hello_app$ git commit -m "add build artifacts files"

[master 6b109ae] add build artifacts files

 3 files changed, 45 insertions(+), 1 deletion(-)

 create mode 100644 appspec.yml

 create mode 100644 taskdef.json

user:~/hello_app$  

user:~/hello_app$ git push

오브젝트 개수 세는 중: 5, 완료.

Delta compression using up to 8 threads.

오브젝트 압축하는 중: 100% (5/5), 완료.

오브젝트 쓰는 중: 100% (5/5), 1.06 KiB | 544.00 KiB/s, 완료.

Total 5 (delta 1), reused 0 (delta 0)

To ssh://git-codecommit.ap-northeast-2.amazonaws.com/v1/repos/helloapp

   60e8b2b..6b109ae  master -> master


4. Fargate 서비스 생성

2번과 마찬가지로 Fargate 서비스도 새로 생성해야 합니다. 생성 단계는 다음과 같습니다.

  1. [클러스터] 에서 기존에 생성했던 클러스터를 선택 후, 상세페이지에서 서비스 탭의 [생성] 버튼을 클릭합니다.
  2. [단계 1: 서비스 구성]는 상단은 기존과 같이 입력합니다.
  3. [단계 1: 서비스 구성]의 하단 부분 Deployments 항목으로 이동,  [Develoymet type]을 [Blue/green deployments][Service role for CodeDeploy]에는 1번에서 생성한 IAM role을 선택 한 후 다음 단계로 진행합니다.
  4. [단계 2: 네트워크 구성]는 상단은 기존과 같이 입력합니다.
  5. [단계 2: 네트워크 구성] 하단의 [로드를 밸런싱할 컨테이너] 항목으로 이동, 현재 서비스에서 사용할 ALB인 helloapp-alb를 추가 후 리스터 포트 80 및 테스트 리스터 포트 8080을 입력하여 신규로 생성합니다.
  6. 하단의 [Additional configuration] 항목으로 이동, [Target group 1 name] [helloapp-tg1]을 선택하고 [Target group 2 name]에는 [helloapp-tg2]를 입력하여 신규 생성합니다.
  7. [단계 3: Auto Scaling (선택사항)] [단계 4: 서비스 검토]를 검토 후 [서비스 생성]을 클릭하면 서비스가 생성되고 기존의 단순 ECS 배포와는 다르게 CodeDeploy Application이 생성되었다는 메세지가 아래와 같이 하단에 추가되며 CodeDeploy에도 해당 Application이 자동으로 생성됩니다.



AWS CodePipeline을 통해 파이프라인 구성

1. CodePipeline 기본설정

CodePipeline은 설정은 대부분 지난글과 같고 CodeDeploy 항목만 다소 차이가 있습니다.

최초 CodePipeline 생성을 위해 콘솔을 열고 [시작하기] 페이지에서 [파이프라인 생성]을 클릭합니다.


[Step 1]에서 [파이프라인 이름]을 입력후 지난글에서 작성한 [Service role]을 선택 하고  [다음]을 클릭합니다.  아티팩트 스토어는 기본 설정으로 유지 합니다.


2. Source 스테이지 구성 - CodeCommit 선택 

[Step 2]에서 [소스 공급자]를 [AWS CodeCommit]을 선택, [리포지토리 이름]과 [브랜치 이름]을 각각 어플리케이션에 맞게 선택 후 [다음]을 클릭합니다.


3. Build 스테이지 구성 - CodeBuild 선택

[Step 3]에서 [빌드 공급자]를 [AWS CodeBuild]을 선택 후, 현재 생성된 빌드 프로젝트가 없기 때문에 [Create project]를 선택합니다.


[Create project]을 클릭하면 빌드 프로젝트를 생성하기 위해 CodeBuild 콘솔이 팝업창으로 뜨고 이 창을 통해 프로젝트를 생성합니다.

프로젝트 설정 항목에서 [Project name]에 빌드 프로젝트 이름을 입력합니다.


환경 설정에서 CodeBuild는 별도의 빌드서버를 계속 구동할 필요 없이 빌드가 수행 되는 순간에만 Instance가 가동되어 빌드가 진행되어 실제 Instance가 구동되는 시간만큼의 비용을 지불하게 됩니다. 이때 빌드가 진행될 환경에 대한 설정으로 환경에 맞게 [Operating system][Runtime][Runtime version], [Image version]을 설정하며 Service Role은 지난 글에서 작성한 Role을 다시 사용합니다.

* 지난글에서 작성한 Role을 사용하면 ECR에 대한 권한 설정이 되어 CodePipeline 최초 구성시에도 Build가 실패하지 않습니다.


빌드 사양 및 로그에 관한 설정은 Default로 두고 [Continue to CodePileline]을 클릭하면 다시 CodePipelline 설정 화면으로 이동합니다.

위에서 작성한 buildspec.yml 파일이 root에 없거나 파일이름이 틀린 경우 [Buildspec name] 따로 입력합니다.


CodePipeline의 Step 3의 [프로젝트 이름]에서 방금 생성한 프로젝트가 선택 된 것을 확인 후 [다음]을 클릭합니다.


4. Deploy 스테이지 구성 - Fargate ECS(블루/그린)으로 배포 구성

[Step 4]에서 [배포 공급자] [Amazon ECS(블루/그린)], 어플리케이션 이름, 배포그룹, 작업정의 파일 AppSpec 파일을 선택 후 [다음]을 클릭합니다.

Build 스테이지에서와 같이 takedef.json 파일과 appsepc.yml 파일의 경로나 이름이 틀린 경우 따로 입력합니다.


[Step 5]에서 내용을 검토 후 하단의 [파이프라인 생성]을 클릭하면 파이프 라인이 생성되고 바로 파이프 라인이 실행되며 Deploy에서 오랜 시간이 진행됩니다. 이때 세부정보를 클릭하면 배포 진행을 자세하게 볼 수 있습니다.



배포 작업 세부정보 하단을 보면 단계적으로 대체 작업이 정상적으로 시작되어 현재 모든 트래픽이 흐르고 있는 것을 확인할 수 있습니다.

그 이후에 기존 작업은 1시간 대기 후 기존 작업을 종료 하게 되어 있습니다. 상용 서비스인 경우는 QA를 수행하겠지만 현재는 Demo 용도인 만큼 수동으로 Terminate시키면 4단계 1시간 대기가 정상 종료 후 배포도 정상 완료됩니다.


수동 Terminate 시킨 후 정상 적으로 배포 완료된 모습입니다.


Fargate 을 통해 배포된 Appilication을 배포하였고 본 글에서는 CodePipeline을 이용하여 기본적인 CI/CD 구성을 하였습니다.

추가로 지난 Fargate 게시글 내용중에 생성한 작업정의(HelloappTask), 서비스(HelloService), 콘테이너(HelloContainer) 이름들과 같이 각각의 이름이 다를 경우 CodePipeline에서 해당 Appilication을 찾지 못하는 에러가 발생할 수 있어 본 글에서는 모두 helloapp으로 통일 하였습니다.

전체적인 작업 요약

  • 파이프라인 구성 준비

    1. CodeCommit에 사용자가 접근 할 수 있게 IAM 권한 설정

    2. CodeCommit에 Repository 생성 

    3. 빌드 사양 파일 추가

  • AWS CodePipeline을 통해 파이프라인 구성

    1. CodePipeline 기본설정

    2. Source 스테이지 구성 - CodeCommit 

    3. Build 스테이지 구성 - CodeBuild 선택

    4. Deploy 스테이지 구성 - Fargate ECS 로 배포 구성

    5. CodeBuild에 Amazon ECR 권한 설정

작업 시작

파이프라인 구성 준비

1. CodeCommit에 사용자가 접근 할 수 있게 IAM 권한 설정 


AWS CodeCommit의 Repository에 연결하여 소스를 업데이트 하기 위해 1.7.9이상의 Git을 설치 후 소스 폴더를 로컬 저장소로 초기화 합니다.

user:~$ sudo apt-get install git

 

...(중략)...

 

user:~$ cd hello_app/

user:~/hello_app$ git init

/home/user/hello_app/.git/ 안의 빈 깃 저장소를 다시 초기화했습니다

user:~/hello_app$



CodeCommit에 엑세스 하기 위해 IAM 을 통해 설정할 IAM 사용자에게 AWSCodeCommitFullAccess  또는 포함하는 권한을 연결합니다.


작업 PC의 터미널에서 ssh-keygen을 입력하여 홈 디렉토리 및의 .ssh/ 디렉토리에 생성된 키 파일의 내용을 확인합니다.

user:~/hello_app$ ssh-keygen


Generating public/private rsa key pair.

Enter file in which to save the key (/home/user/.ssh/id_rsa): /home/user/.ssh/codecommit_rsa          # 키 파일이 저장될 폴더 명을 입력합니다.


Enter passphrase (empty for no passphrase): **********          # 패스워드 입력

Enter same passphrase again: **********          # 패스워드 재 입력


Your identification has been saved in /home/user/.ssh/codecommit_rsa.

Your public key has been saved in /home/user/.ssh/codecommit_rsa.pub.

The key fingerprint is:

45:63:d5:99:0e:99:73:50:5e:d4:b3:2d:86:4a:2c:14 user@demo-pc

The key's randomart image is:

+--[ RSA 2048]----+ | E.+.o*.++| | .o .=.=o.| | . .. *. +| | ..o . +..| | So . . . | | . | | | | | | | +-----------------+

user:~/hello_app$ cat ~/.ssh/codecommit_rsa.pub

ssh-rsa EXAMPLE-AfICCQD6m7oRw0uXOjANBgkqhkiG9w0BAQUFADCBiDELMAkGA1UEBhMCVVMxCzAJB

gNVBAgTAldBMRAwDgYDVQQHEwdTZWF0dGxlMQ8wDQYDVQQKEwZBbWF6b24xFDASBgNVBAsTC0lBTSBDb2

5zb2xlMRIwEAYDVQQDEwlUZXN0Q2lsYWMxHzAdBgkqhkiG9w0BCQEWEG5vb25lQGFtYXpvbi5jb20wHhc

NMTEwNDI1MjA0NTIxWhcNMTIwNDI0MjA0NTIxWjCBiDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAldBMRAw

DgYDVQQHEwdTZWF0dGxlMQ8wDQYDVQQKEwZBbWF6b24xFDAS=EXAMPLE user@demo-pc



IAM 콘솔에서 앞에서 생성된 사용자를 선택 후 보안 자격 증명 탭을 선택한 다음 SSH 퍼블릭 키 업로드를 클릭, codecommit_rsa.pub 내용을 업데이트 합니다.




SSH 키를 업데이트 후 콘솔에 나타난 SSH 키 ID 를 저장합니다.



작업 PC에서 ~/.ssh/ 디렉토리에 config 파일을 생성 한 SSH 퍼블릭 키 설정을 추가 후 해당 파일의 권한을 변경합니다.

user:~/hello_app$ vim ~/.ssh/config

Host git-codecommit.*.amazonaws.com

  User APKABCDEFGH5EXAMPLE

  IdentityFile ~/.ssh/codecommit_rsa


user:~/hello_app$ chmod 600 ~/.ssh/config



터미널을 통해 접속이 잘 되는지 확인해 봅니다. 

user:~/hello_app$ ssh git-codecommit.ap-northeast-2.amazonaws.com

You have successfully authenticated over SSH. You can use Git to interact with AWS CodeCommit. Interactive shells are not supported.Connection to git-codecommit.ap-northeast-2.amazonaws.com closed by remote host.

Connection to git-codecommit.ap-northeast-2.amazonaws.com closed.



2. CodeCommit에 Repository 생성

AWS CodeCommit 콘솔로 이동, [시작하기] - [리포지토리 생성]을 클릭 합니다.  리포지토리 이름을 입력 후 [생성] 을 클릭합니다.



리포지토리를 생성하면 SSH와 HTTPS를 통한 연결방법이 표시 됩니다. 앞에서 SSH 통해 연결하는 단계를 수행하였기 때문에 URL만 복제를 하겠습니다.



작업 PC의 소스가 저장 및 git의 Local Repository 에서 해당 주소를 통해 remote 주소를 추가해줍니다.

user:~/hello_app$ git remote add origin ssh://git-codecommit.ap-northeast-2.amazonaws.com/v1/repos/helloapp

user:~/hello_app$ git remote

origin

user:~/hello_app$ 


3. 파이프라인 구성 준비 - 빌드 사양 파일 추가

Pipeline?

컴퓨터 과학에서 파이프라인(영어: pipeline)은 한 데이터 처리 단계의 출력이 다음 단계의 입력으로 이어지는 형태로 연결된 구조를 가리킨다. 이렇게 연결된 데이터 처리 단계는 한 여러 단계가 서로 동시에, 또는 병렬적으로 수행될 수 있어 효율성의 향상을 꾀할 수 있다. 각 단계 사이의 입출력을 중계하기 위해 버퍼가 사용될 수 있다.

< 파이프라인 (컴퓨팅), 출처 : 위키 백과 >


CodePipeline은 위에서 정의한 파이프라인과 같이 CodeCommit -> CodeBuild -> CodeDeploy의 단계별 진행을 통해 파이프 라인을 구성하고 다음과 같은 순서로 진행됩니다.

  1. 개발자가 소스를 업데이트
  2. CloudWatch Event(권장사항)에서 이를 감지하여 CodeBuild로 전달
  3. CodeBuild는 CodeCommit의 결과물인 Source Artifact를 이용하여 빌드 진행
  4. 빌드 성공 시 이후 빌드의 결과물인 도커 이미지를 ECR에 등록
  5. CodeDelpoy는 CodeBuild의 결과물인 Build Artifact를 이용하여 배포 진행
  6. 배포 설정이 문제가 없으면 ECS Container는 ECR의 이미지를 통해 서비스 수행

앞에서는 1단계를 위한 CodeCommit에서 Remote Repository 생성 및 등록을 하였고 해당 소스를 업데이트 할 수 있는 환경을 구성하였고 실제 Pipeline 구성은 CodeBuild 이후의 설정이 주가 되겠습니다.

CodeBuild 수행을 위해서는 CodeCommit의 결과물인 Source Artifact가 필요하며 여기에는 필드에 필요한 소스 파일과 환경파일들로 다음과 같습니다.

hello.py, DockerFile, requirements.txt 3개 파일은 Local에서 빌드시에도 사용하는 파일이지만 buildspec.yml파일이 추가 되었습니다.

해당 파일은 Local 아닌 AWS에서 Build를 수행 하기 위해서는 실제 빌드에 수행되는 명령어와 환경변수등 빌드 사양을 정의하여 CodeBuild에 알려주기 위한 용도로 사용되며 소스 코드 root 디렉토리에 buildspec.yml을 생성 하여 아래 내용을 추가해 줍니다.

version: 0.2

phases:
pre_build:
commands:
- echo Logging in to Amazon ECR...
- aws --version
- $(aws ecr get-login --region $AWS_DEFAULT_REGION --no-include-email)
- REPOSITORY_URI=01234567890.dkr.ecr.ap-northeast-2.amazonaws.com/fargatedemo/helloapp
- COMMIT_HASH=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
- IMAGE_TAG=${COMMIT_HASH:=latest}
build:
commands:
- echo Build started on `date`
- echo Building the Docker image...
- docker build -t $REPOSITORY_URI:latest .
- docker tag $REPOSITORY_URI:latest $REPOSITORY_URI:$IMAGE_TAG
post_build:
commands:
- echo Build completed on `date`
- echo Pushing the Docker images...
- docker push $REPOSITORY_URI:latest
- docker push $REPOSITORY_URI:$IMAGE_TAG
- echo Writing image definitions file...
- printf '[{"name":"helloapp","imageUri":"%s"}]' $REPOSITORY_URI:$IMAGE_TAG > imagedefinitions.json
artifacts:
files:
- imagedefinitions.json


예제의 내용은 다음과 같습니다.

1. pre_build 단계에서는 다른 Fargate 예제에서 처럼 ECR에 로그인 후 이미지 별로 사용할 고유의 tag를 생성합니다.

2. build 단계에서는 DockerFile을 통해 실제 이미지를 빌드 후 pre_build에서 생성한 tag를 지정합니다.

3. post_build 단계에서는 고유의 tag와 latest tag의 2개의 tag와 함께 이미지를 ECR에 푸쉬 합니다.

    추가로 imagedefinitions.json을 결과물로 생성하여 CodeDeploy에서 이를 참조하여 ECS에 작업을 배포 합니다.


REPOSITORY_URI 값(012345678910.dkr.ecr.us-west-2.amazonaws.com/hello-world)을 해당 도커 이미지의 Amazon ECR 리포지토리 URI(이미지 태그 제외)로 바꿉니다. helloapp은 서비스에서 사용하는 작업 정의에서 도커 이미지를 참조하는 컨테이너 이름으로 바꿉니다.



buildspec.yml가 포함된 Local Repository를 Commit후 Remote로 푸쉬합니다.

user:~/hello_app$  git add .

user:~/hello_app$  git commit -m "first commit."

[master (최상위-커밋) d514011] first commit.

 4 files changed, 56 insertions(+)

 create mode 100644 Dockerfile

 create mode 100644 buildspec.yml

 create mode 100644 helloapp/hello.py

 create mode 100644 requirements.txt

user:~/hello_app$  

user:~/hello_app$  git push --set-upstream origin master

오브젝트 개수 세는 중: 7, 완료.

Delta compression using up to 8 threads.

오브젝트 압축하는 중: 100% (5/5), 완료.

오브젝트 쓰는 중: 100% (7/7), 1.21 KiB | 310.00 KiB/s, 완료.

Total 7 (delta 0), reused 0 (delta 0)

To ssh://git-codecommit.ap-northeast-2.amazonaws.com/v1/repos/helloapp

 * [new branch]      master -> master

'master' 브랜치가 리모트의 'master' 브랜치를 ('origin'에서) 따라가도록 설정되었습니다.




AWS CodePipeline을 통해 파이프라인 구성

1. CodePipeline 기본설정

CodePipeline은 마법사에 따라 간단하게 진행 됩니다.

최초 CodePipeline 생성을 위해 콘솔을 열고 [시작하기] 페이지에서 [파이프라인 생성]을 클릭합니다.



[Step 1]에서 [파이프라인 이름]을 입력후 [다음]을 클릭합니다. Service role 및 Role name, 아티팩트 스토어는 기본 설정으로 유지 합니다.


2. Source 스테이지 구성 - CodeCommit 선택 

[Step 2]에서 [소스 공급자]를 [AWS CodeCommit]을 선택, [리포지토리 이름][브랜치 이름]을 각각 어플리케이션에 맞게 선택 후 [다음]을 클릭합니다.

변경 탐지 옵션은 소스 변경시 바로 업데이트 될 수 있도록 권장사항인 CloudWatch Event를 그대로 두면 됩니다.

추가로 소스 공급자가 CodeCommit과 같은 AWS 자원이 아닌 외부 자원인 GitHub이나 BitBucker등일 때는 Webhook 설정을 해야 합니다.


3. Build 스테이지 구성 - CodeBuild 선택

[Step 3]에서 [빌드 공급자]를 [AWS CodeBuild]을 선택 후, 현재 생성된 빌드 프로젝트가 없기 때문에 [Create project]를 선택합니다.



[Create project]을 클릭하면 빌드 프로젝트를 생성하기 위해 CodeBuild 콘솔이 팝업창으로 뜨고 이 창을 통해 프로젝트를 생성합니다.
프로젝트 설정 항목에서 [Project name]에 빌드 프로젝트 이름을 입력합니다.



환경 설정 화면입니다. CodeBuild는 별도의 빌드서버를 계속 구동할 필요 없이 빌드가 수행 되는 순간에만 Instance가 가동되어 빌드가 진행되어 실제 Instance가 구동되는 시간만큼의 비용을 지불하게 됩니다. 이때 빌드가 진행될 환경에 대한 설정으로 환경에 맞게 [Operating system], [Runtime], [Runtime version], [Image version]을 설정하며 Service Role 및 Role name은 기본 설정으로 유지합니다.


* Role name은 CodeBuild가 진행될 때 ECR의 도커 이미지를 기반으로 빌드 후 다시 업데이트 하기 때문에 해당 Role에 ECR 에 접근할 권한 업데이트가 필요 합니다.




빌드 사양 및 로그에 관한 설정은 Default로 두고 [Continue to CodePileline]을 클릭하면 다시 CodePipelline 설정 화면으로 이동합니다.

위에서 작성한 buildspec.yml 파일이 root에 없거나 파일이름이 틀린 경우 [Buildspec name] 따로 입력합니다.



CodePipeline의 Step 3의 [프로젝트 이름]에서 방금 생성한 프로젝트가 선택 된 것을 확인 후 [다음]을 클릭합니다.


4. Deploy 스테이지 구성 - Fargate ECS 로 배포 구성

[Step 4]에서 [배포 공급자] [Amazon ECS], [클러스터 이름], [서비스 이름]을 ECS에서 생성한 사용했던 클러스터 및 서비스 이름을 선택 후 [다음]을 클릭합니다.


5. CodeBuild에 Amazon ECR 권한 설정

[Step 5]에서 내용을 검토 후 하단의 [파이프라인 생성]을 클릭하면 파이프 라인이 생성되고 바로 파이프 라인이 실행 되지만 CodeBuild에서 언급한 것과 같이 권한이 부족하여 빌드 단계에서 실패하게 됩니다.


권한 부여를 위해 IAM 콘솔에서 CodeBuild에서 생성한 role인 [code-helloapp-service-role]에 아래와 같이 [AmazonEC2ContainerRegistryPowerUser] 정책을 부여 합니다.



권한 업데이트 후 CodePipeline 콘솔에서 [변경 사항 릴리즈]를 통해 파이프라인을 다시 수행하면 다음과 같이 단계별 진행사항을 볼 수 있습니다.



AWS ECS fargate를 사용한 Appilication 배포 - 2

지난 글에서는 Fargate를 통해 Appilication을 배포하였고 본 글에서는 Appilication이 도커 이미지 또는 작업이 업데이트 되는 경우와 기타 옵션들에 대해 좀 더 자세히 확인하도록 하겠습니다.


웹 어플리케이션 업데이트

지난 글에는 간단하게 웹에 접근했을 때 "Hello World!"를 출력하였는데 /welcome 으로 접근할때는 "Welcome!"을 출력하는 엄청난 기능을 추가하였습니다.
# hello.py
from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
return "Hello World!"

@app.route("/welcome")
def hello():
return "Welcome!"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=80)



소스가 업데이트 되었으니 지난글에서와 같이 우선 ECR에 푸쉬 하도록 하겠습니다.

푸쉬 명령어 4개 중에 1번의 로그인 과정은 최초 로그인 후 12시간이 지속되니 로그인 세션이 남아있다면 생략 가능 합니다. 추가로 푸쉬전에 태깅을 할때 latest로 태깅을 하면 지난 푸쉬 이미지 Tag과 겹치니 버전과 같은 고유한 숫자, 문자등으로 식별할 수 있도록 구분하여 태깅합니다. 

이번 푸쉬 명령어에서는 최초에서 변경된 내용만 업데이트 되었습니다.


(venv) user:~/hello_app$ docker build -t fargatedemo/helloapp .

Sending build context to Docker daemon  67.66MB

Step 1/8 : FROM python:alpine

 ---> 1a8edcb29ce4

Step 2/8 : LABEL Name=flaskapp Version=0.0.1

 ---> Using cache

 ---> 840ae2afa937

...(중략)...

Successfully built 74b72d5f1369

Successfully tagged fargatedemo/helloapp:latest

(venv) user:~/hello_app$  

(venv) user:~/hello_app$ docker tag fargatedemo/helloapp:latest 111111111111.dkr.ecr.ap-northeast-2.amazonaws.com/fargatedemo/helloapp:revision3
(venv) user:~/hello_app$
(venv) user:~/hello_app$ docker push 111111111111.dkr.ecr.ap-northeast-2.amazonaws.com/fargatedemo/helloapp:revision3
The push refers to repository [111111111111.dkr.ecr.ap-northeast-2.amazonaws.com/fargatedemo/helloapp]
f2ea5f782ba9: Pushed 
767a8a839569: Pushed 
cb0f6e36ebca: Pushed 
7158e09cb118: Layer already exists 
8643e4accddc: Layer already exists 
43e8a7decf15: Layer already exists 
7484166a246c: Layer already exists 
1c862c0e1a30: Layer already exists 
7bff100f35cb: Layer already exists 
latest: digest: sha256:d192735e68903be86a6f9bc0c33c55c16c4d123640571b11da53c0c1220ccf54 size: 2200
(venv) user:~/hello_app$


푸쉬가 끝난 후 ECR에서 repository를 확인하면 다음과 같이 image가 추가 되어 있습니다.



새로운 이미지를 생성하였으니 작업정의도 업데이트가 필요 합니다. 업데이트를 하기 위하여 작업정의 항목에서 지난글에서 작성한 작업정의를 체크한 후 새 개정 생성을 클릭합니다.



지난글에서 작성하였던 작업정의 생성 화면과 거의 유사한 설정 화면이 나옵니다. 설정한 것들은 현재는 크게 바뀌지 않았고 소스 코드가 담긴 도커 이미지가 바뀌었으니 하단에 컨테이너 정의 항목으로 이동하여 해당 컨테이너를 클릭하여 설정화면이 나오면 이미지의 URL을 새로 업데이트 된 이미지의 URL로 변경합니다.



다음은 컨테이너 항목 창에서 업데이트를 클릭하여 나온 후 최하단의 생성 버튼을 눌러서 새 개정을 생성해 주면 다음과 같이 개정이 추가 됩니다.

추후에도 개정을 도커이미지 업데이트(소스 변화)에 따라 생성시 버젼별로 작업을 관리 할 수도 있고 서비스 업데이트 후 문제가 발생시 지난 버전의 작업으로 빠르게 롤백이 가능합니다.



새로운 작업정의를 바탕으로 서비스도 업데이트가 필요 합니다. 서비스 업데이트를 위해 클러스터 항목에서 지난글에서 작성한 서비스가 포함된 클러스터를 클릭하면 다음과 같이 클러스터에 대한 상세 정보가 표시 됩니다. 업데이트를 할 서비스를 체크 후 업데이트 합니다.



서비스 생성시 화면과 유사한 1단계 설정 화면이 표시되는데 Revision을 최신 버전으로 변경하고 새 배포 적용에 체크를 하고 다음 단계로 넘어갑니다.

추가로 2단계 네트워크 설정 및 3단계 오토스케일링도 변동이 없다면 4단계 검토 화면까지 넘어가서 서비스 업데이트를 적용합니다.



서비스가 업데이트 되면 Fargate는 작업 개수, 최소 정상 상태 백분율, 최대 백분율 배포를 수행합니다.

배포 중에 배포 화면은 다음과 같이 새로 배포된 작업정의 개정이 PRIMARY이지만 기존 작업도 실행하다 안정화 된 후 제외됩니다.



역시 작업탭에서도 Task2의 기존 작업 외에 Task 3이 프로비저닝 -> 펜딩 -> 런닝 상태로 진행 되어 정상 작동시 서비스를 인계 후 기존 작업은 추후에 중지 됩니다.



서비스 업데이트 후 추가로 한 /welcome 경로에 대한 서비스가 추가 되었습니다.


부록

배포 관련 옵션

지난 글에서 배포 관련 옵션인 작업 개수, 최소 정상 상태 백분율, 최대 백분율 배포에 대하여 간략하게 넘겼는데 다음과 같습니다.

작업 개수 - 사용자가 원하는 평상시 원하는 실제 서비스 작업 숫자

최소 정상 상태 백분율 - 작업 개수 대비 배포가 진행중 작업의 stuatus RUNNING의 필수 백분율

최대 백분율 - 작업 개수 대비 배포 진행되는중 PROVISIONING, RUNNING, PENDING 등의 모든 상태가 가능한 백분율


예를 들면 작업개수가 2 이고 최소가 50, 최대가 100이면 배포를 진행하기 위해 이미 실행중이던 작업 하나를 중단하는 상황이 발생 합니다.

최소와 최대의 비율에 따라 대략적으로 아래표와 같이 진행합니다.

결론은 클러스터 자원을 적게 하기 위해서는 1~2번 방법을 가용성을 위해서는 3~4번을 사용하면 되겠습니다.

다만 Fargate 특성상 초단위로 사용한 비용만 청구 되고 실제 4번 단계로 진행되어도 작업개수의 200%로 작업이 진행되는 10분 내외이기 때문에 최대 백분율은 default인 200%가 좋을듯 합니다.

 

 최소정상상태

 최대 백분율

 작업 분류

 배포전

 단계 1

 단계 2

 단계 3

 단계 4

50% 

 100%

 기존 작업

 2(success)

 1(success)

 1(success)

 

 

 배포 대상 작업

 

 

 1(success)

 1(success)

 2(success)

 50% 

150% 

 기존 작업

 2(success)

 2(success)

 1(success)

 

 

 배포 대상 작업

 

 1(pending)

 1(pending)

 1(success) 1(pending)

 2(success)

 100%

150% 

 기존 작업

 2(success)

 2(success)

 1(success) 

1(success)  

 

 배포 대상 작업

 

 1(pending)

 1(success) 1(pending)

 2(success)

 2(success)

 100%

 200%

 기존 작업

 2(success)

 2(success)

 2(success)

 

 

 배포 대상 작업

 

 2(pending)

 2(success)

 2(success)

 


스케일 업

AWS 컴퓨팅 자원들은 트래픽이 증가할 경우 AutoScaling을 통해 자동으로 Scale-Out 을 구현할 수 있습니다. Fargate는 Scale-Out은 물론 Scale-Up도 운영에 큰 부담이 가지 않게 적용 가능합니다. 개발용이나 초창기 어플리케이션은 최하 사양으로도 사용하다 규모나 사용성이 올라가면 손쉽게 Scale-Up을 할 수 있는 것입니다.

상단에서 작업했던 작업 정의에서 새 개정을 생성시 vCPU 및 메모리를 다시 설정할 수 있는데 아래 사진처럼 새 개정 생성을 만들고 새로운 개정을 통해 서비스를 재시작 하기만 하면 위에서 도커 이미지를 업데이트 한것과 같이 Fargate에서 자동으로 작업을 전환합니다.






AWS Fargate 소개

AWS Fargate는 AWS의 컨테이너 서비스인 ECS에 포함된 하나의 옵션으로 2017년 부터 시작된 서비스 이며 2018년 말경 한국리전에서도 사용할 수 있게 되었습니다.

기존의 ECS가 Amazon EC2 인스턴스 클러스터를 관리하고, 인스턴스 유형을 선택하고, 컨테이너의 일정을 관리하고, 클러스터 사용률을 최적화해야 했던 것과는 다르게 EC2 자원 관리를 AWS에 맡겨 서버의 프로비저닝이나 스케일링에 대해 걱정할 필요없이 컨테이너 및 어플리케이션에 집중할 수 있습니다. 추가로 네트워크, 보안 및 서비스 통신에 대한 완벽한 제어 기능을 제공하며 보안, 네트워킹, 액세스 제어, 개발자 툴링, 모니터링 및 로깅을 위해 AWS 서비스와 기본적으로 통합되어 있습니다.


서버를 관리하지 않는 것은  AWS의 다른 ServerLess 서비스인 Lambda와 비슷하여 컨테이너 버전의 ServerLess라고 할 수 있으며 성능이나 시간제한이 있었던 Lambda의 단점을 어느정도 채워줄 수 있는 옵션이 될 수 있습니다.


비용

아래는 AWS 홈페이지에 소개된 비용으로 1CPU 1GB 메모리 기준 시간당 약 0.051$의 요금으로 같은 스펙인 t2.micro 의 0.013$ 보다는 비싸편 입니다.

 
  • 아시아 태평양(서울)
요금
시간별 vCPU당0.04656 USD
시간별 GB당0.00511 USD

다만 지원 되는 구성이 다음와 같이 0.25개부터 가능하여 다소 절약은 가능합니다(그것보다 Fargate 덕분에 감소하는 인적 리소스로 인한 감소가 더 클것입니다.)

CPU
메모리 값
0.25vCPU0.5GB, 1GB, 2GB
0.5vCPU최소 1GB 및 최대 4GB(1GB씩 증가)
1vCPU최소 2GB 및 최대 8GB(1GB씩 증가)
2vCPU최소 4GB 및 최대 16GB(1GB씩 증가)
4vCPU최소 8GB 및 최대 30GB(1GB씩 증가)


작업환경 전 준비사항

1. 로컬 데스크탑 환경 - 본 글에서는 ubuntu 리눅스로 진행하지만 간단한 소스 코드에 AWS 콘솔위주이기 때문에 크게 상관 없습니다.

2. AWS 계정

3. 도커에 대한 기본 지식


작업 시작

IAM 계정 생성

AWS를 사용하며 작업중 aws cli를 사용을 위해 Access 키가 필요하여 필요한 IAM 계정을 생성합니다. 다만 aws cli는 간단하게 명령어 만으로 많은 작업을 수행할 수 있는 강력한 도구이기 때문에 막강한 권한을 가진 root 계정 또는 콘솔 로그인이 가능한 계정 보다는 해당 Appication에서 사용하는 특정 권한만을 허용한 계정을 사용하는 것이 보안에 좋습니다.


맨 처음 IAM 설정 권한을 가진 콘솔 계정으로 로그인하여 IAM을 검색, IAM 설정 페이지로 이동 후 user 생성을 위해 사용자 항목으로 이동을 합니다.


사용자 추가를 클릭하여 사용자 추가 화면으로 이동합니다.


1단계에서는 유저 이름 및 엑세스 유형을 입력합니다. 해당 IAM 계정은  Access Key를 필요로 하는 프로그래밍용 계정이므로 프로그래밍 방식 엑세를 선택 후 다음을 클릭합니다.



2단계는  권한 설정을 하는 페이지로 IAM과 ECS, ECR에 관해 깊은 이해가 있으면 필요한 권한만을 붙이는 것이 좋겠지만 현재 작업에서는 기존에 AWS에서 생성되는 작업으로 진항하겠습니다. 

정책 연결을 위해 기존 정책 직접 연결을 클릭 후 ECR 관련 작업을 위해 AmazonEC2ContainerRegistryFullAccess와 ECS 작업을 위해 AmazonEC2ContainerServiceFullAccess 정책을 각각 검색하여연결해 줍니다. 3단계는 해당 IAM에 Tag를 달아주기 위해 Key에 Name Value에 1단계에서 입력한 IAM롤의 이름을 입력하고 다음을 클릭합니다.

4단계에서는 1~3단계에서 작업한 내용을 확인 후 실제 생성을 위해 사용자 만들기를 클릭합니다.



5단계는 Access Key를 확인하는 단계로 ID와 비밀 키가를 확인하거나 CSV 파일로 다운받아 관리할 수 있습니다.

비밀 액세스 키 밑의 표시를 누르면 위와 같이 표시 되니 잘 관리해야 합니다. 계정의 Access Key는 본 페이지 외에서는 확인할 수 없고 분실할 경우에는 IAM 권한을 가진 계정으로 키를 다시 생성하여 다른 키를 사용해야 합니다.


2. 도커 이미지 생성 및 ECR에 등록

- aws cli 환경설정

우선  어플리케이션을 AWS에 push 하기 위해 먼저 aws cli 환경설정을 합니다. aws cli는 Python pip를 통해 설치하는데 시스템 전체에 영향을 주지 않기 위해 virtualenv를 설치합니다.

user:~$ sudo apt-get update -y

...(중략)...

user:~$ sudo apt-get install -y python-virtualenv

...(중략)...

user:~$ mkdir hello_app

user:~$ cd hello_app/

user:~/hello_app$ 

user:~/hello_app$ virtualenv -p python3 venv

Running virtualenv with interpreter /home/user/flaskapp/venv/bin/python3
Using real prefix '/usr'
New python executable in /home/user/hello_app/venv/bin/python3
Also creating executable in /home/user/hello_app/venv/bin/python
Installing setuptools, pkg_resources, pip, wheel...done.
user:~/hello_app$
user:~/hello_app$ source venv/bin/activate

(venv) user:~/hello_app$ 

Python 3.6.7



다음으로 awscli를 설치하고 기본 설정을 합니다. 설정은 아래와 같이 위에서 설정한 IAM 계정의 Access Key와 비밀키, 기본 리전과 기본 출력 형식을 지정합니다.


(venv) user:~/hello_app$ pip install awscli --upgrade

...(중략)...

(venv) user:~/hello_app$ aws configure

AWS Access Key ID [****************L2DQ]: AKIAIAI5N5YP57AOVZFA

AWS Secret Access Key [****************KEHt]: ssf+...(중략)...DDvp

Default region name [ap-northeast-2]: 

Default output format [json]: 



 -  Docker 이미지용 Application 작성

aws에 이미지를 올리고 컨테이너를 컨트롤할 준비가 되었으면 실제 aws에 올릴 이미지를 작성하겠습니다. 이미지를 생성하기 위해 위해 가장 간단한게 웹페이지에 "Hello World!"를 출력하는 프로그램을 아래와 같이 작성하였습니다. 해당 프로그램은 모든 소스로 부터 접근이 가능하며 80포트로 서비스 하도록 설정되었습니다.

# hello.py
from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
return "Hello World!"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=80)


 - ECR에 repository 생성

다음으로 해당 프로그램을 실제 AWS Fargate로 서비스를 하기 위해 ECR에 등록 합니다. 

참고로 ECR은 Amazon Elastic Container Registry의 약자로 사용자가 Docker 컨테이너 이미지를 손쉽게 저장, 관리 및 배포할 수 있게 해주는 완전관리형 Docker 컨테이너 레지스트리입니다. 쉽게 얘기하면 Fargate를 포함한 아마존의 컨테이너 서비스에서 사용하기 위한 도커 이미지 저장소입니다.


ECR에 등록하기 위해서는 최초에는 AWS 콘솔에서 ECR을 검색한 후 repository를 작성합니다.


다음 구성화면에서 repository 이름을 작성하는데 콘솔에서 보여주는 것과 같이 네임스페이스/서비스 형식의 이름으로 작성할 수 있으며 대문자는 사용 불가능 합니다.


위의 AWS 콘솔에서는 "fargagedemo/helloapp"으로 repository를 작성하였고 aws cli 명령어는 다음과 같습니다.

(venv) user:~/hello_app$ aws ecr create-repository --repository-name fargatedemo/helloapp

{

    "repository": {

        "repositoryArn": "arn:aws:ecr:ap-northeast-2:111111111111:repository/fargatedemo/helloapp",

        "registryId": "111111111111",

        "repositoryName": "fargatedemo/helloapp",

        "repositoryUri": "111111111111.dkr.ecr.ap-northeast-2.amazonaws.com/fargatedemo/helloapp",

        "createdAt": 1547993101.0

    }

}

(venv) user:~/hello_app$ 


 - ECR에 repository에 Docker Image 올리기

repository 생성 후에 ECR 메인 페이지에서 해당 repository이름을 클릭하면 다음과 같이 repository에 포함된 이미지 리스트가 표시되며 최초 이미지 등록시 푸쉬 명력 보기를 통해 손쉽게 도커 이미지를 ECR에 올릴 수 있습니다.


푸쉬 명령은 다음과 같으며 AWS CLI를 통해 직접 명령어를 입력시 오탈자등으로 인해 잘못 입력되기 쉬운데 친절하게 붙여준 텍스트를 단계별로 수행만 하면 이미지가 저장됩니다.


Command 입력 결과는 다음과 같습니다. 로그인 수행 시 최초 명령의 결과값을 그대로 복사하여 다시 입력하면 로그인이 되고 그 이후에 순서대로 2. 빌드 -> 3. 태깅 -> 4. 푸쉬를 진행 합니다.

푸쉬는 모든 이미지가 Pushed가 되면 종료 된 것입니다.

(venv) user:~/hello_app$ (aws ecr get-login --no-include-email --region ap-northeast-2)

docker login -u AWS -p eyJwYXlsb2FkIjoiY1VkeE1sc3d2M1FLbEU0dHVtZzA3aVh0K0F1SWoySzFQZG1OYy9GYjYvYy9MYnR1bnVJNll1b2I1bX

...(중략)...

9uIjoiMiIsInR5cGUiOiJEQVRBX0tFWSIsImV4cGlyYXRpb24iOjE1NDgwMzcyNDh9 https://111111111111.dkr.ecr.ap-northeast-2.amazonaws.com

## 위 명력을 그대로 입력 ##

(venv) user:~/hello_app$ 

(venv) user:~/hello_app$ docker login -u AWS -p eyJwYXlsb2FkIjoiY1VkeE1sc3d2M1FLbEU0dHVtZzA3aVh0K0F1SWoySzFQZG1OYy9GYjYvYy9MYnR1bnVJNll1b2I1bX

...(중략)...

9uIjoiMiIsInR5cGUiOiJEQVRBX0tFWSIsImV4cGlyYXRpb24iOjE1NDgwMzcyNDh9 https://111111111111.dkr.ecr.ap-northeast-2.amazonaws.com


Login Succeeded

(venv) user:~/hello_app$ docker build -t fargatedemo/helloapp .

Sending build context to Docker daemon  17.34MB

Step 1/8 : FROM python:alpine

 ---> 1a8edcb29ce4

Step 2/8 : LABEL Name=flaskapp Version=0.0.1

 ---> Using cache

 ---> 840ae2afa937

...(중략)...

Successfully built 74b72d5f1369

Successfully tagged fargatedemo/helloapp:latest

(venv) user:~/hello_app$  

(venv) user:~/hello_app$ docker tag fargatedemo/helloapp:latest 111111111111.dkr.ecr.ap-northeast-2.amazonaws.com/fargatedemo/helloapp:latest
(venv) user:~/hello_app$
(venv) user:~/hello_app$ docker push 111111111111.dkr.ecr.ap-northeast-2.amazonaws.com/fargatedemo/helloapp:latest
The push refers to repository [111111111111.dkr.ecr.ap-northeast-2.amazonaws.com/fargatedemo/helloapp]
55e63f5d5562: Pushed 
642a791f9fd2: Pushed 
76e39cec4c1f: Pushed 
7158e09cb118: Pushed 
8643e4accddc: Pushed 
43e8a7decf15: Pushed 
7484166a246c: Pushed 
1c862c0e1a30: Pushed 
7bff100f35cb: Pushed 
latest: digest: sha256:1b0130a147ac48795d9f14831cea3028ea7872b497ce64fb6bcebcd22c01256f size: 2200
(venv) user:~/hello_app$


3. 작업 정의

등록한 이미지를 바탕으로 작업을 정의 합니다. 작업(Task)은 같이 실행되는 한개 이상의 컨테이너의 집합체를 말합니다. 작업정의를 통해 하나 이상의 컨테이너 실행될때 컨테이너의 사용할 도커 이미지 사용할 CPU, 메모리, 네트워크 등을 설정할 수 있습니다.


 - 작업 정의 생성

작업 정의를 생성 하기 위해 작업 정의를 선택 후 새 작업 정의 생성을 눌러 작업 정의를 생성합니다.

다음으로 EC2 자원을 정의하지 않는 Fargate를 선택 후 다음단계로 진행합니다.


2단계에서 상단의 항목에서 필수 입력할 항목은 작업이름입니다.

그 외에 작업 역할은 해당 작업이 다른 AWS 서비스를 API를 통해 호출하여 사용할 경우 지정합니다. 예를 들면 RDS에 table을 수정한다면 RDS write권한을 가진 Role을 선택해 줍니다. 해당 예제에서는 없음을 선택하였습니다.

호환성 요구 사항 및 네트워크 모드는 1단계에서 FARGATE 선택시 선택 할 수 없는 옵션이 없이 Default값을 사용합니다.






하단 항목에서는 첫째로 작업이 실행되는 ECS 및 ECR 관련 권한을 가진 IAM Role을 선택하는데 안내와 같이 기본으로 제공되는 ecsTaskExecutionRole을 생성하여 사용합니다.

둘째로 작업 크기는 FARGATE에서만 필수 항목으로 EC2 유형을 선택한 경우는 Instance에 대해 제어하며 관리하기 vCPU 및 메모리에 관하여 이미 Instance에 할당된 자원 내에서 사용하겠지만 Instance를 관리하지 않는 FARGATE는 작업에 사용될 자원만 지정하여 지정된 자원만큼에 대해 비용을 지불하는 방식이기 때문입니다.

세번째는 컨테이너 추가를 클릭하여 도커 이미지를 통해 실제 작업에서 사용할 컨테이너를 구성합니다.

테이너는 1개 이상이 등록가능하지만 AWS에서는 기본적으론 개별적인 컨테이너 프로비저닝, 스캐일링을 할 수 있도록 개별적으로 작업 정의를 사용하길 권하고 있습니다. 그 예외의 경우는 다음과 같습니다.

 - 컨테이너가 공통 수명 주기를 공유하는 경우(즉 함께 시작하고 종료되어야 함).

 - 컨테이너가 동일한 기본 호스트에서 실행되어야 하는 경우(즉 로컬호스트 포트에서 한 컨테이너가 다른 컨테이너를 참조함)

 - 컨테이너가 리소스를 공유하길 원하는 경우.

 - 컨테이너가 데이터 볼륨을 공유하는 경우



 - 작업 정의에 컨테이너 추가

컨테이너 추가를 클릭하여 나타난 다음의 정보를 입력하고 추가를 클릭하면 컨테이너가 등록됩니다.

사용할 이미지는 사용할 이미지의 URL을 입력하는데 아래 첨부된 스샷과 같이 ECR에서 간단하게 복사하여 사용하면 됩니다.

프라이빗 레지스트리 인증은 개별적으로 사용중인 Docker Repository를 사용하는 경우 인증관련 옵션을 설정하는 항목으로 본 예제에서는 사용하지 않습니다.

포트 매핑은 컨테이너가 사용할 포트를 지정하는 것으로 따로 웹으로 별도의 서비스와 연동하지 않는 단순 작업은 지정하지 않아도 되며 본 예제의 코드에서는 80포트를 사용하기 때문에 80으로 지정합니다.




ECR에서 작업에 사용할 Repository 복사



컨테이너를 등록 후 등록된 컨테이너를 확인 후 생성을 클릭하여 작업정의를 생성합니다.


4. 클러스터 및 서비스 생성

ECR을 통해 도커 이미지를 등록했고 ECS에서 작업정의를 통해 작업정의를 작성했다면 다음은 실제로 작업들을 수행하기 위해 클러스터를 구성하고 서비스를 작성하는 단계입니다.
클러스터는 일반적으로 비슷한 역할 또는 기능을 수행하는 집단, 장치등을 묶어서 하나의 집단 장치처럼 작용하게 하는 것으로 IT에서는 주로 컴퓨팅 자원을 묶어서 사용하는데 많이 사용되어 집니다.
ECS에서의 클러스터 또한 리전별로 고유한 서비스 또는 작업들의 논리적인 묶음으로 다수의 서비스 및 작업들을 포함할 수 있습니다.

 - 클러스터 생성

클러스터를 생성하기 위해 클러스터 항목으로 이동하여 클러스터 생성을 클릭합니다.


EC2 자원을 사용하지 않기 때문에 네트워킹 전용을 선택 후 다음단계로 진행합니다.


클러스터 이름을 입력한 후 생성을 클릭합니다.

네트워킹에서 VPC 생성 옵션은 클러스터에서 사용할 신규 VPC를 생성할 때 사용하는 옵션으로 이미 VPC가 구성되어 있고 해당 VPC에서 어플리케이션을 서비스 할 경우 생략 하고 진행하면 되겠습니다.


 - 서비스 생성

클러스터를 생성 확인을 한 후 해당 클러스터를 클릭하면 해당 클러스터에 서비스를 작성 할 수 있습니다.

AWS ECS에서 서비스는 작업 정의에서 정의된 작업들을 실제로 운용 하는 말그대로 서비스 단위 라고 할 수 있습니다. 모놀리식 서비스라면 전체 어플리케이션의 서비스를 뜻하겠고 마이크로서비스 라면 각각의 모듈서비스 들이 될 수 있습니다..

클러스터 내에서는 각각의 서비스들은 작업 정의에서 정해진 작업들을 기반으로 네트워크 설정, 가용성 설정등을 하여 실제 서비스를 구현합니다.


서비스 생성을 위해서 클러스터 상세페이지에서 서비스 탭의 생성 버튼을 클릭합니다.


서비스 생성에서 1단계는 서비스 구성으로 다음과 같은 항목을 입력합니다.

시작 유형은 FARGATE를 선택, 작업 정의는 사용할 작업과 Revision을 선택합니다. Revision(개정)은 작업 정의에서 해당 작업에서 새로운 버전 업데이트 또는 작업의 설정이 변경할 경우 새로운 버전을 뜻합니다.

플랫폼 버전은 ECS에서 FARGATE를 선택한 경우 FARGATE의 플랫폼 버전을 뜻하며 최신으로 선택하였습니다.

클러스터는 기존에 구성한 클러스터중 포함될 클러스터를 선택합니다.

작업 개수 및 최소 정상 상태 백분율, 최대 백분율은 배포랑 가용성과 연관된 항목으로 자세한 내용은 다음 글에서 기재하도록 하고 현재는 작업 개수를 2개 적용하고 다음 단계를 눌러 단계 2로 넘어갑니다.





서비스 생성 2단계는 네트워크 구성입니다.

기존에 사용중인 VPC 및 서브넷을 입력해 줍니다. 가용성을 위해 서브넷은 2개 이상의 가용 영역을 선택하며 보안그룹은 적당히 inbound에 80을 열어주면 되겠습니다. 추가로 보안을 위해 서브넷은 Private 망을 선택하였으며 퍼블릭 IP는 할당하지 않게 설정하였습니다.



아래로 스크롤을 내리면 ELB 설정을 할 수 있습니다. 상태 검사 유예 기간은 ELB에서 상태 검사를 진행시 유예 기간을 설정하는 것으로 너무 수치가 낮을 경우 작업이 시작시간이 다소 걸리는 경우 장애로 판정을 하고 이로 인해 계속 작업이 재시작 되는 경우가 있을 수 있습니다. 

Load Balancing은 타겟 그룹은 설정되지 않은 미리 작성된 Application Load Balancing을 사용하였습니다.

Route 53을 통한 DNS 설정은 해당 글에서는 다루지 않을 것이기 때문에 체크를 해제한 후 다음단계로 진행합니다.





3단계에서는 오토 스케일링 설정을 합니다. 실제 서비스를 구성할 경우 가용성 및 확장성을 위해 활성화를 시켜주시면 되고 현재는 데모용이기 때문에 비활성으로 진행합니다. Default는 비활성입니다.

3단계에서 다음단계를 선택 후 4단계는 검토를 한 후 하단의 서비스 생성을 클릭하면 서비스가 생성 됩니다.



 - 서비스 확인

서비스가 완성되면 다음과 같이 서비스 상태가 PROVISIOING -> Pending -> RUNNING의 순서로 바뀌며 실행중인 개수와 대기중인 개수도 변동하게 됩니다. 또한 FARGATE는 로드 밸런스의 컨트롤 하에 사용자가 설정한 원하는 개수에 맞춰 정상 작업을 유지시켜 줍니다.  



미리 작성 했었던 Application Load Balancing의 DNS의 주소를 브라우저에 입력하면 다음과 같이 Hello World! 가 출력됩니다.




지금까지 AWS ECS fargate를 사용하여 Appilication을 최초로 배포 하였습니다. 다음글에서는 도커 이미지 또는 작업이 업데이트 되는 경우와 기타 옵션들에 대해 좀 더 자세히 확인하는 내용이 될 예정입니다.


esxi 6에 qlogic 16G fc driver upgrade 과정

1. vsphre에 접근 및 유지보수 모드 시작

2. 구성 - 보안 프로파일 - 방화벽 - 속성에서 ssh모드 활성화

3. winscp등을 통해 드라이브 파일(qlnativefc-2.1.43.0-1OEM.600.0.0.2768847.x86_64.vib) esxi의 /tmp로 전송

4. /usr/bin/esxcli software vib install -v /tmp/qlnativefc-2.1.43.0-1OEM.600.0.0.2768847.x86_64.vib --no-sig-check -f

5. 결과 확인

Installation Result

   Message: The update completed successfully, but the system needs to be rebooted for the changes to be effective.

   Reboot Required: true

   VIBs Installed: QLogic_bootbank_qlnativefc_2.1.43.0-1OEM.600.0.0.2768847

   VIBs Removed: QLogic_bootbank_qlnativefc_2.1.10.1-1OEM.600.0.0.2159203

   VIBs Skipped:

6. reboot
7. vsphre에 접근 및 유지보수 모드 종료
8. 드라이버 확인


'virtualization' 카테고리의 다른 글

spice 설정 자료  (0) 2016.02.01
KVM nested virualization  (0) 2016.01.11
PCI passthrough on KVM  (0) 2015.08.07
kvm 설치 centos  (0) 2015.04.03
CentOS 6, KVM에 guest OS bridge 네트워크 설정법  (0) 2015.04.03

Telemetry service 서비스는 일종의 모니터링 하는 서비스이며 코드명은 ceilometer이다.

설치는 우선 controller 노드부터한다.

 

다른 서비스와 마찬가지로 DB부터 설치하는데 다른 서비스와는 다르게 NoSQL인 mongoDB를 사용한다.

ceilometer database를 만든다. CEILOMETER_DBPASS는 사용할 패스워드로 적절하게 변경한다.

[root@controller ~]# mongo --host controller --eval '
   db = db.getSiblingDB("ceilometer");
   db.createUser({user: "ceilometer",
   pwd: "CEILOMETER_DBPASS",

   roles: [ "readWrite", "dbAdmin" ]})'
MongoDB shell version: 2.6.11
connecting to: controller:27017/test
Successfully added user: { "user" : "ceilometer", "roles" : [ "readWrite", "dbAdmin" ] }
[root@controller ~]#

 

ceilometer 유저를 만들고 admin 롤을 부여한다.

[root@controller ~]# openstack user create --domain default --password-prompt ceilometer
User Password:
Repeat User Password:
+-----------+----------------------------------+
| Field     | Value                            |
+-----------+----------------------------------+
| domain_id | default                          |
| enabled   | True                             |
| id        | 594e06a2424b46fa848273811be23de2 |
| name      | ceilometer                       |
+-----------+----------------------------------+

[root@controller ~]# openstack role add --project service --user ceilometer admin
[root@controller ~]#

 

ceilometer 서비스를 만든다.

[root@controller ~]# openstack service create --name ceilometer \
   --description "Telemetry" metering
+-------------+----------------------------------+
| Field       | Value                            |
+-------------+----------------------------------+
| description | Telemetry                        |
| enabled     | True                             |
| id          | 2ff3fef644e0427187b6d0799490c193 |
| name        | ceilometer                       |
| type        | metering                         |
+-------------+----------------------------------+

 

ceilometer 서비스 api endpoint를 만든다.

[root@controller ~]# openstack endpoint create --region RegionOne metering public http://controller:8777
+--------------+----------------------------------+
| Field        | Value                            |
+--------------+----------------------------------+
| enabled      | True                             |
| id           | 9ae278fb7ff74faf989cc8388cb0b827 |
| interface    | public                           |
| region       | RegionOne                        |
| region_id    | RegionOne                        |
| service_id   | 2ff3fef644e0427187b6d0799490c193 |
| service_name | ceilometer                       |
| service_type | metering                         |
| url          | http://controller:8777           |
+--------------+----------------------------------+
[root@controller ~]# openstack endpoint create --region RegionOne metering internal http://controller:8777
+--------------+----------------------------------+
| Field        | Value                            |
+--------------+----------------------------------+
| enabled      | True                             |
| id           | 2ed1d6a7dfa44580bb4738578cb12862 |
| interface    | internal                         |
| region       | RegionOne                        |
| region_id    | RegionOne                        |
| service_id   | 2ff3fef644e0427187b6d0799490c193 |
| service_name | ceilometer                       |
| service_type | metering                         |
| url          | http://controller:8777           |
+--------------+----------------------------------+
[root@controller ~]# openstack endpoint create --region RegionOne metering admin http://controller:8777
+--------------+----------------------------------+
| Field        | Value                            |
+--------------+----------------------------------+
| enabled      | True                             |
| id           | 22b448eeb52241dab95199b97e274e58 |
| interface    | admin                            |
| region       | RegionOne                        |
| region_id    | RegionOne                        |
| service_id   | 2ff3fef644e0427187b6d0799490c193 |
| service_name | ceilometer                       |
| service_type | metering                         |
| url          | http://controller:8777           |
+--------------+----------------------------------+

 

 

패키지를 설치한다.

[root@controller ~]# yum install -y openstack-ceilometer-api \
   openstack-ceilometer-collector openstack-ceilometer-notification \
   openstack-ceilometer-central openstack-ceilometer-alarm \
   python-ceilometerclient
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: centos.mirror.cdnetworks.com
 * extras: centos.mirror.cdnetworks.com
 * updates: www.ftp.ne.jp
Package python-ceilometerclient-1.5.0-1.el7.noarch already installed and latest version
Resolving Dependencies
--> Running transaction check
---> Package openstack-ceilometer-alarm.noarch 1:5.0.2-1.el7 will be installed

...(중략).. 

  unbound-libs.x86_64 0:1.4.20-26.el7             

  yajl.x86_64 0:2.0.4-4.el7

Complete!
[root@controller ~]#

 

 

/etc/ceilometer/ceilometer.conf 파일을 아래와 같이 수정한다.
[database] 섹션에서 DB 접근설정을 한다. CEILOMETER_DBPASS는 설정한 패스워드로 변경한다.
[DEFAULT] 와 [oslo_messaging_rabbit] 섹션에서 RabbitMQ 설정을 한다. RABBIT_PASS는 설정한 패스워드로 변경한다.
[DEFAULT] 와 [keystone_authtoken] 섹션에서 인증서비스 접근 설정을 한다. CEILOMETER_PASS는 설정한 패스워드로 변경한다.
[service_credentials] 섹션에서 서비스 작업증명 설정을 한다. CEILOMETER_PASS는 설정한 패스워드로 변경한다.

(옵션)[DEFAULT] 섹션에서 트러블슈팅시 도움이 될수 있게 verbose를 활성화한다.

[root@controller ~]# vi /etc/ceilometer/ceilometer.conf

[DEFAULT]
...
rpc_backend = rabbit
...
auth_strategy = keystone

...

 

 

[database]
...
connection = mongodb://ceilometer:CEILOMETER_DBPASS@controller:27017/ceilometer

...

 

 

[oslo_messaging_rabbit]
...
rabbit_host = controller
rabbit_userid = openstack
rabbit_password = RABBIT_PASS

...

 


[DEFAULT]

[keystone_authtoken]
...
auth_uri = http://controller:5000
auth_url = http://controller:35357
auth_plugin = password
project_domain_id = default
user_domain_id = default
project_name = service
username = ceilometer
password = CEILOMETER_PASS

...

 


[service_credentials]
...
os_auth_url = http://controller:5000/v2.0
os_username = ceilometer
os_tenant_name = service
os_password = CEILOMETER_PASS
os_endpoint_type = internalURL
os_region_name = RegionOne

 

서비스를 등록 및 시작한다.

[root@controller ~]# systemctl enable openstack-ceilometer-api.service \
   openstack-ceilometer-notification.service \
   openstack-ceilometer-central.service \
   openstack-ceilometer-collector.service \
   openstack-ceilometer-alarm-evaluator.service \
   openstack-ceilometer-alarm-notifier.service
Created symlink from /etc/systemd/system/multi-user.target.wants/openstack-ceilometer-api.service to /usr/lib/systemd/system/openstack-ceilometer-api.service.
Created symlink from /etc/systemd/system/multi-user.target.wants/openstack-ceilometer-notification.service to /usr/lib/systemd/system/openstack-ceilometer-notification.service.
Created symlink from /etc/systemd/system/multi-user.target.wants/openstack-ceilometer-central.service to /usr/lib/systemd/system/openstack-ceilometer-central.service.
Created symlink from /etc/systemd/system/multi-user.target.wants/openstack-ceilometer-collector.service to /usr/lib/systemd/system/openstack-ceilometer-collector.service.
Created symlink from /etc/systemd/system/multi-user.target.wants/openstack-ceilometer-alarm-evaluator.service to /usr/lib/systemd/system/openstack-ceilometer-alarm-evaluator.service.
Created symlink from /etc/systemd/system/multi-user.target.wants/openstack-ceilometer-alarm-notifier.service to /usr/lib/systemd/system/openstack-ceilometer-alarm-notifier.service.
[root@controller ~]# systemctl start openstack-ceilometer-api.service \
   openstack-ceilometer-notification.service \
   openstack-ceilometer-central.service \
   openstack-ceilometer-collector.service \
   openstack-ceilometer-alarm-evaluator.service \
   openstack-ceilometer-alarm-notifier.service

 

 

 

이미지 서비스와의 연동을 위해 glance설정파일도 수정한다.

/etc/glance/glance-api.conf 와 /etc/glance/glance-registry.conf 파일을 아래와 같이 수정한다.

[DEFAULT] 와 [oslo_messaging_rabbit] 섹션에서 notifications and RabbitMQ 설정을 한다. RABBIT_PASS는 설정한 password로 변경한다.

[root@controller ~]# vi /etc/glance/glance-api.conf
[DEFAULT]

...
notification_driver = messagingv2
rpc_backend = rabbit

[oslo_messaging_rabbit]
...
rabbit_host = controller
rabbit_userid = openstack
rabbit_password = RABBIT_PASS

 

2개의 파일을 모두 위와 같은 설정을 한후 이미지 서비스를 재시작한다.

[root@controller ~]# systemctl restart openstack-glance-api.service openstack-glance-registry.service

 

다음으로 컴퓨트 서비스와 연동을 위해

각각의 컴퓨트 노트로 이동한다.

우선 패키지부터 설치한다.

[root@compute1 ~]# yum install -y openstack-ceilometer-compute python-ceilometerclient python-pecan
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: centos.mirror.cdnetworks.com
 * extras: centos.mirror.cdnetworks.com
 * updates: centos.mirror.cdnetworks.com
Package python2-pecan-1.0.2-2.el7.noarch already installed and latest version
Resolving Dependencies
--> Running transaction check
---> Package openstack-ceilometer-compute.noarch 1:5.0.2-1.el7 will be installed

...(중략)... 

  python-tooz.noarch 0:1.24.0-1.el7
  python-werkzeug.noarch 0:0.9.1-2.el7                  

  python2-jsonpath-rw-ext.noarch 0:0.1.7-1.1.el7

Complete!
[root@compute1 ~]#

 

/etc/ceilometer/ceilometer.conf 파일을 아래와 같이 수정한다.

[DEFAULT] 와 [oslo_messaging_rabbit] 섹션에 RabbitMQ 접근 설정을 한다. RABBIT_PASS는 설정된 패스워드로 변경한다.
[DEFAULT] 와 [keystone_authtoken] 섹션에 인증서비스 접근 설정을 한다. CEILOMETER_PASS는 설정된 패스워드로 변경한다.
[service_credentials] 섹션에 서비스 자격정보를 설정한다. CEILOMETER_PASS는 설정된 패스워드로 변경한다.
(옵션)[DEFAULT] 섹션에서 트러블슈팅시 도움이 될수 있게 verbose를 활성화한다.

[root@compute1 ~]# vi /etc/ceilometer/ceilometer.conf

[DEFAULT]
...
rpc_backend = rabbit
...
auth_strategy = keystone
...
verbose = True

...

 

 

[oslo_messaging_rabbit]
...
rabbit_host = controller
rabbit_userid = openstack
rabbit_password = RABBIT_PASS
...


[keystone_authtoken]
...
auth_uri = http://controller:5000
auth_url = http://controller:35357
auth_plugin = password
project_domain_id = default
user_domain_id = default
project_name = service
username = ceilometer
password = CEILOMETER_PASS
...


[service_credentials]
...
os_auth_url = http://controller:5000/v2.0
os_username = ceilometer
os_tenant_name = service
os_password = CEILOMETER_PASS
os_endpoint_type = internalURL
os_region_name = RegionOne 

 

 

 

/etc/nova/nova.conf 파일의 [DEFAULT]섹션을 아래와 같이 수정한다.

[root@compute1 ~]# vi /etc/nova/nova.conf

[DEFAULT]
...
instance_usage_audit = True
instance_usage_audit_period = hour
notify_on_state_change = vm_and_task_state
notification_driver = messagingv2

 

ceilometer 서비스 등록 및 시작, compute 서비스 역시 변경사항이 있으니 재시작 해준다.

[root@compute1 ~]# systemctl enable openstack-ceilometer-compute.service
Created symlink from /etc/systemd/system/multi-user.target.wants/openstack-ceilometer-compute.service to /usr/lib/systemd/system/openstack-ceilometer-compute.service.
[root@compute1 ~]# systemctl start openstack-ceilometer-compute.service
[root@compute1 ~]# systemctl restart openstack-nova-compute.service

 

 

 

다음으로 block storage 서비스와 연동을 위해

각각의 block1 노드로 이동한다.

우선 설정 파일을 수정한다.

/etc/cinder/cinder.conf 파일의 [DEFAULT]섹션에 아래와 같이 notification를 설정한다.

[root@block1 ~]# vi /etc/cinder/cinder.conf

[DEFAULT]
...

notification_driver = messagingv2

 

서비스 재시작을 위해 컨트롤러 및 block1노드의 서비스들을 각각 재시작 해준다.

[root@controller ~]# systemctl restart openstack-cinder-api.service openstack-cinder-scheduler.service

 

[root@block1 ~]# systemctl restart openstack-cinder-volume.service

 

 

다음으로 block storage 서비스와 연동을 설정한다.

Telemetry service 서비스는 Object Storage service 에 접근하는데 ResellerAdmin 롤을 사용한다.

우선 컨트롤로 노드에서 ResellerAdmin 롤을 만들고 ResellerAdmin 롤에 ceilometer 유저를 추가한다.

[root@controller ~]# openstack role create ResellerAdmin
+-------+----------------------------------+
| Field | Value                            |
+-------+----------------------------------+
| id    | d77ca941e0324c6c98d69724e8bffbaf |
| name  | ResellerAdmin                    |
+-------+----------------------------------+

[root@controller ~]# openstack role add --project service --user ceilometer ResellerAdmin

 

다음으로 설치는 컨트롤러 노드 또는 오브젝트 proxy서비스가 실행되는 서버에 진행한다.

/etc/swift/proxy-server.conf파일을 아래와 같이 수정한다.

[filter:keystoneauth] 섹션에 ResellerAdmin 롤을 추가한다.
[pipeline:main] 섹션에 ceilometer를 추가한다.
[filter:ceilometer] 섹션에 notifications 설정을 한다. RABBIT_PASS는 설정한 패스워드로 변경한다.

[root@controller ~]# vi /etc/swift/proxy-server.conf

[filter:keystoneauth]
...
operator_roles = admin, user, ResellerAdmin
...


[pipeline:main]
pipeline = catch_errors gatekeeper healthcheck proxy-logging cache
container_sync bulk ratelimit authtoken keystoneauth container-quotas
account-quotas slo dlo versioned_writes proxy-logging ceilometer
proxy-server
...


[filter:ceilometer]
paste.filter_factory = ceilometermiddleware.swift:filter_factory
...
control_exchange = swift
url = rabbit://openstack:RABBIT_PASS@controller:5672/
driver = messagingv2
topic = notifications
log_level = WARN

 

스위프트 프록시 서비스를 재시작한다.

[root@controller ~]# systemctl restart openstack-swift-proxy.service

 

 

 

설치가 잘되었는지 확인한다.

[root@controller ~]# ceilometer meter-list
+-------------+-------+-------+--------------------------------------+---------+----------------------------------+
| Name        | Type  | Unit  | Resource ID                          | User ID | Project ID                       |
+-------------+-------+-------+--------------------------------------+---------+----------------------------------+
| image       | gauge | image | 49338c63-033c-40a3-abdd-d6410799de24 | None    | 94f9c25aaa4246b0915afacca2d65c22 |
| image.size  | gauge | B     | 49338c63-033c-40a3-abdd-d6410799de24 | None    | 94f9c25aaa4246b0915afacca2d65c22 |
+-------------+-------+-----------+----------------------------------+---------+----------------------------------+

 

 

Image service에서 CirrOS를 다운 받고 meter list를 다시 확인하여 다운되는 것을 모니터링이 잘되는지 확인한다.

[root@controller ~]# IMAGE_ID=$(glance image-list | grep 'cirros' | awk '{ print $2 }')
[root@controller ~]# glance image-download $IMAGE_ID > /tmp/cirros.img
[root@controller ~]# ceilometer meter-list
+----------------+-------+-------+--------------------------------------+----------------------------------+----------------------------------+

| Name           | Type  | Unit  | Resource ID                          | User ID                          | Project ID                       |
+----------------+-------+-------+--------------------------------------+----------------------------------+----------------------------------+
| image          | gauge | image | 49338c63-033c-40a3-abdd-d6410799de24 | 2238ec4daed3436b8cc97491518bd6cf | 94f9c25aaa4246b0915afacca2d65c22 |
| image.download | delta | B     | 49338c63-033c-40a3-abdd-d6410799de24 | 2238ec4daed3436b8cc97491518bd6cf | 94f9c25aaa4246b0915afacca2d65c22 |
| image.serve    | delta | B     | 49338c63-033c-40a3-abdd-d6410799de24 | 2238ec4daed3436b8cc97491518bd6cf | 94f9c25aaa4246b0915afacca2d65c22 |
| image.size     | gauge | B     | 49338c63-033c-40a3-abdd-d6410799de24 | 2238ec4daed3436b8cc97491518bd6cf | 94f9c25aaa4246b0915afacca2d65c22 |
+----------------+-------+-------+--------------------------------------+----------------------------------+----------------------------------+

 

 

image.download 미터에서 사용 통계를 검색한다.

[root@controller ~]# ceilometer statistics -m image.download -p 60
+--------+----------------------------+----------------------------+------------+------------+------------+------------+-------+----------+----------------------------+----------------------------+
| Period | Period Start               | Period End                 | Max        | Min        | Avg        | Sum        | Count | Duration | Duration Start             | Duration End               |
+--------+----------------------------+----------------------------+------------+------------+------------+------------+-------+----------+----------------------------+----------------------------+
| 60     | 2016-03-12T06:01:39.451000 | 2016-03-12T06:02:39.451000 | 13287936.0 | 13287936.0 | 13287936.0 | 13287936.0 | 1     | 0.0      | 2016-03-12T06:01:59.874000 | 2016-03-12T06:01:59.874000 |
+--------+----------------------------+----------------------------+------------+------------+------------+------------+-------+----------+----------------------------+----------------------------+

 

임시로 다운 받은 cirros 이미지를 삭제한다.

[root@controller ~]# rm -f /tmp/cirros.img

Orchestration service서비스는 인스턴스를 생성시 인스턴스에 대한 설정치를 일일히 입력하지 않고

자동화 시키는 서비스이며 코드명은 heat이다.

 

설치는 컨트롤러 노드에 하며 역시나 DB 부터 생성한다.

[root@controller ~]# mysql -u root -p
Enter password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 26
Server version: 5.5.44-MariaDB MariaDB Server

 

Copyright (c) 2000, 2015, Oracle, MariaDB Corporation Ab and others.

 

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

 

MariaDB [(none)]> CREATE DATABASE heat;
Query OK, 1 row affected (0.00 sec)

 

MariaDB [(none)]> GRANT ALL PRIVILEGES ON heat.* TO 'heat'@'localhost' \
   IDENTIFIED BY 'HEAT_DBPASS';
Query OK, 0 rows affected (0.00 sec)

 

MariaDB [(none)]> GRANT ALL PRIVILEGES ON heat.* TO 'heat'@'controller'\
   IDENTIFIED BY 'HEAT_DBPASS';

Query OK, 0 rows affected (0.00 sec)

 

MariaDB [(none)]> GRANT ALL PRIVILEGES ON heat.* TO 'heat'@'%' \
   IDENTIFIED BY 'HEAT_DBPASS';
Query OK, 0 rows affected (0.00 sec)

 

MariaDB [(none)]> quit
Bye

 

heat 유저를 생성하고 admin 롤을 부여한다.

[root@controller ~]# openstack user create --domain default --password-prompt heat
User Password:
Repeat User Password:
+-----------+----------------------------------+
| Field     | Value                            |
+-----------+----------------------------------+
| domain_id | default                          |
| enabled   | True                             |
| id        | 970d758f242944be9eb34477786acfc5 |
| name      | heat                             |
+-----------+----------------------------------+
[root@controller ~]# openstack role add --project service --user heat admin

 

heat와 heat-cfn에 대한 서비스를 만든다.

[root@controller ~]# openstack service create --name heat \
   --description "Orchestration" orchestration
+-------------+----------------------------------+
| Field       | Value                            |
+-------------+----------------------------------+
| description | Orchestration                    |
| enabled     | True                             |
| id          | 7b3ac90bc9524fab9367dff629b2522b |
| name        | heat                             |
| type        | orchestration                    |
+-------------+----------------------------------+
[root@controller ~]# openstack service create --name heat-cfn \
   --description "Orchestration"  cloudformation
+-------------+----------------------------------+
| Field       | Value                            |
+-------------+----------------------------------+
| description | Orchestration                    |
| enabled     | True                             |
| id          | eab5fc4507644a37a0b79b6bce433470 |
| name        | heat-cfn                         |
| type        | cloudformation                   |
+-------------+----------------------------------+

 

 

2개의 서비스에 대해 각각 인터널, 퍼블릭, admin 접근 API 엔드포인트를 만든다.

[root@controller ~]# openstack endpoint create --region RegionOne orchestration public http://controller:8004/v1/%\(tenant_id\)s
+--------------+-----------------------------------------+
| Field        | Value                                   |
+--------------+-----------------------------------------+
| enabled      | True                                    |
| id           | bf13be32e29246dd9c5299f4ee4352e9        |
| interface    | public                                  |
| region       | RegionOne                               |
| region_id    | RegionOne                               |
| service_id   | 7b3ac90bc9524fab9367dff629b2522b        |
| service_name | heat                                    |
| service_type | orchestration                           |
| url          | http://controller:8004/v1/%(tenant_id)s |
+--------------+-----------------------------------------+
[root@controller ~]# openstack endpoint create --region RegionOne orchestration internal http://controller:8004/v1/%\(tenant_id\)s
+--------------+-----------------------------------------+
| Field        | Value                                   |
+--------------+-----------------------------------------+
| enabled      | True                                    |
| id           | 14b6480a837647779df5e4d5235e8b11        |
| interface    | internal                                |
| region       | RegionOne                               |
| region_id    | RegionOne                               |
| service_id   | 7b3ac90bc9524fab9367dff629b2522b        |
| service_name | heat                                    |
| service_type | orchestration                           |
| url          | http://controller:8004/v1/%(tenant_id)s |
+--------------+-----------------------------------------+
[root@controller ~]# openstack endpoint create --region RegionOne orchestration admin http://controller:8004/v1/%\(tenant_id\)s
+--------------+-----------------------------------------+
| Field        | Value                                   |
+--------------+-----------------------------------------+
| enabled      | True                                    |
| id           | 76518471bb614f71874b11dd275a719e        |
| interface    | admin                                   |
| region       | RegionOne                               |
| region_id    | RegionOne                               |
| service_id   | 7b3ac90bc9524fab9367dff629b2522b        |
| service_name | heat                                    |
| service_type | orchestration                           |
| url          | http://controller:8004/v1/%(tenant_id)s |
+--------------+-----------------------------------------+
[root@controller ~]#
[root@controller ~]#
[root@controller ~]# openstack endpoint create --region RegionOne cloudformation public http://controller:8000/v1
+--------------+----------------------------------+
| Field        | Value                            |
+--------------+----------------------------------+
| enabled      | True                             |
| id           | eaee96fd7fb34e9d919849f8cee3db49 |
| interface    | public                           |
| region       | RegionOne                        |
| region_id    | RegionOne                        |
| service_id   | eab5fc4507644a37a0b79b6bce433470 |
| service_name | heat-cfn                         |
| service_type | cloudformation                   |
| url          | http://controller:8000/v1        |
+--------------+----------------------------------+
[root@controller ~]# openstack endpoint create --region RegionOne cloudformation internal http://controller:8000/v1
+--------------+----------------------------------+
| Field        | Value                            |
+--------------+----------------------------------+
| enabled      | True                             |
| id           | a40350b0229f4680b259bd711813c9ef |
| interface    | internal                         |
| region       | RegionOne                        |
| region_id    | RegionOne                        |
| service_id   | eab5fc4507644a37a0b79b6bce433470 |
| service_name | heat-cfn                         |
| service_type | cloudformation                   |
| url          | http://controller:8000/v1        |
+--------------+----------------------------------+
[root@controller ~]# openstack endpoint create --region RegionOne cloudformation admin http://controller:8000/v1
+--------------+----------------------------------+
| Field        | Value                            |
+--------------+----------------------------------+
| enabled      | True                             |
| id           | 72fdae5aec2f464f858ac1cff94fc146 |
| interface    | admin                            |
| region       | RegionOne                        |
| region_id    | RegionOne                        |
| service_id   | eab5fc4507644a37a0b79b6bce433470 |
| service_name | heat-cfn                         |
| service_type | cloudformation                   |
| url          | http://controller:8000/v1        |
+--------------+----------------------------------+

 

오케스트레이션 서비스는 스택관리를 위해 추가로 작업해줄 것이 있다.

일단 heat라는 별도의 도메인을 만든다.

[root@controller ~]# openstack domain create --description "Stack projects and users" heat
+-------------+----------------------------------+
| Field       | Value                            |
+-------------+----------------------------------+
| description | Stack projects and users         |
| enabled     | True                             |
| id          | df7ac09d39e54d6198acd3fd213ea43d |
| name        | heat                             |
+-------------+----------------------------------+ 

 

heat_domain_admin 라는 heat 도메인의 관리자를 만들고 admin 롤을 부여한다.

[root@controller ~]# openstack user create --domain heat --password-prompt heat_domain_admin
User Password:
Repeat User Password:
+-----------+----------------------------------+
| Field     | Value                            |
+-----------+----------------------------------+
| domain_id | df7ac09d39e54d6198acd3fd213ea43d |
| enabled   | True                             |
| id        | e656c268bea8414a9c76574762c6ffa0 |
| name      | heat_domain_admin                |
+-----------+----------------------------------+

 [root@controller ~]# openstack role add --domain heat --user heat_domain_admin admin

 

heat_stack_owner 롤을 만들고 기존에 사용하던 demo계정에 heat_stack_owner 롤을 부여한다

[root@controller ~]# openstack role create heat_stack_owner
+-------+----------------------------------+
| Field | Value                            |
+-------+----------------------------------+
| id    | f09abe94c4b64b20bd49ff9b45a61cf5 |
| name  | heat_stack_owner                 |
+-------+----------------------------------+

[root@controller ~]# openstack role add --project demo --user demo heat_stack_owner

 

heat_stack_user 롤을 만든다. 오케스트레이션 서비스는 자동으로 스택 배포 하는 동안 만들어지는 사용자에 게 heat_stack_user 역할을 할당 한다.

이 롤은 기본적으로이 API 작업이 제한되어 있고 충돌을 피하기 위해, heat_stack_owner을 가진 사용자에게 이 롤을 추가 하지 않아야 한다.

[root@controller ~]# openstack role create heat_stack_user
+-------+----------------------------------+
| Field | Value                            |
+-------+----------------------------------+
| id    | 84768c6edb9c4689b0314f5f7785ff0e |
| name  | heat_stack_user                  |
+-------+----------------------------------+

 

 

이제 패키지를 설치한다.

[root@controller ~]# yum install -y openstack-heat-api openstack-heat-api-cfn openstack-heat-engine python-heatclient
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: centos.mirror.cdnetworks.com
 * extras: centos.mirror.cdnetworks.com
 * updates: www.ftp.ne.jp

Package python-heatclient-0.8.0-1.el7.noarch already installed and latest version
Resolving Dependencies
--> Running transaction check

...(중략)...

Dependency Installed:
  openstack-heat-common.noarch 1:5.0.0-1.el7                                                                             

  python-oslo-cache.noarch 0:0.7.0-1.el7

Complete!
[root@controller ~]#

 

/etc/heat/heat.conf 파일을 열어 아래와 같이 수정한다.

[database] 섹션에서 DB 접근설정을 한다. HEAT_DBPASS는 설정한 패스워드로 변경
[DEFAULT] 과 [oslo_messaging_rabbit] 섹션에서 RabbitMQ 설정을 한다. RABBIT_PASS는 설정한 패스워드로 변경
[keystone_authtoken], [trustee], [clients_keystone], [ec2authtoken] 섹션에서, 인증서비스 접근 설정을 한다. RABBIT_PASS는 설정한 패스워드로 변경
[DEFAULT] 섹션에서 metadata 와 wait condition URLs 설정을 한다.
[DEFAULT] 섹션에서 스택도메인과 관리자격증명 설정을 한다. HEAT_DOMAIN_PASS는 heat_domain_admin 유저의 패스워드로 변경

(옵션)[DEFAULT] 섹션에서 트러블슈팅시 도움이 될수 있게 verbose를 활성화한다.

[root@controller ~]# vi /etc/heat/heat.conf

[database]
...
connection = mysql://heat:HEAT_DBPASS@controller/heat
...
rpc_backend = rabbit
...
heat_metadata_server_url = http://controller:8000
heat_waitcondition_server_url = http://controller:8000/v1/waitcondition
...
stack_domain_admin = heat_domain_admin
stack_domain_admin_password = HEAT_DOMAIN_PASS
stack_user_domain_name = heat

...
verbose = True

...


[oslo_messaging_rabbit]
...
rabbit_host = controller
rabbit_userid = openstack
rabbit_password = RABBIT_PASS
...


[keystone_authtoken]
...
auth_uri = http://controller:5000
auth_url = http://controller:35357
auth_plugin = password
project_domain_id = default
user_domain_id = default
project_name = service
username = heat
password = HEAT_PASS
...


[trustee]
...
auth_plugin = password
auth_url = http://controller:35357
username = heat
password = HEAT_PASS
user_domain_id = default

[clients_keystone]
...
auth_uri = http://controller:5000
...


[ec2authtoken]
...
auth_uri = http://controller:5000

 

heat 서비스 DB의 table들을 생성한다.

[root@controller ~]# su -s /bin/sh -c "heat-manage db_sync" heat
2016-03-11 07:48:26.406 17856 INFO migrate.versioning.api [-] 27 -> 28...
2016-03-11 07:48:27.419 17856 INFO migrate.versioning.api [-] done
2016-03-11 07:48:27.419 17856 INFO migrate.versioning.api [-] 28 -> 29...

...(중략)...

 

 

 

서비스 등록 및 시작한다.

[root@controller ~]# systemctl enable openstack-heat-api.service \
   openstack-heat-api-cfn.service openstack-heat-engine.service
Created symlink from /etc/systemd/system/multi-user.target.wants/openstack-heat-api.service to /usr/lib/systemd/system/openstack-heat-api.service.
Created symlink from /etc/systemd/system/multi-user.target.wants/openstack-heat-api-cfn.service to /usr/lib/systemd/system/openstack-heat-api-cfn.service.
Created symlink from /etc/systemd/system/multi-user.target.wants/openstack-heat-engine.service to /usr/lib/systemd/system/openstack-heat-engine.service.
[root@controller ~]# systemctl start openstack-heat-api.service \
   openstack-heat-api-cfn.service openstack-heat-engine.service

 

서비스가 잘 설치되었는지 확인한다.

[root@controller ~]# heat service-list
+------------+-------------+--------------------------------------+------------+--------+----------------------------+--------+
| hostname   | binary      | engine_id                            | host       | topic  | updated_at                 | status |
+------------+-------------+--------------------------------------+------------+--------+----------------------------+--------+
| controller | heat-engine | 4f28997b-9b78-4b0b-95d1-49b85359c630 | controller | engine | 2016-03-10T23:09:17.000000 | up     |
| controller | heat-engine | 547feaa6-921d-4e02-a2f0-0ca11262ea20 | controller | engine | 2016-03-10T23:09:27.000000 | up     |
| controller | heat-engine | 58648238-5102-4b12-9047-579abce72a57 | controller | engine | 2016-03-10T23:09:27.000000 | up     |
| controller | heat-engine | 8d722bae-651b-4ceb-a81e-4c42ca6a5bd5 | controller | engine | 2016-03-10T23:09:17.000000 | up     |
+------------+-------------+--------------------------------------+------------+--------+----------------------------+--------+

 

Object 스토리지는 cinder와는 다르게 디렉토리 계층 구조와는 다르게 컨테이너라는 단위를 개별 사용자에게 제공

컨테이너에 파일을 저장하는 서비스로 코드명은 swift이다.

구성요소들은 각각 컨트롤러 노드 및 object1, object2노드에 설치 된다.

 

우선 컨트롤러 노드부터 수행한다

swift 서비스는 SQL DB를 사용하지 않고 각각의 스토리지 노드에 분산된 SQLite DB를 사용한다.

 

그럼 swift 유저를 생성하고 admin 롤을 부여한다.

[root@controller ~]# openstack user create --domain default --password-prompt swift
User Password:
Repeat User Password:
+-----------+----------------------------------+
| Field     | Value                            |
+-----------+----------------------------------+
| domain_id | default                          |
| enabled   | True                             |
| id        | 11d4a91e2c144db1b8c8dc57cc3d5758 |
| name      | swift                            |
+-----------+----------------------------------+

[root@controller ~]# openstack role add --project service --user swift admin

 

swift 서비스 및 서비스  API endpoint를 만든다.

[root@controller ~]# openstack service create --name swift --description "OpenStack Object Storage" object-store
+-------------+----------------------------------+
| Field       | Value                            |
+-------------+----------------------------------+
| description | OpenStack Object Storage         |
| enabled     | True                             |
| id          | 671ddd2bc6d74e309c1007ba84643da3 |
| name        | swift                            |
| type        | object-store                     |
+-------------+----------------------------------+

[root@controller ~]# openstack endpoint create --region RegionOne object-store public http://controller:8080/v1/AUTH_%\(tenant_id\)s
+--------------+----------------------------------------------+
| Field        | Value                                        |
+--------------+----------------------------------------------+
| enabled      | True                                         |
| id           | 6cab534b2c284cc7bfa50ae953286c03             |
| interface    | public                                       |
| region       | RegionOne                                    |
| region_id    | RegionOne                                    |
| service_id   | 671ddd2bc6d74e309c1007ba84643da3             |
| service_name | swift                                        |
| service_type | object-store                                 |
| url          | http://controller:8080/v1/AUTH_%(tenant_id)s |
+--------------+----------------------------------------------+
[root@controller ~]# openstack endpoint create --region RegionOne object-store internal http://controller:8080/v1/AUTH_%\(tenant_id\)s
+--------------+----------------------------------------------+
| Field        | Value                                        |
+--------------+----------------------------------------------+
| enabled      | True                                         |
| id           | ed143ae6ac584b1087851fe4a9acd9ad             |
| interface    | internal                                     |
| region       | RegionOne                                    |
| region_id    | RegionOne                                    |
| service_id   | 671ddd2bc6d74e309c1007ba84643da3             |
| service_name | swift                                        |
| service_type | object-store                                 |
| url          | http://controller:8080/v1/AUTH_%(tenant_id)s |
+--------------+----------------------------------------------+
[root@controller ~]# openstack endpoint create --region RegionOne object-store admin http://controller:8080/v1
+--------------+----------------------------------+
| Field        | Value                            |
+--------------+----------------------------------+
| enabled      | True                             |
| id           | 5cd990d72b914e7db019a492ef4c988d |
| interface    | admin                            |
| region       | RegionOne                        |
| region_id    | RegionOne                        |
| service_id   | 671ddd2bc6d74e309c1007ba84643da3 |
| service_name | swift                            |
| service_type | object-store                     |
| url          | http://controller:8080/v1        |
+--------------+----------------------------------+ 


 

 

패키지를 설치한다. swift는 다른 서비스와는 다르게 독립적으로 서비스를 수행 할수 있으며 그럴때는

별도의 인증서비스가 필요로 한다. 다만 여기서는 기본 인증 서비스를 사용하기 때문에 컨트롤로 노드에 설치하며

keystone과 memcache 과 같은 패키지는 기존에 이미 설치 되어 있음

 

[root@controller ~]# yum install -y openstack-swift-proxy python-swiftclient \
   python-keystoneclient python-keystonemiddleware \
   memcached
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: centos.mirror.cdnetworks.com
 * extras: centos.mirror.cdnetworks.com
 * updates: centos.mirror.cdnetworks.com
Package python-swiftclient-2.6.0-1.el7.noarch already installed and latest version
Package 1:python-keystoneclient-1.7.2-1.el7.noarch already installed and latest version
Package python-keystonemiddleware-2.3.1-1.el7.noarch already installed and latest version
Package memcached-1.4.15-9.el7.x86_64 already installed and latest version
Resolving Dependencies
--> Running transaction check
---> Package openstack-swift-proxy.noarch 0:2.5.0-1.el7 will be installed

...(중략)...

  python-dns.noarch 0:1.12.0-1.20150617git465785f.el7
  python-pyeclib.x86_64 0:1.0.7-2.el7

Complete!
[root@controller ~]# 

 

Object Storage source repository 에서 proxy service 설정파일을 가져온다.

[root@controller ~]# curl -o /etc/swift/proxy-server.conf https://git.openstack.org/cgit/openstack/swift/plain/etc/proxy-server.conf-sample?h=stable/liberty
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 29655  100 29655    0     0  20243      0  0:00:01  0:00:01 --:--:-- 20242
[root@controller ~]#

 

 

 

/etc/swift/proxy-server.conf  파일을 아래와 같이 수정한다.

[DEFAULT] 섹션에서 bind port, user, directory를 설정한다.
[pipeline:main] 섹션에서  appropriate modules을 활성화 한다.
[app:proxy-server] 섹션에서 자동 계정 생성을 활성화 한다.
[filter:keystoneauth] 섹션에서 operator로 지정할 유저를 설정한다.
[filter:authtoken] 섹션에서 인증서비스 설정을 한다. SWIFT_PASS 는 설정한 패스워드로 변경한다. 해당 섹션은 아래 내용외에는 모두 삭제한다.
[filter:cache] 섹션에서 memcached 가 설치된 위치를 설정한다.

 

[root@controller ~]# vi /etc/swift/proxy-server.conf

[DEFAULT]
...
bind_port = 8080
user = swift
swift_dir = /etc/swift
...

 


[pipeline:main]
pipeline = catch_errors gatekeeper healthcheck proxy-logging cache container_sync bulk ratelimit authtoken keystoneauth container-quotas account-quotas slo dlo versioned_writes proxy-logging proxy-server
...

 


[app:proxy-server]
use = egg:swift#proxy
...
account_autocreate = true
...

 


[filter:keystoneauth]
use = egg:swift#keystoneauth
...
operator_roles = admin,user
...

 


[filter:authtoken]
paste.filter_factory = keystonemiddleware.auth_token:filter_factory
...
auth_uri = http://controller:5000
auth_url = http://controller:35357
auth_plugin = password
project_domain_id = default
user_domain_id = default
project_name = service
username = swift
password = SWIFT_PASS
delay_auth_decision = true
...

 


[filter:cache]
use = egg:swift#memcache
...
memcache_servers = 127.0.0.1:11211 

 

 

 

 

스토리지 노드(object노드) 설정전에 host박스로 접근

swift는 따로 raid를 구성하지 않고 xfs로 포맷된 개별의 디스크를 사용하며 현재 과정에선

cinder때와 같이 스토리지 노드에 디스크를 먼저 붙여준다.

[root@localhost ~]# qemu-img create -f qcow2 /home/obj1disk1.qcow2 100G
Formatting '/home/obj1disk1.qcow2', fmt=qcow2 size=107374182400 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16
[root@localhost ~]# qemu-img create -f qcow2 /home/obj1disk2.qcow2 100G
Formatting '/home/obj1disk2.qcow2', fmt=qcow2 size=107374182400 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16
[root@localhost ~]# qemu-img create -f qcow2 /home/obj2disk1.qcow2 100G
Formatting '/home/obj2disk1.qcow2', fmt=qcow2 size=107374182400 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16
[root@localhost ~]# qemu-img create -f qcow2 /home/obj2disk2.qcow2 100G
Formatting '/home/obj2disk2.qcow2', fmt=qcow2 size=107374182400 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16

[root@localhost ~]#  

[root@localhost ~]# chown qemu:qemu /home/obj1disk1.qcow2
[root@localhost ~]# chown qemu:qemu /home/obj1disk2.qcow2
[root@localhost ~]# chown qemu:qemu /home/obj2disk1.qcow2
[root@localhost ~]# chown qemu:qemu /home/obj2disk2.qcow2

[root@localhost ~]# virsh pool-refresh home
Pool home refreshed

[root@localhost ~]# virsh vol-list home
 Name                 Path
------------------------------------------------------------------------------

 blockdisk.qcow2      /home/blockdisk.qcow2
...(중략)...

 obj1disk1.qcow2      /home/obj1disk1.qcow2
 obj1disk2.qcow2      /home/obj1disk2.qcow2
 obj2disk1.qcow2      /home/obj2disk1.qcow2
 obj2disk2.qcow2      /home/obj2disk2.qcow2
...(중략)...

 

[root@localhost ~]# vi /etc/libvirt/qemu/obj1disk1.xml

<disk type='file' device='disk'>
   <driver name='qemu' type='qcow2'/>
   <source file='/home/obj1disk1.qcow2'/>
   <target dev='vdb'/>
</disk>
[root@localhost ~]# virsh attach-device --config object1 /etc/libvirt/qemu/obj1disk1.xml --live
Device attached successfully

 

[root@localhost ~]# vi /etc/libvirt/qemu/objt1disk2.xml

<disk type='file' device='disk'>
   <driver name='qemu' type='qcow2'/>
   <source file='/home/obj1disk2.qcow2'/>
   <target dev='vdc'/>
</disk>
[root@localhost ~]# virsh attach-device --config object1 /etc/libvirt/qemu/objt1disk2.xml --live
Device attached successfully

 

[root@localhost ~]# vi /etc/libvirt/qemu/obj2diskt1.xml

<disk type='file' device='disk'>
   <driver name='qemu' type='qcow2'/>
   <source file='/home/obj2disk1.qcow2'/>
   <target dev='vdb'/>

[root@localhost ~]# virsh attach-device --config object2 /etc/libvirt/qemu/obj2diskt1.xml --live
Device attached successfully

 

[root@localhost ~]# vi /etc/libvirt/qemu/obj2disk2.xml

<disk type='file' device='disk'>
   <driver name='qemu' type='qcow2'/>
   <source file='/home/obj2disk2.qcow2'/>
   <target dev='vdc'/>
</disk>
[root@localhost ~]# virsh attach-device --config object2 /etc/libvirt/qemu/obj2disk2.xml --live
Device attached successfully

 

 

 

 

object1 노드로 이동한다.

현재 작업은 object1에서만 진행하지만 object2에서도 같은 작업을 진행한다.

먼저 디스크부터 확인한다.

참고로 물리 장비환경및 물리 디스크 사용했거나 또는 host에서 가상디스크를 scsi또는 sata bus로 붙인다면 /dev/sd? 이다.

현재 환경은 virtio bus를 통해 가상디스크를 붙여서 /dev/vd? 로 디바이스명이 정해진것

[root@object1 ~]# fdisk -l

Disk /dev/vda: 107.4 GB, 107374182400 bytes, 209715200 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x0007868c

   Device Boot      Start         End      Blocks   Id  System
/dev/vda1   *        2048     1026047      512000   83  Linux
/dev/vda2         1026048   209715199   104344576   8e  Linux LVM

...(중략)...


Disk /dev/vdb: 107.4 GB, 107374182400 bytes, 209715200 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes


Disk /dev/vdc: 107.4 GB, 107374182400 bytes, 209715200 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

 

 

본격적인 패키지 설치 전에 필요 유틸리티를 설치한다. xfs는 7.0대의 centos/rhel의 기본 파일시스템이라 이미 설치되어 있을수 있음.

[root@object1 ~]# yum install -y xfsprogs rsync
Loaded plugins: fastestmirror

Determining fastest mirrors
 * base: ftp.neowiz.com
 * extras: ftp.neowiz.com
 * updates: ftp.neowiz.com
Package xfsprogs-3.2.2-2.el7.x86_64 already installed and latest version
Resolving Dependencies
--> Running transaction check
---> Package rsync.x86_64 0:3.0.9-17.el7 will be installed
--> Finished Dependency Resolution

 

Installed:
  rsync.x86_64 0:3.0.9-17.el7

Complete!
[root@object1 ~]# 

 

2개의 디스크를 각각 xfs로 포맷한다.

[root@object1 ~]# mkfs.xfs /dev/vdb
meta-data=/dev/vdb               isize=256    agcount=4, agsize=6553600 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=0        finobt=0
data     =                       bsize=4096   blocks=26214400, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=0
log      =internal log           bsize=4096   blocks=12800, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
[root@object1 ~]# mkfs.xfs /dev/vdc
meta-data=/dev/vdc               isize=256    agcount=4, agsize=6553600 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=0        finobt=0
data     =                       bsize=4096   blocks=26214400, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=0
log      =internal log           bsize=4096   blocks=12800, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0

 

마운트 포인트를 생성한다.

[root@object1 ~]# mkdir -p /srv/node/vdb
[root@object1 ~]# mkdir -p /srv/node/vdc

 

 

/etc/fstab 수정 해당 마운트 정보를 추가하고 마운트를 수행한다.

[root@object1 ~]# vi /etc/fstab

...(중략)... 

/dev/vdb            /srv/node/vdb           xfs     noatime,nodiratime,nobarrier,logbufs=8  0 2
/dev/vdc            /srv/node/vdc           xfs     noatime,nodiratime,nobarrier,logbufs=8  0 2

 

[root@object1 ~]# mount /srv/node/vdb
[root@object1 ~]# mount /srv/node/vdc

 

/etc/rsyncd.conf 파일을 수정하여 아래 내용을 추가한다.

address 항목에는 해당 스토리지 노드 IP를 입력한다. object1은 10.0.0.51, object2는 10.0.0.52

[root@object1 ~]# vi /etc/rsyncd.conf

...

uid = swift
gid = swift
log file = /var/log/rsyncd.log
pid file = /var/run/rsyncd.pid
address = 10.0.0.51

 

[account]
max connections = 2
path = /srv/node/
read only = false
lock file = /var/lock/account.lock

 

[container]
max connections = 2
path = /srv/node/
read only = false
lock file = /var/lock/container.lock

 

[object]
max connections = 2
path = /srv/node/
read only = false
lock file = /var/lock/object.lock

 

rsyncd를 시작 및 서비스 등록한다.

[root@object1 ~]# systemctl enable rsyncd.service
Created symlink from /etc/systemd/system/multi-user.target.wants/rsyncd.service to /usr/lib/systemd/system/rsyncd.service.
[root@object1 ~]# systemctl start rsyncd.service

 

swfit 패키지를 설치한다.

[root@object1 ~]# yum install -y openstack-swift-account openstack-swift-container openstack-swift-object
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: ftp.neowiz.com
 * extras: ftp.neowiz.com
 * updates: ftp.neowiz.com
Resolving Dependencies
--> Running transaction check
---> Package openstack-swift-account.noarch 0:2.5.0-1.el7 will be installed

...(중략)...

  python-tempita.noarch 0:0.5.1-8.el7

  python2-eventlet.noarch 0:0.17.4-4.el7
  python2-greenlet.x86_64 0:0.4.9-1.el7

Complete!
[root@object1 ~]#

 

 

 

Object Storage source repository 에서 accounting, container, object service 설정파일을 가져온다.

[root@object1 ~]# curl -o /etc/swift/account-server.conf https://git.openstack.org/cgit/openstack/swift/plain/etc/account-server.conf-sample?h=stable/liberty
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  6147  100  6147    0     0   6194      0 --:--:-- --:--:-- --:--:--  6190
[root@object1 ~]# curl -o /etc/swift/container-server.conf https://git.openstack.org/cgit/openstack/swift/plain/etc/container-server.conf-sample?h=stable/liberty
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  6976  100  6976    0     0   7501      0 --:--:-- --:--:-- --:--:--  7501
[root@object1 ~]# curl -o /etc/swift/object-server.conf https://git.openstack.org/cgit/openstack/swift/plain/etc/object-server.conf-sample?h=stable/liberty
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 11819  100 11819    0     0  13514      0 --:--:-- --:--:-- --:--:-- 13507 

 

 

 

/etc/swift/account-server.conf 파일을 아래와 같이 수정한다.

[DEFAULT]섹션에서 bind IP address, bind port, user, configuration directory, mount point directory를 설정한다. bind_ip는 스토리지 노드의 IP를 입력한다.
[pipeline:main] 섹션에 모듈들을 활성화 시킨다.
[filter:recon]섹션에서 recon(meters) cache directory를 활성화 한다

[root@object1 ~]# vi /etc/swift/account-server.conf

[DEFAULT]
...
bind_ip = 10.0.0.51
bind_port = 6002
user = swift
swift_dir = /etc/swift
devices = /srv/node
mount_check = true
...


[pipeline:main]
pipeline = healthcheck recon account-server
...


[filter:recon]
use = egg:swift#recon
...
recon_cache_path = /var/cache/swift 

 

/etc/swift/container-server.conf 파일도 /etc/swift/account-server.conf 파일과 같은 설정을 해준다. bind_port만 6001로 설정하면 된다.

[root@object1 ~]# vi /etc/swift/container-server.conf

[DEFAULT]
...
bind_ip = 10.0.0.51
bind_port = 6001
user = swift
swift_dir = /etc/swift
devices = /srv/node
mount_check = true
...


[pipeline:main]
pipeline = healthcheck recon container-server
...


[filter:recon]
use = egg:swift#recon
...
recon_cache_path = /var/cache/swift 

 

 /etc/swift/object-server.conf 파일도 수정하며 역시나 설정이 거의 비슷하다. bind_port가 6000이며 recon_lock_path 설정이 추가 된다.

[root@object1 ~]# vi /etc/swift/object-server.conf

[DEFAULT]
...
bind_ip = 10.0.0.51
bind_port = 6000
user = swift
swift_dir = /etc/swift
devices = /srv/node
mount_check = true
...


[pipeline:main]
pipeline = healthcheck recon object-server

...


[filter:recon]
use = egg:swift#recon
...
recon_cache_path = /var/cache/swift

recon_lock_path = /var/lock

 

swift 마운트 포인트의 권한 설정을 한다.

[root@object1 ~]# chown -R swift:swift /srv/node

 

 

recon 디렉토리를 생성하고 권한 설정을 한다.

[root@object1 ~]# mkdir -p /var/cache/swift
[root@object1 ~]# chown -R root:swift /var/cache/swift

 

 

 

다시 컨트롤러 노드로 간다.

오브젝트 서비스를 시작하기 전에 스토리지 노드에 설치했던 서비스들 account, container, object 에 대해 ring을 만들어 주어야 한다.

ring builder는 각각의 노드들이 스토리지 아키텍처를 배포하기 위한 설정 파일을 만든다.

 

먼저 account ring을 만든다.

account server 서버는 account ring를 이용하여 container의 리스트를 관리한다.

/etc/swift 디렉토리로 이동하여 account.builder 파일을 만든다. 

[root@controller swift]# swift-ring-builder account.builder create 10 3 1

 

 

다음의 command를 통해 각각의 노드를 링에 추가시킨다. 여기서 STORAGE_NODE_MANAGEMENT_INTERFACE_IP_ADDRESS 는

각 object노드들의 IP이며 DEVICE_NAME는 해당 노드의 disk device 이름이다. DEVICE_WEIGHT은 100을 입력한다.

# swift-ring-builder account.builder  add --region 1 --zone 1 --ip STORAGE_NODE_MANAGEMENT_INTERFACE_IP_ADDRESS --port 6002 \
  --device DEVICE_NAME --weight DEVICE_WEIGHT

스토리지 노드에서 설정했던 4개의 disk를 각각 설정한다.

[root@controller swift]# swift-ring-builder account.builder add \
   --region 1 --zone 1 --ip 10.0.0.51 --port 6002 --device vdb --weight 100
Device d0r1z1-10.0.0.51:6002R10.0.0.51:6002/vdb_"" with 100.0 weight got id 0
[root@controller swift]# swift-ring-builder account.builder add \
   --region 1 --zone 2 --ip 10.0.0.51 --port 6002 --device vdc --weight 100
Device d1r1z2-10.0.0.51:6002R10.0.0.51:6002/vdc_"" with 100.0 weight got id 1
[root@controller swift]# swift-ring-builder account.builder add \
   --region 1 --zone 3 --ip 10.0.0.52 --port 6002 --device vdb --weight 100
Device d2r1z3-10.0.0.52:6002R10.0.0.52:6002/vdb_"" with 100.0 weight got id 2
[root@controller swift]# swift-ring-builder account.builder add \
   --region 1 --zone 4 --ip 10.0.0.52 --port 6002 --device vdc --weight 100
Device d3r1z4-10.0.0.52:6002R10.0.0.52:6002/vdc_"" with 100.0 weight got id 3

 

 

링에 잘 추가 되었는지 확인한다.

[root@controller swift]# swift-ring-builder account.builder
account.builder, build version 4
1024 partitions, 3.000000 replicas, 1 regions, 4 zones, 4 devices, 100.00 balance, 0.00 dispersion
The minimum number of hours before a partition can be reassigned is 1
The overload factor is 0.00% (0.000000)
Devices:    id  region  zone      ip address  port  replication ip  replication port      name weight partitions balance meta
             0       1     1       10.0.0.51  6002       10.0.0.51              6002       vdb 100.00          0 -100.00
             1       1     2       10.0.0.51  6002       10.0.0.51              6002       vdc 100.00          0 -100.00
             2       1     3       10.0.0.52  6002       10.0.0.52              6002       vdb 100.00          0 -100.00
             3       1     4       10.0.0.52  6002       10.0.0.52              6002       vdc 100.00          0 -100.00

 

링을 rebalance 시킨다.

[root@controller swift]# swift-ring-builder account.builder rebalance
Reassigned 1024 (100.00%) partitions. Balance is now 0.00.  Dispersion is now 0.00 

 

컨테이너 링과 오브젝트 링도 같은 단계를 거친다. account 명령어를 수정하여 사용할 경우 포트 및 build파일명을 정확히 확인해야 한다.

[root@controller swift]# swift-ring-builder container.builder create 10 3 1

[root@controller swift]# 
[root@controller swift]# swift-ring-builder container.builder add \
   --region 1 --zone 1 --ip 10.0.0.51 --port 6001 --device vdb --weight 100
Device d0r1z1-10.0.0.51:6002R10.0.0.51:6002/vdb_"" with 100.0 weight got id 0
[root@controller swift]# swift-ring-builder container.builder add \
   --region 1 --zone 2 --ip 10.0.0.51 --port 6001 --device vdc --weight 100
Device d1r1z2-10.0.0.51:6002R10.0.0.51:6002/vdc_"" with 100.0 weight got id 1
[root@controller swift]# swift-ring-builder container.builder add \
   --region 1 --zone 3 --ip 10.0.0.52 --port 6001 --device vdb --weight 100
Device d2r1z3-10.0.0.52:6002R10.0.0.52:6002/vdb_"" with 100.0 weight got id 2
[root@controller swift]# swift-ring-builder container.builder add \
   --region 1 --zone 4 --ip 10.0.0.52 --port 6001 --device vdc --weight 100
Device d3r1z4-10.0.0.52:6002R10.0.0.52:6002/vdc_"" with 100.0 weight got id 3
[root@controller swift]#

[root@controller swift]# swift-ring-builder container.builder
container.builder, build version 4
1024 partitions, 3.000000 replicas, 1 regions, 4 zones, 4 devices, 100.00 balance, 0.00 dispersion
The minimum number of hours before a partition can be reassigned is 1
The overload factor is 0.00% (0.000000)
Devices:    id  region  zone      ip address  port  replication ip  replication port      name weight partitions balance meta
             0       1     1       10.0.0.51  6001       10.0.0.51              6001       vdb 100.00          0 -100.00
             1       1     2       10.0.0.51  6001       10.0.0.51              6001       vdc 100.00          0 -100.00
             2       1     3       10.0.0.52  6001       10.0.0.52              6001       vdb 100.00          0 -100.00
             3       1     4       10.0.0.52  6001       10.0.0.52              6001       vdc 100.00          0 -100.00
[root@controller swift]#

[root@controller swift]# swift-ring-builder container.builder rebalance
Reassigned 1024 (100.00%) partitions. Balance is now 0.00.  Dispersion is now 0.00
[root@controller swift]#

[root@controller swift]#

[root@controller swift]# swift-ring-builder object.builder create 10 3 1

[root@controller swift]#
[root@controller swift]# swift-ring-builder object.builder add \
   --region 1 --zone 1 --ip 10.0.0.51 --port 6000 --device vdb --weight 100
Device d0r1z1-10.0.0.51:6002R10.0.0.51:6002/vdb_"" with 100.0 weight got id 0
[root@controller swift]# swift-ring-builder object.builder add \
   --region 1 --zone 2 --ip 10.0.0.51 --port 6000 --device vdc --weight 100
Device d1r1z2-10.0.0.51:6002R10.0.0.51:6002/vdc_"" with 100.0 weight got id 1
[root@controller swift]# swift-ring-builder object.builder add \
   --region 1 --zone 3 --ip 10.0.0.52 --port 6000 --device vdb --weight 100
Device d2r1z3-10.0.0.52:6002R10.0.0.52:6002/vdb_"" with 100.0 weight got id 2
[root@controller swift]# swift-ring-builder object.builder add \
   --region 1 --zone 4 --ip 10.0.0.52 --port 6000 --device vdc --weight 100
Device d3r1z4-10.0.0.52:6002R10.0.0.52:6002/vdc_"" with 100.0 weight got id 3

[root@controller swift]#
[root@controller swift]# swift-ring-builder object.builder
object.builder, build version 4
1024 partitions, 3.000000 replicas, 1 regions, 4 zones, 4 devices, 100.00 balance, 0.00 dispersion
The minimum number of hours before a partition can be reassigned is 1
The overload factor is 0.00% (0.000000)
Devices:    id  region  zone      ip address  port  replication ip  replication port      name weight partitions balance meta
             0       1     1       10.0.0.51  6000       10.0.0.51              6000       vdb 100.00          0 -100.00
             1       1     2       10.0.0.51  6000       10.0.0.51              6000       vdc 100.00          0 -100.00
             2       1     3       10.0.0.52  6000       10.0.0.52              6000       vdb 100.00          0 -100.00
             3       1     4       10.0.0.52  6000       10.0.0.52              6000       vdc 100.00          0 -100.00
[root@controller swift]#

[root@controller swift]# swift-ring-builder object.builder rebalance
Reassigned 1024 (100.00%) partitions. Balance is now 0.00.  Dispersion is now 0.00

 

 

ring 구성 파일인 account.ring.gz, container.ring.gzobject.ring.gz 파일이 잘 생성되었는지 확인 후

모든 스토리지 노드 및 모든 추가 proxy서버(proxy서버 추가한 경우)들의 /etc/swift(위에서 설정파일에 swift_dir로 지정) 배포를 한다.

[root@controller swift]# ls
account.builder    container-reconciler.conf  object.builder       proxy-server.conf
account.ring.gz    container.ring.gz          object-expirer.conf  swift.conf
backups            container-server           object.ring.gz
container.builder  container-server.conf      proxy-server

[root@controller swift]# scp *.gz object1:/etc/swift
The authenticity of host 'object1 (10.0.0.51)' can't be established.
ECDSA key fingerprint is 99:e1:15:2b:05:9c:89:6b:1a:63:1d:e6:0e:7a:09:6e.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'object1,10.0.0.51' (ECDSA) to the list of known hosts.
account.ring.gz                                              100% 1441     1.4KB/s   00:00
container.ring.gz                                            100% 1451     1.4KB/s   00:00
object.ring.gz                                               100% 1428     1.4KB/s   00:00
[root@controller swift]# scp *.gz object2:/etc/swift
The authenticity of host 'object2 (10.0.0.52)' can't be established.
ECDSA key fingerprint is 99:e1:15:2b:05:9c:89:6b:1a:63:1d:e6:0e:7a:09:6e.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'object2,10.0.0.52' (ECDSA) to the list of known hosts.
account.ring.gz                                              100% 1441     1.4KB/s   00:00
container.ring.gz                                            100% 1451     1.4KB/s   00:00
object.ring.gz                                               100% 1428     1.4KB/s   00:00

[root@controller swift]#
 

 

Object Storage source repository에서 /etc/swift/swift.conf 파일을 가져와 아래와 같이 수정한다.

[swift-hash] 섹션에서 hash 설정을 한다. 이때 HASH_PATH_SUFFIXHASH_PATH_PREFIX는 unique한 값으로 교체를 하며

"openssl rand -hex 10" 커맨드를 통해 랜덤값으로 입력해주는 것이 좋다. 단 이 값은 보안을 유지하며 변경 또는 삭제하지 않는다.

[storage-policy:0] 섹션에서 기본 스토리지 정책을 설정한다. 

[root@controller ~]# curl -o /etc/swift/swift.conf \
   https://git.openstack.org/cgit/openstack/swift/plain/etc/swift.conf-sample?h=stable/liberty
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  7200  100  7200    0     0   5204      0  0:00:01  0:00:01 --:--:--  5206
[root@controller ~]# vi /etc/swift/swift.conf

[swift-hash]
...
swift_hash_path_suffix = HASH_PATH_SUFFIX
swift_hash_path_prefix = HASH_PATH_PREFIX
...

 

[storage-policy:0]
...
name = Policy-0
default = yes

 

 

/etc/swift/swift.conf 파일을 모든 swift관련 노드로 배포를 한다.

[root@controller ~]# scp /etc/swift/swift.conf object1:/etc/swift/swift.conf
swift.conf                                                   100% 7224     7.1KB/s   00:00
[root@controller ~]# scp /etc/swift/swift.conf object2:/etc/swift/swift.conf
swift.conf                                                   100% 7224     7.1KB/s   00:00

 

swift 관련 모든 노드에서 /etc/swift 및 하위 경로의 소유권을 수정한다.

[root@controller ~]# chown -R root:swift /etc/swift

 

 

controller 또는 다른 proxy 서비스가 설치된 서버에서 proxy 서비스 를 시작 해주고 서비스로 통록한다.

[root@controller ~]# systemctl enable openstack-swift-proxy.service memcached.service
Created symlink from /etc/systemd/system/multi-user.target.wants/openstack-swift-proxy.service to /usr/lib/systemd/system/openstack-swift-proxy.service.
[root@controller ~]# systemctl start openstack-swift-proxy.service memcached.service

 

스토리지 노드들에서 관련 서비스를 시작 및 서비스 등록해준다.(object1, obect2 동일하게 수행한다.)

[root@object1 ~]# systemctl enable openstack-swift-account.service openstack-swift-account-auditor.service \
   openstack-swift-account-reaper.service openstack-swift-account-replicator.service
Created symlink from /etc/systemd/system/multi-user.target.wants/openstack-swift-account.service to /usr/lib/systemd/system/openstack-swift-account.service.
Created symlink from /etc/systemd/system/multi-user.target.wants/openstack-swift-account-auditor.service to /usr/lib/systemd/system/openstack-swift-account-auditor.service.
Created symlink from /etc/systemd/system/multi-user.target.wants/openstack-swift-account-reaper.service to /usr/lib/systemd/system/openstack-swift-account-reaper.service.
Created symlink from /etc/systemd/system/multi-user.target.wants/openstack-swift-account-replicator.service to /usr/lib/systemd/system/openstack-swift-account-replicator.service.

[root@object1 ~]#  

[root@object1 ~]# systemctl start openstack-swift-account.service openstack-swift-account-auditor.service \

   openstack-swift-account-reaper.service openstack-swift-account-replicator.service

[root@object1 ~]#  

[root@object1 ~]# systemctl enable openstack-swift-container.service \

   openstack-swift-container-auditor.service openstack-swift-container-replicator.service \
   openstack-swift-container-updater.service
Created symlink from /etc/systemd/system/multi-user.target.wants/openstack-swift-container.service to /usr/lib/systemd/system/openstack-swift-container.service.
Created symlink from /etc/systemd/system/multi-user.target.wants/openstack-swift-container-auditor.service to /usr/lib/systemd/system/openstack-swift-container-auditor.service.
Created symlink from /etc/systemd/system/multi-user.target.wants/openstack-swift-container-replicator.service to /usr/lib/systemd/system/openstack-swift-container-replicator.service.
Created symlink from /etc/systemd/system/multi-user.target.wants/openstack-swift-container-updater.service to /usr/lib/systemd/system/openstack-swift-container-updater.service.

[root@object1 ~]# 
[root@object1 ~]# systemctl start openstack-swift-container.service \
   openstack-swift-container-auditor.service openstack-swift-container-replicator.service \
   openstack-swift-container-updater.service

[root@object1 ~]#
[root@object1 ~]# systemctl enable openstack-swift-object.service openstack-swift-object-auditor.service \
   openstack-swift-object-replicator.service openstack-swift-object-updater.service
Created symlink from /etc/systemd/system/multi-user.target.wants/openstack-swift-object.service to /usr/lib/systemd/system/openstack-swift-object.service.
Created symlink from /etc/systemd/system/multi-user.target.wants/openstack-swift-object-auditor.service to /usr/lib/systemd/system/openstack-swift-object-auditor.service.
Created symlink from /etc/systemd/system/multi-user.target.wants/openstack-swift-object-replicator.service to /usr/lib/systemd/system/openstack-swift-object-replicator.service.
Created symlink from /etc/systemd/system/multi-user.target.wants/openstack-swift-object-updater.service to /usr/lib/systemd/system/openstack-swift-object-updater.service.

[root@object1 ~]#
[root@object1 ~]# systemctl start openstack-swift-object.service openstack-swift-object-auditor.service \
   openstack-swift-object-replicator.service openstack-swift-object-updater.service

 

 

오브젝트 서비스가 잘 설치 되었는지 확인한다.

환경설정 스크립트에 identity API 버전 3 사용하여 object 스토리지 서비스 클라이언트 설정한다.

[root@controller ~]# echo "export OS_AUTH_VERSION=3" | tee -a admin-openrc.sh demo-openrc.sh
export OS_AUTH_VERSION=3

 

데모 유저 스크립트를 활성화 한다.

[root@controller ~]# source demo-openrc.sh 

 

서비스 상태를 확인한다.

[root@controller ~]# swift stat
        Account: AUTH_94f9c25aaa4246b0915afacca2d65c22
     Containers: 0
        Objects: 0
          Bytes: 0
X-Put-Timestamp: 1457586763.62553
    X-Timestamp: 1457586763.62553
     X-Trans-Id: tx26363eefacfc4ee68bb3b-0056e1024b
   Content-Type: text/plain; charset=utf-8

 

임시로 파일을 한번 올려본다. grance 설치시 내려 받은 파일을 올려본다.

[root@controller ~]# swift upload container1 cirros-0.3.4-x86_64-disk.img
cirros-0.3.4-x86_64-disk.img

 

컨테이너 리스트 및 상태를 확인한다.  파일 업로드 후 변경되었다.

[root@controller ~]# swift list
container1
[root@controller ~]# swift stat
                        Account: AUTH_94f9c25aaa4246b0915afacca2d65c22
                     Containers: 1
                        Objects: 2
                          Bytes: 26575872
Containers in policy "policy-0": 1
   Objects in policy "policy-0": 2
     Bytes in policy "policy-0": 26575872
    X-Account-Project-Domain-Id: default
                    X-Timestamp: 1457586773.61689
                     X-Trans-Id: tx2126c29c9f3b400cb6539-0056e103b0
                   Content-Type: text/plain; charset=utf-8
                  Accept-Ranges: bytes

 

 

올렸던 파일을 다운 받아 본다.

[root@controller ~]# swift download container1 cirros-0.3.4-x86_64-disk.img
cirros-0.3.4-x86_64-disk.img [auth 0.366s, headers 0.429s, total 0.505s, 95.682 MB/s]

 

+ Recent posts