Kubernetes 下安装和使用 Istio
中文文档:https://istio.io/latest/zh/docs/
下载 Istio
# 最新版本
curl -L https://istio.io/downloadIstio | sh -
# 指定版本
curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.9.3 TARGET_ARCH=x86_64 sh -
# 由于国内网络原因,下载不下来,可以手动从 github 下载 istio-1.9.3-linux-amd64.tar.gz
# https://github.com/istio/istio/releases/tag/1.9.3
cd istio-1.9.3
# 将 istioctl 客户端加入系统环境变量(root 用户)
vi /etc/profile
# 在最下面加入下面两行:
export ISTIO_HOME=/usr/local/istio-1.9.3/bin
export PATH=$ISTIO_HOME:$PATH
# 使环境变量立马生效
source /etc/profile
# 下面切换回普通用户,检查环境变量
echo $PATH
安装 Istio
# 查看 istioctl 安装的 profile 列表,有以下七种配置档可选
istioctl profile list
# 七种配置档如下:
Istio configuration profiles:
default
demo
empty
minimal
openshift
preview
remote
前四种配置档的安装差异:https://istio.io/latest/zh/docs/setup/additional-setup/config-profiles/
# 默认安装,生成环境推荐使用默认安装(不设置profile的情况下: --set profile=default)
istioctl install -y
# 也可以换成上面四种配置档之一
istioctl install --set profile=demo -y
# 给命名空间添加标签,指示 Istio 在部署应用的时候,自动的注入 Envoy 边车代理:
kubectl label namespace default istio-injection=enabled
# kubectl label namespace default istio-injection-
# 检查安装了什么
kubectl -n istio-system get deploy
# 查看安装时的配置参数
kubectl -n istio-system get IstioOperator installed-state -o yaml
# 内容太多,可以导出到一个 yaml 中
kubectl -n istio-system get IstioOperator installed-state -o yaml > installed-state.yaml
# 浏览一个配置档的配置信息
istioctl profile dump default
# 验证安装是否成功
istioctl verify-install
ingressgateway 的默认网络类型是 LoadBanlancer,在没有外部负载均衡的情况下可以修改为 NodePort。
# 将 LoadBanlancer 修改为 NodePort
kubectl get services -n istio-system
kubectl patch service istio-ingressgateway -n istio-system -p '{"spec":{"type":"NodePort"}}'
# 或者 直接编辑,打开后,找到LB,修改为NodePort
kubectl edit svc istio-ingressgateway -n istio-system
修改配置也可以通过执行一个 patch 文件:https://istio.io/latest/zh/docs/setup/install/istioctl/
部署应用并对外开放应用程序 istio.yaml
要开放访问,你需要创建 Istio 入站网关(Ingress Gateway), 它会在网格边缘把一个路径映射到路由。
kubectl apply -f istio.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-quickboot-mybatis-plus
labels:
app: sample-quickboot-mybatis-plus
spec:
replicas: 1
selector:
matchLabels:
app: sample-quickboot-mybatis-plus
template:
metadata:
labels:
app: sample-quickboot-mybatis-plus
spec:
containers:
- name: sample-quickboot-mybatis-plus
image: registry.cn-hangzhou.aliyuncs.com/mengweijin/sample-quickboot-mybatis-plus:0.0.1-SNAPSHOT
# IfNotPresent, Always, Never
imagePullPolicy: IfNotPresent
args: ["--server.ssl.enabled=false"]
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: sample-quickboot-mybatis-plus
spec:
# type: NodePort
selector:
app: sample-quickboot-mybatis-plus
ports:
# 默认情况下,为了方便起见,`targetPort` 被设置为与 `port` 字段相同的值。
- port: 8080
targetPort: 8080
# 在 Istio Gateway 中必须配置,并且格式为:"<protocol>[-<suffix>]"
name: http
---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: sample-quickboot-mybatis-plus
spec:
selector:
# use Istio default gateway implementation
istio: ingressgateway
servers:
- port:
# 需要指定一个公开的端口,80、443
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: sample-quickboot-mybatis-plus
spec:
# 使用 hosts 字段列举虚拟服务的主机——即用户指定的目标或是路由规则设定的目标。这是客户端向服务发送请求时使用的一个或多个地址。
hosts:
- "*"
gateways:
- sample-quickboot-mybatis-plus
http:
- match:
- uri:
prefix: /
route:
- destination:
port:
number: 8080
# 这里应该时服务名(Service 的名称)
host: sample-quickboot-mybatis-plus
执行命令: kubectl get all 会显示 pod READY=2,尽管 pod 在 dashboard 中显示的只有一个。这是由于原来的 pod 具有 READY 为 1/1 的容器,注入 sidecar 后的 pod 则具有 READY 为 2/2 的容器。
部署完成后,需要检查配置文件有没有问题
istioctl analyze
# 如果有问题,参考
[mengweijin@mengweijin ~]$ istioctl analyze
Error [IST0101] (VirtualService sample-quickboot-mybatis-plus.default) Referenced host not found: "mengweijin.com"
Warning [IST0104] (Gateway sample-quickboot-mybatis-plus.default) The gateway refers to a port that is not exposed on the workload (pod selector istio=ingressgateway; port 8080)
Info [IST0118] (Service sample-quickboot-mybatis-plus.default) Port name (port: 8080, targetPort: 8080) doesn't follow the naming convention of Istio port.
Error: Analyzers found issues when analyzing namespace: default.
See https://istio.io/v1.9/docs/reference/config/analysis for more information about causes and resolutions.
在这个页面就能根据 [IST0101] [IST0104] [IST0118] 找到错误原因:https://istio.io/v1.9/docs/reference/config/analysis
改正后,重启部署有问题的应用组件。
# 再次检查
[mengweijin@mengweijin ~]$ istioctl analyze
# 返回如下,就是没有问题了
✔ No validation issues found when analyzing namespace: default.
验证外部访问(minikube)
# 查看访问的 ip
minikube ip
# 查看访问的端口
echo $(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
# 也可以通过如下命令查看80端口映射的端口,就是我们要的访问的端口
kubectl -n istio-system get service istio-ingressgateway
# 组合起来就是下面的命令(打印出访问URL的IP和port):
echo $(minikube ip):$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
# 打印出:
192.168.49.2:31811
# 偷懒方式,输出整个命令
echo curl $(minikube ip):$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')/user/get
# VMware 中虚拟机中访问 url
# 部署文件中配置的hosts 为:- "*" 时访问 URL:
curl 192.168.49.2:31811/user/get
# 部署文件中配置的hosts 为:- "mengweijin.com" 时访问 URL(已经配置了域名在 /etc/hosts 文件):
curl mengweijin.com:31811/user/get
# kube-proxy 端口转发(在新的 ssh 窗口下运行),转发端口:8001
kubectl proxy --address=0.0.0.0 --disable-filter=true
# Windows 下访问:
http://192.168.171.134:8001/api/v1/namespaces/istio-system/services/http:istio-ingressgateway:80/proxy/user/get
打开 Istio Dashboard
# 安装,需要联网拉镜像,耐心等待
# 这条命令如果执行报错了,请再次执行一遍就好了。比如出现错误:no matches for kind "MonitoringDashboard" in version "monitoring.kiali.io/v1alpha1"
kubectl apply -f /usr/local/istio-1.9.3/samples/addons
# 等上面镜像拉完运行成功后,再执行下面这条命令执行时间很长
kubectl rollout status deployment/kiali -n istio-system
# kube-proxy 端口转发(在新的 ssh 窗口下运行),转发端口:8001
kubectl proxy --address=0.0.0.0 --disable-filter=true
# 打开 dashboard(在新的 ssh 窗口下运行)
istioctl dashboard kiali
# 控制台输出如下,记住下面的端口和 url 后缀
http://localhost:20001/kiali
# 在 Windows 下的浏览器中访问URL 即可打开 dashboard: 格式为:
http://<CentOS虚拟机的IP>:<端口为上面proxy中显示的端口,默认8001>/api/v1/namespaces/<服务的namespace>/services/http:<服务名称>:<服务端口>/proxy/<原始 url 的后缀>
# 示例 URL:
http://192.168.171.134:8001/api/v1/namespaces/istio-system/services/http:kiali:20001/proxy/kiali
验证外部访问(官方文档)
确定入站 IP 和端口(minikube)
其他平台参考:https://istio.io/latest/zh/docs/setup/getting-started/
export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
export SECURE_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].nodePort}')
# 确认端口被成功的赋值给了每一个环境变量:
[mengweijin@mengweijin ~]$ echo "$INGRESS_PORT"
32391
[mengweijin@mengweijin ~]$ echo "$SECURE_INGRESS_PORT"
30557
# 设置入站 IP:
export INGRESS_HOST=$(minikube ip)
# 确认 IP 地址被成功的赋值给了环境变量:
[mengweijin@mengweijin ~]$ echo "$INGRESS_HOST"
192.168.49.2
# 在一个新的终端窗口中执行此命令,启动一个 Minikube tunnel,它将把流量发送到你 Istio 入站网关:
minikube tunnel
# 设置环境变量 GATEWAY_URL:
export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT
# 确保 IP 地址和端口均成功的赋值给了环境变量:
[mengweijin@mengweijin ~]$ echo "$GATEWAY_URL"
192.168.49.2:32391
访问 API URL
# 运行下面命令,获取应用的外部访问地址(原始地址:http://localhost:8080/user/get)
[mengweijin@mengweijin ~]$ echo "http://$GATEWAY_URL/user/get"
http://192.168.49.2:32391/user/get
# 把上面命令的输出地址复制粘贴到 curl 并访问,发现成功访问到了数据
curl http://192.168.49.2:32391/user/get
卸载
安装和卸载:https://istio.io/latest/zh/docs/setup/install/istioctl/
# 移除命名空间上的标签
kubectl label namespace default istio-injection-
# 要从集群中完整卸载 Istio,运行下面命令:可选的 --purge 参数将删除所有 Istio 资源,包括可能被其他 Istio 控制平面共享的、集群范围的资源。
istioctl x uninstall --purge
kubectl delete namespace istio-system
minikube
minikube enable addons istio
setup on minikube: https://istio.io/latest/zh/docs/setup/platform-setup/minikube/