[ft_services] docker, kubernetes

Lana Chung·2021년 5월 3일
0
post-thumbnail

(마참내!!!)

선배님들의 자료를 참고 + 유투브 강의를 들으며 하나 하나 쌓았다. 이렇게라도 공부할 수 있어서 다행..

Introduction

ft_services는 쿠버네티스를 소개하는 프로젝트입니다. 쿠버네티스를 통해 클러스터 관리와 배포를 진행할 것입니다. 가상 네트워크를 구축하고 "클러스터링"을 해봅시다. (클러스터링? 분산 컴퓨팅이란 뜻인가? 병렬 처리?)

General Instructions

  • srcs 폴더에 모든 config 파일 넣기
  • setup.sh 파일 레포의 root 위치에 놓기
  • old and new practices 모두 해봐라. Docker, Kubernetes에 대해 맘껏 읽으셈

Mandatory Part

  • Nginx로 웹 서버 구축하기 (한 개의 docker container에)
  • Container OS는 지난번과 같이 debian buster

~how to use docker~
코드 작성 -> 코드를 docker image로 build -> docker hub에 Image 푸시 -> image run해서 container build

클라우드란? 인터넷 기반의 컴퓨팅. 인터넷 상의 가상화된 서버에 프로그램을 두고 필요할 때마다 불러와 사용하는 서비스. 인터넷 통신망 어딘가에서 구름에 싸여 보이지 않는 컴퓨팅 자원(cpu, 메모리, 디스크 등)을 필요한만큼 가져다 사용 가능

가상머신과 컨테이너의 차이

(아래에서부터) 하드웨어(infrastructure), Hypervisor(vm ware, virtualbox 등 >> 이게 뭘까) 위에 가상머신을 설치한다. 가상머신 안에는 하드웨어(메모리, 네트워크, cpu..)를 구성하고, Guest OS를 설치하고, APP을 설치한다. 이 APP이 웹서버라고 하면, 클라이언트 사용자들이 필요한 만큼만 (하드웨어 리소스를 메모리 16기가, cpu 8코어 정도라고 한다면) 하드웨어에서 할당해주면 된다. 클라이언트가 늘어나면, 그만큼 더 할당. 가상머신 하나에는 하나의 APP을. 프론트단, 백단이 나눠지므로 각각 필요한 하드웨어만큼 할당해줌. 효율적!
요즘은 하나의 APP이 다운되도 다른게 잘 굴러가도록 수직이 아닌 수평 형태로 scale out 해줌.
요렇게 APP A를 쓰는 가상머신을 많이 실행시켜주는거임

그럼 컨테이너는? 하드웨어 - Host OS 운영체제 - Docker platform 올림 (daemon) - Containerized Applications가 돌아가게 됨. 각 APP들이 독립적으로 돌아감 (마치 각각이 가상머신인 것처럼)
(가상머신에는 Hypervisor에 최적화 되어있는 OS 포함되어 있다고 함)

APP A가 NginX라고 한다면, 100mb 정도 되는 이 App이 돌아가기 위해서 OS는 적어도 1기가~3기가가 필요한 것. 근데 저 가상머신을 3개나 복제해야 됨 가용성을 위해서.
컨테이너는 웹서버 + 웹 컨텐츠만 필요함. 실질적으로 100mb만 필요함. 확장(복제)도 훨씬 빠름. lightweight하기 때문에, 컨테이너의 주 목적은 배포 Deploy임.

근데 도커 한대가 고장난다면?


그래서 도커 플랫폼 하나를 더 만들어 드렸습니다.(worker node 2개) 세일 시즌 같은 트래픽에 대비해 웹 서버(각각 컨테이너임) 3개를 만들자. 분산해서 운영해주는 것. 근데 개발자가 모든 컨테이너를 배치하고 관리를 해주는 게 어려움. 어떤 시스템엔 APP 2개, 어떤 거엔 1개.. 어떻게 관리해줘야 되냐?에 대한 답 => 컨테이너 오케스트레이션. Container Orchestration 지휘자가 음악에 맞는 악기를 적절하게 배치해주듯이!


worker node를 관리해주는 control plane을 만들자.

컨테이너는 이렇게 쌓여 있습니다.

  • 여기서 우리가 쓸 OS는 debian buster,
  • Container Engine은 docker, Orchestration service model는 Kubernetes

Kubernetes란?

도커 플랫폼에 있는 컨테이너를 관리하고, 스케쥴링, 운영해주는 오케스트레이션이다. K8s (zz)
docs : 컨테이너화 된 애플리케이션을 자동으로 배포, 스케일링 및 관리해주는 오픈소스 시스템입니다. (구글작)

OS의 역할? 하드웨어에서 APP이 잘 동작하도록 도와주는 것. 쿠버네티스 또한 그런 역할을 하기 때문에, 쿠버네티스 개발자는 OS라고도 함

그럼 쿠버네티스를 로컬에 설치해보자.
순서는
1. 설치 전 환경설정 (도커 설치)
2. kubeadm, kubectl, kubelet 설치 (
3. control-plane 구성
4. worker node 구성
인데..

CNI (Container Network Interface)

  • 먼저 체크해줘야 하는 것
  • 컨테이너 간 통신을 지원하는 VxLAN (=Pod Network)
  • 컨테이너들(pod)은 자기만의 IP를 가지고 동작하는데, 서로 어떻게 통신해야 하나?
    - 여기서 pod는 쿠버네티스의 가장 기본적인 배포 단위로, 한 개 이상의 컨테이너로 구성됨
  • 실행) 컨테이너 <-> CNI <-> 물리 네트워크 <-> CNI <-> 또 다른 컨테이너

Kubectl

  • kubernetes command tool line(인듯?)
  • 커맨드 라인 도구, 쿠버네티스 클러스터에 대해 명령 실행하는 도구
  • 참고

쿠버네티스 동작 원리 (운영 flow)

요 강의를 들으면서 정리

Docker Hub의 주소가 hub.example.com일때

1.docker push hub.example.com/nginx

  • 여러 컨테이너 빌드 (main UI를 만들어주는 컨테이너, 로그인 컨테이너, 주문 작업 컨테이너..)
  1. Image nginx is pushed to Docker Hub
  • 도커 명령어로 Docker Hub에 push (사내일수도 있고, Docker.com의 public hub..)
  1. kubectl create deploy web --image=hub.example.com/nginx
  • 쿠버네티스 명령어로 이 컨테이너가 실행될 수 있도록 요청
  • yaml, 또는 CLI 형태의 명령어
    - yaml 작성 -> 서비스에 필요한 image build -> yaml 적용(빌드한 이미지 활용) 구조
    • yaml 파일을 kubectl 명령어를 통해 쿠버네티스 클러스터에 배포함으로써 사용
  1. kubectl issues REST call
  • 마스터 노드(control plane)에게 요청
  • 마스터 노드도 여러개?
  • 마스터에 REST API Server가 있음, 이게 쿠버네티스 요청을 받아줌
  1. Pod created and scheduled to a worker node
  • 작업 노드 여러대 생성
  • 이 중 어떤 노드에 nginx를 배치(실행)할지는 API 서버가 Scheduler에 요청
  • 스케쥴러는 작업 노드들의 상태를 보고 어느 노드가 가장 좋을지 선택, 응답
  1. Kubelet is notified
  • 스케쥴러가 응답한 작업노드의 Kubelet에 요청 (nginx 실행해라)
  1. Kubelet instructs Docker to run the image
  • 마스터 노드의 요청을 받은 Kubelet이 도커 명령으로 바꿔서 해당 노드의 도커 데몬에게 실제 컨테이너 실행 요청을 해줌
  1. Docker pulls and runs nginx
  • 도커 데몬은 도커 허브의 nginx 컨테이너를 서치하고, 있으면 pull 해오고 컨테이너 실행함
  • 그리고 쿠버네티스는 이렇게 동작하는 컨테이너를 POD 라는 단위로 관리함.

쿠버네티스 컴포넌트 (Kubernetes Architecture)

1. 마스터 컴포넌트 (control plane)

  • etcd 저장소
    - key-value 타입으로 저장되어있는 저장소
    • 워커 노드들에 대한 상태 정보 (하드웨어 리소스, docker 컨테이너의 동작 상태, 다운 받은 이미지의 상태..)
    • 이걸 어떻게 저장하냐? 워커 노드에 들어있는 kubelet(데몬)이 실행하면서 CAdvisor라고 하는 컨테이너 모니터링 툴이 해당 노드의 컨테이너 기반 상태 정보 수집함
    • 얘네가 마스터 노드에 전달하고 마스터 노드가 etcd안에 저장하게 되는 것
  • kube-apiserver
    - kubectl create 어쩌고란 명령어로 쿠버네티스를 실행할 때 요청을 받아주는 컴포넌트
    • 요청에 대한 문법, 권한이 합당한지 검사
    • etcd에 있는 정보 확인, 그 정보를 받아서 스케쥴러에게 전달
      • 스케줄러야 nginx 실행해야 하는데 어느 노드에 하는게 제일 합리적이니?
  • kube-scheduler
    - Pod를 실행할 노드 선택
    - 그럼 스케쥴러가 응답합니다. "노드 2"
    - API는 그 정보를 가지고 그러면 노드 2의 kubelet에 요청 보냄 nginx 컨테이너 실행해줘
    - 그럼 kubelet은 docker에게 docker 명령어로 nginx 실행해달라고 요청 보냄
    - 그럼 도커는 (도커 플랫폼에서) Docker Hub에 있는 nginx 컨테이너를 pull 해옴
  • kube-controller-manager
    - 돌아가고 있는 컨테이너의 개수 보장 (Pod를 관찰하며 개수 보장)
    - 나는 nginx 1개를 보장해 주겠어
    - nginx가 돌아가는 노드가 1개인지 계속 체크
    - 만일 부족하면 API에 요청 보냄 하나 더 실행해라~~

2. 워커 노드 컴포넌트

  • kubelet (데몬 형태로 동작)
    - 모든 노드에서 실행되는 k8s 에이전트
    - CAdvisor 컨테이너 모니터링 툴
  • kube-proxy
    - 실제 쿠버네티스의 Network 담당
  • container runtime
    - 실제 컨테이너를 실행해주는 엔진
    • Docker임
  • 컨테이너 간의 통신을 보장해주는 CNI 등은 애드온임
    - 근데 이런 애드온들은 base로 설치된대요 (마스터 구성될때)

3. 애드온

  • 네트워크 애드온 (CNI 등)
  • Dns 애드온 (coreDNS)
  • 대시보드 애드온 (<< 필요) (Kubernetes web UI)
    - pods/Deployments/API리소스
  • 컨테이너 자원 모니터링 (cAdvisor)
  • 클러스터 로깅 (필요한 로그들 정제해서 보여줌)

정리해야 하는 개념들

  • namespace
  • yaml
  • api version

deployment

  • 쿠버네티스가 app을 어떻게 생성하고 update 해야하는지 지시 (컨트롤러)

과제 순서

1. minikube 설치하기

brew install minikube

미니큐브는 쿠버네티스를 로컬에서 실행할 수 있는 도구다. 단일 노드 쿠버네티스 클러스터를 실행하여 쿠버네티스를 사용해보거나 일상적인 개발 작업을 수행할 수 있다. (스케줄러, 컨트롤러, api-server, etcd, kubelet, kube-proxy, DNS 등을) 설치해줌.
참고) 클러스터에서 할 때 ~/.zshrc에 환경변수 등록export MINIKUBE_HOME=~/goinfre
-> goinfre는 추가 메모리가 가능하대

minikube stop : 클러스터 중지

2. virtual box 설치

minikube start --driver=virtualbox
virtualbox vm을 활용하여 minikube 실행 << 하드웨어 위에 쌓는 Hypervisor
이후 setup.sh에 minikube와 virtual box를 연결해준다
(의식의 흐름)
아니 잠만 그래서 버츄얼 박스 어떻게 다운 받는데
아 찾았다 그냥 6.1.22 버젼 다운 받아도 되겠지 Virtualbox 6.1.22 platform packages
이거 260메가나 되네 클러스터에서 안깔리기만 해봐
와 한국말로 실행됨; 신기;
minikube status 로 상태 확인 가능

  • 마스터 노드 타입의 단일 노드 실행중인 것 확인 가능
  • api server, kubelet 동작중

3. MetalLB (Load Balancer) 설치

내용 출처 - https://velog.io/@du0928/ftservices

이게 뭐냐 하면은

  • bare Metal Load Balancer
  • On-premise 환경에서도 로드 밸런서 타입의 서비스를 배포할 수 있게 해주는 도구
    - On-premise : 클라우드나 원격 환경이 아닌 자체적으로 보유한 서버에 직접 설치에 운영하는 방식
  • 쿠버네티스의 서비스 객체들이 Loadbalancer type으로 선언되어 외부 IP를 할당 받을 수 있도록 도와줌 <<
  • 왜 필요한가?
    - 로드밸런서 타입의 서비스를 사용하기 위해 외부에서 접근 가능한 ip를 할당 받아야 하고, 해당 ip는 클라우드 벤더들에게 제공 받아야 한다.
    • 클라우드 벤더들의 ip 제공 없이 Loadbalancer type의 서비스를 사용하기 위해 MetalLB를 사용함.
  • pod는 쉽게 죽기도 하고 재실행 되기도 함. 이러면서 pod의 ip는 고정되어 있지 않고 계속 변함.
  • 이러한 pod를 Load Balancer 타입으로 포장해서 하나의 ip로 접근할 수 있게 하는 것
    설치
    1. kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.3/manifests/namespace.yaml
    - metallb-system으로 지정된 namespace 객체를 클러스터에 배포
    - 실행값 namespace/metallb-system created
    2. kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.3/manifests/metallb.yaml
    - metallb의 controller와 speker 생성
    3. kubectl create secret generic -n metallb-system memberlist --from-literal=secretkey="$(openssl rand -base64 128)" : memberlist secret을 만들어 speaker간 통신을 암호화
    - 실행값 secret/memberlist created
    4. kubectl apply -f ./srcs/metalLB_config.yaml
    - metallB configmap이 적용되기 위해 metallb-system namespace로 configmap yaml 파일을 만들어 적용시켜준다
    5. metallb를 세팅할 떄 사용되는 다양한 프로토콜 중 Layer 2 프로토콜을 활용하고 이를 configmap을 통해 전달함
    6. configmap yaml 파일의 addresses 부분에 트래픽을 받을 ip 범위를 지정해 주는데, host ip가 해당 범위내에 있어야 한다 (host ip는 minikube를 실행한 후에 minikube ip로 확인 가능)

쿠버네티스 명령어로 쿠버네티스 상황 확인
kubectl get all

  • 현재 실행되고 있는 모든 object들의 상태
    kubectl get pod 또는 service
  • 현재 실행되고 있는 모든 pod(service)의 상태
  • 지금 상태에서는 만들어진 pod가 없고 kubernetes라는 서비스만 존재

    kubectl delete service/deployment --all
  • 실행되고 있는 서비스 삭제

4. 도커와 쿠버네티스 연결

  1. eval $(minikube docker-env)
  2. ip는 minikube ip로 설정
  • IP=$(kubectl get node -o=custom-columns='DATA:status.addresses[0].address' | sed -n 2p)
  1. docker build image 필요한 컨테이너들 차례 차례 빌드하자 우선 웹서버부터
    • nginx : 우리의 웹서버
    • ftps :
    • mysql : 우리가 사용할 wp의 DB
    • wp (wordpress)
    • pma (phpmyadmin)
    • influxdb : 모니터링 솔루션
    • telegraf
    • grafana : 모니터링 솔루션 (시각화)

5. Nginx 설치

  1. `nginx -g "daemon off;"
  • nginx를 foreground로 실행하기
  • 다른 프로세스보다 우선적으로 실행되기 (해당 프로세스를 제외한 다른 프로세스 실행 불가)
  • daemon 상태는 background로 실행하는 것 (특정 프로세스가 실행되어도 다른 프로세스 실행 가능)
  1. docker build -t nginx
  • docker build -t nginx ./srcs/nginx
  • ft_server에서 썼던 도커파일 가져와서 이미지로 빌드해서 컨테이너 만들자 (이번엔 debian-buster가 아닌 alpine OS로 구축)
  1. docker run -it -p 80:80 -p 443:443 nginx

    -> 이러면 미니큐브 IP:443에서 nginx의 index.html이 제대로 나오고 있는 것을 확인할 수 있다.
    -> alpine:latest 이미지를 pull 했을 때는 DNS 에러가 발생해서, 3.12로 버젼을 별도로 지정해주었음
    -> 크롬으로 접속하면 보안 문제 때문에 접속이 안됨. 이번 서브젝트에서 ssh 내용이 제외되어서 ssh는 일부러 설정해주지 않았음

여기까지 해주고 setup.sh 업데이트 - nginx만 실행해보기
1. minikube start --driver=virtualbox
2. eval $(minikube docker-env)로 미니큐브-도커 연결
3. minikube addons enable metrics-server, dashboard - 필요한 애드온 사용
4. minikube dashboard & - 대시보드 새창으로 띄워주기
5. build images (docker build -t nginx .)
5. metalLB 로 LoadBalancer Type 만들어주기 (kubectl apply -f ~)
6. metalLB_config.yaml 파일 적용
7. services.yaml 파일로 pod, services 생성 (kubectl create -f ./srcs/nginx.yaml)
- type : Service, Deployment 하나씩
8. 웹서버가 쿠버네티스 위에서 잘 돌아가고 있는지 IP 접속 후 확인합니다.


현재 미니큐브 (쿠버네티스 클러스터)의 상황은, POD가 nginx-deployment 하나 돌아가고 있고, 서비스 객체 쿠버네티스와 nginx-service가 돌아가고 있음. nginx-service는 LoadBalancer type이고, pod를 하나 복제해줬음. 외부에서 해당 서비스로 접근할 수 있는 Cluster-IP는 192.168.99.100임

포트 설정

  • 노드 포트 : 외부에서 접근할 때 쓰는 포트
  • 포트 : 클러스터 내부에서 사용할 서비스 객체의 포트
  • 타겟 포트 : 서비스 객체로 전달된 요청을 Pod(deployment)으로 전달할 때 쓰는 포트

이제 서비스들을 하나 하나 설치 해줍시다 nginx 한 마냥

6. MySQL, phpmyAdmin, wordpress 설치

  1. ft_server에서 했던 config 파일 (wp-config.php, config.inc.php) 갖고오기
  2. init_docker.sh 파일과 init_mysql.sh 파일 정리 필요
    • 대충 데이터 디렉토리 초기화 하고 시스템 테이블 생성하는 명령어 (병렬적으로 처리)
  3. wordpress.sql 파일을 적용해줌.
    • 접속했을 때 설치 화면이 아닌 blog 화면이 바로 뜨게 해야 함
    • 그래서 sql 파일이 백업되어 있어야 하는 것
    • 나는 미리 워드프레스 블로그 개설하고 어드민에서 user랑 글 댓글 같은거 넣고 그거 export 해줌.
  4. yaml파일 - nginx처럼 LoadBalancer type으로 스펙 정의해주고 service/deployment 각각 만들어줌

7. telegraf, InfluxDB, grafana

출처

  • 각각 모니터링 데이터 수집(에이전트), 저장(DB), 시각화(Dashboard)
  • influxDB, telegraf, grafana 순서로 세팅 << 체크 안해봄
  • monitoring kubernetes with Grafana and InfluxDB
  • Grafana는 다수의 모니터링 솔루션으로부터 얻은 데이터(metrics)를 시각화해준다
  • 예쁜 대시보드와 built-in alerting 제공
  • InfluxDB는 시계열 데이터베이스로 고가용성 (high-availability) 저장소에 최적화 되어 있으며 시계열 데이터를 빠르게 retrieve 해준다.
  • InfluxDB는 주로 IoT, 센서 데이터, home 자동화 솔루션에서 사용됨
  • InfluxDB + Grafana 연동하여 쿠버네티스 클러스터에서 모니터링 시스템으로 활용된다
  • 튜토리얼에서는 helm 을 사용하여 설치하고 차트를 가져왔는데
  • 우리는 grafana 설치 후 서비스 별로 dashboard를 json 파일로 만들어서 grafana의 dashboards 폴더에 복사해줄거임
  • (참고) 원래 apk add grafana --repository http://dl-3.alpinelinux.org/alpine/edge/testing/으로 설치해줬는데 레포 주소 바뀜
  • testing 에서 community

dashboards.yaml

  • 설치 후 datasources.yaml 기반으로 influxdb를 연동시킴 (저장할 데이터 가져오기)
  • path에 있는 json 형태의 대시보드를 찾고 시각화

8. 마지막!! ftps 설치

아 그리고 307 redirection에서 엄청 헤맸다;

기존에 있었는데 사라진 것
1. ssh 보안 설정

체크할 때
kubectl get deploy
kubectl exec deploy/SERVICE이름 -- pkill APP (실제 구동되고 있는 엔진)
kubectl exec deploy/influxdb-deployment -- pkill influxd
kubectl exec deploy/ftps-deployment -- pkill pure-ftpd

명령어로 확인하기
curl -I -k https://192.168.99.114/wordpress
-> 307 temp 뜸
-> -k는 https 보안 인증서 certificate 아니어도 무시해주는거

profile
그게 쉬운 일이었다면, 아무런 즐거움도 얻을 수 없었을 것이다.

0개의 댓글