Tetrate Istio Distro 是由 Tetrate 开源的基于 Istio 的发行版。他主要解决了用户使用 Istio 时候的以下痛点:
- Istio 生命周期管理
- 经过测试的安全的 Istio 配置
- 可原生的计算环境支持
- 陡峭的学习曲线及持续支持
想要了解更多关于 Tetrate Istio Distro 的信息请访问 https://istio.tetratelabs.io/。
本文将从带你动手安装和使用 Istio,包括:
- 在 GKE 上安装 Istio 1.7
- 添加一台虚拟机到 mesh 中
- 部署 Bookinfo 示例
- 集成虚拟机测试
- 升级 Istio 到 1.8
从以上过程中你将了解 Istio 的部署架构、基本功能和操作。
准备条件
为了完成动手操作,你需要准备以下环境:
- 一个 Google Cloud 账号,并且其中有足够的余额
- 在本地安装
gcloud
工具安装 Istio
这篇博客只适用于 Istio 1.7,1.8 版本的虚拟机整合步骤有变化,请参考 Istio 文档。
安装 Istio
使用 Tetrate Istio Distro 安装 Istio 1.7.5。
curl -sL https://istio.tetratelabs.io/getmesh/install.sh | bash
getmesh fetch 1.7.5
使用 demo profile(包括 Ingress gateway、egress gateway 和 Istiod 所有组件) 安装 Istio:
getmesh istioctl install --set profile=demo --set values.global.meshExpansion.enabled=true
Detected that your cluster does not support third party JWT authentication. Falling back to less secure first party JWT. See https://istio.io/docs/ops/best-practices/security/#configure-third-party-service-account-tokens for details.
✔ Istio core installed
✔ Istiod installed
✔ Ingress gateways installed
✔ Egress gateways installed
✔ Installation complete
查看 istio-system
namespace 下的 pod:
kubectl get pod -n=istio-system
NAME READY STATUS RESTARTS AGE
istio-egressgateway-695f5944d8-wdk6s 1/1 Running 0 67s
istio-ingressgateway-5c697d4cd7-4cgq7 1/1 Running 0 67s
istiod-59747cbfdd-sbffx 1/1 Running 0 106s
设置 sidecar 自动注入:
kubectl label namespace bookinfo istio-injection=enabled
部署 Bookinfo 示例。
kubectl create ns bookinfo
kubectl apply -n bookinfo -f samples/bookinfo/platform/kube/bookinfo.yaml
service/details created
serviceaccount/bookinfo-details created
deployment.apps/details-v1 created
service/ratings created
serviceaccount/bookinfo-ratings created
deployment.apps/ratings-v1 created
service/reviews created
serviceaccount/bookinfo-reviews created
deployment.apps/reviews-v1 created
deployment.apps/reviews-v2 created
deployment.apps/reviews-v3 created
service/productpage created
serviceaccount/bookinfo-productpage created
deployment.apps/productpage-v1 created
确认示例部署完成。
kubectl exec "$(kubectl get pod -n bookinfo -l app=ratings -o jsonpath='{.items[0].metadata.name}')" -n bookinfo -c ratings -- curl -s productpage:9080/productpage | grep -o "<title>.*</title>"
正常情况下你将看到这样的显示:
<title>Simple Bookstore App</title>
允许外网访问 mesh:
kubectl -n bookinfo apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
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}')
echo "$INGRESS_PORT"
echo "$SECURE_INGRESS_PORT"
export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo "$INGRESS_HOST"
export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT
echo "$GATEWAY_URL"
应用默认的 DestinationRule。
kubectl apply -n bookinfo -f samples/bookinfo/networking/destination-rule-all.yaml
向 Istio mesh 中加入虚拟机
我们将在虚拟机中安装 MySQL,并将其配置为 ratings 服务的后台。最终,bookinfo 示例的拓扑将如下图所示。
我们将在 Google cloud 中创建一台虚拟机,并将它添加到 Istio Mesh 中。假设虚拟机实例的名称是 instance-1
,首先为虚拟机创建证书。
kubectl create secret generic cacerts -n istio-system \
--from-file=samples/certs/ca-cert.pem \
--from-file=samples/certs/ca-key.pem \
--from-file=samples/certs/root-cert.pem \
--from-file=samples/certs/cert-chain.pem
安装 Istio mesh 扩展。
getmesh istioctl install \
-f manifests/examples/vm/values-istio-meshexpansion.yaml
在 Cloud shell 中执行以下命令,生成虚拟机扩展的配置文件。
VM_NAME=instance-1
VM_NAMESPACE=vm
WORK_DIR=vm
SERVICE_ACCOUNT=instance-1
cat <<EOF> "${WORK_DIR}"/vmintegration.yaml
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
values:
global:
meshExpansion:
enabled: true
EOF
getmesh istioctl install -f "${WORK_DIR}"/vmintegration.yaml
kubectl create namespace "${VM_NAMESPACE}"
kubectl create serviceaccount "${SERVICE_ACCOUNT}" -n "${VM_NAMESPACE}"
# 1 hours,注意这个过期时间,这个 token 仅在认证时候使用,后面就不需要了。
tokenexpiretime=3600
echo '{"kind":"TokenRequest","apiVersion":"authentication.k8s.io/v1","spec":{"audiences":["istio-ca"],"expirationSeconds":'$tokenexpiretime'}}' | kubectl create --raw /api/v1/namespaces/$VM_NAMESPACE/serviceaccounts/$SERVICE_ACCOUNT/token -f - | jq -j '.status.token' > "${WORK_DIR}"/istio-token
kubectl -n "${VM_NAMESPACE}" get configmaps istio-ca-root-cert -o json | jq -j '."data"."root-cert.pem"' > "${WORK_DIR}"/root-cert
ISTIO_SERVICE_CIDR=$(echo '{"apiVersion":"v1","kind":"Service","metadata":{"name":"tst"},"spec":{"clusterIP":"1.1.1.1","ports":[{"port":443}]}}' | kubectl apply -f - 2>&1 | sed 's/.*valid IPs is //')
touch "${WORK_DIR}"/cluster.env
echo ISTIO_SERVICE_CIDR=$ISTIO_SERVICE_CIDR > "${WORK_DIR}"/cluster.env
echo "ISTIO_INBOUND_PORTS=3306,8080" >> "${WORK_DIR}"/cluster.env
touch "${WORK_DIR}"/hosts-addendum
echo "${INGRESS_HOST} istiod.istio-system.svc" > "${WORK_DIR}"/hosts-addendum
touch "${WORK_DIR}"/sidecar.env
echo "PROV_CERT=/var/run/secrets/istio" >>"${WORK_DIR}"/sidecar.env
echo "OUTPUT_CERTS=/var/run/secrets/istio" >> "${WORK_DIR}"/sidecar.env
将虚拟机配置文件导入到虚拟机实例 instance-1
中。使用 ssh 登录到虚拟机实例 instance-1
中,将为 Kubernetes 集群和 Istio 生成的文件拷贝到虚拟机的 $HOME
目录下。
sudo apt -y update
sudo apt -y upgrade
sudo mkdir -p /var/run/secrets/istio
sudo cp "${HOME}"/root-cert.pem /var/run/secrets/istio/root-cert.pem
sudo mkdir -p /var/run/secrets/tokens
sudo cp "${HOME}"/istio-token /var/run/secrets/tokens/istio-token
# Setup Istio on the VM
curl -LO https://storage.googleapis.com/istio-release/releases/1.7.1/deb/istio-sidecar.deb
sudo dpkg -i istio-sidecar.deb
sudo cp "${HOME}"/cluster.env /var/lib/istio/envoy/cluster.env
sudo cp "${HOME}"/sidecar.env /var/lib/istio/envoy/sidecar.env
sudo sh -c 'cat $(eval echo ~$SUDO_USER)/hosts-addendum >> /etc/hosts'
sudo cp "${HOME}"/root-cert.pem /var/run/secrets/istio/root-cert.pem
sudo mkdir -p /etc/istio/proxy
sudo chown -R istio-proxy /var/lib/istio /etc/certs /etc/istio/proxy /var/run/secrets
注意:默认情况下虚拟机的防火墙会拒绝对 3306 端口的入站请求,我们需要配置 VPC 中的防火墙规则,以允许 mesh 中的服务访问虚拟机的 3306 端口。
现在可以启动虚拟机中的 Istio 了。
sudo systemctl start istio
虚拟机集成测试
在虚拟机中安装 MySQL,并作为服务的后端。
sudo apt-get update && sudo apt-get install -y mariadb-server
sudo mysql
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY 'password' WITH GRANT OPTION;
quit;
sudo systemctl restart mysql
curl -q https://raw.githubusercontent.com/istio/istio/release-1.7/samples/bookinfo/src/mysql/mysqldb-init.sql | mysql -u root -ppassword
mysql -u root -ppassword test -e "select * from ratings;"
mysql -u root -ppassword test -e "update ratings set rating=5 where reviewid=1;select * from ratings;"
hostname -I
# 假如这里获取到的 IP 地址是 <virtual_machine_ip>
将虚拟机中的服务注册到 mesh 中。
getmesh istioctl experimental add-to-mesh -n vm mysqldb <virtual_machine_ip> mysql:3306
将看到这样的输出:
2020-09-17T11:34:37.740252Z warn Got 'services "mysqldb" not found' looking up svc 'mysqldb' in namespace 'vm', attempting to create it
2020-09-17T11:34:38.111244Z warn Got 'endpoints "mysqldb" not found' looking up endpoints for 'mysqldb' in namespace 'vm', attempting to create them
部署 ratings 服务的 v2 版本,使用 MySQL 作为存储后端。
kubectl apply -n bookinfo -f samples/bookinfo/platform/kube/bookinfo-ratings-v2-mysql-vm.yaml
kubectl apply -n bookinfo -f samples/bookinfo/networking/virtual-service-ratings-mysql-vm.yaml
为部署在虚拟机上的 MySQL 服务添加 DestinationRule、ServiceEntry 和 WorkloadEntry 的配置。
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: mtls-mysqldb-vm
spec:
host: mysqldb.vm.svc.cluster.local
trafficPolicy:
tls:
mode: ISTIO_MUTUAL
---
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: mysqldb-vm
spec:
hosts:
- mysqldb.vm.svc.cluster.local
location: MESH_INTERNAL
ports:
- number: 3306
name: mysql
protocol: mysql
resolution: STATIC
workloadSelector:
labels:
app: mysqldb-vm
---
apiVersion: networking.istio.io/v1alpha3
kind: WorkloadEntry
metadata:
name: mysqldb-vm
spec:
address: <virtual_machine_ip> #修改为虚拟机的 IP
labels:
app: mysqldb-vm
instance-id: ubuntu-vm-mariadb
升级到 Isito 1.8
2020 年 11 月 19 日,Istio 1.8 发布,支持使用 canary 和 in-place 升级。下面我们将使用 in-place 方式升级 Istio。
getmesh fetch --version 1.8
getmesh istioctl upgrade
Confirm to proceed [y/N]?
输入 y 确认升级,确认控制平面升级完成后,接下来我们来升级数据平面。
kubectl rollout restart deployment --namespace bookinfo
使用 getmesh istioctl proxy-status -n bookinfo
命令检查 proxy 的版本,可以看到都已经升级为了 1.8.0。
常用命令
以下是在以上操作过程中的常用命令。
使用 gcloud 命令登录到 Google cloud 的虚拟机
gcloud compute ssh jimmy@instance-1 --zone=us-west2-a
清理 bookinfo 示例
在解压后的 istio 安装包的根目录下执行:
samples/bookinfo/platform/kube/cleanup.sh