Kubernetes: Istio service mesh setup

Hoy toca otra de Kubernetes. Y en esta ocasión es una de las herramientas que está teniendo mas tirón. Se trata de Istio. Es una herramienta de service mesh, que lo que hace es complementar a Kubernetes en la gestión del tráfico. Esto añade funciones extras como mTLS, split de tráfico, seguridad…

Lo que hace, es añadir un sidecar basado en envoy en cada POD con el que controla el tráfico de este. Para conseguir esto, Istio despliega varios servicios encargados de gestionar tanto el estado, las métricas o la seguridad del tráfico.

Para desplegar esto en el cluster, hay diferentes formas (GKE ya lo trae en la fase beta). Nosotros vamos a desplegarlo con HELM (sin tiller).

HELM

Como hemos dicho, vamos a utilizar HELM. Esta es otra de las herramientas de Kubernetes que está pegando fuerte. Es un administrador de paquetes de Kubernetes, que nos vale para realizar despliegues de un modo mas automático. Para esto, hay que instalarlo.

curl https://raw.githubusercontent.com/helm/helm/master/scripts/get > get_helm.sh 
chmod 700 get_helm.sh 
./get_helm.sh

Descargar

Descargar la última versión de Istio. En esta ocasión vamos a usar la 1.1.

helm repo add istio.io https://storage.googleapis.com/istio-release/releases/1.1.2/charts/"

mkdir istio && cd istio

helm fetch istio.io/istio-init --untar --untardir .
helm fetch istio.io/istio --untar --untardir .

Configuración

Preparación

Hay que verificar que nuestro usuario va a tener suficientes permisos para desplegar las configuraciones de Istio. Vamos a utilizar GKE por lo que tenemos que vincular nuestro usuario al clusterrole “cluster-admin”.

kubectl create clusterrolebinding cluster-admin-binding \
    --clusterrole=cluster-admin \
    --user=$(gcloud config get-value core/account)

Antes de desplegar Istio, hay que preparar el cluster. Para ello, hay que crear el namespace de istio y desplegar la parte de Istio-init.

kubectl create namespace istio-system

helm template ./istio-init --name istio-init --namespace istio-system | kubectl apply -f -

for i in istio-init/files/crd*yaml; do kubectl apply -f $i; done

Despliegue

Una vez desplegada la configuración inicial, podemos empezar con la de Istio. Hay varias formas de desplegarlo. La que vamos a utilizar es mediante helm pero sin tiller. Para esto, se puede hacer editando el values.yml o pasándole un oneline con las opciones que queremos. Se pueden encontrar aquí.

(Opcional) En el caso de querer utilizar Kiali, hay que pasar un secret con el usuario y contraseña de la siguiente manera.

KIALI_USERNAME=$(read '?Kiali Username: ' uval && echo -n $uval | base64)
KIALI_PASSPHRASE=$(read -s '?Kiali Passphrase: ' pval && echo -n $pval | base64)

Una vez definidos usuario y password, desplegar el secret.

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
  name: kiali
  namespace: istio-system
  labels:
    app: kiali
type: Opaque
data:
  username: $KIALI_USERNAME
  passphrase: $KIALI_PASSPHRASE
EOF

Ahora ya podemos desplegar Istio

En este ejemplo hemos desplegado Istio con lo siguiente:

helm template ./istio \
  --set certmanager.enabled=true \
  --set gateways.istio-egressgateway.enabled=true \
  --set pilot.autoscaleMax=1\
  --set gateways.istio-ingressgateway.autoscaleMax=2\
  --set tracing.enabled=true \
  --set kiali.enabled=true \
  --set global.proxy.includeIPRanges="10.0.0.0/8" \
  --set global.mtls.enabled=true \
  --set grafana.enabled=true \
  --name istio \
  --namespace istio-system \
  >istio.yaml &&\
kubectl apply -f istio.yaml
  • certmanger: Gestionar certificados automáticos con letsencrypt
  • egressgateway: Habilitar el egress
  • autoscaleMax: Controlar el máximo de replicas de los servicios (HPA)
  • grafana: Para poder visualizar las métricas de grafana
  • tracing: Despliega un jaeger para ver las trazas
  • kiali: Dashboard para ver las conexiones del cluster
  • global.proxy.includeIPRanges: Para añadir la red 10.0.0.0/8 al whitelist del egress. (Esto hay que tener cuidado por que si no se añade, bloqueará el tráfico interno). La red puede variar dependiendo la red interna que utilicemos en nuestro cluster.
  • global.mtls.enabled: Para aplicar MTLS en las conexiones de los PODs.

Verificación

Para verificar que todo funciona correctamente, tenemos que comprobar los servicios y los pods desplegados

kubectl -n istio-system get svc
NAME                     TYPE           CLUSTER-IP      EXTERNAL-IP    PORT(S)                                                                                                                      AGE
grafana ClusterIP 10.11.242.209 3000/TCP 10m
istio-citadel ClusterIP 10.11.255.121 8060/TCP,15014/TCP 10m
istio-egressgateway ClusterIP 10.11.251.171 80/TCP,443/TCP,15443/TCP 10m
istio-galley ClusterIP 10.11.245.73 443/TCP,15014/TCP,9901/TCP 10m
istio-ingressgateway LoadBalancer 10.11.241.200 35.245.14.11 80:31380/TCP,443:31390/TCP,31400:31400/TCP,15029:30382/TCP,15030:31795/TCP,15031:31575/TCP,15032:31014/TCP,15443:30605/TCP 10m
istio-pilot ClusterIP 10.11.246.237 15010/TCP,15011/TCP,8080/TCP,15014/TCP 10m
istio-policy ClusterIP 10.11.244.164 9091/TCP,15004/TCP,15014/TCP 10m
istio-sidecar-injector ClusterIP 10.11.255.223 443/TCP 10m
istio-telemetry ClusterIP 10.11.247.206 9091/TCP,15004/TCP,15014/TCP,42422/TCP 10m
jaeger-agent ClusterIP None 5775/UDP,6831/UDP,6832/UDP 10m
jaeger-collector ClusterIP 10.11.253.233 14267/TCP,14268/TCP 10m
jaeger-query ClusterIP 10.11.252.217 16686/TCP 10m
kiali ClusterIP 10.11.244.167 20001/TCP 10m
prometheus ClusterIP 10.11.242.32 9090/TCP 10m
tracing ClusterIP 10.11.242.227 80/TCP 10m
zipkin ClusterIP 10.11.248.181 9411/TCP 10m
kubectl -n istio-system get pods
NAME                                                        READY   STATUS      RESTARTS   AGE
certmanager-6d8b86cb48-k45jw 1/1 Running 1 21m
grafana-7b46bf6b7c-sjrcv 1/1 Running 0 21m
istio-citadel-5bf5488468-fp6b4 1/1 Running 0 21m
istio-cleanup-secrets-release-1.1-latest-daily-g66t8 0/1 Completed 0 21m
istio-egressgateway-7f9c5f6bb5-r2s9s 1/1 Running 0 21m
istio-galley-7d66584fd5-f9bcs 1/1 Running 0 21m
istio-grafana-post-install-release-1.1-latest-daily-gmwgx 0/1 Completed 0 21m
istio-ingressgateway-7755594468-l475d 1/1 Running 0 21m
istio-pilot-7855c68959-4nhw5 2/2 Running 0 21m
istio-policy-75f9448987-dnbzp 2/2 Running 0 21m
istio-sidecar-injector-744f68bf5f-szbx8 1/1 Running 0 21m
istio-telemetry-66747f497-xt8gx 2/2 Running 0 21m
istio-tracing-759fbf95b7-xccxp 1/1 Running 0 21m
kiali-5d68f4c676-gqdg2 1/1 Running 0 21m
prometheus-566f9c4bdb-59qg6 1/1 Running 0 21m

Aplicar en los NameSpaces

Cuando se cree un namespace nuevo, si se quiere aplicar Istio en este. Hay que añadir la siguiente label

labels:
    istio-injection: enabled

Servicios

Para acceder a los servicios, hay que hacer un port-forward ya que no están expuestos al exterior

Kiali

kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=kiali -o jsonpath='{.items[0].metadata.name}') 20001:20001

http://127.0.0.1:20001/kiali/console

Jaeger

kubectl port-forward -n istio-system $(kubectl get pod -n istio-system -l app=jaeger -o jsonpath='{.items[0].metadata.name}') 16686:16686

http://localhost:16686

Grafana

kubectl port-forward -n istio-system $(kubectl get pod -n istio-system -l app=grafana -o jsonpath='{.items[0].metadata.name}') 3000:3000

http://localhost:3000

Actualizar los proxys de los deployments

Si se actualiza Istio, también es recomendable actualizar los proxys de los deployments desplegados. Para esto lo que hay que hacer es inyectar el nuevo con istioctl utilizando el fichero de cada deployment

kubectl apply -f <(istioctl kube-inject -f deployment.yaml)

Con esto ya tendríamos Istio configurado y preparado para empezar a jugar con él. En los siguientes posts, hablaremos de como gestionar certificados, como hacer Canary deployments, conectar a servicios externos….

Leave a Reply

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *