클라우드 네이티브 기술 오픈 클래스 연구 노트 : K8s 네트워크 개념 및 정책 제어, Kubernetes 서비스

10. Kubernetes 네트워크 개념 및 정책 제어

1. Kubernetes 기본 네트워크 모델

여기에 사진 설명 삽입

여기에 사진 설명 삽입

컨테이너 네트워크 개발의 복잡성은 실제로 호스트 네트워크에서 기생하기 때문입니다. 이러한 관점에서 컨테이너 네트워크 솔루션은 크게 Underlay / Overlay의 두 가지 주요 파벌 로 나눌 수 있습니다 .

  • Underlay의 표준은 호스트 네트워크와 동일한 계층에 있다는 것입니다. 외부에서 볼 수있는 기능은 호스트 네트워크의 동일한 네트워크 세그먼트, 입력 및 출력 기본 장비, 컨테이너의 IP 주소를 사용하는지 여부입니다. 호스트 네트워크와 협력합니까? (동일한 중앙 배포 또는 통합 부서에서). 이것은 언더 레이입니다
  • Overlay의 차이점은 Host 네트워크의 IPM 관리 구성 요소에서 IP를 신청할 필요가 없다는 점입니다. 일반적으로 Host 네트워크와 충돌하지 않고이 IP를 자유롭게 할당 할 수 있습니다.

2. Netns 탐색

여기에 사진 설명 삽입

네트워크 네임 스페이스에서 네트워크 구현을위한 커널 기반입니다. 좁은 의미에서 runC 컨테이너 기술은 하드웨어에 의존하지 않습니다. 실행 기반은 커널입니다. 프로세스를 대표하는 커널은 작업입니다. 격리가 필요하지 않은 경우 호스트 공간 (네임 스페이스)을 사용합니다. 공간 격리 데이터 특별히 설정해야하는 구조 (nsproxy-namespace 프록시)

반대로 독립 네트워크 프록시 또는 마운트 프록시 인 경우 실제 개인 데이터로 채워야합니다. 볼 수있는 데이터 구조는 위 그림과 같습니다.

감각적 관점에서 격리 된 네트워크 공간에는 자체 네트워크 카드 또는 네트워크 장비가 있습니다. 네트워크 카드는 가상 또는 물리적 일 수 있으며 자체 IP 주소, IP 테이블 및 라우팅 테이블, 자체 프로토콜 스택 상태를 갖습니다. 이것은 특히 자체 상태가있는 TCP / Ip 프로토콜 스택과 자체 iptables, ipvs를 나타냅니다.

전체적인 의미에서 이것은 호스트 네트워크와 격리 된 완전히 독립적 인 네트워크를 갖는 것과 같습니다. 물론 프로토콜 스택의 코드는 여전히 공개되지만 데이터 구조는 다릅니다.

여기에 사진 설명 삽입

위의 그림은 포드의 Netns 관계를 명확하게 보여줍니다. 각 포드에는 독립적 인 네트워크 공간이 있으며 포드 넷 컨테이너는이 네트워크 공간을 공유합니다. 일반적으로 K8s는 루프백 인터페이스를 사용하여 포드 넷 컨테이너간에 통신 할 것을 권장하며 모든 컨테이너는 포드의 IP를 통해 외부 서비스를 제공합니다. 또한 호스트의 Root Netns는 Pid가 1이라는 점을 제외하고는 특별한 네트워크 공간으로 간주 할 수 있습니다.

3. 주류 네트워크 솔루션 소개

여기에 사진 설명 삽입

여기에 사진 설명 삽입

Flannel 방식은 현재 가장 일반적으로 사용됩니다. 위의 그림과 같이 일반적인 컨테이너 네트워크 솔루션을 볼 수 있습니다. 가장 먼저 해결해야 할 것은 컨테이너 패키지가 호스트에 도달하는 방법입니다. 여기에 Bridge를 추가하는 방법이 있습니다. 백엔드는 실제로 독립적입니다. 즉, 캡슐화 방법이 사용되거나 캡슐화가 필요하지 않은 패키지가 호스트를 떠나는 방법은 모두 선택 사항입니다.

이제 세 가지 주요 백엔드를 소개하겠습니다.

  • 하나는 사용자 모드 udp로, 가장 초기 구현입니다.
  • 그런 다음 커널의 Vxlan이 있으며 둘 다 오버레이 솔루션으로 간주됩니다. Vxlan의 성능은 더 좋을 것이지만 커널 버전에 대한 요구 사항이 있으며 커널은 Vxlan의 특성을 지원해야합니다.
  • 클러스터가 충분히 크지 않고 동일한 2 계층 도메인에있는 경우 host-gw를 사용하도록 선택할 수도 있습니다. 이런 식으로 백엔드는 기본적으로 브로드 캐스트 라우팅 규칙에 의해 시작되며 성능이 상대적으로 높습니다.

4. 네트워크 정책의 유용성

여기에 사진 설명 삽입

Kubernetes 네트워크의 기본 모델에는 pod 간의 완전한 상호 연결이 필요하다고 방금 언급했습니다. 이로 인해 몇 가지 문제가 발생합니다. K8s 클러스터에서 일부 호출 체인은 직접 호출되지 않습니다. 예를 들어 두 부서 사이에서 A 부서가 B 부서의 서비스를 방문하지 않기를 바랍니다. 이때 전략 개념을 사용할 수 있습니다.

기본적으로 아이디어는 다음과 같습니다. 다양한 선택기 (태그 또는 네임 스페이스)를 사용하여 포드 그룹을 찾거나 통신의 두 끝을 찾은 다음 스트림의 기능 설명을 사용하여 연결할 수 있는지 여부를 결정합니다., 화이트리스트 메커니즘으로 이해 가능

네트워크 정책을 사용하기 전에 apiserver가 위 그림과 같이 이러한 스위치를 켜야합니다. 또 다른 중요한 점은 우리가 선택한 네트워크 플러그인이 네트워크 정책 구현을 지원해야한다는 것입니다. 네트워크 정책은 K8s에서 제공하는 객체 일 뿐이며 구현을위한 기본 제공 구성 요소가 없습니다. 선택한 컨테이너 네트워크 솔루션이이 표준을 지원하는지 여부와 완성도에 따라 다릅니다. Flannel 등을 선택하면 실제로는 그렇지 않습니다. 이 정책이 구현 된 경우이 정책을 시도해도 소용이 없습니다.

여기에 사진 설명 삽입

다음으로 구성의 예 또는 네트워크 정책을 설계 할 때해야 할 일에 대해 이야기하겠습니다.

  • 첫 번째는이 인스턴스의 사양 부분과 마찬가지로 개체를 제어하는 ​​것입니다. 사양에서 podSelector 또는 네임 스페이스 선택기를 통해 특정 pod 집합을 만들도록 선택할 수 있습니다.
  • 두 번째는 흐름 방향에 대해 명확하게 생각하는 것입니다. 들어 오거나 나가는 방향을 제어해야합니까? 여전히 양방향 제어 필요
  • 가장 중요한 부분은 세 번째 부분인데, 선택한 방향에 제어 개체를 추가하여 흐름을 설명하려면 어떤 흐름을 넣거나 나올 수 있습니까? 이 스트림 기능의 5- 튜플과 유사하게 몇 가지 선택기를 사용하여 내 원격이 될 수있는 항목을 결정할 수 있습니다. 이것은 객체의 선택이며 IPBlock의 메커니즘을 사용하여 어떤 IP를 해제 할 수 있는지 확인할 수도 있습니다. 마지막은 어떤 프로토콜 또는 포트입니다. 사실, 흐름 특성의 조합은 특정 허용 흐름을 선택하는 5- 튜플입니다.

11. Kubernetes 서비스

1. 수요 원

1) 서비스 검색이 필요한 이유

여기에 사진 설명 삽입

K8s 클러스터에서 애플리케이션은 포드를 통해 배포됩니다. 기존 애플리케이션 배포와 달리 기존 애플리케이션은 지정된 머신에 배포됩니다. 다른 머신의 IP 주소를 호출하는 방법을 알고 있습니다. 그러나 K8s 클러스터의 애플리케이션은 포드를 통해 배포되며 포드 수명주기는 짧습니다. 포드의 생성 또는 폐기와 같은 포드의 수명주기 동안 해당 IP 주소가 변경되므로 기존 배포 방법을 사용할 수 없으며 지정된 애플리케이션에 액세스하기 위해 IP를 지정할 수 없습니다.

또한 K8의 애플리케이션 배포에서 배포의 배포 모드를 전에 배웠지 만 여전히 포드 그룹을 생성해야하며 이러한 포드 그룹은 통합 액세스 항목을 제공하고 트래픽 부하 분산을 제어하는 ​​방법을 제공해야합니다. 이 그룹에. 예를 들어 테스트 환경, 시험판 환경 및 온라인 환경은 배포 프로세스 중에 동일한 배포 템플릿과 액세스 방법을 유지해야합니다. 이러한 방식으로 동일한 애플리케이션 템플릿 세트를 사용하여 다른 환경에 직접 게시 할 수 있기 때문입니다.

마지막으로 애플리케이션 서비스는 접근을 위해 외부에 노출되어야하고 호출을 위해 외부 사용자에게 제공되어야합니다. 포드의 네트워크와 머신이 네트워크의 동일한 세그먼트에 있지 않은데 포드 네트워크가 외부 액세스에 어떻게 노출 될 수 있습니까? 서비스 발견

2) 서비스 : Kubernetes의 서비스 검색 및 부하 분산

여기에 사진 설명 삽입

K8s에서 서비스 검색 및로드 밸런싱은 K8s 서비스입니다. 위 그림은 K8s의 서비스 구조입니다 .K8s 서비스는 외부 네트워크 및 pod 네트워크에 대한 액세스를 제공합니다. 즉, 서비스를 통해 외부 네트워크에 액세스 할 수 있으며, K8s 서비스를 통해 pod 네트워크에도 액세스 할 수 있습니다.

아래쪽으로 K8s는 다른 포드 집합에 연결됩니다. 즉, 서비스 검색을위한 통합 액세스 포털을 제공 할뿐만 아니라 외부 네트워크에 대한 액세스도 제공하는 K8s 서비스를 통해 포드 집합에로드 밸런싱 될 수 있습니다. 서로 다른 포드간에 통합 액세스 주소 제공

2. 사용 사례 해석

1), 서비스 구문

여기에 사진 설명 삽입

먼저 K8s 서비스의 문법을 살펴보면 위의 그림은 실제로 K8s의 문장 구조입니다. 이 구조에는 많은 구문이 있으며 이전에 소개 된 K8의 일부 표준 객체와 많은 유사점이 있습니다. 예를 들어 선택자를 선택하여 일부를 선택하고 레이블을 지정하여 일부 레이블 레이블을 선언합니다.

여기에 K8s 서비스 서비스 검색을위한 프로토콜 및 포트를 정의하는 새로운 지식 포인트가 있습니다. 이 템플릿을 계속 살펴보고 my-service라는 K8s 서비스를 선언합니다. app:my-service레이블 이 있으며 app:MyApp이러한 레이블 포드를 백엔드로 선택합니다.

마지막은 정의 된 서비스 검색 프로토콜 및 포트입니다.이 예에서는 TCP 프로토콜이 정의되어 있습니다. 포트는 80이고 대상 포트는 9376입니다. 그 결과 서비스 포트 80에 대한 액세스가 백엔드로 라우팅됩니다. 즉,이 서비스 포트 80에 액세스 app:MyApp하는 한 백엔드 레이블 포드의 포트 9376에 로드 밸런싱됩니다.

2), 서비스 생성 및보기

여기에 사진 설명 삽입

서비스 생성 : kubectl apply -f service.yaml또는kubectl created -f service.yaml

서비스 생성 후 결과보기 :kubectl discribe service

서비스가 생성되면 이름이 my-service임을 알 수 있습니다. 네임 스페이스, 라벨 및 선택기는 이전 선언과 동일합니다. 선언 후에 IP 주소가 생성됩니다.이 IP 주소는 서비스의 IP 주소입니다.이 IP 주소는 클러스터의 다른 포드에서 액세스 할 수 있습니다. IP 주소는 포드 및 서비스 검색에 대한 통합 액세스를 제공합니다.

Endpoints의 속성도 있습니다. Endpoints를 통해 볼 수 있습니다. 이전에 선언 된 선택기를 통해 어떤 포드가 선택 되었습니까? 그리고이 포드의 상태는 어떻습니까? 예를 들어 선택기를 통해 이러한 포드의 IP와 이러한 포드가 선언 한 targetPort의 포트를 선택했음을 알 수 있습니다.

여기에 사진 설명 삽입

실제 아키텍처는 위 그림에 나와 있습니다. 서비스가 생성되면 클러스터에 가상 IP 주소와 포트가 생성되며 클러스터 내 모든 포드와 노드는 이러한 IP 주소와 포트를 통해 서비스에 액세스 할 수 있습니다. 이 서비스는 선택한 포드와 해당 IP 주소를 백엔드에 마운트합니다. 이러한 방식으로 서비스의 IP 주소를 통해 액세스 할 때 이러한 백엔드 포드에 부하를 분산 할 수 있습니다.

포드 중 하나가 파괴되는 등 포드의 수명주기가 변경되면 서비스가 자동으로 백엔드에서 포드를 제거합니다. 이는 달성됩니다. 포드의 수명주기가 변경 되더라도 액세스하는 엔드 포인트는 변경되지 않습니다.

3) 클러스터 내 서비스 접근

여기에 사진 설명 삽입

클러스터에서 다른 포드는 우리가 만든 서비스에 어떻게 액세스합니까? 세 가지 방법이 있습니다.

  • 첫째, 당신은 예를 들어, 내 서비스이 서비스는 당신이 단지를 통해, 생성, 가상 IP 서비스 액세스를 통해 갈 수 kubectl get svc또는 kubectl discribe service가상 IP 주소가 172.29.3.27입니다 볼 수있는 포트는이 가상 IP를 사용할 수 있으며, 80 포트 포드에서 직접이 서비스의 주소에 액세스합니다.

  • 두 번째 방법은 DNS 확인에 따라 서비스 이름에 직접 액세스하는 것입니다. 즉, 동일한 네임 스페이스의 포드가 서비스 이름을 통해 방금 선언 된 서비스에 직접 액세스 할 수 있습니다. 다른 네임 스페이스에서 서비스 이름 .을 추가 한 다음 서비스가있는 네임 스페이스를 추가하여 서비스에 액세스 할 수 있습니다. 예를 들어 curl을 사용하여 서비스에 직접 액세스합니다. 즉, my-service : 80이 서비스.

  • 세 번째는 환경 변수를 통해 액세스하는 것입니다. 동일한 네임 스페이스의 포드가 시작되면 K8은 환경 변수를 통해 일부 IP 주소, 포트 및 서비스의 간단한 구성을 K8의 포드에 넣습니다. K8s pod 컨테이너가 시작된 후 시스템의 환경 변수를 읽어서 네임 스페이스의 다른 서비스에서 구성한 주소 또는 포트 번호 등을 읽을 수 있습니다. 예를 들어 클러스터의 포드에서 curl $를 통해 환경 변수의 값을 직접 가져올 수 있습니다. 예를 들어 MY_SERVICE_SERVICE_HOST를 가져 오는 것은 해당 IP 주소이고 MY_SERVICE는 방금 선언 한 MY_SERVICE이며 SERVICE_PORT는 해당 포트 번호입니다. 클러스터에서 MY_SERVICE 서비스를 요청할 수 있습니다.

4) 、 Headless 서비스

여기에 사진 설명 삽입

특별한 형태의 서비스는 헤드리스 서비스입니다. 서비스가 생성되면 clusterIP : None을 지정하여 K8s에게 clusterIP가 필요하지 않다고 알리면 K8s가 서비스에 가상 IP 주소를 할당하지 않습니다. 가상 IP없이로드 밸런싱 및 통합 액세스를 달성하는 방법 주소?

포드는 DNS를 사용하여 service_name을 통해 모든 백엔드 포드의 IP 주소를 직접 확인하고 DNS의 A 레코드를 통해 모든 백엔드 포드의 주소로 확인할 수 있습니다. 클라이언트는 백엔드 IP 주소를 선택하고이 A 레코드는 포드의 수명주기가 변경되면 반환 된 A 레코드 목록도 변경됩니다.이를 위해서는 클라이언트 애플리케이션이 A 레코드의 모든 DNS를 A 레코드 목록의 IP 주소로 반환하고 클라이언트가 적절한 주소를 선택해야합니다. 포드 방문

5), 클러스터 외부에 서비스 노출

여기에 사진 설명 삽입

앞서 소개 한 내용은 클러스터의 노드 나 pod가 서비스에 접근한다는 것인데 어떻게 서비스를 외부에 노출시킬 수 있습니까? 액세스를 위해 실제로 애플리케이션을 공용 네트워크에 노출하는 방법은 무엇입니까? 또한이 문제를 해결하기위한 두 가지 유형의 서비스가 있습니다. 하나는 NodePort이고 다른 하나는 LoadBalancer입니다.

  • NodePort의 방법은 클러스터 노드 (즉, 클러스터 노드의 호스트)에있는 노드의 포트를 노출하는 것인데, 이는 노드의 포트에서 액세스 된 후 전달 계층과 동일합니다. , 그리고 가상 IP 주소 위에 전달은 방금 호스트에있는 서비스의 가상 IP 주소입니다.

  • LoadBalancer 유형은 NodePort의 또 다른 변환 계층입니다. 방금 언급 한 NodePort는 실제로 클러스터의 각 노드에있는 포트입니다. LoadBalancer는 모든 노드 앞에로드 밸런서를 추가하는 것입니다. 예를 들어 Alibaba Cloud에 SLB를 걸면로드 밸런서가 통합 입구를 제공하고 각 클러스터 노드의 노드 포드에 닿는 모든 트래픽을로드 밸런싱합니다. 그런 다음 노드 포드가 ClusterIP로 변환되어 실제 포드에 액세스합니다.

3. 작동 시연

1) 클러스터 내 서비스 접근

service.yaml

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    run: nginx
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    run: nginx    

server.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  labels:
    run: nginx
spec:
  replicas: 2
  selector:
   matchLabels:
    run: nginx
  template:
    metadata:
      labels:
        run: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
hanxiantaodeMBP:yamls hanxiantao$ kubectl create -f server.yaml 
deployment.apps/nginx created
hanxiantaodeMBP:yamls hanxiantao$ kubectl get pod
NAME                     READY   STATUS    RESTARTS   AGE
nginx-79699b7df9-jn5p4   1/1     Running   0          46s
nginx-79699b7df9-th5hj   1/1     Running   0          46s
hanxiantaodeMBP:yamls hanxiantao$ kubectl get pod -o wide -l run=nginx
NAME                     READY   STATUS    RESTARTS   AGE   IP           NODE             NOMINATED NODE   READINESS GATES
nginx-79699b7df9-jn5p4   1/1     Running   0          77s   10.1.0.139   docker-desktop   <none>           <none>
nginx-79699b7df9-th5hj   1/1     Running   0          77s   10.1.0.140   docker-desktop   <none>           <none>

포드 세트를 생성하려면 먼저이 K8 배포를 생성해야합니다. 배포가 생성 된 후 포드가 생성되었는지 살펴 보겠습니다. kubectl get pod -o wide를 통해 IP 주소를 볼 수 있습니다. -l, 즉 레이블 run = nginx를 통해 필터링합니다. 이 두 포드는 각각 IP 주소 10.1.0.139 및 10.1.0.140이며 둘 다 레이블이 run = nginx입니다.

hanxiantaodeMBP:yamls hanxiantao$ kubectl create -f service.yaml 
service/nginx created
hanxiantaodeMBP:yamls hanxiantao$ kubectl describe svc
Name:              kubernetes
Namespace:         default
Labels:            component=apiserver
                   provider=kubernetes
Annotations:       <none>
Selector:          <none>
Type:              ClusterIP
IP:                10.96.0.1
Port:              https  443/TCP
TargetPort:        6443/TCP
Endpoints:         192.168.65.3:6443
Session Affinity:  None
Events:            <none>


Name:              nginx
Namespace:         default
Labels:            run=nginx
Annotations:       <none>
Selector:          run=nginx
Type:              ClusterIP
IP:                10.108.96.80
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.1.0.139:80,10.1.0.140:80
Session Affinity:  None
Events:            <none>

K8s 서비스를 다시 만들어 보겠습니다. kubectl describe svc를 통해이 서비스의 실제 상태를 볼 수 있습니다. 생성 된 nginx 서비스의 경우 해당 선택기는 run = nginx이고, 백엔드에 대한 포드 주소는 방금 본 두 포드의 주소 인 run = nginx의 선택기를 통해 선택됩니다. 10.1.0.139 및 10.1.0.140. 여기에서 K8s가 클러스터에 가상 IP 주소를 생성 한 것을 볼 수 있습니다.이 가상 IP 주소를 통해 다음 두 포드로로드 밸런싱 할 수 있습니다.

pod1.yaml

apiVersion: v1
kind: Pod
metadata:
  name: nginx1
  namespace: default
  labels:
    env: dev
    tie: front  
spec:
  containers:
  - name : nginx
    image: nginx:1.8
    ports:
    - containerPort: 80      

서비스에 액세스하는 방법을 테스트하기 위해 클라이언트 팟 (Pod)을 작성하십시오.

hanxiantaodeMBP:yamls hanxiantao$ kubectl create -f pod1.yaml 
pod/nginx1 created
hanxiantaodeMBP:yamls hanxiantao$ kubectl get pod
NAME                     READY   STATUS    RESTARTS   AGE
nginx-79699b7df9-jn5p4   1/1     Running   0          10m
nginx-79699b7df9-th5hj   1/1     Running   0          10m
nginx1                   1/1     Running   0          39s

kubectl exec -it nginx1 sh를 사용하여이 포드에 들어가 curl을 설치합니다.

先 添加 163 源
tee /etc/apt/sources.list << EOF
deb http://mirrors.163.com/debian/ jessie main non-ffree contrib
deb http://mirrirs.163.com/dobian/ jessie- 주요 비 자유 기여
EOF 업데이트

hanxiantaodeMBP:yamls hanxiantao$ kubectl exec -it nginx1 sh
# apt-get update && apt-get install -y curl

ClusterIP를 통한 액세스

# curl http://10.108.96.80:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

{service name}. {namespace}를 통해 액세스

# curl http://nginx     
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

서비스 이름으로 액세스

# curl http://nginx.default
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

환경 변수를 통한 액세스

# env
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT=443
HOSTNAME=nginx1
HOME=/root
NGINX_PORT_80_TCP=tcp://10.108.96.80:80
TERM=xterm
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
NGINX_VERSION=1.8.1-1~jessie
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
NGINX_SERVICE_HOST=10.108.96.80
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
NGINX_SERVICE_PORT=80
NGINX_PORT=tcp://10.108.96.80:80
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_SERVICE_HOST=10.96.0.1
PWD=/
NGINX_PORT_80_TCP_ADDR=10.108.96.80
NGINX_PORT_80_TCP_PORT=80
NGINX_PORT_80_TCP_PROTO=tcp
# curl $NGINX_SERVICE_HOST
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

2) 클러스터 외부에 서비스 노출

service.yaml 추가type: LoadBalancer

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    run: nginx
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    run: nginx
  type: LoadBalancer  
hanxiantaodeMBP:yamls hanxiantao$ kubectl apply -f service.yaml 
Warning: kubectl apply should be used on resource created by either kubectl create --save-config or kubectl apply
service/nginx configured
hanxiantaodeMBP:yamls hanxiantao$ kubectl get svc -o wide
NAME         TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE   SELECTOR
kubernetes   ClusterIP      10.96.0.1      <none>        443/TCP        29d   <none>
nginx        LoadBalancer   10.108.96.80   localhost     80:31943/TCP   29m   run=nginx

여기에 추가 EXTERNAL-IP가 있으며 http : // localhost /를 통해 서비스에 액세스 할 수 있습니다.

3) 서비스 액세스 주소는 포드 수명주기와 관련이 없습니다.

hanxiantaodeMBP:yamls hanxiantao$ kubectl describe svc nginx
Name:                     nginx
Namespace:                default
Labels:                   run=nginx
Annotations:              <none>
Selector:                 run=nginx
Type:                     LoadBalancer
IP:                       10.108.96.80
LoadBalancer Ingress:     localhost
Port:                     <unset>  80/TCP
TargetPort:               80/TCP
NodePort:                 <unset>  31943/TCP
Endpoints:                10.1.0.139:80,10.1.0.140:80
Session Affinity:         None
External Traffic Policy:  Cluster
Events:
  Type    Reason  Age    From                Message
  ----    ------  ----   ----                -------
  Normal  Type    4m49s  service-controller  ClusterIP -> LoadBalancer

이제 서비스 매핑의 백엔드 IP 주소는 10.1.0.139 및 10.1.0.140입니다.

hanxiantaodeMBP:yamls hanxiantao$ kubectl get pod
NAME                     READY   STATUS    RESTARTS   AGE
nginx-79699b7df9-jn5p4   1/1     Running   0          35m
nginx-79699b7df9-th5hj   1/1     Running   0          35m
nginx1                   1/1     Running   0          25m
hanxiantaodeMBP:yamls hanxiantao$ kubectl delete pod nginx-79699b7df9-jn5p4
pod "nginx-79699b7df9-jn5p4" deleted
hanxiantaodeMBP:yamls hanxiantao$ kubectl get pod -o wide
NAME                     READY   STATUS    RESTARTS   AGE   IP           NODE             NOMINATED NODE   READINESS GATES
nginx-79699b7df9-bb95z   1/1     Running   0          37s   10.1.0.142   docker-desktop   <none>           <none>
nginx-79699b7df9-th5hj   1/1     Running   0          36m   10.1.0.140   docker-desktop   <none>           <none>
nginx1                   1/1     Running   0          26m   10.1.0.141   docker-desktop   <none>           <none>
hanxiantaodeMBP:yamls hanxiantao$ kubectl describe svc nginx
Name:                     nginx
Namespace:                default
Labels:                   run=nginx
Annotations:              <none>
Selector:                 run=nginx
Type:                     LoadBalancer
IP:                       10.108.96.80
LoadBalancer Ingress:     localhost
Port:                     <unset>  80/TCP
TargetPort:               80/TCP
NodePort:                 <unset>  31943/TCP
Endpoints:                10.1.0.140:80,10.1.0.142:80
Session Affinity:         None
External Traffic Policy:  Cluster
Events:
  Type    Reason  Age   From                Message
  ----    ------  ----  ----                -------
  Normal  Type    6m2s  service-controller  ClusterIP -> LoadBalancer

포드 중 하나를 삭제합니다. 이제 포드의 IP 주소가 10.1.0.140 및 10.1.0.142가되고 서비스 매핑의 백엔드 IP 주소도 10.1.0.140 및 10.1.0.142가됩니다.

4. 아키텍처 디자인

여기에 사진 설명 삽입

위의 그림에서 볼 수 있듯이 K8s 서비스 검색 및 K8s 서비스는 이러한 전체 아키텍처입니다.

K8s는 마스터 노드와 작업자 노드로 나뉩니다.

  • 마스터의 주요 내용은 K8s 제어입니다.
  • 작업자 노드는 사용자 애플리케이션이 실제로 실행되는 곳입니다.

K8s 마스터 노드에는 모든 K8 객체를 균일하게 관리하는 APIServer가 있습니다. 모든 구성 요소는이 객체의 변경 사항을 모니터링하기 위해 APIServer에 등록됩니다. 예를 들어 구성 요소 포드의 수명주기가 변경됩니다. 이벤트

세 가지 주요 구성 요소가 있습니다.

  • 하나는 외부 액세스를 위해 LoadBalancer의 부하 분산기를 구성하는 Cloud Controller Manager입니다.
  • 다른 하나는 Coredns를 사용하여 APIServer에서 서비스 백엔드 포드의 변경 사항을 관찰하고 서비스의 DNS 확인을 구성하여 서비스 이름 또는 헤드리스를 통해 서비스의 가상 IP에 직접 액세스 할 수 있습니다. 서비스 유형, IP 목록 분석
  • 그런 다음 각 노드에 kube-proxy 구성 요소가 있으며 서비스 및 포드 변경 사항을 모니터링 한 다음 실제로 클러스터의 노드 포드 또는 가상 IP 주소에 대한 액세스를 구성합니다.

실제 액세스 링크는 무엇입니까? 예를 들어 클러스터 내부의 클라이언트 Pod3에서 서비스에 액세스하는 것은 방금 설명한 효과와 유사합니다. 클라이언트 Pod3은 먼저 Coredns를 통해 ServiceIP를 확인합니다. Coredns는 ServiceName에 해당하는 서비스 IP를 반환합니다.이 클라이언트 Pod3는이 서비스 IP를 사용하여 요청을합니다. 요청이 호스트의 네트워크에 도달 한 후 iptables 또는 IPVS kube-proxy에 의해 구성된 차단 처리 계층을 수행 한 다음 각 실제 백엔드 포드에로드 균형을 조정하여로드 균형 조정 및 서비스 검색을 달성합니다.

예를 들어, 외부 트래픽의 경우, 지금 막 공용 네트워크를 통해 액세스 된 요청입니다. 외부 부하 분산기 Cloud Controller Manager를 사용하여 서비스 변경 사항을 모니터링하고 부하 분산기를 구성한 다음 노드의 NodePort로 전달합니다. NodePort도 kube-proxy에 의해 구성됩니다. Iptables는 NodePort 트래픽을 ClusterIP로 변환 한 다음 부하 분산 및 서비스 검색을 위해 백엔드에있는 포드의 IP 주소에 추가합니다. 이것은 전체 K8s 서비스 검색 및 K8s 서비스의 전체 구조입니다.

코스 주소 : https://edu.aliyun.com/roadmap/cloudnative?spm=5176.11399608.aliyun-edu-index-014.4.dc2c4679O3eIId#suit

추천

출처blog.csdn.net/qq_40378034/article/details/112212177