0부터 시작하는 Kubernetes 공부 - Volume & NFS - MetalLB 실습

Jaehong Lee·2022년 9월 6일
1
post-thumbnail

apply 는 생성해서 배포하는 것이다

container 는 배포 / 가상머신은 provisioning 이다!

언제나 클러스터 실행 후 확인해야할 사항

kubectl get node
kubectl get pod -n kube-system  # calico, api, 스케줄러, controller
kubectl get pod -n metallb-system # controller, speaker
docker login
  • 위 명령어를 통해 모두 동작중인지 확인하라
    • 만약, 위 명령어 조차 실행이 안된다면, 현재 계정은 K8S 환경에 대한 Service Account 가 없는 상태다. /etc/kubernets/admin.conf 를 지정해주어야 한다

1. Volume 과 PV & PVC

Volume 과 PV & PVC

Volume

  • 관리자가 볼륨 제공, 요청을 동시에 수행한다
    • 관리자는 포드 구성 및 포드내에 저장소의 위치 ( IP ), 디렉토리 명등을 정확히 알고 있어야 한다

PV / PVC

  • PVC 는 개발자가, PV 는 관리자가 작성한다
  • PVC 는 볼륨이 어떤 형태로 제공되는지 ( NFS? ISCSI? ) 몰라도 된다. 단지, 자신이 필요한 볼륨의 유형과 크기만 작성하면 된다 ( rw!, ro!, one to one, many to one, 1GB )
  • PV 는 관리자가 NFS, ISCSI 등을 이용하여 적절한 크기의 볼륨을 만들어 이를 Pool 에 보관한다


    pod 의 pvc 를 확인하여, 해당 요청에 맞는 볼륨을 자동으로 pod 와 bond 시킨다

2. NFS

NFS 활용하여 Pod 배포

실질적으로 Pod 는 Node 의 Proxy 까지만 접근하면 되고, Node 외부에는 Proxy 가 나가기 때문에, Client 를 Pod 가 아닌, Node 에 설치한다

apiVersion: v1
kind: Pod
metadata:
  name: nfs-pod2
spec:
  containers:
    - name: nfs-mount-container
      image: busybox
      args: [ "tail", "-f", "/dev/null" ]
      volumeMounts:
      - name: nfs-volume
        mountPath: /mnt           # 포드 컨테이너 내부의 /mnt 디렉터리에 마운트합니다.
  volumes:
  - name : nfs-volume
    nfs:                            # NFS 서버의 볼륨을 포드의 컨테이너에 마운트합니다.
      path: /root/shared
      server: 211.183.3.100 

  • 배포해주자
  • Pod 에게 명령을 전달하여 mnt 디렉토리를 확인하면 파일이 있다

기본적으로 nfs 의 공유 저장소에 외부 사용자가 접속하여 파일을 생성하게 되면, 이 소유주는 nfsnobody 로 작성된다. 하지만 /etc/exports 에 no_root_squash 가 옵션으로 작성되어 있다면, 외부 사용자가 파일을 생성하더라도 root 로 기록된다

3. NFS & MetalLb 실습

확인 사항

선결 조건

  1. metallb 가 동작하고 있어야 한다

    • namespace 와 controller, speaker Pod 가 동작중인지 확인하자

    metallb 는 on-premise 환경에서 사용하기 어려운 service type LB 를 Pod 형태로 제공할 수 있는 방법으로, 각 LB 별로 필요한 구성 값을 추가햐여 배포해야 한다

  2. 생성된 Pod 에 Volume 을 연결할 계획이므로 master 에 nfs 서버가 구축되어 있어야 한다

    상태확인, 마운트 가능 여부를 확인하기 위해, worker node 에서 showmount -e 211.183.3.100 을 했을 때, 확인 가능해야 한다

시나리오

우리는 kia, sk 의 서비스 ( 서비스, deployment, volume ) 을 관리해주는 업체이다. 각 기업은 별도의 ns, address-pool on LB, Mount point ( Mount 하는 디렉토리 ) 를 가져야 한다

NFS 설정

  • nfs-server 가 동작중인지 확인하자
  • 각 기업의 Mount point 인 디렉토리를 생성하고, chmod 을 통해 권한 부여를 한다
    • R 옵션은 디렉토리에 들어있는 모든 것에 권한을 부여해주는 옵션이다

  • exports 에 외부에 접근을 허용할 디렉토리와 허용할 네트워크 대역을 설정해주고, nfs-server 를 재시작하여 설정을 반영하자
  • worker node 에서 잘 확인된다

Namespace 생성

  • 기업별 yaml 파일 생성
  • Namespace 의 버전 확인

kia

apiVersion: v1
kind: Namespace
metadata:
  name: kia
  • 위와 같이 ns 를 생성할 yaml 파일 을 작성하자
  • 생성 후 확인해주자

sk

  • sk Namespace 도 생성해주자

  • 두 가지 ns 를 생성했다

ConfigMap 배포

MetalLB 를 이용하여 사용하게 된 LB 의 주소 대역 지정

default : 211.183.3.201 ~ 211.183.3.210
kia : 211.183.3.211 ~ 211.183.3.220
sk : 211.183.3.221 ~ 211.183.3.230

ConfigMap yaml 파일 작성

apiVersion: v1
kind: ConfigMap
metadata:
  namespace: metallb-system
  name: config
data:
  config: |
    address-pools:
    - name: default
      protocol: layer2
      addresses:
      - 211.183.3.201-211.183.3.210
    - name: kia
      protocol: layer2
      addresses:
      - 211.183.3.211-211.183.3.220
    - name: sk
      protocol: layer2
      addresses:
      - 211.183.3.221-211.183.3.230
  • 리스트 형태로 작성했을 때는 각 줄이 구분된다. 허나, 리스트 형태가 아니라면, 여러 줄로 작성하여도 하나의 줄로 인식된다. 이를 | 를 사용하면, 각 줄을 구분해준다. | - 를 사용하면, 각 줄을 구분해주며, 마지막에 빈 줄이 있다면 삭제해준다

  • 우리는 Calico 에드온을 추가했기에 BGP 를 사용할 수 있다. 이는 주로 규모가 큰 프로젝트에서 ISP 와 직접 연결하여 사용한다. 우리는 그럴 필요가 없으므로 그냥 flat Network 를 구성하는 Protocol 을 layer2 로 설정하자

  • 각 ns 별로 Ip 주소 대역을 지정해주자

배포하기

  • 배포해주자

kia Deployment & SVC 배포 및 확인

각 회사별 deploy & svc 배포하기

apiVersion: apps/v1
kind: Deployment
metadata: #deployment
  namespace: kia 
  name: kia-deploy
spec: #replicaset
  replicas: 3
  strategy: 
    type: Recreate
  selector: 
    matchLabels: 
      app: kia
  template: #pod
    metadata: 
      labels: 
        app: kia
    spec: #container 
      containers:
      - name: kia-nginx
        image: nginx
        ports: 
        - containerPort: 80 # 컨테이너에서 연 포트 = 포드에서 연 포트 ( 자동 매핑된다 )
---
apiVersion: v1
kind: Service
metadata:
  name: nginx
  namespace: kia
  annotations:
    metallb.universe.tf/address-pool: kia # 사용할 address-pool 이름
spec:
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: kia
  type: LoadBalancer
  • 위와 같이 작성하자
    • Pod 에 대한 default Strategy 는 Rolling Update 이다

LB 배포시 사용할 MetalLB ConfigMap 에 정의된 address-pool 이름 을 metallb.universe.tf/address-pool 에 지정해야 한다. 이를 지정하지 않을시 address-pool 의 가장 첫번째 pool 부터 내려가며 남아있는 Ip 를 할당해준다

Pod 의 Port 는 Container 에서 연 Port 와 자동으로 매핑된다. 이는 반드시 같은 Port 번호로 매핑되며, 다른 번호끼리는 매핑이 되지 않는다. 따라서 nginx 의 경우 Pod 의 80 번 Port 와 연결된다. 따라서, target Port 나 ContainerPort 를 이미지에서 연 Port 와 다르게 설정하면 접속이 안된다

ex)
targetport : 85
containerport : 85
nginx
의 경우 서비스가 접속할 Port 와 Contianer 에서 오픈한 Port 가 85 로 연결되므로, 80 번인 nginx 에 접속이 불가능하다. 위 두 가지는 nginx 의 경우 80 번으로 모두 동일하게 설정해야 한다

  • EXTERNAL-IP 를 확인하자. ConfigMap 에 작성한대로 211~220 사이에서 할당되었다
  • 잘 접속된다

sk Deployment & SVC 배포 및 확인

apiVersion: apps/v1
kind: Deployment
metadata: #deployment
  namespace: sk 
  name: sk-deploy
spec: #replicaset
  replicas: 3
  strategy: 
    type: Recreate
  selector: 
    matchLabels: 
      app: sk
  template: #pod
    metadata: 
      labels: 
        app: sk
    spec: #container 
      containers:
      - name: sk-nginx
        image: nginx
        ports: 
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx
  namespace: sk
  annotations:
    metallb.universe.tf/address-pool: sk
spec:
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: sk
  type: LoadBalancer
  • 위와 같이 작성해주자
  • 배포해주자. Ip 는 설정한대로 221~230 사이에서 할당되었다
  • 잘 접속된다

sk NFS 설정 및 확인

deploy 배포시 kia 와 sk 의 모든 Pod 는 각 Pod 의 /test 디릭토리를 각각의 nfs-server 의 /kia , /sk 와 binding 되야 한다

  • 파일을 각각의 디렉토리에 생성하자
  • 이를 통헤 exec 로 Pod 에 ls 명령을 내렸을 때, 해당 파일을 확인할 수 있어야 한다
apiVersion: apps/v1
kind: Deployment
metadata: #deployment
  namespace: sk 
  name: sk-deploy
spec: #replicaset
  replicas: 3
  strategy: 
    type: Recreate
  selector: 
    matchLabels: 
      app: sk
  template: #pod
    metadata: 
      labels: 
        app: sk
    spec: #container 
      containers:
      - name: sk-nginx
        image: nginx
        ports: 
        - containerPort: 80
        volumeMounts: 
        - name: sk-vol
          mountPath: /test
      volumes: 
      - name: sk-vol
        nfs: 
          path: /sk
          server: 211.183.3.100
---
apiVersion: v1
kind: Service
metadata:
  name: nginx
  namespace: sk
  annotations:
    metallb.universe.tf/address-pool: sk
spec:
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: sk
  type: LoadBalancer
  • 위와 같이 Volume 부분을 추가해주자

  • 추가한 내용으로 Update 해주자
  • 잘 확인된다. 특정 ns 에 속한 것들에게 접근하려면, 반드시 -n 옵션으로 ns 를 명시해주자

kia NFS 설정 및 확인

apiVersion: apps/v1
kind: Deployment
metadata: #deployment
  namespace: kia 
  name: kia-deploy
spec: #replicaset
  replicas: 3
  strategy: 
    type: Recreate
  selector: 
    matchLabels: 
      app: kia
  template: #pod
    metadata: 
      labels: 
        app: kia
    spec: #container 
      containers:
      - name: kia-nginx
        image: nginx
        ports: 
        - containerPort: 80
        volumeMounts: 
        - name: kia-vol
          mountPath: /test
      volumes: 
      - name: kia-vol
        nfs: 
          path: /kia
          server: 211.183.3.100
---
apiVersion: v1
kind: Service
metadata:
  name: nginx
  namespace: kia
  annotations:
    metallb.universe.tf/address-pool: kia
spec:
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: kia
  type: LoadBalancer
  • kia 의 yaml 도 위와 같이 작성해주자
  • 배포해주자
  • 잘 확인된다

Load Balancer Ip 정적 할당

apiVersion: v1
kind: Service
metadata:
  name: nginx
  namespace: sk
  annotations:
    metallb.universe.tf/address-pool: sk
spec:
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: sk
  type: LoadBalancer
  loadBalancerIP: 211.183.3.225
  • 위와 같이 사용하고 싶은 Ip 를 정적으로 지정이 가능하다
    • 이는 위에서 사용하는 address-pool 의 Ip 범위 내에서 지정해야 한다
profile
멋진 엔지니어가 될 때까지

0개의 댓글