Istio授权
- 启用授权
使用RbacConfig对象启用Istio授权。
RbacConfig对象,可以指定mode值进行权限限制:
- OFF:禁用Istio授权。
- ON:为网格中的所有服务启用了Istio授权。
- ON_WITH_INCLUSION:仅对inclusion字段中指定的服务和命名空间启用Istio授权。
- ON_WITH_EXCLUSION:对网格中的所有服务启用Istio授权,但exclusion 字段中指定的服务和命名空间除外。
对default命名空间启用Istio授权
apiVersion: "rbac.istio.io/v1alpha1"
kind: RbacConfig
metadata:
name: default
spec:
mode: 'ON_WITH_INCLUSION'
inclusion:
namespaces: ["default"]
TLS认证
前提:集群安装了istio和k8s集群,没有启动全局TLS,即使用istio-1.0.0/install/kubernetes/istio-demo.yaml安装istio,而不是istio-demo-auth.yaml
mode: 连接模式
名称 | 描述 |
---|---|
DISABLE | 不要设置到上游端点的TLS连接。 |
SIMPLE | 发起与上游端点的TLS连接。 |
MUTUAL | 通过提供客户端证书进行身份验证,使用相互TLS保护与上游的连接。 |
ISTIO_MUTUAL | 通过提供客户端证书进行身份验证,使用相互TLS保护与上游的连接。与Mutual模式相比,此模式使用Istio自动生成的证书进行mTLS身份验证。使用此模式时,所有其他字段TLSSettings应为空。。 |
- 建立
创建使用sidecar注入Envoy代理的两个服务foo、bar,没有sidecar注入的服务legacy
kubectl create ns foo
kubectl apply -f <(istioctl kube-inject -f istio-1.0.0/samples/httpbin/httpbin.yaml) -n foo
kubectl apply -f <(istioctl kube-inject -f istio-1.0.0/samples/sleep/sleep.yaml) -n foo
kubectl create ns bar
kubectl apply -f <(istioctl kube-inject -f istio-1.0.0/samples/httpbin/httpbin.yaml) -n bar
kubectl apply -f <(istioctl kube-inject -f istio-1.0.0/samples/sleep/sleep.yaml) -n bar
kubectl create ns legacy
kubectl apply -f istio-1.0.0/samples/httpbin/httpbin.yaml -n legacy
kubectl apply -f istio-1.0.0/samples/sleep/sleep.yaml -n legacy
- 检查
检查sleep.bar到httpbin.foo的可达性
kubectl exec $(kubectl get pod -l app=sleep -n bar -o jsonpath={.items..metadata.name}) -c sleep -n bar -- curl http://httpbin.foo:8000/ip -s -o /dev/null -w "%{http_code}\n"
检查所有可达性,从任意客户端(例如 sleep.foo、sleep.bar 和 sleep.legacy) 向任意服务端 (httpbin.foo、 httpbin.bar 或 httpbin.legacy) 发送 HTTP 请求
for from in "foo" "bar" "legacy"; do for to in "foo" "bar" "legacy"; do kubectl exec $(kubectl get pod -l app=sleep -n ${from} -o jsonpath={.items..metadata.name}) -c sleep -n ${from} -- curl http://httpbin.${to}:8000/ip -s -o /dev/null -w "sleep.${from} to httpbin.${to}: %{http_code}\n"; done; done
- 开启双向TLS认证
全局
cat <<EOF | istioctl create -f -
apiVersion: "authentication.istio.io/v1alpha1"
kind: "MeshPolicy"
metadata:
name: "default"
spec:
peers:
- mtls: {}
EOF
cat <<EOF | istioctl create -f -
apiVersion: "networking.istio.io/v1alpha3"
kind: "DestinationRule"
metadata:
name: "default"
spec:
host: "*.local"
trafficPolicy:
tls:
mode: ISTIO_MUTUAL
EOF
认证策略和规则配置了服务中的sidecar,使服务在双向TLS下进行接收和发送,没有注入sidecar的服务会请求失败,因为没有sidecar来支持认证
如果 HTTP 请求是在双向 TLS 模式下发送并且服务端只接受 HTTP 请求,则返回的错误码为 503。相反,如果请求是以纯文本的格式发送到使用双向 TLS 的服务端,则返回的错误码是 000 (同时 curl 退出码为 56,错误信息是 “failure with receiving network data”)。
- 注入sidecar到不注入sidecar
cat <<EOF | istioctl create -f -
apiVersion: "networking.istio.io/v1alpha3"
kind: "DestinationRule"
metadata:
name: "httpbin"
namespace: "legacy"
spec:
host: "httpbin.legacy.svc.cluster.local"
trafficPolicy:
tls:
mode: DISABLE
EOF
- 创建某服务专属策略
从不带 sidecar 的客户端到带有 sidecar 的服务的连接,将双向TLS模式切换到 PERMISSIVE 模式,创建foo服务
cat <<EOF | istioctl create -f -
apiVersion: "authentication.istio.io/v1alpha1"
kind: "Policy"
metadata:
name: "httpbin"
namespace: "foo"
spec:
targets:
- name: "httpbin"
peers:
- mtls:
mode: PERMISSIVE
EOF
从 sleep.legacy 到 httpbin.foo 的请求应当是成功的,但是到 httpbin.bar 的请求依然会失败。
为单独namespace中所有服务启用双向TLS
- 创建认证策略
cat <<EOF | istioctl create -f -
apiVersion: "authentication.istio.io/v1alpha1"
kind: "Policy"
metadata:
name: "default"
namespace: "foo"
spec:
peers:
- mtls: {}
EOF
- 创建规则
cat <<EOF | istioctl create -f -
apiVersion: "networking.istio.io/v1alpha3"
kind: "DestinationRule"
metadata:
name: "default"
namespace: "foo"
spec:
host: "*.foo.svc.cluster.local"
trafficPolicy:
tls:
mode: ISTIO_MUTUAL
EOF
- 发送测试请求
for from in "foo" "bar" "legacy"; do for to in "foo" "bar" "legacy"; do kubectl exec $(kubectl get pod -l app=sleep -n ${from} -o jsonpath={.items..metadata.name}) -c sleep -n ${from} -- curl http://httpbin.${to}:8000/ip -s -o /dev/null -w "sleep.${from} to httpbin.${to}: %{http_code}\n"; done; done
sleep.foo to httpbin.foo: 200
foo开启双向TLS认证,没有注入sidecar的客户端请求失败,bar没有开启TLS认证,没有注入sidecar的客户端可以请求
- 单个服务启动双向TLS认证
- 创建认证策略
这里使bar启用了双向TLS,在命令行中表明了namespace而不是在metadata,效果一样
cat <<EOF | istioctl create -n bar -f -
apiVersion: "authentication.istio.io/v1alpha1"
kind: "Policy"
metadata:
name: "httpbin"
spec:
targets:
- name: httpbin
peers:
- mtls: {}
EOF
- 创建规则
cat <<EOF | istioctl create -n bar -f -
apiVersion: "networking.istio.io/v1alpha3"
kind: "DestinationRule"
metadata:
name: "httpbin"
spec:
host: "httpbin.bar.svc.cluster.local"
trafficPolicy:
tls:
mode: ISTIO_MUTUAL
EOF
这里的foo也开启了双向TLS认证(与上图做比较),所以请求foo也失败,这里以bar为准
- 如果命名空间存在多个服务
其他服务的流量不会受到影响,这里使用将策略限制到端口的方法验证
- 更新认证策略
cat <<EOF | istioctl replace -n bar -f -
apiVersion: "authentication.istio.io/v1alpha1"
kind: "Policy"
metadata:
name: "httpbin"
spec:
targets:
- name: httpbin
ports:
- number: 1234
peers:
- mtls:
EOF
- 更新规则
cat <<EOF | istioctl replace -n bar -f -
apiVersion: "networking.istio.io/v1alpha3"
kind: "DestinationRule"
metadata:
name: "httpbin"
spec:
host: httpbin.bar.svc.cluster.local
trafficPolicy:
tls:
mode: DISABLE
portLevelSettings:
- port:
number: 1234
tls:
mode: ISTIO_MUTUAL
EOF
- 测试请求
kubectl exec $(kubectl get pod -l app=sleep -n legacy -o jsonpath={.items..metadata.name}) -c sleep -n legacy -- curl http://httpbin.bar:8000/ip -s -o /dev/null -w "%{http_code}\n"
限制到8000,在进行8000请求的时候失败
限制到1234,在进行8000请求的时候成功,表明8000端口不受影响
- 清除
kubectl delete ns foo bar legacy
基于角色的访问控制
前提:启用了双向TLS认证,部署了bookinfo应用
- 创建 Service account:bookinfo-productpage,并用这一身份部署 productpage。
- 创建 Service account:bookinfo-reviews,并用这一身份部署 reviews(注意其中包含 reviews-v2 和 reviews-v3 两个版本)。
kubectl apply -f <(istioctl kube-inject -f istio-1.0.0/samples/bookinfo/platform/kube/bookinfo-add-serviceaccount.yaml)
访问productpage,服务在v1-v3切换
- 启用Istio授权
RbacConfig被定义为Kubernetes CustomResourceDefinition (CRD)对象。
在RbacConfig对象中,运算符可以指定mode值,它可以是:
- OFF:禁用 Istio 授权。
- ON:为网格中的所有服务启用了 Istio 授权。
- ON_WITH_INCLUSION:仅对包含字段中指定的服务和命名空间启用 Istio 授权。
- ON_WITH_EXCLUSION:除了排除字段中指定的服务和命名空间外,网格中的所有服务都启用了 Istio 授权。
istioctl create -f samples/bookinfo/platform/kube/rbac/rbac-config-ON.yaml
[root@k8-master-1 istio-1.0.0]# cat samples/bookinfo/platform/kube/rbac/rbac-config-ON.yaml
apiVersion: "rbac.istio.io/v1alpha1"
kind: RbacConfig
metadata:
name: default
spec:
mode: 'ON_WITH_INCLUSION'
inclusion:
namespaces: ["default"]
访问productpage,提示被拒绝
- 命名空间级的访问控制
productpage、reviews、details 以及 ratings 服务被部署在 default 命名空间中,而 istio-ingressgateway 等 Istio 组件是部署在 istio-system 命名空间中的。我们可以定义一个策略,default 命名空间中所有服务,如果其 app 标签取值在 productpage、reviews、details 以及 ratings 范围之内,就可以被本命名空间内以及 istio-system 命名空间内的服务进行访问。
istioctl create -f samples/bookinfo/platform/kube/rbac/namespace-policy.yaml
- 清楚命名空间级的访问控制
istioctl delete -f samples/bookinfo/platform/kube/rbac/namespace-policy.yaml
- 服务级的访问控制
istio适用与http1.0以上(不包括1.0),http方法包含8种。
============
- 允许访问productpage
istioctl create -f istio-1.0.0/samples/bookinfo/platform/kube/rbac/productpage-policy.yaml
[root@k8-master-1 istio-1.0.0]# cat samples/bookinfo/platform/kube/rbac/productpage-policy.yaml
apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRole
metadata:
name: productpage-viewer
namespace: default
spec:
rules:
- services: ["productpage.default.svc.cluster.local"]
methods: ["GET"]
---
apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRoleBinding
metadata:
name: bind-productpage-viewer
namespace: default
spec:
subjects:
- user: "*"
roleRef:
kind: ServiceRole
name: "productpage-viewer"
可以访问productpage,但是details和reviews服务拒绝访问,没有给productpage访问details和reviews服务的授权
- 允许访问details和reviews服务
istioctl create -f istio-1.0.0/samples/bookinfo/platform/kube/rbac/details-reviews-policy.yaml
[root@k8-master-1 ~]# cat istio-1.0.0/samples/bookinfo/platform/kube/rbac/details-reviews-policy.yaml
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: "cluster.local/ns/default/sa/bookinfo-productpage"
roleRef:
kind: ServiceRole
name: "details-reviews-viewer"
- 允许访问ratings服务
istioctl create -f istio-1.0.0/samples/bookinfo/platform/kube/rbac/ratings-policy.yaml
[root@k8-master-1 ~]# cat istio-1.0.0/samples/bookinfo/platform/kube/rbac/ratings-policy.yaml
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: "cluster.local/ns/default/sa/bookinfo-reviews"
roleRef:
kind: ServiceRole
name: "ratings-viewer"