> ## Documentation Index
> Fetch the complete documentation index at: https://docs.coreweave.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Accéder à un service du tailnet depuis une sandbox

> Acheminez le trafic sortant d’une sandbox via un proxy Tailscale pour accéder à un service qui n’existe que sur votre tailnet.

La fonctionnalité de trafic sortant de cluster de Tailscale permet à une sandbox exécutée sur votre propre cluster CoreWeave Kubernetes Service (CKS) de se connecter à un appareil de votre tailnet, par exemple une API interne, une base de données de votre réseau d’entreprise ou un serveur de modèles sur un poste de travail. L’opérateur Kubernetes de Tailscale publie l’appareil du tailnet sous la forme d’un Service Kubernetes. Une règle de trafic sortant de la sandbox autorise ensuite celle-ci à accéder au proxy situé derrière ce Service.

Cette page s’adresse aux administrateurs qui exécutent un exécuteur de sandbox managé sur un cluster CKS. L’exemple utilise le trafic sortant autonome, avec l’opérateur installé dans le namespace `tailscale`. Deux comportements de la plateforme conditionnent la configuration :

* Exposer un Service interne au cluster via l’opérateur Tailscale permet aux appareils du tailnet de s’y connecter. En revanche, les connexions sortantes d’un Pod vers un appareil du tailnet nécessitent la [fonctionnalité de trafic sortant de cluster de Tailscale](https://tailscale.com/kb/1438/kubernetes-operator-cluster-egress).
* Les règles de trafic sortant des Sandbox ne peuvent qu’autoriser du trafic, sur une référence qui refuse tout par défaut, et `EgressRule(any=True)` exclut les adresses internes au cluster. Une destination interne au cluster, comme un proxy Tailscale, n’est donc accessible que par une règle `selector` ou `tenant`.

## Prérequis

* Un cluster CKS doté d’un exécuteur de sandbox managé dont le `installStatus` est `READY`. Voir [Utiliser votre propre infrastructure de calcul](https://docs.coreweave.com/fr/products/sandboxes/get-started-cks.md).
* L’opérateur Kubernetes Tailscale installé sur ce cluster, avec le fichier de politique de votre tailnet configuré pour CKS. Voir [Déployer l’opérateur Kubernetes Tailscale](https://docs.coreweave.com/products/cks/auth-access/tailscale-operator.md).
* Le nom MagicDNS de l’appareil du tailnet que vous souhaitez joindre, par exemple `db-host.[TAILNET-NAME].ts.net`, ainsi que le port sur lequel votre service écoute.
* Une politique de l’exécuteur qui autorise cette règle de trafic sortant par sélecteur. Un droit `any` ne couvre jamais les sélecteurs. Une politique dont le champ `allowed_egress` n’est pas vide doit donc comporter un droit `selector` de forme correspondante : il doit également définir `namespace_labels`, ses libellés doivent former un sous-ensemble de ceux que déclare la sandbox, et son filtre de port doit couvrir le port TCP 8080. Voir [`SelectorBlock`](https://docs.coreweave.com/fr/products/sandboxes/reference/profile#selectorblock).
* Le SDK Python `cwsandbox` configuré avec des [identifiants d’authentification pour le placement CKS](https://docs.coreweave.com/fr/products/sandboxes/placement.md), ainsi qu’une image de sandbox dans laquelle `curl` et `getent` sont installés.
* Un accès `kubectl` permettant de créer ou de mettre à jour des Services dans le namespace `default` et de lister les Pods dans le namespace de l’opérateur.
* Une politique de tailnet qui autorise le proxy de trafic sortant à se connecter à l’appareil cible et au port de l’application.

## Créer un Service de trafic sortant Tailscale

Créez un Service `ExternalName` annoté avec le nom MagicDNS de l'appareil du tailnet. L'opérateur crée un Pod proxy et un Service headless dans son propre namespace, puis fait pointer le Service `ExternalName` vers ce Service headless. Les exemples utilisent le namespace `tailscale`, comme dans le guide d'installation indiqué en lien ; si vous avez installé l'opérateur dans un autre namespace, adaptez les commandes et les `namespace_labels` ci-dessous.

Remplacez `[TAILNET-FQDN]` par le nom MagicDNS de l'appareil. Cet exemple crée le Service dans `default` et utilise son nom DNS entièrement qualifié pour que les Sandbox puissent s'y connecter depuis d'autres namespace. Il suppose un service HTTP exposé sur le port 8080 avec un point de terminaison `/health` ; adaptez le port et le chemin à votre service.

```yaml title="tailnet-egress.yaml" theme={"system"}
apiVersion: v1
kind: Service
metadata:
  name: internal-api
  namespace: default
  annotations:
    tailscale.com/tailnet-fqdn: "[TAILNET-FQDN]"
spec:
  type: ExternalName
  externalName: placeholder.tailscale.internal # Requis par Kubernetes, écrasé par l’opérateur
```

```bash theme={"system"}
kubectl apply -f tailnet-egress.yaml
```

Les Sandbox se connectent à `internal-api.default.svc.cluster.local:8080`. Le nom court `internal-api:8080` ne fonctionne que depuis le namespace du Service. Si votre cluster utilise un suffixe DNS autre que `cluster.local`, remplacez ce suffixe dans les exemples.

Vérifiez que l'opérateur a bien créé le Pod du proxy :

```bash theme={"system"}
kubectl get pods -n tailscale \
  -l 'tailscale.com/parent-resource=internal-api,tailscale.com/parent-resource-ns=default'
```

Attendez que le proxy soit prêt. Exemple de sortie (le nom du Pod généré peut varier) :

```text theme={"system"}
NAME                     READY   STATUS    RESTARTS   AGE
ts-internal-api-k4x7p-0  1/1     Running   0          32s
```

## Autoriser le trafic sortant de la sandbox vers le proxy

Sélectionnez le Pod du proxy par étiquette dans une `EgressRule`. La règle exige les deux ensembles de libellés :

* `pod_labels` identifie le proxy par le Service qu'il expose, au moyen des libellés `tailscale.com/parent-resource` et `tailscale.com/parent-resource-ns` de l'opérateur. Incluez le libellé de namespace pour éviter que la règle ne corresponde aussi au proxy d'un Service homonyme situé dans un autre namespace.
* `namespace_labels` sélectionne le namespace `tailscale`. Sans ce paramètre, la règle s'applique uniquement au namespace de la sandbox et ne peut pas atteindre un proxy situé dans un autre namespace.

Définissez `ports` sur le port d'écoute du service. Remplacez `[RUNNER-ID]` par l'ID de l'exécuteur du cluster sur lequel vous avez créé le Service. Sans `runner_ids`, le placement CKS peut utiliser n'importe quel exécuteur éligible de votre organisation, y compris un exécuteur situé sur un cluster dépourvu du proxy.

```python theme={"system"}
from cwsandbox import EgressRule, NetworkOptions, Sandbox, SelectorBlock

tailscale_egress = EgressRule(
    selector=SelectorBlock(
        pod_labels={
            "tailscale.com/parent-resource": "internal-api",
            "tailscale.com/parent-resource-ns": "default",
        },
        namespace_labels={"kubernetes.io/metadata.name": "tailscale"},
    ),
    ports=[8080],
)

with Sandbox.run(
    placement_mode="cks",
    runner_ids=["[RUNNER-ID]"],
    network=NetworkOptions(egress=[tailscale_egress]),
) as sandbox:
    result = sandbox.exec([
        "curl", "-sS", "--include", "--max-time", "15",
        "http://internal-api.default.svc.cluster.local:8080/health",
    ]).result()
    print(result.stdout)
    print(result.stderr)
```

Ces sélecteurs et ces ports s’appliquent au trafic sortant autonome. Un `ProxyGroup` de trafic sortant utilise des Pods de proxy partagés et remappe les ports ; cette règle ne constitue donc pas une configuration complète pour ce mode. Voir le [guide de Tailscale sur le trafic sortant à haute disponibilité](https://tailscale.com/docs/kubernetes-operator/egress#high-availability-ha-egress).

Le DNS du cluster reste accessible, sauf si la politique de l’exécuteur refuse le trafic sortant DNS au moyen de la contrainte `dns_egress`. La sandbox peut donc résoudre le nom du Service sans règle supplémentaire.

## Vérifier la connexion

L’exemple affiche les en-têtes et le corps de la réponse HTTP, ainsi que les éventuelles erreurs curl. Pour un point de terminaison d’état de santé qui renvoie le statut 200, vous devriez obtenir une ligne de statut telle que `HTTP/1.1 200 OK`, suivie de la réponse d’état de santé du service. Une erreur HTTP telle que 401 ou 404 indique qu’un serveur HTTP a bien répondu ; vérifiez alors l’authentification de l’application ou le chemin demandé.

Un délai d’expiration ou une erreur de connexion peut survenir entre la sandbox et le proxy, entre le proxy et l’appareil du tailnet, ou au niveau de l’application. Pour vérifier séparément la résolution DNS et l’échange HTTP, exécutez cet exemple de diagnostic avec l’identifiant de votre exécuteur :

```python theme={"system"}
from cwsandbox import EgressRule, NetworkOptions, Sandbox, SelectorBlock

tailscale_egress = EgressRule(
    selector=SelectorBlock(
        pod_labels={
            "tailscale.com/parent-resource": "internal-api",
            "tailscale.com/parent-resource-ns": "default",
        },
        namespace_labels={"kubernetes.io/metadata.name": "tailscale"},
    ),
    ports=[8080],
)

with Sandbox.run(
    placement_mode="cks",
    runner_ids=["[RUNNER-ID]"],
    network=NetworkOptions(egress=[tailscale_egress]),
) as sandbox:
    dns_result = sandbox.exec([
        "getent", "hosts", "internal-api.default.svc.cluster.local",
    ]).result()
    print(dns_result.stdout)
    print(dns_result.stderr)
    http_result = sandbox.exec([
        "curl", "-sv", "--max-time", "15", "-o", "/dev/null",
        "http://internal-api.default.svc.cluster.local:8080/health",
    ]).result()
    print(http_result.stderr)
```

Une résolution DNS réussie affiche au moins une adresse. Dans la sortie de curl, vérifiez la présence d'une connexion à l'adresse du proxy et d'un code de statut de réponse HTTP. La réussite de la résolution DNS ne suffit pas à confirmer que le proxy peut atteindre la cible.

## Dépannage

| Symptôme | Cause possible | Solution |
| - | - | - |
| La création échoue sur la règle de trafic sortant | Un `allowed_egress` non vide ne couvre pas les libellés du sélecteur, les libellés du namespace ou les ports demandés. | Demandez à l’administrateur de la politique d’autoriser le sélecteur avec une forme de namespace correspondante, un sous-ensemble des libellés déclarés et un filtre de port couvrant le port TCP 8080. |
| Le nom n’est pas résolu | Le nom DNS comporte un namespace ou un suffixe de cluster incorrect, l’opérateur n’a pas encore configuré le Service, ou le trafic sortant DNS est refusé. | Vérifiez le champ `externalName` du Service, utilisez le nom complet du Service et vérifiez la politique de trafic sortant DNS de l’exécuteur. |
| Le nom est résolu, mais la connexion expire | La règle sélectionne des Pods ou un namespace incorrects, la politique du tailnet bloque la cible, ou la cible n’est pas en écoute. | Vérifiez les libellés et le namespace du proxy, les règles d’accès du tailnet, ainsi que l’adresse et le port de l’application cible. |
| La connexion ne fonctionne que sur un seul port | La liste `ports` de la règle de trafic sortant n’inclut pas les autres ports. | Ajoutez les ports manquants à la règle de trafic sortant. |
| Aucun Pod proxy n’apparaît dans le namespace `tailscale` | L’opérateur est installé dans un autre namespace, la réconciliation a échoué, ou ses identifiants d’authentification ou ses tags ne sont pas autorisés. | Vérifiez le namespace et les journaux de l’opérateur, puis consultez [Configurer les tags de l’opérateur](https://docs.coreweave.com/products/cks/auth-access/tailscale-operator.md#configure-operator-tags). |

## Pages connexes

* [Déployer l’Opérateur Kubernetes Tailscale](https://docs.coreweave.com/products/cks/auth-access/tailscale-operator.md) : déployer et configurer l’opérateur sur CKS.
* [Règles réseau](https://docs.coreweave.com/fr/products/sandboxes/client/ref/networking/network-rules.md) : la référence complète de `EgressRule` et `SelectorBlock`.
* [Référence des stratégies](https://docs.coreweave.com/fr/products/sandboxes/reference/profile.md) : les droits définis par la politique, dont une règle de trafic sortant déclarée ne doit pas sortir.
* [Points de terminaison publics](https://docs.coreweave.com/fr/products/sandboxes/public-endpoints.md) : attribuer une adresse publique à un service exécuté dans une sandbox.
