GKE로 고정 IP의 내부 Ingress 만들기

2021/02/19 업데이트


내부 Ingress도 지원하기 시작했어요.

TL;DL;


Kubbernetes Ingress내부 Ingrees의 고정 IP는 지원되지 않습니다.에서 nginx-ingress 사용

배경.


GKE에서 내부 Ingress를 만들 때 LB의 IP 주소를 고정하려면
문서를 읽은 후 Kubbernetes Ingress가 대응하지 않았습니다.
나는 대책을 조사했다nginx-igress를 사용하면 해결할 수 있어요..
총결산을 하다

한정 공개된 GKE 만들기.


공용 노드에 무한 접근할 수 있는 유한 공개 그룹을 만듭니다.

GCP 콘솔에서 생성

  • GKE 메뉴에서 선택クラスタの作成
  • 명칭private-cluster-2,위치유형ゾーン,선택asia-northeast1-c
  • 왼쪽 네트워크 킹
  • 열기
  • 限定公開クラスタ 중 선택
  • マスター IP 範囲172.16.0.32/28
  • 입력
  • 네트워크 및 노드의 서브넷을 default
  • 로 설정
  • マスター承認済みネットワークを有効にする의 복선상자가 닫혀 있습니다. (열려 있으면 추가 설정을 하지 않으면kubectl을 통해cloud shell에서 접근할 수 없습니다)
  • 왼쪽 열기 안전
  • クライアント証明書を発行する 확인란은 닫힌 상태로 유지
  • 제작
  • 연결 확인


    클러스터가 생성되면 CLOUD SHELL을 열고 다음 작업을 수행합니다.
    $ gcloud container clusters get-credentials private-cluster-2 --zone asia-northeast1-c --project ${GOOGLE_CLOUD_PROJECT}
    
    다음 작업을 추가로 수행하여 결과를 얻을 수 있으면 OK
    $ kubectl get no
    NAME                                               STATUS   ROLES    AGE   VERSION
    gke-private-cluster-2-default-pool-24553f8b-0fpw   Ready    <none>   96s   v1.17.12-gke.1504
    gke-private-cluster-2-default-pool-24553f8b-38vk   Ready    <none>   95s   v1.17.12-gke.1504
    gke-private-cluster-2-default-pool-24553f8b-nd4r   Ready    <none>   96s   v1.17.12-gke.1504
    

    검색 엔진


    CLOUD SHELL을 사용하여 작업을 진행합니다.
    우선 취득nginx-igress의 선언.
    $ wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/cloud/deploy.yaml
    
    기본적으로 외부 LB가 생성되므로 고정 내부 LB와 IP로 변경하고 시작합니다.
    vi deploy.yml
    
    # Source: ingress-nginx/templates/controller-service.yaml
    apiVersion: v1
    kind: Service
    metadata:
    +  annotations: 
    +    cloud.google.com/load-balancer-type: "Internal"
      labels:
        helm.sh/chart: ingress-nginx-3.6.0
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/instance: ingress-nginx
        app.kubernetes.io/version: 0.40.2
        app.kubernetes.io/managed-by: Helm
        app.kubernetes.io/component: controller
      name: ingress-nginx-controller
      namespace: ingress-nginx
    spec:
      type: LoadBalancer
    +  loadBalancerIP: 10.146.0.101
      externalTrafficPolicy: Local
      ports:
        - name: http
          port: 80
          protocol: TCP
          targetPort: http
        - name: https
          port: 443
          protocol: TCP
          targetPort: https
      selector:
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/instance: ingress-nginx
        app.kubernetes.io/component: controller
    
    는 고정 IP에 대해 GKE의 집단에서 의사소통을 할 수 있는 IP가 되어야 한다.어쨌든 GKE와 같은 subnet 내 IP를 지정하기로 했다.asis-northeast1의default 서브넷으로 제작하면 10.146.0.0/20 사용할 수 있다.(이곳에서 지정해 보았다10.146.0.101.
    변경되면 적용합니다.
    $ kubectl apply -f deploy.yml
    
    다음 명령이 LB를 제대로 생성했는지 확인합니다.EXTERNAL-IP라고 쓰여 있는데 사실 여기는 내부 IP입니다.지정된 내부 IP 주소가 사용되었는지 확인할 수 있습니다.
    $ kubectl get svc ingress-nginx-controller -n ingress-nginx
    NAME                       TYPE           CLUSTER-IP    EXTERNAL-IP    PORT(S)                      AGE
    ingress-nginx-controller   LoadBalancer   10.0.26.117   10.146.0.101   80:31379/TCP,443:32372/TCP   51s
    
    마지막으로 소통 확인을 진행한다.
    CLOUD SHELL이 내부 LB에 접근할 수 없기 때문에 GKE의 node부터 소통을 확인한다.
    GCP 콘솔에서 GCE 화면을 열고 노드 인스턴스 중 하나SSH를 엽니다.

    SSH 화면이 켜지면 아래와 같이 내부 LB와 소통할 수 있는지 확인한다.nginx의 회답이 돌아오면 됩니다.
    $ curl 10.146.0.101
    <html>
    <head><title>404 Not Found</title></head>
    <body>
    <center><h1>404 Not Found</h1></center>
    <hr><center>nginx</center>
    </body>
    </html>
    

    백엔드 디버그


    nginx-ingress를 사용하여 백엔드를 디버깅합니다
    그런 다음 CLOUD SHELL에서 작업을 수행합니다.다음은 앱입니다.yml라는 파일 이름으로 제작되었습니다.
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: hello-app
    spec:
      selector:
        matchLabels:
          app: hello
      replicas: 3
      template:
        metadata:
          labels:
            app: hello
        spec:
          containers:
          - name: hello
            image: "gcr.io/google-samples/hello-app:2.0"
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: hello-service
      labels:
        app: hello
    spec:
      type: NodePort
      selector:
        app: hello
      ports:
      - name: hello-port
        port: 80
        targetPort: 8080
        protocol: TCP
    ---
    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: hello-ingress
      annotations:
        kubernetes.io/ingress.class: "nginx"
    spec:
      rules:
      - host:
        http:
          paths:
          - path: /
            backend:
              serviceName: hello-service
              servicePort: hello-port
    
    이대로 디버깅을 진행하면 다음과 같은 오류가 발생합니다
    $ kubectl apply -f app.yml
    deployment.apps/hello-app unchanged
    service/hello-service unchanged
    Error from server (InternalError): error when creating "app.yml": Internal error occurred: failed calling webhook "validate.nginx.ingress.kubernetes.io": Post https://ingress-nginx-controller-admi
    ssion.ingress-nginx.svc:443/networking/v1beta1/ingresses?timeout=10s: context deadline exceeded
    
    를 대책으로 제어 평면에서 노드로의 TCP 8443 포트 연결 필요
    GCP 문서 보면서 일해요.
    다음 명령에서 GKE의 노드에 사용되는 TARGETTAGS를 확인합니다.
    이름
    $ gcloud compute firewall-rules list \
               --filter 'name~^gke-private-cluster-2' \
                --format 'table(
                        name,
                        network,
                        direction,
                        sourceRanges.list():label=SRC_RANGES,
                        allowed[].map().firewall_rule().list():label=ALLOW,
                        targetTags.list():label=TARGET_TAGS
                )'
    NAME                                       NETWORK  DIRECTION  SRC_RANGES      ALLOW                         TARGET_TAGS
    gke-private-cluster-2-4ffa8a93-all         default  INGRESS    10.4.0.0/14     tcp,udp,icmp,esp,ah,sctp      gke-private-cluster-2-4ffa8a93-node
    gke-private-cluster-2-4ffa8a93-master      default  INGRESS    172.16.0.32/28  tcp:10250,tcp:443             gke-private-cluster-2-4ffa8a93-node
    gke-private-cluster-2-4ffa8a93-vms         default  INGRESS    10.128.0.0/9    icmp,tcp:1-65535,udp:1-65535  gke-private-cluster-2-4ffa8a93-node
    
    gke-private-cluster-2-4ffa8a93-node라는 TARGET태그스입니다.
    위의 절차에 따라 GKE 클러스터를 작성할 때 명령을 변경할 필요가 없습니다.CLUSTER_NAME를 privet-Cluster-2를 제외한 것으로 설정하면 명령--filter 'name~^gke-private-cluster-2'의 일부분을 --filter 'name~^gke-設定したクラスタ名'으로 변경하십시오.
    확인 후 방화벽 규칙 추가
    gcloud compute firewall-rules create gke-private-cluster-2-allow-8443 \
         --action ALLOW \
         --direction INGRESS \
         --source-ranges 172.16.0.32/28 \
         --rules tcp:8443 \
         --target-tags gke-private-cluster-2-4ffa8a93-node
    
    --target-tags에서 이전 명령에서 확인한 태그를 지정하십시오.
    위의 절차에 따라 GKE 클러스터를 만들 때 다른 옵션을 변경할 필요가 없습니다.기본 IP 범위를 172.16.0.32/28 이외로 설정하면 변경--source-ranges여기까지 완성하면 앱.yml 사전 처리
    $ kubectl apply -f app.yml 
    deployment.apps/hello-app created
    service/hello-service created
    ingress.extensions/hello-ingress created
    
    디버깅이 완료된 후 내부 LB가 소통할 수 있는 GKE 노드에 SSH를 진행한다.
    방금 같은 지령을 내렸는데 다음 결과로 돌아가면 OK입니다.
    $ curl 10.146.0.101
    Hello, world!
    Version: 2.0.0
    Hostname: hello-app-7f46745f74-8zxfs
    

    좋은 웹페이지 즐겨찾기