쿠버네티스 서비스 이용 메뉴얼
SKS (Smileserv Kubernetes Service) 이용 메뉴얼 입니다. ver. 2024.12.23 |
쿠버네티스 서비스를 위한 기본 서비스 , 로드밸런서 생성 및 배포 메뉴얼 입니다.
인그레스 - Sticky Session , Proxy Protocol , ip-whitelist , Path-base routing |
쿠버네티스로 서비스를 운영 할 때 일반적으로 필요한 값이 입력된 yaml 파일을 생성하여 운영, 관리 합니다.
* yaml 파일은 들여쓰기 간격을 인식, 구분하니 입력시 주의가 필요 합니다.
vi 에디터에서 복사, 붙여넣기시 입력이 밀리는경우 : set paste 로 붙여넣기 모드로 변경 후 다시 입력 합니다.
** 메뉴얼에 있는 값들은 예시를 위한 샘플데이터로, 상세한 입력값들은 상황에 맞게 수정 해야 합니다.
쿠버네티스 사용 방법에 대한 자세한 메뉴얼은 kubernetes.io 의 공식 문서에서 확인 가능합니다.
yaml 파일 문법 체크
kubectl apply -f FILE.yaml --dry-run=client |
yaml 파일을 작성하여 포드를 생성 할 수 있습니다.
1) 아래와 같이 간단한 정보가 들어있는 pod_test.yaml 을 생성 합니다.
apiVersion: v1 kind: Pod metadata: name: manual-pod labels: app: manual-test spec: containers: - name: manual-container image: nginx |
2) 생성한 파일을 적용하여 포드를 생성 합니다.
kubectl apply -f pod_test.yaml |
3) 포트가 잘 생성 되었는지 확인 합니다.
kubectl get pod |
컨트롤러로 포드 생성, 관리
직접 생성한 pod 는 장애가 발생하거나, 삭제시 수동으로 직접 생성 해야 합니다.
효율적인 서비스 운영을 위해서는 Deployment ,Statefulset 와 같은 컨트롤러 를 사용하는 것이 권장 됩니다.
Deployment 는 API , 웹 서버 와 같은 stateless 어플리케이션 에 주로 사용하고
Statefulset 은 Database 와 같은 Stateful 서비스 운영시 사용 합니다.
본 메뉴얼에서는 Deployment 로 nginx 서비스를 배포하는 방법을 예시로 안내 합니다.
1) deployment 생성을 위한 yaml 파일을 작성합니다.
apiVersion: apps/v1 kind: Deployment metadata: name: manual-deployment spec: replicas: 1 selector: matchLabels: app: manual-nginx template: metadata: labels: app: manual-nginx spec: containers: - name: manual-container image: nginx ports: - containerPort: 80 |
2) 작성한 yaml 파일로 Deployment 를 생성 합니다.
kubectl apply -f test_deployment.yaml |
3) 생성된 Deployment 상태를 조회 할 수 있습니다.
kubectl get deployment |
4) Deployment 에서 자동으로 생성한 pod 상태를 확인 할 수 있습니다.
kubectl get pod |
쿠버네티스에서 실행중인 포드의 통신을 위해서 목적에 맞는 서비스(Service) 를 생성, 연결 해야 합니다.
서비스에는 ClusterIP, NodePort, LoadBalancer ExternalName 등 이 있습니다.
외부에서 쿠버네티스 내부로 접근을 위해서 NodePort, LoadBalancer 를 사용하며 일반적인 상용 서비스레벨 운영시 로드밸런서를 사용 합니다.
노드포트 를 사용하면 외부에서 컨테이너로 간단하게 접속 테스트가 가능합니다.
1) 필요한 정보를 포함한 yaml 파일을 작성 합니다.
apiVersion: v1 kind: Service metadata: name: test-nodeport spec: type: NodePort selector: app: manual-test ports: - protocol: TCP port: 80 targetPort: 80 nodePort: 30088 |
selector : 연결 대상의 라벨과 일치 해야 합니다.
nodePort : 사용할 노드포트번호를 입력 합니다. ( 가용 범위 : 30000 - 32767 )
2) kubectl apply 명령어로 서비스를 생성 합니다.
kubectl apply -f testport.yaml |
3) 생성된 서비스 정보를 확인 합니다.
kubectl get svc |
4) 웹 브라우져에서 접속을 확인 할 수 있습니다.
접속 방법 - 노드 IP:노드포트
쿠버네티스로 운영되는 서비스의 외부 배포를 위해 로드밸런서를 생성, 사용 할 수 있습니다.
**주의) 쿠버네티스에서 로드밸런서 생성시 자동으로 감지하여, iwinv 계정에 IP 와 로드밸런서 서비스가 연결 되며 서비스 이용료가 발생 합니다. 본과정을 그대로 진행시 로드밸런서, IP 가 생성되어 요금이 청구 되므로 확인 후 테스트 진행 부탁 드립니다. |
1) 로드밸런서 작동 테스트를 확인하기 위해 테스트 포드를 생성할 디플로이먼트를 작성 합니다.
로드밸런서 생성 부분만 확인 하려는 경우 > 로드밸런서 생성
apiVersion: apps/v1 kind: Deployment metadata: name: whoami spec: replicas: 3 selector: matchLabels: name: whoami template: metadata: labels: name: whoami spec: containers: - name: whoami image: quanhua92/whoami:latest imagePullPolicy: Always ports: - containerPort: 8080 |
2) 작성한 yaml 파일로 디플로이먼트를 생성 합니다.
kubectl apply -f deploytment_whoami.yaml |
3) 디플로이먼트 상태를 확인 합니다.
kubectl get deployment |
4) 디플로이먼트에 의해 관리 되는 포드 상태를 확인 합니다.
kubectl get pod -o wide |
5) 로드밸런서 생성을 위한 yaml 파일을 작성 합니다.
apiVersion: v1 kind: Service metadata: name: whoami-lb spec: type: LoadBalancer selector: name: whoami ports: - name: http port: 80 targetPort: 8080 |
* selector : 연결 대상 어플리케이션의 라벨과 일치 해야 합니다.
** port : 로드밸런서에 오픈 외부에서 접속 할 포트를 입력 합니다.
*** targetPort : 연결 대상 서비스(포드) 의 포트를 입력 합니다.
6) kubectl apply 명령으로 로드밸런서 서비스를 생성 합니다.
kubectl apply -f lb-whoami.yaml |
7) 잠시 후 로드밸런서 생성이 완료 되면 등록된 메일로 로드밸런서와 로드밸런서에 연결된 공인IP 의 서비스 요금 안내 메일이 발송 됩니다.
8) 세팅이 완료되면 로드밸런서 정보를 조회 할 수 있습니다.
kubectl get svc |
9) 웹 브라우져에서 로드밸러서 정보의 EXTERNAL-IP 로 접속하면 로드벨런서 작동 을 확인 할 수 있습니다.
캐시 비우고 새로고침 (ex) Ctrl + Shift + r ) 을 반복, Hostname 부분에서 로드밸런서에 의해 분배되어 접속된 포드들의 정보를 확인 할 수 있습니다.
10) CURL 을 통해서도 로드밸런서에 의해 3개의 포드로 요청이 분산 되는 것을 확인 할 수 있습니다.
10) iwinv 관리콘솔 > 쿠버네티스 > SKS클러스터 관리 > 클러스터 상세 정보 > 로드 밸런서 탭 에서 로드밸런서 정보를 확인 할 수 있습니다.
로드밸런서 이름 오른쪽 상세정보버튼 으로 로드밸런서 상세 정보를 확인, 수정 할 수 있습니다.
관리콘솔 로드밸런서 메뉴얼 바로가기
LB service 대신 Path-base routing 등 더 다양한 기능을 사용 할 수 있는 Ingress를 통해 트래픽을 제어 할 수 있습니다.
인그레스 이해하기 : https://kubernetes.io/docs/concepts/services-networking/ingress/ |
인그레스를 사용하기 위해서는 클러스터에 인그레스 컨트롤러를 배포해야 합니다.
k8s에서는 본 메뉴얼에서 다룰 Nginx ingress controller 외에도 다양한 서드파티 인그레스 컨트롤러를 사용 할 수 있습니다.
본 메뉴얼에서는 Nginx ingress controller 와 Cert Manager 를 사용하여 서비스에 인증서를 발급, 운영하는 방법을 설명하고 있습니다.
위에서 생성한 whoami 포드에 로드밸런서 서비스로 직접 연결하는 대신 ingress 로 연결하는 방법을 샘플로 진행 합니다.
클러스터 IP 생성 하기
Ingress 로 트래픽을 제어하기위해서는 먼저 포드와 연결할 서비스를 생성 해야 합니다.
1) yaml 파일을 생성하여 포드에 연결할 클러스터 IP서비스를 생성 합니다.
apiVersion: v1 kind: Service metadata: name: whoami-service spec: selector: name: whoami ports: - name: http port: 80 targetPort: 8080 |
kubectl apply -f servcice.yaml |
2) 생성된 서비스를 확인 합니다.
kubectl get svc |
인그레스 컨트롤러중 하나인 Nginx ingress controller 를 배포 합니다.
**주의) 본과정을 그대로 진행시 로드밸런서, IP 가 생성되어 요금이 청구 되므로 확인 후 테스트 진행 부탁 드립니다. |
* 배포 전 현재 운영중인 K8s server 버젼과 호환 되는 버젼을 체크 해야 합니다.
** 현재 메뉴얼 제작 시점 (2024.12.06) 기준 SKS의 K8s server 버젼은 v1.28.9 으로 Nginx Ingress Controller 1.11.3 버젼 으로 배포 진행 했습니다.
깃허브 주소
https://github.com/kubernetes/ingress-nginx/blob/main/README.md#readme |
1) nginx ingress controller 공식 github 의 yaml 파일로 바로 배포 가 가능합니다.
Nginx Ingress Controller 가 배포 되면 Controller에서 관리하는 로드밸런서가 같이 배포 되며
로드밸런서 서비스를 직접 배포 했을때와 같이 IP 가 연결 되며 비용이 발생 합니다.
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.11.3/deploy/static/provider/cloud/deploy.yaml |
2) Nginx Ingress controller 의 Load balancer External-IP 를 확인 합니다.
kubectl get svc -A |
Nginx Ingress controller 관련 pod 확인
kubectl get pod -A |
3) 연결할 도메인의 A 레코드에 위에서 확인한 LB External IP 를 입력합니다.
*이용중인 네임서버에 따라 DNS입력 인터페이스에 차이가 있을 수 있습니다.
*** 주의) 이용중인 로드밸런서를 삭제하실 경우 기존에 사용하시던 IP를 다시 사용할 수 없으니 신중히 삭제 하여 주시기 바랍니다.
4) SSL 인증서 발급을 위해 Cert-manager 를 배포 합니다.
Cert-manager Offical page
https://cert-manager.io/ |
Nginx Ingress controller 처럼 Cert-manager github 의 yaml 파일로 바로 배포 가능합니다.
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.16.2/cert-manager.yaml |
5) 인증서 발급을 위해 Issuer 배포를 위한 yaml 파일을 작성 합니다.
Letsencrypt 인증서 발급의 경우 DCV 인증 실패가 연속되면 횟수 제한에 걸려 거부 될 수 있습니다.
Letsencrypt 에서 최초 개발단계등 인증서 발급 테스트를 위해 실제 발급용인 product 와 함께 staging 도 제공하고 있습니다.
apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-prod spec: acme: # The ACME server URL server: https://acme-v02.api.letsencrypt.org/directory # Email address used for ACME registration email: 담당자메일주소 # Name of a secret used to store the ACME account private key privateKeySecretRef: name: letsencrypt-prod # Enable the HTTP-01 challenge provider solvers: - http01: ingress: ingressClassName: nginx |
* kind 는 특정 네임스페이스에 적용 되는 Issuer 와 클러스터 전체에 적용 되는 ClusterIssuer 중 선택이 가능합니다.
** email 부분에 인증서 갱신, 유지보수 등에 필요한 담당자 메일을 입력 합니다.
6) 작성한 yaml 파일을 apply 합니다.
7) staging Issuer 를 위한 yaml 파일도 동일하게 생성하여 배포 합니다.
apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-staging spec: acme: # The ACME server URL server: https://acme-v02.api.letsencrypt.org/directory # Email address used for ACME registration email: 담당자메일주소 # Name of a secret used to store the ACME account private key privateKeySecretRef: name: letsencrypt-staging # Enable the HTTP-01 challenge provider solvers: - http01: ingress: ingressClassName: nginx |
kubectl apply -f lets-dry.yaml |
8) Cluster issuer 상태를 확인 합니다.
kubectl get clusterissuer |
9) Ingress 배포를 위한 yaml 파일을 작성 합니다.
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: whoami-ingress annotations: cert-manager.io/cluster-issuer: letsencrypt-prod spec: ingressClassName: nginx tls: - secretName: whoami-tls hosts: - My-domain rules: - host: My-domain http: paths: - path: / pathType: Prefix backend: service: name: whoami-service port: number: 80 |
* annotations 의 issuer 를 상황에 맞게 수정 합니다. ( 테스트 = letsencrypt-staging 실제 발급 = letsencrypt-prod )
** rules 부분 호스트에 도메인을 입력하고 아래에 라우팅 방식을 설정 합니다.
yaml 파일을 저장하고 Apply 합니다.
kubectl apply -f ingress.yaml |
10) 생성된 Ingress 의 정보를 확인 합니다.
kubectl get ingress |
배포한 ingress 와 함께 cm-acme-http-solver 가 let's encrypt 인증서 발급을 위해 임시로 생성 되어있는 것을 확인 할 수 있습니다.
잠시 후 인증서 발급이 완료되면 자동으로 삭제 됩니다.
kubectl describe ingress whoami-ingress |
Event 부분에서 인증서가 자동으로 생성 된 것을 확인 할 수 있습니다.
11) 인증서는 secret 오브젝트 에 저장 됩니다.
kubectl get secret |
12) kubectl describe 로 조회하면 인증서와 키 를 포함하고 있는 것을 확인 할수 있습니다.
kubectl describe secret whoami-tls |
13) 웹브라우져에서 도메인으로 HTTPS 접속, 인증서를 확인 할 수 있습니다.
14) 예제를 따라 생성한 인그레스 에 적용한 도메인으로 접속시 대략적인 트래픽 흐름 입니다.
도메인 접속 > Loadbalancer > Nginx Ingress Controller [Ingress route Rule 에 따라 Service 로 연결 ] > Service [ selector 로 포드에 연결 ] > Pod
비회원 장바구니 기능과 같이 서비스중 세션 유지가 필요한 경우가 있습니다.
스티키 세션을 사용하면 세션 유지에 도움이 됩니다.
1) 위에서 배포한 Ingress 의 yaml 파일을 수정 합니다.
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: whoami-ingress annotations: cert-manager.io/cluster-issuer: letsencrypt-prod nginx.ingress.kubernetes.io/affinity: "cookie" nginx.ingress.kubernetes.io/session-cookie-name: "sticky" nginx.ingress.kubernetes.io/session-cookie-max-age: "86400" nginx.ingress.kubernetes.io/session-cookie-expires: "86400" spec: ingressClassName: nginx tls: - secretName: whoami-tls hosts: - My-domain rules: - host: My-domain http: paths: - path: / pathType: Prefix backend: service: name: whoami-service port: number: 80 |
session-cookie-max-age, session-cookie-expires 는 초 단위로 입력 합니다. (86400 = 24시간)
2) 수정한 yaml 파일을 Apply 합니다.
kubectl apply -f |
3) ingress 정보를 확인 합니다.
kubectl describe ingress whoami-ingress |
4) 웹 브라우져로 접속하여 세션 유지를 확인 합니다.
hostname 의 포드 정보와 쿠키 부분에 sticky session 을 확인 할 수 있습니다.
5) curl 로 쿠키 헤더를 확인 할 수 있습니다.
curl -I https://My.Domain |
프록시 프토로콜을 사용하면 로드밸런서, 프록시 등을 통과 할때 실제 IP 와 같은 접속자의 정보를 유지 할 수 있습니다.
1) Nginx Ingress Controller yaml 파일 다운로드
Nginx Ingress Controller 의 수정 배포를 위해 yaml 파일을 다운로드 합니다.
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.11.3/deploy/static/provider/cloud/deploy.yaml |
2) ConfigMap 부분을 수정 합니다.
kind: ConfigMap 으로 검색하면 빠르게 찾을 수 있습니다.
apiVersion: v1 |
3) type: LoadBalancer 로 검색 LoadBalancer 설정 부분에 annotations 를 추가 합니다.
apiVersion: v1 kind: Service metadata: labels: app.kubernetes.io/component: controller app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx app.kubernetes.io/version: 1.11.3 name: ingress-nginx-controller namespace: ingress-nginx annotations: loadbalancer.openstack.org/proxy-protocol: "true" spec: externalTrafficPolicy: Local ipFamilies: - IPv4 ipFamilyPolicy: SingleStack ports: - appProtocol: http name: http port: 80 protocol: TCP targetPort: http - appProtocol: https name: https port: 443 protocol: TCP targetPort: https selector: app.kubernetes.io/component: controller app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx type: LoadBalancer |
4) 수정한 yaml 파일을 배포 합니다.
kubectl apply -f deploy.yaml |
5) 다시 연결한 도메인으로 접속 하면 X-Real-IP 부분에 실제 접속 IP 가 기록 되는 것을 확인 할 수 있습니다.
Nginx Ingress 에 ip 기반 접근 제어 설정
Nginx Ingress 에 ip 화이트리스트 설정을 추가하여 허용된 ip 에서만 접근 가능하도록 제어 할 수 있습니다.
whitelist-source-range 추가시 허용 ip 외 모두 차단 설정 됩니다.
1) ingress yaml 파일을 열어 annotation 을 추가 합니다.
ip는 CIDR 형식으로 입력하며 ',' 로 구분하여 여러개의 ip를 입력 할 수 있습니다.
nginx.ingress.kubernetes.io/whitelist-source-range: 1.2.3.4,255.255.255.0/24 |
2) 수정된 yaml 파일을 적용 합니다.
kubectl apply -f MY-ingress.yaml |
3) 허용되지 않은 IP 에서 접근시 403 Forbidden 이 반환 됩니다.
Path base Routing ( 경로 기반 라우팅 )
ingress 에서는 path 를 기반으로 트래픽을 제어 할 수 있습니다.
1) ingress yaml 파일을 열어 path 부분을 설정 합니다.
pathType 에는 ImplementationSpecific, Exact, Prefix 가 있습니다.
ImplementationSpecific : 기본값, Ingress Controller 의 기본 동작에 따라 매칭 규칙을 결정 합니다.
* 컨트롤러마다 동작이 다를 수 있어 주의가 필요 합니다.
Exact : 지정한 경로와 정확히 일치해야 합니다.
ex) path: /app -> /app 경로만 일치 /app/ , /app/version2 는 일치하지 않음
Prefix : 지정한 경로로 시작하는 모든 서브경로와 매치
ex) path: /app -> /app, /app/ , /app/main/user 모두 매칭
2) 설정한 경로로 요청하여 서비스로 정상 연결 되는지 확인 합니다.
path: /
path: /adm
쿠버네티스 포드는 과부하, 업데이트 재배포 등으로 포드가 삭제, 재생성 될 경우 새로 만들어지며 기존 데이터가 사라지게 됩니다.
데이터의 영구 저장이 필요한 경우 PersistentVolumeClaim 을 사용하여 포드에 연결, 데이터를 저장하는데 사용 할 수 있습니다.
**주의) 본과정을 그대로 진행시 블록스토리지가 생성되어 요금이 청구 되므로 확인 후 테스트 진행 부탁 드립니다. |
* storageClass 에 정의된 기본 파일시스템은 xfs 입니다.
다른 파일시스템으로 변경이 필요한 경우 기술지원 요청을 통해 변경 가능합니다.
1) PVC 생성에 필요한 yaml 파일을 작성 합니다.
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: manual-volume spec: accessModes: - ReadWriteOnce resources: requests: storage: 10Gi storageClassName: block |
2) kubectl apply 로 pvc 를 생성 합니다.
kubectl apply -f test_pvc.yaml |
3) 생성된 정보를 확인 합니다.
kubectl get pv kubectl get pvc |
4) 볼륨이 생성 되면 자동으로 체크, iwinv 계정에 블록 스토리지 서비스가 생성되며 요금이 발생합니다.
회원 아이디에 등록된 이메일로 안내 메일이 발송 됩니다.
블록 스토리지를 연결 하여 Deployment 로 포드 배포하기
본 메뉴얼에 안내 되어있는 정보를 이용하여 생성된 PVC 를 포드에 연결, 배포하는 방법 입니다.
1) deployment 생성을 위한 yaml 파일을 작성합니다.
apiVersion: apps/v1 kind: Deployment metadata: name: manual-deployment spec: replicas: 1 selector: matchLabels: app: manual-nginx template: metadata: labels: app: manual-nginx spec: containers: - name: manual-container image: nginx ports: - containerPort: 80 volumeMounts: - mountPath: "/usr/share/nginx/html" name: manual-disk volumes: - name: manual-disk persistentVolumeClaim: claimName: manual-volume |
2) 작성한 yaml 파일로 Deployment 를 생성 합니다.
3) 생성된 Deployment 상태를 조회 할 수 있습니다.
kubectl get deployment |
4) Deployment 에서 자동으로 생성한 pod 상태를 확인 할 수 있습니다.
kubectl get pod |
5) kubectl exec 명령어로 포드 내부에 접속 할 수 있습니다.
kubectl exec -it 포드명 -- /bin/bash |
6) 포드에 블록스토리지가 정상 마운트 되어있는 것을 확인 할 수 있습니다.
7) 테스트를 위해 간단한 index 파일을 생성, 포드 내부로 복사 합니다.
kubectl cp [file] [Pod_name]:/[복사경로] |
8) 연결된 로드밸런서 ip 로 접속 하여 업로드한 인덱스 페이지를 확인 할 수 있습니다.
사용중인 블록 스토리지 용량을 늘릴 수 있습니다.
* 용량 증가만 가능하며 축소는 불가능합니다.
* 포드에 연결 되어 있어야 용량 업그레이드가 정상적으로 완료 가능 합니다.
**주의) 본과정을 그대로 진행시 블록스토리지 용량이 변경되어 추가된 요금이 청구 되므로 확인 후 테스트 진행 부탁 드립니다. |
1) 현재 사용중인 스토리지 확인
kubectl get pvc |
2) 블록스토리지를 생성할 때 사용한 yaml 파일을 열어 용량을 수정 합니다.
vi test_pvc.yaml |
3) 수정한 yaml 파일을 적용 합니다.
*스토리지 용량은 추가 만 가능하며 감소는 불가능 합니다.
kubectl apply -f test_pvc.yaml |
4) 잠시 후 스토리지 상태를 조회 하면 용량이 변경 된 것을 확인 할 수 있습니다.
스토리지를 생성 했을 때와 같이 서비스 변경 안내 메일이 발송 됩니다.
*) 블록디스크가 정상적으로 확장 되지 않는 경우 pvc 정보 를 조회 하여 확인 할 수 있습니다.
kubectl describe pvc MY_PVC_NAME |
- 일부 오래된 파일시스템 과 같이 디스크 리마운트가 필요한 경우 포드 재시작이 필요 할 수 있습니다.
- 포드에 연결되지 않은 경우 포드에 연결이 필요 합니다.