Istio 연습과제 - Authorization for HTTP Services
docker engine 18.06.2-ce, kubernetes 1.14.0, Istio 1.1.1, minikube v1.0.0 , macOS Mojave 10.14.4(18E226)
Istio는 ClusterRbacConfig 를 통해 권한(접근제어)를 활성화하고 ServiceRole에 대상 서비스들 접근권한 Rule 정의한 후 ServiceRoleBinding을 통해 특정 대상에 해당 ServiceRole에 지정하여 접근통제(권한)를 수행합니다.
개요
- Role-based Access Control(RBAC)
- 네임스페이스, 서비스, HTTP 메소드별 접근제어를 통한 권한기능 제공
- Authorization 구성
- ClusterRbacConfig : 접근제어 활성화 및 범위 정의
- ServiceRole : 대상 서비스들 접근권한 Rule 정의
- ServiceRoleBinding : 특정 대상(사용자, 그룹)에 ServiceRole을 지정
- ClusterRbacConfig 모드
- OFF: 비활성화
- ON: 활성화
- ON_WITH_INCLUSION: 지정된 서비스 및 네임스페이스에 대해서만 활성화
- ON_WITH_EXCLUSION: 지정된 서비스 및 네임스페이스를 제외한 모든 서비스 활성화
준비작업
- minikube 준비
$ minikube start --cpus 4 --memory 8192 -p istio-security
- Helm 설치 및 초기화
$ brew install kubernetes-helm
$ helm init
- Istio 초기화 (namespace, CRDs)
$ wget https://github.com/istio/istio/releases/download/1.1.1/istio-1.1.1-osx.tar.gz
$ tar -vxzf istio-1.1.1-osx.tar.gz
$ cd istio-1.1.1
$ kubectl create namespace istio-system
$ helm template install/kubernetes/helm/istio-init --name istio-init --namespace istio-system | kubectl apply -f -
- Istio ingresgateway는 노드 포트로 설치
$ helm template install/kubernetes/helm/istio --name istio --namespace istio-system \
--set gateways.istio-ingressgateway.type=NodePort \
| kubectl apply -f -
- Istio 파드 정상상태 확인 및 대기
$ kubectl get pod -n istio-system
- bookinfo 설치
$ kubectl apply -f <(istioctl kube-inject -f samples/bookinfo/platform/kube/bookinfo.yaml)
$ kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
$ kubectl apply -f samples/bookinfo/networking/destination-rule-all.yaml
- /productpage 정상 동작여부 확인
$ INGRESS_URL=http://$(minikube ip -p istio-security):$(k get svc/istio-ingressgateway -n istio-system -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')/productpage
$ curl -I $INGRESS_URL
- productpage 와 reviews 의 서비스를 위한
ServiceAccount
생성
$ kubectl apply -f <(istioctl kube-inject -f samples/bookinfo/platform/kube/bookinfo-add-serviceaccount.yaml)
- 브라우저에서 /productpage URL을 열여보기
echo $INGRESS_URL
Istio authorization 활성화
- ClusterRbacConfig 를 구성하여 Istio authorization 을 활성화
- 네임스페이스 “default” 에 대해서 authorization 활성화 합니다.
$ kubectl apply -f - <<EOF
apiVersion: "rbac.istio.io/v1alpha1"
kind: ClusterRbacConfig
metadata:
name: default
spec:
mode: 'ON_WITH_INCLUSION'
inclusion:
namespaces: ["default"]
EOF
- authorization 대상을 지정하지 않았으므로 /productpage 페이지 요청하면 “RBAC: access denied” 결과가 리턴됩니다.
$ curl $INGRESS_URL
RBAC: access denied
Namespace-level 접근 제어
- 네임스페이스 레벨에서 접근통제를 정의합니다.
- app 라벨이 [“productpage”, “details”, “reviews”, “ratings”] 인 서비스의 “GET” 호출에 대해 ServiceRole을 정의하고 전체 사용자에게 ServiceRole을 을 부여(ServiceRoleBinding)
- 공식문서 상에서는 ServiceRoleBinding subjects 에
source.namespace :"default"
를 지정하였으나 정상적으로 동작하지 않아 모든 user 에 대해서(user: "*"
) ServiceRole을 을 부여하도록 조정, 원인 확인 필요
$ kubectl apply -f - <<EOF
apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRole
metadata:
name: my-role
namespace: default
spec:
rules:
- services: ["*"]
methods: ["GET"]
constraints:
- key: "destination.labels[app]"
values: ["productpage", "details", "reviews", "ratings"]
---
apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRoleBinding
metadata:
name: my-role-binding
namespace: default
spec:
subjects:
- user: "*"
roleRef:
kind: ServiceRole
name: "my-role"
EOF
- 결과 확인
- 반영까지 대기한 후 아래 URL을 브라우저에서 열고 반복적으로 refresh 하면
- “RBAC: access denied” 에서 정상적인 화면으로 전환됨을 확인할 수 있음
$ echo $INGRESS_URL
cleanup
$ kubectl delete ServiceRole --all
$ kubectl delete ServiceRoleBinding --all
Service-level 접근 제어
#1. productpage 서비스 접근 허용
- 네임스페이스가 아닌 특정 서비스에 대해서 접근 제어를 허용하는 예제
- 위에서 cleanup 처리했으므로 브라우저는 “RBAC: access denied” 로 전환된 상태
$ echo $INGRESS_URL
- ServiceRole 에 특정 서비스(productpage.default.svc.cluster.local)의 GET 메소드에 대한 ServiceRole 부여하도록 정의하고 전체 사용자에게 ServiceRole를 부여(ServiceRoleBinding)
$ kubectl apply -f - <<EOF
apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRole
metadata:
name: my-role
namespace: default
spec:
rules:
- services: ["productpage.default.svc.cluster.local"]
methods: ["GET"]
---
apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRoleBinding
metadata:
name: my-role-binding
namespace: default
spec:
subjects:
- user: "*"
roleRef:
kind: ServiceRole
name: "my-role"
EOF
- 결과 확인
- 반영까지 대기한 후 브라우져에서 refresh
- /productpage 만 정상적인 조회되지만 Detail 과 Review 부분은 에러가 발생함을 확인
$ echo $INGRESS_URL
#2. details & reviews 서비스 접근 허용
- 추가로 details 과 reviews 의 서비스에 ServiceRole을 부여하여 접근가능하도록 합니다..
- 신규로 ServiceRole 이름을 생성했으므로 이전 ServiceRole,ServiceRoleBinding 과 함께 적용됩니다.
- 공식문서 상에서는 ServiceRoleBinding subjects에
user:"cluster.local/ns/default/sa/bookinfo-productpage"
를 지정하였으나 정상적으로 동작하지 않았습니다.
$ kubectl apply -f - <<EOF
apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRole
metadata:
name: details-reviews-viewer
namespace: default
spec:
rules:
- services: ["details.default.svc.cluster.local", "reviews.default.svc.cluster.local"]
methods: ["GET"]
---
apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRoleBinding
metadata:
name: bind-details-reviews
namespace: default
spec:
subjects:
- user: "*"
roleRef:
kind: ServiceRole
name: "details-reviews-viewer"
EOF
- 결과 확인
- 반영까지 대기한 후 브라우져에서 refresh
- review 부분이 정상으로 조회됩니다.
- 여전히 ratings 부분은 오류를 발생시킵니다.
$ echo $INGRESS_URL
#3. ratings 서비스 접근 허용
- 추가로 ratings 의 서비스에 Role을 부여하여 접근가능하도록 합니다.
- 신규로 ServiceRole 이름을 생성했으므로 이전 ServiceRole,ServiceRoleBinding 과 함께 적용됩니다.
- 공식문서 상에서는 ServiceRoleBinding subjects에
user:"cluster.local/ns/default/sa/bookinfo-reviews"
를 지정하였으나 정상적으로 동작하지 않았습니다.
$ kubectl apply -f - <<EOF
apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRole
metadata:
name: ratings-viewer
namespace: default
spec:
rules:
- services: ["ratings.default.svc.cluster.local"]
methods: ["GET"]
---
apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRoleBinding
metadata:
name: bind-ratings
namespace: default
spec:
subjects:
- user: "*"
roleRef:
kind: ServiceRole
name: "ratings-viewer"
EOF
- 결과 확인
- 반영까지 대기한 후 브라우져에서 refresh
- review 부분의 ratings 값이 정상으로 조회됩니다.
$ echo $INGRESS_URL
cleanup
$ kubectl delete servicerole --all
$ kubectl delete servicerolebinding --all
$ kubectl delete clusterrbacconfig --all
posted at 2019/04/26 14:20