까페24에서 서버 호스팅을 받다가 구글 클라우드 플랫폼으로 이전하기 위해 학습한 내용을 정리한다.

Google App Engine에 Spring Boot 애플리케이션을 배포해보자.


배포를 위해 사용한 환경은 다음과 같다.

1
2
3
IDE : IntelliJ
Application : Spring Boot (Java 8)
Platform : Google App Engine Flexible environment and Container Engine
cs


1. 구글 클라우드 플랫폼에서 프로젝트 생성


https://console.cloud.google.com 접속한 후 새로운 프로젝트 생성

구글 클라우드 플랫폼에서 신규 프로젝트를 생성한다.

 > 페이지 상단의 "프로젝트 선택" 클릭

 > 팝업 레이어에서 신규 프로젝트 생성 버튼 클릭

 > 새 프로젝트 이름을 넣은 후 "만들기" 클릭 


구글 앱 엔진을 사용하기 위해서는 프로젝트가 존재해야 한다.

구조화를 해보면 다음과 같이 되어 있다.

Project

 - App Engine

 - Compute Engine

 - Container Engine



2. 구글 클라우드 결제 설정


https://console.cloud.google.com/project/_/settings

결제 가능한 카드를 등록해야 한다.

나는 무료 크레딧 300달러 받아서 사용 중이다. (1년 사용 가능)

참고로 무료 크레딧을 받더라도 결제 가능한 카드는 등록해야 한다.



3. Google Cloud SDK 로컬 머신에 설치


https://cloud.google.com/sdk/ 접속 후 설치 진행

SDK 설치가 완료되면 command 명령창에서 gcloud init 입력하여 다음의 절차 진행

 - 로그인 할거냐고 물어봄

 - 웹 브라우저가 뜨고 구글 로그인 진행하면 됨

 - 프로젝트 선택 리스트 노출. 원하는 번호 선택



4. Java를 위한 SDK 컴퍼넌트 추가 설치


자바로 개발되어진 애플리케이션을 배포하기 위해서는 구글 SDK에 추가 컴퍼넌트가 필요하다.

command 명령창에서 다음의 명령어 실행

# gcloud components update app-engine-java

# gcloud components update



5. 스프링 부트 애플리케이션 준비


이건 알아서 설정하기



6. app.yaml 작성


배포를 위해서는 스프링 부트 프로젝트에 app.yaml 파일이 존재해야 한다.

src/main/appengine/app.yaml 위치에 파일 생성

1
2
3
4
5
6
7
8
9
service: default
runtime: java
env: flex
        
health_check:
  enable_health_check: False
    
manual_scaling:
  instances: 1
cs



service: default

앱 앱진 플랫폼에 배포되는 서비스 이름이다. 처음 앱 엔진에 애플리케이션을 배포한다면 default로 되어 있어야 한다. 이후에는 servie: nkServce1 과 같이 설정하여 배포 가능하다.

다음처럼 서비스가 되는 구조이다.

Project

 - Google App Engine

  - 서비스

   - default (필수)

   - nkService1

   - nkService2


runtime : java

자바이용


env: flex

스프링 부트를 배포하기 위해서는 flex 설정으로 되어 있어야 한다.

standard 버전도 존재하지만 servlet spec 2.5까지만 지원해서 flex 버전으로 설정해야 한다.

스프링 부트는 공식적으로 서블릿 2.5를 지원하지 않는다. 

단, 지원을 안할 뿐이지 war 배포 방식으로 사용 가능하다.


서블릿 2.5를 지원하는 스프링 부트 설정에 대해서 설명되어져 있다.

https://github.com/dsyer/spring-boot-legacy


flex 버전에 대한 설명

스프링 부트 애플리케이션이 Google Compute Engine 서비스 위에 Docker 컨테이너로 동작

"Using the App Engine flexible environment means that your application instances run within Docker containers on Google Compute Engine virtual machines (VMs)"


instances: 1

인스턴스 한 개만 띄우겠다는 의미

만약 부하 분산이 필요하다면 여러 대의 인스턴스를 띄우면 된다. 나는 서비스를 위한 목적이 아니므로 1로 셋팅했다.



7. maven 플러그인 추가


메이븐 플러그인을 이용해 구글 앱 엔진에 배포가 가능하다.

1
2
3
4
5
<plugin>
    <groupId>com.google.cloud.tools</groupId>
    <artifactId>appengine-maven-plugin</artifactId>
    <version>1.3.1</version>
</plugin>
cs



8. 커맨드 명령창에서 다음의 설정 작업을 실행한다.


아까 생성한 프로젝트 이름을 넣어주면 된다.

gcloud config set project {프로젝트이름}

ex) gcloud config set project nklee-project



9. 배포 및 애플리케이션 페이지 접속


마지막으로 인텔리J의 Maven Projects 윈도우를 통해 플러그인을 실행하면 된다.


빌드 및 배포가 완료되면 다음의 URL로 접속하자.

내가 만든 애플리케이션 페이지를 확인할 수 있다.

https://{프로젝트이름}.appspot.com


구글 클라우드 플랫폼 > project > App Engine > 서비스 메뉴에 접근하면 다음과 같이 default 서비스가 등록되어져 있다.



참고


만약 새로운 프로젝트의 앱 엔진에 애플리케이션을 배포하고 싶다면 다음의 명령어들을 이용해서 설정 변경해주면 된다.


내 계정에 생성된 프로젝트 리스트

gcloud projects list


현재 상태의 설정

gcloud config list


프로젝트 변경 설정

gcloud config set project {프로젝트이름}


연결 계정 정보

gcloud auth list



[참고 URL]

https://github.com/GoogleCloudPlatform/getting-started-java/tree/master/helloworld-springboot

https://cloud.google.com/appengine/docs/flexible/java/

저작자 표시
신고
Posted by nklee

kubernetes 정리

server/others 2017.01.12 17:19

kubernetes는 배포, 확장 및 운영을 자동화하는 컨테이너 관리툴이다.


kubernetes가 왜 필요한지에 대해서 알아보자.

kubernetes없이 Docker를 이용하여 애플리케이션을 서버에 배포하고 운영 하려면 shell script를 작성하거나 별도의 툴을 사용해야 한다.

shell script를 이용한 배포를 예로 들면 docker image registry에서 애플리케이션이 포함되어 있는 custom docker image를 다운로드 받고 이를 각 서버에 배포하고 실행하는 수준이 될 것이다.

이와 같은 배포는 최초 환경 구성 시 빡시게 하면 된다.

단, 서비스 운영을 하면서 과도한 사용자 요청이 있을 경우 성능 저하가 발생하게 되는데 그때서야 부랴부랴 서버를 확장하고 애플리케이션을 각 서버에 적절히 배포해야 하는 수고로움이 또 발생하게 된다.


kubernetes는 이와 같은 반복적인 애플리케이션의 배포 및 확장 그리고 운영을 자동화 하는 매우 좋은 툴이다.

구글에서 만들었고, 2014년에 오픈 소스로 공개하였다.


kubernetes에는 다음과 같은 기본 용어들이 있다.

  • cluster
  • master
  • node
  • deployment 
  • pod
  • service


[cluster]

kubernetes 클러스터를 실행하면 컨테이너화된 애플리케이션을 배치할 수 있다.

master, node를 아우루는 개념이라고 생각하면 된다.

cluster에는 최소한 3개의 node를 가지고 있어야 한다. 

node가 3개 이하로 운영 되어도 kubernetes 시스템 자체의 문제는 발생하지 않지만 

컨테이너의 롤링 업데이트 시 애플리케이션의 down time이 발생하기 때문에 최소 3개의 node를 권장하는 것으로 파악된다.



[master]

클러스터 관리를 담당한다.

클러스터 노드에 컨테이너 구동을 위한 스케줄링 작업을 진행 (스케줄링이라 함은 적절한 node(물리머신 or VM)에 배포를 의미)

master가 설치되어 있는 서버에서 kubernetes관련 프로세스를 확인해 보면 다음과 같이 5개의 프로세스가 동작하는 것을 확인할 수 있다.

마스터 서버의 자동 스케줄링은 각 노드에서 사용 가능한 리소스를 고려한다.


etcd

/opt/bin/etcd -name infra --listen-client-urls=http://127.0.0.1:4001,http://192.168.50.11:4001 -advertise-client-url

분산 코디네이터 overlay network를 지원한다.


etcdctl

etcd 분산 코디네이터를 실행하는 command 명령어


kube-apiserver

kube-controller-manager

kube-scheduler



[node]

node는 VM 또는 물리적 장비들이다.

각 노드에는 kubelet이 존재하며 kubernetes master와 통신(using kubernetes API)하며 노드를 관리한다. (kubelet을 agent라고도 부른다.)

컨테이너의 애플리케이션을 kubernetes에 배포할 때 마스터 서버에게 애플리케이션 컨테이너를 시작한다고 알린다.

각 Node는 Master의 관리를 받는다.



[deployment]

kubernetes Deployment는 애플리케이션 인스턴스들의 생성과 업데이트를 책임진다.

Deployment를 생성하면 쿠버네티스 마스터는 클러스터에 존재하는 각각의 노드위에 애플리케이션 인스턴스를 스케줄링 한다.

애플리케이션 인스턴스들이 생성되면 쿠버네티스 Deployment 컨트롤러는 이러한 인스턴스들을 지속적으로 모니터링 한다.

Deployment 컨트롤러는 노드 호스팅이 다운되거나 삭제가 된다면 인스턴스를 바꿔치기 한다. 이는 기계 고장 또는 장비 유지 보수에 대한 자가치유 메커니즘을 제공한다.

Deployment의 생성과 관리는 쿠버네티스 command line interface로 사용한다. (kubectl)

kubectl은 kubernetes API를 사용하여 cluster와 통신한다.

Deployment를 생성할 때 애플리케이션을 구동하기 위한 복제 숫자 및 명시적인 컨테이너 이미지가 필요하다.

Deployment Scaling up은 가용한 자원의 노드에 pods을 생성하고 스케줄링 하는 것을 보장한다.

쿠버네티스는 autoscaling을 제공한다.

 


[pod]

Deployment를 생성하면 쿠버네티스는 당신의 애플리케이션을 호스트 장비의 pod으로 생성한다.

pod에는 한개 또는 여러 개의 애플리케이션 컨테이너가 존재한다. 그리고 각 컨테이너들이 리소스를 공유할 수 있다.

pod은 항상 Node위에서 동작한다. Node는 쿠버네티스 안에서 동작하는 머신이다.

Node는 여러 개의 pod을 가질 수 있다.

쿠버네티스 마스터는 클러스터의 노드에서 pod을 자동으로 스케줄링 처리한다.



[service]

서비스는 pods에 포함된 컨테이너의 트래픽 로드 밸런싱을 지원한다.

# kubectl expose deployment kubernetes-bootcamp --type="NodePort" --port 8080


기본적으로 모든 pod들은 클러스터 내부에서만 볼 수 있다. 쿠버네티스 외부에서 애플리케이션에 접속하기 위해서는 우리의 머신과 클러스터 머신 사이에 proxy를 생성해야 한다.

# kubectl proxy

외부에서 http://localhost:8001/api/v1/proxy/namespaces/default/pods/<POD_NAME>/ 입력하면 된다.


기본적인 용어를 알아보았으니 이제 컨테이너 이미지를 쿠버네티스 환경에 배포, 실행, 운영하는 방법에 대해서 알아보자.


1.

쿠버네티스 환경 구성

설치 URL : http://lng1982.tistory.com/269



2.

pod 생성

# kubectl run kubernetes-bootcamp --image=jocatalin/kubernetes-bootcamp:v1 --replicas=2 --port=8080

kubernetes-bootcamp은 pod 이름의 prefix 가 된다. 예를 들어 2개의 pod이 생성되면 pod의 이름은 다음처럼 생성된다.

kubernetes-bootcamp-2019480069-7rhvb

kubernetes-bootcamp-2019480069-c6pxk

--image 뒤에 붙는 jocatalin/kubernetes-bootcamp:v1 은 이미지 주소이다.

도커 이미지 레지스트리는 기본적으로 https://hub.docker.com 를 바라본다.



3.

Service 생성

# kubectl expose deployment kubernetes-bootcamp --target-port=8080 --type=NodePort


Service 생성 후 # kubectl get svc 명령을 실행하면 다음과 같은 정보가 출력된다.

CLUSTER-IP : 클러스터 아이피 (kubernetes에서 생성하는 아이피)

EXTERNAL-IP : <nodes>의 의미는 노드의 아이피이다. 즉, 물리 머신의 아이피

PORT : <내부포트>:<NODE_PORT>/TCP


쿠버네티스 클러스터 내부에서는 curl 192.168.3.22:8080 을 통해 애플리케이션 호출이 가능하고 클러스터 외부에서는 curl <NODE_IP>:30958 과 같이 호출 가능하다.



4.

컨테이너 내부 접속

# kubectl exec kubernetes-bootcamp-390780338-178wd -ti bash



5.

컨테이너 로그 스트리밍

# kubectl logs -f kubernetes-bootcamp-390780338-178wd



6.

복제 확장

# kubectl scale deployments/kubernetes-bootcamp --replicas=4

auto scaling 관련 : http://kubernetes.io/docs/user-guide/horizontal-pod-autoscaling/



7.

쿠버네티스는 롤링 업데이트를 허용한다.

롤링 업데이트 시 새로운 pod이 가용한 노드에 생성된다.

롤링 업데이트 하는 동안에 Service는 요청 트래픽을 사용 가능한 pod으로 로드 밸런싱 한다.

# kubectl set image deployment kubernetes-bootcamp kubernetes-bootcamp=jocatalin/kubernetes-bootcamp:v2



8.

롤백

# kubectl rollout history deployment kubernetes-bootcamp

위의 명령어를 통해 history 정보 확인 후 롤백하고 싶은 revision 을 아래 명령어 실행 시 추가하면 된다.

# kubectl rollout undo deployment kubernetes-bootcamp --to-revision=1



[기타 정보]

[deployment 상태 정보]

DESIRED상태는 복제 숫자 설정을 보여주고 있다.

CURRENT상태는 몇 개의 복제가 동작하고 있는지 보여준다.

The UP-TO-DATE is the number of replicas that were updated to match the desired (configured) state

The AVAILABLE state shows how many replicas are actually AVAILABLE to the users



[yaml 파일로 pod 생성]

nginx-deployment.yaml

apiVersion: extensions/v1beta1

kind: Deployment

metadata:

  name: nginx-deployment

spec:

  replicas: 2

  template:

    metadata:

      labels:

        app: nginx

    spec:

      containers:

      - name: nginx

        image: nginx:1.8

        ports:

        - containerPort: 80


pod 생성은 다음의 명령어를 이용한다.

# kubectl create -f nginx-deployment.yaml


pod 정보 업데이트를 하고자 할 때에는 yaml 파일 변경 후 다음의 명령어를 이용한다.

# kubectl apply -f nginx-deployment.yaml 

  



저작자 표시
신고
Posted by nklee

Kubernetes 설치

server/others 2017.01.12 16:19


쿠버테티스 설치를 위한 호스트 정보는 다음과 같다고 가정한다.

 master

 192.168.50.11

 node(minion)

 192.168.50.2

 node(minion)

 192.168.50.11



1.

root로 로그인


2.

모든 호스트에 docker 설치

http://lng1982.tistory.com/268


3.

kubernetes pods 내부의 컨테이너 관리를 위해 설치

# apt-get install bridge-utils


4.

git 설치 및 kubernetes clone

master 노드에만 설치한다.

# apt-get install git -y

# git clone https://github.com/kubernetes/kubernetes.git


5.

설치 파일 및 바이너리 다운로드

# cd /root/kubernetes/cluster/ubuntu

# ./download-release.sh

Prepare flannel 0.5.5 release ...

Prepare etcd 2.3.1 release ...

Prepare kubernetes 1.4.7 release ...

Done! All your binaries locate in kubernetes/cluster/ubuntu/binaries directory


6.

쿠버네티스 node 설정

# vi /root/kubernetes/cluster/ubuntu/config-default.sh

아래 설정에 대해서만 수정하도록 한다. 

nodes에 추가되는 아이피는 마스터 서버를 첫 번째로 지정하고 노드 서버들은 그 뒤에 나열하면 된다. (스페이스로 구분)

roles에 추가되어 있는 a는 마스터를 의미하여 i는 노드를 ai는 마스터&노드를 의미한다. nodes 설정에 추가된 호스트 리스트 갯수에 맞게 설정한다.

export nodes=${nodes:-"root@192.168.50.11 root@192.168.50.2"}

roles=${roles:-"ai i"}

export NUM_NODES=2


7.

RSA 키 생성

# ssh-keygen -t rsa

계정의 홈 디렉토리 하위의 .ssh 폴더로 이동 후 아래 명령어 실행

# cat id_rsa.pub >> authorized_keys


8.

클러스터 배포 및 구동

kube-up 스크립트가 실행되면 바이너리, 설정 파일이 모든 node 머신에 복사되고(using scp) kubernetes 가 실행된다.

# cd /root/kubernetes/cluster

# KUBERNETES_PROVIDER=ubuntu ./kube-up.sh

... Starting cluster using provider: ubuntu

... calling verify-prereqs

Identity added: /root/.ssh/id_rsa (/root/.ssh/id_rsa)

... calling kube-up

~/kubernetes/cluster/ubuntu ~/kubernetes/cluster

Prepare flannel 0.5.5 release ...

Prepare etcd 2.3.1 release ...

Prepare kubernetes 1.5.1 release ...

Done! All your binaries locate in kubernetes/cluster/ubuntu/binaries directory

~/kubernetes/cluster


Deploying master and node on machine 192.168.50.11 <- master, minion 설치 및 실행

make-ca-cert.sh                                                                       100% 4136     4.0KB/s   00:00

easy-rsa.tar.gz                                                                         100%   42KB  42.4KB/s   00:00

config-default.sh                                                                      100% 6250     6.1KB/s   00:00

util.sh                                                                                    100%   29KB  29.1KB/s   00:00

kube-proxy.conf                                                                       100%  688     0.7KB/s   00:00

kubelet.conf                                                                            100%  645     0.6KB/s   00:00

kubelet                                                                                  100% 2158     2.1KB/s   00:00

kube-proxy                                                                             100% 2233     2.2KB/s   00:00

etcd.conf                                                                                100%  707     0.7KB/s   00:00

kube-scheduler.conf                                                                  100%  682     0.7KB/s   00:00

kube-apiserver.conf                                                                   100%  682     0.7KB/s   00:00

kube-controller-manager.conf                                                      100%  761     0.7KB/s   00:00

kube-controller-manager                                                            100% 2672     2.6KB/s   00:00

etcd                                                                                       100% 2073     2.0KB/s   00:00

kube-scheduler                                                                         100% 2360     2.3KB/s   00:00

kube-apiserver                                                                          100% 2358     2.3KB/s   00:00

reconfDocker.sh                                                                        100% 2183     2.1KB/s   00:00

kube-controller-manager                                                             100%   97MB  48.3MB/s   00:02

flanneld                                                                                   100%   16MB  15.8MB/s   00:00

etcd                                                                                        100%   16MB  15.9MB/s   00:00

etcdctl                                                                                     100%   14MB  13.7MB/s   00:00

kube-scheduler                                                                          100%   50MB  50.4MB/s   00:01

kube-apiserver                                                                           100%  117MB  39.1MB/s   00:03

flanneld                                                                                    100%   16MB  15.8MB/s   00:00

kubelet                                                                                    100%  103MB  25.7MB/s   00:04

kube-proxy                                                                               100%   44MB  43.6MB/s   00:01

flanneld.conf                                                                             100%  579     0.6KB/s   00:00

flanneld                                                                                   100% 2121     2.1KB/s   00:00

flanneld.conf                                                                             100%  570     0.6KB/s   00:00

flanneld                                                                                   100% 2131     2.1KB/s   00:00

etcd start/running, process 32528

{"Network":"172.16.0.0/16", "Backend": {"Type": "vxlan"}}

docker stop/waiting

docker start/running, process 32711

Connection to 192.168.50.11 closed.


Deploying node on machine 192.168.50.2 <- minion 설치 및 실행

config-default.sh                                                                     100% 6250     6.1KB/s   00:00

util.sh                                                                                    100%   29KB  29.1KB/s   00:00

reconfDocker.sh                                                                       100% 2183     2.1KB/s   00:00

kube-proxy.conf                                                                       100%  688     0.7KB/s   00:00

kubelet.conf                                                                            100%  645     0.6KB/s   00:00

kubelet                                                                                  100% 2158     2.1KB/s   00:00

kube-proxy                                                                             100% 2233     2.2KB/s   00:00

flanneld                                                                                 100%   16MB  15.8MB/s   00:01

kubelet                                                                                  100%  103MB  25.7MB/s   00:04

kube-proxy                                                                             100%   44MB  43.6MB/s   00:01

flanneld.conf                                                                           100%  579     0.6KB/s   00:00

flanneld                                                                                 100% 2121     2.1KB/s   00:00

flanneld start/running, process 13415

docker stop/waiting

docker start/running, process 13556

Connection to 192.168.50.2 closed.

Validating master

Validating root@192.168.50.11

Validating root@192.168.50.2

Using master 192.168.50.11

Cluster "ubuntu" set.

User "ubuntu" set.

Context "ubuntu" set.

Switched to context "ubuntu".

Wrote config for ubuntu to /root/.kube/config

... calling validate-cluster

Found 2 node(s).

NAME            STATUS    AGE

192.168.50.11   Ready     2h

192.168.50.2    Ready     1d

Validate output:

NAME                 STATUS    MESSAGE              ERROR

controller-manager   Healthy   ok

scheduler            Healthy   ok

etcd-0               Healthy   {"health": "true"}

Cluster validation succeeded

Done, listing cluster services:


Kubernetes master is running at http://192.168.50.11:8080


To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.


8.

패스 추가

root 홈 디렉토리의 .bashrc 파일에 아래 패스 추가

PATH=$PATH:/root/kubernetes/cluster/ubuntu/binaries/

PATH=$PATH:/opt/bin/


9.

노드 확인

# kubectl get nodes

NAME            STATUS    AGE

192.168.50.11   Ready     4h

192.168.50.2    Ready     1d



[명령어 모음]

>> 노드 리스트

kubectl get nodes


>> pod 생성

kubectl run my-nginx --image=nginx --replicas=2 --port=80


>> public internet에 서비스 공개

kubectl expose deployment my-nginx --target-port=80 --type=LoadBalancer


>> 팟 구성 및 상태

kubectl get pods

kubectl get pods --all-namespaces


>> pod의 서비스 상태

kubectl get service

kubectl describe service


>> 배포 상태 확인

kubectl get deployment


>> 컨테이너 삭제 public ip 삭제

kubectl delete deployment,service my-nginx


>> 라벨 확인

kubectl get pods -L run


>> pod 죽이기

kubectl delete pod <POT NAME>


>> pod 업데이트 하기 (하나 하나씩 진행)

kubectl set image deployment/my-nginx my-nginx=nginx:1.9.1


>> 롤백

kubectl rollout history deployment/my-nginx

kubectl rollout undo deployment/my-nginx --to-revision=1



kubectl get : list resources

kubectl describe : show detailed information about a resource

kubectl logs : print the logs from a container in a pod

kubectl exec : execute a command on a container in a pod





저작자 표시
신고
Posted by nklee


티스토리 툴바