Volume

미리 준비된 사용 가능한 볼륨(호스트 볼륨/nfs 등) 등을 매니페스트에서 직접 지정하여 사용할 수 있게 하는 것이다. 사용자가 설정된 볼륨을 사용할 수 있지만, 쿠버네티스에서 신규 볼륨을 생성하거나 기존 볼륨을 삭제하는 작업은 할 수 없다. 또한, 매니페스트에서 볼륨 리소스를 생성하는 것도 불가능하다.

 

- emptyDir, hostPath, downwardAPI, projected, nfs, iscsi, cephfs

 

emptyDir

파드용 임시 디스크 영역으로 사용할 수 있다. 그리고 파드가 종료되면 삭제된다. 호스트의 임의 영역을 마운트할 수 없으며 호스트에 있는 파일을 참조할 수도 없다.

apiVersion: v1
kind: Pod
metadata:
  name: sample-emptydir-memory-with-memory-limits
spec:
  containers:
  - image: nginx:1.16
    name: nginx-container
    resources:
      limits:
        memory: 64Mi
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  volumes:
  - name: cache-volume
    emptyDir:
      medium: Memory #고속 tmpfs 메모리 영역, 삭제시 호스트 볼륨(컨테이너용 임시 디스크 영역) 사용
      sizeLimit: 128Mi

 

hostPath

쿠버네티스 노드상의 영역을 컨테이너에 매핑한다. 호스트의 임의 영역을 마운트할 수 있기 때문에 사용할 때는 호스트의 어떤 영역을 사용할지 지정해야한다. 보안상의 이유로 안전하지 않은 컨테이너가 업로드될 수 있으므로 사용하지 말 것을 권장한다.

Multi node 를 사용할 경우에는 hostPath를 사용하지말아야 한다. 그 이유는 Pod가 모든 노드에 동일한 데이터가 존재할 것으로 기대하기 때문이다. 대신에 , NFS 등 external replicated cluster storage를 사용해야한다. 

apiVersion: v1
kind: Pod
metadata:
  name: sample-hostpath
spec:
  containers:
  - image: nginx:1.16
    name: nginx-container
    volumeMounts:
    - mountPath: /srv
      name: hostpath-sample
  volumes:
  - name: hostpath-sample
    hostPath:
      path: /etc
      type: DirectoryOrCreate

Persistent Volume

외부 영구 볼륨을 제공하는 시스템과 연계하여 신규 볼륨을 생성하거나 기존 볼륨을 삭제하는 등의 작업이 가능하다. 

볼륨은 파드 정의 안에 직접 지정하는 형태로 연결하지만, 영구 볼륨은 개별 리소스로 생성한 후 사용한다. 즉 메니페스트를 사용하여 영구 볼륨 리소스를 생성해야한다. 또한, 영구 볼륨은 클러스터 리소스로 분류된다.

 

- GCE Persistent Disk, AWS Elastic Block Store, nfs, Container Storage Interface ...

 

접근 모드

- ReadWriteOnce(RWO) : 단일 노드에서 Read/Write 가능

- ReadOnlyMany(ROW) : 여러 노드에서 Read 가능

- ReadWriteMany(RWX) : 여러 노드에서 Read/Write 가능

 

Reclaim Policy

영구 볼륨을 사용한 후 처리 방법(삭제 또는 재사용)을 제어하는 정책이다. 즉, 영구 볼륨 클레임에서 사용된 후 그 볼륨 클레임이 삭제되었을 때 영구 볼륨 자체의 동작을 설정한다.

- Delete(default) : 영구 볼륨 자체가 삭제된다.

- Retain : 영구 볼륨 자체를 삭제하지 않고 유지한다. 또 다른 영구 볼륨 클레임에 의해 이 영구 볼륨이 다시 마운트되지 않는다.

- Recycle : 영구 볼륨 데이터를 삭제하고 재사용 가능한 상태로 만든다. 다른 영구 볼륨 클레임에서 다시 마운트 가능.

 

apiVersion: v1
kind: PersistentVolume
metadata:
  name: foo-pv
spec:
  storageClassName: ""
  claimRef:
    name: foo-pvc
    namespace: foo
  ...

Persistent Volume Claim

생성된 영구 볼륨 리소스를 할당하는 리소스다. 영구 볼륨은 클러스터에 볼륨을 등록만 하기 때문에 실제 파드에서 사용하려면 영구 볼륨 클레임을 정의하고 사용해야한다. 또한, 동적 프로비저닝 기능을 사용한 경우에는 영구 볼륨 클레임이 사용된 시점에 영구 볼륨을 동적으로 생성할 수 있다.

 

영구 볼륨 클레임에서 지정된 조건(용량, 레이블)을 기반으로 영구 볼륨에 대한 요청이 들어오면 스케줄러는 현재 가지고 있는 영구 볼륨에서 적당한 볼륨을 할당한다. 이때 주의해야할 것은 영구 볼륨 클레임 용량이 영구 볼륨 용량보다 작으면 할당된다는 점이다.

 

참고) The result of PVC deletion can be terminating because pvc is being used by a pod

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: sample-pvc
spec:
  selector:
    matchLabels:
      type: pv
    matchExpressions:
    - key: environment
      operator: In
      values:
      - stg
  resources:
    requests:
      storage: 3Gi
  accessModes:
  - ReadWriteOnce
  storageClassName: manual

파드에서 사용하는 예제는 아래와 같다.

 

apiVersion: v1
kind: Pod
metadata:
  name: sample-pvc-pod
spec:
  containers:
  - name: nginx-container
    image: nginx:1.16
    volumeMounts:
    - mountPath: "/usr/share/nginx/html"
      name: nginx-pvc
  volumes:
  - name: nginx-pvc
    persistentVolumeClaim:
      claimName: sample-pvc

참고)

- The same is true for ReplicaSets or Deployments. Add this to the pod template section of a Deployment on ReplicaSet.

volumeMounts를 하지 않는다면 Pod 재시작시 기존내용을 복구할 수 없다.

동적 프로비저닝

static provisioning : cloud provider에 디스크 요청 -> pv 생성 -> pvc 생성 -> pod definition 

영구 볼륨 클레임에서는 영구 볼륨을 미리 생성해 두고 영구 볼륨 클레임 요청에 따라 볼륨을 할당하는 순서로 진행되었다. 그래서 사전에 영구 볼륨을 생성해야 하는 번거로움과 영구 볼륨 클레임이 요청하는 용량 이상으로 영구 볼륨이 할당되어 낭비가 발생하는 문제가 있다.

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-vol1
spec:
  accessModes:
    - ReadWriteOnce
  capacity:
    storage: 500Mi
  gcePersistentDisk:
    pdName: pd-disk
    fsType: ext4

 

이런 문제를 해결하는 것이 동적 프로비저닝(Dynamic Provisioning)이다.

 

동적 프로비저닝을 사용한 영구 볼륨 클레임의 경우 영구 볼륨 클레임이 생성되는 타이밍에 동적으로 영구 볼륨을 생성하고 할당한다. 동적 프로비저닝을 사용하려면 사전에 어떤 영구 볼륨을 생성할지 정의한 StorageClass를 생성해야한다.

 

참고) storage class의 VolumeBindingMode(waitForFirstConsumer) -> pvc만 생성시 해당 pvc를 사용하는 pod를 기다림(pvc status : waitForFirstConsumer)

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: sample-storageclass
parameters:
  type: pd-ssd
provisioner: kubernetes.io/gce-pd
reclaimPolicy: Delete
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: sample-pvc-dynamic
spec:
  storageClassName: sample-storageclass
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 3Gi
apiVersion: v1
kind: Pod
metadata:
  name: sample-pvc-wait-pod
spec:
  containers:
  - name: nginx-container
    image: nginx:1.16
    volumeMounts:
    - mountPath: "/usr/share/nginx/html"
      name: nginx-pvc
  volumes:
  - name: nginx-pvc
    persistentVolumeClaim:
      claimName: sample-pvc-dynamic

 

영구 볼륨 클레임 조정을 사용한 볼륨 확장을 하고 싶을 경우 allowVolumeExpansion:true를 설정하자. 다만 영구 볼륨 클레임 조정은 디스크 크기를 확장할 수 있지만 축소할 수는 없다는 점에 주의하자. 또한 파드에 어태치된 볼륨 자체는 확장되는데, 그 위에 있는 파일 시스템 확장은 경우에 따라 잘라질 수 있다. 파일 시스템의 자동 확장은 파일 시스템으로 EXT3/EXT4/XFS를 사용하는 경우만 해당된다.

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: sample-storageclass-resize
parameters:
  type: pd-ssd
provisioner: kubernetes.io/gce-pd
reclaimPolicy: Delete
allowVolumeExpansion: true

스테이트풀셋에서 영구 볼륨 클레임

스테이트풀셋의 워크로드에서는 영구 데이터 영역을 사용하는 경우가 많다. spec.volumeClaimTemplate을 사용하면 영구 볼륨 클레임을 별도로 정의하지 않아도 자동으로 영구 볼륨 클레임을 생성할 수 있다. 또 컨테이너 내부의 volumeMounts에 volumeClaimTemplate 이름을 지정하는 것으로 완료된다.

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: sample-statefulset-with-pvc
spec:
  serviceName: stateful-with-pvc
  replicas: 2
  selector:
    matchLabels:
      app: sample-pvc
  template:
    metadata:
      labels:
        app: sample-pvc
    spec:
      containers:
      - name: sample-pvc
        image: nginx:1.16
        volumeMounts:
        - name: pvc-template-volume
          mountPath: /tmp
  volumeClaimTemplates:
  - metadata:
      name: pvc-template-volume
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 10Gi
      storageClassName: sample-storageclass

 

참고)

how much capacity is now available to the PVC?

--> kubectl get pvc -> capacity

 

Debugging?

kubectl explain persistentvolume --recursive | less

kubectl exec webapp -- cat /log/app.log


출처

- [책] 쿠버네티스 완벽가이드 마사오 아오야마 지음, 박상욱 옮김

- https://kubernetes.io/docs/concepts/storage/storage-classes/

- https://kubernetes.io/docs/concepts/storage/persistent-volumes/#claims-as-volumes

- https://github.com/container-storage-interface/spec

- https://docs.docker.com/engine/extend/legacy_plugins/

'클라우드 컴퓨팅 > 쿠버네티스' 카테고리의 다른 글

Kubernetes Networking  (0) 2021.12.05
Docker Network  (0) 2021.12.05
Kubernetes Security - Authentication/Authorization  (0) 2021.11.10
Kubernetes TLS/PKI 살펴보기  (0) 2021.11.08
Kubernetes Monitoring with Prometheus  (0) 2021.10.27

쿠버네티스에서는 Authenticate/Authorization/Admission Control 이라는 세 단계를 통해서 리소스가 등록된다.

Authenticate

Authentication 에서는 사용자명과 패스워드, 사용자명과 토큰으로 정상 사용자인지 확인한다. 그 외에 Certificates, External Authentication providers(LDAP 등), Service Accounts 을 사용하는 것도 가능하다.

kube-apiserver Basic authenticate 예시

- Auth file

# Static Password File
# user-details.csv
password123,user1,u0001
password123,user2,u0002
password123,user3,u0003
password123,user4,u0004
password123,user5,u0005

- curl -v -k https://master-node-ip:6443/api/v1/pods -u "user1:password123"


# Static Token File
# user-token-details.csv
# --token-auth-file=user-details.csv
KpjCVbI7rCFAHYPkByTIzRb7gu1cUc4B,user10,u0010,group1
rJjncHmvtXHc6MlWQddhtvNyyhgTdxSC,user11,u0011,group1
mjpOFIEiFOkL9toikaRNtt59ePtczZSq,user12,u0012,group2
PG41IXhs7QjqwWkmBkvgGT9glOyUqZij,user13,u0013,group2

- curl -v -k https://master-node-ip:6443/api/v1/pods --header "Authorization: Bearer KpjCVbI7rCFAHYPkBzRb7gu1cUc4B"

/etc/kubernetes/manifests/kube-apiserver.yaml : basic-auth-file

apiVersion: v1
kind: Pod
metadata:
	creationTimestamp: null
	name: kube-apiserver
	namespace: kube-system
spec:
	containers:
	- command:
		- kube-apiserver
		- --authorization-mode=Node,RBAC
		- --advertise-address=172.17.0.107
        - --allow-privileged=true
        - --enable-admission-plugins=NodeRestriction
        - --enable-bootstrap-token-auth=true
        - --basic-auth-file=user-details.csv
        image: k8s.gcr.io/kube-apiserver-amd64:v1.11.3
        name: kube-apiserver

 

Kubeadm basic authentication 예시

/tmp/users/user-details.csv

# User File Contents
password123,user1,u0001
password123,user2,u0002
password123,user3,u0003
password123,user4,u0004
password123,user5,u0005

 

Edit the kube-apiserver static pod configured by kubeadm to pass in the user details.

The file is located at /etc/kubernetes/manifests/kube-apiserver.yaml

 

Change Volume Mounts : /tmp/users

apiVersion: v1
kind: Pod
metadata:
name: kube-apiserver
namespace: kube-system
spec:
  containers:
  - command:
      - kube-apiserver
      <content-hidden>
  image: k8s.gcr.io/kube-apiserver-amd64:v1.11.3
  name: kube-apiserver
  volumeMounts:
  - mountPath: /tmp/users
    name: usr-details
    readOnly: true
  
  volumes:
  - hostPath:
    path: /tmp/users
    type: DirectoryOrCreate
    name: usr-details

 

Modify the kube-apiserver startup options to include the basic-auth file

apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
name: kube-apiserver
namespace: kube-system
spec:
  containers:
  - command:
      - kube-apiserver
      - --authorization-mode=Node,RBAC
      <content-hidden>
      - --basic-auth-file=/tmp/users/user-details.csv

 

Create the necessary roles and role bindings for these users : user1

---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
  resources: ["pods"]
  verbs: ["get", "watch", "list"]
 
---
# This role binding allows "user1" to read pods in the "default" namespace.
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: read-pods
  namespace: default

subjects:
- kind: User
  name: user1 # Name is case sensitive
  apiGroup: rbac.authorization.k8s.io

roleRef:
  kind: Role #this must be Role or ClusterRole
  name: pod-reader # this must match the name of the Role or ClusterRole you wish to bind to
  apiGroup: rbac.authorization.k8s.io

 

Once created, you may authenticate into the kube-api server using the users credentials

 

curl -v -k https://localhost:6443/api/v1/pods -u "user1:password123"

 


Authorization

Authorization 에서는 그 사용자가 하고자 하는 요청에 대해 실행 가능한 권한이 있는지를 제어한다.

 

RBAC(Role Based Access Control)는 어떤 조작을 허용하는지를 결정하는 롤을 생성하고 서비스 어카운트 등의 사용자에게 롤을 연결하여(롤바인딩) 권한을 부여한다. 또 AggregationRule을 사용하여 여러 롤을 집약한 롤을 생성할 수 있어 롤 관리성을 향상시킬 수 있다.

 

롤과 롤바인딩에는 네임스페이스 수준의 리소스(롤과 롤바인딩)와 클러스터 수준의 리소스(클러스터롤과 클러스터롤바인딩)가 있다.

 

kube-apiserver에서 RBAC 설정

kube-apiserver authorization-mode : AlwaysAllow or Node, RBAC, Webhook ...

ExecStart=/usr/local/bin/kube-apiserver \\
--advertise-address=${INTERNAL_IP} \\
--allow-privileged=true \\
--apiserver-count=3 \\
--authorization-mode=AlwaysAllow, RBAC, Webhook \\
--bind-address=0.0.0.0 \\

 

Role 정의

- kubectl get roles

- kubectl describe role {role_name}

 

apiGroups, resources, verbs 세 가지를 지정하고, apiGroups와 resources로 지정된 리소스에 대해 verbs 권한을 인가한다.

종류 개요
* 모두 처리
create 생성
delete 삭제
get 조회
list 목록 조회
patch 일부 업데이트
update 업데이트
watch 변경 감시

 

 

레플리카셋/디폴로이먼트/디플로이먼트의 스케일에 대해 모든 권한을 사용할 수 있는 롤을 기본 네임스페이스로 생성

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: sample-role
  namespace: default
rules:
- apiGroups:
  - apps
  - extensions
  resources:
  - replicasets
  - deployments
  - deployments/scale
  verbs:
  - "*"

특정 리소스에 대해서 접근권한을 줄수도 있다.

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: developer
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["list“, "get", “create“, “update“, “delete"]
  resourceNames: ["blue", "orange"]

 

롤 바인딩 정의

- kubectl get rolebindings

- kubectl describe rolebindings {role_bindings_name}

 

롤바인딩은 네임스페이스에 연결되는 리소스다. 사용자에 대해 특정 네임스페이스에서 롤 또는 클러스터롤에 정의한 권한을 부여한다.

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: sample-rolebinding
  namespace: default
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: sample-role
subjects:
- kind: ServiceAccount
  name: sample-serviceaccount
  namespace: default
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: devuser-developer-binding
subjects:
- kind: User
  name: dev-user
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: developer
  apiGroup: rbac.authorization.k8s.io

클러스터롤 정의

- kubectl get clusterroles xxx

 

클러스터롤은 rules에 nonResourceUrls를 지정할 수 있다는 점과 metadata.namespace를 지정할 수 없다는 점(전 네임스페이스에 적용된다)이 일반 롤과 다른점이다. nonResourceUrls는 헬스 체크용 엔드포인트나 버전 정보 표시용 엔드포인트의 URL이다.

 

모든 네임스페이스의 레플리카셋과 디폴로이먼트에 대해 get을 할 수 있는 권한과 /healthz와 /version의 Get 요청을 할 수 있는 클러스터롤을 생성한다.

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: sample-clusterrole
rules:
- apiGroups:
  - apps
  - extensions
  resources:
  - replicasets
  - deployments
  verbs:
  - get
  - list
  - watch
- nonResourceURLs:
  - /healthz
  - /healthz/*
  - /version
  verbs:
  - get

 

클러스터롤의 Aggregation

클러스터롤에만 여러 클러스터롤의 정의를 읽어오는 Aggregation 기능이 있다. Aggregation은 클러스터롤에 정의된 레이블을 기반으로 이루어지며, 집계되는 쪽 클러스터롤에 정의된 롤은 반영되지 않는다.

---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: sub-clusterrole1
  labels:
    app: sample-rbac
rules:
- apiGroups: [""]
  resources: ["deployments"]
  verbs: ["get"]

---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: sub-clusterrole2
  labels:
    app: sample-rbac
rules:
- apiGroups: [""]
  resources: ["services"]
  verbs: ["get"]

---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: sample-aggregated-clusterrole
aggregationRule:
  clusterRoleSelectors:
  - matchLabels:
      app: sample-rbac
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get"]

클러스터롤 바인딩 정의

클러스터롤바인딩은 네임스페이스에 연결되지 않은 클러스터 수준의 리소스다. 사용자에 대해 모든 네임스페이스에서 클러스터롤로 정의된 권한을 부여한다.

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: sample-clusterrolebinding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: sample-clusterrole
subjects:
- kind: ServiceAccount
  name: sample-serviceaccount
  namespace: default

 

 

 

유저가 접근 권한이 있는지 확인하고 싶다면?

 

Check Access

- kubectl auth can-i create deployments

- kubectl auth can-i delete nodes

- kubectl auth can-i create deployments --as dev-user

- kubectl auth can-i create pods --as dev-user --namespaces test

- kubectl auth can-i list storageclasses --as dev


참고

어드미션 컨트롤

어드미션 컨트롤 단계에서는 별도로 그 요청을 허가할지 판단하거나 요청받은 리소스를 변경하여 등록할 수 있다. 따라서 쿠버네티스 클러스터 관리자가 임의의 상태로 수정할 수 있으므로, 리소스의 limit가 등록되어 있지 않을 경우 등록하거나 리소스 쿼터 체크 처리를 이 단계에서 수행할 수 있다.

 

어드미션 컨트롤은 플러그인 형태로 되어 있어 ResourceQuota, PodSecurityPolicy 등을 제공한다.

 

Get API groups and resource names

root@controlplane:~# kubectl api-resources
NAME                              SHORTNAMES   APIVERSION                             NAMESPACED   KIND
bindings                                       v1                                     true         Binding
componentstatuses                 cs           v1                                     false        ComponentStatus
configmaps                        cm           v1                                     true         ConfigMap
endpoints                         ep           v1                                     true         Endpoints
events                            ev           v1                                     true         Event
limitranges                       limits       v1                                     true         LimitRange
namespaces                        ns           v1                                     false        Namespace
nodes                             no           v1                                     false        Node
persistentvolumeclaims            pvc          v1                                     true         PersistentVolumeClaim
persistentvolumes                 pv           v1                                     false        PersistentVolume
pods                              po           v1                                     true         Pod
podtemplates                                   v1                                     true         PodTemplate
replicationcontrollers            rc           v1                                     true         ReplicationController
resourcequotas                    quota        v1                                     true         ResourceQuota
secrets                                        v1                                     true         Secret
serviceaccounts                   sa           v1                                     true         ServiceAccount
services                          svc          v1                                     true         Service
mutatingwebhookconfigurations                  admissionregistration.k8s.io/v1        false        MutatingWebhookConfiguration
validatingwebhookconfigurations                admissionregistration.k8s.io/v1        false        ValidatingWebhookConfiguration
customresourcedefinitions         crd,crds     apiextensions.k8s.io/v1                false        CustomResourceDefinition
apiservices                                    apiregistration.k8s.io/v1              false        APIService
controllerrevisions                            apps/v1                                true         ControllerRevision
daemonsets                        ds           apps/v1                                true         DaemonSet
deployments                       deploy       apps/v1                                true         Deployment
replicasets                       rs           apps/v1                                true         ReplicaSet
statefulsets                      sts          apps/v1                                true         StatefulSet
tokenreviews                                   authentication.k8s.io/v1               false        TokenReview
localsubjectaccessreviews                      authorization.k8s.io/v1                true         LocalSubjectAccessReview
selfsubjectaccessreviews                       authorization.k8s.io/v1                false        SelfSubjectAccessReview
selfsubjectrulesreviews                        authorization.k8s.io/v1                false        SelfSubjectRulesReview
subjectaccessreviews                           authorization.k8s.io/v1                false        SubjectAccessReview
horizontalpodautoscalers          hpa          autoscaling/v1                         true         HorizontalPodAutoscaler
cronjobs                          cj           batch/v1beta1                          true         CronJob
jobs                                           batch/v1                               true         Job
certificatesigningrequests        csr          certificates.k8s.io/v1                 false        CertificateSigningRequest
leases                                         coordination.k8s.io/v1                 true         Lease
endpointslices                                 discovery.k8s.io/v1beta1               true         EndpointSlice
events                            ev           events.k8s.io/v1                       true         Event
ingresses                         ing          extensions/v1beta1                     true         Ingress
flowschemas                                    flowcontrol.apiserver.k8s.io/v1beta1   false        FlowSchema
prioritylevelconfigurations                    flowcontrol.apiserver.k8s.io/v1beta1   false        PriorityLevelConfiguration
ingressclasses                                 networking.k8s.io/v1                   false        IngressClass
ingresses                         ing          networking.k8s.io/v1                   true         Ingress
networkpolicies                   netpol       networking.k8s.io/v1                   true         NetworkPolicy
runtimeclasses                                 node.k8s.io/v1                         false        RuntimeClass
poddisruptionbudgets              pdb          policy/v1beta1                         true         PodDisruptionBudget
podsecuritypolicies               psp          policy/v1beta1                         false        PodSecurityPolicy
clusterrolebindings                            rbac.authorization.k8s.io/v1           false        ClusterRoleBinding
clusterroles                                   rbac.authorization.k8s.io/v1           false        ClusterRole
rolebindings                                   rbac.authorization.k8s.io/v1           true         RoleBinding
roles                                          rbac.authorization.k8s.io/v1           true         Role
priorityclasses                   pc           scheduling.k8s.io/v1                   false        PriorityClass
csidrivers                                     storage.k8s.io/v1                      false        CSIDriver
csinodes                                       storage.k8s.io/v1                      false        CSINode
storageclasses                    sc           storage.k8s.io/v1                      false        StorageClass
volumeattachments                              storage.k8s.io/v1                      false        VolumeAttachment

 

Security Context

컨테이너에 대한 보안 설정. 설정가능한 항목은 아래 표와 같다.

종류 개요
privileged 특수 권한을 가진 컨테이너로 실행
capabilites Capabilites의 추가와 삭제
allowPrivilegeEscalation 컨테이너 실행 시 상위 프로세스보다 많은 권한을 부여할지 여부
readOnlyRootFilesystem root 파일 시스템을 읽기 전용으로 할지 여부
runAsUser 실행 사용자
runAsGroup 실행 그룹
runAsNonRoot root에서 실행을 거부
seLinuxoptions SELinux 옵션
apiVersion: v1
kind: Pod
metadata:
  name: web-pod
spec:
  #Globally take effect on all pods
  runAsUser: 1000
  containers:
    - name: ubuntu
      image: ubuntu
      command: ["sleep", "3600"]
      securityContext:
        runAsUser: 1000
        capabilities:
          add: ["MAC_ADMIN"]
          drop: ["AUDIT_WRITE"]

* Capabilities are only supported at the container level and not at the POD level

 

 

Q. What is the user used to execute the sleep process within the 'ubuntu-sleeper' pod?

kubectl exec ubuntu-sleeper -- whoami 

> root

출처

- [강의] udemy - Certified Kubernetes Administrator

- [책] 쿠버네티스 완벽 가이드(마사야 아오야마 지음, 박상욱 옮김)

'클라우드 컴퓨팅 > 쿠버네티스' 카테고리의 다른 글

Docker Network  (0) 2021.12.05
Kubernetes Storage  (0) 2021.11.22
Kubernetes TLS/PKI 살펴보기  (0) 2021.11.08
Kubernetes Monitoring with Prometheus  (0) 2021.10.27
Helm으로 매니페스트 범용화하기  (0) 2021.10.26

TLS(Transport Layer Security)

TLS는 인터넷에서의 정보를 암호화 해서 송수신하는 프로토콜로서 SSL에 기반한 기술이며 국제 인터넷 표준화 기구에서 표준으로 인정받은 프로토콜이다. TLS 위에 HTTP 프로토콜을 얹어 보안된 HTTP 통신을 하는 것을 HTTPS라고 하며, 443 포트를 사용한다.

 

Symmetric / Asymmetric encryption

클라이언트와 서버사이에 같은 symmetric key를 가지고 통신할 때 해커가 키를 갈취할 수 있는 방법이 있어 asymmetric encryption에 대한 필요성이 제기된다.  Asymmetric encryption은 public key로 암호화하고, private key로 복호화하며 통신한다. 어떤 사람도 public key를 소유할 수 있지만 private key는 그렇지 않다.

 

TLS는 symmetric과 asymmetric encrption을 모두 사용한다. Asymmetric encryption은 클라이언트와 서버사이의 세션을 안전하게 유지하기 위해 사용되고, Symmetric encryption은 이 세션을 통해 데이터를 교환할 때 사용된다.

 

PKI(Public Key Infrastructure)

디지털 증명서의 생성, 관리, 배포, 사용, 저장 등 공개키 암호화의 관리에 필요한 역할, 정책 등 일련의 절차들을 포괄하는 개념이다.

 

- Public Key : *crt, *pem 등으로 발급된다.

- Private Key : *.key, *-key.pem 등으로 발급된다.

openssl genrsa -out my-bank.key 1024

--> my-bank.key

openssl rasa -in my-bank.key -pubout > mybank.pem

--> my-bank.key, mybank.pem

 

PKI 동작 방식을 순서대로 살펴보자.

 

public key를 보내주는 서버에 대해서 특정 에이전시가 사인해준다면(Certificate), 위험 사이트 인지 아닌지에 대해서 클라이언트가 알수 있게된다. 또한, 브라우저는 이 사인의 주체가 공인된 CA(Certificate Authority) 이라면 합법적이라고 판단하고, 그렇지 않다면 클라이언트에게 경고 메세지를 보낸다.

 

1. 서버는 CSR(certificate signing request)를 CA에게 보낸다.

openssl req -new -key my-bank.key -out my-bank.scr -subj "/C=US/ST=CA/O=MyOrg, Inc./CN=mydomain.com"

--> my-bank.key, my-bank.csr(Certificate Siging Request)

2. CA는 CA private key로 해당 요청을 사인한다.

3. CA 사인된 증명서를 서버에게 보낸다.(해커가 요청했을 경우 CA는 증명서를 발급하지 않는다)

------> 로컬 PC에는 CA의 Public Key를 가지고 있는 상태가 된다.

4. 최초 사이트에 접속을 하게 되면 유저에게 사인된 증명서 public key를 함께 보낸다.

5. 유저는 보유한 CA public key로 증명서를 검증하고, the public key를 얻게된다. 브라우저는 그 후 sysmetric key를 생성한다.

6. 사용자의 브라우저는 the symmetric key the public key로 암호화(encrypt)하여 서버에 보낸다.

7. 서버는 private key를 가지고 the symmetric key를 복호화(decrypt) 한다.(해커는 private key를 가지고있지 않기 때문에 복호화 불가!)

8. 사용자와 서버는 서로 the symmetric key를 갖게되고, 서로 데이터를 암호화하고 복호화할 수 있는 상태가된다.

(user/password 정보를 안심하고 입력해서 서버에 전달해도 되는 상태)

 

결론적으로  Asymmetric encryption은 sysmetric key 를 안전하게 암호화하는데 사용되고, Symmetric encryption은 sysmetric key 를 이용하여 안전하게 데이터를 교환할 때 사용된다고 할 수 있다.

 

서버가 클라이언트가 해커가 아니라는 것을 어떻게 판단할까?

 

1. 서버가 클라이언트에게 증명서를 요청한다.

2. 클라이언트는 public key와 private key를 생성한다 for CSR(certificate signing request).

3. 클라이언트는 CSR(certificate signing request)를 CA에 보내고, 증명서를 발급받는다.

4. 클라이언트는 CA로 부터 받은 증명서를 서버에 보낸다.

 

위의 과정은 브라우저와 서버사이에 내부적으로 일어나는 프로세스라서 유저가 관여하지 않는다. 이 과정까지 포함하여 PKI라고 부른다.

 

참고

* CA는 private key와 public key를 가진다. CA는 private CA(회사 내부), public CA로 나눌 수 있다.

- private key는 증명서를 서명하는데 사용하고,

- public key는 브라우저에 내장되어 있고, 증명서를 검사할 때 사용한다.

 

*The symmetric key : 랜덤 대칭 암호화키(Random symmetric encryption key) by 브라우저(동일한 키로 암호화/복호화)


이제 TLS와 PKI에 대해서 살펴보았으니 Kubernetes에서 어떻게 적용되는지 살펴보자.

TLS in Kubernetes

Certificate for Certificate Authority

- private key through openssl

openssl genrsa -out ca.key 2048
-> ca.key

- certificate signing request

openssl req -new -key ca.key -subj "/CN=KUBERNETES-CA" -out ca.scr
-> ca.csr

- sign certificates

oepnssl x509 -req -in ca.csr -signkey ca.key -out ca.crt
-> ca.crt

 

결과적으로 CA는 privat key와 root certificate file을 갖게된다.

 

Client Certificates

Admin : admin.crt, admin.key

- private key

openssl genrsa -out admin.key 2048
-> admin.key

- certificate signing request

openssl req -new -key admin.key -subj "/CN=kube-admin/O=system:masters" -out admin.csr
-> admin.csr

O=system:masters -> 그룹정보(admin user with admin privileges)

 

- signed certificate

openssl x509 -req -in admin.csr -CA ca.crt -CAkey ca.key -out admin.crt
-> admin.crt

 

결과적으로 client(admin)는 privat key와 certificate file을 갖게된다.

 

client private key와 certificate file은 2가지 형태로 사용될 수 있다.

 

첫째, command line으로 kube api-server로 리소스를 요청.

curl https://kube-apiserver:643/api/v1/pods \
--key admin.key --cert admin.crt
--cacert ca.crt

{
	"kind": :PodList",
    "apiVersion": "v1",
    "metadata": {
    	"selfLink": "/api/v1/pods",
    },
    "items": []
}

둘째, kube config 설정

apiVersion: v1
clusters:
- cluster:
    certificate-authority: ca.crt
    server: https://kube-apiserver:6443
  name: kubernetes
kind: Config
users:
- name: kubernetes-admin
  user:
    client-certificate: admin.crt
    client-key: admin.key

 

그 밖의 Client Certificates ...

Client Certificates
kube-scheduler scheduler.crt, scheduler.key
kube-controller-manager controller-manager.crt, controller-manager.key
kube-proxy kube-proxy.crt, kube-proxy.key
kube-api-server apiserver-kubelet-client.crt, apiserver-kubelet-client.key
apiserver-etcd-client.crt, apiserver-etcd-client.key
kubelet server kubelet-client.crt, kubelet-client.key

 

Server Certificates

Etcd-server & etcd-peer

- etcd
- --advertise-client-urls=https://127.0.0.1:2379
# ETCD server
- --key-file=/path-to-certs/etcdserver.key
- --cert-file=/path-to-certs/etcdserver.crt

- --client-cert-auth=true
- --data-dir=/var/lib/etcd

- --initial-advertise-peer-urls=https://127.0.0.1:2380
- --initial-cluster=master=https://127.0.0.1:2380
- --listen-client-urls=https://127.0.0.1:2379
- --listen-peer-urls=https://127.0.0.1:2380
- --name=master

# ETCD peer
- --peer-key-file=/etc/kubernetes/pki/etcd/peer.key
- --peer-cert-file=/path-to-certs/etcdpeer1.crt
- --peer-trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt

- --peer-client-cert-auth=true
- --snapshot-count=10000

# ROOT CA
- --trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt

 

Kube-api-server : apisever.crt, apiserver.key

- private key

openssl genra -out apiserver.key 2048
-> apiserver.key

- certificate signing request

openssl req -new -key apiserver.key -sub "/CN=kube-apiserver" -out apiserver.csr -openssl.cnf
-> apiserver.csr
# openssl.cnf
[req]
req_extensions = v3_req
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation,
subjectAltName = @alt_names
[alt_names]
DNS.1 = kubernetes
DNS.2 = kubernetes.default
DNS.3 = kubernetes.default.svc
DNS.4 = kubernetes.default.svc.cluster.local
IP.1 = 10.96.0.1
IP.2 = 172.17.0.87

- sign certificates

openssl x509 -req -in apiserver.csr -CA ca.crt -CAkey ca.key -out apiserver.crt

 

결과적으로 api server는 private key와 certificate file을 갖게된다.

 

 

예제) kube-apiserver 실행 with related certificates

ExecStart=/usr/local/bin/kube-apiserver \\
--advertise-address=${INTERNAL_IP} \\
--allow-privileged=true \\
--apiserver-count=3 \\
--authorization-mode=Node,RBAC \\
--bind-address=0.0.0.0 \\
--enable-swagger-ui=true \\

# ETCD client certificates
--etcd-cafile=/var/lib/kubernetes/ca.pem \\
--etcd-certfile=/var/lib/kubernetes/apiserver-etcd-client.crt \\
--etcd-keyfile=/var/lib/kubernetes/apiserver-etcd-client.key \\

--etcd-servers=https://127.0.0.1:2379 \\
--event-ttl=1h \\

# Kubelet client certificates
--kubelet-certificate-authority=/var/lib/kubernetes/ca.pem \\
--kubelet-client-certificate=/var/lib/kubernetes/apiserver-etcd-client.crt \\
--kubelet-client-key=/var/lib/kubernetes/apiserver-etcd-client.key \\

--kubelet-https=true \\
--runtime-config=api/all \\
--service-account-key-file=/var/lib/kubernetes/service-account.pem \\
--service-cluster-ip-range=10.32.0.0/24 \\
--service-node-port-range=30000-32767 \\

# ROOT certificate
--client-ca-file=/var/lib/kubernetes/ca.pem \\

# Kube api server certificates
--tls-cert-file=/var/lib/kubernetes/apiserver.crt \\
--tls-private-key-file=/var/lib/kubernetes/apiserver.key \\

--v=2

 

Kubelet-server certificates for kubelet nodes : kubelet.crt, kubelet.key

# kubelet-config.yaml(node01)
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
authentication:
  x509:
    clientCAFile: "/var/lib/kubernetes/ca.pem"
authorization:
  mode: Webhook
clusterDomain: "cluster.local"
clusterDNS:
  - "10.32.0.10"
podCIDR: "${POD_CIDR}"
resolvConf: "/run/systemd/resolve/resolv.conf"
runtimeRequestTimeout: "15m"
tlsCertFile: "/var/lib/kubelet/kubelet-node01.crt"
tlsPrivateKeyFile: "/var/lib/kubelet/node01.key"

 

이렇게 생성된 증명서들은 어디에 저장되어 있을까?

 

/etc/kubernetes/manifests/kube-apiserver.yaml

...

spec:
containers:
- command:
- kube-apiserver
- --authorization-mode=Node,RBAC
- --advertise-address=172.17.0.32
- --allow-privileged=true

- --client-ca-file=/etc/kubernetes/pki/ca.crt

- --disable-admission-plugins=PersistentVolumeLabel
- --enable-admission-plugins=NodeRestriction
- --enable-bootstrap-token-auth=true

- --etcd-cafile=/etc/kubernetes/pki/etcd/ca.crt
- --etcd-certfile=/etc/kubernetes/pki/apiserver-etcd-client.crt
- --etcd-keyfile=/etc/kubernetes/pki/apiserver-etcd-client.key

- --etcd-servers=https://127.0.0.1:2379
- --insecure-port=0

- --kubelet-client-certificate=/etc/kubernetes/pki/apiserver-kubelet-client.crt
- --kubelet-client-key=/etc/kubernetes/pki/apiserver-kubelet-client.key

- --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname

- --proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.crt
- --proxy-client-key-file=/etc/kubernetes/pki/front-proxy-client.key

- --secure-port=6443
- --service-account-key-file=/etc/kubernetes/pki/sa.pub
- --service-cluster-ip-range=10.96.0.0/12

- --tls-cert-file=/etc/kubernetes/pki/apiserver.crt
- --tls-private-key-file=/etc/kubernetes/pki/apiserver.key

 

/etc/kubernetes/pki/apiserver.crt 를 살펴보자.

 

- Subject : CN=kube-apiserver

- Alternative Names : ...

- Not After : F2b 11 05:39:20 2020 GMT

- Issuer : CN=kubernetes

openssl x509 -in /etc/kubernetes/pki/apiserver.crt -text -noout

Certificate:
Data:
Version: 3 (0x2)
Serial Number: 3147495682089747350 (0x2bae26a58f090396)
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=kubernetes
Validity
Not Before: Feb 11 05:39:19 2019 GMT
Not After : Feb 11 05:39:20 2020 GMT
Subject: CN=kube-apiserver
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:d9:69:38:80:68:3b:b7:2e:9e:25:00:e8:fd:01:
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
X509v3 Extended Key Usage:
TLS Web Server Authentication
X509v3 Subject Alternative Name:
DNS:master, DNS:kubernetes, DNS:kubernetes.default,
DNS:kubernetes.default.svc, DNS:kubernetes.default.svc.cluster.local, IP
Address:10.96.0.1, IP Address:172.17.0.27

Certificate Signing Request in Kubernetes

첬째, private key를 생성한다.

openssl genrsa -out jane.key 2048
-> jane.key

둘째, private key를 이용해서 csr을 생성한다.

openssl req -new -key jane.key -subj "/CN=jane" -out jane.csr
-> jane.csr
cat jane.csr | base64

셋째, csr 파일을 base64 처리한 뒤 request 필드에 입력한다.

apiVersion: certificates.k8s.io/v1beta1
kind: CertificateSigningRequest
metadata:
  name: jane
spec:
  groups:
  - system:authenticated
  usages:
  - digital signature
  - key encipherment
  - server auth
request:
     LS0tLSdfdfdff ...(jane.csr by base64)

 

Certificate Signing Request  조회, 제어

- kubectl get csr

- kubectl certificate approve jane

kubectl certificate deny jane

- kubectl delete csr jane

- kubectl get csr jane -o yaml

- certificate 원문을 확인하고 싶을 경우 : echo "LS0adsf ..." | base64 --decode

----BEGIN CERTIFICATE -----
xxxxxxxxxx
xxxxxxxxxx
xxxxxxxxxx
----END CERTIFICATE -----

 

Certificate Signing Request는 누가 관리할까?

 

kube-controller-manager

- csr에 대한 관리를 맡고 있음(csr-approving, csr-signing)

- root certificate : cluster-signing-cert-file, cluster-signing-key-file

# /etc/kubernetes/manifests/kube-controller-manager.yaml
spec:
containers:
- command:
- kube-controller-manager
- --address=127.0.0.1
# Root Certificates
- --cluster-signing-cert-file=/etc/kubernetes/pki/ca.crt
- --cluster-signing-key-file=/etc/kubernetes/pki/ca.key

- --controllers=*,bootstrapsigner,tokencleaner
- --kubeconfig=/etc/kubernetes/controller-manager.conf
- --leader-elect=true

- --root-ca-file=/etc/kubernetes/pki/ca.crt

- --service-account-private-key-file=/etc/kubernetes/pki/sa.key
- --use-service-account-credentials=true

 


여러 개의 Kubernetes cluster가 존재할 경우 kubectl context를 사용해서 손쉽게 원하는 클러스터 환경으로 전환할 수 있다. 이때 context에 대한 환경설정을 kubeConfig에 설정할 수 있다.

 

매번 다른 증명서로 리소스 조회를 요청하는 것은 아주 지루한 작업이 될 수 있다.

$ curl https://kube-apiserver:6443/api/v1/pods \
--key admin.key 
--cert admin.crt
--cacert ca.crt

{
	"kind": :PodList",
    "apiVersion": "v1",
    "metadata": {
    	"selfLink": "/api/v1/pods",
    },
    "items": []
}

$ kubectl get pods
--server kube-apiserver:6443
--client-key admin.key
--client-certificate admin.crt
--certificate-authority ca.crt

 

KubeConfig

kubectl을 설치하면 $HOME/.kube/config 파일에 context 설정을 할 수 있다.

 

아래는 자주 사용하는 명령어이다.

- kubectl config view

- kubectl config view --kubeconfig=my-custom-config

- kubectl config use-context prod-user@production

- kubectl config -h (help)

 

To use that context, run the command

>> kubectl config --kubeconfig=/root/my-kube-config use-context research


To know the current context, run the command

>> kubectl config --kubeconfig=/root/my-kube-config current-context

apiVersion: v1
kind: Config
current-context: my-admin@my-ground

# Contexts
contexts:
- name: my-admin@my-ground
  context:
    cluster: my-ground
    user: my-admin
    namespace: default
    
# Clusters
clusters:
- name: my-ground
  cluster:
    certificate-authority: ca.crt
    #certificate-authority-data: xxx(cat ca.crt | base64)
    server: https://my-ground:6443

# Users
users:
- name: my-admin
  user:
    client-certificate: admin.crt
    client-key: admin.key

 

증명서 없이 kube api server에 접근할 수 있는 방법이 있을까?

 

kubectl proxy

아래는 kube api server를 증명서 없이 접근하는 예시이다.

$ kubectl proxy
Starting to server on 127.0.0.1:8001

$ curl http://localhost:8081 -k
{
    "paths": [
    "/api",
    "/api/v1,
  
    ...


}

 


참고)

1. SSH access using 키페어(public key, private key)

ssh-keygen로 키페어 생성

- id_rsa(private key), id_rsa.pub(public key)

$ ssh-keygen -t rsa -f id_rsa
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in id_rsa.
Your public key has been saved in id_rsa.pub.
The key fingerprint is:
SHA256:rEDRHwUPEG/HgPZNhjFrFVTHpDfPKDBPjpEeRbpFjVU aicar@aicar-dev-baston-server
The key's randomart image is:
+---[RSA 2048]----+
|    ..o+**=+=*+.E|
|     .+.oOo=.oo  |
|    .. o==@ + o  |
|   .   +oo.% . = |
|    .   S + + . o|
|     . .     .   |
|      .          |
|                 |
|                 |
+----[SHA256]-----+

- ssh -i id_rsa user@server

서버에는 public key가 ~/.ssh/authorized_keys에 보관된다.

클라이언트는 private key로 서버에 접속할 수 있다.

 

2. 도커 로그

kubectl 동작하지 않을 경우 서비스 로그를 확인하고 싶을 경우 도커 로그를 활용하자.

docker ps -a
docker logs xxx

 

프로메테우스(Prometheus)는 CNCF가 호스트하는 오픈 소스 소프트웨어 모니터링 도구다.

 

프로메테우스 구성요소

- prometheus-alertmanager : 규칙에 위반하는 사항에 대해서 알람을 전송(메일, 슬랙 등).

- prometheus-kube-state-metrics : 메트릭 수집을 위한 /metrics 엔드포인트를 제공

- prometheus-pushgateway : application이 push gateway에 메트릭을 push 한 후, prometheus server가 pushgateway에 접근해 metric을 pull하는 방식. 프록싱으로 접근할 수 없는 곳에 데이터가 존재하는 경우 사용.

- prometheus-server : 저장소.

- prometheus-node-exporter : prometheus에게 메트릭 정보를 제공.

 

프로메테우스 서버가 수집하는 메트릭은 데이터 소스에서 수집하는 풀방식 아키텍처를 채용하고 있으므로 프로메테우스 서버가 데이터를 수집하러 가는 형태가 된다. 

출처 : https://prometheus.io/docs/introduction/overview/
출처 : https://medium.com/finda-tech/kube-state-metrics%EC%97%90-%EB%8C%80%ED%95%B4%EC%84%9C-1303b10fb8f8

Helm을 이용한 설치

- 옵션 확인

helm inspect values stable/prometheus

- 설치

helm install prometheus stable/prometheus
--set alertmanager.persistentVolume.storageClass="xx"
--set server.persistentVolume.storageClass="xx"
--set pushgateway.persistentVolume.storageClass="xx"

--set nodeExporter.tolerations[0].key=xxx \
--set nodeExporter.tolerations[0].operator=Exists \
--set nodeExporter.tolerations[0].effect=NoSchedule

- 업데이트

helm upgrade prometheus -f values.yaml stable/prometheus

- 삭제

helm uninstall prometheus

- Grafana 설치

helm install grafana stable/grafana \
--set datasources."datasources\.yaml".apiVersion=1 \
--set datasources."datasources\.yaml".datasources[0].name=Prometheus \
--set datasources."datasources\.yaml".datasources[0].type=prometheus \
--set datasources."datasources\.yaml".datasources[0].url=http://prometheus-server.default.svc.cluster.local \
--set datasources."datasources\.yaml".datasources[0].access=proxy \
--set datasources."datasources\.yaml".datasources[0].isDefault=true \

--set adminPassword='password' \

--set plugins=grafana-kubernetes-app

출처

- [Helm prometheus]

https://gruuuuu.github.io/cloud/l-helm-basic/

- [Grafana] 

https://grafana.com/grafana/dashboards/315

- [prometheus arch]

https://medium.com/finda-tech/kube-state-metrics%EC%97%90-%EB%8C%80%ED%95%B4%EC%84%9C-1303b10fb8f8

https://prometheus.io/docs/introduction/overview/

- [container restart] : https://stackoverflow.com/questions/41452930/how-can-i-alert-for-container-restarted

+ Recent posts