이 문서에서는 Google Distributed Cloud용 사용자, 하이브리드 또는 독립형 클러스터에서 Kubernetes 인그레스 객체를 만드는 방법을 보여줍니다. 인그레스는 각각 포드 집합과 연결된 서비스 하나 이상과 연결됩니다.
배포 만들기
배포를 만들려면 다음 단계를 따르세요.
배포 매니페스트를 만듭니다.
apiVersion: apps/v1 kind: Deployment metadata: name: hello-deployment spec: selector: matchLabels: greeting: hello replicas: 3 template: metadata: labels: greeting: hello spec: containers: - name: hello-world image: "gcr.io/google-samples/hello-app:2.0" env: - name: "PORT" value: "50000" - name: hello-kubernetes image: "gcr.io/google-samples/node-hello:1.0" env: - name: "PORT" value: "8080"
이 실습을 진행하면서 배포 매니페스트에 대해 알아야 할 중요한 사항은 다음과 같습니다.
배포에 속한 각 pod에는
greeting: hello
라벨이 있습니다.각 pod에는 2개의 컨테이너가 있습니다.
env
필드는hello-app
컨테이너가 TCP 포트 50000에서 리슨하고node-hello
컨테이너가 TCP 포트 8080에서 리슨하는 것을 지정합니다.hello-app
의 경우 소스 코드를 보면PORT
환경 변수의 효과를 확인할 수 있습니다.
이름이
hello-deployment.yaml
인 파일에 매니페스트를 복사합니다.배포를 만듭니다.
kubectl apply --kubeconfig CLUSTER_KUBECONFIG -f hello-deployment.yaml
CLUSTER_KUBECONFIG
를 클러스터의 kubeconfig 파일 이름으로 바꿉니다.
서비스에 배포 노출
클라이언트가 배포의 포드로 요청을 보내는 안정적인 방법을 제공하려면 서비스를 만드세요.
클러스터 내부 클라이언트에 배포를 노출하는 서비스 매니페스트를 만듭니다.
apiVersion: v1 kind: Service metadata: name: hello-service spec: type: ClusterIP selector: greeting: hello ports: - name: world-port protocol: TCP port: 60000 targetPort: 50000 - name: kubernetes-port protocol: TCP port: 60001 targetPort: 8080
이름이
hello-service.yaml
인 파일에 매니페스트를 복사합니다.서비스 만들기:
kubectl apply --kubeconfig CLUSTER_KUBECONFIG -f hello-service.yaml
CLUSTER_KUBECONFIG
를 클러스터의 kubeconfig 파일 이름으로 바꿉니다.서비스를 확인합니다.
kubectl --kubeconfig CLUSTER_KUBECONFIG get service hello-service --output yaml
서비스에 제공된
clusterIP
의 값이 출력에 표시됩니다. 예를 들면 다음과 같습니다.apiVersion: v1 kind: Service metadata: annotations: ... spec: clusterIP: 10.96.14.249 clusterIPs: - 10.96.14.249 ipFamilies: - IPv4 ipFamilyPolicy: SingleStack ports: - name: world-port port: 60000 protocol: TCP targetPort: 50000 - name: kubernetes-port port: 60001 protocol: TCP targetPort: 8080 selector: greeting: hello sessionAffinity: None type: ClusterIP status: loadBalancer: {}
위 출력에서
ports
필드는 이름이 각각world-port
및kubernetes-port
인ServicePort
객체의 배열입니다. 서비스 필드에 대한 자세한 내용은 Kubernetes 문서의 ServiceSpec을 참조하세요.클라이언트에서 서비스를 호출할 수 있는 방법은 다음과 같습니다.
world-port
사용: 클러스터 노드 중 하나에서 실행되는 클라이언트가port
(예:10.96.14.249:60000
)의clusterIP
에 요청을 전송합니다. 인그레스 컨트롤러는targetPort
(예:POD_IP_ADDRESS:50000
, 여기서POD_IP_ADDRESS
은 구성원 포드의 IP 주소)의 구성원 포드로 요청을 전달합니다.kubernetes-port
사용: 클러스터 노드 중 하나에서 실행되는 클라이언트가port
(10.96.14.249:60001
)의clusterIP
에 요청을 전송합니다. 인그레스 컨트롤러는targetPort
(POD_IP_ADDRESS:8080
)의 멤버 포드로 요청을 전달합니다.
인그레스 구성요소
인그레스와 관련된 몇 가지 클러스터 구성요소는 다음과 같습니다.
istio-ingress
배포. 인그레스 프록시입니다. 인그레스 프록시는 인그레스 객체에 지정된 규칙에 따라 트래픽을 내부 서비스로 전달합니다.istio-ingress
서비스. 이 서비스는istio-ingress
배포를 노출합니다.istiod
배포. 인그레스 컨트롤러입니다. 인그레스 컨트롤러는 인그레스 객체 생성을 감시하고 그에 따라 인그레스 프록시를 구성합니다.
이러한 모든 Istio 클러스터 내 구성요소는 gke-system
네임스페이스에 설치됩니다. 이 네임스페이스는 전체 Istio/Cloud Service Mesh 설치와 충돌하지 않습니다.
인그레스 만들기
다음 단계에 따라 인그레스를 만듭니다.
인그레스 매니페스트를 만듭니다.
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-ingress spec: rules: - http: paths: - path: /greet-the-world pathType: Exact backend: service: name: hello-service port: number: 60000 - path: /greet-kubernetes pathType: Exact backend: service: name: hello-service port: number: 60001
이름이
my-ingress.yaml
인 파일에 매니페스트를 복사합니다.인그레스를 만듭니다.
kubectl apply --kubeconfig CLUSTER_KUBECONFIG -f my-ingress.yaml
사용자 클러스터를 만들 때 클러스터 구성 파일에서 loadbalancer.ingressVIP
값을 지정합니다. 이 IP 주소는 클러스터 부하 분산기에서 구성됩니다. 인그레스를 만들면 외부 IP 주소와 동일한 이 VIP가 인그레스에 지정됩니다.
클라이언트가 사용자 클러스터 인그레스 VIP로 요청을 전송하면 요청이 부하 분산기로 라우팅됩니다. 부하 분산기는 istio-ingress
서비스를 사용하여 사용자 클러스터에서 실행되는 인그레스 프록시로 요청을 전달합니다.
인그레스 프록시는 요청 URL의 경로에 따라 요청을 다른 백엔드로 전달합니다.
/greet-the-world
경로
인그레스 매니페스트에서 /greet-the-world
경로가 serviceName: hello-service
및 servicePort: 60000
과 연결되어 있음을 나타내는 규칙을 확인할 수 있습니다. 60000은 hello-service
서비스의 world-port
섹션에 있는 port
값입니다.
- name: world-port
port: 60000
protocol: TCP
targetPort: 50000
인그레스 서비스는 요청을 clusterIP
:50000으로 전달합니다. 그런 다음 요청은 hello-service
서비스의 구성원 포드 중 하나로 이동합니다. 해당 포드의 포트 50000에서 리슨하는 컨테이너에 Hello World!
메시지가 표시됩니다.
/greet-kubernetes
경로
인그레스 매니페스트에서 /greet-kubernetes
경로가 serviceName: hello-service
및 servicePort: 60001
과 연결되어 있음을 나타내는 규칙을 확인할 수 있습니다. 60001은 hello-service
서비스의 kubernetes-port
섹션에 있는 port
값입니다
- name: kubernetes-port
port: 60001
protocol: TCP
targetPort: 8080
인그레스 서비스는 요청을 clusterIP
: 8080으로 전달합니다. 그런 다음 요청은 hello-service
서비스의 구성원 포드 중 하나로 이동합니다. 해당 포드의 포트 8080
에서 리슨하는 컨테이너에 Hello Kubernetes!
메시지가 표시됩니다.
인그레스 테스트
/greet-the-world
경로를 사용하여 인그레스를 테스트합니다.curl CLUSTER_INGRESS_VIP/greet-the-world
CLUSTER_INGRESS_VIP
를 인그레스의 외부 IP 주소로 바꿉니다.출력에
Hello, world!
메시지가 표시됩니다.Hello, world! Version: 2.0.0 Hostname: ...
/greet-kubernetes
경로를 사용하여 인그레스를 테스트합니다.curl CLUSTER_INGRESS_VIP/greet-kubernetes
출력에
Hello, Kubernetes!
메시지가 표시됩니다.Hello Kubernetes!
번들 인그레스 사용 중지
Google Distributed Cloud와 함께 번들로 제공되는 인그레스 기능은 인그레스 기능만 지원합니다. Istio 또는 Cloud Service Mesh와 통합할 수 있습니다. 이러한 제품은 상호 전송 계층 보안 (mTLS), 서비스 간 인증 관리 기능, 워크로드 관측 가능성과 같이 모든 기능을 갖춘 서비스 메시의 추가 이점을 제공합니다. Istio 또는 Cloud Service Mesh와 통합하는 경우 번들 인그레스 기능을 사용 중지하는 것이 좋습니다.
클러스터 구성 파일의 spec.clusterNetwork.bundledIngress
필드를 사용하여 번들 인그레스를 사용 설정하거나 중지할 수 있습니다.
이 필드는 버전 1.13.0 이상 클러스터에서만 사용할 수 있습니다. bundledIngress
필드의 기본값은 true
이며 생성된 클러스터 구성 파일에 없습니다. 이 필드는 변경 가능하며 버전 1.13.0 이상의 클러스터를 만들거나 업데이트할 때 변경할 수 있습니다.
번들 인그레스 기능을 사용 중지하려면 클러스터 구성 파일의
clusterNetwork
섹션에bundledIngress
필드를 추가하고 다음 예와 같이 값을 false로 설정합니다.apiVersion: v1 kind: Namespace metadata: name: cluster-hybrid-basic --- apiVersion: baremetal.cluster.gke.io/v1 kind: Cluster metadata: name: hybrid-basic namespace: cluster-hybrid-basic spec: type: hybrid profile: default anthosBareMetalVersion: 1.13.0 gkeConnect: projectID: project-fleet controlPlane: nodePoolSpec: nodes: - address: 10.200.0.2 clusterNetwork: bundledIngress: false pods: cidrBlocks: - 192.168.0.0/16 services: cidrBlocks: - 10.96.0.0/20 ...
인그레스에 HTTPS 설정
클라이언트의 HTTPS 요청을 수락하려면 인그레스 프록시에 인증서가 있어야 인그레스 프록시가 클라이언트에게 ID를 증명할 수 있습니다. 또한 이 프록시에 비공개 키가 있어야 HTTPS 핸드셰이크를 완료할 수 있습니다.
다음 예시에서 이러한 항목이 사용됩니다.
인그레스 프록시: HTTPS 핸드셰이크에 참여한 후
hello-service
서비스의 구성원 포드에 패킷을 전달합니다.hello-service
서비스의 도메인: 예시 조직의 altostrat.com
다음 단계를 따르세요.
루트 인증서와 비공개 키를 만듭니다. 이 예시에서는 루트 CA 예시 조직에서
root.ca.example.com
의 루트 인증 기관을 사용합니다.openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj \ '/O=Root CA Example Inc./CN=root.ca.example.com' -keyout root-ca.key \ -out root-ca.crt
인증서 서명 요청을 만듭니다.
openssl req -out server.csr -newkey rsa:2048 -nodes -keyout server.key -subj \ "/CN=altostrat.com/O=Example Org"
인그레스 프록시에 대해 서빙 인증서를 만듭니다.
openssl x509 -req -days 365 -CA root-ca.crt -CAkey root-ca.key -set_serial 0 \ -in server.csr -out server.crt
이제 다음 인증서 및 키가 생성되었습니다.
root-ca.crt
: 루트 CA의 인증서root-ca.key
: 루트 CA의 비공개 키server.crt
: 인그레스 프록시에 대한 제공 인증서server.key
: 인그레스 프록시의 비공개 키
서빙 인증서 및 키가 포함된 Kubernetes 보안 비밀을 만듭니다.
kubectl create secret tls example-server-creds --key=server.key --cert=server.crt \ --namespace gke-system
결과 보안 비밀은 이름이
example-server-creds
로 지정됩니다.
배포 및 서비스 만들기
이 가이드의 HTTP 부분에서 배포와 서비스를 만든 경우 이를 그대로 둡니다. 만들지 않았으면 HTTP에 설명된 단계에 따라 지금 만듭니다.
인그레스 만들기
HTTPS용 인그레스를 만드는 것은 HTTP용 인그레스를 만드는 것과 비슷하지만 HTTPS용 인그레스 사양에는 호스트와 보안 비밀을 지정하는 tls
섹션이 포함됩니다. tls
섹션의 hosts
는 rules
섹션의 host
와 명시적으로 일치해야 합니다.
백엔드 서비스가 별도의 네임스페이스에 있는 경우 인그레스와 동일한 네임스페이스에 ExternalName 유형의 서비스를 만들어 트래픽을 백엔드 서비스로 라우팅해야 합니다.
HTTPS 또는 HTTP용 인그레스를 만드는 전체 단계는 매니페스트 파일에서 구성하는 내용을 제외하고 동일합니다.
이 문서의 이전에 HTTP 부분에서 인그레스를 만든 경우 계속하기 전에 해당 인그레스를 삭제합니다.
kubectl --kubeconfig CLUSTER_KUBECONFIG delete ingress my-ingress
이전에 만든 서비스의 트래픽을 처리하려면
tls
섹션이 있는 새 인그레스 매니페스트를 만듭니다.tls
구성을 사용하면 클라이언트와 인그레스 프록시 간에 HTTPS가 사용 설정됩니다.apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-ingress-2 spec: tls: - hosts: - altostrat.com secretName: example-server-creds rules: - host: altostrat.com http: paths: - path: /greet-the-world pathType: Exact backend: service: name: hello-service port: number: 60000 - path: /greet-kubernetes pathType: Exact backend: service: name: hello-service port: number: 60001
매니페스트를
my-ingress-2.yaml
이라는 파일에 저장하고 인그레스를 만듭니다.kubectl apply --kubeconfig CLUSTER_KUBECONFIG -f my-ingress-2.yaml
다음과 같이 테스트하여 인그레스가 생성되었고 제대로 작동하는지 확인합니다.
/greet-the-world
경로를 테스트합니다.curl -v --resolve altostrat.com:443:CLUSTER_INGRESS_VIP \ https://altostrat.com/greet-the-world \ --cacert root-ca.crt
출력:
Hello, world! Version: 2.0.0 Hostname: hello-deployment-5ff7f68854-wqzp7
/greet-kubernetes
경로를 테스트합니다.curl -v --resolve altostrat.com:443:CLUSTER_INGRESS_VIP \ https://altostrat.com/greet-kubernetes --cacert root-ca.crt
출력:
Hello Kubernetes!
LoadBalancer 서비스 만들기
클러스터 외부에 워크로드를 노출하는 또 다른 방법으로 LoadBalancer
유형의 서비스가 있습니다. LoadBalancer
유형의 서비스를 만드는 방법에 대한 안내 및 예시는 애플리케이션 배포에서 LoadBalancer
유형의 서비스 만들기를 참고하세요.
삭제
인그레스를 삭제합니다.
kubectl --kubeconfig CLUSTER_KUBECONFIG delete ingress INGRESS_NAME
INGRESS_NAME
을my-ingress
또는my-ingress-2
와 같은 인그레스 이름으로 바꿉니다.서비스를 삭제합니다.
kubectl --kubeconfig CLUSTER_KUBECONFIG delete service hello-service
배포를 삭제합니다.
kubectl --kubeconfig CLUSTER_KUBECONFIG delete deployment hello-deployment
LoadBalancer 서비스를 삭제합니다.
kubectl --kubeconfig CLUSTER_KUBECONFIG delete service service-does-not-use-nodeports