7주차 - Service Mesh: Istio 기능들

1. Istio 요약

  • 목적성

    • msa 환경에서 내부 통신을 하게되면 N(N-1) 의 경우의 수가 생기는데 모니터링의 어려움이 생깁니다.

    • 내부자 권한 처리나 요구사항들이 계속 생기게 됩니다.

    • 이러한 요구사항을 충족시키기 위해 Envoy와 같은 프록시로 통신시키고 모니터링하고 컨트롤 하는 것을 Service Mesh 로 대표적인 구현체로 Istio가 있습니다.

  • 제공하는 기능들

    • 트래픽 모니터링

    • 트래픽 컨트롤

      • 트래픽 시프팅: 신규 앱에 전달하는 트래픽을 단계적으로 적용 - TRAFFIC SIFTING

      • 서킷 브레이커: 목적지 마이크로 서비스에 문제가 있을 경우, 접속 차단 (연쇄 에러 방지)

      • 폴트 인젝션: 의도적으로 실패 구현 - FAULT INJECTION

      • 속도 제한: 요청 제한 - RATE LIMITER

      • 트래픽 미러링: 동일한 트래픽을 다른 서비스에 복사가 가능합니다.

2. Istio 아키텍처 및 구성요소

  • Control Plane

    • Istiod

      • Pilot(파일럿) : 모든 Envoy 사이드카에서 프록시 라우팅 규칙을 동기하고 서비스 디스커버리와 로드 밸런싱 설정을 제공합니다.

      • Galley(갤리) : Istio와 쿠버네티스를 연결해주는 역할을 합니다. 서비스 메시 구성 데이터를 검증하고 변환합니다. (Controller 같은 역할)

      • Citadel(시타델) : 보안 기능을 담당하고 TLS 인증을 발급하고 서비스간 통신을 암호화합니다.

  • Data Plane

    • Istio Proxy: Envoy를 래핑하고, istiod와 통신해 서비스 트래픽을 통제하고 메트릭을 수집합니다.

  • Istio Proxy는 Side Car 패턴을 사용하게 되는데 원리는 다음과 같습니다.

  • 파드 내에 컨테이너로 주입되어서 동작하고 Proxy 컨테이너가 Application 트래픽을 가로채서 iptable rules에 맞게 라우팅합니다.

    • proxy 에서 istiod(pilot) 과 변경된 iptables 에 대해 동기화를 동적으로 해주게 됩니다.

    • 사담으로, pod의 모든 컨테이너는 동일한 루프백 네트워크 인터페이스를 공유합니다.

3. [실습] 설치

// istio를 설치합니다.
export ISTIOV=1.23.2
echo "export ISTIOV=1.23.2" >> /etc/profile
curl -s -L https://istio.io/downloadIstio | ISTIO_VERSION=$ISTIOV TARGET_ARCH=x86_64 sh -
tree istio-$ISTIOV -L 2 # sample yaml 포함
cp istio-$ISTIOV/bin/istioctl /usr/local/bin/istioctl
istioctl version --remote=false

// demo 프로파일 컨트롤 플레인 배포하고 egressGateway 없이 실습 환경 구성했습니다.
istioctl profile list
istioctl profile dump default
istioctl profile dump --config-path components.ingressGateways
istioctl profile dump --config-path values.gateways.istio-ingressgateway
istioctl profile dump demo

// 해당 프로파일로 istio 설치
istioctl install -f demo-profile.yaml -y


// istio-ingressgateway 의 envoy 버전 확인
kubectl exec -it deploy/istio-ingressgateway -n istio-system -c istio-proxy -- envoy --version

# istio-ingressgateway 서비스 NodePort로 변경
kubectl patch svc -n istio-system istio-ingressgateway -p '{"spec":{"type":"NodePort"}}'

# istio-ingressgateway 서비스 확인
kubectl get svc,ep -n istio-system istio-ingressgateway

## istio-ingressgateway 서비스 포트 정보 확인
kubectl get svc -n istio-system istio-ingressgateway -o jsonpath={.spec.ports[*]} | jq
설치 버전 확인

istio 설치
k8s에서 crd들 확인

4. [실습] Istio sidecar auto injection

// istio 사이다카를 모두 자동 생성하게 끔 훅을 생성합니다.

kubectl label namespace default istio-injection=enabled

설정 확인

5. [실습] Istio 외부 노출

aws ec2 describe-instances --query "Reservations[*].Instances[*].{PublicIPAdd:PublicIpAddress,InstanceName:Tags[?Key=='Name']|[0].Value,Status:State.Name}" --filters Name=instance-state-name,Values=running --output text


# istio ingress gw NodePort(HTTP 접속용) 변수 지정 : 아래 ports[0] 은 어떤 용도의 포트일까요?
export IGWHTTP=$(kubectl get service -n istio-system istio-ingressgateway -o jsonpath='{.spec.ports[1].nodePort}')
echo $IGWHTTP
IGWHTTP=<각자 자신의 NodePort>


MYDOMAIN=<각자 자신의 www 도메인> # 단, 사용하고 있지 않는 공인 도메인을 사용 할 것
MYDOMAIN=www.simonsichangpark.com
echo "<istio-ingressgateway 파드가 있는 워커 노드> $MYDOMAIN" >> /etc/hosts

export MYDOMAIN=www.gasida.dev
echo -e "192.168.10.10 $MYDOMAIN" >> /etc/hosts
echo -e "export MYDOMAIN=$MYDOMAIN" >> /etc/profile


# istio ingress gw 접속 테스트 : 아직은 설정이 없어서 접속 실패가 된다
curl -v -s $MYDOMAIN:$IGWHTTP



cat <<EOF | kubectl create -f -
apiVersion: v1
kind: ServiceAccount
metadata:
  name: kans-nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-websrv
spec:
  replicas: 1
  selector:
    matchLabels:
      app: deploy-websrv
  template:
    metadata:
      labels:
        app: deploy-websrv
    spec:
      serviceAccountName: kans-nginx
      terminationGracePeriodSeconds: 0
      containers:
      - name: deploy-websrv
        image: nginx:alpine
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: svc-clusterip
spec:
  ports:
    - name: svc-webport
      port: 80
      targetPort: 80
  selector:
    app: deploy-websrv
  type: ClusterIP
EOF

// 사이드카 배포 확인
kubectl get pod,svc,ep,sa -o wide
POD 2개 생성
POD 내에 CONTAINER 2개 PROXY도 뜬것 확인

6. [실습] Istio Gateway/Virtual Serivce 설정

cat <<EOF | kubectl create -f -
apiVersion: networking.istio.io/v1
kind: Gateway
metadata:
  name: test-gateway
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"
---
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
  name: nginx-service
spec:
  hosts:
  - "$MYDOMAIN"
  gateways:
  - test-gateway
  http:
  - route:
    - destination:
        host: svc-clusterip
        port:
          number: 80
EOF

7. [실습] Istio를 통한 Nginx 파드 접속 테스트

// istio ingress gw 를 통해서 접속 테스트를 해봅니다.
# istio ingress gw 를 통한 접속 테스트
curl -s $MYDOMAIN:$IGWHTTP | grep -o "<title>.*</title>"
curl -v -s $MYDOMAIN:$IGWHTTP
curl -v -s <유동공인이IP>:$IGWHTTP

# istio-proxy 사용자 정보 확인 : uid(1337):gid(1337) 확인 -> iptables rule 에서 사용됨
kubectl exec -it deploy/deploy-websrv -c istio-proxy -- tail -n 3 /etc/passwd

8. [실습] 유닉스 도메인 소켓 통신 확인

Last updated