레이블이 kubeadm인 게시물을 표시합니다. 모든 게시물 표시
레이블이 kubeadm인 게시물을 표시합니다. 모든 게시물 표시

install kubernetes

# kubernetes(k8s) 는 물리적으로 master(control plane 이라고 불린다.) 와 worker 노드로 구성된다.

# k8s master 노드의 컴포넌트들
# kube-apiserver : kubectl, kubelet, kube-scheduler, kube-controller 등 의 api 요청을 처리하는 웹서버 역할
# etcd : key-value 저장소로 k8s 모든 정보가 저장되는 곳이다. kubectl 등의 리소스 명세서등도 여기 저장된다.
# kube-scheduler : 워커노드의 리소스 상태를 파악하고 pod 를 적절한 워커노드에 띄운다.
# kube-controller : pod 를 모니터링하며서 pod 가 특정 상태를 유지하도록 한다.(ex. replica 2 일때 pod 2개중 1개가 죽으면 pod 1개를 새로 띄운다.)

# k8s worker 노드 컴포넌트
# kubelet : master 의 kube-apiserver 와 통신하며 원하는 리소스(ex. pod)들을 관리하는 일종의 에이전트
# kube-proxy : network proxy 역할

# ubuntu 에서 kubeadm(k8s 클러스터 구성 및 관리 툴) 설치

# apt 저장소 추가
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update

# master, worker 모두에 설치하자.
k8s_version="1.19.16-00"
sudo apt-get install -y kubelet=${k8s_version} kubeadm=${k8s_version} kubectl=${k8s_version}

# kubelet kubeadm kubectl 업데이트 되지 않도록 hold 설정
sudo apt-mark hold kubelet kubeadm kubectl

# kubeadm 으로 클러스터를 구성한다.
sudo kubeadm init \
 --apiserver-advertise-address=192.168.104.2 \
 --apiserver-cert-extra-sans=192.168.104.2 \
 --node-name=control-plane \
 --pod-network-cidr=10.224.0.0/16 \
 --service-cidr=10.225.0.0/16

# 설치가 완료되면 다음과 같은 메시지가 출력된다.
# kubectl 사용을 위한 kubeconfig 설정
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
... 생략 ...
# worker -> master 에 조인을 위해  worker 노드에서 실행한다.
... 생략 ...
kubeadm join 192.168.104.2:6443 --token aaaaa --discovery-token-ca-cert-hash sha256:aaaaa
... 생략 ...

# 참고로 kube-apiserver 에서 6443포트를 사용한다.

# master 에서 노드 상태 watching 하고
kubectl get nodes -w

# worker1, worker2 에서 다음 명령을 실행해 master 노드에 join 하도록 한다.
sudo kubeadm join 192.168.104.2:6443 --token aaaaa --discovery-token-ca-cert-hash sha256:aaaaa

# node 에서 돌고 있는 서비스
kubelet
kube-proxy

# master node 돌고 있는 서비스
kube-scheduler
kube-controller-manager
kube-apiserver


#####

# 노드 삭제시
kubectl delete node 노드명

# 노드에 접속해서 kubelet 서비스 비활성화 및 설정 파일 제거
ssh ysoftman@노드 "sudo kubeadm reset -f"

# 클러스터 정보 확인
kubectl cluster-info

# 노드 추가시 
# 노드에서 kubeadm, kubelet, kubectl 설치하고
# token 확인
sudo kubeadm token list

# hash 확인
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'

# 마스터 노드에 조인
sudo kubeadm join 마스터노드IP:6443 --token 토큰 --discovery-token-ca-cert-hash sha256:해시

kubernetes(k8s) command

# kubernetes(쿠버네티스,줄여서 k8s,배의 조타수)는 도커 기반의 컨테이너를
# 배포, 스케일링등(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 를 설치해야 사용할 수 있다.
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

# pod 별 cpu, memory 사용량 보기, memory 순으로
kubectl top pod --sort-by=memory

# contianer 별 cpu, memory 사용량 보기, cpu 순으로
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 파일 복사
# 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

# 네임스페이스안의 리소스들 모두 삭제
all=pods,deployments,rs 등의미, 단 secrets,configmaps 등 일부는 수동으로 삭제해야 한다..
kubectl delete all --all --namespace ysoftman-namespace

# 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

# 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

#####

# 노드 재부팅시
# 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 명령들