쿠버네티스에 대하여 - 9.6 (nfs,configMap,namspace,ingress)

양승현·2022년 9월 6일
0

kubernetes

목록 보기
7/18
post-thumbnail

볼륨(volume)

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

PV/PVC

  • PVC 는 개발자가, PV 는 관리자가 작성한다.
  • PVC 는 볼륨이 어떤형태로 제공되는지(nfs? iscsi?..) 몰라도 된다. 단지, 자신이 필요한 볼륨의 유형과 크기만 작성하면 된다. (rw!, ro!, one to one , many to one, 1g, 10g)
  • PV 는 관리자가 nfs, iscsi 등을 이용하여 적절한 크기의 볼륨을 만들어 이를 pool 에 보관한다.
root@manager:~/k8slab# echo $KUBECONFIG
/etc/kubernetes/admin.conf <-- 쿠버네티스 전체 관리자 admin
  • KUBECONFIG 는 service account 의 정보를 누구로 할 것인지 파일을 지정하는 변수
  • 현재 위치 파일의 pod 모두 삭제
root@manager:~/k8slab# kubectl delete -f .
kubectl get pod
kubectl get svc

nfs

    1. master 노드에 NFS 마운트를 위한 서버 설치
root@master:~# apt-get -y install nfs-server
root@master:~# systemctl status nfs-server | grep Active
Active: active (exited) since Thu 2022-03-31 08:39:45 KST; 10s ago
root@master:~# mkdir -p ~/pvpvc/shared
root@master:~# chmod 777 pvpvc/shared/
root@master:~# vi /etc/exports
root@master:~# # 아래 내용을 추가
/root/pvpvc/shared *(rw,no_root_squash,sync)
no_root_squash -> 외부 노드에서 작성한 파일을 로컬(nfs-server) 에서 확인했을 때 root 가 작성한것으로(소유주가 root) 간주해 준다. 
root@master:~# ufw disable
Firewall stopped and disabled on system startup
root@master:~# systemctl enable nfs-server --now
root@master:~# systemctl restart nfs-server
    1. 생성된 공유저장소 마운트를 위한 포드배포
root@master1:~/k8s# cat nfs-pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: nfs-pod
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/pvpvc/shared   # 변경해야 함
      server: 211.183.3.100  # 변경해야 함
    1. Pod에서 nfs 서버에 직접접속하는 것이 아니라 노드에서 접속하게 되므로 node1~node3
      에 nfs 클라이언트 설치
root@node1:~# apt-get -y install nfs-common
root@node2:~# apt-get -y install nfs-common
root@node3:~# apt-get -y install nfs-common
    1. Pod 배포와 마운트 확인
root@master:~/pvpvc# cat nfs-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nfs-pod
spec:
  containers:
  - name: nfs-mount-container
    image: nginx
    volumeMounts:
    - name: nfs-volume
      mountPath: /mnt
  volumes:
  - name: nfs-volume
    nfs:
      path: /root/pvpvc/shared
      server: 211.183.3.100

root@master:~/pvpvc# kubectl apply -f nfs-pod.yaml
root@master:~/pvpvc# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE ...
nfs-pod 1/1 Running 0 8s 192.168.166.141 node1 ...
root@master:~/pvpvc# kubectl exec nfs-pod -- ls /mnt
root@master:~/pvpvc# touch /root/pvpvc/shared/nfscheck.txt # nfs-server 에 파일 생성
root@master:~/pvpvc# kubectl exec nfs-pod -- ls /mnt # pod 에서 확인
nfscheck.txt
  • 기본적으로 nfs 의 공유 저장소에 외부 사용자가 접속하여 파일을 생성하게 되면 이 소유주는 "nfsnobody" 로 작성된다. 하지만 /etc/exports 에 no_root_squash 가 옵션으로 작성되어 있다면 외부 사용자가 파일을 생성하더라도 root 로 기록된다.
  • PV 생성
root@master:~/pvpvc# cat nfs-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs-pv
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
nfs:
path: /root/pvpvc/shared
server: 211.183.3.100
readOnly: false
root@master:~/pvpvc# kubectl apply -f nfs-pv.yaml
persistentvolume/nfs-pv created
root@master:~/pvpvc# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS
REASON AGE
nfs-pv 1Gi RWX Retain Available
5s
  • pvc, pod 생성과 생성된 pv 와의 연결상태 확인
root@master:~/pvpvc# cat nfs-pod-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-nfs-pvc
spec:
storageClassName: ""
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: Pod
metadata:
name: nfs-mount-container
spec:
containers:
- name: nfs-mount-container
image: nginx
volumeMounts:
- name: nfs-volume
mountPath: /mnt
volumes:
- name: nfs-volume
persistentVolumeClaim:
claimName: my-nfs-pvc
root@master:~/pvpvc# kubectl apply -f nfs-pod-pvc.yaml
persistentvolumeclaim/my-nfs-pvc created
pod/nfs-mount-container created
root@master:~/pvpvc#
root@master:~/pvpvc# kubectl get pv,pvc
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM
STORAGECLASS REASON AGE
persistentvolume/nfs-pv 1Gi RWX Retain Bound
default/my-nfs-pvc 6m51s
NAME STATUS VOLUME CAPACITY ACCESS MODES
STORAGECLASS AGE
persistentvolumeclaim/my-nfs-pvc Bound nfs-pv 1Gi RWX
9s
root@master:~/pvpvc# kubectl get pod | grep nfs-mount
nfs-mount-container 1/1 Running 0 29s
root@master:~/pvpvc# kubectl exec nfs-mount-container -- df | grep /mnt
211.183.3.100:/root/pvpvc/shared 19992576 11765248 7188480 63% /mnt
root@master:~/pvpvc# # volume 이 아닌 nfs를 사용하고 있어 1G 로 표시되지는 않음

[실습]

    1. 211.183.3.100 에 nfs-server 를 구축한다
    1. manager 에 /shared 디렉토리를 생성하고 퍼미션을 777 로 조정한다.
    1. /etc/exports 에 /shared 를 외부에 공개하도록 설정한다.
      단, 포드에서만 접속이 가능하도록 해야 한다. 어떤주소를 허용해야 하는가?
    /shared    211.183.3.0/24(rw,no_root_squash,sync)
    1. nfs-server 활성화/실행
    1. 위의 pod 구성을 위한 매니페스트 파일을 참고하여 포드3개를 배포하고 포드의 /mnt 를 nfs-server 의 /shared 와 마운트한다.
    1. manager 에서 /shared 에 임의 파일(test.txt)을 생성하고 포드에서 exec 를 활용하여 해당 파일을 볼 수 있어야 한다. 단 모든 포드에서 볼 수있어야 한다.

[실습1]

선결조건

  • metallb 가 준비된 상태이어야 한다. on-premise 환경에서 사용하기 어려운 service type LoadBalancer 를 포드 형태로 제공할 수 있는 방법
  • 각 LB 별로 필요한 구성값을 추가하여 배포해야 한다.
  • 생성된 포드에 볼륨을 연결할 계획이므로 master 에 nfs 서버가 구축되어 있어야 한다.
    (상태확인, 마운트 가능여부 확인을 위해 , node 에서 showmount -e 211.183.3.100)

시나리오.

  • 우리는 kia, sk 의 서비스(서비스(nodeport/lb), deployment, volume) 을 관리해 주는 업체이다
  • kia, sk 는 별도의 ns , address-pool on LB, mount point

1. nfs

  • nfs 에서의 구성
root@manager:~/k8slab# systemctl status nfs-server | grep Active        
Active: active 
  • 모든 파일과 디렉터리 권한을 777로 부여
root@manager:~/k8slab# mkdir /kia /sk
root@manager:~/k8slab# chmod 777 /sk -R
root@manager:~/k8slab# chmod 777 /kia -R
root@manager:~/k8slab# tail -2 /etc/exports
/kia            211.183.3.0/24(rw,sync,no_root_squash)
/sk             211.183.3.0/24(rw,sync,no_root_squash)
root@manager:~/k8slab# systemctl restart nfs-server
  • [확인@worker1~3]
root@worker2:~# showmount -e 211.183.3.100
Export list for 211.183.3.100:
/sk     211.183.3.0/24
/kia    211.183.3.0/24
/shared 211.183.3.0/24
  • 파일 생성
root@manager:~/k8slab# mkdir lab1; cd lab1
root@manager:~/k8slab/lab1# touch kia-ns.yaml sk-ns.yanl

2. namespace

  • ns 버전 확인
root@manager:~/k8slab/lab1# kubectl api-resources | grep Name
namespaces                        ns           v1                                     false        Namespace
  • namespace 생성
root@manager:~/k8slab/lab1# cat kia-ns.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: kia
root@manager:~/k8slab/lab1# kubectl create ns kia
  • namespace 생성
root@manager:~/k8slab/lab1# cat sk-ns.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: sk
root@manager:~/k8slab/lab1# kubectl create ns sk

3. ConifMap

  • 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
  • 버전 확인
root@manager:~/k8slab/lab1# kubectl api-resources | grep ConfigMap
configmaps                        cm           v1                                     true         ConfigMap
root@manager:~/k8slab/lab1# cat lb-config.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
  • metallb 의 config 부분에 data 를 하나로 보내기 위해 | 사용
root@manager:~/k8slab/lab1# touch kia-deploy-svc.yaml sk-deploy-svc.yaml
root@manager:~/k8slab/lab1# cat kia-deploy-svc.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: kia
  name: kia-deploy
spec:
  strategy:      # repliacas
    type: Recreate
  replicas: 3
  selector:
    matchLabels:
      app: kia
  template:       # POD
    metadata:
      labels:
        app: kia
    spec:         #container
      containers:
      - name: kia-nginx
        image: nginx
        ports:
        - containerPort: 80
  • 배포하기
root@manager:~/k8slab/lab1# kubectl apply -f kia-deploy-svc.yaml
  • 확인하기
root@manager:~/k8slab/lab1# kubectl get pod
NAME                              READY   STATUS    RESTARTS   AGE
hpa-hname-pods-6df6f77d64-pz57p   1/1     Running   1          18h
root@manager:~/k8slab/lab1# kubectl get pod -n kia
NAME                          READY   STATUS    RESTARTS   AGE
kia-deploy-5fcb8b68db-4pwpl   1/1     Running   0          17s
kia-deploy-5fcb8b68db-j2xsw   1/1     Running   0          17s
kia-deploy-5fcb8b68db-xf9vn   1/1     Running   0          17s

4. 각 회사별 deploy-svc 생성/배포하기

참고 : https://metallb.universe.tf/usage/

5. deploy 배포시 kia와 sk의 모든 포드는 각 포드의 /test 디렉토리를 각각 nfs 서버의 /kia, /sk 와 마운트되어야 한다.

  • 확인해야 할 사항
kubectl exec [포드이름] -n kia -- ls /test   
kia.txt
  • 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
root@manager:~/k8slab/lab1# kubectl apply -f kia-deploy-svc.yaml
root@manager:~/k8slab/lab1# kubectl get pod -n kia
root@manager:~/k8slab/lab1# kubectl exec kia-deploy-5ccc6dc745-2nmd7 -n kia -- ls /test
kia.txt

인그레스를 통한 서비스 요청처리

① nginx 인그레스 서비스 환경 구현

  • lb-ingress-service
root@manager:~/k8slab/lab2# vi ingress-config.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-nginx
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
  - http:
      paths:
        - path: /
          pathType: Prefix
          backend:
            service:
              name: default
              port:
                number: 80
        - path: /shop
          pathType: Prefix
          backend:
            service:
              name: shop
              port:
                number: 80
        - path: /blog
          pathType: Prefix
          backend:
            service:
              name: blog
              port:
                number: 80
  • 인그레스 컨트롤러 배포
root@manager:~/k8slab/lab2# kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.2/deploy/static/provider/cloud/deploy.yaml
  • 포드 배포
root@manager:~/k8slab/lab2# touch shop-deploy-svc.yaml
root@manager:~/k8slab/lab2# touch blog-deploy-svc.yaml
root@manager:~/k8slab/lab2# touch default-deploy-svc.yaml
  • yaml 파일 구성
root@manager:~/k8slab/lab2# vi shop-deploy-svc.yaml
root@manager:~/k8slab/lab2# cat shop-deploy-svc.yaml > default-deploy-svc.yaml
root@manager:~/k8slab/lab2# vi default-deploy-svc.yaml
root@manager:~/k8slab/lab2# cat shop-deploy-svc.yaml > blog-deploy-svc.yaml
root@manager:~/k8slab/lab2# sed -i 's/shop/blog/g' blog-deploy-svc.yaml
root@manager:~/k8slab/lab2# sed -i 's/nginx/httpd/g' blog-deploy-svc.yaml
root@manager:~/k8slab/lab2# sed -i 's/30001/30002/g' blog-deploy-svc.yaml
root@manager:~/k8slab/lab2# cat default-apiVersion: apps/v1
kind: Deployment
metadata:
  name: default
spec:
  replicas: 3
  selector:
    matchLabels:
      app: default
  template:
    metadata:
      name: default
      labels:
        app: default
    spec:
      containers:
      - name: default
        image: nginx
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: default
spec:
  ports:
  - name: default-port
    port: 80    # service's port
    targetPort: 80      # Pod's Port
    nodePort: 30000
  selector:
    app: default
  type: NodePort
root@manager:~/k8slab/lab2# cat shop-deploy-svc.yaml    
apiVersion: apps/v1
kind: Deployment
metadata:
  name: shop
spec:
  replicas: 3
  selector:
    matchLabels:
      app: shop
  template:
    metadata:
      name: shop
      labels:
        app: shop
    spec:
      containers:
      - name: shop
        image: nginx
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: shop
spec:
  ports:
  - name: shop-port
    port: 80    # service's port
    targetPort: 80      # Pod's Port
    nodePort: 30001
  selector:
    app: shop
  type: NodePort
root@manager:~/k8slab/lab2# cat blog-deploy-svc.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: blog
spec:
  replicas: 3
  selector:
    matchLabels:
      app: blog
  template:
    metadata:
      name: blog
      labels:
        app: blog
    spec:
      containers:
      - name: blog
        image: httpd
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: blog
spec:
  ports:
  - name: blog-port
    port: 80    # service's port
    targetPort: 80      # Pod's Port
    nodePort: 30002
  selector:
    app: blog
  type: NodePort
  • 현재까지 내용을 확인하기 위한 방법
    master/manager에서 curl을 이용하여 노드 포트를 통해 각 포드에 접속할 수 있는지 여부를 확인한다. 이는 클러스터 환경 외부(인터넷)에서의 접속을 확인하는 것은 아니고 내부적으로 정상 동작 여부를 확인하기 위한 것이다.
root@manager:~/k8slab/lab2# curl http://211.183.3.101:30000

root@manager:~/k8slab/lab2# curl http://211.183.3.101:30001

root@manager:~/k8slab/lab2# curl http://211.183.3.101:30002

root@manager:~/k8slab/lab2# kubectl get ing
NAME            CLASS    HOSTS   ADDRESS         PORTS   AGE
ingress-nginx   <none>   *       211.183.3.201   80      38m

추가 요구

아래와 같은 요구 사항을 적용시키자

/ - default - Pod : 10 ~ 15 0.25/16m
/blog - blod - Pod : 5 ~ 10 0.25/16m
/shop - shop - Pod : 10 ~ 20 0.5/32m
  • 최종적으로 우리 회사 DNS 서버에 아래의 정보를 등록시켜야 한다
  • test.com -> zone file 파일 -> test.com.db 에 등록해야 한다
  • 도메인이 test.com 일 때, hong IN A 211.183.3.201 로 등록하면 hong.test.com 에 접속시 211.183.3.201 에 접속된다
  • 별도 도메인을 구매하여 해당 도메인과 211.183.3.201 을 매핑하는 방법도 있다
각각의 페이지는 configmap 을 이용하여 붙여넣기 해 보세요!!! 
default(nginx) -> https://www.naver.com/
shop(nginx)    -> https://www.coupang.com/
blog(httpd)     -> https://www.kakaocorp.com/

ingress

  • ingress-config.yaml
root@manager:~/k8slab/lab2# cat ingress-config.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-nginx
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
  - http:
      paths:
        - path: /
          pathType: Prefix
          backend:
            service:
              name: default
              port:
                number: 80
        - path: /shop
          pathType: Prefix
          backend:
            service:
              name: shop
              port:
                number: 80
        - path: /blog
          pathType: Prefix
          backend:
            service:
              name: blog
              port:
                number: 80
kubectl apply -f ingress-config.yaml

default

curl -L http://www.naver.com > index.html
kubectl create cm defaultcm --from-file index.html
root@manager:~/k8slab/lab2# cd default
root@manager:~/k8slab/lab2/default# vi default-deploy-svc.yaml
root@manager:~/k8slab/lab2/default# cat default-deploy-svc.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: default
spec:
  replicas: 3
  selector:
    matchLabels:
      app: default
  template:
    metadata:
      name: default
      labels:
        app: default
    spec:
      containers:
      - name: default
        image: nginx
        ports:
        - containerPort: 80
        volumeMounts:
        - name: defaultvol
          mountPath: /usr/share/nginx/html
      volumes:
      - name: defaultvol
        configMap:
          name: defaultcm
kubectl apply -f default-deploy-svc.yaml

shop

curl -L https://www.coupang.com/ > index.html
kubectl create cm shopcm --from-file index.html
root@manager:~/k8slab/lab2# cd shop
root@manager:~/k8slab/lab2/shop# vi shop-deploy-svc.yaml
root@manager:~/k8slab/lab2/shop# cat shop-deploy-svc.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: shop
spec:
  replicas: 3
  selector:
    matchLabels:
      app: shop
  template:
    metadata:
      name: shop
      labels:
        app: shop
    spec:
      containers:
      - name: shop
        image: nginx
        ports:
        - containerPort: 80
        volumeMounts:
        - name: shopvol
          mountPath: /usr/share/nginx/html
      volumes:
      - name: shopvol
        configMap:
          name: shopcm
kubectl apply -f shop-deploy-svc.yaml

blog

curl -L https://www.kakaocorp.com/ > index.html
kubectl create cm blogcm --from-file index.html
root@manager:~/k8slab/lab2# cd blog
root@manager:~/k8slab/lab2/blog# vi blog-deploy-svc.yaml
root@manager:~/k8slab/lab2/blog# cat blog-deploy-svc.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: blog
spec:
  replicas: 3
  selector:
    matchLabels:
      app: blog
  template:
    metadata:
      name: blog
      labels:
        app: blog
    spec:
      containers:
      - name: blog
        image: httpd
        ports:
        - containerPort: 80
        volumeMounts:
        - name: blogvol
          mountPath: /usr/local/apache2/htdocs/
      volumes:
      - name: blogvol
        configMap:
          name: blogcm
kubectl apply -f blog-deploy-svc.yaml

[secret]

  • 일반적인 사용방법은 configMap 거의 동일하지만, 저장된 secret 을 describe 를 통해 확인할 수는 없다.
  • ssh, key, 인증서, username/password 등을 Pod 내에 전달할 때 주로 사용한다.
  • 사설 저장소를 사용하는 경우 각 노드는 사설 저장소로 접속하기 위한 인증정보를 보유하고 있어야 한다. 인증정보에 포함되는 요소들은 username, password, 저장소의 주소

[docker hub]

docker login
user:
pass:
docker login https://reg.test.com 
username: 
password:
  • secret 은 노드간 통신에서는 보이지 않지만 포드내에서는 clear text 로 확인이 된다.
https://kubernetes.io/ko/docs/tasks/configure-pod-container/pull-image-private-registry/
  • 도커 허브로의 로그인을 위한 secret 생성하기와 지정된 저장소 주소로의 접속을 위한 secret
    생성하기
kubectl create secret docker-registry regcred --docker-server=<your-registry-server> --docker-username=<your-name> --docker-password=<your-pword> --docker-email=<your-email>
kubectl create secret generic dockerhub1 \
--from-file=.dockerconfigjson=/root/.docker/config.json \
--type=kubernetes.io/dockerconfigjson

docker-registry -> 현재 만드는 secret 은 일반적인 generic 이 아니라 도커 저장소에 접속을 위한 secret 으로 사용된다.(type 지정)
regcred -> secret 이름
--docker-server=사설저장소주소
[활용]

apiVersion: v1
kind: Pod
metadata:
  name: private-reg
spec:
  containers:
  - name: test-oracle
    image: oraclelinux:latest
  imagePullSecrets:
  - name: dockerhub1

0개의 댓글