# Kubernetes # 용어해설 #####
**용어** | **정의** |
쿠버네티스 (Kubernetes) | 컨테이너 오케스트레이션 도구로, 대규모 분산 시스템을 쉽게 관리할 수 있게 해주는 오픈소스 플랫폼 |
K8s | 쿠버네티스(Kubernetes)의 약어로, 컨테이너 오케스트레이션 도구를 간단하게 부르는 방법 |
오브젝트 | 쿠버네티스에서 오브젝트는 쿠버네티스 시스템에서 관리하는 기본 단위 |
오픈소스 | 공개된 소프트웨어로, 소스 코드를 누구나 열람하고 수정할 수 있는 소프트웨어를 의미 |
컨테이너 | 소프트웨어를 격리된 환경에서 실행할 수 있도록 도와주는 기술로, 가상화 기술의 일종 |
컨테이너화 | 애플리케이션을 컨테이너에 담아서 실행 가능한 형태로 만드는 기술 |
배포 | 소프트웨어나 애플리케이션을 실제 사용 환경에 설치하고 실행할 수 있도록 전달하는 과정 |
스케일링 | 시스템이나 애플리케이션의 성능을 유연하게 조절하면서 대규모 트래픽 처리나 높은 가용성을 유지하기 위한 기술 |
Borg | 구글이 개발한 대규모 클러스터 관리 시스템으로, Kubernetes의 전신이 되는 기술 |
모놀리식 (monolithic) | 전통적인 방식의 소프트웨어 아키텍처로, 모든 기능을 하나의 애플리케이션으로 구성하는 방식 |
LAMP 스택 | 리눅스, 아파치, MySQL, PHP를 조합한 오픈소스 웹 개발 환경을 의미 |
Docker | 컨테이너 기반 가상화 플랫폼으로, 애플리케이션을 컨테이너로 추상화하여 배포 및 관리를 용이하게 해주는 기술 |
Podman | 컨테이너 기반 가상화 플랫폼으로, Docker와 유사한 기능을 제공하지만 데몬 없이 컨테이너를 관리할 수 있는 기술 |
LXC | 리눅스 컨테이너를 만들고 관리하기 위한 운영 체제 레벨 가상화 기술 |
마이크로서비스 | 작고 독립적인 기능을 갖는 애플리케이션으로, 각각이 분리되어 개발, 배포, 확장이 가능한 아키텍처 패턴 |
오케스트레이션 | 서로 다른 요소를 결합하여 큰 작업을 수행한다는 과정 (예: 지휘자가 음악 공연을 조율하는 것) |
Docker swarm | 도커 오케스트레이션 툴 중 하나로 분산 애플리케이션을 쉽게 배포하고 관리할 수 있는 기술 |
클러스터화 | 여러 대의 컴퓨터나 서버를 하나로 묶어 하나의 시스템처럼 동작하게 만든 컴퓨팅 환경 |
롤아웃/롤백 | 소프트웨어나 서비스의 업데이트나 배포 과정에서 새로운 버전으로 전환하는 것(롤아웃)과 문제가 발생했을 때 이전 버전으로 돌아가는 것(롤백) |
DNS | 도메인 이름을 IP 주소로 변환하여 컴퓨터나 장치들이 인터넷에 연결되어 있는 다른 장치들을 찾을 수 있도록 돕는 인터넷 프로토콜 |
라우팅 | 여러 개의 네트워크를 연결하여 인터넷과 같은 대규모 네트워크를 구성 해주는 기술 |
로드밸런싱 | 여러 대의 서버에 트래픽을 분산시켜 부하를 분산시키고, 안정적으로 서비스를 제공하는 기술 |
퍼블릭 클라우드 | 인터넷을 통해 누구나 이용 가능한 클라우드 서비스로, 인프라와 리소스를 외부 서비스 제공업체에서 제공하고 관리 |
Nginx | 무료 오픈 소스 웹 서버 소프트웨어로, 웹 서버, 리버스 프록시, 메일 프록시 등의 기능을 수행 |
SSH | 인터넷에서 안전하게 원격 제어를 가능케 하는 프로토콜로, 암호화 기술을 사용하여 통신을 보호 |
Prometheus | 오픈소스 모니터링 시스템. 애플리케이션, 시스템, 서비스 등을 모니터링할 수 있으며, 다양한 메트릭을 수집, 저장하고 조회할 수 있다 |
Jenkins | 오픈소스 지속적인 통합(CI) 서버. 애플리케이션 개발에서 빌드, 테스트, 배포 등의 과정을 자동화할 수 있으며, 다양한 플러그인을 지원하여 기능을 확장할 수 있다 |
OAuth | 사용자 인증을 위한 오픈 표준 프로토콜로, 웹이나 앱 등에서 다른 서비스의 정보나 기능을 사용할 수 있도록 권한 부여를 관리 |
노드 (node) | 서버로서의 노드는 클라이언트 요청을 처리하고, 다른 컴퓨터나 디바이스와 연결하여 네트워크에서 데이터를 주고받을 수 있는 컴퓨터나 장치 |
MSA (Micro Service Architecture) | 마이크로서비스 아키텍처의 약어로, 작고 독립적인 서비스 단위로 구성된 분산 시스템 아키텍처를 의 |
Kubernetes Control Plane | 쿠버네티스 클러스터에서 마스터 컴포넌트들이 실행되는 노드 그룹으로, 클러스터의 전반적인 상태 및 구성, 스케줄링, 배포, 업데이트, 모니터링 등의 관리 작업을 수행 |
워크로드 | 시스템에서 실행되는 작업을 의미하며, 컴퓨터의 CPU, 메모리, 디스크 등의 리소스를 사용하여 작업을 수행 |
모니터링 | 시스템 또는 프로세스를 지속적으로 감시하고 분석하여 성능, 가용성, 안정성, 보안 등을 평가하고 문제를 신속하게 해결하기 위한 작업 |
프록시 | 클라이언트와 서버 사이에서 요청과 응답을 전달하는 중간 서버로, 클라이언트의 IP를 숨기고 보안을 강화하거나 캐싱 등의 기능을 수행 |
Flannel | 쿠버네티스 클러스터에서 사용하는 네트워크 솔루션 중 하나 |
워크플로우 | 업무나 작업의 진행 과정을 시각적으로 표현하여 보여주는 것으로, 업무의 흐름을 파악하고 관리하기 위한 방법 |
manifest 파일 | 쿠버네티스에서 어플리케이션 배포에 필요한 설정 정보를 담은 YAML 또는 JSON 파 |
YAML 형식 | 데이터를 인간이 쉽게 읽고 작성할 수 있도록 디자인된 경량 마크업 언어로, 키-값 쌍으로 이루어진 데이터 집합을 표현하는 포맷 |
kubectl 명령어 | 쿠버네티스 클러스터에서 리소스를 생성하고 관리하기 위한 커맨드 라인 인터페이스 도구 |
Kubernetes API schema | 쿠버네티스 API 서버가 제공하는 리소스의 스팩(Spec)과 상태(Status)를 정의하는 YAML 파일 |
스케줄링 | 컴퓨터 자원의 할당과 작업 처리 순서를 결정하는 작업 |
라우팅 | 서로 다른 네트워크를 연결 해주는 과정 |
Vanilla | 소프트웨어 산업에서 제품이나 소프트웨어 패키지의 표준 버전을 가리키는 용어 |
Swap Memory | 운영 체제가 하드 디스크 공간을 사용하여 사용 가능한 RAM을 보완할 수 있도록 하는 가상 메모리의 한 유형 |
Hardware(하드웨어) | Node |
---|---|
Orchestration(오케스트레이션) | Deployment, Job, CronJob, StatefulSet, DaemonSet |
Configuration(구성) | ConfigMap, Secret |
Persistence(지속성) | PersistentVolume, PersistentVolumeClaim(PVC) |
AccessControl(접근 제어) | Namespace, ServiceAccount, Role, ClusterRole |
Exposure(외부 노출) | Service, Ingress |
BGP모드는 Border Gateway Protocol의 약자로 인터넷에서 라우팅 정보를 교환하고 관리하기 위해 사용 된다 ARP는 IP 주소와 MAC 주소 간의 매핑을 수행하는 네트워크 프로토콜이다
예시: ```bash vi app.yaml # 로드 밸런서 YAML 파일 apiVersion: v1 kind: Service metadata: name: nginx-loadbalancer spec: ports: - name: web-port port: 80 targetPort: 8080 selector: app: webserver type: LoadBalancer --- # 웹 사이트 배포 YAML 파일 apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 8080 ``` 이렇게 YAML 파일을 적용 시킨 후 결과를 확인 하면 ```bash # YAML 파일 적용 kubectl apply -f app.yaml # 모든 리소스 확인 kubectl get all NAME READY STATUS RESTARTS AGE pod/nginx-deployment-6f67db9747-l8shl 1/1 Running 0 6s pod/nginx-deployment-6f67db9747-tcc8k 1/1 Running 0 6s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.233.0.1참고용 MetalLB installation 페이지 링크: [https://metallb.universe.tf/installation/](https://metallb.universe.tf/installation/)
공식 사이트에 나와있는 매니페스트 파일 방식으로 L2모드 설치를 진행 해 보았다. L2 모드는 대부분의 경우, 프로토콜 특정 구성이 필요하지 않으며, IP 주소만 필요하고 쉽게 구성 할 수 있다.L2 모드는 워커 노드의 네트워크 인터페이스의 IP를 할당할 필요가 없다. 이 모드는 로컬 네트워크에서 ARP 요청에 직접 응답하여 클라이언트에게 기계의 MAC 주소를 제공 하는 모드다.
제일 먼저, strictARP 모드를 활성화 해야 한다. 마스터 노드에서, ```bash kubectl edit configmap -n kube-system kube-proxy ``` vim editor 처럼 파일 수정이 가능 하다. 파일 속에서 41번째 줄에 있는 값을 변경 해준다. ```bash # 기본으로 false strictARP: true ``` 그 후 저장 후 파일에서 나온다. MetalLB설치 할 준비는 끝났으나 이제 바로 매니페스트 파일을 적용 시켜 주면 된다 ```bash # 공식 사이트 Installation에 나온 링크 kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.10/config/manifests/metallb-native.yaml namespace/metallb-system configured customresourcedefinition.apiextensions.k8s.io/addresspools.metallb.io created customresourcedefinition.apiextensions.k8s.io/bfdprofiles.metallb.io created customresourcedefinition.apiextensions.k8s.io/bgpadvertisements.metallb.io created customresourcedefinition.apiextensions.k8s.io/bgppeers.metallb.io created customresourcedefinition.apiextensions.k8s.io/communities.metallb.io created customresourcedefinition.apiextensions.k8s.io/ipaddresspools.metallb.io created customresourcedefinition.apiextensions.k8s.io/l2advertisements.metallb.io created serviceaccount/controller unchanged serviceaccount/speaker unchanged role.rbac.authorization.k8s.io/controller configured role.rbac.authorization.k8s.io/pod-lister configured clusterrole.rbac.authorization.k8s.io/metallb-system:controller configured clusterrole.rbac.authorization.k8s.io/metallb-system:speaker configured rolebinding.rbac.authorization.k8s.io/controller configured rolebinding.rbac.authorization.k8s.io/pod-lister configured clusterrolebinding.rbac.authorization.k8s.io/metallb-system:controller unchanged clusterrolebinding.rbac.authorization.k8s.io/metallb-system:speaker unchanged configmap/metallb-excludel2 created secret/webhook-server-cert created service/webhook-service created deployment.apps/controller configured daemonset.apps/speaker configured validatingwebhookconfiguration.admissionregistration.k8s.io/metallb-webhook-configuration created ``` 이렇게 매니페스트를 적용 하게 되면 자동으로 MetalLB의 모든 필요 요소들이 자동으로 설치가 된다. 확인을 하기 위해 metallb-system namespace을 보면, controller과 speaker들이 보일 것이다 ```bash # 확인 하기 위해 새로 생성 된 metallb 네임 스페이스 리소스들 보기 kubectl get all -n metallb-system NAME READY STATUS RESTARTS AGE pod/controller-5fd797fbf7-r28s6 0/1 Running 0 17s pod/controller-bdf98b979-pp7dp 1/1 Running 0 80s pod/speaker-2hx68 1/1 Running 0 80s pod/speaker-p2nh4 1/1 Running 0 80s pod/speaker-r95cx 0/1 Running 0 17s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/webhook-service ClusterIP 10.233.32.213참고용 MetalLB Configuration 링크: [https://metallb.universe.tf/configuration/](https://metallb.universe.tf/configuration/)
먼저 IP 풀을 지정 해 줘야 한다. ```bash # IP 풀 설정을 위해 매니페스트 파일 생성 vi metallb-config.yaml apiVersion: metallb.io/v1beta1 kind: IPAddressPool metadata: name: first-pool namespace: metallb-system spec: addresses: - 192.168.1.40-192.168.1.50 # IP 주소 풀 할당 --- apiVersion: metallb.io/v1beta1 kind: L2Advertisement metadata: name: metal namespace: metallb-system spec: ipAddressPools: - first-pool ``` 매니페스트 파일 저장 후 적용을 한다 ```bash kubectl apply -f metallb-config.yaml ipaddresspool.metallb.io/first-pool created l2advertisement.metallb.io/metal created ``` 테스팅을 위해 이미 배포 되어 있는 웹 사이트의 서비스 타입을 LoadBalancer로 바꿔 보았다 ```bash # 웹 사이트 매니페스트 파일 vi my-app.yaml apiVersion: v1 kind: Service metadata: name: my-app-service spec: type: LoadBalancer # 전에는 NodePort로 서비스 selector: app: my-app ports: - protocol: TCP port: 80 ``` 진행 중인 서비스들 목록을 확인 해보면 이젠 로드 밸런서가 EXTERNAL-IP를 지정 한 IP 풀 안에서 자동으로 부여 하는 것을 확인 할 수 있다 ``` kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.233.0.1Window 속 'hosts' 파일 경로 C:\\Windows\\System32\\drivers\\etc\\hosts Linux 속 'hosts' 파일 경로 /etc/hosts
'hosts' 파일 속 IP 매핑 후 모습 ```bash . . 192.168.90.73 host.docker.internal 192.168.90.73 gateway.docker.internal # 인그레스 컨트롤러의 서비스 External-IP와 매핑 192.168.1.40 myapp.ingtest.com 192.168.1.40 myapp2.ingtest.com ``` 웹 사이트 접속 결과: myapp.ingtest.com [](http://138.2.116.150/uploads/images/gallery/2023-06/rjOimage.png) myapp2.ingtest.com [](http://138.2.116.150/uploads/images/gallery/2023-06/gIAimage.png) //SSL 추가 및 더 디테일 한 YAML 파일 설명 그리고 /myapp /myapp2 형태의 분리 작업 남음 # 쿠버네티스 스토리지 # 볼륨과 PV 오브젝트 # 시크릿 리소스 # 컨피그맵(ConfigMap) 리소스 # 쿠버네티스 RBAC # 네임스페이스 오브젝트 ##### **Namespace** 네임스페이스는 쿠버네티스 리소스들을 논리적으로 묶어주는 오브젝트다. 패키지라고 생각하면 된다. [](http://138.2.116.150/uploads/images/gallery/2023-05/HVDimage.png) 예시: ```bash apiVersion: v1 kind: Namespace metadata: name: production ``` 위와 같이 파일을 만들거나 `kubectl create ns {네임스페이스명}` 으로 만들어도 된다. 쿠버네티스 사용 시 자동으로 사용하도록 설정되는 네임스페이스는 `default` 다. 별도로 옵션을 명시하지 않았다면 해당 네임스페이스를 사용했을 것이다. # 롤 & 클러스터롤 # 계정 - Service Account & User Account # 쿠버네티스 애플리케이션 배포 # Pod 템플릿 정의하기 ##### **Pod** 쿠버네티스에서는 애플리케이션을 배포할 수 있는 최소 단위인 파드(Pod)라는 개념을 제공한다. 파드는 하나 이상의 컨테이너를 포함할 수 있으며, 같은 파드 안에 있는 컨테이너는 동일한 호스트에서 실행된다. [](http://138.2.116.150/uploads/images/gallery/2023-05/jvrimage.png) 위에서 본 예시 Yaml파일을 적용 해보면: ```bash kubectl apply -f example-pod.yaml pod/example-pod.yaml created ``` 이렇게 Nginx 파드가 생성 되었다. 확인 결과: ```bash kubectl get pods NAME READY STATUS RESTARTS AGE example-pod 1/1 Running 0 40s ``` 이 Nginx 파드는 사용할 포트를 80으로 지정 했지만, 아직 외부에서 접근 할 수 있도록 노출 되지는 않았다. 이 파드를 삭제 하려면: ```bash kubectl delete -f example-pod.yaml pod "example-pod" deleted kubectl get pods No resources found in default namespace ``` # Deployment 리소스 소개 쿠버네티스 클러스터 안에는 모든 리소스들을 오브젝트 형태로 관리한다. 컨테이너의 집합 (Pod), 컨테이너 집합을 관리하는 컨트롤러 (ReplicaSet), 사용자 (Service Account) 등등 을 모두 하나의 오브젝트로 사용 할 수 있다. 이 오브젝트들은 YAML 파일을 이용해서 생성 할 수 있다. 이 YAML 파일들을 Manifest(매니페스트) 파일이라고 부른다. 이 파일은 일련의 설정 정보를 포함하고 있으며, 쿠버네티스 클러스터에게 어떤 리소스를 생성하고 구성해야 하는지를 지시한다. 매니페스트 파일의 예시: ```bash # Nginx 컨테이너로 구성된 파드를 직접 생성하는 yaml 파일 예시 apiVersion: v1 kind: Pod metadata: name: example-pod spec: containers: - name: example-container image: nginx:latest ports: - containerPort: 80 protocol: TCP ``` 쿠버네티스 매니페스트 YAML파일은 일반적으로 apiVersion, kind, metadata, spec 네 가지 항목으로 구성 된다. - **apiVersion** yaml 파일에서 정의한 오브젝트의 API 버전 - **kind** 리소스의 종류(`kubectl api-resources` 명령어의 KIND 항목에서 확인 가능) - **metadata** 리소스의 부가 정보(label, annotation, name 등) - **spec** 리소스를 생성하기 위한 자세한 정보(파드에서 실행될 컨테이너 정보, 도커 이미지 정보, 포트 정보 등). `-` 은 list 형식이라고 생각하면 된다. `example-container` 라는 이름의 `nginx:latest` 이미지를 가진 컨테이너가 있다는 뜻이고, 포트는 80을 사용한다는 뜻이다. `kubectl apply -f쿠버네티스 클러스터 설정 시 Swap Memory 비활성화를 권장 한다. Swap Memory는 하드 디스크를 이용하여 RAM을 보충하는 가상 메모리이지만, K8s는 많은 자원을 요구하므로 Swap Memory를 사용하면 성능 저하와 스케줄링 지연이 발생할 수 있다. 또한, Swap Memory는 리소스 관리에 문제를 야기할 수 있으므로 안정적이고 효율적인 성능을 위해 스왑 메모리를 비활성화해야 한다. 더 자세한 내용은 여기 블로그 [링크](https://kgw7401.tistory.com/50) 참고.
### ### **CentOS 7에서 K8s 클러스터** ##### **Docker Installation** 시작 전, 이전 버전들을 삭제 한다 ```bash sudo dnf remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine ``` yum-utils 설치와 로컬 yum repository (저장소) 지정 ```bash sudo dnf install -y yum-utils ``` ```bash sudo dnf-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo ``` 도커 최신 버전 설치 ```bash sudo dnf install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin ``` 도커 서비스 시작 ```bash sudo systemctl start docker ``` 도커 버전 확인 ```bash docker version ``` ##### **Kubernetes Installation** 💡 *Master Node과 Worker Node에서 동일 하게 작업* [Swap Memory](http://138.2.116.150/books/kubernetes/page/8d7d8) 비활성화 ```bash swapoff -a ``` daemon.json 파일 생성 후 cgroupdriver을 systemd로 설정 ```bash vi /etc/docker/daemon.json { "exec-opts": ["native.cgroupdriver=systemd"] } ``` daemon 재시작 ```bash systemctl daemon-reload systemctl restart docker ``` 쿠버네티스 로컬 저장소 지정 및 설치 ```bash vi /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://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg # 쿠버네티스 설치 dnf install -y kubelet-1.19.16-0.x86_64 kubectl-1.19.16-0.x86_64 kubeadm-1.19.16-0.x86_64 ``` 쿠버네티스 설치 완료 확인 ```bash rpm -qa | grep kube ``` 쿠버네티스 클러스터 요소들 통신을 위해 방화벽 포트 추가 ```bash firewall-cmd --permanent --add-port=80/tcp firewall-cmd --permanent --add-port=443/tcp firewall-cmd --permanent --add-port=2376/tcp firewall-cmd --permanent --add-port=2379/tcp firewall-cmd --permanent --add-port=2380/tcp firewall-cmd --permanent --add-port=6443/tcp firewall-cmd --permanent --add-port=8472/udp firewall-cmd --permanent --add-port=9099/tcp firewall-cmd --permanent --add-port=10250/tcp firewall-cmd --permanent --add-port=10251/tcp firewall-cmd --permanent --add-port=10252/tcp firewall-cmd --permanent --add-port=10254/tcp firewall-cmd --permanent --add-port=10255/tcp firewall-cmd --permanent --add-port=30000-32767/tcp firewall-cmd --permanent --add-port=30000-32767/udp firewall-cmd --permanent --add-masquerade firewall-cmd --reload ``` 💡*마스터 노드에서만 진행* 쿠버네티스 클러스터 생성 ```bash kubeadm init --apiserver-advertise-address=192.168.1.10 --pod-network-cidr=10.244.0.0/16 # K8s control plane 생성 완료 화면 Your Kubernetes control-plane has initialized successfully! To start using your cluster, you need to run the following as a regular user: 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.1.10:6443 --token 172vji.r0u77jcmcnccm6no \ --discovery-token-ca-cert-hash sha256:72b9648c647f724ab52471847cb06c47b23097375f2e67633b745fc69db16e8d ``` kubectl 활성화 위해 admin.conf 복사 작업 ```bash mkdir -p $HOME/.kube cp -i /etc/kubernetes/admin.conf $HOME/.kube/config chown $(id -u):$(id -g) $HOME/.kube/config ``` 네트워크 플러그인 다운로드 ([Flannel](http://138.2.116.150/books/kubernetes/page/8d7d8)) \[ CNI(Container Network Interface)는 컨테이너를 위한 네트워킹을 제어할 수 있는 플러그인을 만들기 위한 표준이라고 한다. 간단하게 설명 하면 CNI플러그인을 쿠버네티스 클러스터에 설치하여 서로 다른 노드에서 실행되는 컨테이너 간의 네트워킹을 할 수 있다 \] 더 자세한 내용은 [링크](https://tommypagy.tistory.com/390) 참고 ```bash curl -O -L https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml ``` kube-flannel.yml 파일 안에 --iface=(가상 인터페이스 이름) 지정 ```bash vi kube-flannel.yml args: - --ip-masq - --kube-subnet-mgr - --iface=ens160 ``` 네트워크 플러그인 YAML 파일 적용 후 kubelet 재시작 ```bash kubectl apply -f kube-flannel.yml systemctl restart kubelet ``` 💡 *Worker Node에서 작업* Master Node에서 받은 Discovery Token 값을 join 명령어로 통해 Master과 Worker 노드 묶기 ```bash kubeadm join 192.168.1.10:6443 --token 172vji.r0u77jcmcnccm6no \ --discovery-token-ca-cert-hash sha256:72b9648c647f724ab52471847cb06c47b23097375f2e67633b745fc69db16e8d This node has joined the cluster: * Certificate signing request was sent to apiserver and a response was received. * The Kubelet was informed of the new secure connection details. Run 'kubectl get nodes' on the control-plane to see this node join the cluster. ``` Join 작업이 완료 후 마스터 노드에서 쿠버네티스 클러스터 확인 ```bash kubectl get nodes NAME STATUS ROLES AGE VERSION master Ready master 107m v1.19.16 node-1 Ready**Control 노드 에서 작업**
전체 패키지 업데이트 및 파이썬 그리고 pip을 설치 한다 ```bash sudo apt update # 깃을 사용 하여 kubespray 코드를 가져와야 한다 sudo apt install git python3 python3-pip -y ``` 파이썬 버전과 pip 버전을 확인 한다 ```bash python3 -V python 3.10.6 pip -V pip 22.0.2 from /usr/lib/python3/dist-packages/pip (python 3.10) ```pip을 통해 Ansible 과 Jinja 패키지를 설치 할 수 있다. pip을 통해 설치하는 것이 권장되는 이유는 pip가 파이썬의 패키지 설치 도구이며, Ansible과 Jinja 모두 파이썬 기반 도구이기 때문이다
`git clone` 명령어를 통해 kubespray 깃 허브 소스 코드를 내려 받는다 ```bash git clone https://github.com/kubernetes-incubator/kubespray.git ``` kubespray의 깃 허브 소스 코드를 내려 받으면 이미 필요한 요소들을 쉽게 설치 할 수 있는 `requirements.txt` 파일이 존재 한다 ```bash # kubespray 디렉터로 이동 cd kubespray # 파일 안에 있는 모든 항목들을 pip을 사용 하여 설치 한다 pip install -r requirements.txt ```참고로 requirements.txt 파일 안에 존재하는 항목들은
[](http://138.2.116.150/uploads/images/gallery/2023-05/XSHimage.png) 설치가 무사히 완료 된 후 아래 명렁어를 사용 했을때 `ansible` 버전을 확인 할 수 있다 ``` ansible --version ansible [core 2.12.5] config file = /home/ansible/kubespray/ansible.cfg configured module search path = ['/home/ansible/kubespray/library'] ansible python module location = /home/ansible/.local/lib/python3.10/site-packages/ansible ansible collection location = /home/ansible/.ansible/collections:/usr/share/ansible/collections executable location = /home/ansible/.local/bin/ansible python version = 3.10.6 (main, Mar 10 2023, 10:55:28) [GCC 11.3.0] jinja version = 3.1.2 libyaml = True ```-bash: ansible: command not found?
만약에 설치가 완료 되었지만 ansible 명령어를 찾을 수 없다고 나온다면, Ansible이 설치된 디렉터리가 PATH 환경 변수에 포함되지 않았다는 거다. Ansible 설치 경로는 여기서 확인 ```bash ls ~/.local/bin/ __pycache__ ansible-config ansible-console ansible-galaxy ansible-playbook ansible-test jp.py pbr ansible ansible-connection ansible-doc ansible-inventory ansible-pull ansible-vault netaddr ```pip을 사용하여 Ansible을 설치하면 기본적으로 ~/.local/bin 디렉토리에 설치 된다. Python packaging의 일반적인 관례로, 사용자 별로 패키지를 격리하고 개별적으로 관리하기 위해 사용자의 로컬 디렉토리에 설치되는 것이다
Ansible의 설치 경로를 `~/.bashrc`파일에 추가 해주면 해결 된다~/.bashrc는 Bash Shell 환경을 자신의 선호에 맞게 구성할 수 있는 파일
```bash vi ~/.bashrc # 마지막 줄에 추가 export PATH=$PATH:/home/ansible/.local/bin # 저장 후 나가기 :wq # bashrc파일의 변경 내용을 업데이트 source ~/.bashrc ``` ansible이 정상적으로 작동 하는지 확인 후 호스트 파일을 만들기 위해 아래 명령어들을 실행 한다 ```bash # inventory/sample 디렉토리의 내용을 inventory/mycluster 디렉토리로 복사한다 # -rfp 옵션을 사용하여 재귀적으로 모든 하위 디렉터리 포함 복사하여 원본 파일의 속성들도 보존 한다 cp -rfp inventory/sample inventory/mycluster # IPS라는 배열 변수를 선언하고, IP 주소 목록을 할당한다 declare -a IPS=(192.168.1.150 192.168.1.160 192.168.1.170) # inventory.py라는 파이썬 스크립트를 실행한다 # 스크립트는 CONFIG_FILE 환경 변수가 설정되어야 하므로, hosts.yaml로 설정 한다 CONFIG_FILE=inventory/mycluster/hosts.yml python3 contrib/inventory_builder/inventory.py ${IPS[@]} # inventory 디렉토리의 주어진 IP 주소와 디렉토리 구조를 사용하여 인벤토리 파일(hosts.yaml)을 생성하는 설정 프로세스 ``` 설정 완료 후 `hosts.yaml` 파일안에 내용을 아래와 같이 수정 한다 ```bash vi inventory/mycluster/hosts.yml all: hosts: node1: ansible_host: 192.168.1.150 # 작업을 실행하기 위해 대상 노드에 연결할 때 사용하는 IP 주소 또는 호스트 이름을 지정하는 필드 ip: 192.168.1.150 access_ip: 192.168.1.150 node2: ansible_host: 192.168.1.160 ip: 192.168.1.160 access_ip: 192.168.1.160 node3: ansible_host: 192.168.1.170 ip: 192.168.1.170 access_ip: 192.168.1.170 children: kube_control_plane: # 마스터 노드 지정 하는 곳 hosts: node1: kube_node: # 워커 노드 지정 하는 곳 hosts: node2: node3: etcd: # etcd 노드 지정 하는 곳 hosts: node1: k8s_cluster: children: kube_control_plane: kube_node: calico_rr: hosts: {} ``` 그 외 쿠버네티스 클러스터 관련 검토 및 수정 할 수 있는 설정 파일은: ```bash vi inventory/mycluster/group_vars/k8s_cluster/k8s-cluster.yml # 파일 내용이 너무 길어서 중요한 요소들만 지정 하였다 # 20번째 줄 kube_version: v1.26.5 # 70번째 줄 kube_network_plugin: calico # 76번째 줄 kube_service_addresses: 10.233.0.0/18 # 81번째 줄 kube_pods_subnet: 10.233.64.0/18 # 160번째 줄 cluster_name: cluster.local # 229번째 줄 container_manager: containerd ``` 마지막으로 추가적인 클러스터 요소들을 클러스터 설치 시 같이 활성화 시킬 수 있게 설정 할 수 있는 파일: ```bash vi inventory/mycluster/group_vars/k8s_cluster/addons.yml # 파일 내용이 너무 길어서 중요한 요소들만 지정 하였다 # 4번째 줄 dashboard_enabled: false # 7번째 줄 helm_enabled: false # 10번째 줄 registry_enabled: false # 16번째 줄 metrics_server_enabled: false # 100번째 줄 ingress_nginx_enabled: false # 177번째 줄 metallb_enabled: false # 246번째 줄 argocd_enabled: false ```**만약에 Control 노드에서 root 유저로 지금 까지 진행 하였다면 아래 호스트 노드들에서의 작업이 불필요하다**
**호스트 노드들에서 작업**
현재 까지의 Control노드의 설정들은 'ansible'유저 이름로 진행 되었다. 그렇기 때문에 Ansible 명령어를 실행 하려면 호스트 노드들도 동일한 이름의 유저가 존재 해야 한다. 각각 호스트 노드에 먼저 새로운 'ansible' 유저 생성 후 `sudoers.d` 파일에 등록 시켜 줘야 한다. ```bash # 모든 호스트노드에서 동일하게 설정 useradd ansible passwd ansible New Password: # root 사용자를 위해 sudoers파일에 ansible 사용자가 비밀번호를 입력 하지 않고도 root 권한으로 모든 명령어를 실행할 수 있게 해 준다 echo "ansible ALL=(ALL) NOPASSWD:ALL" | sudo tee /etc/sudoers.d/root ```**Control노드에서 작업**
이제 Control 노드가 호스트 노드들 (마스터 와 워커 노드)의 설정들을 자유롭게 할 수 있게 접근권한을 부여 하는 설정을 해야 한다 첫째로 Control노드에서 SSH 접속을 위해 SSH 키를 발행 한다 ```bash ssh-keygen ``` SSH키를 발급 받은 후 그 Public키를 모든 호스트 노드들에게 전달 해야된다. ```bash # non-root 유저(ansible 유저)로 진행 하였을 경우 ssh-copy-id ansible@192.168.1.150 ssh-copy-id ansible@192.168.1.160 ssh-copy-id ansible@192.168.1.170 # root 유저로 진행 하였을 경우 ssh-copy-id root@192.168.1.150 ssh-copy-id root@192.168.1.160 ssh-copy-id root@192.168.1.170 ``` 마지막으로 Kubespray 실행 하기 전에 Firewall을 비활성화 그리고 IPv4 포워딩을 활성화 해주는 작업을 진행 한다. 쿠버네티스는 클러스터의 구성요소간 통신에 다양한 네트워크 포트를 사용 한다. 방화벽을 사용하지 않도록 설정하면 클러스터 노드 간의 원활한 통신을 위해 필요한 포트가 열려 있고 차단되지 않도록 할 수 있다. 그리고 IPv4 Forwarding을 사용 하면 쿠버네티스 클러스터에서는 노드, 포드 및 서비스간 서로 다른 네트워크 인터페이스 또는 서브넷 간에 네트워크 트래픽을 라우팅할 수 있다. ```bash # Kubespray 디렉토리로 이동 cd kubespray # ansible 명령어를 통해 모든 호스트들의 firewalld 서비스 중단 ansible all -i inventory/mycluster/hosts.yml -m shell -a "sudo systemctl stop firewalld && sudo systemctl disable firewalld" # IPv4 포트 forwarding 기능 활성화 ansible all -i inventory/mycluster/hosts.yml -m shell -a "echo 'net.ipv4.ip_forward=1' | sudo tee -a /etc/sysctl.conf" # Swap memory off 설정 ansible all -i inventory/mycluster/hosts.yml -m shell -a "sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab && sudo swapoff -a" ``` 모든 준비 단계들과 요소들이 끝났다. 이제 Kubespray를 통해 Kubernetes 클러스터를 생성 하면 된다 ```bash ansible-playbook -i inventory/mycluster/hosts.yml --become --become-user=root cluster.yml ``` 이 한 명령어로 쿠버네티스 클러스터가 생성 된다 (네트워크 속도와 하드웨어 장비의 리소스의 따라 20 ~ 40 분 사이 시간 소요) 모든 설정들이 완료 되면 이런 화면이 보일 것이다 [](http://138.2.116.150/uploads/images/gallery/2023-05/6Jlimage.png) 마스터 노드에서 확인 [](http://138.2.116.150/uploads/images/gallery/2023-05/T5Timage.png)Worker노드들의 경우 기본적으로 특정 역할이 할당되지 않으므로 "<none>"으로 표시 된다. "Ready" 상태인 한, Worker 노드들은 올바르게 동작 한다. 추가로 <none> Label을 수동으로 바꿀 수 있는 명령어가 있다 `kubectl label node <노드 이름> node-role.kubernetes.io/worker=worker`
변경 후: [](http://138.2.116.150/uploads/images/gallery/2023-05/FPNimage.png) # 웹 페이지 배포 쿠버네티스 클러스터는 이미 생성 되어 있는 관계로 바로 간단한 웹 페이지를 쿠버네티스 클러스터에 배포 및 테스트 해 보겠다. 제일 먼저 준비 해야 될 것은 물론 배포 해야 될 웹 페이지다. 일단 기존에 테스트 용으로 만든 장고 웹 사이트를 배포 해 보겠다. 먼저, 웹 애플리케이션을 K8s 클러스터에 배포하기 위해서는 애플리케이션의 컨테이너 이미지를 준비해야 한다. 일반적으로 Docker와 같은 컨테이너 플랫폼을 사용하여 애플리케이션을 컨테이너화 하고 이미지를 빌드 한다. 빌드 된 이미지는 컨테이너 레지스트리에 저장되어 클러스터 내에서 사용할 수 있게 된다. 웹 사이트의 소스 코드를 받은 후 Dockerfile을 추가 하였다. Dockerfile은 도커 이미지를 생성하기 위한 설정 파일이다. 이 파일에는 도커 이미지를 구성하는데 필요한 모든 단계와 명령어가 포함된다. Dockerfile을 작성하여 도커 이미지를 생성하면, 도커를 사용하여 해당 이미지를 기반으로 컨테이너를 실행할 수 있다. ```bash # 파이썬 이미지 받기 FROM python:3.11 # 환경 변수 지정 ENV PYTHONUNBUFFERED 1 ENV PYTHONDONTWRITEBYTECODE 1 # 워킹 디렉터리 지정 WORKDIR /app # 의존성 설치 COPY requirements.txt . RUN pip install -r requirements.txt # 컨테이너 안에 소스 코드 복사 COPY . . # 장고 사이트가 실행 되기 위해 포트 열기 EXPOSE 8000 # 웹 사이트가 실행 하기 위해 초기 명령어 CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"] ``` 마지막으로 이 Dockerfile을 빌드 및 Docker 레지스트리에 Push 해준다 ```bash # Dockerfile을 사용하여 커스텀 이미지 생성 docker build -t django:v2 ./ # 생성된 이미지 태그 달기 docker tag django:v1 waji97/django:v2 # 태그 된 이미지 레지스트리에 업로드 docker push waji97/django:v2 ``` 이제 배포를 위해 매니페스트 YAML 파일을 작성 해야 된다. 파일 안에 먼저 Deployment 리소스를 사용하여 애플리케이션의 Replica을 지정 하고 어떤 이미지를 사용 하여 파드를 실행 시킬지 지정 한다. 그 후 Service 리소스 중 Nodeport 서비스를 사용하여 배포 된 웹 사이트를 접근 할 수 있게 포트 번호를 맞춰 준다. ```bash # 매니페스트 파일 작성 및 적용을 위해 같은 경로 이동 mkdir myapp cd myapp # 매니페스트 파일 생성 vi my-app.yaml apiVersion: apps/v1 kind: Deployment metadata: name: my-app spec: replicas: 3 selector: matchLabels: app: my-app template: metadata: labels: app: my-app spec: containers: - name: my-app image: waji97/django:v2 # 방금 업로드한 웹 사이트 이미지 ports: - containerPort: 8000 --- apiVersion: v1 kind: Service metadata: name: my-app-service spec: type: NodePort selector: app: my-app ports: - protocol: TCP port: 80 targetPort: 8000 ``` 이렇게 YAML파일 지정 후 이 파일을 적용 시킨다 ```bash kubectl apply -f my-app.yaml deployment.apps/my-app created service/my-app-service created ``` 적용 후 생성 되는 Pod, Deployment 그리고 Service를 확인 할 수 있다 ```bash # Pod 확인 kubectl get pods NAME READY STATUS RESTARTS AGE my-app-74dd96c584-9plfb 1/1 Running 0 30s my-app-74dd96c584-lf97s 1/1 Running 0 30s my-app-74dd96c584-tvl2n 1/1 Running 0 30s # Service 확인 kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1etcd는 쿠버네티스 클러스터의 상태 정보를 안전하게 저장하기 위한 신뢰성 있는 분산형 키-값 저장소
이미 마스터 노드에 포함 되어 있는 컴포넌트를 따로 분리 하여 별도에 노드에 배치하여 제일 좋은 점은 보안이라고 볼 수 있다. 그 외에도 몇 가지 장점을 표현 한다면: - **가용성 향상:** etcd를 마스터 노드와 분리하여 외부에 배치하면 신뢰성과 가용성을 향상시킬 수 있다. 마스터 노드에 장애가 발생할 경우에도 etcd 클러스터가 별도로 유지되므로 클러스터의 상태 정보를 안전하게 유지할 수 있다. - **확장성:** 외부 etcd 클러스터를 사용하면 쿠버네티스 클러스터를 확장할 때 좀 더 유연성을 가질 수 있다. etcd 클러스터는 더 많은 리소스를 할당하여 고가용성 및 높은 처리량을 제공할 수 있으며, 대규모 클러스터 운영에 필수적이다. - **유지 보수 및 업그레이드 용이성:** etcd를 외부로 분리하면 클러스터의 유지 보수 및 업그레이드 작업이 간편해진다. 마스터 노드의 유지 보수 작업이 etcd 클러스터에 영향을 미치지 않고 수행될 수 있다. - **분리된 관리 및 보안:** etcd를 외부에 배치하면 마스터 노드에서 실행되는 다른 구성 요소와 분리된 관리와 보안을 제공할 수 있다. etcd 클러스터는 전용 네트워크 또는 보안 그룹을 통해 격리되어 안전한 환경에서 운영될 수 있다. Etcd 컴포넌트를 마스터 노드에서 분리 하여 배치 하는 작업은 클러스터 생성시 설정을 하면 된다. 이미 Kubespray및 Kubeadm으로 클러스터를 생성 해 보았지만, etcd노드를 분리 하여 해 보지는 않았다. 그래서 이번에는 Kubespray를 통해 쿠버네티스 클러스터를 아래와 같은 구성으로 생성 해 보았다 - Control Node (Ubuntu 22.04): 192.168.1.90 - Master Node (CentOS 7): 192.168.1.150 - Worker Node (CentOS 7): 192.168.160 - ETCD Node (CentOS 7): 192.168.1.170 - ETCD Node 2 (CentOS 7): 192.168.1.180 - ETCD Node 3 (CentOS 7): 192.168.1.190 #### **Kubespray를 통해 클러스터 생성** Kubespray를 통해 쿠버네티스 클러스터 생성 하는 방법은 이미 [여기](http://138.2.116.150/books/kubernetes/page/kubespray)에 정리 해 놓았다. 설정 방법과 진행은 다 동일 하지만 다른 점은 `hosts.yml` 파일 속 추가 된 내용이다. ```bash vi inventory/mycluster/hosts.yml all: hosts: node1: ansible_host: 192.168.1.150 # 작업을 실행하기 위해 대상 노드에 연결할 때 사용하는 IP 주소 또는 호스트 이름을 지정하는 필드 ip: 192.168.1.150 access_ip: 192.168.1.150 node2: ansible_host: 192.168.1.160 ip: 192.168.1.160 access_ip: 192.168.1.160 node3: ansible_host: 192.168.1.170 ip: 192.168.1.170 access_ip: 192.168.1.170 node4: ansible_host: 192.168.1.180 ip: 192.168.1.180 access_ip: 192.168.1.180 node5: ansible_host: 192.168.1.190 ip: 192.168.1.190 access_ip: 192.168.1.190 children: kube_control_plane: # 마스터 노드 지정 하는 곳 hosts: node1: node2: node3: kube_node: # 워커 노드 지정 하는 곳 hosts: node4: etcd: # etcd 노드 지정 하는 곳 hosts: node5: k8s_cluster: children: kube_control_plane: kube_node: calico_rr: hosts: {} ``` 이렇게 `hosts.yml` 파일 수정 후 Kubespray Ansible Playbook을 실행 한다. 아무 문제 없이 완료 되면 결과를 확인 할 수 있다. [](http://138.2.116.150/uploads/images/gallery/2023-06/XhYimage.png) 이제 마스터 노드 쪽에서 클러스터 생성 결과를 확인 하기 위해: it is normal that when you use the `kubectl get nodes` command from your master node, you will not see the etcd nodes included in the output. The `kubectl get nodes` command provides information about the worker nodes in your cluster, not the etcd nodes. Etcd nodes are not considered as part of the worker node pool and are typically not included in the output of the `kubectl get nodes` command. Etcd operates as a separate distributed key-value store that stores the cluster's state and configuration information. It is responsible for providing data persistence and coordination among the control plane components. # Helm 패키지 매니저 Helm은 쿠버네티스 애플리케이션의 생성, 패키징, 구성 및 배포를 자동화하는 도구이다. 구성 파일을 하나로 결합하여 재 사용 가능한 패키지로 만들어 준다. Microservice 아키텍처에서 애플리케이션이 커짐에 따라 더 많은 microservice를 생성하는 경우 관리가 점점 어려워 진다. 쿠버네티스는 오픈 소스 컨테이너 오케스트레이션 기술로, 여러 microservice를 하나의 배포로 그룹화하여 프로세스를 단순화 한다. 그러나 개발 수명 주기 동안의 쿠버네티스 애플리케이션 관리는 버전 관리, 리소스 할당, 업데이트 및 롤 백과 같은 도전 과제를 동반 한다. Helm은 이러한 문제에 대한 가장 접근 가능한 해결책 중 하나를 제공하여 배포를 더 일관적이고 반복 가능하며 신뢰할 수 있게 만들어 주었다. 쿠버네티스 관리의 단순화를 위한 Helm 컨테이너는 애플리케이션과 해당 종속성을 단일 이미지 파일로 묶는 경량 소프트웨어 구성 요소이다. 컨테이너는 다양한 플랫폼 간에 이식할 수 있으므로 애플리케이션 시작 시간이 빨라지고 쉬운 확장이 가능 하다. 쿠버네티스는 YAML 구성 파일을 사용하여 배포한다. 그렇기 때문에 자주 업데이트되는 복잡한 배포의 경우 이러한 파일의 다양한 버전을 추적하는 것은 어려울 수 있다. Helm은 단일 배포 YAML 파일에 버전 정보를 유지하는 편리한 도구이다. Helm은 Helm 차트 라는 쿠버네티스 클러스터에 애플리케이션을 배포하기 위해 필요한 모든 리소스를 포함하는 패키지 파일이다. 배포, 서비스, Secrets 및 ConfigMap에 대한 YAML 구성 파일을 포함하여 애플리케이션의 원하는 상태를 정의한다. Helm 차트는 YAML 파일과 템플릿을 함께 패키징하여 매개 변수화된 값을 기반으로 추가 구성 파일을 생성할 수 있다. 이를 통해 환경에 맞게 구성 파일을 사용자 정의하고 다양한 배포에 재사용 가능한 구성을 만들 수 있다. 또한 각 Helm 차트는 독립적으로 버전 관리되므로 다른 구성을 가진 애플리케이션의 여러 버전을 쉽게 유지할 수 있다. [](http://138.2.116.150/uploads/images/gallery/2023-06/VUZimage.png) Helm 아키텍처는 버전 2와 3 사이에서 크게 개선되었다. 버전 2는 Tiller 서버를 사용하여 Helm 클라이언트와 Kubernetes API 서버 간의 중개를 담당했다. Helm을 클러스터에 설치할 때 Tiller가 필요하며 보안 이슈가 있을 수 있습니다. 그러나 Helm 3에서는 Tiller가 제거되었고 Helm 클라이언트가 직접 Kubernetes API 서버와 상호 작용하도록 변경되었습니다. [](http://138.2.116.150/uploads/images/gallery/2023-06/apDimage.png) Version 3 [](http://138.2.116.150/uploads/images/gallery/2023-06/NADimage.png) 요약하자면, Helm은 쿠버네티스 애플리케이션 관리를 단순화하는 도구입니다. Helm 차트를 사용하여 애플리케이션의 배포, 구성 및 관리를 쉽게 할 수 있습니다. Helm은 YAML 파일로 구성된 리소스를 패키지로 묶어 재사용 가능한 차트를 생성하며, Helm 클라이언트와 라이브러리를 통해 쿠버네티스 클러스터와 상호 작용합니다. ##### **Helm 설치** Helm 설치하기 전, Git 먼저 설치 ```bash # Red Hat 계열 dnf install git # 우분투 계열 sudo apt install git ``` Helm 설치 하는 방법은 간단하다. 설치 방법들은 공식 Installation 페이지에서 확인 가능. [Helm Installation 바로가기](https://helm.sh/docs/intro/install/) 많은 설치 방법들 중에 스크립트로 설치하는 방법으로 진행 하였다 ```bash # 설치 스크립트를 가져온 다음 로컬에서 실행 한다 curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 # 스크립트 실행하기 위해 권한 수정 chmod 700 get_helm.sh # 스크립트 실행 ./get_helm.sh Downloading https://get.helm.sh/helm-v3.12.0-linux-amd64.tar.gz Verifying checksum... Done. Preparing to install helm into /usr/local/bin helm installed into /usr/local/bin/helm # 버전 확인 helm version version.BuildInfo{Version:"v3.12.0", GitCommit:"c9f554d75773799f72ceef38c51210f1842a1dea", GitTreeState:"clean", GoVersion:"go1.20.3"} ``` # 배포 전략 및 설정 ### **배포 전략** 쿠버네티스에서 애플리케이션을 배포할 때, 다양한 배포 전략을 고려하는 것이 중요하다. 이를 통해 어플리케이션의 안정성, 확장성, 사용자 경험 등을 최적화할 수 있다. 아래에서 가장 일반적으로 사용되는 배포 전략 몇 가지를 살펴보겠다. #### **1. 롤링 업데이트 (Rolling Update)** 롤링 업데이트는 새로운 버전의 애플리케이션을 점진적으로 배포하는 전략이다. 이전 버전의 파드들을 점차적으로 새로운 버전으로 교체하면서 서비스의 가용성을 유지 한다. 롤링 업데이트는 다음과 같은 단계로 진행된다. 1. 새로운 버전의 파드를 클러스터에 추가한다. 2. 서비스의 로드밸런서를 통해 새로운 파드들에 트래픽을 점진적으로 라우팅 한다. 3. 이전 버전의 파드들을 하나씩 제거하면서 새로운 버전의 파드로 교체 한다. 롤링 업데이트는 배포 과정 중에 중단 없이 서비스를 계속 제공할 수 있으며, 문제가 발생한 경우 롤백도 쉽게 수행할 수 있다. #### **2. 블루-그린 배포 (Blue-Green Deployment)** 블루-그린 배포는 새로운 버전의 애플리케이션을 기존 버전과 완전히 분리된 환경에서 배포하고, 완전히 검증된 후에 트래픽을 전환하는 전략이다. 다음은 블루-그린 배포의 단계다: 1. 블루 환경에 현재 운영 중인 애플리케이션 버전을 배포한다. 2. 그린 환경에 새로운 버전의 애플리케이션을 배포하고 테스트 한다. 3. 테스트가 성공적으로 완료되면 로드밸런서를 이용하여 트래픽을 블루에서 그린으로 전환 한다. 4. 그린 환경에서 정상적으로 동작하는지 확인한 후, 필요에 따라 블루 환경을 제거 한다. 블루-그린 배포는 롤백 시에도 용이하며, 사용자에게 거의 무감각한 배포를 제공할 수 있다. 하지만 추가 인프라 자원이 필요하며, 배포 시간도 더 오래 걸릴 수 있다. #### **3. 카나리아 배포 (Canary Deployment)** 카나리아 배포는 새로운 버전의 애플리케이션을 일부 사용자 또는 트래픽의 일부에게 노출시켜서 테스트하고, 성능 및 안정성을 확인한 후에 전체로 확장하는 전략 이다. 아래는 카나리아 배포의 주요 단계들이다: 1. 새로운 버전의 애플리케이션을 일부 파드로 배포 한다. 2. 로드밸런서를 통해 일부 사용자 또는 일부 트래픽을 새로운 버전의 파드로 라우팅 한다. 3. 새로운 버전의 파드들에서 성능 및 안정성을 모니터링하고 평가 한다. 4. 테스트가 성공적으로 완료되면 나머지 파드들에 새로운 버전을 배포하고, 모든 트래픽을 새로운 버전으로 전환 한다. 카나리아 배포는 배포 전략의 일부분을 선택적으로 테스트할 수 있는 유연성을 제공하며, 더 많은 피드백과 데이터를 수집할 수 있다. 그러나 추가적인 관리 비용이 발생하며, 배포 프로세스가 복잡해질 수 있다. ### **배포 설정** 쿠버네티스 에서 애플리케이션을 배포하기 위해서는 몇 가지 기본 설정이 필요하다. 아래는 일반적으로 사용되는 배포 설정의 예시들이다. #### **1. Pod 정의** 애플리케이션의 실행을 담당하는 파드를 정의해야 한다. 이를 위해 Pod의 설정 파일을 작성하고, 컨테이너 이미지, 리소스 요구사항, 환경 변수, 포트 포워딩 등을 설정해야 한다. #### **2. 서비스 정의** 애플리케이션에 접근하기 위한 서비스를 정의해야 한다. 서비스는 파드 집합에 대한 로드밸런싱을 처리하고, 네트워크 연결을 제공한다. 클러스터 내부 또는 외부에서 접근 가능한 엔드포인트를 설정할 수 있다. #### **3. 볼륨 및 볼륨 클레임 정의** 애플리케이션에서 사용하는 데이터를 보존하기 위해 볼륨과 볼륨 클레임을 정의해야 한다. 이를 통해 데이터의 지속성과 공유를 보장할 수 있다. #### **4. 배포 및 스케일링 설정** 애플리케이션의 배포 전략을 선택하고 설정해야 한다. 롤링 업데이트, 블루-그린 배포, 카나리아 배포 등의 전략을 적용할 수 있으며, 파드 의 수를 조정하여 스케일링할 수도 있다. #### **5. 모니터링 및 로깅 설정** 애플리케이션의 모니터링과 로깅 을 위한 설정을 추가해야 한다. 이를 통해 애플리케이션의 상태를 추적하고, 문제를 진단하고 해결할 수 있다. 예를 들어 Prometheus, Grafana, ELK 스택 등의 도구를 활용할 수 있다. #### **6. 보안 설정** 애플리케이션에 대한 보안 설정을 추가해야 한다. 인증, 권한 부여, 네트워크 정책 등을 구성하여 애플리케이션의 안전성을 강화할 수 있다.이는 일반적인 설정 예시일 뿐이며, 실제 애플리케이션의 요구 사항에 따라 설정이 달라질 수 있다
# 노드 관리 쿠버네티스에서 노드는 클러스터의 실행 환경으로서 컨테이너화된 애플리케이션을 실행하는 물리적인 또는 가상의 서버이다. 노드 관리는 클러스터의 성능, 안정성 및 가용성을 유지하는 데 중요한 역할을 한다. ##### **1. 노드 추가 및 제거** 쿠버네티스에서는 클러스터에 노드를 추가하거나 제거할 수 있다. 새로운 노드를 추가하면 클러스터의 자원 용량이 증가하고 애플리케이션의 수평 확장이 가능해진다. 노드를 제거할 때는 해당 노드에서 실행 중인 파드를 안전하게 이동시키고 클러스터의 자원 사용을 최적화해야 한다. ##### **2. 노드 상태 모니터링** 쿠버네티스는 노드의 상태를 지속적으로 모니터링하여 노드의 가용성을 확인 한다. 노드가 정상 상태인지 여부를 확인하고, 필요한 경우 노드의 비정상적인 동작을 감지하고 조치 한다. 이를 통해 클러스터는 노드 장애에 대응하고 애플리케이션의 지속적인 가용성을 유지할 수 있다. ##### **3. 노드 레이블링** 쿠버네티스에서는 노드에 레이블을 지정하여 특정 속성이나 기능을 가진 노드를 식별할 수 있다. 노드 레이블은 노드 선택, 파드 스케줄링, 네트워크 정책 등과 같은 다양한 용도로 활용될 수 있다. 이를 통해 애플리케이션을 특정 노드에 배치하거나 특정 노드에서 실행되는 파드 간의 통신을 제어할 수 있다. ##### **4. 노드 업그레이드** 쿠버네티스에서는 노드의 운영체제, 컨테이너 런타임, 커널 등을 업그레이드할 수 있다. 노드 업그레이드는 애플리케이션의 가용성을 유지하기 위해 롤링 업데이트 전략을 사용하여 점진적으로 업그레이드를 수행 한다. 이를 통해 클러스터의 노드를 최신 버전으로 유지하고 보안 패치를 적용할 수 있다. //Cron과 Drain? https://arisu1000.tistory.com/27845 # 리소스 관리 1. 라벨링과 애노테이션 # 모니터링과 로깅 1. 메트릭 수집 2. 로그 관리 # 스케일링 및 롤링 업데이트 쿠버네티스는 애플리케이션의 수평 스케일링과 롤링 업데이트를 지원하여 애플리케이션의 성능 향상과 지속적인 개선을 가능하게 한다. 이를 통해 애플리케이션을 더욱 확장 가능하고 안정적으로 운영할 수 있다. ##### **1. 수평 스케일링** 쿠버네티스는 파드의 수를 동적으로 조정하여 애플리케이션의 수평 스케일링을 지원 한다. 파드 수를 늘리면 애플리케이션의 처리량과 부하 분산이 증가하며, 반대로 파드 수를 줄이면 자원 사용량을 최적화할 수 있다. 이를 통해 애플리케이션의 성능을 향상시킬 수 있다. ##### **2. 롤링 업데이트** 롤링 업데이트는 애플리케이션의 새 버전을 점진적으로 배포하는 과정을 말한다. Kubernetes는 롤링 업데이트를 통해 애플리케이션의 가용성을 유지하면서 새로운 버전으로의 전환을 원활하게 처리한다. 롤링 업데이트는 애플리케이션의 가용성을 유지하면서 시스템의 안정성을 보장한다. ##### **3. 블루-그린 배포** 블루-그린 배포는 새로운 버전의 애플리케이션을 별도의 환경에 배포한 후, 기존 버전과 새 버전 사이에서 전환하는 전략이다. 쿠버네티스는 블루-그린 배포를 지원하며, 서비스의 라우팅 설정을 변경하여 전환을 수행한다. 이를 통해 애플리케이션의 변경 사항을 테스트하고 문제가 발생하지 않으면 전환을 완료할 수 있다. # 클러스터 업그레이드 # kubectl 자동 완성 (수정 중) 쿠버네티스의 자동 완성 기능은 긴 쿠버네티스 리소스 이름을 자동 완성 시킬때 꽤 유용 하다. 자세한 정보는 [k8s 자동완성 설정](https://kubernetes.io/ko/docs/tasks/tools/included/optional-kubectl-configs-bash-linux/) 먼저 type \_init\_completion 명령어를 사용하여 이미 설정이 되어 있는지 부터 확인 안되어 있는 경우: type \_init\_completion -bash: type: \_init\_completion: not found 설정 하려면: source /usr/share/bash-completion/bash\_completion \[root@main ~\]# exec bash만약에 위 명령어 사용 시 'Not Found' 애러 발생 하면, 먼저 'bash-completion'툴을 설치 하고 다시 진행 해야 한다
RHEL 계열: dnf install bash-completion Ubuntu 계열: apt install bash-completion
설정 후 type \_init\_completion \_init\_completion is a function \_init\_completion () { local exclude= flag outx errx inx OPTIND=1; while getopts "n:e:o:i:s" flag "$@"; do case $flag in n) exclude+=$OPTARG ;; e) errx=$OPTARG ;; o) outx=$OPTARG ;; i) inx=$OPTARG ;; s) split=false; exclude+== ;; esac; done; COMPREPLY=(); local redir="@(?(\[0-9\])<|?(\[0-9&\])>?(>)|>&)"; \_get\_comp\_words\_by\_ref -n "$exclude<>&" cur prev words cword; \_variables && return 1; if \[\[ $cur == $redir\* || $prev == $redir \]\]; then local xspec; case $cur in 2'>'\*) xspec=$errx ;; \*'>'\*) xspec=$outx ;; \*'<'\*) xspec=$inx ;; \*) case $prev in 2'>'\*) xspec=$errx ;; \*'>'\*) xspec=$outx ;; \*'<'\*) xspec=$inx ;; esac ;; esac; cur="${cur##$redir}"; \_filedir $xspec; return 1; fi; local i skip; for ((i=1; i < ${#words\[@\]}; 1)) do if \[\[ ${words\[i\]} == $redir\* \]\]; then \[\[ ${words\[i\]} == $redir \]\] && skip=2 || skip=1; words=("${words\[@\]:0:i}" "${words\[@\]:i+skip}"); \[\[ $i -le $cword \]\] && cword=$(( cword - skip )); else i=$(( ++i )); fi; done; \[\[ $cword -eq 0 \]\] && return 1; prev=${words\[cword-1\]}; \[\[ -n ${split-} \]\] && \_split\_longopt && split=true; return 0 } 그 후 쿠버네티스 상 자동 완성 설정. 이제 kubectl 자동 완성 스크립트가 모든 셸 세션에서 제공되도록 해야 한다. 이를 수행할 수 있는 두 가지 방법이 있다. 현재 사용자에게 만 설정 echo 'source <(kubectl completion bash)' >>~/.bashrc 모든 사용자에게 설정 ubectl completion bash | sudo tee /etc/bash\_completion.d/kubectl > /dev/null \[root@node1 ~\]# exec bash \[root@node1 ~\]# kubectl get ns default kube-node-lease kube-public kube-system \[root@node1 ~\]# kubectl get ns // 미완성 # Bastion에서 Kubectl 쓰기 (수정 중) References: Installting Kubectl: [https://kubernetes.io/docs/tasks/tools/](https://kubernetes.io/docs/tasks/tools/) ```bash curl -LO https://dl.k8s.io/release/v1.24.6/bin/linux/amd64/kubectl % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 138 100 138 0 0 666 0 --:--:-- --:--:-- --:--:-- 666 100 43.6M 100 43.6M 0 0 21.0M 0 0:00:02 0:00:02 --:--:-- 29.6M ls kubectl kubespray kubesprayv2.20 original-ks.cfg curl -LO https://dl.k8s.io/release/v1.24.6/bin/linux/amd64/kubectl.sha256 % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 138 100 138 0 0 650 0 --:--:-- --:--:-- --:--:-- 650 100 64 100 64 0 0 122 0 --:--:-- --:--:-- --:--:-- 122 ls kubectl kubectl.sha256 kubespray kubesprayv2.20 original-ks.cfg echo "$(cat kubectl.sha256) kubectl" | sha256sum --check kubectl: OK sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl kubectl version --client WARNING: This version information is deprecated and will be replaced with the output from kubectl version --short. Use --output=yaml|json to get the full version. Client Version: version.Info{Major:"1", Minor:"24", GitVersion:"v1.24.6", GitCommit:"b39bf148cd654599a52e867485c02c4f9d28b312", GitTreeState:"clean", BuildDate:"2022-09-21T13:19:24Z", GoVersion:"go1.18.6", Compiler:"gc", Platform:"linux/amd64"} Kustomize Version: v4.5.4 # Master노드에 있는 '.kube/config' 파일을 복붙 mkdir .kube cd .kube vi config # 그대로 복붙 하면 안됨, 왜냐면 거기에서는 로컬 호스트로 지정 되어 있음 kubectl get nodes The connection to the server 127.0.0.1:6443 was refused - did you specify the right host or port? # 그래서 5번째 줄에서 서버 IP를 Master노드 IP로 지정 vi config server: https://192.168.122.8:6443 kubectl get nodes NAME STATUS ROLES AGE VERSION node1 Ready control-plane 13d v1.24.6 node2 Ready