반응형

 

  • 볼륨을 사용해야하는 이유?

컨테이너 특성 상 어떠한 문제가 발생하여 컨테이너가 삭제 된다면 데이터도 같이 삭제 됩니다. 웹 소스 파일의 경우 이미지에 들어있어 삭제 되더라도 상관 없겠지만(컨테이너에서 웹소스를 변경하지 않는 이상) 로그 파일을 보관해야 한다거나, 데이터 베이스를 사용할 경우 실시간으로 생성되던 데이터가 사라지면 큰 장애가 발생 합니다.

이러한 이유로 컨테이너를 사용할 때 중요한 데이터가 있다면 볼륨을 사용하여 데이터를 보관해주어야 합니다.

 

  • 1-1. emptryDir 개념과 예시 코드

emptryDir은 Pod가 사라지면 볼륨도 같이 삭제되는 임시 볼륨의 성격을 가지고 있고 Pod가 실행되는 디스크의 공간에  볼륨 마운트를 하게 됩니다.

위의 이유로 Life cycle이 컨테이너가 아닌, Pod 단위로 되어있어서 컨테이너가 어떠한 문제로 삭제되어도 Pod는 실행중이므로 데이터는 emptyDir에 의해 보관되며 Pod가 삭제되는 순간 emptyDir로 보관중이던 모든 데이터는 삭제 됩니다.

apiVersion: v1
kind: Pod
metadata:
  name: emptydir-pod
spec:
  containers:
  - name: nginx
    image: nginx
    volumeMounts:
    - mountPath: /emptydir
      name: emptydir-volume
  volumes:
  - name: emptydir-volume
    emptyDir: {}
  • spec.containers.volumeMounts.mountPath → 실행될 컨테이너 안에 마운트할 경로 입니다. 컨테이너 안에 해당 디렉토리가 없더라도 자동으로 생성 해줍니다.
  • spec.containers.volumeMounts.mountPath → 마운트할 볼륨의 이름 입니다.
  • spec.voluems → 위에 작성한 emptydir-volume을 사용하도록 지정 해줍니다.

 

  • 1-2 emptyDir 기존 컨테이너 종료 후 새로운 컨테이너에 데이터가 남아있는지 확인

kubectl exec -it [pod name] bash을 입력하여 생성한 emptydir-pod의 쉘로 진입하여 확인하면 마운트 경로로 설정한 /emptydir이 자동으로 생성되어있는 모습을 볼 수 있습니다.

 

해당 Pod가 생성된 노드로 접속하여 emptydir-pod에 있는 nginx 컨테이너를 삭제 하였고, 이후 쿠버네티스에 의해 컨테이너가 다시 생성되는걸 확인 하였습니다.

 

다시 마스터 노드로 돌아와서 emptydir-pod에 bash로 접속 후 확인해보면 새로 생긴 컨테이너에 test.txt 파일이 남아있는것을 확인할 수 있습니다.

 

  • 1-3 emptyDir Pod 삭제 후 데이터가 삭제되는 내용 확인

emptrydir pod가 생성된 워커노드에서 아래와 같이 Pod 삭제 전/후를 비교하면 데이터가 삭제되는것을 확인하실 수 있습니다.

 

  • 2-1. hostPath 개념과 예시 코드

hostPath는 노드의 디스크에 볼륨을 생성하여 Pod가 삭제 되더라도 볼륨에 있던 데이터는 유지 됩니다.

apiVersion: v1
kind: Pod
metadata:
  name: hostpath-pod
spec:
  containers:
  - name: hostpath-pod
    image: nginx
    volumeMounts:
    - mountPath: /hostpath
      name: hostpath-volume
  volumes:
  - name: hostpath-volume
    hostPath:
      path: /tmp/hostpath   # 해당 디렉토리가 존재해야 합니다.
      type: Directory
  • spec.containers.volumeMounts.mountPath → 실행된 컨테이너 안에 마운트할 경로 입니다. 컨테이너 안에 해당 디렉토리가 없더라도 자동으로 생성 해줍니다.
  • spec.containers.volumeMounts.name → 마운트할 볼륨의 이름 입니다.
  • spec.voluems.name → 위에 작성한 hostpath-volume을 사용하도록 지정 해줍니다.
  • spec.voluems.hostPath → 노드에 마운트할 경로를 정해주고 해당 경로는 Directory 라는것을 명시 합니다. 해당 디렉토리는 노드에 생성되어 있어야 하며, DirectoryOrCreate를 사용할 경우 디렉토리가 존재하지 않으면 디렉토리를 생성 해줍니다.

주의해야할 점은 여러개의 워커노드를 사용중인 환경이라면 가장 밑에 있는 부분 중 DirectoryOrCreate가 아닌, Directory를 사용했을 경우 Pod가 실행될 노드의 path에 작성한 디렉토리가 있어야 하므로 잘 확인해주어야 합니다.

만약, Directory를 명시하고 path에 작성한 디렉토리가 없을 경우 ContainerCreating 상태에서 생성되지 않습니다.

 

  • 2-2 hostPath Pod 종료 후 노드에 데이터가 남아있는지 확인

테스트를 위해 hostpath-pod를 bash로 진입 후 볼륨 마운트했던 /hostpath에 테스트 파일을 생성 합니다. 

 

이후 hostpath-pod가 생성된 노드로 이동하여 볼륨 마운트했던 /tmp/hostpath 경로를 확인해보면 위에서 생성한 hostpath-test.txt 파일이 정상적으로 생성된것을 확인할 수 있습니다.

 

다시 마스터노드로 돌아와서 hostpath-pod를 삭제 후 hostpath-pod가 생성 되었던 노드로 이동하여 확인해보면 Pod가 삭제되도 데이터가 그대로 유지되는것을 확인할 수 있습니다.

 

참고로 Pod가 생성된 인스턴스는 kubectl describe [pod name] 을 입력하면 Pod가 생성된 노드의 호스트명을 확인할 수 있고, 2편(pv, pvc)은 아래 링크에서 확인 가능 합니다.

 

쿠버네티스 볼륨 개념 2편 (PersistentVolume, PersistentVolumeClaim) : https://nirsa.tistory.com/157

 

반응형
반응형

 

RBAC 개념 및 롤바인딩 : https://nirsa.tistory.com/154

 

  • 쿠버네티스 클러스터롤바인딩(clusterrolebinding) 이란?

클러스터롤은 특정 API나 리소스(pod,deploy 등), 사용권한(get, edit 등)을 매니페스트 파일에 명시해둔 규칙의 집합이 되며 클러스터 전체 사용 권한을 설정 해줍니다. 롤은 특정 네임스페이스의 권한만을 주므로 롤과 클러스터롤은 차이점이 있습니다.

클러스터롤바인딩은 사용자와 클러스터롤을 묶어주는 역할을 수행하고, 지정한 사용자들에 한해서 롤에 명시한 규칙들을 기준으로 권한을 사용할 수 있도록 관리 합니다.

 

  • 클러스터롤바인딩 구성

구성전에 간단한 디플로이먼트가 필요하며, 코드가 없으신분들은 아래 코드를 사용하시면 됩니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: test-deployment
  labels:
    app: test-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: test-deployment
  template:
    metadata:
      labels:
        app: test-deployment
    spec:
      containers:
      - name: test-deployment
        image: nginx:1.7.9
        ports:
        - containerPort: 80

 

  • 1. 클러스터롤 생성
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: dev-clusterrole
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list"]
  • apiGroups → api를 선택할 수 있으며 deployment를 사용한다면 apps를 추가 해주어야 합니다.
  • resources → pods를 사용할 수 있도록 설정 하며 그 외의 것은 모두 사용 불가 입니다. 추가적으로 더 실행시키고 싶은 resource(deployment, daemonset 등)가 있으면 추가 해주시면 됩니다.
  • verbs → get을 사용할 수 있도록 설정 하며 list가 없을 경우 resources와 apiGroups를 가져오지 못하는 상황이 발생하기 때문에 list를 넣어 주었습니다. 추가적으로 더 실행시키고 싶은 verbs(describe, edit, scale 등)이 있으면 추가 해주시면 됩니다.

 

  • 2. 사용자 생성

우선 아래 코드를 이용하여 ServiceAccount를 생성 후 apply 합니다.

apiVersion: v1
kind: ServiceAccount
metadata:
  name: dev01
  namespace: default

 

이후 아래 과정을 거쳐서 생성한 ServiceAccount의 secret token 값을 가져옵니다.

 

위 사진의 경우 token: 바로 앞인 eyJhb~~ 부분부터 복사 후 아래 명령어를 입력 합니다. 참고로 아래 명령어는 모두 $HOME_DIR/.kube/config 파일에 입력되며 해당 파일에서 직접 추가,수정,삭제를 해주셔도 됩니다.

# kubectl config set-credentials [생성할 계정명] --token=[확인한 secret token 값]
kubectl config set-credentials dev01 --token=eyJhb~~

# 아래 명령어 입력 후 클러스터명을 확인
kubectl config get-clusters

# kubectl config set-context [생성할 context명] --cluster=[확인한 클러스터명] --user=[위에서 생성한 계정명]
kubectl config set-context dev-user --cluster=cluster.local --user=dev01

## 참고 : 삭제 명령은 kubectl config delete-context [context명]

 

  • 3. 클러스터롤바인딩 생성
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: dev-clusterrolebinding
subjects:
- kind: ServiceAccount
  name: dev01
  namespace: default
  apiGroup: ""
roleRef:
  kind: ClusterRole
  name: dev-clusterrole
  apiGroup: rbac.authorization.k8s.io

 

  • context 전환 및 클러스터롤바인딩 확인

위에서 생성했던 context 으로 전환 해주세요.

# 사용 가능한 context 확인
kubectl config get-contexts

# dev-user context로 전환
# kubectl config use-context [변경할 context]
kubectl config use-context dev-user

# 현재 사용중인 context 확인
kubectl config current-context

 

kubectl get all을 하면 권한을 설정한 pods 말고는 모두 에러가 발생 합니다.

 

마지막으로, 해당 context는 권한이 한정되어 있으므로  다시 원래의 context로 전환 해주셔야 정상적인 이용이 가능 합니다.

# 사용 가능한 context 확인
kubectl config get-contexts

# dev-user context로 전환
# kubectl config use-context [변경할 context]
kubectl config use-context kubernetes-admin@cluster.local

# 현재 사용중인 context 확인
kubectl config current-context

 

반응형
반응형

 

  • 쿠버네티스 RBAC 이란?

쿠버네티스의 RBAC(Role-Based Access Control)은 역할(Role) 기반으로 쿠버네티스 시스템의 권한을 관리 합니다. 특정 사용자(User)와 역할(Role) 두가지를 조합하여 사용자에게 특정 권한을 부여할 수 있습니다.

 

  • 쿠버네티스 롤바인딩(rolebinding) 이란?

롤은 특정 API나 리소스(pod,deploy 등), 사용 권한(get, edit 등)을 매니페스트 파일에 명시해둔 규칙의 집합이 되며 특정 네임스페이스에 대한 권한을 관리 합니다.

롤바인딩은 위에 설명한 롤과 특정 사용자를 묶어주는 역할을 수행하고, 지정한 사용자들에 한해서 롤에 명시한 규칙들을 기준으로 권한을 사용할 수 있도록 권한을 관리 해줍니다.

예를들어 개발팀에게는 개발 전용 네임스페이스를 따로 만들어주고, 개발 전용 네임스페이스만을 컨트롤할 수 있는 계정을 부여하는 등의 일이 가능 해집니다. 또는 개발 전용 네임스페이스에서 get을 사용한 조회만이 가능한 계정을 부여할수도 있습니다.

 

  • 롤바인딩 구성

우선 롤바인딩을 구성하기 전에 원활한 테스트를 위해 간단한 디플로이먼트를 생성 하겠습니다. 없으신분들은 아래 코드를 복붙하여 kubectl apply -f [yaml파일명] 입력해서 실행 해주세요.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: test-deployment
  labels:
    app: test-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: test-deployment
  template:
    metadata:
      labels:
        app: test-deployment
    spec:
      containers:
      - name: test-deployment
        image: nginx:1.7.9
        ports:
        - containerPort: 80

 

  • 1. 룰 생성

간단한 롤을 구성한 파일 이며 apply 해줍니다. 참고로 이후에 설정할 롤바인딩은 롤의 name을 참조하여 사용 됩니다.

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: default
  name: role-dev
rules:
- apiGroups: ["", "apps"]
  resources: ["pods", "deployments"]
  verbs: ["get", "list", "edit"]
  • apiGroups → 사용할 api들을 명시 합니다. 쿠버네티스 특정 버전 이상부터는 각각의 resources 들을 사용하기 위한 api를 모두 지정해주어야 한다고 합니다. 위의 코드에서 deployments를 사용하기 위해선 apps api가 필요 합니다.
  • resources → pod, deployment과 같은 resources를 명시 합니다.
  • verbs → get, edit, list와 같은 verbs를 명시 합니다. list가 없으면 api와 resource를 읽어오지 못해 에러가 발생 합니다.

 

  • 2. 사용자 생성

우선 아래 코드를 이용하여 ServiceAccount를 생성 후 apply 합니다.

apiVersion: v1
kind: ServiceAccount
metadata:
  name: dev01
  namespace: default

 

이후 아래 과정을 거쳐서 생성한 ServiceAccount의 secret token 값을 가져옵니다.

 

위 사진의 경우 token: 바로 앞인 eyJhb~~ 부분부터 복사 후 아래 명령어를 입력 합니다. 참고로 아래 명령어는 모두 $HOME_DIR/.kube/config 파일에 입력되며 해당 파일에서 직접 추가,수정,삭제를 해주셔도 됩니다.

# kubectl config set-credentials [생성할 계정명] --token=[확인한 secret token 값]
kubectl config set-credentials dev01 --token=eyJhb~~

# 아래 명령어 입력 후 클러스터명을 확인
kubectl config get-clusters

# kubectl config set-context [생성할 context명] --cluster=[확인한 클러스터명] --user=[위에서 생성한 계정명]
kubectl config set-context dev-user --cluster=cluster.local --user=dev01

## 참고 : 삭제 명령은 kubectl config delete-context [context명]

 

  • 3. 롤바인딩 생성

롤바인딩 구성 파일 이며 subjects는 위에서 만든 사용자 계정을, roleRef는 위에서 만든 룰을 참조하고 있습니다. apply 해줍니다.

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: dev-rolebinding
  namespace: default
subjects:
- kind: ServiceAccount
  name: dev01
  apiGroup: ""
roleRef:
  kind: Role
  name: role-dev
  apiGroup: rbac.authorization.k8s.io

 

  • context 전환 및 롤바인딩 확인

위에서 생성했던 context 으로 전환 해주세요.

# 사용 가능한 context 확인
kubectl config get-contexts

# dev-user context로 전환
# kubectl config use-context [변경할 context]
kubectl config use-context dev-user

# 현재 사용중인 context 확인
kubectl config current-context

 

이제 role-dev.yaml 에서 입력했던 get, edit와 pods, deployment는 정상적으로 사용할 수 있어야 합니다.

 

하지만 정의해주지 않았던 명령(아래 이미지의 경우 scale)들은 아래와 같이 권한 에러가 발생 합니다.

 

마지막으로, 해당 context는 권한이 한정되어 있으므로  다시 원래의 context로 전환 해주셔야 정상적인 이용이 가능 합니다.

# 사용 가능한 context 확인
kubectl config get-contexts

# dev-user context로 전환
# kubectl config use-context [변경할 context]
kubectl config use-context kubernetes-admin@cluster.local

# 현재 사용중인 context 확인
kubectl config current-context

 

반응형
반응형

 

  • 쿠버네티스 Docker Hub-Private Image 가져오는 방법

Private Image를 가져와야 할 때 쿠버네티스의 secret을 이용하면 됩니다. 이 글에서는 Docker Hub을 기준으로 작성 합니다. 우선 Private Image 가져오는 방법인 만큼 아래와 같이 이미 Docker Hub에 이미지가 등록되어 있다는 가정하에 진행 합니다.

 

  • 쿠버네티스 매니페스트 파일 작성

저는 아래와 같이 간단한 Deployment를 설정해주는 매니페스트 파일(.yaml)을 작성 하였습니다.

Private Image를 가져와서 사용할 매니페스트 파일을 vi편집기로 여신 후 spec.template.spec.ImagePullSecrets.name 필드에 임의의 값을 설정 해줍니다. 이 값은 이후 생성할 secret name 이므로 참고하여 작성해주시면 됩니다. 또한 image 명도 재대로 입력 해주셔야 합니다.

* 매니페스트 파일에 필요한 필드만 작성 후 아직 apply는 하지 말아주세요.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-nginx
spec:
  selector:
    matchLabels:
      run: my-nginx
  replicas: 2
  template:
    metadata:
      labels:
        run: my-nginx
    spec:
      containers:
      - name: my-nginx
        image: nirsa/nginx		## docker hub 이미지 지정
        ports:
        - containerPort: 80
      imagePullSecrets:			## 참조할 secret name
      - name: dockersecret
  • spec.template.spec.containers.image → Docker Hub에 등록된 이미지의 이름을 등록 합니다. 일반적으로 [DockerHub사용자명]/[이미지이름] 의 형태를 가지며 뒤에 버전이 추가될 수 있습니다. 이미지명을 모른다면 docker hub 홈페이지에 접속하여 로그인 후 확인하시면 됩니다. 
  • spec.template.spec.ImagePullSecrets.name → 어떤 name을 가진 secret을 참조할 지 설정하는 부분 입니다. 이후 커맨드를 통해 생성할 name을 지정하게 되는데, 우선 저는 dockersecret으로 설정 하였습니다.

 

  • 쿠버네티스 secret 생성

쿠버네티스의 마스터 노드에서 아래와 같이 명령어를 입력 해줍니다. []으로 묶어준 부분들은 모두 상황에 따라 작성 해주셔야 하는 부분 입니다. 아래 내용을 참고하여 커맨드 작성 후 엔터를 치시면 secret이 생성된걸 확인할 수 있습니다.

  • [secret name] 은 위에서 작성했던 매니페스트 파일에 기입한 name을 작성해주셔야 합니다. (~ImagePullSecrets.name 부분에 작성한 내용으로, 저같은 경우 dockersecret 이 됩니다.)
  • Docker Hub 계정과 패스워드는 실제로 Private Image가 등록되어 있는 Docker Hub의 계정과 패스워드를 작성해주어야 합니다.
kubectl create secret docker-registry [secret name] --docker-username="[Docker Hub 계정]" \
--docker-password="[Docker Hub 패스워드]" --docker-server=https://index.docker.io/v1/

 

  • Private Image 파일을 잘 가져오는지 확인

이제 Docker Hub의 Private Image 파일을 가져올 준비는 모두 되었으니, 작성해두었던 매니페스트 파일을 apply 하여 실제로 잘 가져오는지 확인만 하면 됩니다.

kubectl describe [pod name] | grep Image 명령어를 통해 정상적으로 원하는 이미지 파일을 가져 왔는지도 볼 수 있습니다.

 

  • ImagePullBackOff 발생 시

만약 매니페스트 파일에 작성한 spec.template.spec.ImagePullSecrets.name 필드에 작성한 secret name이 다르다면 정상적으로 이미지 파일을 가져올 수 없습니다. 또는 secret에 등록한 docker hub 계정 정보가 달라 docker hub에 접근할 수 없어 이미지를 못가져와서 발생할수도 있습니다.

  1. 매니페스트 파일에 작성한 secret name과 생성한 secret name이 같은지 다시 한번 확인 해보세요. (secret name은 kubectl get secret 으로 확인할 수 있습니다. 만약 없다면 생성되지 않은것입니다)
  2. secret을 생성할때 등록한 docker hub의 계정 정보가 맞는지 확인 해보세요.

 

아래 예시는 secret name이 dockersecret으로 되어 있지만, 매니페스트 파일에는 dockersecret2로 저장하였고 그 후 apply 할 때 secret을 참조할 수 없어 이미지를 못가져오고 ImagePullBackOff가 발생합니다.

 

반응형

+ Recent posts