Kubernetes
(면접 때 Q. 쿠버네티스를 왜 쓰는 지 대답할 수 있어야 한다.)
역사 - 쿠버네티스가 유용해지기까지
초기엔 하나의 물리서버에 여러 서비스를 돌리다 보니 한 서버가 나가면 죄다 장애가 나는 문제가 생겼다.
게다가 서비스 하나 하나가 먹는 리소스 한계를 정의할 방법이 없었기 때문에, 리소스 할당의 문제가 발생했다.
예를 들어 물리 서버 하나에서 여러 서비스를 실행하면 리소스 전부를 차지하는 서비스가있을 수 있고,
결과적으로는 다른 애플리케이션의 성능이 저하될 수 있었다.
그러다 이런 단점을 보완하기 위해 한 서버당 한 서비스를 돌리게 됐다.
하지만 DNS나 WEB같이 리소스가 많이 노는 서비스의 경우 한 서버를 차지하는 것 조차 낭비인 경우가 생겼다.
사업주 입장에선 굉장히 손해다.
그래서 다시 DNS와 WEB서비스같이 일부 서비스들을 한 서버에 두는 시대가 오기도 했다.
이 후 궁극적인 단점을 없애고 장점만을 취하기 위해 가상화 기술을 개발했다.
이는 단일 물리 서버의 CPU에서 여러 가상 시스템 (VM)을 실행할 수 있게 한다.
VM 머신의 무겁다는 단점 등을 개선하여 나온 것이 컨테이너 기술이다.
컨테이너 는 VM과 유사하지만 격리 속성을 완화하여 애플리케이션 간에 운영체제(OS)를 공유한다. 그러므로 컨테이너는 가볍다고 여겨진다. VM과 마찬가지로 컨테이너에는 자체 파일 시스템, CPU 점유율, 메모리, 프로세스 공간 등이 있다. 기본 인프라와의 종속성을 끊었기 때문에, 클라우드나 OS 배포본에 모두 이식할 수 있다.
개발 환경과 실제 환경간의 호환성 문제도 컨테이너의 격리된 속성 덕에 해결할 수 있다.
https://kubernetes.io/ko/docs/concepts/overview/
쿠버네티스는 그래서 왜 필요한가?
클라우드도 그렇지만 컨테이너는 스케일 인과 스케일 아웃이 굉장히 짧은 시간안에 가능한 것이 장점이다.
기존 컨테이너 20개가 장애가 나면 자동으로 금방 20개를 다시 스케일 인 해주면 된다.
그 다수의 컨테이너를 자동으로 작동하게 도와주는 오케스트레이션 프로그램이 바로 쿠버네티스다.
오케스트레이션에 포함된 기능은 여러가지다.
서비스 디스커버리(DNS, 자체IP)와 로드 밸런싱
스토리지 오케스트레이션
자동화된 롤아웃과 롤백
자동화된 빈 패킹(노드에 맞춘 리소스 배분)
자동화된 복구(self-healing)
보안 시크릿 구성 관리
개념
참고로 아래와 같이 쿠버네티스를 깔지 않고도 웹상에서 콘솔을 경험해 볼 수 있는 기능이 공식 홈에 있다.
하지만 우린 후술할 설치 단계에서 직접 VMware 위에 깔아서 사용할 것이다.
https://kubernetes.io/ko/docs/tutorials/kubernetes-basics/create-cluster/cluster-interactive/
쿠버네티스 클러스터
쿠버네티스 클러스터는 쿠버네티스의 여러 리소스를 관리하기 위한 집합체이다
마스터노드와 워커노드의 집합으로 이루어져있다. (실제 권장사항은 마스터 노드 3개 이상)
노드는 클러스터의 관리 대상으로 등록된 도커 호스트로, 도커 컨테이너가 배치되는 대상이다.
(말단의 디바이스를 의미한다.)
워커 노드 안에 컨테이너들은 pod라는 집합으로 구성된다. (컨테이너 최소1개로 구성)
컨트롤 플레인은 워커 노드와 클러스터 내 파드를 관리한다. 일반적으로 여러 컴퓨터에 걸쳐 실행된다.
컨트롤 플레인 컴포넌트는 클러스터에 관한 전반적인 결정(예를 들어, 스케줄링)을 수행하고
클러스터 이벤트(예를 들어, 디플로이먼트의 replicas 필드에 대한 요구 조건이 충족되지 않을 경우
새로운 파드를 구동시키는 것)를 감지하고 반응한다.
컨트롤 플레인 컴포넌트
kube-apiserver
API 서버는 쿠버네티스 API를 노출하는 쿠버네티스 컨트롤 플레인 컴포넌트이다. API 서버는 쿠버네티스 컨트롤 플레인의 프론트 엔드이다.
api란 애플리케이션을 만들 때 운영체제에서 동작하는 프로그램을 쉽게 만들 수 있도록
화면 구성이나 프로그램 동작에 필요한 각종 함수를 미리 모아놓은 도서관 같은것을 말한다.
etcd
모든 클러스터 데이터를 담는 쿠버네티스 뒷단의 저장소로 사용되는 일관성·고가용성 키-값 저장소.
쿠버네티스 클러스터에서 etcd를 뒷단의 저장소로 사용한다면, 이 데이터를 백업하는 계획은 필수이다.
kube-scheduler
노드가 배정되지 않은 새로 생성된 파드 를 감지하고, 실행할 노드를 선택하는 컨트롤 플레인 컴포넌트.
kube-controller-manager
컨트롤러 프로세스를 실행하는 컨트롤 플레인 컴포넌트.
논리적으로, 각 컨트롤러는 분리된 프로세스이지만, 복잡성을 낮추기 위해
모두 단일 바이너리로 컴파일되고 단일 프로세스 내에서 실행된다.
이들 컨트롤러는 다음을 포함한다.
- 노드 컨트롤러: 노드가 다운되었을 때 통지와 대응에 관한 책임을 가진다.
- 잡 컨트롤러: 일회성 작업을 나타내는 잡 오브젝트를 감시한 다음, 해당 작업을 완료할 때까지 동작하는 파드를 생성한다.
- 엔드포인트 컨트롤러: 엔드포인트 오브젝트를 채운다(즉, 서비스와 파드를 연결시킨다.)
- 서비스 어카운트 & 토큰 컨트롤러: 새로운 네임스페이스에 대한 기본 계정과 API 접근 토큰을 생성한다
cloud-controller-manager
클라우드별 컨트롤 로직을 포함하는 쿠버네티스 컨트롤 플레인 컴포넌트이다. 클라우드 컨트롤러 매니저를 통해 클러스터를 클라우드 공급자의 API에 연결하고, 해당 클라우드 플랫폼과 상호 작용하는 컴포넌트와 클러스터와만 상호 작용하는 컴포넌트를 구분할 수 있게 해 준다.
cloud-controller-manager는 클라우드 제공자 전용 컨트롤러만 실행한다. 자신의 사내 또는 PC 내부의 학습 환경에서 쿠버네티스를 실행 중인 경우 클러스터에는 클라우드 컨트롤러 매니저가 없다.
노드 컴포넌트
kubelet
클러스터의 각 노드에서 실행되는 에이전트. Kubelet은 파드에서 컨테이너가 확실하게 동작하도록 관리한다.
Kubelet은 다양한 메커니즘을 통해 제공된 파드 스펙(PodSpec)의 집합을 받아서 컨테이너가 해당 파드 스펙에 따라 건강하게 동작하는 것을 확실히 한다. Kubelet은 쿠버네티스를 통해 생성되지 않는 컨테이너는 관리하지 않는다
kube-proxy
kube-proxy는 클러스터의 각 노드에서 실행되는 네트워크 프록시로, 쿠버네티스의 서비스 개념의 구현부이다.
kube-proxy는 노드의 네트워크 규칙을 유지 관리한다. 이 네트워크 규칙이 내부 네트워크 세션이나 클러스터 바깥에서 파드로 네트워크 통신을 할 수 있도록 해준다.
kube-proxy는 운영 체제에 가용한 패킷 필터링 계층이 있는 경우, 이를 사용한다. 그렇지 않으면, kube-proxy는 트래픽 자체를 포워드(forward)한다
설계도
쿠버네티스용 머신 구성
터미널은 아래것을 쓴다 (취향)
https://mobaxterm.mobatek.net/download-home-edition.html
vi /etc/sysconfig/network-scripts/ifcfg-ens33
master.labs.local
node1.labs.local
node2.labs.local
node3.labs.local
각각 호스트네임 수정 후에 hosts파일에 서로 주소 등록해줘서 통신 가능하게 한다.
vi /etc/hostname
vi /etc/hosts
selinux 정지
vi /etc/sysconfig/selinux
selinux = permissive
재부팅하기
방화벽 해제 및 NetworkManager 해제
systemctl disable --now firewalld
systemctl disable --now NetworkManager
SWAP 주석처리 해서 중지
swapoff -a && sed -i '/swap/s/^/#/' /etc/fstab
설치
도커 설치!
yum install -y yum-utils
yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
yum -y install docker-ce docker-ce-cli containerd.io
systemctl enable --now docker
(--now 옵션 : 오토스타트 + 스타트)
docker0가 추가된 것이 보인다.
브릿지 연결 설정
cat <<EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
활성화
sysctl --system
쿠버네티스 설치
아래와 같이 쿠버네티스 리포지토리를 설정한다.
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=1
repo_gpgcehcek=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg http://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOF
설정한 리포지토리로 들어간다.
안에 kubernetes.repo 파일을 보면 방금 한 설정이 잘 들어가 있는 것을 확인할 수 있다.
cd /etc/yum.repos.d
쿠버네티스 설치
yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
활성화
systemctl enable --now kubelet
실행
master.labs.local
예전에는 도커 컨테이너에서 제공해주는 런타임을 썼었는데, 지금은 최적화를 위해 이를 버렸다.
이제는 쿠버네티스 쪽에서 자체 런타임을 개발해서 그것으로 실행해야 한다.
그냥 실행하려면 다음과 같이 CRI 에러가 뜨면서 안되는 상태다.
kubeadm init
다음과 같이 잘못된 파일을 지우고 다시 시작해보자.
rm -f /etc/containerd/config.toml
systemctl restart containerd
안됐던 런타임 실행이 잘 성공한다!
kubeadm init
아래와 같은 성공창이 뜨는 데 이 내용이 이후 작업에 제법 중요하다.
그러니까 복사해서 여기 붙여넣어주자.
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Alternatively, if you are the root user, you can run:
export KUBECONFIG=/etc/kubernetes/admin.conf
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.108.3:6443 --token gcrmph.v9repwro3qxdtuw9 \
--discovery-token-ca-cert-hash sha256:5e22b4f3f06a4ac00db230d8ba3f4f965f91dd68767bee606cfa06ea7166f031
kubeadm join 10.0.0.1:6443 --token wceyno.eskn0lrcd4tw6rr4 \
--discovery-token-ca-cert-hash sha256:3f14ad20dfbd2c855a362c1cf7e8cb52a1bc571f1f51ff977d445050b97cabf1
설정
복사해놓은 내용을 따라한다. 우선 아래 4줄을 복붙해서 적용해준다.
앞으로 과정의 선행작업으로 다음과 같은 내용이 요구되기 때문이다.
인증 토큰값을 넣어준다. 매우 중요하니까 틀리지 말 것.
pod의 네트워크가 add on 되지 않아서 아직 NotReady 상태이다.
kubectl get nodes
CNI설치
모든 노드간의 통신은 CNI를 통해서 한다.
이제 calico와 weave라는 두 사이트중 한 곳을 골라 cni관련 파일을 다운받아야 하는데, weave를 선택해보겠다.
다음 사이트를 참고해서 필요한 yaml을 다운받아보자.
https://www.weave.works/docs/net/latest/kubernetes/kube-addon/
이 글을 작성할 땐 위 사이트가 알려준 주소는 아래와 같았다.
kubectl apply -f https://github.com/weaveworks/weave/releases/download/v2.8.1/weave-daemonset-k8s.yaml
(참고로 칼리코 설치법 :curl https://docs.projectcalico.org/manifests/calico.yaml -O
kubectl apply -f calico.yaml)
적용 하고 나면 다음과 같이 Ready 상태가 된다.
kubectl get nodes
조인
token 전송
node1, 2, 3도 master와 같은 쿠버네티스 클러스터에 조인하려고 한다.
master에서 node1, 2, 3 쪽에 아까 만든 token 파일을 전송한다.
node1, 2, 3 조인
Active Directory의 D.C에 가입하는 것과 비슷한 의미의 '조인' 이다.
master node에 조인해보자.
bash token
만약 node1,2,3 에서 아래와 같이 명령어가 안 먹고 에러를 띄운다면
다음 조취를 따라라.
rm /etc/containerd/config.toml
systemctl restart containerd
bash token
다음과 같이 잘 starting 된다.
kubectl get nodes
다음과 같이 master 쪽에서 조인된 다른 node들이 보이고, Ready 상태가 된다.
(만약 Ready 상태가 안된다면 VMware 자체를 껐다가 켜면 되기도 한다)
상태 확인
자세한 설정값과 상태 확인
kubectl describe nodes master.labs.local
API 버전에 대한 목록
batch/V1 , V1 등을 자주 사용한다.
kubectl api-versions | more
API를 동작시키는 리소스 목록
kubectl api-resources
API 특정 버전에 대한 정보
kind에 따라 api version이 달라지기 때문에 사용할 api 종류를 잘 확인하고 인터넷에서 맞는 정보를 찾아야 한다.
V1에 대한 정보를 찾아보겠다.
메타데이터 등 항목별 설명이 출력 되고있다. 이 필드 항목을 골라서 다음 항목으로 계속 들어갈 수 있다.
kubectl explain --api-version=apps/v1 deployment
이런식으로 자동으로 포드를 생성해주는 탬플릿 정보까지 들어가 볼 수 있다.
kubectl explain --api-version=apps/v1 deployment.spec.template |more
Windows에서 kubectl 관리
번외) 그냥 master node에서 관리 해도 되겠지만, Windows 환경에서 관리하는 방법도 있다.
kubectl 실행파일 다운로드
https://dl.k8s.io/release/v1.25.0/bin/windows/amd64/kubectl.exe
cmd 관리자 권한으로 실행
다운로드 받은 kubectl 실행파일을 다운로드 폴더에서 system32 폴더로 이동
cd c:\Windows\System32
move c:\Users\user\Downloads\kubectl.exe c:\Windows\System32
이동 확인
dir kubectl.exe
kubectl같이 path 등록 된 항목은 조회가 된다.
mkdir C:\Users\user\.kube
cd C:\Users\user\.kube
scp root@192.168.108.3:/root/.kube/config ./
notepad config
kubectl get node
다음과 같이 윈도우 cmd 창에서도 쿠버네티스 클러스터를 관리할 수 있다.
https://platform9.com/kb/kubernetes/cni-plugin-not-initialized-on-master-node
'Kubernetes' 카테고리의 다른 글
kubectl config 명령어 (클러스터 context 변경) (0) | 2022.12.27 |
---|---|
Namespace (0) | 2022.12.26 |
Kubernetes Resource 관리 (0) | 2022.12.22 |
Kubernetes 기본 명령어 (0) | 2022.12.21 |
Kubernetes image pull error (0) | 2022.12.20 |