ネットワークトレーニング33日目(2022.02.18)


サービスマルチポート構成

파드의 애플리케이션은 항상 하나의 포트로만 서비스하는 것이 아닌
여러 포트를 사용하여 서비스 가능

서비스 역시 파드의 서비스 포트가 다중 포트인 경우, 노출할 서비스 포트 여시 다중 포트로 구성할 수 있음

예를 들어 웹 서버인 경우 HTTP는 80번, HTTPS는 443번 다중 포트를 가진 파드 및 서비스를 구성해야 할 경우도 있음

다중 포트 구성은 서비스 포트가 단일 포트라고 하더라도, yml의 리스트로 구성 가능
다중 포트를 설정할 때는 반드시 포트의 이름을 부여해야 함

.spec.ports.name: 포트의 이름

- 포트 이름 참조

파드나 파드를 생성하는 컨트롤러의 파드 템플릿의 컨테이너 포트에도 이름을 부여할 수 있음

이렇게 하면 파드(컨테이너)의 포트 이름을 이용하여 서비스 생성 시 
파드의 대상포트(targetPort)에 이름을 이용하여 연결 가능

이는 이름으로 참조하기 때문에 파드의 포트 이름만 변경되지 않았다면,
실제 파드의 포트 번호가 변경되더라도,
스펙의 변경 없이 계속해서 연결할 수 있음
이럴 경우, 엔드포인트도 변경

ポート名を使用したReplicasetとサービスの作成


컨테이너의 8080 포트에 testapp-http라는 이름을 부여
이름을 서비스 생성 시 참조 가능

リファレンスポート名のサービスの設定


.spec.ports.targetPort: 대상 파드의 포트 이름 지정

Replicasetコントローラとサービスの作成

kubectl create -f testapp-rs-namedport.yml -f testapp-svc-namedport.yml

オブジェクトのチェック

kubectl replicasets.apps testapp-rs-namedport

エンドポイントの確認

kubectl get endpoints
kubectl get endpoints testapp-svc-namedport

シードリストとIPの検証

kubectl get pods -o wide -l app=testapp-rs-namedport
ブラウズサービス -クバーネディスのクラスタ・サービスは、パイドで直接ナビゲートおよびアクセスできます。
● 환경 변수를 이용한 탐색 방법
● DNS를 이용한 탐색 방법

- 환경 변수를 이용한 서비스 탐색
쿠버네티스 클러스터는 파드가 시작될 때 현재 존재하는 서비스를 파드 내의 쉘 환경 변수로 설정

하나의 서비스에 설정되는 여러 형태의 쉘 환경 변수:
● {SVC_NAME}_SERVICE_HOST={SVC_IP}
● {SVC_NAME}_SERVICE_PORT={SVC_PORT}
● {SVC_NAME}_PORT={PROTOCOL}://{SVC_IP}:{SVC_PORT}
● {SVC_NAME}_PORT_{PORT_NUMBER}_{PROTOCOL}={PROTOCOL}://{SVC_IP}:{SVC_PORT}
● {SVC_NAME}_PORT_{PORT_NUMBER}_{PROTOCOL}_ADDR={SVC_IP}
● {SVC_NAME}_PORT_{PORT_NUMBER}_{PROTOCOL}_PORT={SVC_PORT}
● {SVC_NAME}_PORT_{PORT_NUMBER}_{PROTOCOL}_PROTO={PROTOCOL}

envコマンドを使用してShell環境変数をチェック kubectl run nettool -it -- image=ghcr.io/c1t1d0s7/network-multitool --rm bash bash-5.1# env 出力されるほとんどの環境変数には、先に作成したkubernetes、testpp-svc、testpp-svc-namedport、testpp-svc-se-affサービスの環境変数が含まれます。 testpp-svcサービスの以下の環境変数を参照してください。 ● testapp_SVC_SERVICE_HOST=10.233.24.226 ● testapp_SVC_SERVICE_PORT=80 アプリケーションがサービス名のみを知っている場合は、 適切な環境変数を参照してください。 アクセスするサービスのIPとポートを特定

DNSナビゲーションサービスの使用

쿠버네티스 클러스터는 클러스터 시스템 내부에서 사용할 수 있는
DNS 서버가 동작하고 있음

DNS関連リソースの検証

kubectl get all -n kube-system -l k8s-app=kube-dns

DNS 관련 서비스인 service/coredns 서비스가 있으며 
10.233.xxx.xxxx IP로 접근할 수 있음
표준 DNS 포트인 53번으로 서비스하고 있음

PARD内部DNS設定の確認

kubectl run nettool -it --image=ghcr.io/c1t1d0s7/network-multitool --rm bash

bash-5.1# cat /etc/resolv.conf

예상과는 다르게 DNS 서버는 169.254.25.10으로 설정되어 있음

ノードローカルDNSキャッシュ

기존에는 파드 내의 DNS 서버 설정도 coredns 서비스의 IP가 부여되어 있음

즉, 파드가 직접적으로 coredns 서비스에 DNS 쿼리/응답을 받게 되었는데, 이는 대규모 환경에서 병목현상을 만들어 성능이 저하된다는 단점이 있음

쿠버네티스 1.15 버전부터 추가된 노드 로컬 DNS 캐시(NodeLocal DNSCache) 기능이 도입

노드 로컬 DNS 캐시 기능은 
쿠버네티스의 각 노드에 DNS 캐시 기능을 가지고 있는 파드를 데몬셋으로 배치하고,
파드의 DNS 쿼리 및 응답을 coredns가 대신하게 되는 구조

NodeLocal
Pod <--> NodeLocal DNSCache(169.254.25.10) <--> iptables <--> coredns(10.233.0.3)

kubectl get daemonsets.apps -l k8s-app=kube-dns -n kube-system

kube-system 네임스페이스에 nodelocaldns 데몬셋 컨트롤러가 존재

Nodelocaldnsに関連するシードリストをチェック

kubectl get pods -l k8s-app=nodelocaldns -n kube-system

Nodelocaldnsシードの仕様設定

kubectl get pods -l k8s-app=nodelocaldns -n kube-system -o jsonpath='{.items[*].spec.containers[*].args[*]}'

이는 각 노드에서 169.254.25.10 IP인 링크로컬 주소 대역을 사용해 DNS 캐시 서비스를 제공한다는 의미

FQDNナビゲーションサービスの使用

kubectl run nettool -it --image=ghcr.io/c1t1d0s7/network-multitool --rm bash


bash-5.1# curl http://testapp-svc

bash-5.1# curl http://testapp-svc.default

bash-5.1# curl http://testapp-svc.default.svc

bash-5.1# curl http://testapp-svc.default.svc.cluster.local

testapp-svc 서비스에 접근하기 위한 FQDN 주소는 mynapp-svc.default.svc.cluster.local 

● mynapp-svc: 서비스의 이름
● default: 서비스 리소스의 네임스페이스 이름
● svc: 서비스 그 자체를 의미함
● cluster.local: 쿠버네티스 클러스터 도메인

FQDNのアドレスフォーマット

<서비스 이름>.<네임스페이스>.<리소스 종류>.<클러스터 도메인>
mynapp-svc.default.svc.cluster.local

クラスタ外部サービス

쿠버네티스 클러스터에서 웹의 프론트엔드 서비스를 실행하는 파드의 경우 쿠버네티스 클러스터의 외부로 노출시켜 접근 가능하도록 구성

외부 서비스용 레플리카셋 생성 및 확인

기존에 작성된 testapp-rs 파일을 이용하여 컨트롤러 및 파드를 생성

kubectl create -f testapp-rs.yml

컨트롤러 및 파드가 생성되었는지 확인

kubectl get replicasets.apps

kubectl get pods

NodePortサービスの作成


.spec.type: 서비스 타입 (기본: ClusterIP)
.spec.ports.nodePort: 30000-32767 포트, 포트를 지정하지 않으면 랜덤한 포트 지정

서비스 타입은 NodePort이며, 노드에 노출할 포트는 31111 포트이다.
포트는 기본적으로 30000-32767 포트 내에서만 사용 가능

ノードポートサービスの作成

kubectl create -f testapp-svc-np.yml
NodePort 서비스 확인

kubectl get service testapp-svc-np

- 노드의 31111 포드로 접근하면 서비스의 80 포트로 리다이렉션

kubectl get endpoints testapp-svc-np

서비스의 80 포트는 파드의 8080 포트로 리다이렉션

- 노드의 IP를 확인

kubectl get nodes -o wide

- 노드포트 접근

curl http://192.168.56.11:31111

curl http://192.168.56.21:31111

curl http://192.168.56.22:31111

curl http://192.168.56.23:31111

외부에서 192.168.56.X:31111로 접근하면, 서비스 포트인 80번 포트로 리다이렉션 되며,
이는 다시 내부 파드의 8080번 포트로 리다이렉션
LoadBankサービス

作成

클라우드 인프라에서 LoadBalancer 서비스를 생성하면 
클라우드 인프라의 로드 밸런서를 자동으로 프로비저닝 하게 되며, 
이 로드 밸런서를 통해 서비스와 파드에 접근할 수 있음

환경설정

Kubernetes 로드밸런서 서비스를 위한 MetalLB 설치

- 디렉토리 변경

cd ~/kubespray


- Kubernetes 클러스터 설정 변경

vi inventory/mycluster/group_vars/k8s-cluster/k8s-cluster.yml

kube_proxy_strict_arp: true


- 로드밸런서에 할당할 IP 범위 설정

vi contrib/metallb/roles/provision/defaults/main.yml

  ip_range: "192.168.56.200-192.168.56.220"


- MetalLB 설치

ansible-playbook -i inventory/mycluster/inventory.inicontrib/metallb/metallb.yml -b



- MetalLB 네임스페이스 확인

kubectl get ns
kubectl create -f testapp-svc-lb.yml

ロードバランササービスの確認

 kubectl get service testapp-svc-lb

로드 밸런서의 외부 IP가 192.168.56.200으로 정상적으로 할당된 것을 확인할 수 있음

클라우드의 관리형 쿠버네티스 서비스 및 MetalLB를 사용하지 않는 경우, 
외부 로드 밸런서가 프로비저닝 되지 않기 때문에 
외부 IP(로드 밸런서 IP)가 할당되지 않고 <pending> 상태로 보고

실제 외부 로드 밸런서를 사용할 수 있는 경우, 
외부의 로드 밸런서가 생성되고 IP가 할당되기까지 시간이 필요

- 로드 밸런서 서비스의 IP로 접근

curl http://192.168.56.200

外部名サービスの作成

ExternalName 서비스는 NodePort 및 LoadBalancer와 다르게 
외부에서 접근하기 위한 서비스 종류가 아닌 
내부 파트가 외부의 특정 FQDN에 쉽게 접근하기 위한 서비스

즉, 쿠버네티스 클러스터의 coredns 서비스가 특정 FQDN에 대한 CNAME(서비스의 FQDN)을 제공함
해당 CNAME을 이용하여 쉽게 통신할 수 있음

심지어 접속하기 위한 외부 FQDN 주소가 바뀌더라도, 
CNAME은 그대로 유지할 수 있어 애플리케이션을 다시 작성하거나 빌드 하지 않아도 됨
외부 FQDN은 www.google.com이며 
이에 대한 CNAME은 testapp-svc-extname 
이름을 제공하는 서비스
파드와 매칭하지 않기 때문에 레이블 셀렉터는 없음

kubectl create -f testapp-svc-extname.yml

ExternalName 서비스 확인

kubectl get service testapp-svc-extname

서비스 타입은 ExternalName이며, 
외부 IP에는 www.google.com의 FQDN이 할당되어 있음

즉, 파드는 testapp-svc-extername CNAME을 사용하면 
www.google.com의 주소를 알 수 있음

kubectl run nettool -it --image=ghcr.io/c1t1d0s7/network-multitool --rm bash

bash-5.1# host testapp-svc-extname