[Retry, k8s] 20. 서비스 API - 인그레스(Ingress) (2)
카테고리: KUBERNETES
태그: kubernetes
[Retry, k8s] 20. 서비스 API - 인그레스(Ingress) (2)
🔔 인그레스(Ingress) - SSL/TLS 암호화
(1) TLS 암호화를 포함한 인그레스의 매니페스트 작성
-
“nginx.ingress.kubernetes.io/force-ssl-redirect: ‘true’“는 HTTP로 접속한 경우 HTTPS로 리다이렉트하는 설정
-
“tls”는 암호 설정 섹션으로 대상이 되는 도메인(“tls.hosts”)과 해당 도메인의 (“tls.secretName”) 서버 인증서가 보관된 시크릿을 지정
cat << EOF > ingress-tls.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hello-ingress
annotations:
kubernetes.io/ingress.class: 'nginx'
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/force-ssl-redirect: 'true'
spec:
tls:
- hosts:
- abc.sample.com
secretName: tls-certificate
rules:
- host: abc.sample.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: helloworld-svc
port:
number: 8080
- path: /apl2
pathType: Prefix
backend:
service:
name: nginx-svc
port:
number: 9080
- host: xyz.sample.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: java-svc
port:
number: 9080
EOF
(2) 자체 서명 인증성 생성
$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout nginx-selfsigned.key -out ngin-selfsigned.crt
(3) 자체 서명 인증서를 시크릿에 보관
$ kubectl create secret tls tls-certificate --key nginx-selfsigned.key --cert ngin-selfsigned.crt
secret/tls-certificate created
$ kubectl get secrets
NAME TYPE DATA AGE
default-token-62jwj kubernetes.io/service-account-token 3 37d
tls-certificate kubernetes.io/tls 2 7s
(4) 보안 프로토콜을 적용한 인그레스 생성과 확인
$ kubectl apply -f ingress-tls.yaml
ingress.networking.k8s.io/hello-ingress created
$ kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
hello-ingress <none> abc.sample.com,xyz.sample.com 192.168.219.190 80, 443 65s
## abc.sample.com의 도메인과 대응하는 시크릿의 이름이 출력되어 정상적으로 매니페스트가 적용된 것을 알 수 있다.
$ kubectl describe ingress
Name: hello-ingress
Labels: <none>
Namespace: default
Address: 192.168.219.190
Ingress Class: <none>
Default backend: <default>
TLS:
tls-certificate terminates abc.sample.com ## <- 이 부분에 주목
Rules:
Host Path Backends
---- ---- --------
abc.sample.com
/ helloworld-svc:8080 (10.46.0.2:80)
/apl2 nginx-svc:9080 (10.40.0.2:80,10.40.0.3:80,10.46.0.3:80)
xyz.sample.com
/ java-svc:9080 (10.46.0.4:9080)
Annotations: kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/force-ssl-redirect: true
nginx.ingress.kubernetes.io/rewrite-target: /
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Sync 70s (x2 over 85s) nginx-ingress-controller Scheduled for sync

🔔 인그레스(Ingress) - 세션 어피니티
-
로드 밸런서의 세션 어피니티(Sticky Session)와 쿠버네티스의 세션 어피니티는 비슷한 개념이지만 구현 방식이 다르다.
-
로드 밸런서의 세션 어피니티(Sticky Session)는 **클라이언트의 요청을 특정 서버에 고정시키는 기능**으로, 쿠키나 IP 주소 등을 이용하여 구현할 수 있다.
-
쿠버네티스의 세션 어피니티는 서비스 오브젝트의 spec.sessionAffinity 필드를 이용하여 설정할 수 있으며, 클라이언트 IP 주소를 기반으로 파드에 요청을 분배한다.
-
-
쿠버네티스의 세션 어피니티는 로드밸런서의 세션 어피니티보다 간단하고 제한적인 기능을 제공한다.
-
쿠버네티스의 세션 어피니티는 클라이언트 IP 주소만을 기반으로 하기 때문에, 로그인 상태를 유지하는 등의 세션을 유지 할 수 없다.
-
그래서 ingress나 LoadBalancer 서비스와 같은 L7 로드밸런서를 사용하여 로드 밸런서의 세션 어피니티를 이용할 수 있다.
-
(1) 세션 어피니티를 설정하는 매니페스트
- “nginx.ingress.kubernetes.io/affinity: ‘cookie’” : 세션 어피니티 활성화
cat <<EOF > ingress-session.yaml
cat ingress-session.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hello-ingress
annotations:
kubernetes.io/ingress.class: 'nginx'
nginx.ingress.kubernetes.io/affinity: 'cookie'
spec:
rules:
- host: abc.sample.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: session-svc
port:
number: 9080
EOF
(2) Test 용 Deployment 매니페스트
cat <<EOF > session-test.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: session-deployment
spec:
selector:
matchLabels:
app: session
replicas: 10
template:
metadata:
labels:
app: session
spec:
containers:
- image: 'maho/session-test:latest'
name: session
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: session-svc
spec:
selector:
app: session
ports:
- port: 9080
targetPort: 80
EOF
(3) 매니페스트 적용
$ kubectl get all,ingress
NAME READY STATUS RESTARTS AGE
pod/session-deployment-79977b8778-268rk 1/1 Running 0 111s
pod/session-deployment-79977b8778-2r2hz 1/1 Running 0 111s
pod/session-deployment-79977b8778-4x2l5 1/1 Running 0 111s
pod/session-deployment-79977b8778-6ljlp 1/1 Running 0 111s
pod/session-deployment-79977b8778-gvhq8 1/1 Running 0 111s
pod/session-deployment-79977b8778-hdq6w 1/1 Running 0 111s
pod/session-deployment-79977b8778-k9fml 1/1 Running 0 111s
pod/session-deployment-79977b8778-nxlnt 1/1 Running 0 111s
pod/session-deployment-79977b8778-trmbs 1/1 Running 0 111s
pod/session-deployment-79977b8778-wn2rf 1/1 Running 0 111s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 6h10m
service/session-svc ClusterIP 10.110.133.243 <none> 9080/TCP 111s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/session-deployment 10/10 10 10 111s
NAME DESIRED CURRENT READY AGE
replicaset.apps/session-deployment-79977b8778 10 10 10 111s
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress.networking.k8s.io/hello-ingress <none> abc.sample.com 192.168.219.190 80 4m1s
(4) 결과 확인
-
curl -c 옵션 : 요청을 보내고, 응답 쿠키를 파일에 저장
-
curl -b 옵션 : 저장한 쿠키를 헤더에 추가해서 요청
-
쿠키 값에 따라 파드가 결정되어 카운트 값이 증가한 것을 알 수 있다.
$ curl -c cookie.dat http://abc.sample.com
Hostname: session-deployment-79977b8778-79lrc<br>
1th time access.
$ curl -b cookie.dat http://abc.sample.com
Hostname: session-deployment-79977b8778-79lrc<br>
2th time access.
$ curl -b cookie.dat http://abc.sample.com
Hostname: session-deployment-79977b8778-79lrc<br>
3th time access.
$ curl -b cookie.dat http://abc.sample.com
Hostname: session-deployment-79977b8778-79lrc<br>
4th time access.
$ curl -b cookie.dat http://abc.sample.com
Hostname: session-deployment-79977b8778-79lrc<br>
5th time access.
$ curl -b cookie.dat http://abc.sample.com
Hostname: session-deployment-79977b8778-79lrc<br>
6th time access.
댓글 남기기