# 배포, 스케일링등(docker orchestrator) 위한 오픈소스 플랫폼
# 용어
# cluster : master + node 구성된 추상적인 단위
# master : node 이벤트를 김지하고 cluster 를 관리하는 주체
# node : 실제 서버들
# pod : 도커 컨테이너 집합, 가장 작은 단위로 node 위에서 동작하는 앱(docker container 에 담긴) 1개 이상으로 구성
# object : pod, volume, namespace 등
# Deployment : 리소스의 한 종류(kind)로 pod 에 컨테이너를 띄운다.
# Service : 리소스의 한 종류(kind)로 오픈(노출)하기전 Deployment 와같은 리소스를 묶어 주는 추상적인 개념
# ingress : Servcie 를 외부에서 접속할 수 있게 해준다.
# GCP(GoogleCloudPlatform), AWS(AmazonWebService)로 클러스터를 구성한다.
# 참고 GCP, AWS 등의 Cloud Provider 를 사용하지 않고 클러스터 구성하는 경우
# 장비를 구하기도 힘들고 구성도 어려워 비추
# https://kubernetes.io/docs/setup/scratch/
# 구축된 k8s 환경이없다면 minikube 로 로컬에서 k8s 클러스터를 구성할 수있다.
https://minikube.sigs.k8s.io/docs/start/
# kubectl(kubernets cli tool) 설치
# centos, ubuntu
# https://kubernetes.io/docs/tasks/tools/install-kubectl/
# https://kubernetes.io/ko/docs/tutorials/
# mac
brew install kubernetes-cli
# 개인적으로 GCP의 k8s 는 요금이 발생해 현재 사용하고 있지 않다.
# k8s cluster 생성 후 로컬에서 해당 클러스터를 사용하려면 다음 설정을 해야 한다.
kubectl config set-credentials ysoftman --username=ysoftman --password=aaa123
kubectl config set-cluster ysoftman-test-cluster --insecure-skip-tls-verify=true --server https://10.10.10.10:6443
kubectl config set-context ysoftman-test-context --cluster=ysoftman-test-cluster --user=ysoftman
kubectl config use-context ysoftman-test-context
# 접속 설정에 password 대신 토큰 사용할 수도 있다.
# 토큰 생성전에는 최초 username, password 로 접속이 필요하다.
# 사용자 토큰 파악
kubectl --namespace=kube-system get secrets | grep ysoftman | awk '{print $1}' | xargs kubectl --namespace=kube-system describe secrets
# ~/.kube/config 에 다음과 같이 user수정
#- name: ysoftman
# user:
# password: aaa123
# username: ysoftman
- name: ysoftman
user:
token: zzzzz
# 설정 보기
kubectl config view
# 클러스터 정보 보기
kubectl cluster-info
# 노드 상태 보기
kubectl get nodes -o wide
# pod 상태 보기
kubectl get pods -o wide
# pod 내부 정보 보기 (CrashLoopBackOff 상태일때 확인)
kubectl describe pod
# kubectl top 명령은 metrics-server 를 설치해야 사용할 수 있다.
# k8s cluster 생성 후 로컬에서 해당 클러스터를 사용하려면 다음 설정을 해야 한다.
kubectl config set-credentials ysoftman --username=ysoftman --password=aaa123
kubectl config set-cluster ysoftman-test-cluster --insecure-skip-tls-verify=true --server https://10.10.10.10:6443
kubectl config set-context ysoftman-test-context --cluster=ysoftman-test-cluster --user=ysoftman
kubectl config use-context ysoftman-test-context
# 접속 설정에 password 대신 토큰 사용할 수도 있다.
# 토큰 생성전에는 최초 username, password 로 접속이 필요하다.
# 사용자 토큰 파악
kubectl --namespace=kube-system get secrets | grep ysoftman | awk '{print $1}' | xargs kubectl --namespace=kube-system describe secrets
# ~/.kube/config 에 다음과 같이 user수정
#- name: ysoftman
# user:
# password: aaa123
# username: ysoftman
- name: ysoftman
user:
token: zzzzz
# 설정 보기
kubectl config view
# 클러스터 정보 보기
kubectl cluster-info
# 노드 상태 보기
kubectl get nodes -o wide
# pod 상태 보기
kubectl get pods -o wide
# pod 내부 정보 보기 (CrashLoopBackOff 상태일때 확인)
kubectl describe pod
# kubectl top 명령은 metrics-server 를 설치해야 사용할 수 있다.
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
# node 별 cpu, memory 사용량 보기, cpu 순으로
kubectl top node --sort-by=cpu
kubectl top pod --sort-by=memory
kubectl top pod --containers --sort-by=cpu
# ktop(https://github.com/vladimirvivien/ktop)으로 cpu,memory 사용을 더 편하게 볼 수도 있다.
# 설치
brew install ktop
# 전체 네임스페이스의 리소스 보기
ktop
# 특정 네임스페이스에 해당하는 리소스만 보기
ktop -n ysoftman
# 앱 배포(Deployment)
# deployment 설명 : https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.16/#deployment-v1-apps
# 예제 : https://kubernetes.io/docs/concepts/services-networking/connect-applications-service/
# nginx 배포 예제 yaml 파일 다운로드
curl https://raw.githubusercontent.com/kubernetes/website/master/content/en/examples/service/networking/run-my-nginx.yaml -O
# run-my-nginx.yaml 내용
apiVersion: apps/v1 # 앱 생성에 사용할 k8s api 버전
kind: Deployment # 생성할 resource 종류
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 2
template:
metadata: # 오브젝트 구분을 위한 값
labels:
run: my-nginx
spec: # 생성할 오브젝트의 상태(스펙)
containers: # 컨테이너를 구동하는경우
- name: my-nginx
image: nginx
ports:
- containerPort: 80
# yaml 파일로 앱 배포(object 생성)
kubectl apply -f run-my-nginx.yaml
# 배포(실행중) 상태 보기
kubectl get all -o wide
# pod 에 보이는 IP 는 kubernetes 내부에 사용하는 IP 로 접근할 수 없다.
kubectl get pods -o wide
# 다음 명령이 실행될 동안 my-nginx-xxxx pod 80 포트가 로컬 9999 포트로 임시로 포트 포워딩 된다.
kubectl port-forward my-nginx-xxxx 9999:80
http://localhost:9999/ 로 확인
# pod ssh 접속
# kubectl exec -h 참고
kubectl exec -it my-nginx-xxxx -- /bin/bash
# 이름을 알기 위해서 다음처럼 사용하면 편하다.
kubectl exec -it $(kubectl get pods -o name | sed 's/pod\///' | grep my-nginx) -- /bin/bash
# local -> k8s pod container 파일 복사
# 예제 : https://kubernetes.io/docs/concepts/services-networking/connect-applications-service/
# nginx 배포 예제 yaml 파일 다운로드
curl https://raw.githubusercontent.com/kubernetes/website/master/content/en/examples/service/networking/run-my-nginx.yaml -O
# run-my-nginx.yaml 내용
apiVersion: apps/v1 # 앱 생성에 사용할 k8s api 버전
kind: Deployment # 생성할 resource 종류
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 2
template:
metadata: # 오브젝트 구분을 위한 값
labels:
run: my-nginx
spec: # 생성할 오브젝트의 상태(스펙)
containers: # 컨테이너를 구동하는경우
- name: my-nginx
image: nginx
ports:
- containerPort: 80
# yaml 파일로 앱 배포(object 생성)
kubectl apply -f run-my-nginx.yaml
# 배포(실행중) 상태 보기
kubectl get all -o wide
# pod 에 보이는 IP 는 kubernetes 내부에 사용하는 IP 로 접근할 수 없다.
kubectl get pods -o wide
# 다음 명령이 실행될 동안 my-nginx-xxxx pod 80 포트가 로컬 9999 포트로 임시로 포트 포워딩 된다.
kubectl port-forward my-nginx-xxxx 9999:80
http://localhost:9999/ 로 확인
# pod ssh 접속
# kubectl exec -h 참고
kubectl exec -it my-nginx-xxxx -- /bin/bash
# 이름을 알기 위해서 다음처럼 사용하면 편하다.
kubectl exec -it $(kubectl get pods -o name | sed 's/pod\///' | grep my-nginx) -- /bin/bash
# local -> k8s pod container 파일 복사
# pod 내 container 가 여러개면 -c 로 container 이름을 지정하면 된다.
kubectl cp file.txt ysoftman_namespace/ysoftman_pod:/home/ysoftman/ -c ysoftman_container
# pod log 확인
# kubectl logs -h 참고
kubectl logs my-nginx-xxxx
# -f 옵션으로 stream 되는 로그를 follow 할 수 도 있다.
kubectl logs my-nginx-xxxx -f
# pod 내 2개 이상의 container 가 있는 경우
kubectl logs my-nginx-xxxx -c 컨테이너이름
# 서비스(Service) 생성
# nginx-svc.yaml 다운로드
curl https://raw.githubusercontent.com/kubernetes/website/master/content/en/examples/service/networking/nginx-svc.yaml -O
# 위 Deployment 된 앱을 서비스 단위로 묶어 준다.
# nginx-svc.yaml 를 다음과 같이 nodeport 설정 추가한다.
apiVersion: v1 # https://kubernetes.io/ko/docs/concepts/overview/kubernetes-api/ 참고
kind: Service
metadata:
name: my-nginx
labels:
run: my-nginx
spec:
type: NodePort
ports:
- port: 80
protocol: TCP
nodePort: 30010 # 30000~32767
selector:
run: my-nginx
# 서비스 적용
# 참고로 2개의 yaml 을 --- 로 구분해서 파일 하나로 만들어 한번에 적용해도 된다.
# 참고로 yaml 수정하고 apply 하면 수정된 내용을 다시 반영된다.
kubectl apply -f nginx-svc.yaml
# my-nginx 가 서비스된 것을 확인(service 대신 svc 도 가능)
kubectl get service
# my-nginx 서비스만 조회
kubectl get service -l app=my-nginx
# 참고로 my-nginx 서비스 설정을 yaml 파일로 저장할 수 있다.
kubectl get service -l app=my-nginx -o yaml > temp.yaml
# my-nginx 서비스 events(log) 확인
kubectl describe service my-nginx
# 전체 네임스페이스(-A, --all-namespaces)에서 pod, service, ingress 등 함께 조회
kubectl get pod,svc,ingress --all-namespaces
# 전체 네임스페이스에서 모든 리소스 조회
kubectl get all -A
# k8s 클러스터 외부에서는 노드IP:30010 로 접속 가능
kubectl get nodes -o wide
http://노드IP:30010
# 참고로 사용하는 클라우드 서비스에서 ingress 를 지원한다면
# NodePort 는 주석처리하고 ingress(kind) yaml 만들어 적용하면 된다.
# ingress 를 사용하면 host, path 등의 분기처리등 다양한 기능을 이용할 수 있다.
# 배포한 앱 삭제
kubectl delete service my-nginx
kubectl delete deployment my-nginx
# pod 전체 삭제
# pod 만 삭제하면 replica 에 의해 pod 를 복원하려고 한다.
# 따라서 deployment object 를 먼제 삭제해야 한다.
kubectl delete pods --all
# unknown 상태의 pods 가 삭제되지 않는다면 다음 옵션을 사용하자.
kubectl delete pods --all --grace-period=0 --force --wait=false
# 네임스페이스안의 리소스들 모두 삭제
kubectl get nodes -o wide
http://노드IP:30010
# 참고로 사용하는 클라우드 서비스에서 ingress 를 지원한다면
# NodePort 는 주석처리하고 ingress(kind) yaml 만들어 적용하면 된다.
# ingress 를 사용하면 host, path 등의 분기처리등 다양한 기능을 이용할 수 있다.
# 배포한 앱 삭제
kubectl delete service my-nginx
kubectl delete deployment my-nginx
# pod 전체 삭제
# pod 만 삭제하면 replica 에 의해 pod 를 복원하려고 한다.
# 따라서 deployment object 를 먼제 삭제해야 한다.
kubectl delete pods --all
# unknown 상태의 pods 가 삭제되지 않는다면 다음 옵션을 사용하자.
kubectl delete pods --all --grace-period=0 --force --wait=false
# 네임스페이스안의 리소스들 모두 삭제
all=pods,deployments,rs 등의미, 단 secrets,configmaps 등 일부는 수동으로 삭제해야 한다..
kubectl delete all --all --namespace ysoftman-namespace
kubectl delete ns ysoftman-namespace
# https://kubernetes.io/docs/concepts/services-networking/network-policies/
# https://github.com/ahmetb/kubernetes-network-policy-recipes
#####
# resource 종류 : https://kubernetes.io/docs/reference/kubectl/overview/#resource-types
# 지원되는 resources 리스트 보기
kubectl api-resources
# 리소스 설명 보기
kubectl explain 리소스명
# 지원하는 api 종류 보기
kubectl get apiservices
kubectl get apiservices
# vi 에디터로 ysoftman 서비스 수정
KUBE_EDITOR="vi" kubectl edit svc/ysoftman# ysoftman deployment 재시작(pod 새로 생성)
kubectl rollout restart deployment/ysoftman
# ysoftman statefulset 재시작(pod 새로 생성)
kubectl rollout restart statefulset/ysoftman
# 새 pod 로 시작
# replicas=0 으로 만면 pod 삭제 후 # replicas=1 로 새 pod 생성
kubectl scale --replicas=0 deployment/ysoftman
kubectl scale --replicas=1 deployment/ysoftman
# 새 pod 로 시작
# replicas=0 으로 만면 pod 삭제 후 # replicas=1 로 새 pod 생성
kubectl scale --replicas=0 deployment/ysoftman
kubectl scale --replicas=1 deployment/ysoftman
#####
# 노드 재부팅시
# node 확인
kubectl get nodes
# ysoftman1 노드에 pod 스케쥴링 되지 않도록 방지
# drain 과정에 cordon 이 있어, drain 할거면 굳이 할 필요 없음
kubectl cordon ysoftman1
# ysoftman1 노드의 모든 pod 를 graceful 종료
# drain 과정에 cordon 이 포함되어 있다.
# daemonset 이 있는 경우라면 --ignore-daemonsets 옵션 추가
kubectl drain ysoftman1
# ysoftman1 노드에 다시 pod 스케쥴링 하기
# 재부팅되면 cordon 상태라 uncordon 해야 된다.
kubectl uncordon ysoftman1
# 추가로 tain/toleration 은
# ysoftman1 노드에 pod 스케쥴링 되지 않도록 방지
# cordon 과 다르게 toleration 로 강제로 스케쥴링 되게 할 수 있다.
kubectl taint node ysoftman1 key1=value1:NoSchedule
# ysoftman1 노드에 taint 무시하고 pod 스케쥴링
kubectl toleration node ysoftman1
#####
# 새노드 추가시
# master(control-plane) 에서 조인을 위한 토큰 확인
sudo kubeadm token create --print-join-command
# 새로운 노드에서 다음 명령을 실행해 master 노드에 join 하도록 한다.
sudo kubeadm join {control-plane-ip}:6443 --token {토큰값}
# 참고 kubectl 명령들