하위 태스크 1

Deployment 생성

Service에 연결할 애플리케이션 Deployment 생성

deployment.yaml:

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

Deployment를 생성한다.

kubectl apply -f deployment.yaml

결과:

deployment.apps/my-app-deploy created

Pod의 상태를 확인한다.

kubectl get pods

결과:

NAME                             READY   STATUS    RESTARTS   AGE
my-app-deploy-78f59dd94b-bgww2   0/1     Pending   0          50s
my-app-deploy-78f59dd94b-ctqdh   0/1     Pending   0          50s
my-app-deploy-78f59dd94b-dl5pj   0/1     Pending   0          50s

하위 태스크 2

ClusterIP Service 생성

클러스터 내부 통신을 위한 Service 생성

clusterip.yaml:

apiVersion: v1
kind: Service
metadata:
  name: my-app-service
spec:
  type: ClusterIP
  selector:
    app: my-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80

Service를 생성한다.

kubectl apply -f clusterip.yaml

결과:

service/my-app-service created

하위 태스크 3

Service와 Pod 연결 확인

kubectl get endpoints로 연결 상태 확인

서비스 상태와 IP를 확인한다.

kubectl get svc

결과:

NAME             TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
kubernetes       ClusterIP   10.96.0.1      <none>        443/TCP   12m
my-app-service   ClusterIP   10.105.6.138   <none>        80/TCP    25s

엔드포인트 연결을 확인한다.

kubectl get endpoints

결과:

NAME             ENDPOINTS           AGE
kubernetes       192.168.1.10:6443   13m
my-app-service   <none>              91s

하위 태스크 4

클러스터 내부 접근 테스트

클러스터 내부에서 Service를 통한 접근 테스트

클러스터 내부에서 curl 명령어를 사용할 수 있는 임시 Pod를 띄운다.

kubectl run test-pod --image=curlimages/curl -it --rm -- /bin/sh

셸에 접속되면 Service의 이름을 사용해서 HTTP 요청을 보낸다.

curl http://my-app-service

하위 태스크 5

NodePort Service 생성

외부 접근을 위한 NodePort Service 생성

nodepart.yaml:

apiVersion: v1
kind: Service
metadata:
  name: my-app-nodeport
spec:
  type: NodePort
  selector:
    app: my-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 30001

Service를 생성한다.

kubectl apply -f nodeport.yaml

결과:

service/my-app-nodeport created

생성된 서비스를 확인한다.

kubectl get svc

결과:

NAME              TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes        ClusterIP   10.96.0.1        <none>        443/TCP        31m
my-app-nodeport   NodePort    10.103.120.110   <none>        80:30001/TCP   4m32s
my-app-service    ClusterIP   10.105.6.138     <none>        80/TCP         20m

하위 태스크 6

외부 접근 테스트

노드 IP와 포트로 외부에서 접근 테스트

호스트에서 curl 명령어를 사용한다.

curl http://192.168.1.10:30001

결과:

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, nginx is successfully installed and working.
Further configuration is required for the web server, reverse proxy,
API gateway, load balancer, content cache, or other features.</p>
 
<p>For online documentation and support please refer to
<a href="https://nginx.org/">nginx.org</a>.<br/>
To engage with the community please visit
<a href="https://community.nginx.org/">community.nginx.org</a>.<br/>
For enterprise grade support, professional services, additional
security features and capabilities please refer to
<a href="https://f5.com/nginx">f5.com/nginx</a>.</p>
 
<p><em>Thank you for using nginx.</em></p>
</body>
</html>

하위 태스크 7

포트 포워딩 실습

kubectl port-forward로 로컬 접근

로컬의 8080 포트를 Pod의 80 포트로 연결한다.

kubectl port-forward pod/my-app-deploy-78f59dd94b-bgww2 8080:80

하위 태스크 8

Ingress Controller 확인

Ingress Controller 설치 상태 확인

kubectl get pods -n ingress-nginx

결과: Ingress Controller가 설치되지 않았다.

No resources found in ingress-nginx namespace.

Ingress Controller를 설치한다.

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.2/deploy/static/provider/baremetal/deploy.yaml

설치 상태를 다시 확인한다.

kubectl get pods -n ingress-nginx

결과:

NAME                                        READY   STATUS              RESTARTS   AGE
ingress-nginx-admission-create-lq4lk        0/1     Completed           0          6s
ingress-nginx-admission-patch-lxkl9         0/1     Completed           0          6s
ingress-nginx-controller-66bdb4887b-4kl4b   0/1     ContainerCreating   0          6s

하위 태스크 9

Ingress 규칙 작성

도메인과 경로 기반 라우팅 규칙 작성

ingress.yaml:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-app-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
  - host: example.com
    http:
      paths:
      - path: /web
        pathType: Prefix
        backend:
          service:
            name: my-app-service
            port:
              number: 80

하위 태스크 10

Ingress 적용 및 테스트

Ingress를 적용하고 도메인으로 접근 테스트

Ingress를 적용한다.

kubectl apply -f ingress.yaml

결과:

ingress.networking.k8s.io/my-app-ingress created

실제 도메인이 없으므로 hosts 파일을 수정한다.

/etc/hosts:

# ...
192.168.1.10 example.com

설정한 도메인과 경로로 요청을 보낸다.

curl http://example.com:31980/web

결과:

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, nginx is successfully installed and working.
Further configuration is required for the web server, reverse proxy,
API gateway, load balancer, content cache, or other features.</p>
 
<p>For online documentation and support please refer to
<a href="https://nginx.org/">nginx.org</a>.<br/>
To engage with the community please visit
<a href="https://community.nginx.org/">community.nginx.org</a>.<br/>
For enterprise grade support, professional services, additional
security features and capabilities please refer to
<a href="https://f5.com/nginx">f5.com/nginx</a>.</p>
 
<p><em>Thank you for using nginx.</em></p>
</body>
</html>