istio 는 control plane 을 canary upgrade 가 가능하도록 revision tag 로 구분할 수 있게 권장하고 있다. 그리고 istio-operator 네임스페이스에 operator 를 설치하고, istio-system 네임스페이스에 istio control plane 을 설치한다.
operator 를 생성할 때 istio-operator 네임스페이스는 자동으로 생성되나 istio-system 네임스페이스는 operator 를 설치하기 전에 수동으로 생성해 놓아야 한다.
meshConfig 는 istiod 와 envoy proxy 가 서로 연결되는 정보를 나타내며 discoveryAddress 는 control plane 인 istiod 의 service url 을 tracing 은 Jaeger 정보를 저장할 데이터소스 url 이다. 여기서는 jaeger tracing backend 로 elastic search 를 사용하고 있다.meshConfig 의 값은 istiod 가 설치되는 istio-system 네임스페이스에 istiod-1-9-1 이라는 이름의 ConfigMap 으로 저장된다.
components 는 pilot(istiod), ingressGateway, egressGateway 에 대한 설치 정보이다. hpa 로 auto scaling 을 활용하기 위해서는 kubernetes cluster 에 metric-server 가 설치되어 있어야 한다.
아래와 같이 custom resource 를 생성한다.
사전에 node-selector 로 어느 서버에 istiod 와 gateway 를 설치할 수 있는지 지정할 수 있다.
$ kubectl label node k1-node03 taco-istio=enabled
$ kubectl label node k1-node04 taco-istio=enabled
$ kubectl label node k1-node05 taco-istio=enabled
$ kubectl apply -f istio-cr-1-9-1.yaml
설치 현황은 아래 명령으로 확인할 수 있다.
$ kubectl get iop -n istio-system
-----------------------------------------------
NAME REVISION STATUS AGE
istio-controlplane 1-9-1 HEALTHY 44h
3. 서비스별 gateway 추가 설치
gateway 는 서비스별로 추가할 수 있다. 이 또한 custom resource 만 생성하면 되며 custom resource 는 아래와 같다.
$ vi istio-gateway-cr.yaml
---
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
namespace: istio-system
name: istio-gateway-sample
spec:
revision:"1-9-1"
profile: empty
values:
global:
logging:
level:"default:info"
istioNamespace: istio-system
components:
ingressGateways:
- name: istio-ingressgateway-istio-gateway-sample
namespace: istio-gateway-sample
label:
app: istio-ingressgateway-istio-gateway-sample
istio: ingressgateway-istio-gateway-sample
enabled:true
k8s:
resources:
requests:
cpu: 1000m
memory: 1024Mi
hpaSpec:
maxReplicas:10
minReplicas:2
nodeSelector:
taco-istio: enabled
service:
type: NodePort
ports:
- name: status-port
port:15021
targetPort:15021
- name: http2
port:80
targetPort:8080
nodePort:31081
- name: https
port:443
targetPort:8443
nodePort:31443
- name: tcp
port:31400
targetPort:31400
- name: tls
port:15443
targetPort:15443
profile 값은 empty 로 지정한다. empty 는 istiod 를 설치하지 않겠다는 뜻이다.
Gateway 에 label 은 중요하다. default label 값은 app=istio-ingressgateway 와 istio=ingressgateway 이다. Gateway 를 여러개 설치하면 서비스별로 VirtualService 와 연결해야 하는데 이 때 활용되는 것이 label 이다. 그러니 Gateway 별로 구별할 수 있게 label 을 서로 다르게 주는 것이 중요하다.
새로운 네임스페이스에 생성된 Gateway 에 istiod 와 연결할 url 정보를 주는 것이 중요하다. 그런데 그 정보를 갖고 있는 meshConfig 에 넣어도 새로운 네임스페이스에 istio-1-9-1 ConfigMap 이 생성되지 않는다. 그래서 istio-1-9-1 ConfigMap 은 수동으로 설치해 주어야 한다.
Gateway 를 설치할 네임스페이스 생성과 그 네임스페이스에 istio-system 에 있는 istio-1-9-1 ConfigMap 을 복사하여 생성한다.
$ kubectl create ns istio-gateway-sample
$ kubectl get cm istio-1-9-1-n istio-system -o yaml \
istio-egressgateway-66cb5c46c7-c9q4b.istio-system SYNCED SYNCED SYNCED NOT SENT istiod-1-9-1-58ff56d6f8-dftbh 1.10-alpha.f88f93ff2b8172b37c83d6066363d76b4477bd2d
istio-egressgateway-66cb5c46c7-qjrwj.istio-system SYNCED SYNCED SYNCED NOT SENT istiod-1-9-1-58ff56d6f8-25z28 1.10-alpha.f88f93ff2b8172b37c83d6066363d76b4477bd2d
Istio 를 Operator 를 사용해서 revision 값을 주면 sidecar 를 자동으로 injection 하기 위해서 더이상 istio-injection=enabled 와 같은 Label을 쓰지 않는다. 위에 처럼 label 을 변경줘야 한다. istio-injection=enabled 으로 설명하는 문서들이 있으면 demo 와 같은 simple 한 설치이거나 이전 설치 방법이다.
간단히 설명하면 A, B, C 라는 서비스가 각각 D 라는 하나의 서비스를 호출한다고 가정하자. 이 때 D 서비스의 처리량 이상을 A 서비스가 호출한다면, B, C 서비스도 더이상 D 서비스를 호출하여 응답을 받을 수 없다. 그래서 A 서비스가 D를 호출하는 것을 buffer 에 저장하여 잠시 늦추는 효과를 준다면 D 서비스는 이상없이 동작하게 되고 B, C 서비스도 정상적인 응답을 받을 수 있다.
여기서 A서비스에 적용한 것이 Backpressure 이다.
Backpressure 를 적용하기 위한 전략은 다음과 같다.
Controlthe producer (slow down/speed up is decided by consumer)
Buffer(accumulate incoming data spikes temporarily)
AWS 기반으로 CodeCommit 과 연동하여 개발을 하다보면 Windows 기반의 Eclipse 연동을 주로 사용합니다.
AWS 에서 IntelliJ 가 아닌 Eclipse plugin 을 사용하라고 가이드 하는 것은 아마도 Eclipse 가 오픈소스 IDE 툴 이기 때문에 aws plugin 을 만들어서 배포하기데 적절하기 때문이 아닌가 하고 생각이 드네요.
저는 Mac 기반의 Eclipse 를 사용하는데 AWS CodeCommit 과 연동시키는데 몇시간을 고생해서 해결한 내용을 설명하고자 합니다.
Eclipse 를 설치하기 전에 먼저 JDK 가 설치되어야 하는데, 이전 글에서 Mac 에 JDK 를 설치하는 것은 설명을 드렸습니다.
다음으로 Eclipse 설치는 그냥 Applications 아이콘에 복사만 하면 되므로 Eclipse 설치는 생략...
Eclipse 에서 AWS toolkt 설치는 "메뉴 >> Help >> Install New Software..." 창을 띄우고 "Work with" 레이블이 있는 Text 상자에 "https://aws.amazon.com/eclipse/site.xml" 를 입력해서 software 를 설치하면 됩니다.
AWS CodeCommit 을 사용하기 위해서는 "IAM >> Users" 의 Security Credentials 탭에서 "HTTPS Git credentials for AWS CodeCommit" 항목에 사용자를 등록하면 사용할 수 있습니다.
그리고 AWS CodeStar 에서 Project 를 하나 만들면, CodeCommit Repository 가 생성이 되고, 이 Project 의 Team 메뉴에 위의 IAM User 를 할당해 주면 해당 User 가 CodeCommit 을 사용할 수 있습니다.
이제 Eclipse 의 주황색 아이콘을 클릭해서 CodeCommit 의 repository 로 부터 소스를 받아오겠습니다.
AWS Access Key ID, Secret Access Key 를 넣고 region 을 선택합니다. 그리고 CodeCommit 의 git id 와 패스워드를 입력하면 소스를 다운받을 수 있습니다.
하지만 다운을 받다가 에러가 발생하면서 실패하게 됩니다.
이 부분에서 고생을 많이 했었는데..
1. 처음에는 Oracle Java 에서 나는 문제로 오해해서 Mac 에 OpenJDK 를 설치했습니다. 그리고 Eclipse 를 띄울 때 OpenJDK 를 사용할 수 있게 수정했습니다.
그래도 똑같은 에러가 발생했습니다.
2. 그래서 JGit 의 버그로 생각하고 5.9 버전에서 낮은 버전으로 다시 설치했습니다.
그래도 에러가 발생.
3. IAM User 에서 https git credential 을 지우고 다시 생성하면 된다고 구글리에 나와 있어서 다시 했지만 또 에러.
마지막으로 아래 부분을 적용했더니 해결.
4. Eclipse "Preferences > General > Security > Secure Storage" 에서 OS X keystore 연동 체크박스를 해제
결국은 Mac 에서 keychain 연동할 때 eclipse 의 security storage 와의 이슈 때문이었습니다.
저는 OpenStack 을 오랫동안 해왔기 때문에 OpenStack 의 Neutron 로 비교하면 이해가 더 쉽게 되더라고요.
먼저 네트워크 대역을 만들기 위해서는 VPC 가 필요합니다. virtual 하게 만드는 것이기 때문에 10.0.0.0/16 과 같이 사설망 대역을 사용합니다.
그리고 외부와의 통신을 위해서는 Internet gateway (IGW)를 생성합니다. 이것은 software gateway 라고 생각이 들고 여기까지는 VPC 와 상관이 없습니다. 그래서 이해하기 쉽게 IGW 를 VPC 바깥에 그렸습니다.
IGW 를 VPC 와 연결 (associate) 하는 순간에 port 가 생성되어 연결될 것으로 보입니다.
VPC 내에는 subnet 을 만들어 Network 대역을 다시 나눌 수 있는데 subent 은 10.0.0.0/24 처럼 VPC 대역 내여야 하고, 하나의 subent 은 AZ 의 하나에만 할당될 수 있습니다. AZ 내에 하나만 할 당 할 수 있는 이유는 EC2 VM 을 만들면 VPC 내의 Subnet 을 선택하고, VM에 ip 를 할당하면서 해당 IP 에 대해서 s/w 적으로 연결이 될텐데 여러 AZ 에 대역이 펼쳐져 있으면 통신이 꼬일 수 밖에 없습니다.
그러므로 실제로 중요한 것은 VPC 라기 보다는 Subnet 입니다. Subnet 의 정보를 가지고 다 처리를 하는데 다만 통합적으로 관리할려고 VPC 라는 개념을 가져온 것 뿐입니다.
Subnet 은 라우팅을 잡아야 하는데, 내부적으로는 VM 을 관리하는 Baremetal Host 서버에 라우팅을 세팅하기 위한 방법이 필요합니다. (혹은 Baremetal 에 떠 있는 software network switch 에서 라우팅을 세팅)
그래서 라우팅 테이블을 만들고 Subnet 에 연결(assocation) 해주면 그 라우팅 정보를 가지고 있다가 VM 이 생성될 때 세팅을 해줄 수 있습니다.
정리해보면 다음과 같습니다.
1. IGW 는 VPC 에 attach 하는 부분이 필요하다. (router 에서 인터넷으로 가는 GW port 를 연결하는 작업)
2. Route table 을 Subnet 에 association 하는 부분이 필요하다 ( VM 이 생성될 때 통신될 수 있도록 라우팅을 세팅해야 하므로 해당 정보를 이용)
AWS 가 내부적으로 어떻게 구성되어 있는 지는 모르겠습니다. 하지만 OpenStack Neutron 을 보면 저런 방법을 사용하고 있기 때문에 아마도 동작 방식은 비슷하지 않을까 생각합니다.