Secret

  • 보안유지가 필요한 자격증명 및 개인 암호화 키 같은 중요한 정보를 저장하고 분류하기 위해 제공되는 리소스

1) 특징

  • 패스워드 같은 기밀 정보를 Base64 인코딩으로 만들 수 있다.
  • key=value 쌍으로 사용한다.
  • 환경 변수로 secret 정보를 컨테이너에 전달할 수 있다.
  • 볼륨의 파일로서 시크릿 정보를 저장할 수 있다.
  • 메모리에 저장된다.
  • 시크릿 크기가 너무 커지면 쿠버네티스의 apiserver나 kubelet의 메모리를 많이 차지하게되기 때문에 개별 시크릿의 최대 크기는 1MB까지 정의한다.

 

2) 종류

  • Built in 시크릿(default-token secret)
    : 클러스터 내부에서 API 이용 시 사용됨
    : 내부에서 사용되는 계정인 Service account를 생성하면 자동으로 secret 생성
    : 만들어진 secret으로 해당 service account가 권한을 가지고 있는 API 접근 가능

  • 사용자 정의 시크릿
    : 말그대로 사용자가 정의한 시크릿
    : create 명령어를 사용하여 생성할 수 있고, yaml 파일에 정의해서 생성할 수도 있음

 

3) Secret vs ConfigMap

  • 민감하지 않은 일반 데이터는 configMap 리소스를 사용한다.
  • 중요 데이터가 포함되어 있으면 Secret 리소스를 사용하는 것이 좋다.

 

4) Built in Secret

  • 모든 Pod에는 자동으로 연결된 secret 볼륨이 존재한다.

 

$ kubectl describe pod [name]

Mounts:

      /var/run/secrets/kubernetes.io/serviceaccount from default-token-kf7wl (ro)


---------------------------

Volumes:

  default-token-kf7wl:

    Type:        Secret (a volume populated by a Secret)

    SecretName:  default-token-kf7wl

    Optional:    false

$kubectl describe secret default-token-kf7wl

Name:         default-token-kf7wl

Namespace:    default

Labels:       <none>

Annotations:  kubernetes.io/service-account.name=default

              kubernetes.io/service-account.uid=7223520f-e519-11e9-876a-025000000001


Type:  kubernetes.io/service-account-token


Data

====

ca.crt:     1025 bytes

namespace:  7 bytes

token:      eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImRlZmF1bHQtdG9rZW4ta2Y3d2wiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGVmYXVsdCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjcyMjM1MjBmLWU1MTktMTFlOS04NzZhLTAyNTAwMDAwMDAwMSIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OmRlZmF1bHQifQ.P4FnIdYC_JHXCM-RyboMkotOEkf2sRhRgXkyS9nUezIOddQ3lQGdsPI8ZXiIq1PPZN2KrXUMjq6B7rDJw3_A-zN2e1UwQfemPqllhrSNduy1WWwJTCsv71rjZmLrmrA5klmgW7DzizfLNgKY6hLpK7lSlA3pxIDzkdtYhG9AQ4oXPTym6LUCgPCO2DhonMVbbkQtRI2JoWvCdxS6geea-Kne4Op82lWFErv5zP0hmUhb5vyiFXGWBQYp-CZehiwAuNNg44_cyz3d6r_51oJAwcKiovxPRkqjJqiJfxG5gjDlPu6GT9Enbbh5Jo2x3hHYXwBqOV8CV0iT7ZyU_p2eEA


 

 

 

 

 

=> secret volume을 통해 제공되는 3가지 항목은 kubenetes API 서버와 안전하게 통신하기 위해 필요하다.

=> 즉 https 통신을 하기 위함

key

설명

ca-crt

certificate-authority , 인증서

 

 

5) 사용자 정의 시크릿

  • mac이나 linux에서 다음과 같은 명령어로 문자열을 base64로 인코딩 할 수 있다.

  • base64로 인코딩하는 이유는 ssl인증서나 binary 데이터의 지원을 위해 사용된다.

 

$ echo password | base64

cGFzc3dvcmQK

 

 

5.1) 시크릿 생성 - 명령어

$ echo -n ‘sa’ > ./username.txt
$ kubectl create secret generic h2-user-name --from-file=./username.txt

 

 

5.2) 시크릿 생성 - yaml 파일

apiVersion: v1
kind: Secret
metadata:
 name: mysqlsecret
type: Opaque
data:
 MYSQL_USER: cm9vdAo=
 MYSQL_PASSWORD: cm9vdAo=
in:/sbin:/bin



 

$ kubectl describe secret mysqlsecret

Name:         mysqlsecret
Namespace:    default
Labels:       
Annotations:  
Type:         Opaque

Data
====
MYSQL_PASSWORD:  5 bytes
MYSQL_USER:      5 bytes


Opaque 및 타입에 대해 알아보기

https://github.com/kubernetes/kubernetes/blob/7693a1d5fe2a35b6e2e205f03ae9b3eddcdabc6b/pkg/apis/core/types.go#L4394-L4478

 

 

5.3) 시크릿 적용

<simple-database-secret.yaml>

apiVersion: v1
kind: Secret
metadata:
 name: mysqlsecret
type: Opaque
data:
 MYSQL_USER: cm9vdAo=
 MYSQL_PASSWORD: cm9vdAo=in:/sbin:/bin

apiVersion: v1
kind: ConfigMap
metadata:
 name: database-config
data:
 MH_ADDR: "192.168.137.100"
 MYSQL_PORT: "3306"
 MYSQL_DATABASE: "sample"

---

apiVersion: apps/v1
kind: Deployment
metadata:
 name: health-check-app
 labels:
   app: healthcheck-test
spec:
 replicas: 1
 selector:
   matchLabels:
     app: healthcheck-test
 template:
   metadata:
     labels:
       app: healthcheck-test
   spec:
     containers:
       - name: health-check-app
         image: chulm/health-check-app:latest
         envFrom:
           - configMapRef:
               name: database-config
         env:
           - name: MYSQL_USER
             valueFrom:
               secretKeyRef:
                 name: mysqlsecret
                 key: MYSQL_USER
           - name: MYSQL_PASSWORD
             valueFrom:
               secretKeyRef:
                 name: mysqlsecret
                 key: MYSQL_PASSWORD
         ports:
           - containerPort: 8080

 

 

5.4) 환경변수 조회

$ kubectl exec health-check-app-86758956dd-lqb2t -- env | sort

 

....

KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_SERVICE_PORT=443
KUBERNETES_SERVICE_PORT_HTTPS=443
LANG=C.UTF-8
MH_ADDR=192.168.137.100
MYSQL_DATABASE=sample
MYSQL_PASSWORD=root
MYSQL_PORT=3306
MYSQL_USER=root

 

 

참조: https://kubernetes.io/docs/concepts/configuration/secret/

namespace

 쿠버네티스는 클러스터 안에 가상 클러스터를 또 만들 수 있다.

- kubectl get namespace

 

 

pod

 

1) yaml 파일 정의해서 생성하기

 

simple-pod.yaml

apiVersion: v1

kind: Pod

metadata:

 name: health-check-app

spec:

 containers:

   - name: health-app

     image: chulm/health-check-app:latest

     ports:

       - containerPort: 8080

 

 

key

설명

kind

쿠버네티스 리소스의 유형을 지정

metadata

쿠버네티스 리소스의 메타데이터 지정

spec

리소스를 정의하는 속성



$ kubectl apply -f simple-pod.yaml

 

2) pod 정보 조회

$ kubectl get pod

$ kubectl get pods --all-namespaces -o wide



3) pod 내부 컨테이너 실행

$ kubectl exec -it health-check-app sh -c health-app

 

4) 로그 보기

$ kubectl logs health-check-app

 

5) pod 삭제

$ kubectl delete pod health-check-app

 

6) 리소스 전체 삭제

$ kubectl delete -f simple-my-pod.yaml



7) 로컬 포트 포워딩

$ kubectl port-forward health-check-app 8080:8080 

 

replicaset

: 똑같은 정의를 갖는 파드를 여러 개 생성하고 관리하기 위한 리소스

 

simple-replicaset.yaml

apiVersion: apps/v1

kind: ReplicaSet

metadata:

 name: health-check-app

 labels:

   app: healthcheck-test

   environment: dev

spec:

 replicas: 3

 selector:

   matchLabels:

     app: healthcheck-test

 template:

   metadata:

     labels:

       app: healthcheck-test

   spec:

     containers:

       - name: health-check-app

         image: chulm/health-check-app:latest

         ports:

             - containerPort: 8080

 

 

key

설명

label

쿠버네티스의 리소스를 선택하는데 사용한다.

template

template 속성의 내용은 pod 메타데이터의 정의와 같다.

selector

라벨 조건을 정의, equality based selector와 set based selector가 존재


  1. equality based selector로 pod 조회


: 등가로 표현 (= , !=)

  • kubectl get pod -selector app=healthcheck-test


:약식으로는 -l 옵션으로 조회

  • kubectl get pod -l  app=healthcheck-test


  1. set based selector로 pod 조회 

: 집합형태로 표현 

  • kubectl get pod -l  ‘app in (healthcheck-test, other)’



 

1) replicaset 생성

 $ kubectl apply -f [file]

 

2) label 조회

$ kubectl get pods --show-labels

 


NAME                           READY STATUS RESTARTS AGE       LABELS

health-check-app-hng7g   1/1 Running 0       1m app=healthcheck-test

health-check-app-klg9q    1/1 Running 0     1m app=healthcheck-test

health-check-app-v6rhz    1/1 Running 0     1m app=healthcheck-test


3) replicatset 삭제

$ kubectl delete rs health-check-app --cascade=false 

  : cascade default는 true, pod이 삭제됨

 

4) pod 삭제할 경우

  : replicaset에 의해 복제된 개수가 유지되기 때문에 자동으로 Pod을 추가 생성




deployment

  : 애플리케이션 배포의 기본 단위가 되는 리소스, rs의 상위 리소스

 

simple-deployment.yaml

apiVersion: apps/v1

kind: Deployment

metadata:

 name: health-check-app

 labels:

   app: healthcheck-test

   environment: dev

spec:

 replicas: 3

 selector:

   matchLabels:

     app: healthcheck-test

 template: ### template 아래는 pod 리소스 정의와 같음.

   metadata:

     labels:

       app: healthcheck-test

   spec:

     containers:

       - name: health-check-app

         image: chulm/health-check-app:latest

         ports:

           - containerPort: 8080




  • deployment 리소스는 replicaSet 리소스를 관리한다.

https://www.pinterest.co.kr/pin/825003225467521861/

  • replicaSet의 리소스를 수정한다고 해서 revision이 변경되지는 않는다.

: 예로 replicas의 개수를 수정한다고 배포의 revision은 바뀌지 않으며, replicaSet만 변경된다.

 

  • 컨테이너를 변경하고 재 배포하면, 기존 컨테이너는 중지되고 revision 이 2가 된다.

$ kubectl rollout history deployment health-check-app 

deployments "health-check-app"

REVISION  CHANGE-CAUSE

1         kubectl apply --filename=simple-my-deployment.yaml --record=true

2         <none> (--record 옵션을 주지 않으면 명령어가 기록되지 않음)



1) yaml 파일 정의해서 생성하기
$ kubectl apply -f simple-deployment.yaml --record

(명령 실행 기록을 남기는 --record 옵션)

 

2) deployment revision 확인

$ kubectl rollout history deployment health-check-app
$ kubectl rollout history deployment health-check-app --revision=1

 

3) rollback 하기

$ kubectl rollout undo deployment health-check-app
$ kubectl rollout undo deployment health-check-app  --revision=1

 

4) deployment  진행 상태 확인

$ kubectl rollout status deployment health-check-app

 

5) deployment 상세 확인

$ kubectl describe deployment health-check-app 

 

service

: po의 집합(주로 rs)에 대한 서비스 디스커버리를 제공하는 리소스
: service의 대상이 되는 pod는 label selector로 정해진다.

 

  • service type 4가지가 존재함.
    cluster IP : cluster IP 생성

Node Port : cluster IP 생성 및 global port 개방
load Balancer : 로컬 환경에서는 사용 할 수 없음. 주로 클라우드 플랫폼에서 사용
external name : 셀렉터 및 포트 정의 하지 않음. externalName만으로 접근



simple-service.yaml

apiVersion: v1

kind: Service

metadata:

 name: healthcheck-nodeport

spec:

 type: NodePort

 ports:

   - port: 8080

     targetPort: 8080

 selector:

   app: healthcheck-test   ##label과 연결

 

1) service 조회
$ kubectl get svc

 

ingress

service로 nodePort를 노출시킬 때, l4(tcp) 레벨까지만 다룰 수 있기 때문에 http/https 경로를 기반으로 서비스를 전환하는 l7 레벨의 제어는 불가능하다. 이를 해결하기 위한 리소스가 ingress이다.

로컬 환경에서는 인그레스를 사용해 서비스를 노출 시킬 수 없기 때문에 nginx_ingress_controller를 다음과 같이 배포해야 한다.

 

1) ingress-nginx의 배포

-namespace

$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml

- service, pod

$kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/cloud-generic.yaml

 

2) ingress-nginx의 service와 pod 조회

$ kubectl -n ingress-nginx get svc, pod

 

NAME                    TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
service/ingress-nginx   LoadBalancer   10.106.139.137   localhost     80:32144/TCP,443:30813/TCP   14m

NAME                                            READY     STATUS    RESTARTS   AGE
pod/nginx-ingress-controller-75cb46c787-t48kr   1/1       Running   0          16m

 

3) simple-svc.yaml 생성 및 실행

apiVersion: v1
kind: Service
metadata:
name: healthcheck-svc
spec:
ports:
- name: http
port: 8080
targetPort: 8080
selector:
app: healthcheck-test

 

$ kubectl apply -f simple-svc.yaml

 

 

4) simple-ingress.yaml 생성 및 실행

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: healthcheck-ingress
spec:
rules:
- host: com.k8s.myapp
http:
paths:
- path: /
backend:
serviceName: healthcheck-svc
servicePort: 8080

 

 

 

$ kubectl apply -f simple-ingress.yaml

 

5) 테스트

$  curl http://localhost/healthCheck -H 'Host: com.k8s.myapp' 

 

> 결과

 

'Cloud & NoSQL & Middleware > Kubernetes' 카테고리의 다른 글

kubernetes - secret  (0) 2019.10.11
쿠버네티스 배경 및 입문  (0) 2019.09.03

배경

 

시대가 변함에 따라, 과거 모놀로틱 아키텍쳐의 많은 서비스를 거쳐 많은 프로젝트들이 MSA 기반의 트렌드로 변하고 있다.

이에 따라 애플리케이션들은 물리 서버 혹은 물리 서버의 VM(Virtual Machine)을 지나 도커와 같은 컨테이너 기반의 가상화 플랫폼위의 컨테이너에 존재하는 시대가 되었다.

 

 

 

Container Orchestration

컨테이너는 애플키에션을 포장하고 실행하며 관리하기에 좋은 도구이다. 하지만 컨테이너의 확장에 따라 이러한 컨테이너들의 관리해줄 도구가 분명 필요하다. 즉 간단하게 말해서 쿠버네티스는 컨테이너 관리 도구라고 생각하면 쉽다.

 

Apache Mesos, Docker Swarm, ECS 등 다양한 Container Orchestration이 존재하지만 확실하게 쿠버네티스는 높은 수준의 관리 기능을 제공해 주는 인기있는 툴이다.

 

 

Kubernetes

- 구글에서 15년간 프로덕션 워크로드 운영한 경험을 토대로 구축

- 컨테이너 운영을 자동화하기 위한 컨테이너 오케스트레이션 도구

- 약어 K8s ( k와 s 사이에 8글자라서.. 하하^^), Kube 등으로 불림

- 많은 수의 컨테이너를 협조적으로 연동하기 위한 통합 시스템

- 명령어 도구 kubectl 제공

- 러닝 커브가 좀 높다.

 

 

특징

  1. Service Discovey
    : 쿠버네티스는 DNS 및 자체 IP를 사용하여 컨테이너를 노출한다.
  2. load Balancing
     : 컨테이너의 트래픽이 많으면 로드밸런싱을 하여 배포한다.
  3. Storage Orchestraion
    : 로컬 저장소 및 클라우드와 시스템과 연동 및 자동 탑재한다.
  4. Self-Healing
    : 문제가 발생한 컨테이너를 자동 재시작한다.
  5. Automated rollout and rollback
    : 컨테이너의 원하는 상태를 서술하며 언제든지 변경가능하다.
  6. Batch execute
    : 스케쥴러 배치 작업이 가능하다. 
  7. Horizontal Scaling
    : CPU 사용에 따라서, 명령어 혹은 UI 등과 함께 Scale Up and Down이 가능하다.
  8. Docker Host Management

 

 

 

참고

 https://kubernetes.io/ko/docs/concepts/overview/what-is-kubernetes/

'Cloud & NoSQL & Middleware > Kubernetes' 카테고리의 다른 글

kubernetes - secret  (0) 2019.10.11
kubernetes - pod, rs, svc, deployment, ingress  (0) 2019.10.03

+ Recent posts