효율적인 어플리케이션 관리

  1. NameSpace
  2. ConfigMap
  3. Secret

Namespace

리소스를 논리적으로 구분하는 장벽

용도에 따라 컨테이너 목록을 구분할 수 있는 논리적인 그룹의 필요성

라벨과의 차이점은 ?

네임스페이스 목록 확인

kubectl get namespace
kubectl get ns
  • 네임스페이스는 포드, 레플리카셋, 서비스와 같은 리소스가 따로 존재하므로, 포드만 따로 보려고 할 때는
kubectl get pods --namespace default
or
kubectl get pods -n {NAMESPACE}

KUBE_SYSTEM

쿠버네티스 클러스터 구성에 필수적인 리소스와 설정 값이 모여있는 네임스페이스

kubectl get pods -n kube-system

생성한 적 없는 포드들을 확인할 수 있다.

보통 사용하는 default namespace와 논리적으로 구분되어 있어 보지 못한 것!

KUBE-SYSTEM은 쿠버네티스에 대한 충분한 이해가 없으면 건들지 않는 게 좋다

네임스페이스의 용도

  • 쿠버네티스 클러스터를 여러 명이 사용 시, 각 사용자마다 독립적인 네임스페이스 할당
  • 용도에 따라 여러 네임스페이스를 만들어, 특정 목적의 디플로이먼트, 서비스를 동작
  • 대부분 사용하는 경우는 모니터링, 로드 밸런싱, 인그레스 등의 특정 목적 </aside>

🐋 네임스페이스는 논리적 구분일 뿐, 물리적 구분이 아니다.

→ 같은 노드에 다른 네임스페이스의 리소스가 존재할 수 있음

네임스페이스와 라벨의 차이점

논리적 구분이라는 개념은 같으나 네임스페이스가 좀 더 넓은 범위를 커버한다.

라벨 목록 띄우기

kubectl get pods -l app=webserver
  • ResourceQuota라는 오브젝트를 이용하여 특정 네임스페이스의 리소스 사용을 제한할 수도 있으며
  • 애드미션 컨트롤러라는 기능을 이용해 특정 컨테이너에는 항상 사이드카 컨테이너가 붙도록 설정할 수 있음

네임스페이스 사용하기

네임스페이스 만들기

**yaml의 경우**
apiVersion: v1
kind: Namespace
metadata:
  name: production

**콘솔로 만들기
kubectl create namespace production

특정 네임스페이스 확인할 경우
kubectl get ns | grep production**

특정 네임스페이스에서 리소스 생성하기

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hostname-deployment-ns
  namespace: production
spec:
  replicas: 1
  selector:
    matchLabels:
      app: webserver
  template:
    metadata:
      name: my-webserver
      labels:
        app: webserver
    spec:
      containers:
      - name: my-webserver
        image: alicek106/rr-test:echo-hostname
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: hostname-svc-clusterip-ns
  namespace: production
spec:
  ports:
    - name: web-port
      port: 8080
      targetPort: 80
  selector:
    app: webserver
  type: ClusterIP

—- 를 사용하여 여러 개의 리소스를 생성할 수 있다. 위에는 디플로이먼트랑 서비스가 동시 실행된다.

모든 네임스페이스의 리소스 확인하기

kubectl get --all namespaces

네임스페이스의 서비스 접근하기

쿠버네티스 클러스에서 서비스 이름을 통해 포드를 접근할 수 있다는 건 = “같은 네임스페이스 내의 서비스”에 접근 가능하다는 의미.

{서비스이름}.{네임스페이스 이름}.svc 처럼 서비스 이름 뒤에 네임스페이스 이름을 붙이면
다른 네임스페이스의 서비스에 접근 가능하다.
curl hostname-svc-clusterip-ns.production.svc:8080 --silent | grep hello

🐋 서비스 DNS 이름에 대한 FQDN(Fully Qualified Domain Name)은 일반적으로 다음과 같이 정의

**<서비스 이름="">. <네임스페이스 이름="">. svc.cluster.local**

네임스페이스 삭제

네임스페이스 삭제 시, 네임스페이스에 존재하는 모든 리소스도 삭제가 된다.
kubectl delete namespace {NAMESPACE}

네임스페이스에 종속되는 오브젝트 & 독립적인 오브젝트

모든 리소스가 네임스페이스에 의해 구분되는 것은 아니다.

네임스페이스에 종속되는 오브젝트 목록

kubectl api-resources --namespaced=true

네임스페이스에 독립적인 오브젝트 목록

kubectl api-resources --namespaced=false

노드/네임스페이스처럼 쿠버네티스 클러스터에서 저수준인 오브젝트가 대표적인 예이다.

🐋 클러스터 관리를 위한 저수준의 오브젝트는 네임스페이스에 속하지 않을 수도 있다.

컨피그맵(Configmap)

YAML에 환경 변수를 직접 명시할 수도 있지만, 개발 환경에 따라 환경 변수만 다른 YAML 템플릿이 나올 수도 있음. 쿠버네티스는 YAML 파일과 설정 값을 분리하는 컨피그맵, 시크릿 제공

컨피그 맵을 사용하지 않으면, 환경변수만 다른 여러 개 파일이 필요하다.

컨피그맵 생성

kubectl create configmap {컨피그맵 이름} {각종 설정 값}
kubectl create configmap log-level-configmap -from-literal LOG_LEVEL=DEBUG
Log_Level의 환경변수가 DEBUG인 log-level-configmap 이라는 이름의 컨피그맵 생성

또는 -from-literal 옵션을 여러 번 사용하여 여러 개의 키-값을 지정할 수도 있다.
kubectl create configmap start-k8s --from-literal k8s=kubernetes \\
--from-literal container=docker

컨피그맵 설정 값 확인

kubectl get cm
kubectl get configmap

kubectl describe configmap log-level-configmap

kubectl get configmap long-level-configmap -o yaml

포드에 컨피그맵 지정

[##_Image kage@cPzlxU/btr8LidnwHO/Emelcl9jy2xpxElKbmz511/img.png CDM 1.3 {“originWidth”:1010,”originHeight”:305,”style”:”alignCenter”}_##]

세 가지 지정방식

  1. 컨피그맵의 값을 컨테이너의 환경변수로 사용
  2. 컨피그맵의 값을 포드 내부의 파일로 마운트해 사용
    1. EX) LOG_LEVEL=INFO라는 값을 가지는 컨피그 맵을 /etc/config/log_level이라는 파일로 마운트 하면, log_level 파일에는 INFO라는 값이 저장하게 된다. → Nginx.conf 등의 파일을 통해 설정값을 읽어드린다면 이점이 되는 방식
  3. 컨피그맵의 데이터를 컨테이너의 환경변수로 가져오기
apiVersion: v1
kind: Pod
metadata:
  name: container-env-example
spec:
  containers:
    - name: my-container
      image: busybox
      args: ['tail', '-f', '/dev/null']
      envFrom:
      - configMapRef:
          name: log-level-configmap
      - configMapRef:
          name: start-k8s

YAML 파일에서 envFrom 항목은 하나의 컨피그맵에 여러 개의 키-쌍 관계가 존재하더라도 모두 환경 변수로 가져오도록 설정한다.

환경변수 설정되었는지 확인

kubectl apply -f all-env-from-configmap.yaml

kubectl exec all-env-from-configmap env 
//컨테이너 내부의 환경변수 목록을 확인할 수 있다

여러 개의 환경변수 중 특정 데이터만 사용하기

apiVersion: v1
kind: Pod
metadata:
  name: container-selective-env-example
spec:
  containers:
    - name: my-container
      image: busybox
      args: ['tail', '-f', '/dev/null']
      env:
      - name: ENV_KEYNAME_1     # (1.1) 컨테이너에 새롭게 등록될 환경 변수 이름
        valueFrom: 
          configMapKeyRef:
            name: log-level-configmap
            key: LOG_LEVEL
      - name: ENV_KEYNAME_2  # (1.2) 컨테이너에 새롭게 등록될 환경 변수 이름
        valueFrom: 
          configMapKeyRef:
            name: start-k8s      # (2) 참조할 컨피그맵의 이름
            key: k8s             # (3) 가져올 데이터 값의 키
                                 # 최종 결과 -> ENV_KEYNAME_2=$(k8s 키에 해당하는 값)
                                 #              ENV_KEYNAME_2=kubernetes

컨피그맵의 내용을 파일로 포드 컨테이너에 마운트

apiVersion: v1
kind: Pod
metadata:
  name: configmap-volume-pod
spec:
  containers:
    - name: my-container
      image: busybox
      args: [ "tail", "-f", "/dev/null" ]
      volumeMounts:
      - name: configmap-volume          # volumes에서 정의한 컨피그맵 볼륨 이름 
        mountPath: /etc/config             # 컨피그맵의 데이터가 위치할 경로

  volumes:
    - name: configmap-volume            # 컨피그맵 볼륨 이름
      configMap:
        name: start-k8s

원하는 데이터만 마운트 하기

apiVersion: v1
kind: Pod
metadata:
  name: selective-cm-volume-pod 
spec:
  containers:
    - name: my-container
      image: busybox
      args: [ "tail", "-f", "/dev/null" ]
      volumeMounts:
      - name: configmap-volume
        mountPath: /etc/config       # 마운트되는 위치는 변경되지 않았습니다.
  volumes:
    - name: configmap-volume
      configMap:
        name: start-k8s
        items:                       # 컨피그맵에서 가져올 키-값의 목록을 나열합니다.
        - key: k8s                    # k8s라는 키에 대응하는 값을 가져옵니다.
          path: k8s_fullname         # 최종 파일 이름은 k8s_fullname이 됩니

파일로부터 컨피그맵 생성

$ kubectl create configmap {컨피그맵 이름} --from-file {파일 이름}

여러개의 환경변수를 가져올 경우
$ kubectl create configmap from-envfile --from-env-file {파일이름}

—from-file에서 별도의 키-값을 명시해주지 않으면 파일 이름이 key 파일 내용이 value가 된다.

컨피그 맵을 생성하지 않고 yaml 파일로 출력

$ kubectl create configmap {컨피그맵 이름} \\
--from-literal key=value --dry-run -o yaml

—dry-run : 특정 작업의 실행 가능 여부를 검토하는 API, 실제로 쿠버네티스 리소스를 생성하지는 않는다.

🐋 컨피그맵의 키-값 데이터가 너무 많아지면 YAML 파일의 길이가 불필요하게 길어진다.

→ 이 문제를 해결하기 위해 kustomize 기능을 사용하게 된다.

시크릿

시크릿은 SSH, 비밀번호 등 민감한 정보를 저장하기 위한 용도의 리소스이며, 네임스페이스에 종속된다.

시크릿 생성하기

kubectl create secret generic\\
my-password --from-literal password=1q2w3e4r

kubectl create secret generic \\
our-password --from-file pw1 --from-file pw2

시크릿 값을 포드로 가져오기

//전체 키값 불러오기
apiVersion: v1
kind: Pod
metadata:
  name: secret-env-example
spec:
  containers:
    - name: my-container
      image: busybox
      args: ['tail', '-f', '/dev/null']
      envFrom:
      - secretRef:
          name: my-password
//선택적 키값 불러오기 
apiVersion: v1
kind: Pod
metadata:
  name: selective-secret-env-example
spec:
  containers:
  - name: my-container
    image: busybox
    args: ['tail', '-f', '/dev/null']
    env:
    - name: YOUR_PASSWORD
      valueFrom:
        secretKeyRef:
          name: our-password
          key: pw2

포드 볼륨에 마운트 할 시

//전체 키값 마운트
apiVersion: v1
kind: Pod
metadata:
  name: secret-volume-pod
spec:
  containers:
    - name: my-container
      image: busybox
      args: [ "tail", "-f", "/dev/null" ]
      volumeMounts:
      - name: secret-volume          #  volumes에서 정의한 시크릿 볼륨 이름
        mountPath: /etc/secret             # 시크릿의 데이터가 위치할 경로
  volumes:
  - name: secret-volume            # 시크릿 볼륨 이름
    secret:
      secretName: our-password                  # 키-값 쌍을 가져올 컨피그맵 이름
//선택적 키값 마운트
apiVersion: v1
kind: Pod
metadata:
  name: selective-volume-pod
spec:
  containers:
  - name: my-container
    image: busybox
    args: [ "tail", "-f", "/dev/null" ]
    volumeMounts:
    - name: secret-volume
      mountPath: /etc/secret
  volumes:
  - name: secret-volume
    secret:
      secretName: our-password          # our-password 라는 시크릿을 사용
      items:                       # 시크릿에서 가져올 키-값의 목록
      - key: pw1                    # pw1라는 키에 대응하는 값이 사용됨.
        path: password1           # 최종 파일은 /etc/config/password1이 됨

kustomize

kustomize yaml파일 작성법

secretGenerator:                # 시크릿을 생성하기 위한 지시문
- name: kustomize-secret
  type: kubernetes.io/tls       # tls 타입의 시크릿을 생성 
  files:
  - tls.crt=cert.crt            # tls.crt 라는 키에 cert.crt 파일의 내용을 저장
  - tls.key=cert.key            # tls.key 라는 키에 cert.key 파일의 내용을 저장
시크릿을 생성하기 전에 kustomize로부터 생성될 시크릿을 미리 확인할 경우
kubectl kustomize ./

시크릿 생성 시
kubectl apply -k ./

config맵 생성 시

configMapGenerator:                # 컨피그맵을 생성하기 위한 지시문
- name: kustomize-secret
  files:
  - tls.crt=cert.crt            # tls.crt 라는 키에 cert.crt 파일의 내용을 저장
  - tls.key=cert.key            # tls.key 라는 키에 cert.key 파일의 내용을 저장

컨피그맵/시크릿 업데이트 하기

  1. kubectl edit 사용
  2. YAML 파일 변경 후 kubectl apply 사용
  3. kubectl patch

리소스 정리하기

kubectl delete deployment --all
kubectl delete pod --all
kubectl delete configmap --all
kubectl delete secret --all

단 서비스 어카운트와 연결된 시크릿은 삭제해도 쿠버네티스에 의해 자동으로 복구된다.