一般应用层面的业务服务都会基于http做各种请求get、post、put等方法的授权功能,这里做简单的演示
1.由于前面已经部署好bookinfo服务,如果做过对reviews服务的路由配置,这里可以把它删除掉,这样堆reviews服务的访问就会轮询它下面的三个实例,分别展示红星、黑星和无星
kubectl delete vs reviews
2.接下来在default的namespace下创建一个拒绝所有请求的策略,可以看到这个策略没有配置任何选择器selector,这个策略就会适用于default 命名空间下所有的服务实例,spec:的值也是空{},这代表着所有流量都被拒绝
kubectl apply -f - <
3.再去刷新页面就会返回RBAC: access denied的页面提示
4.创建一个允许get请求访问productpage服务的策略,这个策略没有设置from字段的值,这意味着任何来源的请求都允许访问
kubectl apply -f - <
这个时候再去刷新页面可以看到productpage页面但是,details服务和reivews服务的内容依然是看不到的,这是服务期望的,因为我们授权productpage可以访问details和reviews
5.接下来创建允许productpage可以访问details服务的策略,它允许cluster.local/ns/default/sa/bookinfo-productpage这个service account发出的get请求去访问details服务
kubectl apply -f - <
执行之后刷新页面就可以看到details服务显示内容了
6.创建允许productpage可以访问reviews服务的策略,它允许cluster.local/ns/default/sa/bookinfo-productpage这个service account发出的get请求去访问reviews服务
kubectl apply -f - <
刷新页面就可以看到右侧reviews服务的内容就可以看到了,但是ratings服务的内容依然是不可用的,无法看到,原因也是因为没有创建对应的授权策略
7.最后创建运训reviews服务访问ratings服务的策略,它允许cluster.local/ns/default/sa/bookinfo-reviews 这个service account发出的任何get请求访问ratings服务
kubectl apply -f - <
最后刷新页面,就可以像开头那样看到不同版本的reviews服务的内容了
1.为服务创建根证书和私钥:
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=example Inc./CN=example.com' -keyout example.com.key -out example.com.crt
2.为httpbin.example.com创建证书和私钥:
openssl req -out httpbin.example.com.csr -newkey rsa:2048 -nodes -keyout httpbin.example.com.key -subj "/CN=httpbin.example.com/O=httpbin organization"
openssl x509 -req -days 365 -CA example.com.crt -CAkey example.com.key -set_serial 0 -in httpbin.example.com.csr -out httpbin.example.com.crt
kubectl create -n istio-system secret tls httpbin-credential --key=httpbin.example.com.key --cert=httpbin.example.com.crt
4.定义网关引用上一步的secret 指定https协议和443端口
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: mygateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 443
name: https
protocol: HTTPS
tls:
mode: SIMPLE
credentialName: httpbin-credential
hosts:
- httpbin.example.com
5.如果之前没有部署http-bin服务,需要部署一下
apiVersion: v1
kind: Service
metadata:
name: httpbin
labels:
app: httpbin
spec:
ports:
- name: http
port: 8000
selector:
app: httpbin
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpbin
spec:
replicas: 1
selector:
matchLabels:
app: httpbin
version: v1
template:
metadata:
labels:
app: httpbin
version: v1
spec:
containers:
- image: docker.io/citizenstig/httpbin
imagePullPolicy: IfNotPresent
name: httpbin
ports:
- containerPort: 8000
6.定义验证需要的路由VirtualService
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: mygateway
spec:
hosts:
- "*"
gateways:
- mygateway
http:
- match:
- uri:
exact: /status
- uri:
prefix: /status
route:
- destination:
host: httpbin
port:
number: 8000
7.获取https对外暴露的地址
//获取https 443 对外暴露的端口
kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].nodePort}'
31967
//获取https 443 对外暴露的ip
kubectl get po -l istio=ingressgateway -n istio-system -o jsonpath='{.items[0].status.hostIP}'
192.168.188.130
curl -i -HHost:httpbin.example.com \
--resolve httpbin.example.com:31967:10.25.155.1 \
--cacert example.com.crt "https://httpbin.example.com:31967/status/418"
HTTP/2 418
server: istio-envoy
date: Thu, 10 Sep 2020 10:09:26 GMT
access-control-allow-origin: *
access-control-allow-credentials: true
x-more-info: http://tools.ietf.org/html/rfc2324
content-length: 135
x-envoy-upstream-service-time: 48
-=[ teapot ]=-
_...._
.' _ _ `.
| ."` ^ `". _,
\_;`"---"`|//
| ;/
\_ _/
`"""`
1.首先创建模拟服务httpbin和sleep,为这俩服务注入envoy 代理实现鉴权
root@kube1:~# kubectl create ns foo
namespace/foo created
root@kube1:~/istio/istio-1.5.1# kubectl apply -f <(istioctl kube-inject -f samples/httpbin/httpbin.yaml) -n foo
serviceaccount/httpbin created
service/httpbin created
deployment.apps/httpbin created
root@kube1:~/istio/istio-1.5.1# kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml) -n foo
serviceaccount/sleep created
service/sleep created
deployment.apps/sleep created
2.验证这俩服务部署成功,并且可以互相通讯
root@kube1:~/istio/istio-1.5.1# kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- curl http://httpbin.foo:8000/ip -s -o /dev/null -w "%{http_code}\n"
200
3.在foo这个namespace下为httpbin这个服务创建jwt的认证策略,这个策略只接受[email protected] 颁发的jwt令牌
kubectl apply -f - <
4.等待一会策略才会生效,当通过一个无效的令牌访问这个服务的时候,会返回401
root@kube1:~/istio/istio-1.5.1# kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- curl "http://httpbin.foo:8000/headers" -s -o /dev/null -H "Authorization: Bearer invalidToken" -w "%{http_code}\n"
401
5.当你不通过jwt去访问这个服务,依然可以请求成功,因为它还没有配置授权策略
root@kube1:~/istio/istio-1.5.1# kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- curl "http://httpbin.foo:8000/headers" -s -o /dev/null -w "%{http_code}\n"
200
6.为httpbin这个服务创建一个授权策略,所有请求这个服务的流量必须携带有效的jwt信用凭证
kubectl apply -f - <
7.接着生成一个jwt的token也就是一个信用凭证
root@kube1:~/istio/istio-1.5.1# TOKEN=$(curl https://raw.githubusercontent.com/istio/istio/release-1.7/security/tools/jwt/samples/demo.jwt -s) && echo "$TOKEN" | cut -d '.' -f2 - | base64 --decode -
{"exp":4685989700,"foo":"bar","iat":1532389700,"iss":"[email protected]","sub":"[email protected]"}root@kube1:~/istio/istio-1.5.1
8.携带这个token去请求服务,可以得到200的成功响应
root@kube1:~/istio/istio-1.5.1# kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- curl "http://httpbin.foo:8000/headers" -s -o /dev/null -H "Authorization: Bearer $TOKEN" -w "%{http_code}\n"
200
9.现在不携带token去访问就会返回403拒绝服务了
root@kube1:~/istio/istio-1.5.1# kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- curl "http://httpbin.foo:8000/headers" -s -o /dev/null -w "%{http_code}\n"
403