본문 바로가기
Kubernetes

Kubernetes 기본

by 손영진 2023. 8. 7.
728x90

#1 Kubernetes 기본

   1. 정의

  • Linux 컨테이너 작업을 자동화하는 오픈소스 플랫폼
  • 컨테이너화된 애플리케이션을 배포하고 확장하며 수동 프로세스 필요치 않음
  • 클러스터는 퍼블릭, 프라이빗, 하이브리드 클라우드 전체로 호스트 확장 가능

 

   2. 개념

  • Observe : 현재 상태
  • Diff : 현 상태가 아닌 요구사항
  • Act : 현 상태를 요구사항 상태로 만들기 위해 현 상태를 변경
    • 상태체크(ovserve) -> 차이점 발견(diff) -> 조치(act) -> 상태체크(observe) -> loop

=> 이러한 loop 프로세스를 Controller라고 부름.

 

   3. Container Orchestration Tools

  • Container의 배포, 관리, 확장, 네트워킹을 자동화하는 기술
  • 목적
    • 여러 컨테이너의 배포 프로세스를 최적화하며, 컨테이너와 호스트 수 증가 시 사용 가치 상승
  • 기능
    • 컨테이너 자동 배치 및 복제, 그룹에 대한 로드 밸런싱
    • 장애 복구, 외부에 서비스 노출, 확장 및 축소

 

   4. 사용 이유

  • 애플리케이션은 여러 컨테이너에 걸쳐 있고 이러한 컨테이너는 여러 서버 호스트에 배포
  • 지속적 상태 관리, 여러 컨테이너에 걸쳐 애플리케이션 서비스 구축

 

   5. Container 운영 환경

  • Scheduling : 컨테이너를 적절한 서버에 배포하는 역할
  • 스케쥴링 외에 컨테이너가 정상적으로 작동하는지 점검, 재시작, 모니터링 등 종합정 관리 환경

 

#2 구성요소

   1. Control Plane Component(Master)

  • 클러스터에 관한 전반적인 결정( ex 스케쥴링 )을 수행하고 이벤트 감지
  • 클러스터 내 어떠한 머신에서도 동작 가능

 

   2. Node Component

  • Kubelet
    • 클러스터 각 노드에서 실행되는 에이전트
    • Pod에서 컨테이너가 확실하게 동작하도록 관리 - 생명주기
    • Pod 내부의 컨테이너의 이상유무를 주기적으로 Master에 상태 전달
  • Kube-proxy
    • 각 노드에서 실행되는 네트워크 프록시로 쿠버네티스의 서비스 개념 구현부
    • 노드의 네트워크 규칙 유지 관리
    • Userspace
      • 클라이언트에서 서비스IP 통해 요청
      • iptables거쳐 kube-proxy가 요청 받음
      • 그 서비스IP가 연결되어야 하는 적절한 Pod 로 연결
      • Round Robin 방식
    • Iptables
      • 관리하는 역할과 직접 클라이언트로부터 트래픽을 받지 않음
      • 모든 요청은 iptables를 거쳐 직접 Pod로 전달
      • iptables는 Pod 하나로 가는 요청을 실패 시 재시도 않고 요청 실패
        • 이와 반대되게 Userspace 모드는 요청 실패시 자동으로 다른 Pod로 연결 재시도
      • 이를 방지하기 위해 Readiness probe 설정 필요
  • Container Runtime
    • 컨테이너 실행을 담당하는 소프트웨어

 

#3 Objects

   1. Pod

  • Kubernetes에서 배포 할 수 있는 가장 작은 단위
  • 한 개 이상의 컨테이너와 스토리지, 네트워크 속성을 가짐
  • 서로 Localhost로 접근 가능
  • 컨테이너 하나만 사용하는 경우도 반드시 Pod로 감싸서 관리

 

   2. NameSpace

  • 한 쿠버네티스 클러스터 내 논리적 분리단위
  • Pod, Service 등은 namespace 별 생성/관리 가능
  • 역할
    • 사용자별 namespace별로 접근 권한 다르게 운영
    • namespce 별 리소스의 할당량 지정
    • 리소스를 나눠서 관리

 

#4 Controller

   1. 종류

  • Replication Controller( RC )
  • Replication Set : RC이후의 버전
    • Pod 여러 개를 복제하여 관리하는 오브젝트
    • Pod생성하고 개수 유지하려면 반드시 Replicaset 사용
  • DaemonSet
    • Pod가 각 노드에서 하나씩만 실행
    • 특정 Node들에만 Pod가 하나씩만 배포되도록 설정 가능 - 'node selector'를 이용
  • Job, StatefulSet
  • Deployment

 

#5 실습

   1. 서버 3개의 EC2 인스턴스 생성( Master, Worker1, Worker2)

 

   2. Security Group : 하나의 그룹에 Master와 Worker 모두 설정

22 : ssh server
80 : http, web port
443 : https
모든 ICMP

6443 : 쿠버네티스 API Server
2379 ~ 2380 : Client API
10250 ~ 10252 : Kubelet API ,...

30000 ~ 32767 : Nodeport Services

   3. instance 설정 값

 

 

   4. 초기 설정 (master, worker1, worker2)

sudo -i
hostnamectl set-hostname master.example.com
bash

apt update
apt install net-tools -y
			// ip를 할당 받을 수 있도록 툴을 설치

vim /etc/hosts
> [master의 사설IP]	master
> [worker1의 사설IP]	worker1
> [worker2의 사설IP]	worker2
			// 각 서버끼리의 통신을 위함으로 ip와 hostname 사이는 tab키로 이용하여 띄어쓴다.

swapoff -a		// swap 비활성화
echo 0 > /proc/sys/vm/swappiness

<<패키치 설치(docker, kubernetes)>>
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add –
chmod -R 777 /etc/apt
vim /etc/apt/sources.list.d/kubernetes.list
> deb http://apt.kubernetes.io/ kubernetes-xenial main

wget -qO- get.docker.com | sh		// docker 설치
apt-get update
apt-get install -y kubelet kubeadm kubectl kubernetes-cni 

<<docker 환경설정 변경>>
usermod -aG docker $USER
vim /etc/docker/daemon.json
> {"exec-opts": ["native.cgroupdriver=systemd"]}
vim /etc/containerd/config.toml
> #disabled_plugins = ["cri"]		// 앞에 # 만 붙여주어 주석처리 한다.

systemctl daemon-reload
systemctl restart docker
systemctl enable docker
systemctl restart containerd
docker version		// version이 나오면 제대로 된 것

<<Kernel 파라미터 변경>>
vim /etc/sysctl.d/k8s.conf
> net.bridge.bridge-nf-call-ip6tables = 1
> net.bridge.bridge-nf-call-iptables = 1

sysctl --system		// 변경사항 활성화

 

   5. Master 노드 설정 ( Master )

kubeadm config images pull
systemctl enable kubelet
kubeadm init --apiserver-advertise-address 0.0.0.0 \
> --pod-network-cidr=192.168.0.0/16
			// 결과값 안의 kubeadm 의 명령어를 worker1, worker2에 작성

mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
systemctl status kubelet
kubectl get nodes		// 생성한 kubectl의 상태를 확인 -> NotReady 상태임

<<CNI Calico 설치>>
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/ \
> v3.25.1/manifests/tigera-operator.yaml

kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/ \
> v3.25.1/manifests/custom-resources.yaml

kubectl get pods --all-namespaces
kubectl get nodes		// CNI Calico를 설치하며 kubectl의 상태를 Ready로 전환

 

   6. Worker Node 설정 ( Worker1, Worker2 )

 

systemctl enable kubelet		// kubelet을 활성화시킴

kubeadm join ~
			// Master Node설정 시 생성된 명령어를 kubelet 활성화 후 작성
            
kubectl get nodes -o wide
			// 각 노드에도 kubelet이 생긴 것을 확인

 

   7. Kubernetes Cluster Test ( Master )

kubectl cluster-info		// kubenetes cluster 세부정보 확인

<<Deployment, Service 생성>>
kubectl create deployment nginx-server --image=nginx --port=80
kubectl create service nodeport nginx-server --tcp=80:80

kubectl get pods -o wide
			// 생성된 pods의 세부정보로 deploy가 어느 노드에 생성되었는지 확인
kubectl get svc -o wide
			// 생성된 service 세부정보로 부여된 NodePort를 확인

curl [생성된 노드 이름]:[NodePort번호]

[생성된 노드의 공인IP]:[N]

   8.  Deploy 복제

kubectl scale deploy nginx-server --replicas=4
kubectl get pods -o wide
			// 4개의 복제품을 만들어도 master에는 할당되지 않고 worker에만 할당되는 모습 확인

kubectl scale deploy nginx-server --replicas=2
kubectl get deploy
			// 복제는 총 2개가 되는 것으로 마무리

 

   9. Pods Object 삭제

kubectl delete deployment nginx
kubectl delete service nginx
kubectl get pods
			// 삭제 된 것 확인

 

#6 Pods & Namespace 실습

   1. Pod 생성 및 정보 확인

kubectl create namespace nginx-app
kubectl get namespaces		// 생성된 namespace 확인

wget https://raw.githubusercontent.com/ahmetb/kubectx/master/kubens
chmod +x kubens			//kubens에 실행 권환 부여
cp kubens /usr/bin/
kubens nginx-app		// 생성한 namespace의 nginx-app 실행

kubectl create deploy nginx --image=nginx 
kubectl get deploy
kubectl get pods -o wide

kubectl scale deploy nginx --replicas=3
kubectl get pods -o wide

kubectl create service nodeport nginx --tcp=80:80
kubectl get svc -o wide

kubectl describe deployments nginx
			// describe는 docker의 inspect와 같은 의미로 세부정보 확인을 의미

 

   2. Pod 접속 및 오브젝트 삭제

kubectl get pods		// pods 이름 확인
kubectl exec -it nginx-6799fc88d8-f98wx -- /bin/bash
			// pods의 이름을 포함하여 접속      
> echo 'Nginx index page' > /usr/share/nginx/html/index.html
> exit

kubectl exec nginx-6799fc88d8-f98wx -- cat /usr/share/nginx/html/index.html
			// cat을 통하여 해당 경로의 파일 내용 확인
            
kubectl delete svc nginx
kubectl delete deployment nginx

 

   3. 템플릿 이용 Pod 생성

vim nginx-app.yaml
<더보기 참조>

kubectl apply -f nginx-app.yaml			// 작성한 파일 적용 및 deploy 생성
kubectl get deploy

kubectl expose deployment nginx-app --type=NodePort
			// NodePort를 가지게 deploy 생성
kubectl get svc -o wide			// NodePort 번호 확인
kubectl get pods -o wide		// 생성된 pods의 노드 확인
curl [노드이름]:[NodePort 번호]
  • nginx-app.yaml
더보기

apiVersion: apps/v1

kind: Deployment

metadata:

   name: nginx-app

   labels:

     app: nginx-app

spec:

   replicas: 1

   selector:

     matchLabels:

       app: nginx-app

   template:

     metadata:

       labels:

         app: nginx-app

     spec:

       containers:

       - name: nginx-app

         image: nginx

         ports:

         - containerPort: 80

 

   cf. ubuntu의 비밀번호

grep ubuntu /etc/passwd /etc/shadow
<그림1> -> ! : 비밀번호가 없다는 뜻

Passwd ubuntu		// 비밀번호 설정
>new password
>reply

grep ubuntu /etc/passwd /etc/shadow
<그림2>

그림 1
그림 2

 

   4. Pod 자원 할당 및 환경 변수

kubectl create namespace pod-test
kubens		// 생성한 namespace가 활성화 되어 있는거 확인

kubens pod-test

vim pod-resource.yaml
<그림 3 참조>

kubectl apply -f pod-resource.yaml		// Pod 생성

kubectl describe pod kubernetes-pod-test
			// pod의 이름 작성 (kuber ~ -test)하여 세부 내용을 확인하며 yaml에 작성한 내용 확인
            
<<환경변수>>

vim pod-resource.yaml
		// <그림 4>의 내용을 추가
kubectl apply -f pod-env.yaml
 
kubectl exec -it kubernetes-pod-test -- sh		// 환경 변수 확인으로 해당 pod에 접속
> env		// 방금 추가한 내용을 확인
그림 3 그림 4

 

#7 Controller

   1. Replicaset

  • replicaset-nginx.yaml
더보기
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: nginx-replicaset
spec:
  template:
    metadata:
      name: nginx-replicaset
      labels:
        app: nginx-replicaset
    spec:
      containers:
      - name: nginx-replicaset
        image: nginx
        ports:
        - containerPort: 80
  replicas: 3
  selector:
    matchLabels:
      app: nginx-replicaset
vim replicaset-nginx.yaml
<더보기 참조>

kubectl apply -f replicaset-nginx.yaml		// 생성한 .yaml 파일로 pods생성
kubectl get pods -o wide		// 생성한 pods 세부정보 확인


kubectl delete pod [생성된 pods의 이름]
kubectl get pods -o wide		// replicaset으로 인하여 지워도 다시 3개인 것을 확인

kubectl get replicaset
			// replicaset을 몇으로 지정하였는지 확인. 이는 .yaml 내에서 지정한다.
            
kubectl delete replicaset nginx-replicaset --cascade=orphan
			// orphan을 통해 replicaset과 pods를 분리
  • Replicaset과 Pods를 분리시키지 않는 이상, pods를 아무리 지워도 지정해놓은 숫자만큼 계속해서 생긴다.
  • 분리 후 pods가 지워지고 2개인 것을 확인가능하지만, apply릍 통해 사기 연결 시 자동으로 pods가 생긴다.

 

   2. Deamonset

  • 클러스터 전체 노드에 특정 Pod를 실행 시 사용하는 컨트롤러
  • 더보기

    apiVersion: apps/v1

    kind: DaemonSet

    metadata:

      name: fluentd-elasticsearch

      namespace: kube-system

      labels:

        k8s-app: fluentd-logging

    spec:

      selector:

        matchLabels:

           name: fluentd-elasticsearch

      updateStrategy:

        type: RollingUpdate

      template:

         metadata:

           labels:

             name: fluentd-elasticsearch

        spec:

           tolerations:

           - key: node-role.kubernetes.io/master

             effect: NoSchedule

           containers:

           - name: fluentd-elasticsearch

             image: k8s.gcr.io/fluentd-elasticsearch:1.20

             resources:

               limits:

                 memory: 200Mi

               requests:

                 cpu: 100m

                 memory: 200Mi

             volumeMounts:

             - name: varlog

               mountPath: /var/log

             - name: varlibdockercontainers

               mountPath: /var/lib/docker/containers

               readOnly: true

          terminationGracePeriodSeconds: 30

          volumes:

          - name: varlog

             hostPath:

               path: /var/log

         - name: varlibdockercontainers

            hostPath:

               path: /var/lib/docker/containers

vim daemonset.yaml
<더보기 참조>

kubens kube-system
kubectl apply -f daemonset.yaml

kubectl get pods -o wide | grep fluentd
<그림>

kubectl delete daemonset fluentd-elasticsearch

 

   3. Statefulset

  • 상태를 가지고 있는 Pod들을 관리하는 컨트롤러
  • 특정데이터를 기록하고 그것을 pod 재시작해도 이를 유지
  • statefulset.yaml
더보기

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: nginx # has to match .spec.template.metadata.labels
  serviceName: "nginx"
  replicas: 3 
  template:
    metadata:
      labels:
        app: nginx # has to match .spec.selector.matchLabels
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
          name: web

vim statefulset.yaml
<더보기 참조>

kubectl create ns pod-test
kubens pod-test
kubectl apply -f statefulset.yaml

kubectl get pods -o wide		// 각 worker에 트래픽을 분산하여 고르게 분포하는 것을 확인

 

   4. Cronjob

  • job을 시간 기준으로 관리
  • 지정한 시간에 한번만 실행하거나 지정한 시간동안 주기적으로 반복 실행
  • cronjob.yaml
더보기

apiVersion: batch/v1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
       spec:
         containers:
         - name: hello
           image: busybox
           args: 
           - /bin/sh
           - -c
           - date; echo Hello from the Kubernetes cluster
         restartPolicy: OnFailure

vim cronjob.yaml
<더보기 참조>

kubectl apply -f cronjob.yaml
kubectl get cronjob		// 활성화 된 것을 확인
			// 안의 내용 중 ' */1 * * ~ '의 내용은 시간 당 한번이라는 뜻

'Kubernetes' 카테고리의 다른 글

Kubernetes Scheduling  (0) 2023.08.15
Kubernetes ConfigMap & volume  (0) 2023.08.09
Kubernetes Deploy & Service & Ingress  (0) 2023.08.08