쿠버네티스 공식문서
v1.24 버전을 다룰 것이다.
mkdir vagrant/kube
cd vagrant/kube
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
$vm_provider = "virtualbox"
$box_image = "ubuntu/focal64"
$vm_name_prefix = "kube"
$number_of_control_planes = 1
$number_of_nodes = 3
$vm_subnet = "192.168.56"
$vm_control_plane_cpus = 2
$vm_control_plane_memory = 3072
$vm_node_cpus = 2
$vm_node_memory = 2560
# Kubernetes Control Planes
(1..$number_of_control_planes).each do |i|
config.vm.define "#{$vm_name_prefix}-control#{i}" do |node|
node.vm.box = $box_image
node.vm.provider $vm_provider do |vm|
vm.name = "#{$vm_name_prefix}-control#{i}"
vm.cpus = $vm_control_plane_cpus
vm.memory = $vm_control_plane_memory
end
node.vm.hostname = "#{$vm_name_prefix}-control#{i}"
node.vm.network "private_network", ip: "#{$vm_subnet}.1#{i}", nic_type: "virtio"
end
end
# Kubernetes Nodes
(1..$number_of_nodes).each do |i|
config.vm.define "#{$vm_name_prefix}-node#{i}" do |node|
node.vm.box = $box_image
node.vm.provider $vm_provider do |vm|
vm.name = "#{$vm_name_prefix}-node#{i}"
vm.cpus = $vm_node_cpus
vm.memory = $vm_node_memory
end
node.vm.hostname = "#{$vm_name_prefix}-node#{i}"
node.vm.network "private_network", ip: "#{$vm_subnet}.2#{i}", nic_type: "virtio"
end
end
# Change APT Repository & Enable SSH Password Authentication
config.vm.provision "shell", inline: <<-SHELL
sed -i 's/archive.ubuntu.com/mirror.kakao.com/g' /etc/apt/sources.list
sed -i 's/security.ubuntu.com/mirror.kakao.com/g' /etc/apt/sources.list
sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config
systemctl restart ssh
SHELL
end
# vagrant 파일 만든 것 실행
vagrant up
# vagrant 실행 상태 확인
vagrant status
Timed out while waiting for the machine to boot. This means that
Vagrant was unable to communicate with the guest machine within
the configured ("config.vm.boot_timeout" value) time period.
SSH 인증 방법: 개인 키" 문제의 원인으로 Windows 10이 vagrant와 충돌하는 것으로 생각됨
-> 해결책
지금 해결 방법은 다음 VirtualMachinePlatform을 실행하여 Windows에서 기능을 비활성화하는 것입니다. PowerShell에서 다음 명령을 관리자로 실행하여
Disable-WindowsOptionalFeature -Online -FeatureName "VirtualMachinePlatform"
Docker를 사용해야 하는 경우 이 기능을 다시 활성화합니다.
Enable-WindowsOptionalFeature -Online -FeatureName "VirtualMachinePlatform"
# 해당 디렉터리에서 실행해야 가능
vagrant ssh kube-control1
# SSH 키 생성
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -N ''
# 생성된 키 확인
ls .ssh
# ssh 키 복사 -> yes, passwd는 vagrant이다.
ssh-copy-id -i ~/.ssh/id_ed25519.pub vagrant@192.168.56.11
ssh-copy-id -i ~/.ssh/id_ed25519.pub vagrant@192.168.56.21
ssh-copy-id -i ~/.ssh/id_ed25519.pub vagrant@192.168.56.22
ssh-copy-id -i ~/.ssh/id_ed25519.pub vagrant@192.168.56.23
# 패키지 목록 가져오기
sudo apt update
sudo apt install -y python3 python3-pip git
# kubespray 설치
cd ~
git clone --branch release-2.20 https://github.com/kubernetes-sigs/kubespray.git
# kubespray 설치 확인
ls
cd kubespray
sudo pip3 install -r requirements.txt
cp -rfp inventory/sample inventory/mycluster
vi 파일 내용 전체 삭제하는 방법
- 아래 명령어로 문서의 최 상단으로 이동합니다.
gg // 문서 최상단으로 이동- 아래 명령어로 문서 전체를 블럭으로 선택합니다.
Shift + v + g // 전체선택- 전체 선택이 되고 나면 아래 명령어로 내용을 삭제합니다.
d // 전체 삭제
vi inventory/mycluster/inventory.ini
[all]
kube-control1 ansible_host=192.168.56.11 ip=192.168.56.11
kube-node1 ansible_host=192.168.56.21 ip=192.168.56.21
kube-node2 ansible_host=192.168.56.22 ip=192.168.56.22
kube-node3 ansible_host=192.168.56.23 ip=192.168.56.23
[kube_control_plane]
kube-control1
[etcd]
kube-control1
[kube_node]
kube-node1
kube-node2
kube-node3
[calico_rr]
[k8s_cluster:children]
kube_control_plane
kube_node
calico_rr
vi inventory/mycluster/group_vars/k8s_cluster/addons.yml
...
metrics_server_enabled: true
...
ingress_nginx_enabled: true
...
metallb_enabled: true
...
metallb_ip_range:
- "192.168.56.200-192.168.56.209"
...
metallb_protocol: "layer2"
...
vi inventory/mycluster/group_vars/k8s_cluster/k8s-cluster.yml
...
kube_proxy_strict_arp: true
...
container_manager: docker
...
ansible all -i inventory/mycluster/inventory.ini -m ping
<옵션> Apt 캐시 업데이트
ansible all -i inventory/mycluster/inventory.ini -m apt -a 'update_cache=yes' --become
# X 부분에는 현재 버전 정보를 입력한다.
ansible-playbook -i inventory/mycluster/inventory.ini cluster.yml -e kube_version=v1.24.X --become
kube_version: 현재 Kubespray v2.20.0 버전의 경우 기본 Kubernetes 버전은 1.24.6
호스트 시스템 사양, VM 개수, VM 리소스 및 네트워크 성능에 따라 20~60분 소요
# 자격 증명 가져오기
mkdir ~/.kube
sudo cp /etc/kubernetes/admin.conf ~/.kube/config
sudo chown $USER:$USER ~/.kube/config
# kubectl 명령 자동완성
kubectl completion bash | sudo tee /etc/bash_completion.d/kubectl
exec bash
# Kubernetes 클러스터 확인
kubectl get nodes
kubectl cluster-info
쿠버네티스를 배포하면 클러스터를 얻는다.
쿠버네티스 클러스터는 컨테이너화된 애플리케이션을 실행하는 노드라고 하는 워커 머신의 집합. 모든 클러스터는 최소 한 개의 워커 노드를 가진다.
워커 노드는 애플리케이션의 구성요소인 파드를 호스트한다. 컨트롤 플레인은 워커 노드와 클러스터 내 파드를 관리한다. 프로덕션 환경에서는 일반적으로 컨트롤 플레인이 여러 컴퓨터에 걸쳐 실행되고, 클러스터는 일반적으로 여러 노드를 실행하므로 내결함성과 고가용성이 제공된다.
컨트롤 플레인 컴포넌트는 클러스터에 관한 전반적인 결정(예를 들어, 스케줄링)을 수행하고 클러스터 이벤트(예를 들어, 디플로이먼트의 replicas 필드에 대한 요구 조건이 충족되지 않을 경우 새로운 파드를 구동시키는 것)를 감지하고 반응한다.
컨트롤 플레인 컴포넌트는 클러스터 내 어떠한 머신에서든지 동작할 수 있다. 그러나 간결성을 위하여, 구성 스크립트는 보통 동일 머신 상에 모든 컨트롤 플레인 컴포넌트를 구동시키고, 사용자 컨테이너는 해당 머신 상에 동작시키지 않는다.
쿠버네티스의 구성요소들은 서로 절대 통신하지 않고 api서버하고만 통신한다. kubectl명령어를 통해 api서버에 어떠한 작업을 요청한다
모든 클러스터 데이터를 담는 쿠버네티스 뒷단의 저장소로 사용되는 일관성·고가용성 키-값 저장소이다. 쿠버네티스의 모든 data는 etcd에 저장되지만 반드시 etcd일 필요는 없다. DB로도 대체는 가능하다.
노드가 배정되지 않은 새로 생성된 파드를 감지하고, 실행할 노드를 선택하는 컨트롤 플레인 컴포넌트이다.
즉, 어떤 노드(컨테이너)에 어플리케이션을 배치할 것인지 결정하는 것을 의미한다.
컨트롤러 프로세스를 실행하는 컨트롤 플레인 컴포넌트이다.
논리적으로, 각 컨트롤러는 분리된 프로세스이지만, 복잡성을 낮추기 위해 모두 단일 바이너리로 컴파일되고 단일 프로세스 내에서 실행된다.
이들 컨트롤러는 다음을 포함한다.
클라우드에 쿠버네티스를 올릴때 사용되는 요소이다. 쿠버네티스에서 클라우드를 제어하는 것을 담당하고 쿠버네티스와 클라우드 간의 상호작용을 담당한다.
클라우드 컨트롤러 매니저를 통해 클러스터를 클라우드 공급자의 API에 연결하고, 해당 클라우드 플랫폼과 상호 작용하는 컴포넌트와 클러스터와만 상호 작용하는 컴포넌트를 구분할 수 있게 해 준다.
💡 이들 요소중 단 하나라도 장애가 발생하면 쿠버네티스는 작동을 하지 않는다. 따라서 각 요소는 반드시 3중화를 통해 구성한다.
-> 그림을 잘 보면 세개로 겹쳐있는 것을 볼 수 있다.
-> 클러스터로 다중화를 구성할 때는 짝수개로는 구성하지 않는다.
노드 컴포넌트는 동작 중인 파드를 유지시키고 쿠버네티스 런타임 환경을 제공하며, 모든 노드 상에서 동작한다.
=> Container Runtime Interface (CRI) = 쿠버네티스 런타임 환경
클러스터의 각 노드에서 실행되는 에이전트. Kubelet은 파드에서 컨테이너가 확실하게 동작하도록 관리한다.
kubectl은 kubelet에게 요청을 하지 않는다.
Kubelet은 다양한 메커니즘을 통해 제공된 파드 스펙(PodSpec)의 집합을 받아서 컨테이너가 해당 파드 스펙에 따라 건강하게 동작하는 것을 확실히 한다. Kubelet은 쿠버네티스를 통해 생성되지 않는 컨테이너는 관리하지 않는다
kube-proxy는 클러스터의 각 노드에서 실행되는 네트워크 프록시로, 쿠버네티스의 서비스 개념의 구현부이다.
kube-proxy는 노드의 네트워크 규칙을 유지 관리한다. 이 네트워크 규칙이 내부 네트워크 세션이나 클러스터 바깥에서 파드로 네트워크 통신을 할 수 있도록 해준다.
kube-proxy는 운영 체제에 가용한 패킷 필터링 계층이 있는 경우, 이를 사용한다. 그렇지 않으면, kube-proxy는 트래픽 자체를 포워드(forward)한다.
sudo ss -tnlp # kube-proxy 확인 가능
애드온은 쿠버네티스 리소스(데몬셋, 디플로이먼트 등)를 이용하여 클러스터 기능을 구현한다. 이들은 클러스터 단위의 기능을 제공하기 때문에 애드온에 대한 네임스페이스 리소스는 kube-system 네임스페이스에 속한다.
애드온들이 옵션이기 때문에 반드시 필요로 하지 않지만 DNS는 많은 예시에서 필요로하고 없으면 관리가 힘들어지기 때문에 모든 쿠버네티스 클러스터는 클러스터 DNS를 갖추어야 한다.
클러스터 DNS는 구성환경 내 다른 DNS 서버와 더불어, 쿠버네티스 서비스를 위해 DNS 레코드를 제공해주는 DNS 서버다.
대시보드는 쿠버네티스 클러스터를 위한 범용의 웹 기반 UI다. 사용자가 클러스터 자체뿐만 아니라, 클러스터에서 동작하는 애플리케이션에 대한 관리와 문제 해결을 할 수 있도록 해준다.
보안상의 이유로 인해 권장하는 요소가 아니다.
컨테이너 리소스 모니터링은 중앙 데이터베이스 내의 컨테이너들에 대한 포괄적인 시계열 매트릭스를 기록하고 그 데이터를 열람하기 위한 UI를 제공해 준다.
기업에서 반드시 구성하는 요소중 하나이다.
클러스터-레벨 로깅 메커니즘은 검색/열람 인터페이스와 함께 중앙 로그 저장소에 컨테이너 로그를 저장하는 책임을 진다.
기업에서 반드시 구성하는 요소중 하나이다.
# 컨테이너들을 확인
kubectl get pods -A
# 더 자세한 내용을 보여줌 node정보, IP정보 등
kubectl get pods -A -o wide
-> 위의 아키텍처를 보면 그림에서는 생략되었지만 사실 명령어로 알 수 있다시피 control plane도 kube-proxy를 가지고 있다.
-> 즉 control plane도 사실 node의 기능을 가지고 있다.
-> control plane은 node를 관리하는 대장느낌이라면 node는 각 컨테이너를 실행하는 병사다.
systemctl status etcd
systemctl status kubelet
-> etcd, kubelet은 컨테이너가 아닌 서비스이기 때문에 kubectl이 아닌 systemd로 확인
컨테이너는 stateless, 즉 상태가 없기 때문에 항상 일정하다. 따라서 이미지를 통해 컨테이너를 생성할 수 있다.
kubectl api-resources
-> API서버가 가지고 있는 리소스의 종류를 볼 수 있다.
= 즉 만들수 있는 리소스의 리스트를 알 수 있다