Habilitar la comunicación para instancias de rol en Azure Cloud Services (clásico)
Importante
Cloud Services (clásico) ahora está en desuso para todos los clientes a partir del 1 de septiembre de 2024. Microsoft detendrá y apagará las implementaciones en ejecución existentes y los datos se perderán de forma permanente a partir de octubre de 2024. Las nuevas implementaciones deben utilizar el nuevo modelo de implementación basado en Azure Resource Manager Azure Cloud Services (soporte extendido) .
Los roles de servicio en la nube se comunican a través de conexiones internas y externas. Las conexiones externas se denominan puntos de conexión de entrada mientras que conexiones internas se denominan puntos de conexión internos. En este artículo se describe cómo modificar la definición de servicio para crear puntos de conexión.
Extremo de entrada
Los extremos de entrada se usan para exponer un puerto al exterior. Tiene que especificar el tipo de protocolo y el puerto del extremo que se aplicará a los puertos internos y externos del extremo. Si lo desea, puede especificar un puerto interno diferente para el extremo mediante el atributo localPort .
El extremo de entrada puede usar los siguientes protocolos: http, https, tcp y udp.
Para crear un punto de conexión de entrada, agregue el elemento secundario InputEndpoint al elemento Endpoints de un rol web o de trabajo.
<Endpoints>
<InputEndpoint name="StandardWeb" protocol="http" port="80" localPort="80" />
</Endpoints>
Extremo de entrada de instancia
Los puntos de conexión de entrada de instancia son similares a los puntos de conexión de entrada, pero permiten asignar puertos específicos orientados al público para cada instancia de rol individual mediante el reenvío de puertos en el equilibrador de carga. Puede especificar un único puerto público o un intervalo de puertos.
Solo puede utilizar el punto de conexión de entrada de instancia como protocolo tcp o udp.
Para crear un punto de conexión de entrada de instancia, agregue el elemento secundario InstanceInputEndpoint al elemento Endpoints del rol web o de trabajo.
<Endpoints>
<InstanceInputEndpoint name="Endpoint2" protocol="tcp" localPort="10100">
<AllocatePublicPortFrom>
<FixedPortRange max="10109" min="10105" />
</AllocatePublicPortFrom>
</InstanceInputEndpoint>
</Endpoints>
Punto de conexión interno
Los extremos internos están disponibles para la comunicación entre instancias. El puerto es opcional y si se omite, se asigna un puerto dinámico al extremo. Además, puede usar un intervalo de puertos. Hay un límite de cinco puntos de conexión internos por rol.
El extremo interno puede usar los siguientes protocolos: http, tcp, udp y any.
Para crear un punto de conexión de entrada interno, agregue el elemento secundario InternalEndpoint al elemento Endpoints de un rol web o de trabajo.
<Endpoints>
<InternalEndpoint name="Endpoint3" protocol="any" port="8999" />
</Endpoints>
También puede usar un intervalo de puertos.
<Endpoints>
<InternalEndpoint name="Endpoint3" protocol="any">
<FixedPortRange max="8999" min="8995" />
</InternalEndpoint>
</Endpoints>
Roles de trabajo en comparación con los Roles web
Hay una pequeña diferencia entre los extremos cuando se trabaja con roles web y de trabajo. El rol web debe tener como mínimo un extremo de entrada que use el protocolo HTTP .
<Endpoints>
<InputEndpoint name="StandardWeb" protocol="http" port="80" localPort="80" />
<!-- more endpoints may be declared after the first InputEndPoint -->
</Endpoints>
Uso del SDK de .NET para tener acceso a un extremo
La Biblioteca administrada de Azure proporciona métodos a las instancias de rol para que puedan comunicarse en tiempo de ejecución. Desde el código que se ejecuta dentro de una instancia de rol, puede recuperar información sobre la existencia de otras instancias de rol y sus puntos de conexión. También puede obtener información sobre la instancia de rol actual.
Nota:
Solo puede recuperar información sobre las instancias de rol que se ejecuten en el servicio en la nube y que definan, al menos, un extremo interno. Asimismo, no puede obtener datos sobre instancias de rol que se ejecuten en un servicio diferente.
Puede usar la propiedad Instances para recuperar las instancias de rol. Primero, use el elemento CurrentRoleInstance para devolver una referencia a la instancia de rol actual y, a continuación, use la propiedad Role para devolver una referencia al propio rol.
Si se conecta a una instancia de rol mediante programación a través del SDK de .NET, le será relativamente fácil obtener acceso a la información del extremo. Por ejemplo, después de conectarse a un entorno de rol específico, puede obtener el puerto de un punto de conexión específico con este código:
int port = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["StandardWeb"].IPEndpoint.Port;
La propiedad Instances devuelve una colección de objetos RoleInstance. Tenga en cuenta que esta colección siempre contiene la instancia actual. Si el rol no define un punto de conexión interno, la colección incluye la instancia actual, pero ninguna otra instancia. El número de instancias de rol en la colección es siempre uno en el caso de que no se haya definido ningún punto de conexión interno para el rol. Si el rol define un punto de conexión interno, sus instancias se pueden detectar en tiempo de ejecución y el número de instancias de la colección corresponde al número de instancias especificadas para el rol en el archivo de configuración del servicio.
Nota:
La Biblioteca administrada de Azure no le proporciona una manera de determinar el estado de otras instancias de rol, pero siempre puede implementar estas evaluaciones de estado si el servicio necesita esta funcionalidad. Puede usar Diagnósticos de Azure para obtener información acerca de las instancias de rol que se estén ejecutando.
Para determinar el número de puerto de un extremo interno en una instancia de rol, puede usar la propiedad de InstanceEndpoints
para que se devuelva un objeto Dictionary que contenga nombres de extremo, así como las direcciones IP y los puertos correspondientes. La propiedad IPEndpoint
devuelve la dirección IP y el puerto del extremo que se haya especificado. La propiedad PublicIPEndpoint
devuelve el puerto de un punto de conexión con equilibrio de carga. No se utiliza la parte de dirección IP de la PublicIPEndpoint
propiedad.
Este es un ejemplo que recorre en iteración las instancias de rol.
foreach (RoleInstance roleInst in RoleEnvironment.CurrentRoleInstance.Role.Instances)
{
Trace.WriteLine("Instance ID: " + roleInst.Id);
foreach (RoleInstanceEndpoint roleInstEndpoint in roleInst.InstanceEndpoints.Values)
{
Trace.WriteLine("Instance endpoint IP address and port: " + roleInstEndpoint.IPEndpoint);
}
}
Aquí tiene el ejemplo de un rol de trabajo que obtiene el punto de conexión expuesto a través de la definición de servicio, y que inicia la escucha de conexiones.
Advertencia
Este código solo funcionará en un servicio implementado. Cuando se ejecutan en el Emulador de Azure Compute, los elementos de configuración de servicio que crean extremos de puerto directo (elementosInstanceInputEndpoint ) se ignoran.
using System;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.Diagnostics;
using Microsoft.WindowsAzure.ServiceRuntime;
using Microsoft.WindowsAzure.StorageClient;
namespace WorkerRole1
{
public class WorkerRole : RoleEntryPoint
{
public override void Run()
{
try
{
// Initialize method-wide variables
var epName = "Endpoint1";
var roleInstance = RoleEnvironment.CurrentRoleInstance;
// Identify direct communication port
var myPublicEp = roleInstance.InstanceEndpoints[epName].PublicIPEndpoint;
Trace.TraceInformation("IP:{0}, Port:{1}", myPublicEp.Address, myPublicEp.Port);
// Identify public endpoint
var myInternalEp = roleInstance.InstanceEndpoints[epName].IPEndpoint;
// Create socket listener
var listener = new Socket(
myInternalEp.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
// Bind socket listener to internal endpoint and listen
listener.Bind(myInternalEp);
listener.Listen(10);
Trace.TraceInformation("Listening on IP:{0},Port: {1}",
myInternalEp.Address, myInternalEp.Port);
while (true)
{
// Block the thread and wait for a client request
Socket handler = listener.Accept();
Trace.TraceInformation("Client request received.");
// Define body of socket handler
var handlerThread = new Thread(
new ParameterizedThreadStart(h =>
{
var socket = h as Socket;
Trace.TraceInformation("Local:{0} Remote{1}",
socket.LocalEndPoint, socket.RemoteEndPoint);
// Shut down and close socket
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
));
// Start socket handler on new thread
handlerThread.Start(handler);
}
}
catch (Exception e)
{
Trace.TraceError("Caught exception in run. Details: {0}", e);
}
}
public override bool OnStart()
{
// Set the maximum number of concurrent connections
ServicePointManager.DefaultConnectionLimit = 12;
// For information on handling configuration changes
// see the MSDN topic at https://go.microsoft.com/fwlink/?LinkId=166357.
return base.OnStart();
}
}
}
Reglas de tráfico de red para controlar la comunicación entre roles
Una vez definidos los extremos internos, puede agregar reglas de tráfico de red (basadas en los extremos que haya creado) para controlar el modo en que se comunican las instancias de rol. En el siguiente diagrama verá algunos escenarios comunes para controlar la comunicación entre roles:
En el siguiente ejemplo de código verá las definiciones de rol de los roles que se mostraban en el diagrama anterior. Cada definición de rol incluye, al menos, un extremo interno definido:
<ServiceDefinition name="MyService" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
<WebRole name="WebRole1" vmsize="Medium">
<Sites>
<Site name="Web">
<Bindings>
<Binding name="HttpIn" endpointName="HttpIn" />
</Bindings>
</Site>
</Sites>
<Endpoints>
<InputEndpoint name="HttpIn" protocol="http" port="80" />
<InternalEndpoint name="InternalTCP1" protocol="tcp" />
</Endpoints>
</WebRole>
<WorkerRole name="WorkerRole1">
<Endpoints>
<InternalEndpoint name="InternalTCP2" protocol="tcp" />
</Endpoints>
</WorkerRole>
<WorkerRole name="WorkerRole2">
<Endpoints>
<InternalEndpoint name="InternalTCP3" protocol="tcp" />
<InternalEndpoint name="InternalTCP4" protocol="tcp" />
</Endpoints>
</WorkerRole>
</ServiceDefinition>
Nota:
Es posible que los extremos internos de tanto puertos asignados fijos como automáticos tengan restricciones de comunicación entre roles.
De forma predeterminada, una vez definido el extremo interno, la comunicación puede fluir sin restricciones desde cualquier rol hasta el extremo interno de otro rol. Para restringir la comunicación, debe agregar un elemento NetworkTrafficRules al elemento ServiceDefinition que se encuentra en el archivo de definición de servicio.
Escenario 1
Permitir solo el tráfico de red de WebRole1 a WorkerRole1.
<ServiceDefinition name="MyService" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
<NetworkTrafficRules>
<OnlyAllowTrafficTo>
<Destinations>
<RoleEndpoint endpointName="InternalTCP2" roleName="WorkerRole1"/>
</Destinations>
<AllowAllTraffic/>
<WhenSource matches="AnyRule">
<FromRole roleName="WebRole1"/>
</WhenSource>
</OnlyAllowTrafficTo>
</NetworkTrafficRules>
</ServiceDefinition>
Escenario 2
Permitir solo el tráfico de red de WebRole1 a WorkerRole1 y WorkerRole2.
<ServiceDefinition name="MyService" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
<NetworkTrafficRules>
<OnlyAllowTrafficTo>
<Destinations>
<RoleEndpoint endpointName="InternalTCP2" roleName="WorkerRole1"/>
<RoleEndpoint endpointName="InternalTCP3" roleName="WorkerRole2"/>
</Destinations>
<WhenSource matches="AnyRule">
<FromRole roleName="WebRole1"/>
</WhenSource>
</OnlyAllowTrafficTo>
</NetworkTrafficRules>
</ServiceDefinition>
Escenario 3
Permitir solo el tráfico de red de WebRole1 a WorkerRole1 y WorkerRole1 a WorkerRole2.
<ServiceDefinition name="MyService" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
<NetworkTrafficRules>
<OnlyAllowTrafficTo>
<Destinations>
<RoleEndpoint endpointName="InternalTCP2" roleName="WorkerRole1"/>
</Destinations>
<AllowAllTraffic/>
<WhenSource matches="AnyRule">
<FromRole roleName="WebRole1"/>
</WhenSource>
</OnlyAllowTrafficTo>
</NetworkTrafficRules>
<NetworkTrafficRules>
<OnlyAllowTrafficTo>
<Destinations>
<RoleEndpoint endpointName="InternalTCP3" roleName="WorkerRole2"/>
</Destinations>
<WhenSource matches="AnyRule">
<FromRole roleName="WorkerRole1"/>
</WhenSource>
</OnlyAllowTrafficTo>
</NetworkTrafficRules>
</ServiceDefinition>
Escenario 4
Permitir solo el tráfico de red de WebRole1 a WorkerRole1, WebRole1 a WorkerRole2 y WorkerRole1 a WorkerRole2.
<ServiceDefinition name="MyService" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
<NetworkTrafficRules>
<OnlyAllowTrafficTo>
<Destinations>
<RoleEndpoint endpointName="InternalTCP2" roleName="WorkerRole1"/>
</Destinations>
<AllowAllTraffic/>
<WhenSource matches="AnyRule">
<FromRole roleName="WebRole1"/>
</WhenSource>
</OnlyAllowTrafficTo>
</NetworkTrafficRules>
<NetworkTrafficRules>
<OnlyAllowTrafficTo >
<Destinations>
<RoleEndpoint endpointName="InternalTCP3" roleName="WorkerRole2"/>
</Destinations>
<AllowAllTraffic/>
<WhenSource matches="AnyRule">
<FromRole roleName="WorkerRole1"/>
</WhenSource>
</OnlyAllowTrafficTo>
</NetworkTrafficRules>
<NetworkTrafficRules>
<OnlyAllowTrafficTo >
<Destinations>
<RoleEndpoint endpointName="InternalTCP4" roleName="WorkerRole2"/>
</Destinations>
<AllowAllTraffic/>
<WhenSource matches="AnyRule">
<FromRole roleName="WebRole1"/>
</WhenSource>
</OnlyAllowTrafficTo>
</NetworkTrafficRules>
</ServiceDefinition>
Puede encontrar una referencia de esquema XML para los elementos usados aquí.
Pasos siguientes
Obtenga más información sobre el modelodel servicio en la nube.