3장
환경 세팅
이제 쿠버네티스로 컨테이너 인프라 환경을 자동으로 구축해보자.
위에서 언급했듯이 컨테이너 인프라 환경이란 운영 체제의 커널 하나에서 여러 개의 컨테이너가 격리된 상태로 실행되는 인프라 환경이다.
컨테이너는 가상머신과 많이 비교된다.
가상머신 VS 컨테이너?
AWS에서는 가상머신과 컨테이너를 애플리케이션을 IT 인프라 리소스로부터 독립적으로 만드는 배포 기술이라고 정의한다. 두 기술은 공통적으로 소프트웨어 인프라를 이미지 파일이라는 단일 파일로 패키징할 수 있도록 해서 편리하게 애플리케이션을 어디서나 실행할 수 있도록 해준다. 두 기술은 각각 아래와 같이 설명할 수 있다.
가상머신은 물리적 머신의 디지털 사본이다. 기존의 컴퓨터, 즉 호스트OS 위에 원하는 운영체제를 가상화한 게스트OS를 띄워 사용하는 방식이다. 호스트OS를 가상화시켜주는 소프트웨어를 하이퍼바이저라고 하는데 우리가 위에서 사용했던 virtual box도 여기에 포함된다. 가상머신을 사용하면 게스트OS도 하나의 OS를 독립적으로 가지고 있는 것처럼 사용이 가능하다.
가상머신은 물리적 하드웨어 용량을 효율적으로 사용하기 위한 용도로 개발되었다. 하나의 물리적 서버에서 하나의 애플리케이션 환경을 실행하면 하드웨어 리소스의 활용도가 낮아지므로 가상머신을 사용해서 여러 운영체제를 설치하고 하나의 물리적 시스템에 여러 환경을 구축하는 방식으로 사용한다.
컨테이너는 소프트웨어 코드 패키지이다. 가상머신처럼 독립적으로 OS를 사용하는게 아닌, 하나의 호스트OS를 공유한다. Docker와 같은 소프트웨어가 컨테이너를 만들어주고 컨테이너들간의 호스트 자원을 분리해서 사용하게 해준다. 즉, 컨테이너는 하나의 OS를 공유하는 구조이기 때문에 가상머신보다 빠르지만 서로다른 OS를 사용할 수 있는 가상머신과 다르게 리눅스 OS에서 윈도우용 컨테이너를 사용할 수 없다는 단점을 가지고 있다.
컨테이너는 여러 환경해서 반복적으로 애플리케이션을 패키징하고 실행하기 위한 용도로 개발되었다. 환경을 재구축하는 불편함을 줄이고 모든 유형의 환경에서 실행가능하도록 애플리케이션을 패키징한 것이다.
MSA 환경에서 분리된 애플리케이션을 빠르게 배포하는 요즘에는 가상머신보다는 컨테이너 방식을 더 많이 사용한다. 가상머신은 환경을 재생성해야 하기 때문에 수정하고 검증하는데 시간이 오래 걸리기 때문이다. 반면에 컨테이너는 고급 소프트웨어만 포함되어 있기 때문에 수정하고 검증하는 속도가 매우 빠르다. 또한 컨테이너는 하나의 ’파드‘ 단위로 묶어서 파드 단위로 배포를 간편하게 할 수 있고 서비스에 부하가 많이 가는 경우 필요한 파드만 확장할 수 있다. 이러한 작업을 ’쿠버네티스‘가 해주게 된다.
쿠버네티스란?
쿠버네티스는 컨테이너 오케스트레이션을 위한 솔루션이다. 오케스트레이션(Orchestration)이란 복잡한 단계를 관리하고 요소들의 유기적인 관계를 미리 정의해 손쉽게 사용하도록 서비스를 제공하는 것을 의미한다. 즉, 쿠버네티스는 위에서 언급한 컨테이너 인프라 환경을 좀 더 효율적으로 관리할 수 있도록 도와준다.
쿠버네티스를 구성하는 방법은 크게 3가지가 있다.
- AWS, Azure, Google Cloud Platform 과 같은 퍼블릭 클라우드 업체에서 제공하는 관리형 쿠버네티스를 사용하는 방법
-> 구성이 이미 다 갖춰져 있고 마스터 노드를 클라우드 업체에서 관리하기 때문에 학습용으로 적합하지 않음 - Rancher, OpenShift와 같은 설치형 쿠버네티스를 사용하는 방법
-> 유료라 쉽게 접근하기 어려움 - 사용하는 시스템에 쿠버네티스 클러스터를 자동으로 구성해주는 kubeadm, kops, KRIB, kubespray와 같은 구성형 쿠버네티스
-> 우리는 학습을 위해 사용자 설정이 가장 많이 필요한 kubeadm으로 구성!
또한, 쿠버네티스가 설치되는 서버 노드는 가상머신을 사용해서 실제 온프레미스에 가깝게 구성할 것이고, 설치되는 과정을 베이그런트로 자동화해서 필요하면 쿠버네티스 테스트 환경을 재구성할 수 있도록 한다.
베이그런트 스크립트 파일을 제공되는 실습파일을 활용한다. 주어진 코드는 다음과 같다.
# Vagrantfile - 베이그런트 프로비저닝을 위한 정보를 담고 있는 메인 파일
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
N = 3 # max number of worker nodes -> 해당 변수를 24, 46번째 줄에서 config.sh로 넘김. 사용자가 워커 노드의 개수를 직접 조절할 수 있게 하기 위함.
Ver = '1.18.4' # Kubernetes Version to install
#=============#
# Master Node #
#=============#
config.vm.define "m-k8s" do |cfg|
cfg.vm.box = "sysnet4admin/CentOS-k8s"
cfg.vm.provider "virtualbox" do |vb|
vb.name = "m-k8s(github_SysNet4Admin)"
vb.cpus = 2
vb.memory = 3072
vb.customize ["modifyvm", :id, "--groups", "/k8s-SgMST-18.6.0(github_SysNet4Admin)"]
end
cfg.vm.host_name = "m-k8s"
cfg.vm.network "private_network", ip: "192.168.1.10"
cfg.vm.network "forwarded_port", guest: 22, host: 60010, auto_correct: true, id: "ssh"
cfg.vm.synced_folder "../data", "/vagrant", disabled: true
cfg.vm.provision "shell", path: "config.sh", args: N # kubeadm으로 쿠버네티스를 설치하기 위한 사전 조건을 설정하는 스크립트 파일
cfg.vm.provision "shell", path: "install_pkg.sh", args: [ Ver, "Main" ] # 쿠버네티스 버전정보와 Main(마스터 노드에서만 특정 행위를 하도록)이라는 문자를 install.pkg로 넘김
cfg.vm.provision "shell", path: "master_node.sh" # 마스터 노드를 위한 코드
end
#==============#
# Worker Nodes #
#==============#
(1..N).each do |i|
config.vm.define "w#{i}-k8s" do |cfg|
cfg.vm.box = "sysnet4admin/CentOS-k8s"
cfg.vm.provider "virtualbox" do |vb|
vb.name = "w#{i}-k8s(github_SysNet4Admin)"
vb.cpus = 1
vb.memory = 2560
vb.customize ["modifyvm", :id, "--groups", "/k8s-SgMST-18.6.0(github_SysNet4Admin)"]
end
cfg.vm.host_name = "w#{i}-k8s"
cfg.vm.network "private_network", ip: "192.168.1.10#{i}"
cfg.vm.network "forwarded_port", guest: 22, host: "6010#{i}", auto_correct: true, id: "ssh"
cfg.vm.synced_folder "../data", "/vagrant", disabled: true
cfg.vm.provision "shell", path: "config.sh", args: N
cfg.vm.provision "shell", path: "install_pkg.sh", args: Ver
cfg.vm.provision "shell", path: "work_nodes.sh" # 워커 노드를 위한 코드
end
end
end
# config.sh - kubeadm으로 쿠버네티스를 설치하기 위한 사전 조건을 설정하는 스크립트 파일
#!/usr/bin/env bash
# vim configuration -> vi를 호출시 vim을 호출하도로고 프로파일에 입력 (코드에 하이라이트 넣을 수 있음)
echo 'alias vi=vim' >> /etc/profile
# swapoff -a to disable swapping -> 쿠버네티스의 설치 요구 조건을 맞추기 위해 스왑되지 않도록 설정
swapoff -a
# sed to comment the swap partition in /etc/fstab -> 시스템이 다시 시작되더라도 스왑되지 않도록 설정
sed -i.bak -r 's/(.+ swap .+)/#\1/' /etc/fstab
# kubernetes repo
gg_pkg="packages.cloud.google.com/yum/doc" # Due to shorten addr for key
cat <<EOF > /etc/yum.repos.d/kubernetes.repo -> ~21번째줄: 쿠버네티스를 내려받을 리포지터리 설정
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://${gg_pkg}/yum-key.gpg https://${gg_pkg}/rpm-package-key.gpg
EOF
# Set SELinux in permissive mode (effectively disabling it) -> selinux가 제한적으로 사용되지 않도록 permissive모드로 변경
setenforce 0
sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
# RHEL/CentOS 7 have reported traffic issues being routed incorrectly due to iptables bypassed -> 특정 패킷을 iptables가 관리하도록 설정
cat <<EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
modprobe br_netfilter # br_netfilter 커널 모듈을 사용해 브리지로 네트워크를 구성
# local small dns & vagrant cannot parse and delivery shell code. -> 쿠버네티스 안에서 노드 간 통신을 이름으로 할 수 있도록 호스트 설정
echo "192.168.1.10 m-k8s" >> /etc/hosts
for (( i=1; i<=$1; i++ )); do echo "192.168.1.10$i w$i-k8s" >> /etc/hosts; done
# config DNS -> 외부와 통신할 수 있도록 DNS 서버 지정
cat <<EOF > /etc/resolv.conf
nameserver 1.1.1.1 #cloudflare DNS
nameserver 8.8.8.8 #Google DNS
EOF
# docker repo
yum install yum-utils -y
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
참고
* swap: 리눅스에서 swap은 컴퓨터의 메모리가 모두 사용됐을 때 추가적으로 사용할 수 있는 메모리부분을 swap(파티션)이라는 예비 공간으로 사용. swapoff명령어는 swap 영역을 비활성화하는 명령어. 비활성화를 하게 되면 swap영역을 비워내게 된다. -a는 /etc/fstab 파일에 등록된 스왑 영역을 전부 비활성화 시키는 옵션이다.
* SELinux: 보안 모듈. enforce(default), permissive, disable 3가지 모드가 있음. enforce는 보안 정책에 위배되는 모든 액션을 차단시킴. (setenforce 1 명령어를 통해 전환) permissive는 경고 메시지를 내고 차단하지는 않음. (setenforce 0 명령어를 통해 전환). disable은 SELinus를 끄는 모드. (SELINUX=disabled를 통해 끔)
# install_pkg.sh - 클러스터를 구성하기 위해서 가상 머신에 설치돼야 하는 의존성 패키지를 명시
#!/usr/bin/env bash
# install packages
yum install epel-release -y
yum install vim-enhanced -y
yum install git -y
# install docker
yum install docker-ce-18.06.0.ce-3.el7 docker-ce-cli-18.06.0.ce-3.el7 \
containerd.io-1.2.6-3.3.el7 -y
systemctl enable --now docker
# install kubernetes cluster -> 첫번째 변수($1=Ver='1.18.4')로 넘겨받은 버전의 kubectl, kubelet, kubeadm을 설치하고 kubelet을 시작
yum install kubectl-$1 kubelet-$1 kubeadm-$1 -y
systemctl enable --now kubelet
# git clone _Book_k8sInfra.git -> 두번째 변수($2 = 'Main')로 전체 실행 코드를 마스터 노드에만 내려받고 /root로 파일을 옮기고 권한을 재설정함
if [ $2 = 'Main' ]; then
git clone https://github.com/sysnet4admin/_Book_k8sInfra.git
mv /home/vagrant/_Book_k8sInfra $HOME
find $HOME/_Book_k8sInfra/ -regex ".*\.\(sh\)" -exec chmod 700 {} \;
fi
# master_node.sh - 1개의 가상 머신(m-k8s)를 쿠버네티스 마스터 노드로 구성하는 스크립트. CNI도 함께 구성
#!/usr/bin/env bash
# init kubernetes -> kubeadm을 통해 쿠버네티스의 워커 노드를 받아들일 준비
kubeadm init --token 123456.1234567890123456 --token-ttl 0 \
--pod-network-cidr=172.16.0.0/16 --apiserver-advertise-address=192.168.1.10
# config for master node only -> 마스터 노드에서 현재 사용자가 쿠버네티를 ㅡ정상적으로 구동할 수 있도록 설정 파일을 루트의 홈디렉터리에 복사하고 권한 부여
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
# config for kubernetes's network -> 컨테이너 네트워크 인터페이스(CNI)인 캘리코의 설정을 적용해 쿠버네티스의 네트워크 구성
kubectl apply -f \
https://raw.githubusercontent.com/sysnet4admin/IaC/master/manifests/172.16_net_calico.yaml
# work_nodes.sh - 3대의 가상 머신에 쿠버네티스 워커 노드를 구성하는 스크립트. 마스터 노드에 구성 된 클러스터에 조인이 필요한 정보가 모두 코드화되어 있어 스크립트를 실행하기만 하면 워커노드로서 쿠버네티스 클러스터에 조인됨.
#!/usr/bin/env bash
# config for work_nodes only
kubeadm join --token 123456.1234567890123456 \
--discovery-token-unsafe-skip-ca-verification 192.168.1.10:6443
구성된 파일을 모두 살펴봤으니 이제 vagrant up 명령어를 통해 쿠버네티스 클러스터를 자동으로 구성해보고 kubectl get nodes 로 쿠버네티스 클러스터에 마스터 노드와 워커 노드들이 정상적으로 생성되고 연결됐는지 확인한다.
쿠버네티스 구성요소
쿠버네티스 클러스터는 이렇게 하나의 마스터노드(m-k8s)와 여러대의 워커노드(w[N]-k8s)가 하나의 클러스터를 이루고 있는 구조다.
마스터노드는 쿠버네티스 클러스터 전체를 컨트롤한다. API 서버를 통해 쿠버네티스를 관리하고, 모든 컴포넌트들은 API 서버를 통해 통신한다. 크게 kubectl, API 서버, etcd, 컨트롤러 매니저, 스케줄러 등의 요소가 있다.
- kubectl
- 쿠버네티스 클러스터에 명령을 내리는 역할
- 다른 구성 요소들과 다르게 바로 실행되는 명령 형태인 바이너리로 배포되기 때문에 마스터 노드에 있을 필요는 없음
- API 서버와 주로 통신
- API 서버
- 쿠버네티스 클러스터의 중심 역할을 하는 통로
- 주로 상태 값을 저장하는 etcd와 통신하지만 그 밖의 요소들도 API 서버를 중심에 두고 통신함
- etcd (엣시디)
- 구성 요소들의 상태 값이 모두 저장되는 곳
-> etcd외의 다른 구성 요소는 상태 값을 관리하지 않음. 따라서 etcd 정보만 백업되어 있다면 장애 상황에서 쿠버네티스 클러스터 복구할 수 있음 - 분산 저장이 가능한 key-value 저장소
-> 복제해 여러 곳에 저장해 두면 하나의 etcd에서 장애가 나더라도 시스템의 가용성을 확보할 수 있음
- 구성 요소들의 상태 값이 모두 저장되는 곳
- 컨트롤러 매니저
- 쿠버네티스 클러스터의 오브젝트 상태를 관리
- 여러 종류가 있음
-> ex) 레플리카셋 컨트롤러는 요청된 파드 개수되로 파드를 생성 및 제거함
- 스케줄러
- 노드의 상태와 자원, 레이블, 요구 조건 등을 고려해 파드를 어떤 워커 노드에 생성할 것인지를 결정하고 할당함
워커노드는 마스터노드에 의해 명령을 받고 실제 워크로드를 생성해서 서비스하는 컴포넌트이다. API 서버의 요청을 Kubelet 을 통해 수행한다. 크게 kubelet, 컨테이너 런타임, 파드 등의 요소가 있다.
- kubelet
- 파드의 구성 내용(PodSpec)을 받아서 컨테이너 런타임으로 전달하고, 파드 안의 컨테이너들이 정상적으로 작동하는지 모니터링
- 컨테이너 런타임(CRI, Container Runtime Interface)
- 파드를 이루는 컨테이너의 실행을 담당
- 파드 안에서 다양한 종류의 컨테이너가 문제 없이 작동하게 만드는 표준 인터페이스
- 파드
- 한 개 이상의 컨테이너로 단일 목적의 일을 하기 위해 모인 단위
- 파드는 언제라도 죽을 수 있는 존재
쿠버네티스는 이렇게 다양한 요소들로 이루어져 있는데, 역할이 명확하게 구분되어 있기 때문에 각자의 역할에 충실하면 클러스터 시스템이 안정적으로 운영된다. 이러한 구조는 MSA와 밀접하게 연관되어 있으며 어디서 문제가 발생했는지 디버깅하기도 편리하다. 이번에는 파드의 생명주기로 쿠버테니스 구성요소의 역할을 알아보자.
- kubectl을 통해 API 서버에 파드 생성을 요청
- API 서버에 전달된 내용이 있으면 API 서버는 etcd에 전달된 내용 모두 기록해 클러스터의 상태값을 최신으로 유지
- API 서버에 파드 생성이 요청된 것을 컨트롤러 매니저가 인지하면 컨트롤러 매니저가 파드 생성하고 이 상태를 API 서버에 전달
- API 서버에 파드가 생성됐다는 정보를 스케줄러가 인지하면 스케줄러가 생성된 파드를 어떤 워커 노드에 적용할지 결정하고 해당 워커 노드에 파드를 띄우도록 요청한다.
- API 서버에 전달된 정보대로 지정한 워커 노드에 속해 있는지 스케줄러가 kubelet으로 확인한다.
- kubelet에서 컨테이너 런타임으로 파드 생성을 요청한다.
- 파드가 생성되고 사용가능한 상태가 된다.
여기서 포인트는 쿠버네티스가 작업을 순서대로 진행하는 워크플로 구조가 아니라 선언적인 시스템 구조라는 것이다. 즉, 각 요소가 추구하는 상태를 선언하면 현재 상태와 맞는지 점검하고 그것에 맞추려고 노력하는 구조다. 다만, 워크노드는 워크플로 구조인데, 쿠버네티스가 kubelet과 컨테이너 런타임을 통해 파들르 새로 생성하고 제거해야 하는 구조여서 선언적인 방식으로 구조화하기에는 어려움이 있기 때문이다. 워크플로 구조는 성능에 좋지만 선언적인 시스템은 안정적으로 시스템을 유지시킨다.
쿠버네이스 기본 사용법
파드 생성하는 방법
- kubectl run: 가장 간단하게 파드를 만드는 방식. 파드의 정보가 기록된 yaml 파일을 사용해 파드를 만드는 create, apply와 달리 run은 실행 커맨드에 각종 정보를 입력해서 생성. 가장 간편하지만 실행시 입력한 정보가 남지 않아 재실행이 어렵고 문제가 발생했을 때 원인을 찾거나 해결방법을 공유하기 어렵다.
- kubectl create: yaml을 통해 파드를 만드는 방식. apply와 가장 큰 차이점은 기존에 동일한 파드가 있을 경우 에러가 발생한다는 것. 파드 실행 시 입력한 정보가 파일 형태로 남아있기 때문에 재실행하거나 문제의 원인을 찾는 등의 작업이 수월.
- kubectl apply: yaml을 통해 파드를 만드는 방식. create와 가장 큰 차이점은 기존에 동일한 pod가 없다면 새로운 파드를 생성하고 잇다면 기존 config와 비교해서 숮어된 부분만 업데이트 한다.
오브젝트
쿠버네티스에서 오브젝트란 쿠버네티스 시스템에서 spec과 status를 가지고 있는 구성단위라고 할 수 있다. spec은 오브젝트 생성시 스펙, status는 오브젝트의 현재 상태를 설명한다.
기본 오브젝트부터 알아보자.
- 파드(Pod): 쿠버네티스에서 실행되는 최소단위. 웹 서비스를 구동하는데 필요한 최소 단위. 하나의 파드는 1개 이상의 컨테이너를 가지고 있음.
- 네임스페이스(Namespaces): 쿠버네티스 클러스터에서 사용되는 리소스들을 구분해 관리하는 그룹. 기본인 default, 쿠버네티스 시스템에서 사용되는 kube-system, 온프레미스에서 쿠버네티스를 사용할 경우 외부에서 쿠버네티스 클러스터 내부로 접속하게 도와주는 컨테이너들이 속해 있는 metallb-system이 있음.
- 볼륨(Volume): 파드가 생성될 때 파드에서 사용할 수 있는 디렉터리를 제공. 파드는 영속되는 개념이 아니기 때문에 제공되는 디렉터리도 임시로 사용된다. 하지만 볼륨 오브젝트를 통해 파드가 사라지더라도 저장과 보존이 가능한 디렉터리를 생성할 수 있다.
- 서비스(Service): 쿠버네티스 외부에서 쿠버네티스 내부로 접속할 때 내부가 어떤 구조로 돼 있는지, 파드가 살았는지 죽었는지 신경 쓰지 않아도 이를 논리적으로 연결하는 것. 로드밸런서, 게이트웨어와 비슷한 역할
기본 오브젝트 외에 더 많은 기능을 가진 오브젝트들도 있다. (ex. 디플로이먼트, 데몬셋, 레플리카셋 등)
그 외의 쿠버네티스의 기능
- 파드는 자동으로 복구되는 기능이 있다. 이를 셀프 힐링(Self-Healing)이라고 한다. 제대로 작동하지 않는 컨테이너를 다시 시작하거나 교체해 파드가 정상적으로 작동하게 한다.
- 쿠버네티스는 파드 자체에 문제가 발생하면 파드를 자동 복구해서 파드가 항상 동작하도록 보장하는 기능이 있다. replicas에서 개수를 선언해두면 replicas는 선언된 개수대로 파드를 유지할 수 있도록 파드의 수를 항상 확인한다.
- kubectl cordon '노드명' 명령어를 통해 이 노드에 파드가 추가 스케줄링되지 않을 수 있도록 쿠버네티스에 알려줄 수 있다.
- kubectl drain '노드명' 명령어를 통해 노드를 끌 수 있다. 해당 노드에 있던 파드들은 다시 스케줄링되어 다른 노드로 이동한다.
- 파드를 업데이트 했을 때 --record 옵션으로 배포정보의 히스토리를 기록했다면 rollout undo로 명령 실행을 취소하거나 --to-revision옵션을 주어 특정 시점으로 파드를 복구할 수 있다.
쿠버네티스의 연결을 담당하는 서비스
쿠버네티스에서 서비스란 외부에서 쿠버네티스 클러스터에 접속하는 방법을 의미한다. 서비스의 종류에 대해 알아보자.
- 노드포트(NodePort) 서비스란 외부에서 쿠버네티스 클러스터의 내부에 접속하는 가장 쉬운 방법이다. 노드포트 서비스를 설정하면 모든 워커 노드의 특정 포트(노드포트)를 열고 여기로 오는 모든 요청을 노드포트 서비스로 전달한다. 그리고 노드포트 서비스를 해당 업무를 처리할 수 있는 파드로 요청을 전달한다.
- 노드포트 서비스는 1개의 노드포트에 1개의 디플로이먼트만 적용된다. 디플로이먼트가 여러개 있는 경우 인그레스(Ingress)를 사용하는데, 인그레스는 고유한 주소를 제공해 사용 목적에 따라 다른 응답을 제공할 수 있고, 트래픽에 대한 L4/L7 로드밸런서와 보안 인증서를 처리하는 기능을 제공한다.
- 위 2개는 모드 워커 노드의 노드포트를 통해 노드포트 서비스로 이동하고 이를 다시 쿠버네티스의 파드로 보내는 구조다. 이는 비효율적이므로 로드밸런서(LoadBalancer) 서비스를 이용해 간단한 구조로 파드를 외부에 노출하고 부하를 분산한다.
Reference
도서 - 컨테이너 인프라 환경 구축을 위한 쿠버네티스/도커
https://daaa0555.tistory.com/m/464
https://aws.amazon.com/ko/compare/the-difference-between-containers-and-virtual-machines/
https://kubernetes.io/ko/docs/concepts/overview/
'Java & Spring' 카테고리의 다른 글
[Kafka] 기본 개념 및 이해 (0) | 2024.04.16 |
---|---|
[쿠버네티스/도커] 3 - 쿠버네티스에서의 도커, 젠킨스, 프로메테우스, 그라파나 (1) | 2024.04.14 |
[쿠버네티스/도커] 1 - 컨테이너 인프라 환경이란, 테스트 환경 구성 (1) | 2024.02.25 |
[모던자바인액션] Part4 Optional, 날짜시간, 디폴트메서드, 모듈 (0) | 2023.09.18 |
[Error] Parameter 1 of constructor in '...' required a bean of type 'com.couchbase.client.core.deps.com.fasterxml.jackson.databind.ObjectMapper' that could not be found. (0) | 2022.10.11 |