[쿠버네티스] K8s 설치 및 kubespray 배포 & 쿠버네티스 컴포넌트

신현식·2023년 2월 13일
0

구름_Kubernetes

목록 보기
1/25
post-thumbnail

인프라 개발자의 역할

데브옵스 로드맵 참고

  • 개발자를 도와주는 역할
  • 개발자들이 인프라를 사용하기 쉽도록 도움을 주는 도구를 개발함

쿠버네티스(K8s) 설치

쿠버네티스 공식문서
v1.24 버전을 다룰 것이다.

  • vagrant 디렉터리 생성

mkdir vagrant/kube
cd vagrant/kube

VM 시스템 구성

  • Vagrantfile 문서 내용
# -*- 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 파일 만든 것 실행
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"

SSH키 설정

# 해당 디렉터리에서 실행해야 가능
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

python3, pip, git 설치

# 패키지 목록 가져오기
sudo apt update  

sudo apt install -y python3 python3-pip git

Kubespray 배포

kubespray Git 저장소 클론

# kubespray 설치
cd ~
git clone --branch release-2.20 https://github.com/kubernetes-sigs/kubespray.git 

# kubespray 설치 확인
ls
cd kubespray

requirements.txt 파일에서 의존성 확인 및 설치

  • ansible과 필요한 도구들을 같이 설치

sudo pip3 install -r requirements.txt  

cp -rfp inventory/sample inventory/mycluster

인벤토리 수정

vi 파일 내용 전체 삭제하는 방법

  1. 아래 명령어로 문서의 최 상단으로 이동합니다.
    gg // 문서 최상단으로 이동
  2. 아래 명령어로 문서 전체를 블럭으로 선택합니다.
    Shift + v + g // 전체선택
  3. 전체 선택이 되고 나면 아래 명령어로 내용을 삭제합니다.
    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 통신 가능 확인

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

쿠버네티스 컴포넌트

쿠버네티스를 배포하면 클러스터를 얻는다.

  • 쿠버네티스 클러스터는 컨테이너화된 애플리케이션을 실행하는 노드라고 하는 워커 머신의 집합. 모든 클러스터는 최소 한 개의 워커 노드를 가진다.

  • 워커 노드는 애플리케이션의 구성요소인 파드를 호스트한다. 컨트롤 플레인은 워커 노드와 클러스터 내 파드를 관리한다. 프로덕션 환경에서는 일반적으로 컨트롤 플레인이 여러 컴퓨터에 걸쳐 실행되고, 클러스터는 일반적으로 여러 노드를 실행하므로 내결함성과 고가용성이 제공된다.

  • Control Plane = Master
    Node = Worker , Minions , Data Plane

📢 쿠버네티스 컴포넌트 공식 문서 참조

Control Plane 컴포넌트

컨트롤 플레인 컴포넌트는 클러스터에 관한 전반적인 결정(예를 들어, 스케줄링)을 수행하고 클러스터 이벤트(예를 들어, 디플로이먼트의 replicas 필드에 대한 요구 조건이 충족되지 않을 경우 새로운 파드를 구동시키는 것)를 감지하고 반응한다.

컨트롤 플레인 컴포넌트는 클러스터 내 어떠한 머신에서든지 동작할 수 있다. 그러나 간결성을 위하여, 구성 스크립트는 보통 동일 머신 상에 모든 컨트롤 플레인 컴포넌트를 구동시키고, 사용자 컨테이너는 해당 머신 상에 동작시키지 않는다.

  • 마스터는 보통 고가용성을 만족하고자 3대 이상으로 구성해서 운영

kube-apiserver

쿠버네티스의 구성요소들은 서로 절대 통신하지 않고 api서버하고만 통신한다. kubectl명령어를 통해 api서버에 어떠한 작업을 요청한다

  • API 서버는 쿠버네티스 컨트롤 플레인의 프론트 엔드이다.

etcd

모든 클러스터 데이터를 담는 쿠버네티스 뒷단의 저장소로 사용되는 일관성·고가용성 키-값 저장소이다. 쿠버네티스의 모든 data는 etcd에 저장되지만 반드시 etcd일 필요는 없다. DB로도 대체는 가능하다.

  • api서버는 장애 발생시 복구하면 그만이지만 etcd는 데이터이기 떄문에 복구가 안된다. 따라서 백업 계획은 필수이다.

kube-scheduler

노드가 배정되지 않은 새로 생성된 파드를 감지하고, 실행할 노드를 선택하는 컨트롤 플레인 컴포넌트이다.
즉, 어떤 노드(컨테이너)에 어플리케이션을 배치할 것인지 결정하는 것을 의미한다.

kube-controller-manager

컨트롤러 프로세스를 실행하는 컨트롤 플레인 컴포넌트이다.
논리적으로, 각 컨트롤러는 분리된 프로세스이지만, 복잡성을 낮추기 위해 모두 단일 바이너리로 컴파일되고 단일 프로세스 내에서 실행된다.

이들 컨트롤러는 다음을 포함한다.

  • 노드 컨트롤러: 노드가 다운되었을 때 통지와 대응에 관한 책임을 가진다. = EC2
  • 레플리케이션 컨트롤러: 시스템의 모든 레플리케이션 컨트롤러 오브젝트에 대해 알맞은 수의 파드들을 유지시켜 주는 책임을 가진다.
  • 엔드포인트 컨트롤러: 엔드포인트 오브젝트를 채운다(즉, 서비스와 파드를 연결시킨다.) = 네트워크
  • 서비스 어카운트 & 토큰 컨트롤러: 새로운 네임스페이스에 대한 기본 계정과 API 접근 토큰을 생성한다. = 접근제어

cloud-controller-manager

클라우드에 쿠버네티스를 올릴때 사용되는 요소이다. 쿠버네티스에서 클라우드를 제어하는 것을 담당하고 쿠버네티스와 클라우드 간의 상호작용을 담당한다.

클라우드 컨트롤러 매니저를 통해 클러스터를 클라우드 공급자의 API에 연결하고, 해당 클라우드 플랫폼과 상호 작용하는 컴포넌트와 클러스터와만 상호 작용하는 컴포넌트를 구분할 수 있게 해 준다.

  • 로컬에서 쿠버네티스를 사용한다면 존재하지 않는 요소이다.

💡 이들 요소중 단 하나라도 장애가 발생하면 쿠버네티스는 작동을 하지 않는다. 따라서 각 요소는 반드시 3중화를 통해 구성한다.
-> 그림을 잘 보면 세개로 겹쳐있는 것을 볼 수 있다.
-> 클러스터로 다중화를 구성할 때는 짝수개로는 구성하지 않는다.

Node 컴포넌트

노드 컴포넌트는 동작 중인 파드를 유지시키고 쿠버네티스 런타임 환경을 제공하며, 모든 노드 상에서 동작한다.

=> Container Runtime Interface (CRI) = 쿠버네티스 런타임 환경

  • Docker: 컨테이너를 구현하기 위한 기술 중 하나

kubelet

클러스터의 각 노드에서 실행되는 에이전트. Kubelet은 파드에서 컨테이너가 확실하게 동작하도록 관리한다.

  • kubectl은 kubelet에게 요청을 하지 않는다.

  • Kubelet은 다양한 메커니즘을 통해 제공된 파드 스펙(PodSpec)의 집합을 받아서 컨테이너가 해당 파드 스펙에 따라 건강하게 동작하는 것을 확실히 한다. Kubelet은 쿠버네티스를 통해 생성되지 않는 컨테이너는 관리하지 않는다

kube-proxy

kube-proxy는 클러스터의 각 노드에서 실행되는 네트워크 프록시로, 쿠버네티스의 서비스 개념의 구현부이다.

kube-proxy는 노드의 네트워크 규칙을 유지 관리한다. 이 네트워크 규칙이 내부 네트워크 세션이나 클러스터 바깥에서 파드로 네트워크 통신을 할 수 있도록 해준다.
kube-proxy는 운영 체제에 가용한 패킷 필터링 계층이 있는 경우, 이를 사용한다. 그렇지 않으면, kube-proxy는 트래픽 자체를 포워드(forward)한다.

sudo ss -tnlp # kube-proxy 확인 가능 

애드온 ( = 옵션)

애드온은 쿠버네티스 리소스(데몬셋, 디플로이먼트 등)를 이용하여 클러스터 기능을 구현한다. 이들은 클러스터 단위의 기능을 제공하기 때문에 애드온에 대한 네임스페이스 리소스는 kube-system 네임스페이스에 속한다.

DNS

애드온들이 옵션이기 때문에 반드시 필요로 하지 않지만 DNS는 많은 예시에서 필요로하고 없으면 관리가 힘들어지기 때문에 모든 쿠버네티스 클러스터는 클러스터 DNS를 갖추어야 한다.

클러스터 DNS는 구성환경 내 다른 DNS 서버와 더불어, 쿠버네티스 서비스를 위해 DNS 레코드를 제공해주는 DNS 서버다.

  • 쿠버네티스에 의해 구동되는 컨테이너는 DNS 쿼리에서 이 DNS 서버를 자동으로 포함한다. 자체 DNS서버 같은 느낌이다.

웹 UI (대시보드)

대시보드는 쿠버네티스 클러스터를 위한 범용의 웹 기반 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, 즉 상태가 없기 때문에 항상 일정하다. 따라서 이미지를 통해 컨테이너를 생성할 수 있다.

  • 컨테이너 = Immutable Infrastructure
    컨테이너는 stateless이지만 데이터는 state가 존재한다. 따라서 컨테이너에 데이터를 저장하고 컨테이너를 없애면 데이터도 같이 날아간다. 하지만 데이터는 매우중요하다. 따라서 이러한 데이터를 저장하기 위해서 컨테이너에 Volume을 사용하는 것이다.
kubectl api-resources

-> API서버가 가지고 있는 리소스의 종류를 볼 수 있다.
= 즉 만들수 있는 리소스의 리스트를 알 수 있다

profile
전공 소개

0개의 댓글