En esta guía, se explica cómo realizar una instalación limpia de la versión 1.11.8-asm.4 de Anthos Service Mesh en GKE en VMware y en Bare Metal. Si tienes instalada una versión anterior de Anthos Service Mesh, consulta Actualiza Anthos Service Mesh en las instalaciones.
En la guía de instalación, se muestra cómo instalar la autoridad certificadora de Anthos Service Mesh (CA de Mesh) o la autoridad certificadora de Istio (antes conocida como Citadel). En esta guía, se hace referencia al clúster como cluster1
, pero puedes repetir estos pasos para configurar muchos clústeres.
Acerca de los componentes del plano de control
GKE en VMware y Bare Metal vienen con los siguientes componentes de Istio preinstalados:
- La autoridad certificadora de Istio (antes conocida como Citadel) está instalada en el espacio de nombres
kube-system
. - La puerta de enlace de entrada de Istio y otros componentes de Istio se instalan en el espacio de nombres
gke-system
.
GKE on VMware y Bare Metal usan estos componentes para habilitar la entrada y asegurar la comunicación entre los componentes controlados por Google.
Cuando instalas Anthos Service Mesh, sus componentes se instalan en el espacio de nombres istio-system
. Debido a que los componentes de Anthos Service Mesh están en un espacio de nombres diferente, no entran en conflicto con los componentes de Istio preinstalados.
Antes de comenzar
Revisa los siguientes requisitos antes de comenzar la configuración.
Requisitos
Debes tener una suscripción a Anthos. Como alternativa, la opción de facturación prepaga está disponible solo para GKE Enterprise en Google Cloud. Para obtener más información, consulta la guía de precios de GKE Enterprise.
Asegúrate de que el clúster de usuario en el que instales Anthos Service Mesh tenga al menos 4 CPU virtuales, 15 GB de memoria y 4 nodos.
Solo en CA de Mesh: Los nodos del clúster de usuario necesitan Internet para completar la instalación de Anthos Service Mesh de forma correcta. No es posible acceder a Internet a través de un proxy HTTP.
Debes asignar un nombre a los puertos de servicio con la siguiente sintaxis:
name: protocol[-suffix]
, en la que los corchetes indican un sufijo opcional que debe comenzar con un guion. Para obtener más información, consulta Asigna nombres a puertos de servicio.Verifica que la versión del clúster se enumere en las plataformas compatibles.
Configure su entorno
Necesitas las siguientes herramientas en la computadora en la que controlas el proceso de instalación. Ten en cuenta que solo puedes instalar Anthos Service Mesh en un clúster de usuario, no en uno de administrador.
- La herramienta de línea de comandos de
curl
- Google Cloud CLI.
Después de instalar Google Cloud CLI:
Autentica con Google Cloud CLI
gcloud auth login
Actualiza los componentes:
gcloud components update
Instala
kubectl
:gcloud components install kubectl
Instala
kpt
:curl -L https://github.com/GoogleContainerTools/kpt/releases/download/v0.39.2/kpt_linux_amd64 > kpt_0_39_2 chmod +x kpt_0_39_2 alias kpt="$(readlink -f kpt_0_39_2)"
Configure variables de entorno
Obtén el nombre de contexto del clúster con los valores de la columna
NAME
en el resultado de este comando:kubectl config get-contexts
Configura las variables de entorno en el nombre del contexto del clúster, que esta guía usará en muchos pasos más adelante:
export CTX_CLUSTER1=CLUSTER1_CONTEXT_NAME
Otorga permisos de administrador del clúster
Otorga permisos de administrador de clúster a tu cuenta de usuario (tu dirección de correo electrónico de acceso de Google Cloud). Estos permisos son obligatorios a fin de crear las reglas de control de acceso basado en funciones (RBAC) necesarias para Anthos Service Mesh:
kubectl --context="${CTX_CLUSTER1}" create clusterrolebinding cluster-admin-binding \ --clusterrole=cluster-admin \ --user=USER_ACCOUNT
Descarga el archivo de instalación
Linux
Descarga el archivo de instalación de Anthos Service Mesh en el directorio de trabajo actual:
curl -LO https://storage.googleapis.com/gke-release/asm/istio-1.11.8-asm.4-linux-amd64.tar.gz
Descarga el archivo de firma y usa
openssl
para verificar la firma:curl -LO https://storage.googleapis.com/gke-release/asm/istio-1.11.8-asm.4-linux-amd64.tar.gz.1.sig openssl dgst -verify /dev/stdin -signature istio-1.11.8-asm.4-linux-amd64.tar.gz.1.sig istio-1.11.8-asm.4-linux-amd64.tar.gz <<'EOF' -----BEGIN PUBLIC KEY----- MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEWZrGCUaJJr1H8a36sG4UUoXvlXvZ wQfk16sxprI2gOJ2vFFggdq3ixF2h4qNBt0kI7ciDhgpwS8t+/960IsIgw== -----END PUBLIC KEY----- EOF
El resultado esperado es:
Verified OK
.Extrae el contenido del archivo a cualquier ubicación en tu sistema de archivos. Por ejemplo, para extraer el contenido en el directorio de trabajo actual, ingresa este comando:
tar xzf istio-1.11.8-asm.4-linux-amd64.tar.gz
El comando crea un directorio de instalación en tu directorio de trabajo actual llamado
istio-1.11.8-asm.4
que contiene lo siguiente:- Hay aplicaciones de muestra en el directorio
samples
. - La herramienta de línea de comandos de
istioctl
que usas para instalar Anthos Service Mesh se encuentra en el directoriobin
. - Los perfiles de configuración de Anthos Service Mesh se encuentran en el directorio
manifests/profiles
.
- Hay aplicaciones de muestra en el directorio
Asegúrate de estar en el directorio raíz de la instalación de Anthos Service Mesh.
cd istio-1.11.8-asm.4
macOS
Descarga el archivo de instalación de Anthos Service Mesh en el directorio de trabajo actual:
curl -LO https://storage.googleapis.com/gke-release/asm/istio-1.11.8-asm.4-osx.tar.gz
Descarga el archivo de firma y usa
openssl
para verificar la firma:curl -LO https://storage.googleapis.com/gke-release/asm/istio-1.11.8-asm.4-osx.tar.gz.1.sig openssl dgst -sha256 -verify /dev/stdin -signature istio-1.11.8-asm.4-osx.tar.gz.1.sig istio-1.11.8-asm.4-osx.tar.gz <<'EOF' -----BEGIN PUBLIC KEY----- MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEWZrGCUaJJr1H8a36sG4UUoXvlXvZ wQfk16sxprI2gOJ2vFFggdq3ixF2h4qNBt0kI7ciDhgpwS8t+/960IsIgw== -----END PUBLIC KEY----- EOF
El resultado esperado es:
Verified OK
.Extrae el contenido del archivo a cualquier ubicación en tu sistema de archivos. Por ejemplo, para extraer el contenido en el directorio de trabajo actual, ingresa este comando:
tar xzf istio-1.11.8-asm.4-osx.tar.gz
El comando crea un directorio de instalación en tu directorio de trabajo actual llamado
istio-1.11.8-asm.4
que contiene lo siguiente:- Hay aplicaciones de muestra en el directorio
samples
. - La herramienta de línea de comandos de
istioctl
que usas para instalar Anthos Service Mesh se encuentra en el directoriobin
. - Los perfiles de configuración de Anthos Service Mesh se encuentran en el directorio
manifests/profiles
.
- Hay aplicaciones de muestra en el directorio
Asegúrate de estar en el directorio raíz de la instalación de Anthos Service Mesh.
cd istio-1.11.8-asm.4
Windows
Descarga el archivo de instalación de Anthos Service Mesh en el directorio de trabajo actual:
curl -LO https://storage.googleapis.com/gke-release/asm/istio-1.11.8-asm.4-win.zip
Descarga el archivo de firma y usa
openssl
para verificar la firma:curl -LO https://storage.googleapis.com/gke-release/asm/istio-1.11.8-asm.4-win.zip.1.sig openssl dgst -verify - -signature istio-1.11.8-asm.4-win.zip.1.sig istio-1.11.8-asm.4-win.zip <<'EOF' -----BEGIN PUBLIC KEY----- MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEWZrGCUaJJr1H8a36sG4UUoXvlXvZ wQfk16sxprI2gOJ2vFFggdq3ixF2h4qNBt0kI7ciDhgpwS8t+/960IsIgw== -----END PUBLIC KEY----- EOF
El resultado esperado es:
Verified OK
.Extrae el contenido del archivo a cualquier ubicación en tu sistema de archivos. Por ejemplo, para extraer el contenido en el directorio de trabajo actual, ingresa este comando:
tar xzf istio-1.11.8-asm.4-win.zip
El comando crea un directorio de instalación en tu directorio de trabajo actual llamado
istio-1.11.8-asm.4
que contiene lo siguiente:- Hay aplicaciones de muestra en el directorio
samples
. - La herramienta de línea de comandos de
istioctl
que usas para instalar Anthos Service Mesh se encuentra en el directoriobin
. - Los perfiles de configuración de Anthos Service Mesh se encuentran en el directorio
manifests/profiles
.
- Hay aplicaciones de muestra en el directorio
Asegúrate de estar en el directorio raíz de la instalación de Anthos Service Mesh.
cd istio-1.11.8-asm.4
Instala Anthos Service Mesh con la CA de Mesh
En esta sección, se explica cómo instalar Anthos Service Mesh con la CA de Mesh y registrar el clúster en la flota. Recomendamos que uses la CA de Mesh por los siguientes motivos:
- La CA de Mesh es un servicio altamente confiable y escalable que está optimizado para cargas de trabajo escaladas de forma dinámica en Google Cloud y de forma local.
- Con la CA de Mesh, Google administra la seguridad y la disponibilidad del backend de CA.
- La CA de Mesh te permite tener una sola raíz de confianza entre clústeres.
Si deseas usar la CA de Istio con tu propia CA raíz, consulta Configura la CA de Istio.
La función de la CA de Mesh depende del registro de la flota. De forma predeterminada, tu clúster está registrado en una flota. Para verificar el estado de tu clúster, consulta Visualiza clústeres registrados.
Habilita las siguientes API:
gcloud services enable \ anthos.googleapis.com \ cloudtrace.googleapis.com \ cloudresourcemanager.googleapis.com \ container.googleapis.com \ compute.googleapis.com \ gkeconnect.googleapis.com \ gkehub.googleapis.com \ iam.googleapis.com \ iamcredentials.googleapis.com \ logging.googleapis.com \ meshca.googleapis.com \ meshtelemetry.googleapis.com \ meshconfig.googleapis.com \ monitoring.googleapis.com \ stackdriver.googleapis.com \ sts.googleapis.com
Inicializa la configuración de la malla:
IDENTITY_PROVIDER="$(kubectl get memberships.hub.gke.io membership -o=jsonpath='{.spec.identity_provider}')" IDENTITY="$(echo "${IDENTITY_PROVIDER}" | sed 's/^https:\/\/gkehub.googleapis.com\/projects\/\(.*\)\/locations\/global\/memberships\/\(.*\)$/\1 \2/g')" read -r ENVIRON_PROJECT_ID HUB_MEMBERSHIP_ID <<EOF ${IDENTITY} EOF POST_DATA='{"workloadIdentityPools":["'${ENVIRON_PROJECT_ID}'.hub.id.goog","'${ENVIRON_PROJECT_ID}'.svc.id.goog"]}' curl --request POST \ --header "Content-Type: application/json" \ --header "Authorization: Bearer $(gcloud auth print-access-token)" \ --data "${POST_DATA}" \ https://meshconfig.googleapis.com/v1alpha1/projects/${ENVIRON_PROJECT_ID}:initialize
Configura la instalación:
kpt pkg get \ https://github.com/GoogleCloudPlatform/anthos-service-mesh-packages.git/asm@release-1.11 asm ENVIRON_PROJECT_NUMBER=$(gcloud projects describe "${ENVIRON_PROJECT_ID}" --format="value(projectNumber)") CLUSTER_NAME="${HUB_MEMBERSHIP_ID}" CLUSTER_LOCATION="global" HUB_IDP_URL="$(kubectl get memberships.hub.gke.io membership -o=jsonpath='{.spec.identity_provider}')" kpt cfg set asm gcloud.core.project ${ENVIRON_PROJECT_ID} kpt cfg set asm gcloud.container.cluster ${CLUSTER_NAME} kpt cfg set asm gcloud.compute.location ${CLUSTER_LOCATION} kpt cfg set asm anthos.servicemesh.hub gcr.io/gke-release/asm kpt cfg set asm anthos.servicemesh.rev asm-1118-4 kpt cfg set asm anthos.servicemesh.tag 1.11.8-asm.4 kpt cfg set asm gcloud.project.environProjectNumber ${ENVIRON_PROJECT_NUMBER} kpt cfg set asm anthos.servicemesh.trustDomain ${ENVIRON_PROJECT_ID}.svc.id.goog kpt cfg set asm anthos.servicemesh.idp-url "${HUB_IDP_URL}"
Si es necesario, cambia al directorio
istio-1.11.8-asm.4
. El clienteistioctl
depende de la versión. Asegúrate de usar la versión en el directorioistio-1.11.8-asm.4/bin
.Ejecuta el siguiente comando para instalar Anthos Service Mesh.
bin/istioctl install \ -f asm/istio/istio-operator.yaml \ -f asm/istio/options/hub-meshca.yaml --revision=asm-1118-4
Si deseas habilitar una función compatible opcional, incluye
-f
y el nombre del archivo YAML en la siguiente línea de comandos, después de-f cluster.yaml
. Consulta Habilita funciones opcionales para obtener más información.
Instala Anthos Service Mesh con la CA de Istio
En esta sección, se explica cómo generar certificados y claves para la CA de Istio que Anthos Service Mesh local usa a fin de firmar tus cargas de trabajo. Si ya instalaste Anthos Service Mesh con la CA de Mesh, puedes pasar a Configura la red predeterminada.
Para obtener la mayor seguridad, recomendamos enfáticamente que mantengas una CA raíz sin conexión y uses las CA subordinadas a fin de emitir certificados para cada clúster. Para obtener más información, consulta Conecta certificados de CA. En esta configuración, todas las cargas de trabajo en la malla de servicios usan la misma autoridad certificadora raíz (CA). Cada CA de Anthos Service Mesh usa una clave y un certificado intermedios de firma de CA firmados por la CA raíz. Cuando existen varias CA dentro de una malla, se establece una jerarquía de confianza entre las CA. Puedes repetir estos pasos a fin de aprovisionar certificados y claves para cualquier cantidad de autoridades certificadas.
Crea un directorio para los certificados y las claves:
mkdir -p certs && \ pushd certs
Genera un certificado raíz y una clave:
make -f ../tools/certs/Makefile.selfsigned.mk root-ca
Esto genera los siguientes archivos:
- root-cert.pem: El certificado raíz
- root-key.pem: La clave raíz
- root-ca.conf: La configuración para openssl a fin de generar el certificado raíz
- root-cert.csr: La CSR para el certificado raíz
Genera un certificado intermedio y una clave:
make -f ../tools/certs/Makefile.selfsigned.mk cluster1-cacerts
Con esta acción, se generan estos archivos en un directorio llamado
cluster1
:- ca-cert.pem: Los certificados intermedios
- ca-key.pem: La clave intermedia
- cert-chain.pem: La cadena de certificados que usa Istio
- root-cert.pem: El certificado raíz
Si sigues estos pasos con una computadora sin conexión, copia el directorio generado a una computadora con acceso a los clústeres.
Crea un secreto
cacerts
que incluya todos los archivos de entradaca-cert.pem
,ca- key.pem
,root-cert.pem
ycert-chain.pem
:kubectl --context="${CTX_CLUSTER1}" create namespace istio-system kubectl --context="${CTX_CLUSTER1}" create secret generic cacerts -n istio-system \ --from-file=cluster1/ca-cert.pem \ --from-file=cluster1/ca-key.pem \ --from-file=cluster1/root-cert.pem \ --from-file=cluster1/cert-chain.pem
Anthos Service Mesh local detectará la presencia de estos certificados o claves y los usará durante el proceso de instalación en pasos posteriores.
Regresa al directorio anterior:
popd
Configura y, luego, instala Anthos Service Mesh con la CA de Istio
En esta sección, se explica cómo instalar Anthos Service Mesh con los certificados de CA de Istio (antes conocido como Citadel) que generaste antes. Si ya instalaste Anthos Service Mesh con la CA de Mesh, puedes pasar a Configura la red predeterminada.
Crea una variable de entorno para el ID del proyecto:
export PROJECT_ID=YOUR_PROJECT_ID
Crea una variable de entorno para el número de proyecto:
export PROJECT_NUMBER=$(gcloud projects describe ${PROJECT_ID} --format="value(projectNumber)")
Crea una variable de entorno para el identificador de malla. Puede ser cualquier string, pero debe estar en un formato que sea coherente entre tus clústeres.
export MESH_ID="proj-${PROJECT_NUMBER}"
Crea la configuración del plano de control del clúster, que instalará Anthos Service Mesh mediante el perfil
asm-multicloud
. Si deseas habilitar una función compatible opcional, incluye-f
y el nombre del archivo YAML en la siguiente línea de comandos. Consulta Habilita funciones opcionales para obtener más información.En el siguiente ejemplo:
Usa el
MESH_ID
definido en los pasos anteriores.NETWORK_ID
puede ser cualquier string que identifique la red de un clúster. En esta configuración local, todos los clústeres se encuentran en su propia red, por lo que cada clúster debe tener un valor diferente.NETWORK_ID
tiene las mismas limitaciones de string que una etiqueta de Kubernetes descrita en Sintaxis y grupo de caracteres.
cat <<EOF > cluster.yaml apiVersion: install.istio.io/v1alpha1 kind: IstioOperator spec: profile: asm-multicloud revision: asm-1118-4 values: global: meshID: ${MESH_ID} multiCluster: clusterName: CLUSTER_NAME network: NETWORK_ID EOF
Si es necesario, cambia al directorio
istio-1.11.8-asm.4
. El clienteistioctl
depende de la versión. Asegúrate de usar la versión en el directorioistio-1.11.8-asm.4/bin
.Ejecuta el siguiente comando para instalar Anthos Service Mesh. Si deseas habilitar una función compatible opcional, incluye
-f
y el nombre del archivo YAML en la siguiente línea de comandos, luego de-f cluster.yaml
. Consulta Habilita funciones opcionales para obtener más información.bin/istioctl install \ --context="${CTX_CLUSTER1}" \ -f cluster.yaml
Configura la red predeterminada
Configura la red predeterminada en el espacio de nombres istio-system
.
kubectl --context="${CTX_CLUSTER1}" label \ namespace istio-system topology.istio.io/network=NETWORK_ID
Configura el webhook de validación
Cuando instales Anthos Service Mesh, configura una etiqueta de revisión en istiod
. Debes configurar la misma revisión en el webhook de validación.
Guarda el siguiente YAML en un archivo llamado
istiod-service.yaml
:cat <<EOF > istiod-service.yaml apiVersion: v1 kind: Service metadata: name: istiod namespace: istio-system labels: istio.io/rev: asm-1118-4 app: istiod istio: pilot release: istio spec: ports: - port: 15010 name: grpc-xds # plaintext protocol: TCP - port: 15012 name: https-dns # mTLS with k8s-signed cert protocol: TCP - port: 443 name: https-webhook # validation and injection targetPort: 15017 protocol: TCP - port: 15014 name: http-monitoring # prometheus stats protocol: TCP selector: app: istiod istio.io/rev: asm-1118-4 EOF
Configura el webhook de validación para que pueda encontrar el servicio
istiod
con la etiqueta de revisión:kubectl --context="${CTX_CLUSTER1}" apply -f istiod-service.yaml
Este comando crea una entrada de servicio que permite que el webhook de validación verifique de manera automática las configuraciones antes de que se apliquen.
La TLS mutua automática (mTLS automática) está habilitada de forma predeterminada. Con la mTLS automática, un proxy de sidecar de cliente detecta si el servidor tiene un sidecar de forma automática. El sidecar del cliente envía mTLS a las cargas de trabajo con sidecars y envía tráfico de texto sin formato a las cargas de trabajo sin sidecars.
Verifica los componentes del plano de control
Comprueba que los pods del plano de control en istio-system
se encuentren en ejecución:
kubectl --context="${CTX_CLUSTER1}" get pod -n istio-system
El resultado esperado es similar al siguiente:
NAME READY STATUS RESTARTS AGE istio-ingressgateway-74cc894bfd-786rg 1/1 Running 0 7m19s istiod-78cdbbbdb-d7tps 1/1 Running 0 7m36s promsd-576b8db4d6-lqf64 2/2 Running 1 7m19s
Inserta proxies de sidecar
Anthos Service Mesh usa proxies de sidecar para mejorar la seguridad, confiabilidad y observabilidad de la red. Con Anthos Service Mesh, estas funciones se abstraen del contenedor principal de la aplicación y se implementan en un proxy común fuera del proceso, que se entrega como un contenedor separado en el mismo pod.
La instalación no se completará hasta que habilites la inserción automática de proxy de sidecar y reinicies los Pods para las cargas de trabajo que se estaban ejecutando en tu clúster antes de instalar Anthos Service Mesh.
Para habilitar la inserción automática, debes etiquetar tus espacios de nombres con la etiqueta de revisión que se estableció en istiod
cuando instalaste Anthos Service Mesh. El webhook de inyector de sidecar usa la etiqueta de revisión para asociar los sidecars insertados con una revisión istiod
particular. Después de agregar la etiqueta, los Pods existentes al espacio de nombres deben reiniciarse para que se incorporen los archivos adicionales.
Antes de implementar cargas de trabajo nuevas en un espacio de nombres nuevo, asegúrate de configurar la inserción automática para que Anthos Service Mesh pueda supervisar y proteger el tráfico.
Para habilitarla, usa este comando:
Usa el siguiente comando para encontrar la etiqueta de revisión en
istiod
:kubectl --context=${CTX_CLUSTER1} \ -n istio-system get pods -l app=istiod --show-labels
El resultado es similar al siguiente:
NAME READY STATUS RESTARTS AGE LABELS istiod-asm-1118-4-5788d57586-bljj4 1/1 Running 0 23h app=istiod,istio.io/rev=asm-1118-4,istio=istiod,pod-template-hash=5788d57586 istiod-asm-1118-4-5788d57586-vsklm 1/1 Running 1 23h app=istiod,istio.io/rev=asm-1118-4,istio=istiod,pod-template-hash=5788d57586
En el resultado, en la columna
LABELS
, observa el valor de la etiqueta de revisiónistiod
, que está después del prefijoistio.io/rev=
. En este ejemplo, el valor esasm-1118-4
.Aplica la etiqueta de revisión y quita la etiqueta
istio-injection
si existe. En el siguiente comando,NAMESPACE
es el nombre del espacio de nombres en el que deseas habilitar la inserción automática yREVISION
es la etiqueta de revisión que anotaste en el paso anterior.kubectl --context=${CTX_CLUSTER1} \ label namespace NAMESPACE istio-injection- istio.io/rev=REVISION --overwrite
Puedes ignorar el mensaje
"istio-injection not found"
en el resultado. Esto significa que el espacio de nombres no tenía la etiquetaistio-injection
, que debería aparecer en las nuevas instalaciones de Anthos Service Mesh o en implementaciones nuevas. Debido a que la inserción automática falla si un espacio de nombres tiene tanto laistio-injection
como la etiqueta de revisión, todos los comandoskubectl label
de la documentación de Anthos Service Mesh incluyen la acción de quitar la etiquetaistio-injection
.Si las cargas de trabajo se estaban ejecutando en tu clúster antes de instalar Anthos Service Mesh, reinicia los Pods para activar la reinserción.
La forma de reiniciar los pods depende de tu aplicación y del entorno en el que se encuentra el clúster. Por ejemplo, en el entorno de etapa de pruebas, puedes borrar todos los pods, lo que hace que se reinicien. Sin embargo, en tu entorno de producción, es posible que tengas un proceso que implemente una implementación azul-verde para que puedas reiniciar los pods de forma segura y evitar la interrupción del tráfico.
Puedes usar
kubectl
para realizar un reinicio progresivo:kubectl --context=${CTX_CLUSTER1} \ rollout restart deployment -n NAMESPACE
Verifica que tus pods estén configurados para apuntar a la nueva versión de
istiod
.kubectl --context=${CTX_CLUSTER1} \ get pods -n NAMESPACE -l istio.io/rev=REVISION
Próximos pasos
Si planeas usar varios clústeres para tu malla de servicios local, consulta Instala Anthos Service Mesh de forma local en varios clústeres y redes.
De lo contrario, el siguiente paso es Configurar direcciones IP externas.