[Kubernetes] 컨테이너를 다루는 표준 아키텍처, 쿠버네티스
OS환경은 Windows 10 기준으로 작성되었습니다.
3.1 쿠버네티스 이해하기
3.1.1 왜 쿠버네티스일까
-
쿠버네티스는 컨테이너 관리 도구이자 컨테이너 오케스트 레이션을 위한 솔루션이다.
오케스트레이션
이란 복잡한 단계를 관리하고 요소들의 유지적인 관계를 미리 정의해 손쉽게 사용하도록 서비스를 제공하는 것을 의미 -
컨테이너 오케스트레이션 솔루션 비교
구분 도커 스웜 메소스 노매드 쿠버네티스 설치 난이도 쉬움 매우 어려움 쉬움 어려움 사용 편의성 매우 좋음 좋음 매우 좋음 좋음 세부 설정 지원 거의 없음 있음 거의 없음 다양하게 있음 안정성 매우 안정적임 안정적임 안정적임 매우 안정적임 확장성 어려움 매우 잘 됨 어려움 매우 잘 됨 정보량 많음 적음 적음 매우 많음 에코 파트너 없음 거의 없음 있음 매우 많음 학습 곡선 쉬움 매우 어려움 어려움 어려움
3.1.2 쿠버네티스 구성 방법
-
쿠버네티스를 구성하는 방법은 크게 3가지가 있다.
- 관리형 쿠버네티스 (EKS, AKS, GKE) - 설치형 쿠버네티스 (RANCHER, OPENSHIFT) - 구성형 쿠버네티스 (kubeadm, kops, KRIB, kubespray)
-
쿠버네티스 클러스터 구성 솔루션 비교
구분 KRIB kops kubespray kubeadm 정보량 적음 많음 많음 매우 많음 세부 설정 변경 가능함 가능함 제한적으로 가능함 다양함 사전 요구 조건 적음 적음 적음 매우 적음 온프레미스 지원 매우 좋음 안 됨 좋음 매우 좋음 클라우드 지원 안 됨 매우 좋음 좋음 좋음 학습 곡선 매우 어려움 어려움 쉬움 어려움 자동화 기능 제공됨 제공됨 쉽게 제공됨 제한적으로 제공됨
3.1.3 쿠버네티스 구성하기
- 베이그런트 프로비저닝을 위한 정보를 담고 있는 파일
Vagrantfile
vagrant up
명령어를 통해 쿠버네티스 클러스터를 자동으로 구성한다.
Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
N = 3 # max number of worker nodes
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-1.13.1(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
cfg.vm.provision "shell", path: "install_pkg.sh", args: [ Ver, "Main" ]
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-1.13.1(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으로 쿠버네티스를 설치 전 설정하는 스크립트 파일
config.sh
#!/usr/bin/env bash
# vim configuration
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
[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)
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
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
# 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
cat <<EOF > /etc/resolv.conf
nameserver 1.1.1.1 #cloudflare DNS
nameserver 8.8.8.8 #Google DNS
EOF
install_pkg.sh
는 클러스터를 구성하기 위해 가상 머신에 설치되야 하는 의존성 패키지를 명시
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 -y && systemctl enable --now docker
# install kubernetes cluster
yum install kubectl-$1 kubelet-$1 kubeadm-$1 -y
systemctl enable --now kubelet
# git clone _Book_k8sInfra.git
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)을 쿠버네티스 마스터 노드로 구성하는 스크립트
master_node.sh
#!/usr/bin/env bash
# init kubernetes
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
kubectl apply -f \
https://raw.githubusercontent.com/sysnet4admin/IaC/master/manifests/172.16_net_calico.yaml
work_nodes.sh
는 나머지 가상 머신에 쿠버네티스 워크 노트를 구성하는 스크립트
work_nodes.sh
#!/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
-
디렉토리에
Vagrantfile
,config.sh
,install_pkg.sh
,master_node.sh
,work_nodes.sh
파일을 생성 후vagrant up
명령어 실행 -
ssh 툴을 이용하여 터미널에 접속.
https://blog.uluru.io/study/vagrant-1 에서 2.3.2 참조.
3.1.4 파드 배포를 중심으로 쿠버네티스 구성 요소 살펴보기
-
kubectl get pods --all-namespaces
명령으로 모든 네임스페이스 파드 리스트를 확인할 수 있다.특정 구성요소를 보려면 grep '문자열' 을 추가. kubectl get pods --all-namespaces | grep "kube-proxy"
관리자나 개발자가 파드를 배포할 때
마스터 노드
- kubectl
- 쿠버네티스 클러스터에 명령을 내리는 역할을 한다.
- 바이너리 형태로 배포된다.
- API서버
- 쿠버네티스 클러스터의 중심 역할을 하는 통로.
- 상태 값을 저장하는 etcd와 통신을 주로 한다.
- 회사에 비유하면 모든 직원과 상황을 관리하고 목표를 설정하는 관리자에 해당.
- etcd
- 구성 요소들의 상태 값이 모두 저장 되는 곳.
- 분산 저장이 가능한 key-value 저장소이다.
- 컨트롤러 매니저
- 쿠버네티스 클러스터의 오브젝트 상태를 관리.
- 스케줄러
- 노드의 상태와 자원, 레이블, 요구 조건 등을 고려해 파드를 어떤 워커 노드에 생성 할 것인지 결정하고 할당
워커 노드
- kubelet
- 파드의 구성 내용(PodSpec)을 받아서 컨테이너 런타임으로 전달.
- 파드 안의 컨테이너들이 정상적으로 작동하는지 모니터링.
- 컨테이너 런타임
- 파드를 이루는 컨테이너의 실행을 담당.
- 파드
- 한 개 이상의 컨테이너로 단일 목적의 일을 하기 위해서 모인 단위.
- 웹 서버 역할을 할 수도 있고 로그나 데이터를 분석할 수도 있다.
- 파드는
언제라도 죽을 수 있는 존재
이다.
선택 가능한 구성 요소
- 네트워크 플러그인
- 일반적으로 CNI로 구성하며 주로 사용하는 CNI에는 갤리코, 플래널, 실리움, 큐브 라우터, 로마나, 위브넷, Canal 등이 있다.
- CoreDNS
- 쿠버네티스 클러스터에서 도메인 이름을 이용해 통신하는데 사용.
사용자가 배포된 파드에 접속할 때
- kube-proxy
- 쿠버네티스 클러스터는 파드가 위치한 노드에 kube-proxy를 통해 파드가 통신할 수 있는 네트워크를 설정.
- br_netfilter와 iptables로 관리.
- 파드
- 이미 배포된 파드에 접속하고 필요한 내용을 전달 받음
3.1.5 파드의 생명주기로 쿠버네티스 구성 요소 살펴보기
-
파드의 생명주기란. 파드가
생성
,수정
,삭제
되는 과정. -
쿠버네티스는 작업을 순서대로 진행하는 워크플로 구조가 아니라 선언적인 시스템 구조를 가지고 있다.
-
각 요소가 추구하는 상태를 선언하면 현재 상태와 맞는지 점검하고 그것에 맞추려고 노력하는 구조로 되어있다.
3.1.6 쿠버네티스 구성 요소의 기능 검증하기
- kubectl
- kubectl은 반드시 마스터 노드에 위치할 필요가 없다.
- kubectl이 어느 위치에 있더라도 API 서버의 접속 정보만 있다면 어느 곳에서든 쿠버네티스 클러스트에 명령을 내릴 수 있다.
- kubelet
- 쿠버네티스에서 파드의 생성과 상태 관리 및 복구 등을 담당한느 매우 중요한 구성요소이다. 따라서 kubelet에 문제가 생기면 파드가 정상적으로 관리되지 않는다.
- kube-proxy
- 파드의 통신을 담당한다.
- br_netfilter 커널 모듈을 적재하고 iptables를 거쳐 통신할 수 있다.