说明
- istio版本号
1.4.2
- k8s集群版本
v1.14.8
- istio在
1.4
提供了基于istioctl命令直接部署的功能,这里使用istioctl部署istio。- 自带配置校验、和丰富的自定义配置选项
- API版本号还在Alpha阶段,
install.istio.io/v1alpha2
,请自行判断是否适用 - 部署要求
- 至少得有Kubernetes集群
- Istio-1.4版本在
1.13
、1.14
、1.15
的k8s集群上是做过测试通过的 - 最新的
1.16
没在官方文档里注明,应该也是可以用的。官方说明在此
- 这里通过官方示例熟悉一下istio的ServiceMesh特性
Ingress
说明
在Kubernetes环境中,Kubernetes的Ingress资源用于配置集群外部访问集群内部的服务。
在Istio中,使用Istio Gateway进行替代。
Istio通过Gateway实现对进入集群的流量进行路由和监控。
环境准备
- 部署
httpbin
1 | kubectl apply -f samples/httpbin/httpbin.yaml |
确定Ingress的IP地址端口
1 | kubectl get svc istio-ingressgateway -n istio-system |
输出示例,家境贫寒,这里用的是
NodePort
1 | NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE |
LoadBalancer
对于使用
LoadBalancer
的Service,可以通过EXTERNAL-IP
加端口的形式访问Istio-Gateway
1 | export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}') |
NodePort
我的实验环境没有
LoadBalancer
,因此用了NodePort
1 | export INGRESS_HOST=$(kubectl get po -l istio=ingressgateway -n istio-system -o jsonpath='{.items[0].status.hostIP}') |
基础的Ingress
使用Gateway配置ingress
与Kubernetes自带的Ingress对象不同
Istio Gateway会使用istio自己的路由规则来转发流量,转发方式跟集群内部路由方式相同。
创建Gateway
1 | kubectl apply -f - <<EOF |
创建VirtualService
指定了
httpbin-gateway
作为Istio Gateway只允许
/status
和/delay
两个请求,其他外部请求会404
主机名指定
httpbin.example.com
1 | kubectl apply -f - <<EOF |
集群外部访问
命令行
- 正确访问方式
1 | curl -I -H 'Host:httpbin.example.com' http://$INGRESS_HOST:$INGRESS_PORT/status/200 |
输出示例
1 | HTTP/1.1 200 OK |
- 错误访问方式
1 | 不带Host字段或者Host字段不匹配 |
输出示例
1 | HTTP/1.1 404 Not Found |
浏览器
修改hosts文件
添加以下内容,注意替换
Ingress_HOST
的值
1 | <Ingress_HOST> httpbin.example.com |
打开网页
注意替换
Ingress_Port
的值
http://httpbin.example.com:<Ingress_PORT>/status/200
清理环境
按需清理,后面做HTTPS还要用到httpbin
1 | kubectl delete gateway httpbin-gateway |
基于SSL/TLS的Ingress (File Mount文件挂载)
说明
- Istio-Gateway同样可以处理HTTPS请求
- TLS类型的Secret会被挂载到
/etc/istio/ingressgateway-certs
- Secret对象的名字必须是
istio-ingressgateway-certs
并且命名空间是在istio-system
,否则istio-Gateway无法识别
创建TLS类型的Secret
已有证书
如果购买了公网的可信任证书,可以跳过自建证书的步骤。
自建证书
创建CA证书
1 | openssl req -x509 \ |
创建证书
1 | openssl req -out \ |
创建Secret
1 | kubectl -n istio-system create secret tls \ |
检查证书是否挂载
1 | kubectl exec -it -n istio-system $(kubectl -n istio-system get pods -l istio=ingressgateway -o jsonpath='{.items[0].metadata.name}') -- ls -al /etc/istio/ingressgateway-certs |
输出示例
1 | total 0 |
使用Gateway配置Ingress
创建Gateway
1 | kubectl apply -f - <<EOF |
创建VirtualService
1 | kubectl apply -f - <<EOF |
访问HTTPS服务
1 | curl -v \ |
输出示例
1 | * Added httpbin.example.com:30885:192.168.48.37 to DNS cache |
配置多Host的TLS Ingress
创建TLS类型的Secret
这里以bookinfo.com作为示例
创建证书
1 | openssl req \ |
创建Secret
1 | kubectl -n istio-system create secret tls \ |
更新istio-ingressgateway
这里需要重新配置istio-ingressgateway
的deployment
以挂载新的证书
创建Patch file
1 | cat > gateway-patch.json <<EOF |
部署Patch
1 | kubectl -n istio-system patch --type=json deploy istio-ingressgateway -p "$(cat gateway-patch.json)" |
检查证书挂载
1 | kubectl exec -it -n istio-system $(kubectl -n istio-system get pods -l istio=ingressgateway -o jsonpath='{.items[0].metadata.name}') -- ls -al /etc/istio/ingressgateway-bookinfo-certs |
输出示例
1 | total 0 |
配置bookinfo.com路由
部署bookinfo
1 | kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml |
定义Gateway
1 | kubectl apply -f - <<EOF |
定义VirtualService
1 | kubectl apply -f - <<EOF |
访问服务
bookinfo
1 | curl -o /dev/null \ |
输出示例
1 | * Added bookinfo.com:30885:192.168.48.37 to DNS cache |
httpbin
httpbin服务依然能正常访问
1 | curl -H 'Host:httpbin.example.com' \ |
输出示例
1 | -=[ teapot ]=- |
清理现场
说明
请按需清理!后面做SSL/TLS实验还会用到!
清理istio资源对象
1 | kubectl delete gateway --ignore-not-found=true httpbin-gateway bookinfo-gateway |
清理证书
1 | rm -rf example.com.crt example.com.key |
清理Patch文件
1 | rm -rf gateway-patch.json |
清理httpbin服务
1 | kubectl delete --ignore-not-found=true -f samples/httpbin/httpbin.yaml |
基于SSL/TLS的Ingress(SDS密钥发现服务)
说明
通过
Secret Discovery Service
可以监视TLS Credential
的生成IngressGateway
可以动态增删改查证书,而不是通过Patch的方式重新部署IngressGateway
不需要配置
IngressGateway
挂载Secret
卷IngressGateway
可以监控多个密钥对,因此只需要更新Gateway
定义即可Demo
默认不开启SDS
功能,需要通过istioctl重新配置istio,配置如下1
2--set values.gateways.istio-egressgateway.enabled=false
--set values.gateways.istio-ingressgateway.sds.enabled=true
环境准备
Istio特性部署要求
- 启用SDS功能
Istio部署参数
1 | istioctl manifest apply \ |
为了方便测试,这里额外添加了部署参数
1 | istioctl manifest apply \ |
获取Ingress环境变量
1 | export INGRESS_HOST=$(kubectl get po -l istio=ingressgateway -n istio-system -o jsonpath='{.items[0].status.hostIP}') |
部署httpbin
1 | kubectl apply -f samples/httpbin/httpbin.yaml |
创建Secret
说明
- Secret对象的名字不能以
istio
或者prometheus
开头 - Secret对象不能包含
token
字段
已有证书
如果购买了公网的可信任证书,可以跳过自建证书的步骤。
自建证书
创建CA证书
1 | openssl req -x509 \ |
创建证书
1 | openssl req -out \ |
创建Secret
1 | kubectl -n istio-system \ |
使用Gateway配置Ingress
创建Gateway
1 | cat <<EOF | kubectl apply -f - |
创建VirtualService
1 | cat <<EOF | kubectl apply -f - |
访问HTTPS服务
1 | curl -v \ |
输出示例
1 | * Added httpbin.example.com:31944:192.168.48.37 to DNS cache |
配置多Host的TLS Ingress
创建TLS类型的Secret
这里以bookinfo.com作为示例
创建证书
1 | openssl req \ |
创建Secret
1 | kubectl -n istio-system \ |
配置Gateway
添加bookinfo的host
1 | cat <<EOF | kubectl apply -f - |
配置VirtualService
配置bookinfo的VirtualService
1 | kubectl apply -f - <<EOF |
访问HTTPS服务
bookinfo
1 | curl -o /dev/null \ |
httpbin
1 | curl -H 'Host:httpbin.example.com' \ |
清理现场
清理istio资源对象
1 | kubectl delete sds-gateway mygateway |
清理证书
1 | rm -rf httpbin.example.com.crt httpbin.example.com.csr httpbin.example.com.key |
清理Kubernetes资源对象
1 | kubectl delete service --ignore-not-found=true bookinfo |
Ingress Gateway without TLS Termination
说明
- 这个TLS Termination不知道怎么翻译,简单的说就是Gateway不处理TLS/HTTPS,直接透传后端的TLS
- 这里简单部署一个提供HTTPS的Nginx服务作为实验样例
环境准备
创建证书
沿用上面的证书生成方式
1 | openssl req \ |
创建Secret
1 | kubectl create \ |
创建Nginx配置
1 | events { |
创建ConfigMap
1 | kubectl create configmap nginx-configmap --from-file=nginx.conf=./nginx.conf |
部署Nginx
1 | cat <<EOF | istioctl kube-inject -f - | kubectl apply -f - |
测试Nginx服务
1 | NGINX_POD=$(kubectl get pod -l run=my-nginx -o jsonpath={.items..metadata.name}) |
输出示例
1 | HTTP/1.1 200 OK |
使用Gateway配置Ingress
配置Gateway
1 | kubectl apply -f - <<EOF |
配置VirtualService
1 | kubectl apply -f - <<EOF |
测试TLS直通
从集群外部访问Nginx服务
1 | curl -v \ |
输出示例
这里可以看到证书信息是
nginx.example.com
,并且证书能顺利通过验证
1 | * Added nginx.example.com:31944:192.168.48.37 to DNS cache |
清理现场
清理Kubernetes资源对象
1 | kubectl delete secret nginx-server-certs |
清理证书和配置文件
1 | rm -rf nginx.conf nginx.example.com.crt nginx.example.com.csr nginx.example.com.key |
Ingress With Cert-Manager
[暂时没这块需求就不弄了]
说明
Cert-Manager
是一个社区项目,这里是文档- 项目状态是
pre-1.0
,还没GA,API可能还会变更,所以谨慎使用! - 可以通过这个项目申请
Let's Encrypt
证书 - 自动管理和颁发证书
- 定期更新轮换证书
环境准备
Istio特性部署要求
- SDS(Secrect Discovery Service)
- Ingress
Istio部署参数
1 | istioctl manifest apply \ |
为了测试方便,这里额外添加参数
1 | istioctl manifest apply \ |
部署Cert-Manager
参考这里的Cert-Manager安装部署文档
创建命名空间
1 | kubectl create namespace cert-manager |
部署CRD和Cert-Manager
1 | kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v0.12.0/cert-manager.yaml |
验证安装
1 | kubectl get pods --namespace cert-manager |
Egress
[暂时没这块需求就不弄了]
说明
- Egress是用来管控Istio服务网格的出口流量