nayoungs
항상 끈기있게
nayoungs
  • 분류 전체보기 (274)
    • Cloud (21)
      • AWS (15)
      • Azure (3)
      • NCP (2)
      • GCP (1)
    • DevOps (68)
      • Docker (16)
      • Kubernetes (50)
      • CICD (2)
    • IaC (25)
      • Ansible (17)
      • Terraform (8)
    • Certification (4)
    • 금융 IT (5)
    • AI (3)
    • Linux (47)
    • 미들웨어 (5)
    • Programming (7)
      • GoLang (3)
      • Spring (4)
    • CS (25)
      • 네트워크 (17)
      • 운영체제 (5)
      • Web (1)
      • 개발 상식 (2)
      • 데이터베이스 (0)
    • Algorithm (59)
      • 프로그래머스 (36)
      • 백준 (18)
      • 알고리즘 정리 (5)
    • ETC (5)

블로그 메뉴

  • 홈
  • 방명록

공지사항

인기 글

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
nayoungs

항상 끈기있게

DevOps/Kubernetes

[Kubernetes] k8s ConfigMap과 Secret (feat. 컨테이너 환경 변수)

2022. 5. 25. 02:07
728x90

📌Index

  • 컨테이너 환경 변수
  • ConfigMap
  • Secret

 

✔️ 컨테이너 환경 변수

쿠버네티스 파드의 컨테이너를 위한 환경 변수를 정의하는 방법에 대해 알아본다.

 

pods.spec.containers.env

  • name
  • value
$ kubectl explain pods.spec.containers.env
KIND:     Pod
VERSION:  v1

RESOURCE: env <[]Object>

DESCRIPTION:
     List of environment variables to set in the container. Cannot be updated.

     EnvVar represents an environment variable present in a Container.

FIELDS:
   name <string> -required-
     Name of the environment variable. Must be a C_IDENTIFIER.

   value        <string>
     Variable references $(VAR_NAME) are expanded using the previously defined
     environment variables in the container and any service environment
     variables. If a variable cannot be resolved, the reference in the input
     string will be unchanged. Double $$ are reduced to a single $, which allows
     for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the
     string literal "$(VAR_NAME)". Escaped references will never be expanded,
     regardless of whether the variable exists or not. Defaults to "".

   valueFrom    <Object>
     Source for the environment variable's value. Cannot be used if value is not
     empty.

다음과 같이 yaml 파일에 env 필드를 작성하여 파드의 컨테이너에 환경 변수를 제공해보자.

 

myweb.yaml

apiVersion: v1
kind: Pod
metadata:
  name: myweb-env
spec:
  containers:
    - name: myweb
      image: ghcr.io/c1t1d0s7/go-myweb:alpine
      env: #환경변수
        - name: MESSAGE
          value: "Customized Hello World"
$ kubectl create -f myweb.yaml            
pod/myweb-env created
$ kubectl get po              
NAME                                      READY   STATUS    RESTARTS   AGE
myweb-env                                 1/1     Running   0          5s

파드에 접속하여 환경변수를 확인해보면,

환경 변수 MESSAGE=Customized Hello World가 정상적으로 등록된 것을 확인할 수 있다.

$ kubectl exec -it myweb-env -- sh
/ # env
KUBERNETES_PORT=tcp://10.233.0.1:443
KUBERNETES_SERVICE_PORT=443
HOSTNAME=myweb-env
SHLVL=1
HOME=/root
TERM=xterm
KUBERNETES_PORT_443_TCP_ADDR=10.233.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP=tcp://10.233.0.1:443
KUBERNETES_SERVICE_PORT_HTTPS=443
MESSAGE=Customized Hello World
KUBERNETES_SERVICE_HOST=10.233.0.1
PWD=/

 

✔️ ConfigMap

컨피그맵(ConfigMap)은 컨테이너에서 필요한 환경설정 내용을

컨테이너와 분리해서 제공해 주기 위한 기능으로,

key-value 쌍의 비기밀 데이터를 저장하는 데 사용하는 API 오브젝트이다.

 

파드에서 환경 변수(변수:값) 또는 파일(파일명:내용)을 제공할 수 있다.

 

사용 용도

  • 환경 변수
  • 볼륨/파일
    • 설정파일
    • 암호화 키/인증서

 

리소스 확인

$ kubectl api-resources| grep configmap 
configmaps                        cm           v1                                     true         ConfigMap

 

리소스 정의 방법 확인

$ kubectl explain cm

configmap은 spec이 없다.

 

 

immutable

 

default는 false이고,

true로 설정하면 해당 값은 나중에 변경할 수 없다. --> replace, edit, patch 등이 불가능하다.

$ kubectl explain cm.immutable  
KIND:     ConfigMap
VERSION:  v1

FIELD:    immutable <boolean>

DESCRIPTION:
     Immutable, if set to true, ensures that data stored in the ConfigMap cannot
     be updated (only object metadata can be modified). If not set to true, the
     field can be modified at any time. Defaulted to nil.

 

data

 

해시 방식으로 key:value를 지정한다.

$ kubectl explain cm.data       
...
FIELD:    data <map[string]string>

DESCRIPTION:
     Data contains the configuration data. Each key must consist of alphanumeric
     characters, '-', '_' or '.'. Values with non-UTF-8 byte sequences must use
     the BinaryData field. The keys stored in Data must not overlap with the
     keys in the BinaryData field, this is enforced during validation process.
  • 환경 변수 제공하기
    • containers.envFrom.configMapRef : configMap의 모든 데이터를 제공
    • containers.env.valueFrom.configMapKeyRef : 키를 직접 지칭
$ kubectl explain pods.spec.containers.envFrom.configMapRef
...
FIELDS:
   name <string>
     Name of the referent. More info:
     https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names

   optional     <boolean>
     Specify whether the ConfigMap must be defined
$ kubectl explain pods.spec.containers.env.valueFrom.configMapKeyRef
...
FIELDS:
   key  <string> -required-
     The key to select.

   name <string>
     Name of the referent. More info:
     https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names

   optional     <boolean>
     Specify whether the ConfigMap or its key must be defined
  • 볼륨으로 제공하기 : volumes.configMap
$ kubectl explain pods.spec.volumes.configMap 
...
FIELDS:
   defaultMode  <integer>
     Optional: mode bits used to set permissions on created files by default.
     Must be an octal value between 0000 and 0777 or a decimal value between 0
     and 511. YAML accepts both octal and decimal values, JSON requires decimal
     values for mode bits. Defaults to 0644. Directories within the path are not
     affected by this setting. This might be in conflict with other options that
     affect the file mode, like fsGroup, and the result can be other mode bits
     set.

   items        <[]Object>
     If unspecified, each key-value pair in the Data field of the referenced
     ConfigMap will be projected into the volume as a file whose name is the key
     and content is the value. If specified, the listed keys will be projected
     into the specified paths, and unlisted keys will not be present. If a key
     is specified which is not present in the ConfigMap, the volume setup will
     error unless it is marked optional. Paths must be relative and may not
     contain the '..' path or start with '..'.

   name <string>
     Name of the referent. More info:
     https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names

   optional     <boolean>
     Specify whether the ConfigMap or its keys must be defined

 

💻 실습 1 : 환경변수 참조하기

 

mymessage.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: mymessage
data: #key:value 지정
  MESSAGE: Customized Hello ConfigMap

mymessage 컨피그맵이 생성된 것을 확인할 수 있다.

$ kubectl create -f mymessage.yaml     
configmap/mymessage created
$ kubectl get cm                  
NAME               DATA   AGE
kube-root-ca.crt   1      7d14h
mymessage          1      3s

key:value 쌍이 1개이기 때문에 DATA는 1개이다.

 

다음으로 kubectl describe 명령을 통해 확인해보자.

$  kubectl describe cm mymessage                    
Name:         mymessage
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
MESSAGE:  #key
----
Customized Hello ConfigMap  #value

BinaryData
====

Events:  <none>

컨피그맵 테스트를 위해 파드를 한개 생성한다.

 

myweb-env.yaml : 2가지 방식 중에 선택

  • envForm.configMapRef : 컨피그맵의 모든 데이터를 등록
apiVersion: v1
kind: Pod
metadata:
  name: myweb-env
spec:
  containers:
    - name: myweb
      image: ghcr.io/c1t1d0s7/go-myweb:alpine
      envFrom: 
        - configMapRef: #컨피그맵을 참조
            name: mymessage #컨피그맵의 이름
  • env.valueForm.configMapkeyRef : 키를 직접 지정
apiVersion: v1
kind: Pod
metadata:
  name: myweb-env
spec:
  containers:
    - name: myweb
      image: ghcr.io/c1t1d0s7/go-myweb:alpine
      env:
        valueFrom:
          configMapKeyRef:
            name: mymessage
            key: MESSAGE
$ kubectl create -f myweb-env.yaml

sh을 통해 파드에 접속해보면, 환경변수 MESSAGE를 확인할 수 있다.

$ kubectl exec -it myweb-env -- sh            
/ # env
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://10.233.0.1:443
HOSTNAME=myweb-env
SHLVL=1
HOME=/root
TERM=xterm
KUBERNETES_PORT_443_TCP_ADDR=10.233.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP=tcp://10.233.0.1:443
MESSAGE=Customized Hello ConfigMap
KUBERNETES_SERVICE_HOST=10.233.0.1
PWD=/

이와 같이 envForm.configMapRef를 통해 컨피그맵의 환경변수를 참조할 수 있고,

앞서 [컨테이너 환경변수]에서 살펴봤듯이 env를 통해 직접 환경변수를 제공할 수도 있다.

편한 방법을 골라 사용하면 된다.

 


💻 실습 2 : 파일로 참조하기

 

configmap 파일은 실습1과 동일하게 mymessage.yaml을 사용한다.

 

myweb-cmvol.yaml

apiVersion: v1
kind: Pod
metadata:
  name: myweb-cm-vol
spec:
  containers:
    - name: myweb
      image: ghcr.io/c1t1d0s7/go-myweb:alpine
      volumeMounts:
        - name: cmvol
          mountPath: /myvol
  volumes: #볼륨 참조
    - name: cmvol
      configMap: #컨피그맵 이름
        name: mymessage
$  kubectl create -f myweb-cmvol.yaml 
pod/myweb-cm-vol created
$ kubectl get po                    
NAME                                      READY   STATUS    RESTARTS      AGE
myweb-cm-vol                              1/1     Running   0             5s

파드에 접속해서 확인해보면, /myvol 디렉토리에 MESSAGE 가 있는 것을 확인할 수 있다.

$ kubectl exec -it myweb-cm-vol -- sh
/ # cd /myvol
/myvol # ls -l MESSAGE
lrwxrwxrwx    1 root     root            14 May 24 15:53 MESSAGE -> ..data/MESSAGE
/myvol # cat MESSAGE
Customized Hello ConfigMap

key가 파일명이 되고, 파일 안의 데이터가 value가 된다.

 

 

✔️ Secret

value --base64--> encoded data

시크릿(secret)은 value를 base64로 인코딩하여 encoded data를 만든다.

 

시크릿은 암호, 키, 인증서 등 민감한 데이터를 저장하기위해 만들어졌으나,

기본적으로 base 인코딩만 할뿐 암호화를 하지 않기 때문에 안전하지 않다.

 

 

시크릿 타입

빌트인 타입 사용처
Opaque 임의의 사용자 정의 데이터(일반적인 텍스트)
kubernetes.io/service-account-token 서비스 어카운트 토큰
kubernetes.io/dockercfg 직렬화 된(serialized) ~/.dockercfg 파일
kubernetes.io/dockerconfigjson 직렬화 된 ~/.docker/config.json 파일
kubernetes.io/basic-auth 기본 인증을 위한 자격 증명(credential)
kubernetes.io/ssh-auth SSH를 위한 자격 증명
kubernetes.io/tls TLS 클라이언트나 서버를 위한 데이터
bootstrap.kubernetes.io/token 부트스트랩 토큰 데이터

 

리소스 정보

$  kubectl api-resources| grep secret   
secrets                                        v1                                     true         Secret

 

리소스 정의 방법 확인하기

$ kubectl explain secret
  • 환경변수 제공하기
    • containers.envFrom.secretRef
    • containers.env.valueFrom.secretKeyRef
$ ubectl explain pods.spec.containers.envFrom.secretRef
...
FIELDS:
   name <string>
     Name of the referent. More info:
     https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names

   optional     <boolean>
     Specify whether the Secret must be defined
$ kubectl explain pods.spec.containers.env.valueFrom.secretKeyRef   
...
FIELDS:
   key  <string> -required-
     The key of the secret to select from. Must be a valid secret key.

   name <string>
     Name of the referent. More info:
     https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names

   optional     <boolean>
     Specify whether the Secret or its key must be defined
  • 볼륨으로 제공하기
    • volumes.secret.secretName
$ kubectl explain pods.spec.volumes.secret.secretName                                     
...
FIELD:    secretName <string>

DESCRIPTION:
     Name of the secret in the pod's namespace to use. More info:
     https://kubernetes.io/docs/concepts/storage/volumes#secret

 

💻 실습 1 : 시크릿 생성하기

 

mydata.yaml

apiVersion: v1
kind: Secret
metadata:
  name: mydata
  type: Opaque
data:   
  id: admin
  pwd: P@ssw0rd

base64 인코딩을 하지 않았기 때문에, 실행 시 에러가 발생한다.

$ kubectl create -f mydata.yaml
error: error validating "mydata.yaml": error validating data: ValidationError(Secret.metadata): unknown field "type" in io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta; if you choose to ignore these errors, turn validation off with --validate=false

base인코딩 값을 확인하고, mydata.yaml파일을 수정한다.

$ echo "admin" | base64
YWRtaW4K
$ echo "P@ssw0rd" | base64
UEBzc3cwcmQK

mydata.yaml

apiVersion: v1
kind: Secret
metadata:
  name: mydata
type: Opaque
data:
  id: YWRtaW4K
  pwd: UEBzc3cwcmQK
$ kubectl create -f mydata.yaml

mydata 시크릿이 생성된 것을 확인할 수 있다.

$ kubectl get secret           
NAME                                 TYPE                                  DATA   AGE
mydata                               Opaque                                2      46s

secret은 configmap과 달리 데이터는 확인할 수 없고, 크기만 보여준다.

$ kubectl describe secret mydata
Name:         mydata
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
id:   6 bytes
pwd:  9 bytes

그러나 yaml로 보면, 인코딩된 데이터를 확인 가능하다.

$ kubectl get secret mydata -o yaml
apiVersion: v1
data:
  id: YWRtaW4K
  pwd: UEBzc3cwcmQK
kind: Secret
metadata:
  creationTimestamp: "2022-05-24T16:27:35Z"
  name: mydata
  namespace: default
  resourceVersion: "784587"
  uid: 692be111-7c60-4436-93a6-aa6fe56f813f
type: Opaque

 

💻 실습 2 : 환경변수 참조하기

secret 파일은 실습 1에서 사용한 것과 동일하게 mydata.yaml을 사용한다.

 

configMap과 마찬가지로 환경변수 참조 시, 2가지 방법이 가능하다.

  • envForm.secretRef
apiVersion: v1
kind: Pod
metadata:
  name: myweb-secret
spec:
  containers:
    - name: myweb
      image: ghcr.io/c1t1d0s7/go-myweb:alpine
      envFrom:
        - secretRef:
            name: mydata
  • env.valueFrom.secretKeyRef
apiVersion: v1
kind: Pod
metadata:
  name: myweb-env
spec:
  containers:
    - name: myweb
      image: ghcr.io/c1t1d0s7/go-myweb:alpine
      env:
        valueFrom:
          secretKeyRef:
            name: mydata 
            key: id
$ kubectl create -f myweb-secret.yaml

파드 컨테이너에 접속해서 환경 변수를 확인해보면,

id와 pwd 환경 변수가 정상적으로 설정된 것을 확인할 수 있다.

$ kubectl exec -it myweb-secret -- sh
/ # env
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://10.233.0.1:443
HOSTNAME=myweb-secret
SHLVL=1
HOME=/root
id=admin
pwd=P@ssw0rd
TERM=xterm
KUBERNETES_PORT_443_TCP_ADDR=10.233.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP=tcp://10.233.0.1:443
KUBERNETES_SERVICE_HOST=10.233.0.1

 

💻 실습 3 : 파일 참조하기

secret 파일은 실습 1,2에서 사용한 것과 동일하게 mydata.yaml을 사용한다.

 

myweb-sec-vol.yaml

apiVersion: v1
kind: Pod
metadata:
  name: myweb-sec-vol
spec:
  containers:
    - name: myweb
      image: ghcr.io/c1t1d0s7/go-myweb:alpine
      volumeMounts:
        - name: secvol
          mountPath: /secvol
  volumes:
    - name: secvol
      secret:
        secretName: mydata
$ kubectl create -f myweb-secret.yaml

파드 컨테이너에 접속해보면,

secvol/ 디렉토리에 key 값이 id와 pwd 파일이 있는 것을 확인할 수 있고,

파일의 내용은 각각의 value값과 같은 것을 확인할 수 있다.

$ kubectl exec -it myweb-sec-vol -- sh
/ # ls secvol/
id   pwd
/ # cat secvol/id
admin
/ # cat secvol/pwd
P@ssw0rd
/ # exit

 

 

 

참고

더보기

https://arisu1000.tistory.com/27843

 

728x90
저작자표시 비영리 (새창열림)
    'DevOps/Kubernetes' 카테고리의 다른 글
    • [Kubernetes] k8s 헤드리스 서비스(Headless Service)와 스테이트풀셋(StatefulSet)
    • [Kubernetes] TLS/SSL Termination with Ingress
    • [Kubernetes] k8s Volume : 동적 프로비저닝 with NFS & 기본 스토리지 클래스
    • [Kubernetes] k8s 디플로이먼트(Deployments)
    nayoungs
    nayoungs
    안되면 될 때까지

    티스토리툴바