이전까지 docker를 run 하고 run 된 docker의 log 를 어떤식으로 통합해서 관리하는지에 대해 공부했다.
이제는 docker에 대한 배포 관리를 어떻게 할지 공부해 본다.
프로젝트를 진행하면 굉장히 많은 docker images들이 생길것이다.
인증API 부터 여러 기능의 API들과 front End 부분의 nginx들도 있을것이고
이런 docker images들의 배포 와 실행을 효율적인 관리가 필요해져 생겨난것이 쿠버네티스 이다.
쿠버네티스 Doc 참조 : https://kubernetes.io/ko/docs/concepts/overview/what-is-kubernetes/
이제 쿠버네티스를 설치해보고 배포까지 해보도록하자.
먼저 쿠버네티스 설치를 위해 GCP 인스턴스를 두개를 만들도록 한다. 하나는 쿠버네티스 Master node로 하나는 Worker node로 사용할 것이다.
master-node : Ubuntu 18.04 CPU 2core mem 4g
worker-node : Ubuntu 18.04 CPU 2core mem 4g
이렇게 두개를 만들었다.
이제 두 인스턴스에 공통으로 설치되야하는 부분을 설치해보도록 하자.
먼저 Docker를 설치한다.
sudo apt update
sudo apt-get update
# Docker CE 설치
## 리포지터리 설정
### apt가 HTTPS 리포지터리를 사용할 수 있도록 해주는 패키지 설치
sudo apt-get install -y \
apt-transport-https ca-certificates curl software-properties-common gnupg2
### Docker의 공식 GPG 키 추가
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
### Docker apt 리포지터리 추가.
sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
## Docker CE 설치.
sudo apt-get update && sudo apt-get install -y \
containerd.io=1.2.13-1 \
docker-ce=5:19.03.8~3-0~ubuntu-$(lsb_release -cs) \
docker-ce-cli=5:19.03.8~3-0~ubuntu-$(lsb_release -cs)
# 데몬 설정.
sudo su -
cat > /etc/docker/daemon.json <<EOF
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2"
}
EOF
exit
sudo mkdir -p /etc/systemd/system/docker.service.d
# Docker 재시작.
sudo systemctl daemon-reload
sudo systemctl restart docker
이제 쿠버네티스에 필요한 kubeadm, kubelet, kubectl 를 설치 한다.
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install -y apt-transport-https curl
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
cat <<EOF | sudo tee /etc/apt/sources.list.d/kubernetes.list
deb https://apt.kubernetes.io/ kubernetes-xenial main
EOF
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
# 자동업데이트 방지
sudo apt-mark hold kubelet kubeadm kubectl
kubeadm version
kubelet --version
kubectl version
이제 mater node에서 아래 명령어를 실행한다.
sudo kubeadm init --pod-network-cidr=10.244.0.0/16 \
--apiserver-advertise-address=<GCP 인스턴스 내부아이피>
위 명령를 실행하면 아래와 같은 메세지가 나오는데
o start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Alternatively, if you are the root user, you can run:
export KUBECONFIG=/etc/kubernetes/admin.conf
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 10.178.0.10:6443 --token b3127i.2zzufx7o47jpl6s4 \
--discovery-token-ca-cert-hash sha256:d1f0978b8950b5009a5376ed2bde4826d87b4973902c7b6b3fe7bf2a9b0d9c55
위 메세지 부분에서 kubectl 명령어를 root 계정없이 사용하기 위해 아래를 실행
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
그리고 제일 마지막 부분의 kubeadm... 부분을 copy 해서 worker node에서 실행시켜주면된다.
kubeadm join 10.178.0.10:6443 --token b3127i.2zzufx7o47jpl6s4 \
--discovery-token-ca-cert-hash sha256:d1f0978b8950b5009a5376ed2bde4826d87b4973902c7b6b3fe7bf2a9b0d9c55
master node에 네트워크 add on을 설치한다. 쿠버네티스 클러스터 네트워킹의 동작을 위한 플러그인이라고 한다.
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/2140ac876ef134e0ed5af15c65e414cf26827915/Documentation/kube-flannel.yml
여기까지하고 master node에서 kubectl get pods 를 실행해보면 아래 처럼 나오는것을 확인 할 수 있다.
이제 테스트를 위해 docker hub에서 hello world images를 쿠버네티스에 deploy 시켜 pod를 할당해 보자.
kubectl create deployment kubernetes-bootcamp --image=gcr.io/google-samples/kubernetes-bootcamp:v1
위 명령어를 실행하면 만들어 놓은 worker-node에 pod가 할당되는것을 확인 할 수 있다.
kubectl get pods -o wide
pod에 할당받은 IP로 실행한 이미지가 가 잘 작동하는지 테스트 해 보자
curl을 날려 해당 container가 잘 작동하는것을 확인 할 수 있다.
이제 쿠버네티스가 잘 설치 되었다는것을 확인 했으니 앞에서 만들어 놓은 rest api images를 배포해 보자.
먼저 만들어 놓은 이미지를 docker hub에 psush 한다.
docker hub에 이미지를 올리고 아래 처럼 쿠버네티스 deployment yml파일 작성하고 deployment를 생성한다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-react-app
spec:
replicas: 3
minReadySeconds: 5
selector:
matchLabels:
app: my-react-app
template:
metadata:
name: my-react-app-pod
labels:
app: my-react-app
spec:
containers:
- name: my-react-app
image: kangzu8743/apitest:v1
imagePullPolicy: Always
ports:
- containerPort: 8080
kubectl create -f my-react-app-deployment.yml
depl,oyment를 실행하면 해당 deploymeny yml에 설정된 내용으로 pod가 만들어 진다.
기본으로 replica 3으로 설정되어 3개의 pod가 만들어 진다.
각각의 3개의 pod에 curl을 날려서 확인해 보자 .
의 그림과 같이 결과가 나오는것을 확인 할 수 있다. 이제 여기에 각각의 pod를 앞에 LoadBalancer 를 설정해 보자 .
쿠버네티스에서는 간단히 Component가 있다. 아래 yml 파일을 보면서 이해해 보자.
apiVersion: v1
kind: Service
metadata:
name: my-react-app-service
spec:
selector:
app: my-react-app
ports:
- port: 8080
protocol: TCP
targetPort: 8080
type: LoadBalancer
Service type이고 selector 부분을 보면 pod name이 my-react-app 인것들을 연결하고
포트는 8080 port 이고 my-react-app의 내부port 도 8080 이고 이 service의 type은 LoadBalancer 라고 되어 있다.
이렇게 설정된 값으로 service를 생성해 보자.
kubectl create -f lb-service.yml
결과를 확인해 보면
kubectl get services
와 같이 LB가 생성된 것을 확인 할 수 있다. 이제 curl로 확인을 해보면
여기서 문제는 EXTERNAL_IP가 pending 이 되어 있다. exnternal_ip가 할당 되지 않아서 그런지 CLUSTER-IP로는 정상적으로 데이터가 호출이 되는데 GCE 외부IP로 호출하게 되면 접속이 안된다.
확인해 보니 현재 instance에 8080으로 LISTEN 하고 프로세스가 없는것을 확인. 이로 미로어 볼때 쿠버네티스 클러스터에서 8080이 할당되어 있고 클러스터 외부에서는 8080을 Listen 하지 않는다는것인데 ...
여러내용을 찾아본 결과 서비스 생성 yml을 아래와같이 수정해 주면 해결!
apiVersion: v1
kind: Service
metadata:
name: my-react-app-service
spec:
selector:
app: my-react-app
ports:
- port: 8080
protocol: TCP
targetPort: 8080
externalIPs:
- 10.178.0.10
type: LoadBalancer
externalIPs:
- 10.178.0.10 ==> 이부분이 GCE의 내부IP(master node) 로 추가하면 외부에서 GCE 외부 IP로 접속해서 service 호출이 가능해 진다.
여기까지 쿠버네티스를 설치하고 배포하고 배포된 pod에 대한 LB 까지 테스트 해 봤다.
다음은 간단히 쿠버네티스의 무중단 배포에 대해 알아보도록 하자. 무중단 배포에 간단한 원리와 쿠버네티스에서는 어떤식으로 무중단 배포를 지원하는지를 공부해보자.
'Docker 시작하기 - RestAPI편' 카테고리의 다른 글
5) 쿠버네티스 CircleCI를 이용해 무중단 배포하기 (0) | 2021.01.06 |
---|---|
3) Spring Boot Rest API Docker log 보기 (0) | 2020.12.10 |
2) Spring Boot REST API를 Docker Image로 만들기 (0) | 2020.12.09 |
1) Docker 시작하기 (0) | 2020.12.08 |