쿠버네티스 설치, 개념
vagrant(베이그란트) : 가상 개발 환경을 구축하고 관리하기 위한 오픈소스 도구
하이퍼 바이저 : 서버 가상화 핵심, 가상화 기술을 사용해 물리적 호스트 시스템에서 여러개의 가상머신을 동시에 실행하과 관리하는 소프트웨어
containers(컨테이너) 쓰는 이유??? : app을 isolation 하기위해, 컨테이너는 운영체제가 없다, 그렇기에 vm에 비해 가볍다(운영체제가 공유되어 있음)
즉, 운영체제가 없기에 그냥 바로 컨테이너 실행하면됨
즉, app들을 조금더 빠르고, lsolation하게 실행하기 위해 컨테이너를 사용!!!!
>>> 컨테이너 기술중 가장 널리 사용되는 것은 앞서 배웠던 도커이다!!!!
그럼,, 쿠버네티스는 왜??? 사용하냐
관리할 컨테이너가 수십대, 수백대가 되면... 어질어질
여러대의 시스템을 오케스트레이션 하기위해 !!
즉, 여러대의 컨테이너를 지휘하기위해!! 또는 여러대의 컨테이너를 클러스터를 하기 위해 사용한다!!!
YAML : 쿠버네티스 시스템에서 정보를 담고있는 개체
파드 : 쿠버네티스 워크로드 리소스중, 만들고 배포할 수 있는 가장 작은 기본 구성단위!!!!
파드는 쿠버네티스 클러스터 내에서 애플리케이션을 배포하며 동작하는 프로세스
파드는 애플리케이션 컨테이너 이며, 하나 이상의 컨테이너로 구성될수 있다.
mkdir ~/kube >>> kube디렉토리 생성
cp Vagrantfile ~/kube >>> 설치한 파일 kube디렉토리로 이동시키기
wget https://releases.hashicorp.com/vagrant/2.3.7/vagrant_2.3.7-1_amd64.deb
sudo dpkg -i vagrant_2.3.7-1_amd64.deb
vagrant plugin install vagrant-disksize
vagrant plugin install vagrant-hostmanager
vagrant box add centos/7 가상머신 이미지 다운로드
vagrant box list
vagrant plugin list 확인
vagrant up 가상머신 배포
vagrant plugin list 확인
vagrant up 가상머신 배포
vagrant status 가상머신 상태확인
vagrant ssh default -> default 라는 이름의 가상머신에 원격접속
vagrant halt 가상머신 종료
vagrant destroy : 가상머신 제거
ks8 설치
cd ~/kube
# vagrant 기본 준비 완료 후
vagrant up
# [종료시 사용] vagrant 종료
vagrant halt
vagrant ssh kube-control1 # 가성머신 접속
# ssh 키 생성 및 배포
# 패스워드 없이 로그인 할 수 있는 환경을 구성
# 키 생성
ssh-keygen # 엔터 세번
# 키 배포
# 비밀번호는 vagrant
ssh-copy-id vagrant@localhost
ssh-copy-id vagrant@192.168.56.21
ssh-copy-id vagrant@192.168.56.22
ssh-copy-id vagrant@192.168.56.23
# kubespary
# [kube-control1]
git clone -b v2.21.0 https://github.com/kubernetes-sigs/kubespray
sudo apt-get update
sudo apt-get install python3 python3-pip -y
cd kubespray
sudo pip3 install -r requirements.txt # pip -r 옵션 : 텍스트파일의 패키지 설치
# inventory 디렉토리 복사
cp -rfp inventory/sample inventory/mycluster
vim inventory/mycluster/inventory.ini
# [inventory.ini]
[all]
kube-control1 ansible_host=192.168.56.11 ip=192.168.56.11 ansible_connection=local
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
[all:vars]
ansible_python_interpreter=/usr/bin/python3
[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
vim inventory/mycluster/group_vars/k8s_cluster/addons.yml
# [addons.yml]
16 metrics_server_enabled: true
...
100 ingress_nginx_enabled: true
...
165 metallb_enabled: true
...
167 metallb_ip_range:
168 - "192.168.56.200-192.168.56.210"
...
195 metallb_protocol: "layer2"
vim inventory/mycluster/group_vars/k8s_cluster/k8s-cluster.yml
# [k8s-cluster.yml]
129 kube_proxy_strict_arp: true
# ansible
# 모든 가상머신이 서로 통신하는지 확인
ansible all -i inventory/mycluster/inventory.ini -m ping
# 출력값
kube-control1 | SUCCESS => {
"changed": false,
"ping": "pong" # 모든 가상머신에 대해 ping, pong 확인
}
...
# 모든 가상머신에서 apt update 실행
ansible all -i inventory/mycluster/inventory.ini -m apt -a "update_cache=yes" --become
# 출력값
kube-control1 | CHANGED => {
"cache_update_time": 1688092019,
"cache_updated": true, # 모든 가상 머신에 대해 true가 출력되는지 확인
"changed": true # 모든 가상 머신에 대해 true가 출력되는지 확인
}
...
# 설치하기
ansible-playbook -i inventory/mycluster/inventory.ini cluster.yml --become
# 설치 오래걸림
# 설치가 끝난 후
mkdir ~/.kube
sudo cp /etc/kubernetes/admin.conf ~/.kube/config
sudo chown vagrant:vagrant ~/.kube/config
# 명령어 자동완성 편의기능
kubectl completion bash | sudo tee /etc/bash_completion.d/kubectl
exec bash
# 4개의 노드 상태 출력 (Ready 확인)
kubectl get nodes
NAME STATUS ROLES AGE VERSION
kube-control1 Ready control-plane 119m v1.25.6
kube-node1 Ready <none> 117m v1.25.6
kube-node2 Ready <none> 117m v1.25.6
kube-node3 Ready <none> 117m v1.25.6
1. 쿠버네티스 개요
쿠버네티스는 통치자와 인공두뇌학이 어원
1) 쿠버네티스가 제공하는 기능
- 컨테이너 플랫폼
- 마이크로서비스 플랫폼
- 이식성 있는 클라우드 플랫폼
쿠버네티스는 컨테이너 기반의 분산 클러스터 환경을 제공하며 워크로드를 위해 컴퓨팅, 네트워킹 및 스토리지 인프라를 오케스트레이션 한다. 쿠버네티스는 Iaas의 유연함을 더해주며, PaaS를 제공함
(2) 쿠버네티스가 제공하지 않는 기능
쿠버네티스는 PaaS의 분류에 속하지만, 일반적인 PaaS의 모든 개념을 포함하고 있지 않다. 쿠버네티스는 컨테이너 레벨에서 운영 되기 떄문에, PaaS의 일부 기능만 제공함
2. 구성요소 및 API
쿠버네티스 클러스터는 마스터와 노드 구성요소가 있고, 추가 요소가 있다. 이런 구성요소들은 API를 통해 메시지를 주고받는다.

(1) 컨트롤 플레인
클러스터의 컨트롤 플레인을 제공. 클러스터에 대한 전반적인 결정(스케줄링) 을 수행하고 클러스터 이벤트를 감지하고 이에 대응한다. 프로덕션 환경에서는 반드시 멀티 마스터 환경을 구성한다.
1) API 서버 (kube-apiserver)
쿠버네티스 클러스터의 모든 구성요소들은 마스터의 API 서버와 메시지를 주고 받는다. 컨트롤 플레인에 대한 프론트엔드를 담당.
2) 쿠버네티스 컨트롤 관리자
컨트롤러는 API서버를 통해 클러스터의 상태를 감시, 필요한 상태로 이행하는 기능을 가짐. 이런 컨트롤러를 담당하는 마스터의 구성요소이다. 컨트롤러 관리자의 종류는 다음과 같다.
- 노드 컨트롤러 : 노드를 관리하며 노드가 다운되었을 때 알림과 대응을 한다.
- 애플리케이션 컨트롤러 : 복제 컨트롤러를 사용하는 모든 오브젝트를 관리하며 알맞은 수의 파드를 유지하는 기능을 한다.
- 엔트포인트 컨트롤러 : 서비스와 파드를 연결한다.
- 서비스 어카운트 및 토큰 컨트롤러 : 쿠버네티스의 네임스페이스, 계정, 토큰을 담당한다.
3) 클라우드 컨트롤러 관리자 : 클라우드를 제공하는 업체의 기능과 클라우드에서 동작하는 쿠버네트스 구성요소와 상호작용 할 수 있도록 하는 컨트롤러 관리자. 이 클라우드 컨트롤러 관리자는 클라우드 제공업체의 코드와 쿠버네티스의 코드가 서로 독립적으로 발전시켜 나갈 수 있도록 해줌
클라우드 컨트롤러 관리자 종류
* 노드 컨트롤러 : 노드가 응답이 없을시 클라우드 상에서 노드가 삭제 되어졌는지 확인을 담당
* 라우트 컨트롤러 : 클라우드 인프라의 네트워크 경로 구성을 담당
* 서비스 컨트롤러 : 클라우드 로드밸런서 관리를 담당
* 볼륨 컨트롤러 : 클라우드 볼륨 관리를 담당
클라우드 컨트롤러 관리자는 클라우드 공급자(AWS, GCP, Azure, OCI 등)의 의존성을 갖는다
4) 키값 저장소(etcd)
쿠버네티스 클러스터의 모든 정보 데이터를 저장하는 일관성과 고가용성을 지원하는 키값 저장소
5) 쿠버네티스 스케줄러
새로 생성되는 파드를 감지하고 이를 적절한 노드에 배정한다
(2) 노드
노드는 쿠버네티스의 컨테이너 런타임 환경을 제공하며, 동작중인 파드를 유지하는 기능을 담당한다. 예전에는 미니언 또는 워커노드라고 불리었다.
1) kubelet
각 노드에서 실행되는 에이전트로, 마스터로부터 제공받은 파드의 구성 정보를 받아서 컨테이너가 확실하게 동작하는 것을 관리하고 보장한다.
2) 쿠버네티스 프록시
호스트 레벨의 네트워크 규칙을 구성하고 외부 연결을 파드에 대한 포워딩을 담당한다. 쿠버네티스의 서비스 추상화가 가능하도록 한다.
3) 컨테이너 런타임
컨테이너의 동작을 책임지는 구성요소이다.
지원하는 컨테이너 런타임
* Docker
* containerd
* cri-o
* rktlet
* Kubernetes CRI를 구현한 모든 런타임
기본적으로 도커 플랫폼을 사용한다
3. 애드온
쿠버네티스 클러스터에 추가할 수 있는 확장 기능을 제공한다.
주요 애드온 구성요소
- 클러스터 dns
- 대시보드
- 컨테이너 리소스 모니터링
- 클러스터 로깅
쿠버네티스 에서 사용가능한 애드온 확장 기능은 아래 링크에서 확인
https://kubernetes.io/docs/concepts/cluster-administration/addons/
4. 쿠버네티스 api
쿠버네티스의 모든 구성요소는 api서버를 통해 api로 메시지를 주고 받음
알파버전api, 베타버전api, 안정화버전ap
kubectl api-versions >>> 클러스터에서 지원되는 API버전확인
kubectl api-resources >>> 클러스터에서 지원되는 API 리소스 확인
2.2 YAML 및 오브젝트 기본
쿠버네티스 오브젝트는 쿠버네티스 시스템에서 정보를 담고 있는 개체이다. 이런 오브젝트는 YAML 문법으로 정의된다.
쿠버네티스 오브젝트 : 쿠버테닌스는 클러스터의 상태를 나태내기 위해 오브젝트 개체를 정의하여 사용한다.
다음은 파드 오브젝트를 기술한 간단한 yaml파일의 예제
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
모든 오브젝트 정의 시 필수적으로 요구되는 필드
apiVersion : 오브젝트를 생성하기 위한 api버전
kind : 오브젝트의 종류
metdata : name, uid, namespace등을 포함하는 기본적인 정보
spec : 오브젝트의 상태 정의
kubectl explain pods >>> Kubernetes의 pods 리소스에 대한 설명을 제공

3장 워크로드 - 파드
파드는 쿠버네티스 워크로드 리소스 중에서 만들고 배포할 수 있는 가장 작은 기본 구성단위
파드는 쿠버네티스 클러스터 내에서 애플리케이션을 배포하며 동작하는 프로세스이다. 파드는 애플리케이션 컨테이너 이며, 하나 이상의 컨테이서로 구성될 수 있다. 즉, 하나의 파드는 하나의 컨테이너만 가질 수도 있고, 두 개 이상의 컨테이너를 가질 수도 있다.
"파드"는 컨테이너화된 애플리케이션을 실행하기 위한 Kubernetes의 기본 실행 단위입니다. 파드는 한 개 이상의 컨테이너로 구성될 수 있으며, 이 컨테이너들은 네트워크 및 스토리지 리소스를 공유하고 함께 실행됩니다.
vs코드 실행 >> 확장 >> ssh검색 >> remote-ssh
밑에꺼 복사

복사하고 호스트name변경해주기

port 도 22로 변경해 줘야됨
2) 파드 정의

파드를 생성 수 있는 YAML파일을 작성해 보자
code myapp-pod.yaml ( vim과 똑같음 )
.spec.ontainers : 컨테이너 정의
.spec.containers.image : 컨테이너에 사용할 이미지
.spec.containers.name : 컨테이너 이름
.spec.containers.ports : 노출할 포트 정의
.spec.containers.ports.containerPort : 노출할 컨테이너 포트번호
.spec.containers.ports.protocol : 노출할 컨테이너 포트의 프로토콜(기본 : TCP)
즉, api버전은 코어 그룹의v1이고 생성할 오브젝트 종류는 당연하지만 파드이다. 파드 오브젝트 리음은 myapp-pod이며, 하나의 컨테이너를 가지고 있다. 컨테이너 이름은 myapp이며, 사용할 이미지는 ghcr.io/clt1d0s7/go-myweb 이다. 또한 애플리케이션의 응답 대기 포트는 TCP 8080 이다.
3) 파드 생성
kubectl create -f myapp-pod.yaml

kubectl delets -f myapp-pod.yaml >> 파드 삭제 명렁어
4) 파드 목록 확인
kubectl get pods

5) 실행 중인 파드 정의 확인
-o yaml 명령을 이용해 파드의 정보를 자세히 확인할 수 있다.
kubectl get pod myapp-pod -o yaml
6) 파드의 자세한 정보 확인
kubectl describe pod myapp-pod >>> kubectl describe 명령을 이용하여 자세히 확인할 수 있다.
7) 파드 로그 확인
kubectl logs >>> 파드의 로그를 확인할 수 있다.
kubectl logs myapp-pod
8) 파드 포트 포워딩
kubectl port-forward 명령을 이용해 호스트 포트를 컨테이너의 포트로 포워딩 해보자
kubectl port-forward myapp-pod 8080:8080 >>> Kubernetes 클러스터에서 실행 중인 "myapp-pod"라는 이름의 Pod에 대해 로컬 포트 포워딩을 설정하는 명령입니다. 이를 통해 로컬 시스템의 8080 포트와 Pod의 8080 포트가 연결되어, 로컬에서 Pod의 서비스에 접근할 수 있게 됩니다.
curl http://localhost:8080 >> curl 명령을 이용해 포워딩된 포트를 이용해 웹 애플리케이션을 확인해보자.
port-forward 명령은 포그라운드 상태에서 동작하기 떄문에, 확인 시 별도의 터미널에서 확인을 하고, 더이상 필요하지 않은 경우 ctrl+c로 중지한다!!!
3.2 레이블 및 셀렉터
1) 레이블 소개
레이블은 쿠터네티스 클러스터의 모든 오브젝트에 키/값 쌍으로 리소스를 식별하고 속성을 지정하는 데 사용
오브젝트 개수가 많아지면 오브젝트를 식별하는데 매우 어려울 수 있으며, 오브젝트의 적절한 레이블을 부여하여 성격을 정의하고 검색을 용이하게 할 수 있다.
레이블은 사용자에게 중요하자만, 쿠버네티스 클러스터에 직접적인 의미는 없다.
2) 레이블을 사용한 파드 정의
code myapp-pod-label.yaml

env와 tier 레이블을 추가해 myapp-pod-label 파드를 생성한다.
4) 파드 생성
kubectl create -f myapp-pod-label.yaml
5) 파드 레이블 확인
kubectl get pods 명령에서 --show-labels 옵션을 사용하면 파드 목록에서 레이블을 확인할 수 있다.

-L 옵션을 사용하여 특정 레이블을 지정해 필드로 표시할 수 있다.
kubectl get pods -L env,tier

-o yaml 옵션에서도 레이블이 있다면 확인이 가능하다.
kubectl get pod myapp-pod-label -o yaml

6) 파드 레이블 수정
현재 존재하는 파드에 레이블을 추가하거나 이미 존재하는 레이블을 수정할 수도 있다!!!
앞에서 생성한 레이블이 없는 myapp-pod 파드에 env 레이블을 추가해 보자
kubectl label pod myapp-pod env=dev

myapp-pod-label 파드에 env 레이블을 수정해 보자
kubectl label pod myapp-pod-label env=debug

myapp-pod-label 파드에 dev 레이블은 이미 존재하며, debug로 수정하려고 했지만 이미 dev 값을 가지고 있다고 오류를 발생시켰다. 이미 레이블이 존재하는 경우 --overwrite 옵션을 사용하여 수정할 수 있다.

7) 레이블 셀렉터
오브젝트에 부여되어 있는 레이블을 식별하고 검색할 수 있다.
두 가지 검색 방법
- 특정 키가 있는/없는 레이블 포함
- 특정 키와 값이 있는/없는 레이블 포함
일치성 기준(=, ==, !=), 집합성 기준(in, notin, exists)
8) 일치성 기준 레이블 셀렉터
tier 키가 포함되어 있는 레이블
kubectl get pods --show-labels -l tier

tier 키를 제외한 레이블
kubectl get pods --show-labels -l '!tier'

env 키에 debug 값이 포함되어 있는 레이블
kubectl get pods --show-labels -l env=debug

env 키를 가지지만 debug 값이 포함되지 않은 레이블
kubectl get pods --show-labels -l 'env!=debug'

참고 : ! 메타 문자가 쉘이 의해 해석되지 않게 따옴표로 묶어 줘야됨!!!
9) 집합성 기반 레이블 셀렉터
dev 키에 debug, dev 값이 포함되어 있는 레이블
kubectl get pods --show-labels -l 'env in (debug,dev)'

tier 키를 가지지만 frontend 값이 포함되어 있지 않은 레이블
kubectl get pods --show-labels -l 'tier notin (frontend)'

3.3 어노테이션
주석이라고도 하며 오브젝트에 비-식별 메타데이터를 지정할 수 있다.
그럼 레이블이랑 무슨차이가 있음???
레이블은 검색할수 있지만 어노테이션은 검색할수 없음
말 그대로 그냥 설명을 붙이는것이다. 실제 작동에 영향을 미치지 않는 단순 정보이다.
2) 어노테이션 추가 및 수정
레이블과 마찬가지로 오브젝트 생성 시 선언할 수도 있고, 오브젝트가 생성된 후에도 추가 및 수정할 수 있다.
기존 myapp-pod 파드에 deveops-teml/developer 라는 어노테이션을 추가해보자
kubectl annotate pods myapp-pod devops-team/developer="John Smith"
kubectl describe 명령을 사용해 어노테이션 확인
kubectl describe pod myapp-pod

kubectl get pods myapp-pod -o yaml 명령으로도 역시확인 가능
YAML 파일로 선언할 때 pods.metadata.annotations 필드에 선언할 수도 있다.
code myapp-pod-annotations.yaml

kubectl describe pod myapp-pod-annotation 명령어를 이용해 확인해보자

3.4 네임스페이스
모든 오브젝트에 레이블을 부여할 수 있다. 그러나 이는 레이블 셀렉터를 이용해서 식별 및 검색을 할 수 있을 뿐, 논리적으로 분리되어 있지 않다. 즉, 많은 오브젝트를 관리할 때 논리적으로 오브젝트의 분리가 필요
즉, 네임스페이스는 오브젝트를 논리적으로 분리할 수 있는 논리적 파티션이다.
2) 네임 스페이스 확인
kubectl get namespaces

여태 생성한 오브젝트는 모두 기본 네임스페이스인 default 네임스페이스를 사용했음
즉, 오브젝트 생성시 특정 네임스페이스 지정하지 않으면 기본 네임스페이스를 사용한다.
default : 기본네임스페이스
kube-node-lease : 쿠버네티스 노드의 가용성을 체크하기 위한 네임스페이스
kube-public : 모든 사용자가 읽기 권한으로 접근할 수 있음
kube-systeml : 쿠버네티스 클러스터의 핵심 리소스 배치
3) 네임스페이스의 오브젝트 확인
kube-systeml 네임스페이스에 존재하는 파드의 목록을 확인하는 명령이다

네임스페이스를 지정하는 옵션은 -n 또는 --namespace 옵션을 사용하고, 해당 옵션을 사용하지 않는 경우 기본 네임스페이스인 default 네임스페이스가 자동으로 지정됨
kube-system 네임스페이스는 쿠버네티스 시스템이 동작하기 위한 구성요소들이 파드 형태로 동작하고 있다.
kubectl get all -n kube-system >>> 실제 파드 이외의 다른 리소스도 존재하며, 다음과 같이 확인할 수 있다.
kubectl get pods -A >>> 모든 네임스페이스의 파드 오브젝트도 한 번에 확인할 수 있다.

4) 네임스페이스 생성
YAML 파일을 생성하지 않고도 간단히 명령을 이용해 네임스페이스를 생성할수 있다.
kubectl create namespace development >>> development 네임스페이스 생성 명령어
kubectl get namespaces >>> 네임스페이스 확인 명령어

YAML 파일을 이용하여 네임스페이스를 생성할 수 있다.
code aq-ns.yaml

YAML 파일을 선언해 quality-assurance 네임스페이스를 만든다.
kubectl create -f aq-ns.yaml
kubectl get namespaces >>> 생성되었는지 확인한다.

5) 특정 네임스페이스에서 파드(및 오프젝트) 생성
오브젝트 생성 시 특정 네임스페이스를 지정하면 해당 네임스페이스에 오브젝트를 생성할 수 있다.
kubectl create -f myapp-pod.yaml -n development
development 네임스페이스를 확인해보자
kubectl get pods -n development

YAML 파일의 pods.metadatd.namespaces 필드에 직접 네임스페이스도 선언 가능하다.

6) 리소스 삭제
리소스의 삭제는 크게 세 가지 방법으로 가능!!!
- 오브젝트 이름으로 삭제
- 오브젝트 정의 파일로 삭제
- 오브젝트 레이블로 삭제
1) 오브젝트 이름으로 파드 삭제
kubectl delete pod myapp-pod >>> 네임스페이스를 지정하지 않았기 때문에 default 네임스페이스의 myapp-pod 파드가 삭제된다

2) YAML 파일로 파드 삭제
kubectl delece -f myapp-pod-ns.yaml
3) 오브젝트 레이블을 이용한 오브젝트 삭제
kubectl delete pods -l tier=frontend
4) 네임스페이스 삭제
kubectl delete namespaces development

정의된 YAML을 이용하여 quality-assurance 네임스페이스를 삭제한다
kubectl delete -f aq-ns.yaml
5) 삭제된 네임스페이스 확인
kubectl get namespaces
