1) Nginx Ingress 컨트롤러
2) AWS Load Balancer 컨트롤러
3) Nginx Ingress 컨트롤러를 활용하여 실습한다.
- m1에서 ingress 실습이 까다로울 수 있어서 ubuntu로 진행하였다.
- 참고로 ubuntu는 UTM(가상머신)으로 설치하였고, m1으로 ubuntu ssh 접속을 통해 실습을 진행하였다.
- ingress 폴더를 만들고 3개의 yml을 준비한다.
- ingress 폴더안에 grafana, hello, httpd 폴더를 추가로 만들고 각각에 yml을 2개씩 또 만든다.
ingress-path.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: path
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- http:
paths:
- path: /hello
pathType: Prefix
backend:
service:
name: hello
port:
name: http
- http:
paths:
- path: /grafana
pathType: Prefix
backend:
service:
name: grafana
port:
name: http
ingress-host.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: host
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: hello.bakumando
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: hello
port:
name: http
- host: grafana.bakumando
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: grafana
port:
name: http
ingress-default-backend.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: default-backend
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
defaultBackend:
service:
name: httpd
port:
number: 80
rules:
- host: hello.bakumando
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: hello
port:
name: http
- host: grafana.bakumando
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: grafana
port:
name: http
- ingress 테스트를 위한 3가지 yml 파일들을 준비했다. 이에 대한 설명은 하나씩 실습을 하면서 진행해보자.
grafana/deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: grafana
labels:
app: "grafana"
spec:
replicas: 1
selector:
matchLabels:
app: "grafana"
template:
metadata:
labels:
app: "grafana"
spec:
containers:
- name: grafana
image: grafana/grafana:latest
ports:
- name: http
containerPort: 3000
grafana/service.yml
apiVersion: v1
kind: Service
metadata:
name: grafana
labels:
app: "grafana"
spec:
type: ClusterIP
ports:
- name: http
protocol: TCP
port: 80
targetPort: 3000
selector:
app: "grafana"
- grafana 폴더에 deployment와 service yml을 각각 만든다.
hello/deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello
spec:
replicas: 3
selector:
matchLabels:
app: hello
template:
metadata:
name: hello
labels:
app: hello
spec:
containers:
- name: nginx
image: nginxdemos/hello:plain-text
ports:
- name: http
containerPort: 80
protocol: TCP
hello/service.yml
apiVersion: v1
kind: Service
metadata:
name: hello
labels:
app: hello
spec:
type: ClusterIP
ports:
- name: http
protocol: TCP
port: 8080
targetPort: 80
selector:
app: hello
- hello 폴더에 deployment와 service yml을 각각 만든다.
httpd/deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpd
labels:
app: "httpd"
spec:
replicas: 1
selector:
matchLabels:
app: "httpd"
template:
metadata:
labels:
app: "httpd"
spec:
containers:
- name: httpd
image: httpd:latest
ports:
- name: http
containerPort: 80
httpd/service.yml
apiVersion: v1
kind: Service
metadata:
name: httpd
labels:
app: "httpd"
spec:
type: ClusterIP
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
selector:
app: "httpd"
- httpd 폴더에 deployment와 service yml을 각각 만든다.
(1) ingress 기본 세팅 및 조회
- kubectl apply -f grafana/
- kubectl apply -f hello/
- kubectl apply -f httpd/
- 만들어둔 deployment, service yml을 전부 적용한다.
- kubectl get all
- 생성 결과를 조회해본다.
- minikube addons list
- ingress가 disabled인걸 확인할 수 있다.
- minikube addons enable ingress
- 이어서 바로 ingress를 설치한다.
- kubectl get ns
- namespace를 조회한다. 그럼 ingress-nginx라는 ns가 새로 생긴 걸 볼 수 있다.
- kubectl get all -n ingress-nginx
- ingress-nginx 네임스페이스에 대한 전체 오브젝트 조회를 해본다.
- 여러가지 오브젝트들이 생성되어 있음을 알 수 있다.
- kubectl get ingressclass
- ingress 클래스도 조회해본다. 클래스로 nginx가 적용된 걸 확인할 수 있다.
- kubectl get ingressclass nginx -o yaml
- 이렇게 yaml 파일로도 출력해볼 수 있다.
(2) ingress-path 실습
- cat ingress-path.yml
- 명세를 보면 name은 path인 걸 확인할 수 있고, ingressClassName도 nginx인 걸 알 수 있다.
- http.paths.path가 /hello일 경우, hello service에 http 포트로 보내라 라는 정의가 되어 있다.
- http.paths.path가 /grafana일 경우, grafana service에 http 포트로 보내라 라는 정의가 되어 있다.
- kubectl apply -f ingress-path.yml
- kubectl get ingress
- ingress-path.yml를 적용한 뒤에 ingress 목록을 조회해보았다.
- name은 path, class는 nginx을 사용하도록 하는 ingress 오브젝트가 생성되었음을 알 수 있다.
- kubectl get service -n ingress-nginx
- ingress-nginx라는 ns(namespace)의 service를 조회한 것이다. ingress-nginx의 컨트롤러도 service형태로 띄워진다는 걸 확인할 수 있다. 서비스 타입은 NodePort이고 모든 Node가 공통의 포트로 오픈되어 외부 트래픽을 받게 된다.
- 접근 가능한 URL은 {Node IP}:{NodePort} 형식이다.
- kubectl get node -o wide
- Node IP를 조회해보자. 192.168.49.2이다.
- Node Port는 위에서 이미 조회하였다. http는 32655이다.
- curl http://192.168.49.2:32655
- nginx로 연결된 걸 알 수 있다.
- curl http://192.168.49.2:32655/grafana
- curl http://192.168.49.2:32655/hello
- grafana, hello 경로 접근도 잘 이루어진다는 걸 알 수 있다.
- kubectl delete -f ingress-path.yml
- ingress-path.yml를 지워준다.
(3) ingress-host 실습
- cat ingress-host.yml
- ingress-path와 다른 건 동일한데, rules의 host가 추가되었고, path가 변경되었다.
- 들어오는 요청에 대해서 host가 hello.bakumando면, hello service의 http 포트로 보내라는 정의를 하였다.
- 반면 host가 grafana.bakumando면, grafana service의 http 포트로 보내라는 정의를 하였다.
- kubectl apply -f ingress-host.yml
- kubectl get ingress
- ingress-host.yml을 적용하고, ingress를 조회하였다.
- name은 host, class는 nginx를 사용하도록 되어있고 hosts도 2가지가 잘 설정되어 있다.
- curl http://192.168.49.2:32655
- 마찬가지로 ingress controller 서비스의 Node Ip와 Port를 토대로 조회하면 된다.
- 역시나 nginx가 잘 연결된다.
- curl http://192.168.49.2:32655 -H "Host: hello.bakumando"
- curl http://192.168.49.2:32655 -H "Host: grafana.bakumando"
- 조회 -H "Host: {host 값}" 형식을 추가해주면 된다.
- 여기서 -H는 http header를 의미한다. 즉 header를 변경해주면 되는 것이다. 그 뒤에는 형식에 맞춰 설정한 값을 잘 넣어주면 된다.
- hello.bakumando, grafana.bakumando host 둘다 잘 접근되었다.
- 물론 실제 현업에서는 header값을 변조하지 않는다. 실제 쿠버네티스 클러스터 상의 도메인 설정을 해준다.
- kubectl delete -f ingress-host.yml
- ingress-host.yml를 제거해준다.
(4) ingress-default-backend 실습
- cat ingress-default-backend.yml
- ingress-host와 거의 동일한데, defaultBackend라는 부분이 추가되었다. defaultBackend 속성은 아래 rules 중에 아무것도 속하지 못할 경우에 해당 백엔드로 보내라는 것이다.
- 즉, 앞선 두번의 실습에선 경로나 호스트를 제대로 명시해주지 않으면 그냥 nginx not found 404 결과가 나왔었는데, defaultBackend를 정의하게 되면 그 아래 service 설정대로 응답을 받게된다.
- defaultBackend를 httpd라는 이름으로 정의해두었다.
- kubectl apply -f ingress-default-backend.yml
- kubectl get ingress
- ingress-default-backend.yml를 적용하고 조회하였다.
- name은 default-backend, class는 nginx를 사용하도록 되어있고, hosts도 이전과 같다.
- curl http://192.168.49.2:32655 -H "Host: hello.bakumando"
- curl http://192.168.49.2:32655 -H "Host: grafana.bakumando"
- 호스트값을 토대로 돌아오는 접근 결과는 이전과 같다.
- curl http://192.168.49.2:32655 -H "Host: bakumando"
- 설정되어있지 않은 호스트값을 넣었더니, nginx 404가 아닌 다른 결과가 나오는 걸 볼 수 있다.
- 이게 바로 defaultBackend 속성을 정의했기 때문이며, 거기에 httpd로 응답되도록 설정 해뒀기 때문에, httpd 컨테이너의 결과인 것이다.