-
Notifications
You must be signed in to change notification settings - Fork 13
Description
Definition Service 의 Deploy
Docker image 업로드
git clone https://github.com/TheOpenCloudEngine/uEngine5-base.git
cd uEngine5-base/definition-service
mvn package -B
docker build -t gcr.io/uengine5-k8s-project/uengine-definition-service:v1 .
docker push gcr.io/uengine5-k8s-project/uengine-definition-service:v1
Deployment 만들기
$ nano deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: uengine-definition-deployment
labels:
app: uengine-definition
group: uengine
spec:
replicas: 3
selector:
matchLabels:
app: uengine-definition
template:
metadata:
labels:
app: uengine-definition
group: uengine
spec:
containers:
- name: uengine-definition
image: gcr.io/uengine5-k8s-project/uengine-definition-service:v1
ports:
- containerPort: 8080
Deploy 시키기
kubectl create -f deployment.yml
kubectl get pods # deploy 확인
(pod 3개 생성된 것 확인)
uengine-definition-deployment-79d484b99f-px4fk 1/1 Running 0 1m
uengine-definition-deployment-79d484b99f-qb5hj 1/1 Running 0 1m
uengine-definition-deployment-79d484b99f-tvnp9 1/1 Running 0 1m
Service 생성하기
$ nano service.yml
apiVersion: v1
kind: Service
metadata:
name: uengine-definition-svc
labels:
app: uengine-definition
group: uengine
spec:
type: LoadBalancer
ports:
- port: 8080
selector:
app: uengine-definition
$ kubectl create -f service.yml
$ kubectl get services # 확인
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
eureka-svc LoadBalancer 10.43.253.142 35.225.148.29 8080:30547/TCP 1h
kubernetes ClusterIP 10.43.240.1 <none> 443/TCP 1d
uengine-definition-svc LoadBalancer 10.43.242.217 35.232.6.115 8080:32248/TCP 2m
웹브라우저를 하나 열어, 확인된 External-IP 인 35.232.6.115 에 8080 으로 접속하면 아래와 같이 서비스가 열린것을 확인 가능:
{
"_links" : {
"profile" : {
"href" : "http://35.232.6.115:8080/profile"
}
}
}
[Note] 지금은 테스트를 위해 Definition Service 를 곧바로 LoadBalancer 로 바로 노출 시켜 인터넷에서 확인했지만 나중에 Zuul 로 포장하여 우회시키고 ClusterIP (내부 ip) 로만 서비스를 열 예정이다.
프로세스 정의의 deploy
$ http POST http://35.232.6.115:8080/definition/raw/folder/object1.json definition="Hello"
HTTP/1.1 200
Content-Type: application/json;charset=UTF-8
Date: Mon, 27 Aug 2018 03:15:13 GMT
Transfer-Encoding: chunked
X-Application-Context: definition:msa:8080
{
"_links": {
"instantiation": {
"href": "http://35.232.6.115:8080/instance?defPath=/folder/object1.String.xml"
},
"raw": {
"href": "http://35.232.6.115:8080/definition/raw//folder/object1.String.json"
},
"self": {
"href": "http://35.232.6.115:8080/definition//folder/object1.String.xml"
}
},
"directory": false,
"name": "object1.String.xml",
"path": "/folder/object1.String.xml"
}
그런데, Deployment 가 3개 있기 때문에 파일의 저장소가 각 인스턴스별 달라져서 External Ip 로 GET할때마다 있을때도 있고 없을때도 있다. 이 문제는 Replica 들이 동일한 저장소를 mount하도록 처리함으로서 해결할 수 있다 (continued)
Google Cloud Disk 의 mount
앞서 인스턴스간 파일 시스템 공유를 위한 작업으로 PersistenceVolume 과 PersistenceVolumeClaim 객체를 만든다:
$ nano pv.yml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-demo2
spec:
storageClassName:
capacity:
storage: 20G
accessModes:
- ReadWriteOnce
gcePersistentDisk:
pdName: disk-2
fsType: ext4
$ kubectl create -f pv.yaml
$ nano pvc.yaml
apiVersion: v1
kind : PersistentVolumeClaim
metadata:
name: pv-claim-demo2
spec:
storageClassName: ""
volumeName: pv-demo2
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20G
$ kubectl create -f pvc.yml
각 Storage 는 gcloud 에서 미리 생성해두어야 한다. storage 생성방법은 아래와 같으며, project 와 동일한 region 에 생성시켜주야 한다.
gcloud compute disks create mydisk --size 100gb --type pd_standard
그런후, 생성한 PersistenceVolumeClaim 을 Deployment 내의 spec 란에 mount 시켜주면 된다.
$ nano deployment.yml
...
spec:
containers:
- name: uengine-definition
image: gcr.io/uengine5-k8s-project/uengine-definition-service:v1
ports:
- containerPort: 8080
volumeMounts:
- name: storage
mountPath: /oce/repository
volumes:
- name: storage
persistentVolumeClaim:
claimName: pv-claim-demo2
위와 같이 수정후, 반영:
kubectl apply -f deployment.yml
무정지 재배포
kubectl get pods
kubectl get deployments
kubectl set image deployment/uengine-definition-deployment uengine-definition=uengine-definition-service:v2 #container 명=registry:tag
kubectl rollout status deployment/uengine-definition-deployment
kubectl get deployments
kubectl get pods
kubectl describe pods (podname)
롤백
kubectl get pods
kubectl get deployments -o wide
kubectl rollout undo deployment/uengine-definition-deployment
kubectl get deployments -o wide
오토스케일링
kubectl autoscale deployment uengine-definition-deployment --cpu-percent=50 --min=1 --max=10
Availability 체크 통한 Self-Healing 관리
$ nano deployment.yml
...
spec:
containers:
...
livenessProbe:
httpGet:
path: /healthz
port: 8080
httpHeaders:
- name: X-Custom-Header
value: Awesome
initialDelaySeconds: 3
periodSeconds: 3
(저장후 quit)
kubectl apply -f ~/deployment.yml
Netflix OSS 적용하기
Registry 서비스 올리기
cd ~/
docker build -t gcr.io/uengine5-k8s-project/eureka:v1 . #gcr.io 가 들어가면 goole registry 에 등록됨
docker push gcr.io/uengine5-k8s-project/eureka:v1
$ nano deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: eureka-deployment
labels:
app: eureka
spec:
replicas: 3
selector:
matchLabels:
app: eureka
template:
metadata:
labels:
app: eureka
spec:
containers:
- name: eureka
image: gcr.io/uengine5-k8s-project/eureka:v1 #전체 주소를 주야 함.
ports:
- containerPort: 8741 # 8741 로 내부에서 오픈했다...
(kubectl delete deployments -l app=eureka # 지울일이 있다면.. 그러나 정지상태를 노출할 수 있으니 테스트 때만 사용하고, 운영때는 apply -f 나 image change 를 하는걸 추천)
kubectl apply -f deployment.yml
kubectl get pods
kubectl describe pod eureka-deployment-7cddf689df-hxvzh #pod가 일단 잘 디플로이 됐는지 확인
서비스(LoadBalancer) 등록 통한 외부노출
apiVersion: v1
kind: Service
metadata:
name: eureka-svc
labels:
app: eureka
spec:
ports:
- port: 27017
protocol: TCP
selector:
app: eureka
Registry 서비스의 주소는 환경변수를 통하여 각 서비스에 전파시켜야 하는데, Kubernetes 에서는 각 서비스들의 주소를 전달하는 체계로 환경변수 혹은 내부 DNS 를 사용한다. 환경 변수는 유레카가 내려갔다 올라올때 전체 서비스의 재기동을 야기할 수 있으므로, 여기서는 내부 DNS를 사용하는게 좋다:
$ nano src/main/resources/application.yml
... dev, stg, prod 에 해당하는 profile 에서 설정 ..
eureka:
client:
serviceUrl:
defaultZone: http://eureka-svc.default.svc.cluster.local:8761/eureka/ #서비스명.네임스페이스명(기본은 default).svc.cluster.local 로 접근가능하다.
설정을 먹히게 하기 위해 1. 메이븐빌드, 2. 도커빌드, 3. 레지스트리 푸시, 4. 쿠버 desired state 변경을 아래와 같이 수행한다:
mvn package -B
docker build -t gcr.io/uengine5-k8s-project/uengine-definition-service:v2 . # 버전업
docker push gcr.io/uengine5-k8s-project/uengine-definition-service:v2
nano deployment.yml
(image 를 gcr.io/uengine5-k8s-project/uengine-definition-service:v2 로 변경 후 저장)
kubectl apply -f deployment.yml
[Tip] 환경 변수로 혹시 전달을 해야 하는 경우라면, 다음과 같이 모든 서비스들의 주소는 아래처럼 container 내부의 환경 변수로 전달됨을 확인할 수 있으므로, "Service명_HOST" 를 통하여 얻어낸 후 애플리케이션에 전달해주면 된다.
$ kubectl exec -it uengine-definition-deployment-79d484b99f-px4fk -- /bin/sh
/ # export
export CI_COMMIT_SHA=''
export CI_PROJECT_NAME=''
export EUREKA_SVC_PORT='tcp://10.43.253.142:8080'
export EUREKA_SVC_PORT_8080_TCP='tcp://10.43.253.142:8080'
export EUREKA_SVC_PORT_8080_TCP_ADDR='10.43.253.142'
export EUREKA_SVC_PORT_8080_TCP_PORT='8080'
export EUREKA_SVC_PORT_8080_TCP_PROTO='tcp'
export EUREKA_SVC_SERVICE_HOST='10.43.253.142'
export EUREKA_SVC_SERVICE_PORT='8080'
export HOME='/root'
export HOSTNAME='uengine-definition-deployment-79d484b99f-px4fk'
export JAVA_ALPINE_VERSION='8.111.14-r0'
export JAVA_HOME='/usr/lib/jvm/java-1.8-openjdk'
export JAVA_VERSION='8u111'
export KUBERNETES_PORT='tcp://10.43.240.1:443'
export KUBERNETES_PORT_443_TCP='tcp://10.43.240.1:443'
export KUBERNETES_PORT_443_TCP_ADDR='10.43.240.1'
export KUBERNETES_PORT_443_TCP_PORT='443'
export KUBERNETES_PORT_443_TCP_PROTO='tcp'
export KUBERNETES_SERVICE_HOST='10.43.240.1'
export KUBERNETES_SERVICE_PORT='443'
export KUBERNETES_SERVICE_PORT_HTTPS='443'
export LANG='C.UTF-8'
export PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/lib/jvm/java-1.8-openjdk/jre/bin:/usr/lib/jvm/java-1.8-openjdk/bin'
export PWD='/'
export SHLVL='1'
export TERM='xterm'