나그네소
Kubernetes for Goldilocks DB POD 생성 본문
Kubernetes API 에서 Docker에 Goldilocks DB Container 여러개 생성 되는 과정을
기록 하고 이에 대한 문제점을 분석해 본다.
1. Kubernetes 기본 동작 사항
- 사용자가 Kubernetes API에게 POD 생성 요청을 한다.
- API는 etcd etcd의 정보를 참고 하여 해당 node에 POD 생성해 달라 요청 한다.
- Node1,2 에는 kubelte에 Container 생성을 요청 한다.
- kubelte : 모든 노드에서 실행되는 k8s 에이전트
- kubelte : 데몬 형태로 동작 한다.
- kubelet는 docker에게 컨테이너 생성 요청 한다.
- docker 에서는 local repository 또는 docker hub에서 해당 되는 이미지를 가지고와 Goldilocks 컨테이너를 생성 한다.
2. Goldilocks Image Create
Docker 에서 사용 할 Goldilocks Docker Image을 생성 한다.
$> ls
Dockerfile Makefile dockerenv.default entrypoint.sh goldilocks
2-1) dockerenv.default
Docker Build 처리 시 사용할 환경 설정 값을 기록 한 파일 이다.
#!/usr/bin/env
# docker image create
NS ?= sunjesoft
VERSION ?= 21.1.9
IMAGE_NAME ?= cluster
CONTAINER_NAME ?= goldilocks
CONTAINER_INSTANCE ?= 0
# docker run
PORTS = -p 16101:10101 -p 24581:22581
ENV = -e TABLE_SPACE_SIZE=100M -e TEMP_TABLESPACE_SIZE=100M -e SERVICE_ACCOUNT=SA
OPTION= --sysctl kernel.shmmax=50359959552 \
--sysctl kernel.shmmni=4096 \
--sysctl kernel.shmall=12294912 \
--sysctl kernel.sem="250 32000 100 128" \
--hostname goldilocks-0
: dockrer run으로 수행 할게 아니기에 실제 Image에서 사용은 #docker image create 환경 설정값만 사용한다.
2-2) Dockerfile
FROM centos:7
# centos update
# yum update 처리한다
RUN yum update -y
# o/s에서 필요한 util 설치 한다
RUN yum install -y net-tools whtich crontabs vim locales tzdata gdb
# sunje 계정을 생성 한다.
RUN useradd -m -s /bin/bash sunje
# container에서 db을 생성 하기 위한 binary & data를 copy한다.
COPY *.sh /home/sunje/
COPY ./goldilocks/goldilocks_home /home/sunje/goldilocks_home
COPY ./goldilocks/goldilocks_data /home/sunje/goldilocks_data_create
RUN chown -R sunje:sunje /home/sunje/ \
&& mkdir -p /home/sunje/goldilocks_data \
&& chown -R sunje:sunje /home/sunje/goldilocks_home \
&& chown -R sunje:sunje /home/sunje/goldilocks_data \
&& chmod 777 -R /home/sunje
USER root
RUN echo "root:root" | chpasswd
USER sunje
WORKDIR /home/sunje
ENV CREATE_TABLE_QUERY="CREATE TABLE TEST (C1 INT PRIMARY KEY)"
ENTRYPOINT ["/bin/bash"]
CMD ["./entrypoint.sh"]
: 위의 Docker 파일을 이용하여 Container을 생성 한다.
2-3) Makefile
Docker Build를 사용해도 되지만 일관성을 유지하기 위하여 Makefile을 만들었다.
include dockerenv.default
build:
docker build -t $(NS)/$(IMAGE_NAME):$(VERSION) -f Dockerfile .
exec_shell:
docker exec -it $(CONTAINER_NAME)-$(CONTAINER_INSTANCE) bash
run_shell:
docker run -it --rm --name $(CONTAINER_NAME)-$(CONTAINER_INSTANCE) $(PORTS) $(VOLUMES) $(OPTION) $(ENV) $(NS)/$(IMAGE_NAME):$(VERSION)
stop:
docker kill $(CONTAINER_NAME)-$(CONTAINER_INSTANCE)
push:
docker push $(NS)/$(IMAGE_NAME):$(VERSION)
clean:
docker rmi sunjesoft/$(IMAGE_NAME):$(VERSION)
remove:
rm /home/son_kube/ymal/goldilocks/goldilocks/goldilocks_data/goldilocks-* -rf
version:
@echo $(VERSION)
: Image지를 만들 때는 build & push 두개만 사용 한다.
2-4) entrypoint.sh
Docker Container 수행 시 수행 할 shell을 기록 한다.
#!/bin/bash
source ~/.bashrc
${HOME}/goldilocks_home/entrypoint-init.sh
tail -f $GOLDILOCKS_DATA/trc/system.trc
2-5) goldilocks 디렉토리에 실제 수행 될 shell
goldilcks 디렉 토리에 container 수행 시 실제 수행하여 DB를 생성하는 shell에 대하여 분석해 본다.
: goldilocks 디렉토리는 위와 같은 환경으로 구성 되어 있는데 여기에서 중요한 항목은 entrypoint-init.sh로
실제 컨테이너는 Goldilocks 패키지만 들어가 있고 DB 생성 은 Docker run 실행 시 entrypoint-init.sh가 수행
되어 DB을 생성 하게 되는 구조로 되어 있다.
[entrypoint-init.sh]
#!/bin/bash
echo "pod name : $MY_POD_NAME"
rm ~/.bashrc
cp /home/sunje/goldilocks_home/bashrc-init ~/.bashrc
cp /home/sunje/goldilocks_home/gsql.ini ~/.gsql.ini
source ~/.bashrc
set -euxo pipefail
#DOCKER TEST Arument
########################
#MY_POD_NAME=goldilocks-0
#APP_NAME=GOLDILOCKS
#MY_POD_IP=127.0.0.1
########################
TABLE_SPACE_SIZE=${TABLE_SPACE_SIZE:-100M}
TABLE_SPACE_NAME=${TABLE_SPACE_NAME:-DATA_TBS}
TABLE_SPACE_FILE_NAME=${TABLE_SPACE_FILE_NAME:-data_01.dbf}
TEMP_TABLESPACE_SIZE=${TEMP_TABLESPACE_SIZE:-100M}
TEMP_TABLESPACE_NAME=${TEMP_TABLESPACE_NAME:-TEMP_TBS}
TEMP_TABLESPACE_FILE_NAME=${TEMP_TABLESPACE_FILE_NAME:-temp_01}
SERVICE_ACCOUNT_NAME=${SERVICE_ACCOUNT_NAME:-SA}
SERVICE_ACCOUNT_PASSWD=${SERVICE_ACCOUNT_PASSWD:-passwd}
CLUSTER_PORT=${CLUSTER_PORT:-10101}
GOLDILOCKS_HOME=/home/sunje/goldilocks_home
export ODBCINI=/home/sunje/goldilocks_data/$MY_POD_NAME/conf/odbc.ini
## Make goldilocks_data directory - bskim
if [ ! -d "/home/sunje/goldilocks_data/$MY_POD_NAME" ];
then
mkdir -p /home/sunje/goldilocks_data/$MY_POD_NAME
export GOLDILOCKS_DATA=/home/sunje/goldilocks_data/$MY_POD_NAME
cp /home/sunje/goldilocks_data_create/init-data/* /home/sunje/goldilocks_data/$MY_POD_NAME -R
echo $GOLDILOCKS_DATA
else
export GOLDILOCKS_DATA=/home/sunje/goldilocks_data/$MY_POD_NAME
fi
## Set Group name - bskim
## MY_POD_NAME : goldilocks-0
c=`echo $MY_POD_NAME | awk -F'-' '{print $2}'`
CLUSTER_CREATE_CHECK=$c
## Set Master name(toUpper membername) - bskim
## MEMBER_NAME : GOLDILOCKS-0
lower_name=$MY_POD_NAME
MEMBER_NAME=${lower_name^^}
## MEMBER_NAME, MY_POD_NAME, APP_NAME kubernetes yaml statefulset or yaml file set -shw-
if [ $c -gt 2 ];
then
GROUP_NAME=G2
MASTER=$APP_NAME'-3'
MASTER_OG=$APP_NAME'-0'
else
## GROUP_NAME : G1
## MASTER : GOLDILOCKS-0
GROUP_NAME=G1
MASTER=$APP_NAME'-0'
fi
## 공유 goldilocks_home/tmp/IP지정
## [root@tech10 tmp]# ls
# GOLDILOCKS-0 GOLDILOCKS-1 GOLDILOCKS-2 GOLDILOCKS-3 GOLDILOCKS-4
cat > /home/sunje/goldilocks_home/tmp/$MEMBER_NAME <<EOF
$MY_POD_IP
EOF
function init_cluster(){
# eq Master name - bskim
if [ $MEMBER_NAME == $MASTER ];
then
echo "-------------------------start master-------------------"
## lower_name=goldilocks-0
## GOLDILOCKS-0
lower_name=$MY_POD_NAME
MASTER_NAME=${lower_name^^}
## GROUP_NAME = G1 // DB만 Create 처리.
if [ $GROUP_NAME == "G1" ];
then
gcreatedb --cluster --member "$MASTER_NAME" --host $MY_POD_IP --port $CLUSTER_PORT
gsql sys gliese --as sysdba <<EOF
STARTUP
ALTER SYSTEM OPEN GLOBAL DATABASE;
\q
EOF
glsnr --start
glsnr --status
## Cluster Group 생성. : CREATE CLUSTER GROUP ....
gsql sys gliese --as sysdba <<EOF
CREATE CLUSTER GROUP $GROUP_NAME CLUSTER MEMBER "$MASTER_NAME" HOST '$MY_POD_IP' PORT $CLUSTER_PORT;
CREATE TABLESPACE $TABLE_SPACE_NAME DATAFILE '$TABLE_SPACE_FILE_NAME' SIZE $TABLE_SPACE_SIZE;
CREATE TEMPORARY TABLESPACE $TEMP_TABLESPACE_NAME MEMORY '$TEMP_TABLESPACE_FILE_NAME' SIZE $TEMP_TABLESPACE_SIZE;
CREATE USER $SERVICE_ACCOUNT_NAME IDENTIFIED BY $SERVICE_ACCOUNT_PASSWD DEFAULT TABLESPACE $TABLE_SPACE_NAME TEMPORARY TABLESPACE $TEMP_TABLESPACE_NAME;
GRANT ALL ON DATABASE TO $SERVICE_ACCOUNT_NAME;
\q
EOF
gsql sys gliese --as sysdba -i $GOLDILOCKS_HOME/admin/cluster/DictionarySchema.sql --silent
gsql sys gliese --as sysdba -i $GOLDILOCKS_HOME/admin/cluster/InformationSchema.sql --silent
gsql sys gliese --as sysdba -i $GOLDILOCKS_HOME/admin/cluster/PerformanceViewSchema.sql --silent
else
## G2 Group Member Create
gcreatedb --cluster --member "$MASTER_NAME" --host $MY_POD_IP --port $CLUSTER_PORT
gsql sys gliese --as sysdba <<EOF
STARTUP
ALTER SYSTEM OPEN GLOBAL DATABASE;
CREATE TABLESPACE $TABLE_SPACE_NAME DATAFILE '$TABLE_SPACE_FILE_NAME' SIZE $TABLE_SPACE_SIZE;
CREATE TEMPORARY TABLESPACE $TEMP_TABLESPACE_NAME MEMORY '$TEMP_TABLESPACE_FILE_NAME' SIZE $TEMP_TABLESPACE_SIZE;
COMMIT;
\q
EOF
glsnr --start
glsnr --status
MASTER_DNS=`cat /home/sunje/goldilocks_home/tmp/$MASTER_OG`
cat > /home/sunje/goldilocks_data/$MY_POD_NAME/conf/odbc.ini <<EOF
[$MASTER_OG]
HOST=$MASTER_DNS
PORT=22581
EOF
gsqlnet sys gliese --as sysdba --dsn=$MASTER_OG <<EOF
CREATE CLUSTER GROUP $GROUP_NAME CLUSTER MEMBER "$MEMBER_NAME" HOST '$MY_POD_IP' PORT $CLUSTER_PORT;
ALTER DATABASE REBALANCE;
COMMIT;
EOF
fi
echo "-------------------------end master-------------------"
else
echo "-------------------------start slave-------------------"
echo " MASTER_DNS=172.32.24.219(MASTER IP)"
MASTER_DNS=`cat /home/sunje/goldilocks_home/tmp/$MASTER`
cat > /home/sunje/goldilocks_data/$MY_POD_NAME/conf/odbc.ini <<EOF
[$MASTER]
HOST=$MASTER_DNS
PORT=22581
EOF
## MEMBER_NAME : GOLDILOCKS-1
## SLAVE Member DB Create
gcreatedb --cluster --member $MEMBER_NAME --host $MY_POD_IP --port $CLUSTER_PORT
gsql sys gliese --as sysdba <<EOF
STARTUP
ALTER SYSTEM OPEN GLOBAL DATABASE;
CREATE TABLESPACE $TABLE_SPACE_NAME DATAFILE '$TABLE_SPACE_FILE_NAME' SIZE $TABLE_SPACE_SIZE;
CREATE TEMPORARY TABLESPACE $TEMP_TABLESPACE_NAME MEMORY '$TEMP_TABLESPACE_FILE_NAME' SIZE $TEMP_TABLESPACE_SIZE;
COMMIT;
\q
EOF
glsnr --start
glsnr --status
echo "### CLUSTER_LOCAL_IP_ADDR[$MY_POD_IP]"
echo "### --dsn=$MASTER 접속하여 해당 Group에 Member Slave Member 추가"
gsqlnet sys gliese --as sysdba --dsn=$MASTER <<EOF
ALTER CLUSTER GROUP $GROUP_NAME ADD CLUSTER MEMBER "$MEMBER_NAME" HOST '$MY_POD_IP' PORT $CLUSTER_PORT;
ALTER DATABASE REBALANCE;
COMMIT;
EOF
echo "-------------------------end slave-------------------"
fi
}
function start_cluster(){
gsql sys gliese --as sysdba <<EOF
STARTUP
\q
EOF
glsnr --start
glsnr --status
}
DB=$GOLDILOCKS_DATA/db/system_data.dbf
if [ -f "$DB" ]; then
start_cluster
else
init_cluster
fi
tail -f $GOLDILOCKS_DATA/trc/system.trc
: 위의 부분은 하나씩 따라가면서 분석해 보면 이해가 갈것이다. 결론은 Goldilocks DB Master Member 기준으로
Cluster DB를 생성 후 하나씩 조인해 주는 것을 알 수 있다.
3. Goldilocks Docker Image 생성 및 Docker Hub push
Goldilocks Image 생성 하여 Docker Hub Site에 Push 한다.
3-1) Docker Build
make build option을 사용하여 빌드 한다.
$> make build
docker build -t sunjesoft/cluster:21.1.9 -f Dockerfile .
Sending build context to Docker daemon 343.7MB
Step 1/15 : FROM centos:7
7: Pulling from library/centos
2d473b07cdd5: Pull complete
Digest: sha256:c73f515d06b0fa07bb18d8202035e739a494ce760aa73129f60f4bf2bd22b407
Status: Downloaded newer image for centos:7
---> eeb6ee3f44bd
Step 2/15 : RUN yum update -y
---> Running in 5475cbb8cdcb
Loaded plugins: fastestmirror, ovl
Determining fastest mirrors
* base: mirror.anigil.com
* extras: mirror.anigil.com
* updates: mirror.anigil.com
Resolving Dependencies
--> Running transaction check
---> Package bash.x86_64 0:4.2.46-34.el7 will be updated
....
....
....
....
Removing intermediate container abebcdfaa943
---> 30a5241c3265
Successfully built 30a5241c3265
Successfully tagged sunjesoft/cluster:21.1.9
$> docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
sunjesoft/cluster 21.1.9 30a5241c3265 About a minute ago 1.46GB
centos 7 eeb6ee3f44bd 13 months ago 204MB
:sunjesoft/cluster:21.1.9로 Image가 생성 된 것을 알 수 있다.
3-2) image docker hub site push
$>make push
docker push sunjesoft/cluster:21.1.9
The push refers to repository [docker.io/sunjesoft/cluster]
29ce0c1a0f07: Pushed
a5451f019bc8: Pushed
492c9f154f19: Pushed
fb2ea567b7e5: Pushed
068d42a1b5d2: Pushed
d1fb19f9507d: Pushed
d43f5933b12b: Pushed
276057dc47d9: Pushed
21.1.9: digest: sha256:f64985b1662625afe9136801b69bc0fed1603ed3e38b5350b1e777caf4c90848 size: 2211
: pod을 생성 할 때 docker hub site를 사용 하거나 local repository을 이용하기에 docker hub site에 올린다.
'Cloud > Kubernetes' 카테고리의 다른 글
kubernetes pod container 정리 (0) | 2022.11.09 |
---|---|
kubernetes yaml 템플릿 과 API (0) | 2022.11.09 |
kubernets namespace (0) | 2022.11.02 |
kubernetes 동작 원리 (0) | 2022.11.02 |
kubernetes 명령어 (0) | 2022.11.01 |