# 부하 테스트 설명 및 구성도
1. kubelet - cAdvisor : cAdvisor(Container Advisor)는 컨테이너 사용자에게 실행 중인 컨테이너의 리소스 사용 및 성능 특성에 대한 정보를 제공한다.
2. Aggregate : 프로세스를 수집하고 실행 중인 컨테이너에 대한 정보를 내보내는 실행 데몬이다.
3. k8s API Server : API는 쿠버네티스 클러스터를 관리, 생성, 구성하는 데 사용되는 인터페이스입니다. 이 인터페이스를 통해 사용자, 외부 구성 요소, 클러스터의 각 부분이 서로 통신합니다.
4. HPA : HPA는 메트릭을 모니터링하고, 실제로 Pod의 수를 늘리거나 줄이는것은 ReplicaSet이나 Deployment에 의해서 컨트롤 된다.
5. ReplicaSet : 레플리카셋은 실행되는 파드 개수에 대한 가용성을 보증 하며 지정한 파드 개수만큼 항상 실행될 수 있도록 관리 합니다. 즉 5개의 파드를 항상 실행 하도록 설정하면 이후 파드 1개가 삭제될 경우 다시 파드 1개가 실행되어 5개를 유지할 수 있도록 해줍니다.
# 부하테스트를 위한 이미지 작성
1. 새로운 폴더를 생성한다.
mkdir php
cd php
2. 부하 테스트 코드를 생성한다.
vim index.php
<?php
$x = 0.0001;
for ($i = 0; $i <= 1000000; $i++) {
$x += sqrt($x);
}
echo "OK!";
?>
3. 부하테스트 코드를 포함한 도커 이미지 작성
vim Dockerfile
FROM php:5-apache
ADD index.php /var/www/html/index.php
RUN chmod a+rx index.php
4. 도커 이미지 빌드
- 현재 폴더의 Dockerfile을 읽어서 해당 id에 빌드를 수행한다.
$ docker build --tag {docker id}/php-apache .
$ docker images |grep php
kongru/php-apache latest 39e1797ad29c 23 seconds ago 355MB
- 빌드 수행 내역 : 빌드 작업은 이미지를 만드는 작업이라고 생각하면 된다.
ec2-user:~/environment/php $ docker build --tag may9noy/php-apache .
Sending build context to Docker daemon 3.072kB
Step 1/3 : FROM php:5-apache
5-apache: Pulling from library/php
5e6ec7f28fb7: Pull complete
cf165947b5b7: Pull complete
7bd37682846d: Pull complete
99daf8e838e1: Pull complete
ae320713efba: Pull complete
ebcb99c48d8c: Pull complete
9867e71b4ab6: Pull complete
936eb418164a: Pull complete
bc298e7adaf7: Pull complete
ccd61b587bcd: Pull complete
b2d4b347f67c: Pull complete
56e9dde34152: Pull complete
9ad99b17eb78: Pull complete
Digest: sha256:0a40fd273961b99d8afe69a61a68c73c04bc0caa9de384d3b2dd9e7986eec86d
Status: Downloaded newer image for php:5-apache
---> 24c791995c1e
Step 2/3 : ADD index.php /var/www/html/index.php
---> 2dd98569fdec
Step 3/3 : RUN chmod a+rx index.php
---> Running in 76dca74c5529
Removing intermediate container 76dca74c5529
---> 4d6b9c737c37
Successfully built 4d6b9c737c37
Successfully tagged may9noy/php-apache:latest
ec2-user:~/environment/php $
- 빌드 완료 후 docker image를 조회해보면 아래와같이 생성이 된것을 확인 할 수있다.
ec2-user:~/environment/php $ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
may9noy/php-apache latest 4d6b9c737c37 About an hour ago 355MB
jenkins/jenkins lts-jdk11 619aabbe0502 7 weeks ago 441MB
lambci/lambda python3.8 094248252696 8 months ago 524MB
lambci/lambda nodejs12.x 22a4ada8399c 8 months ago 390MB
lambci/lambda nodejs10.x db93be728e7b 8 months ago 385MB
lambci/lambda python3.7 22b4b6fd9260 8 months ago 946MB
lambci/lambda python3.6 177c85a10179 8 months ago 894MB
lambci/lambda python2.7 d96a01fe4c80 8 months ago 763MB
lambci/lambda nodejs8.10 5754fee26e6e 8 months ago 813MB
php 5-apache 24c791995c1e 2 years ago 355MB
- 여기까지는 local환경에 docker image가 생성되고 저장된 것이라고 보면되고, docker hub에 업로드 하기위해서는 별도의 작업이 필요하다.
-5. 생성한 docker image를 docker hub에 push 하는 작업을 해보자.
- 첫번째로 docker login을 입력하고, 개인 아이디와 패스워드를 인증하여 docker hub에 로그인을 하자.
ec2-user:~/environment/php $ docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: may9noy
Password:
WARNING! Your password will be stored unencrypted in /home/ec2-user/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
- 생성한 이미지를 docker hub에 push
docker push may9noy/php-apache
- docker push 프로세스
ec2-user:~/environment/php $ docker push may9noy/php-apache
Using default tag: latest
The push refers to repository [docker.io/may9noy/php-apache]
17f3175a133b: Pushed
4642696d2b69: Pushed
1aab22401f12: Mounted from library/php
13ab94c9aa15: Mounted from library/php
588ee8a7eeec: Mounted from library/php
bebcda512a6d: Mounted from library/php
5ce59bfe8a3a: Mounted from library/php
d89c229e40ae: Mounted from library/php
9311481e1bdc: Mounted from library/php
4dd88f8a7689: Mounted from library/php
b1841504f6c8: Mounted from library/php
6eb3cfd4ad9e: Mounted from library/php
82bded2c3a7c: Mounted from library/php
b87a266e6a9c: Mounted from library/php
3c816b4ead84: Mounted from library/php
latest: digest: sha256:d6f0c6c65d60bdcea9edf809f089e0502f2e63167d0050187310a64aab769e13 size: 3449
6. 부하테스트를 위해 쿠버네티스 클러스터에 pod으로 배포
vim hpa-test.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: php-apache
spec:
selector:
matchLabels:
run: php-apache
replicas: 1
template:
metadata:
labels:
run: php-apache
spec:
containers:
- name: php-apache
image: may9noy/php-apache #자신의 docker 저장소로 변경
ports:
- containerPort: 80
resources:
limits:
cpu: 500m
requests:
cpu: 200m
---
apiVersion: v1
kind: Service
metadata:
name: php-apache
labels:
run: php-apache
spec:
ports:
- port: 80
selector:
run: php-apache
7. 작성한 yaml 파일을 배포하자
kubectl apply -f hpa-test.yaml
deployment.apps/php-apache created
service/php-apache created
8. hpa 배포
- 오토 스케일러를 생성하자.
vim autoscaler.yaml
- 위에서 만든 부하테스트용 pod인 php-apache의 평균 cpu사용량을 50%로 맞추기 위해 레플리카의 개수를 늘리고 줄입니다. 50%가 넘어가면 새로운 pod를 10개까지 생성하고 50% 미만이 되면 생성된 pod를 줄입니다.
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: php-apache
namespace: default
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: php-apache
minReplicas: 1
maxReplicas: 10
targetCPUUtilizationPercentage: 50
- 실행 명령어
kubectl apply -f autoscaler.yaml
- hpa커맨드를 통해 현재 hpa에 감지되는 시스템 부하정도와 관리하는 pod의 개수를 확인할 수 있습니다.
ec2-user:~/environment/php $ kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
php-apache Deployment/php-apache <unknown>/50% 1 10 0 11s
ec2-user:~/environment/php $
아직은 서버로 어떠한 요청도 하지 않았기 때문에, 현재 cpu소비량은 0%임을 알 수 있습니다.
(TARGET은 deployment에 의해 제어되는 pod들의 평균을 뜻합니다. 예를들어 pod의 갯수가 10개라면 10개의 평균 사용량을 나타냅니다. /50%로 되어있는것은 pod의 평균 사용량이 50%를 넘을경우 pod를 스케일 아웃하여 10개까지 지속적으로 확장하겠다는 의미 입니다.)
9. 부하 테스트
- 실행 명령어
kubectl run -i --tty load-generator --rm --image=busybox --restart=Never -- /bin/sh -c "while sleep 0.01; do wget -q -O- http://php-apache; done"
- 오류 발생 만약 아래와 비슷한 오류가 발생한다면 istio를 설치 해주어야 한다.
failed calling webhook "namespace.sidecar-injector.istio.io"
1) AWS EKS 클러스터에 Istio 설치하기
1-1. Istio 다운로드
1) 우선 최신버전의 Istio 설치 파일을 다운받자.
curl -L https://istio.io/downloadIstio | sh -
(만약 최신버전이 아닌 특정 버전의 Istio 설치를 원한다면 아래 명령어를 통해 다운받으면 된다)
curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.6.8 TARGET_ARCH=x86_64 sh -
2) 설치가 완료되었으면 설치된 디렉토리로 이동한다.
cd istio-1.11.3
해당 디렉토리에서 istioctl 클라이언트 바이너리 파일은 bin/ 디렉토리에 존재하며, 실습을 위한 sample 어플리케이션은 sample/ 디렉토리에 존재한다.
3) 다음으로 istioctl 클라이언트를 PATH에 추가하자
export PATH=$PWD/bin:$PATH
2-2. Istio 설치
다음으로 Istio를 설치해보자. Istio 설치는 istioctl을 통해서 진행한다.
istioctl install
위 명령어를 통해 아무런 옵션 없이 설치를 하게 되면 Istio가 기본 설정 프로파일을 통해 쿠버네티스 클러스터에 설치된다. 상용 환경에서 설치를 진행할 때는 위와 같이 기본 설정으로 설치하는 것이 좋다.
부하가 증가함에 따라 오토스케일러가 어떻게 반응하는지 살펴보겠습니다.
창을 하나 더 띄워서 php-apache 서비스에 무한루프 쿼리를 전송합니다.
2-3. Istio 설치 체크
설치가 완료되었으면 Istio가 정상적으로 설치되었는지 확인해보자.
kubectl get deploy -n istio-system
ec2-user:~/environment/istio-1.11.3 $ kubectl get deploy -n istio-system
NAME READY UP-TO-DATE AVAILABLE AGE
istio-ingressgateway 1/1 1 1 13m
istiod 1/1 1 1 14m
ec2-user:~/environment/istio-1.11.3 $
- Istio가 정상적으로 실행되는것을 확인 할 수 있다.
- 이어서 부하 테스트를 진행해보자.
- 위에서 에러가 발생한 명령어를 다시 실행하여 부하 테스트를 진행하자.
kubectl run -i --tty load-generator --rm --image=busybox --restart=Never -- /bin/sh -c "while sleep 0.01; do wget -q -O- http://php-apache; done"
- 1~2분 지난 뒤에 hpa커맨드로 부하상태를 살펴보면 TARGET의 수치가 높아진 것을 확인할 수 있습니다.
$ kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
php-apache Deployment/php-apache 248%/50% 1 10 1 12m7s
- hpa 진행 상황을 살펴보자
ec2-user:~/environment $ kubectl get hpa -w
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
php-apache Deployment/php-apache 132%/50% 1 10 6 3m25s
php-apache Deployment/php-apache 129%/50% 1 10 6 3m45s
php-apache Deployment/php-apache 129%/50% 1 10 6 4m46s
- 그리고 deployment 컨트롤러를 확인해보면 pod의 replica수가 6개까지 늘어난 것을 확인할 수 있습니다.
ec2-user:~/environment $ kubectl get deploy php-apache
NAME READY UP-TO-DATE AVAILABLE AGE
php-apache 2/6 6 2 5m49s
ec2-user:~/environment $ 5 12m
- busybox컨테이너를 띄운 터미널에서 Ctrl+C로 부하 발생을 중단시키고, 몇 분 후에 결과를 확인합니다.
kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
php-apache Deployment/php-apache 0%/50% 1 10 5 11m
- cpu의 사용량이 0%까지 떨어졌고, deployment의 pod replica수도 1개로 줄어든 것을 확인할 수 있습니다.
kubectl get deploy php-apache
NAME READY UP-TO-DATE AVAILABLE AGE
php-apache 1/1 1 1 19m
- 최종확인 : replicas가 6개까지 증가하였다가, 서비스를 중지하고 나서 1개로 줄어든것을 확인 할 수 있습니다. targets의 부하도 1%로 줄어든것을 확인 할 수 있습니다. 스케일 아웃된 상태에서 부하가 줄어든면서 스케일 인으로 replicas를 줄인것을 확인 할 수 있습니다.
ec2-user:~/environment $ kubectl get hpa -w
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
php-apache Deployment/php-apache 132%/50% 1 10 6 3m25s
php-apache Deployment/php-apache 129%/50% 1 10 6 3m45s
php-apache Deployment/php-apache 129%/50% 1 10 6 4m46s
php-apache Deployment/php-apache 129%/50% 1 10 6 5m46s
php-apache Deployment/php-apache 1%/50% 1 10 6 6m46s
php-apache Deployment/php-apache 1%/50% 1 10 6 11m
php-apache Deployment/php-apache 1%/50% 1 10 1 11m
- 지금까지 쿠버네티스 부하테스트를 통한 오토스케일링 스케일 아웃과 스케일 인에 대해서 알아보았습니다.