본문 바로가기
Kubernetes

Kubernetes Deploy & Service & Ingress

by 손영진 2023. 8. 8.
728x90

#1 YAML 파일 구조

  1. apiVersion
    • 오브젝트를 생성하기 위해 사용하고 있는 쿠버네티스 API 버전
  2. kind
    • 어떤 종류의 오브젝트를 생성하고자 하는니
  3. metadata
    • 이름 문자열, UID, 선택적 네임스페이스를 포함하여 오브젝트 유일하게 구분할 데이터
  4. spec
    • 오브젝드에 대해 어떤 상태를 의도하는지 정의

 

#2 Deployment Controller

  • 애플리케이션 배포 시 사용하는 가장 기본적인 컨트롤러
  • Replicaset은 고가용성 위해 항상 원하는 개수를 정하지만, 이는 서버 다운없이 새로운 버전의 Pod로 교체 가능
  • 베포에 대한 기능 세분화
  • 개수 유지 뿐만 아니라 롤링 업데이트 가능

   1. RollingUpdate

  • deployment-nginx.yaml
  • 더보기
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment
      labels:
        app: nginx
    spec:
      replicas: 3 
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx
            ports:
            - containerPort: 80
kubectl create ns deployment
kubens deployment
vim deployment-nginx.yaml
<더보기 참조>		// 생성될 Pod의 개수를 지정

kubectl apply -f deployment-nginx.yaml

<< 설정 정보 업데이트 >>
kubectl edit deploy nginx-deployment
> 127번쨰 줄 : - image : nginx:1.10.1		// 버전 변경

kubectl get rs -o wide		// 변경된 replica 확인

<< rollback 사용 >>
kubectl rollout history deploy nginx-deployment		//이전 버전으로 변경
kubectl rollout history deploy nginx-deployment --revision=2
			// 2번째 버전으로 변경

<< Pod 개수 조정 >>
kubectl scale deploy nginx-deployment --replicase=5
kubectl scale deploy nginx-deployment --replicase=2

 

   2. Canary

  • deployment-v1.yaml
  • 더보기
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment
      labels:
        app: nginx
    spec:
      replicas: 3 
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx
            ports:
            - containerPort: 80
  • deployment-v2.yaml
  • 더보기
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: k8s-canaryapp-test
      labels:
        app: myapp
        version: canary
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: myapp
          version: canary
      template:
        metadata:
          labels:
            app: myapp
            version: canary
        spec:
          containers:
          - name: canaryapp
            image: arisu1000/simple-container-app:v0.2
            ports:
            - containerPort: 8080
  • myapp-svc.yaml
  • 더보기
    apiVersion: v1
    kind: Service
    metadata:
      labels:
        app: myapp
      name: myapp-svc
      namespace: label-space
    spec:
      ports:
      - nodePort: 30900
        port: 8080
        protocol: TCP
        targetPort: 8080
      selector:
        app: myapp
      type: NodePort
kubectl create namespace label-space
kubens label-space
vim deployment-v1.yaml	<더보기 참조>
vim deployment-v2.yaml	<더보기 참조>

kubectl apply -f deployment-v1.yaml
kubectl apply -f deployment-v2.yaml

kubectl get deploy
kubectl get pods

<< service 생성 >>
vim myapp-svc.yaml	<더보기 참조>
kubectl apply -f myapp-svc.yaml
kubectl get svc -o wide		// 생성된 포트 번호확인
kubectl get pods -o wide		// 생성된 pods의 노드 확인

-> 웹 브라우저에 [생성된 노드의 공인IP]:[포트번호] 를 입력하여 내용 확인

예시

 

   3. Blue/Green Deployment

  • echo-version-blue.yaml
  • 더보기
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: echo-version-blue
      labels:
        app: echo-version 
        color: blue
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: echo-version
          color: blue
      template:
        metadata:
          labels:
            app: echo-version
            color: blue
        spec:
          containers:
          - name: echo-version
            image: nginx:1.20.0
            ports:
            - containerPort: 80
  • echo-version-green.yaml
  • 더보기
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: echo-version-green
      labels:
        app: echo-version 
        color: green
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: echo-version
          color: green
      template:
        metadata:
          labels:
            app: echo-version
            color: green
        spec:
          containers:
          - name: echo-version
            image: nginx:1.21.1
            ports:
            - containerPort: 80
  • echo-version-service.yaml
  • 더보기
    apiVersion: v1
    kind: Service
    metadata:
      name: echo-version
      labels:
        app: echo-version
    spec:
      type: NodePort
      ports:
      - nodePort: 31000
        port: 80
        protocol: TCP
        targetPort: 80
      selector:
        app: echo-version
        color: blue
vim echo-version-blue.yaml	<더보기 참조>
vim echo-version-green.yaml	<더보기 참조>

kubectl apply -f echo-version-[green/blue 둘 중 하나 작성].yaml
kubectl get deploy

vim echo-version-service.yaml	<더보기 참조>
			// 안에는 blue가 쓰인다.
kubectl apply -f echo-version-service.yaml
kubectl get svc -o wide		//포트번호 확인
kubectl get pods -o wide		// 노드 확인

kubectl patch service echo-version -p '{"spec":{"selector":{"color":"green"}}}'
			// 이를 통하여 blue와 green을 교체 가능

-> 웹브라우저에 [노드의 공인ip]:[포트번호] 검색하여 확인

 

#3 Service

 

1. ClusterIP

• 기본 서비스 타입, Kubernetes 클러스터 내부에서 사용가능

• 클러스터 내부 노드나 Pod에서 이 ClusterIP 이용해서 이 서비스에 연결된 Pod 접속 가능

• 클러스터 외부에선 이용 불가

 

2. NodePort

• 각 노드 지정된 포트 할당하는 방식

• node1:8080, node2:8080 이런 방식으로 노드에 상관없이 포트번호만 서비스에 지정된 걸 사용하면 접근 가능

• 노드 포트 사용하기 때문에 클러스터 내부 뿐 아니라 클러스터 외부서도 접근 가능

• 클러스터 외부에서 클러스터 내부 Pod로 접근할 때 사용할 수 있는 가장 간단한 방법

 

3. LoadBalancer

• AWS, GCP 같은 클라우드 서비스 사용할 때 사용 가능한 옵션

• Pod를 클라우드에서 제공해주는 로드밸런서와 연결하고 그 로드밸런서 IP 이용해서 클러스터 외부에서 접근 가능

• 서비스 확인: kubectl get service

 

4. ExternalName

• 서비스를 externalName의 값과 매치

• 클러스터 내부에서 외부로 접근할 때 주로 사용(Ingress -> Exgress)

• 이 서비스로 접근하면 설정한 CNAME값으로 연결되어 클러스터 외부로 접근 가능

• 외부로 접근할 때 사용하는 값이기 때문에 설정할 때 Selector 필요 없음


   1. service ClusterIP

  • my-deployment.yaml
  • 더보기
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: my-deployment
    spec:
      selector:
        matchLabels:
          app: metrics
          department: sales
      replicas: 3
      template:
        metadata:
          labels:
            app: metrics
            department: sales
        spec:
          containers:
          - name: hello
            image: "gcr.io/google-samples/hello-app:2.0"
  • my-service.yaml
  • 더보기
    apiVersion: v1
    kind: Service
    metadata:
      name: my-cip-service
    spec:
      type: ClusterIP
      selector:
        app: metrics
        department: sales
      ports:
      - protocol: TCP
        port: 80
        targetPort: 8080
kubectl create ns service
kubens service
vim my-deployment.yaml	<더보기 참조>
kubectl apply -f my-deployment.yaml

vim my-service.yaml	<더보기 참조>
kubectl apply -f my-service.yaml

kubectl get svc -o wide
kubectl get pods -o wide

-> 포트번호화 노드 확인하여 웹브라우저에서 확인

   2. NodePort

  • ClusterIP와 다르게 외부에서의 Pod 접속을 허용
  • my-deployment-50000.yaml
  • 더보기
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: my-deployment-50000
    spec:
      selector:
        matchLabels:
          app: metrics
          department: engineering
      replicas: 3
      template:
        metadata:
          labels:
            app: metrics
            department: engineering
        spec:
          containers:
          - name: hello
            image: "gcr.io/google-samples/hello-app:2.0"
            env:
            - name: "PORT"
              value: "50000"
  • my-np-service.yaml
  • 더보기
    apiVersion: v1
    kind: Service
    metadata:
      name: my-np-service
    spec:
      type: NodePort
      selector:
        app: metrics
        department: engineering
      ports:
      - protocol: TCP
        port: 80
        targetPort: 50000
        nodePort: 30198
vim my-deployment-50000.yaml	<더보기 참조>
kubectl apply -f my-deployment-50000.yaml

vim my-np-service.yaml	<더보기 참조>

kubectl get svc -o wide		//nodeport 번호 확인

-> 노드와 포트번호 확인 후 웹 브라우저에 확인

   3. LoadBalancer

  • my-deployment-50001.yaml
  • 더보기
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: my-deployment-50001
    spec:
      selector:
        matchLabels:
          app: products
          department: sales
      replicas: 3
      template:
        metadata:
          labels:
            app: products
            department: sales
        spec:
          containers:
          - name: hello
            image: "gcr.io/google-samples/hello-app:2.0"
            env:
            - name: "PORT"
              value: "50001"
  • my-lb-service.yaml
  • 더보기
    apiVersion: v1
    kind: Service
    metadata:
      name: my-lb-service
    spec:
      type: LoadBalancer
      selector:
        app: products
        department: sales
      ports:
      - protocol: TCP
        port: 60000
        targetPort: 50001
      externalIPs:
        - 172.31.32.174
vim my-deployment-50001.yaml	<더보기 참조>
kubectl apply -f my-deployment-50001.yaml

vim my-lb-service.yaml	<더보기 참조>
kebectl apply -f my-lb-service.yaml

-> 생성된 노드의 ip와 포트번호를 작성 시 각 pods로 부하 분산을 시켜주기에 새로고침시 내용이 계속 바뀐다
-> 그러나 aws에서는 이를 받아주지 못하기 때문에 시크릿창을 띄어 동일한 주소에서 다르게 나타나는 것을 확인한다.

#4 Ingress

  • Ingress는 외부로부터 서버 내부로 유입되는 트래픽, egress는 내부에서 외부로의 트래픽
  • 쿠버네티스에서 실행 중인 Deployment와 Service에 접근하기 위한 gateway 역할
  • 이 외에 NodePort, ExternalIP 등이 있지만 이들은 Layer4에서 요청을 처리하여 세부 처리 로직을 구현하기 힘들다

   1. Ingress 소스 파일

  • ingress.yaml
  • 더보기
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: ingress-nginx
      annotations:
        nginx.ingress.kubernetes.io/rewrite-target: /
    spec:
      ingressClassName: nginx 
      rules:
      - host: foo.bar.com 
        http:
          paths:
          - path: /foo
            pathType: Prefix
            backend:
              service:
                name: svc1
                port:
                  number: 80
          - path: /bar
            pathType: Prefix
            backend:
              service:
                name: svc2
                port:
                  number: 80
vim ingress.yaml	<더보기 참조>
kubectl apply -f ingress.yaml
kubectl get ingress -o wide	// hosts 확인

  

   2. Ingress-nginx

  • 외부 요청에 대한 로드밸런싱, TLS/SSL 인증서 처리, 도메인 기반 가상 호스팅 제공 등의 규칙들을 정의한 자원
<<nginx 웹서비스 생성>>

kubectl create ns ingress-ngnix
kubens ingress-nginx
kubectl create deployment nginx1 --image=nginx:latest
kubectl create deployment nginx2 --image=nginx:latest
kubectl expose deployment ningx1 --name=svc1 --port=80 --type=NodePort
kubectl expose deployment ningx2 --name=svc2 --port=80 --type=NodePort

kubectl get svc -o wide	// 생성한 두 개의 service의 NodePort번호확인
kubectl get pods -o wide	// 생성된 pods의 node 확인

<<생성한 service 테스트>>
echo 'Ingress index1' > index.html
kubectl cp index.html [첫번째 pod의 name]:/usr/share/nginx/html/index.html
echo 'Ingress index2' > index.html
kubectl cp index.html [두번째 pod의 name]:/usr/share/nginx/html/index.html

curl [생성된 pods의 node 이름]:[service의 Nodeport 번호]
			// 두 개의 service가 생성되어 포트 번호도 두개이다.
            // 두 개의 index.html 파일이 다르므로 내용도 다르다. <그림 참조>

<<nginx 생성>>

wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/ \
> controller-v1.0.0-beta.3/deploy/static/provider/cloud/deploy.yaml
kubectl apply -f deploy.yaml

 

   3. Ingress Rule 설정 -> 되는지 확인해볼 필요 있음

vim ingress.yaml	<더보기 참조>
kubectl delete validatingwebhookconfiguration ingress-nginx-admission
kubectl apply -f ingress.yaml

kubectl ger ing		// hosts name 확인
kubectl get svc		// type이 LoadBalancer인 것과, 포트번호 확인

vim /etc/hosts
> 127.0.0.1	[hosts name]		// 추가하여 해당 hosts를 확인하게 해준다.
curl [hosts name]:[포트번호]/[foo/bar]

 

'Kubernetes' 카테고리의 다른 글

Kubernetes Scheduling  (0) 2023.08.15
Kubernetes ConfigMap & volume  (0) 2023.08.09
Kubernetes 기본  (1) 2023.08.07