쿠버네티스에 대하여 - 9.5 (환경구성, metalLB, namespace, configMap, 메트릭 서버)

양승현·2022년 9월 5일
0

kubernetes

목록 보기
6/18

현재상태

  • 모든 노드가 ubuntu 20.04
  • 모든 노드에 동일한 패키지가 설치되어 있다(kubernetes 동작)
  • kubelet 도 manager 에 설치되어 있다.
  • 토큰 발행은 되어있지 않다.
  • #swapoff -a <-- 각 노드에서 가상메모리를 사용하지 않는다.
    모든 노드의 일관성을 유지하기 위해 k8s에서는 가상메모리 사용을 못하도록 한다.
  • 노드 실행시마다 자동으로 가상메모리 사용을 못하도록 하고 싶다면?
    /etc/fstab 의 가장 아래에 있는 내용 (/swap 관련 라인)을 주석처리
#/swapfile          none            swap    sw              0       0

클러스터링

step1. manager(master) 에서 토큰 발행

kubeadm init --apiserver-advertise-address 211.183.3.100
mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config
  • 현재사용자가 쿠버네티스의 어드민 계정에 대한설정 내용이 포함된 파일을 관리할 수 있다
export KUBECONFIG=/etc/kubernetes/admin.conf
-> 현재 사용자가 쿠버네티스 관리자로 등록된다. 
내일 오전에 재부팅한 뒤 kubectl 이용하여 클러스터에 대한 명령을 실행하는데 오류가 발생한다면?
export KUBECONFIG=/etc/kubernetes/admin.conf 
또는 KUBECONFIG=/etc/kubernetes/admin.conf 를 처음 실행시 자동으로 실행될 수 있도록 .bashrc 에 등록해 둔다.

step2. 포드간 오버레이 네트워크 구성을 위한 애드온 을 추가한다.

kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
kubectl get pod -n kube-system
  • 클러스터를 초기화 하고 싶다면
kubeadm reset 
  • 시작
kubeadm init 

CNI

  • CNI 는 컨테이너들과의 통신을 위해 개발된 인터페이스이며 표준화를 통해 어떠한 컨테이너가 됐건 상관없이 연결이 가능하도록 해 준다.
  • CNI 의 종류는 크게 L2, L3 로 구분한다.
  • L2 는 각각의 노드에 나뉘어 배포된 모든 포드를 하나의 가상 스위치에 연결하여 통신시킬 수있다.
  • L3 는 각 네트워크간 통신을 가상의 라우터를 사용하여 라우팅한다. 또한 BGP 를 제공하여 회사내에서 보유하고 있는 독립된 공인주소 대역을 ISP 와의 통신에 활용할수 있다.
  • 어느것을 사용하더라도 포드간 통신에는 문제 없다.
  • 노드에 생성된 각각의 포드는 별도의 독립적인 주소와 이에 해당하는 도메인이름이 할당된다. 우리는 이 정보가 저장된 coreDNS 를 통해 통신시킬 수 있다.
  • manager 에 있는 api, 스케줄러, 컨트롤러 등등은 모두 포드 형태로 생성되어 서비스를 제공한다. 또한 coreDNS, calico 도 포드 형태로 서비스가 제공된다. 따라서 이미지 다운로드 -> 포드생성의 단계를 거쳐야 한다.

실습환경 구성

1. metalLB 구성하기

  • 퍼블릭 환경의 경우에는 포드와 외부 사용자간 연결을 위해 손쉽게 LB 를 이용할 수 있다.
  • 하지만 on-premise 에서는 LB 서비스를 사용할 수 없다. 이를 해결하기 위해 metallb 를 이용하면 LB 이용이 가능하다.

2. 생성된 객체 metallb 에 어떠한 공인주소를 LB Pod 를 통해 전달할 것인지를 결정할 ConfigMap 을 작성하고 이를 배포한다.

root@manager:~/k8slab# cat metallb.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  namespace: metallb-system
  name: config
data:
  config: |
    address-pools:
    - name: default
      protocol: layer2
      addresses:
      - 211.183.3.201-211.183.3.211
      - 211.183.3.231-211.183.3.239      
root@manager:~/k8slab# kubectl apply -f metallb.yaml

3. LB, Pod 배포

root@manager:~/k8slab# cat nginx-deploy-svc.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deploy
spec:           # 아래는 ReplicaSet 설정
  replicas: 3
  selector:     # 아래의 라벨 개수를 확인하여 관리
    matchLabels:
      app: webserver
  template:     # 아래는 Pod 구성
    metadata:
      name: my-webserver
      labels:
        app: webserver
    spec:       # 아래 부분은 컨테이너 구성 내용
      containers:
      - name: my-webserver
        image: nginx
        ports:
        - containerPort: 80

---
apiVersion: v1
kind: Service
metadata:
  name: nginx-lb
spec:
  ports:
  - name: web-port
    port: 80
  selector:
    app: webserver
  type: LoadBalancer

yml 파일 작성하기

    1. 확장자는 yaml, yml 로 작성한다.
    1. tab 은 기본적으로 인정하지않는다. space bar 를 사용해야 한다.
    1. 만약 주석을 사용하고 싶다면
      json 은 기본적으로 주석을 허용하지 않는다. 하지만, yaml 은 # 로 제공한다.
    1. 두가지 이상의 작업을 하나의 파일에 작성하고 싶다면 --- 를 이용하여 구분한다.
apiVersion: v1
...
---    <--- "---" 을 넣어 구분한다

apiVersion: apps/v1 
...
    1. 리스트 사용가능하다.
  5.1 [  ,  ,  ]  -> ["gildong", "chulsoo", "minsoo"]
  5.2 
        - 
        - 
    1. 기본적으로 yaml 은 string 이다.
'
 abc
 def 
'
출력 => abcdef 
    1. 여러줄로 작성된 내용을 사진찍듯이 그대로 옮기고 싶다면
      | 를 이용할 수 있다. 즉, 기본적으로 한 줄 뒤에는 \n 이 생략되어 있다.
      만약 | 아래에 한줄을 비웠다면 이 역시 그대로 한줄 비우기가 전달된다.
      추가적으로 | 뒤에 - 를 붙이면 마지막 라인이 비워져 있어도 이를 지워준다.

네임스페이스 사용하기 [namespace]

Namespace Object 란

  • 컨테이너의 네임스페이스아니라 object 네임스페이스!
  • 용도에 따라 컨테이너와 그에 관련된 리소스를 구분짓는 그룹의 역할
  • 포드,RS,Deployment, svc 등과 쿠버네티스 리소스 들이 묶여 있는 가상의 작업 공간
  • 우리회사가 여러 고객들의 포드를 관리해 주는 업체라면 각 고객사별로 별도의 네임스페이스를 할당하고 해당 ns 에서 pod, svc, ... 를 이용한 서비스를 제공해야 할 것이다.

Namespace 종류

  • kube-system 은 쿠버네티스 동작을 위한 포드가 관리되는 곳이다.
  • 기본적으로 서로 다른 NS 에 속해있는 리소스 간에는 통신이/접근이 되지 않는다.
    (gcp 에서 별도의 project 를 만들고 이 공간내에 vm,vpc 등을 할당하는 것과 비슷)

  • 네임스페이스에 속하는 object와 그렇지 않는 object 가 있다
    kubectl api-resources

  • 쿠버네티스 클러스터를 여러명이 동시에 사용해야 한다면 사용자마다 네임스페이스를 별도로 생성하여 사용하도록 설정할 수 있다. (MSP 에서 고객사를 관리하는 방법)

  • 네임스페이스의 리소스들은 논리적으로 구분되어 있는 것이며 물리적으로 격리된 것이 아니므로 서로 다른 네임스페이스에서 생성된 포드가 같은 노드에 존재할 수 있다.

  • 네임스페이스 생성하기

1. yaml
apiVersion: v1
kind: Namespace
metadata:
  name: testns

2. kubectl create ns testns

  • 포드 배포시 네임스페이스를 추가적으로 작성해야 한다.(metadata)
root@manager:~/k8slab# cat nginx-deploy-svc.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: rapa
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deploy
  namespace: rapa
spec:           # 아래는 ReplicaSet 설정
  replicas: 3
  selector:     # 아래의 라벨 개수를 확인하여 관리
    matchLabels:
      app: webserver
  template:     # 아래는 Pod 구성
    metadata:
      name: my-webserver
      labels:
        app: webserver
    spec:       # 아래 부분은 컨테이너 구성 내용
      containers:
      - name: my-webserver
        image: nginx
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-lb
  namespace: rapa
spec:
  ports:
  - name: web-port
    port: 80
  selector:
    app: webserver
  type: LoadBalancer
  • 생성
root@manager:~/k8slab# kubectl apply -f nginx-deploy-svc.yaml
  • 생성 확인
root@manager:~/k8slab# kubectl get deploy
NAME           READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deploy   3/3     3            3           98s

configMap과 Secret

  • 도커의 이미지는 빌드 후 불변의 상태를 갖기 때문에 설정 옵션을 우연하게 변경할 수 없음.
  • configMap은 설정값/사용자별 별도의, 파일/사용자별 별도의
  • Secret - 일반적인 username/password, 사설 저장소 접근을 위한 인증
root@manager:~/k8slab# kubectl create configmap testmap --from-literal k8s=kubernetes --from-literal container=docker
configmap/testmap created

컨피그 맵을 포드에서 사용해보기

  • 컨피그 맵에 저장된 key:value 데이터가 컨테이너의 환경변수 key:value로 사용되기 때문에 쉘에서 echo $k8s와 같은 방법으로 값을 확인할 수 있다.

컨피그 맵의 값을 포드 내부의 파일로 마운트하여 사용하기

  • 생성된 cm을 포드 내의 특정 파일과 마운트하게 되면 포드내에서 해당 파일을 cat등으로 열어서 내용을 확인할 수 있다. 파일명이 key, value는 파일내에 기록되어 있다.

[configMap 실습]

root@manager:~/k8slab# kubectl create cm cmtest1 --from-literal name=gildong --from-literal age=24
root@manager:~/k8slab# kubectl create cm cmtest2 --from-literal name=chulsoo --from-literal age=25
root@manager:~/k8slab# cat cmtestpod.yml
apiVersion: v1
kind: Pod
metadata:
  name: cmtestpod
spec:
  containers:
  - name: cmtestpod-ctn
    image: busybox
    args: ['tail','-f','/dev/null']      #docker에 cmd와 같다
    envFrom:         # 환경 변수 설정
    - configMapRef:
        name: cmtest1
root@manager:~/k8slab# kubectl get pod
NAME        READY   STATUS    RESTARTS   AGE
cmtestpod   1/1     Running   0          63s
root@manager:~/k8slab# kubectl exec cmtestpod -- env
...
age=24
name=gildong
...
    1. configmap 을 볼륨처럼 이용하여 포드의 특정 파일과 마운트 시킨다
root@manager:~/k8slab# vi cmtestpodvol.yaml

apiVersion: v1
kind: Pod
metadata:
  name: cmtestpodvol
spec:
  containers:
  - name: cmtestpodvolctn
    image: busybox
    args: ['tail', '-f', '/dev/null']
    volumeMounts:
    - name: cmtestpod-volume
      mountPath: /etc/testcm
  volumes:
  - name: cmtestpod-volume
    configMap:
      name: cmtest2
root@manager:~/k8slab# kubectl get pod
NAME           READY   STATUS    RESTARTS   AGE
cmtestpod      1/1     Running   0          11m
cmtestpodvol   1/1     Running   0          32s
root@manager:~/k8slab# kubectl exec cmtestpodvol -- ls /etc/testcm
age  # 파일이름 = configmap 의 key 값
name  # 파일이름 = configmap 의 key 값
root@manager:~/k8slab# kubectl exec cmtestpodvol -- cat /etc/testcm/age
25
root@manager:~/k8slab# kubectl exec cmtestpodvol -- cat /etc/testcm/name
chulsoo

메트릭 서버 (HPA 를 통한 AutoScale 구성)

  • 각 포드의 자원사용량 정보를 수집하기 위한 도구
  • 메트릭 서버를 인터넷으로 부터 직접 설치하게 되면 공인인증서를 통한 인증이 먼저 수행되어야한다.
  • 하지만 우리는 해당 인증서 발급을 하지 않은 상태이므로 이 단계를 bypass하더라도 문제없도록 --kubelet-insecure-tls를 작성해 둔다.
  • 포드의 autoscale 은 지정된 자원사용량의 제한을 확인하고 이를 넘어서는 경우 수평적인 확장을 하게된다. 따라서 포드가 어느정도의 자원을 할당 받았는지 미리 지정해 두어야 한다.
참고 :
1000m 이 1 개의 CPU 
cpu: 500m -> 0.5 개
200m -> 0.2 개
  • 최소 보장값은 0.2 개
    만약 다른 포드에서 CPU 를 사용하고 있지 않아
    물리자원(CPU)에 여유가 있다면 이를 확장하여
    최대 0.5 개까지 사용하겠다.
    gke 에서 0.5 ~ 2 (VM)

Quiz.

    1. hpa 배포
    1. deployment + svc
    • deployment : replicas 3
    • svc : lb
    1. http://211.183.3.201
    1. hpa 를 이용하여 pod 의 cpu 사용량이 10% 를 넘어서게 되면 수평확장을 통해 최대 20개까지 사용가능하도록 하라. 단, min -> 1 개 로 지정한다
      Quiz. 그렇다면 replica 는 몇이 되는건가?? 3?? 1??
    1. 외부에서 트래픽을 보내본다.
      외부에서 http://211.183.3.201 로 ab 를 이용하여 트래픽을 보내본다.
      몇개까지 늘어나고 ab 중지 된 뒤 몇개까지 줄어드는가?

[해설]

1. 메트릭 서버 배포

root@master:~# wget \
https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/compon
ents.yaml
  • 깃허브에서 metric-server 소스코드 다운로드 후 파일 내용 수정
  • 매트릭 서버 배포하기
root@master:~# kubectl apply -f components.yaml

2. 테스트를 위한 포드와 서비스 배포

root@manager:~/k8slab# cat autoscaletest.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: autoscaletest
spec:
  selector:
    matchLabels:
      color: black
  replicas: 3
  template:
    metadata:
      labels:
        color: black
    spec:
      containers:
      - name: autoscaletest-nginx
        image: nginx
        ports:
        - containerPort: 80
        resources:
          limits:
            cpu: 500m
          requests:
            cpu: 200m
---
apiVersion: v1
kind: Service
metadata:
  name: autoscaletest-lb
spec:
  ports:
  - name: autoscaleest-port
    port: 80
  selector:
    color: black
  type: LoadBalancer
  • 포드와 서비스 LB 배포
root@master:~# kubectl apply -f autoscaletest.yaml
root@master:~# kubectl get deploy,svc
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/autoscaletest 1/1 1 1 108s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
AGE
service/autoscaletest-np NodePort 10.96.48.228 <none>
8080:30001/TCP 108s
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP
25h
  • HPA를 통한 오토스케일 구성
root@master:~# kubectl autoscale deploy autoscaletest --cpu-percent=20 --min=1
--max=10
  • 또는 아래와 같이 yaml 파일 작성후 배포
    또는 아래와 같이 yaml 파일 작성후 배포
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: test-hpa
spec:
  maxReplicas: 10
  minReplicas: 1
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: autoscaletest
  targetCPUUtilizationPercentage: 20

3. 트래픽 발생과 오토스케일 확인

  • 현재 상태 확인
root@master:~# kubectl get pod
NAME READY STATUS RESTARTS AGE
autoscaletest-7775f84674-9rxkx 1/1 Running 0 15m
root@master:~# kubectl top no --use-protocol-buffers ; kubectl get hpa
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
master 284m 7% 2744Mi 72%
node1 128m 6% 1103Mi 59%
node2 112m 5% 1043Mi 56%
node3 137m 6% 1054Mi 57%
NAME REFERENCE TARGETS MINPODS MAXPODS
REPLICAS AGE
autoscaletest Deployment/autoscaletest 0%/20% 1 10 1
5m14s
  • LB 포트 확인
root@manager:~/k8slab# kubectl get svc
NAME               TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
autoscaletest-lb   LoadBalancer   10.103.59.78   <pending>     80:30072/TCP   52m
kubernetes         ClusterIP      10.96.0.1      <none>        443/TCP        5h59m
  • 외부에서 부하 발생시키기
root@manager:~/k8slab# ab -c 1000 -n 200 -t 60 http://211.183.3.101:30072/

4. 현재 상태 재 확인

root@master:~# kubectl top no --use-protocol-buffers ; kubectl get hpa
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
master 1778m 44% 2742Mi 72%
node1 1553m 77% 1109Mi 60%
node2 1372m 68% 1079Mi 58%
node3 1107m 55% 1051Mi 57%
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
autoscaletest Deployment/autoscaletest 46%/20% 1 10 10 10m
root@master:~# kubectl get pod
NAME READY STATUS RESTARTS AGE
autoscaletest-7775f84674-4crq7 1/1 Running 0 19s
autoscaletest-7775f84674-4l66v 1/1 Running 0 19s
autoscaletest-7775f84674-9rxkx 1/1 Running 0 15m
autoscaletest-7775f84674-hnpkw 1/1 Running 0 49s
autoscaletest-7775f84674-hs5sp 1/1 Running 0 34s
autoscaletest-7775f84674-ld7vd 1/1 Running 0 34s
autoscaletest-7775f84674-pkvlb 1/1 Running 0 49s
autoscaletest-7775f84674-rdgt4 1/1 Running 0 34s
autoscaletest-7775f84674-xz8dh 1/1 Running 0 49s
autoscaletest-7775f84674-z5tdc 1/1 Running 0 34s

0개의 댓글