[JAVA] Lassen Sie uns mit Azure Batch einen Stapel in einem Container ausführen

Einführung

Ich habe AWS Batch verwendet, mit dem die Logik in einem Container begrenzt und bequem auf jeder Instanz ausgeführt werden kann. Da das aktuelle Projekt jedoch Azure war, habe ich versucht, Azure Batch zu verwenden. Das Konzept ist das gleiche wie bei AWS. Wie üblich gibt es nicht viele Artikel in Dokumenten und Qiita, daher hoffe ich, dass Sie es nützlich finden.

Dieses Mal ist es übrigens mit Java SDK implementiert. Wenn Sie jedoch einen Stapel auf dem Bildschirm definieren oder SDK einer anderen Sprache verwenden, können Sie ihn verschieben, indem Sie denselben Einstellungswert festlegen. Ich denke, dass dies hilfreich ist.

Azure Batch

Azure Batch ist ein Dienst, mit dem Sie jedes Programm (einschließlich Shell) auf einer Instanz einer bestimmten Größe ausführen können. Es ist möglich, Programme in Containern wie AWS Batch auszuführen. Übrigens hat AWS (*) CloudWatch-Ereignisse zum Planen verwendet, Azure Batch verfügt jedoch über eine integrierte Zeitplanfunktion.

Vorbereitung

Das Programm, das im Container ausgeführt wird, sieht folgendermaßen aus. Lassen Sie uns Informationen wie das Betriebssystem ausgeben, um zu überprüfen, ob sie auf der angegebenen Instanz ordnungsgemäß ausgeführt werden.

Übrigens ist https://github.com/oshi/oshi praktisch, um Betriebssysteminformationen in Java abzurufen.

public class BatchMain {

    public static void main(String[] args) {

        System.out.println("execute main method.");

        System.out.println("Environment Variables");
        System.getenv().forEach((k,v) -> System.out.println(k + ":" + v));

        var si = new SystemInfo();
        System.out.println("OS: " + si.getOperatingSystem());

        var hardware = si.getHardware();
        System.out.println("Processor: " + hardware.getProcessor());

        var memory = hardware.getMemory();
        System.out.println("Memory: " + memory.getAvailable() + " / " + memory.getTotal());

        System.exit(0);
    }
}

Jetzt werden wir dies an die Azure Container-Registrierung weiterleiten. Wie gewohnt mit Ausleger drücken. Stellen Sie sicher, dass Sie USERNAME und PASSWORD in gradle.properties schreiben.

jib {
    to {
        image = 'xxxxx.azurecr.io/batch:0.0.1-SNAPSHOT'
        auth {
            username = "${USERNAME}"
            password = "${PASSWORD}"
        }
    }
}
gradlew jib

Erstellen Sie ein Azure-Stapelkonto

Wählen Sie Stapelkonten aus.

image.png

Erstellen Sie ein Stapelkonto.

image.png

Erstellen Sie eine Kopie des Stapelkontos, der URL und des primären Zugriffsschlüssels. Dies wird verwendet, wenn es programmgesteuert angegeben wird.

image.png

Machen Sie einen Pool

In Azure Batch wird die Ausführungsumgebung im Pool definiert. Es ist nicht erforderlich, für jeden Job eine Pooleinstellung zu erstellen. Wenn sich die Umgebung nicht ändert, ist eine in Ordnung. In AWS ist es eine Computerumgebung.

Unterstützte Images von virtuellen Maschinen (Linux) werden hier aufgelistet [https://docs.microsoft.com/en-us/azure/batch/batch-docker-container-workloads], jedoch nur für Centos oder Ubuntu Werden. Natürlich können Sie Ihre eigenen vorbereiten.

Es ist einfacher, den von Ihnen angegebenen Wert in der Azure-Administratorkonsole zu finden

image.png


public class Pool {

    public static final String POOL_ID = "pool_1";

    public static void main(String[] args) throws IOException {
        BatchClient client = BatchClient.open(new BatchSharedKeyCredentials(
                "https://xxxxx.japaneast.batch.azure.com",
                "xxxx",
                "xxxxxx"));

        ContainerRegistry containerRegistry = new ContainerRegistry()
                .withRegistryServer("xxxxxx.azurecr.io")
                .withUserName("xxxxxx")
                .withPassword("xxxxxxxxx");

        ContainerConfiguration containerConfiguration = new ContainerConfiguration();
        containerConfiguration.withContainerRegistries(Arrays.asList(containerRegistry));
        containerConfiguration.withContainerImageNames(Arrays.asList("xxxx.azurecr.io/batch:0.0.1-SNAPSHOT"));

        ImageReference imageReference = new ImageReference();
        imageReference.withPublisher("microsoft-azure-batch");
        imageReference.withOffer("ubuntu-server-container");
        imageReference.withSku("16-04-lts");
        imageReference.withVersion("latest");

        // VM Configuration
        VirtualMachineConfiguration virtualMachineConfiguration = new VirtualMachineConfiguration();
        virtualMachineConfiguration.withImageReference(imageReference);
        virtualMachineConfiguration.withContainerConfiguration(containerConfiguration);
        virtualMachineConfiguration.withNodeAgentSKUId("batch.node.ubuntu 16.04");

        // Create Pool
        client.poolOperations().createPool(POOL_ID, "standard_d1_v2", virtualMachineConfiguration, 1);
    }

}

Bewegen Sie sich einfach

Verschieben wir JOB und Task basierend auf den in Pool definierten Informationen. Erstellen Sie zunächst einen Job.


public class SimpleJob {

    public static final String POOL_ID = "pool_1";

    public static final String JOB_ID = "job_1";

    public static void main(String[] args) throws IOException {
        BatchClient client = BatchClient.open(new BatchSharedKeyCredentials(
                "https://xxxxx.japaneast.batch.azure.com",
                "xxxx",
                "xxxxxx"));

        PoolInformation poolInformation = new PoolInformation();
        poolInformation.withPoolId(POOL_ID);

        // CreateJob
        client.jobOperations().createJob(JOB_ID, poolInformation);
    }
}

Führen Sie die Aufgabe innerhalb des Jobs aus.

public class SimpleTask {

    public static void main(String[] args) throws IOException, InterruptedException {

        BatchClient client = BatchClient.open(new BatchSharedKeyCredentials(
                "https://xxxxx.japaneast.batch.azure.com",
                "xxxx",
                "xxxxxx"));

        TaskAddParameter parameter = new TaskAddParameter();
        parameter.withId("task1")
                .withUserIdentity(new UserIdentity().withAutoUser(new AutoUserSpecification().withElevationLevel(ElevationLevel.ADMIN).withScope(AutoUserScope.TASK)))
                .withContainerSettings(new TaskContainerSettings().withImageName("xxxx.azurecr.io/batch:0.0.1-SNAPSHOT")
                        .withContainerRunOptions("--rm"))
                .withConstraints(new TaskConstraints().withMaxTaskRetryCount(-1)).withCommandLine("");
        client.taskOperations().createTask(ScheduleJob.JOB_ID, parameter);

        long timeout = 300 * 1000;
        long startTime = System.currentTimeMillis();

        while (System.currentTimeMillis() - startTime <= timeout) {
            CloudTask task = client.taskOperations().getTask(ScheduleJob.JOB_ID, parameter.id());

            if (task.state() != TaskState.COMPLETED) {
                Thread.sleep(1000);
            }
        }
    }
}

Wenn Sie dies tun, können Sie es auf dem Azure-Administratorbildschirm sehen.

image.png

Wenn Sie auf den verschobenen Job klicken, wird der Aufgabenbildschirm angezeigt und Sie können den Ausgabeinhalt auf dem Bildschirm sehen.

Führen Sie JOB zum angegebenen Zeitpunkt aus

Geben Sie die JOB-Zeit mit withDoNotRunUntil an. Außerdem werden die Aufgaben definiert, die verschoben werden, wenn der Job ausgeführt wird.


public class ScheduleJob {

    public static final String POOL_ID = "pool_1";

    public static final String JOB_ID = "job_5";

    public static void main(String[] args) throws IOException {
        BatchClient client = BatchClient.open(new BatchSharedKeyCredentials(
                "https://xxxxx.japaneast.batch.azure.com",
                "xxxx",
                "xxxxxx"));

        // Create Schedule SimpleJob
        DateTime scheduleDateTime = new DateTime(2019,8,22,4,30, DateTimeZone.UTC);
        Schedule schedule = new Schedule().withDoNotRunUntil(scheduleDateTime);

        // pool
        PoolInformation poolInformation = new PoolInformation();
        poolInformation.withPoolId(POOL_ID);

        // container
        JobManagerTask task = new JobManagerTask();
        task.withId("scheduletask")
                .withUserIdentity(new UserIdentity().withAutoUser(new AutoUserSpecification().withElevationLevel(ElevationLevel.ADMIN).withScope(AutoUserScope.TASK)))
                .withContainerSettings(new TaskContainerSettings().withImageName("xxxxx.azurecr.io/batch:0.0.1-SNAPSHOT")
                        .withContainerRunOptions("--rm"))
                .withCommandLine("");

        JobSpecification jobSpecification = new JobSpecification().withPoolInfo(poolInformation).withJobManagerTask(task);

        client.jobScheduleOperations().createJobSchedule(JOB_ID,schedule, jobSpecification);
    }
}

Bewegen Sie sich wiederholt von der angegebenen Zeit (Cron)

Geben Sie die Zeit an, zu der zum ersten Mal mit DoNotRunUntil verschoben werden soll, und geben Sie die Zeit an, zu der mit RecurrenceInterval wiederholt verschoben werden soll. Wenn Sie DoNotRunUntil nicht angeben, wird der JOB ab dem festgelegten Zeitpunkt wiederholt ausgeführt.

public class CronScheduleJob {

    public static final String POOL_ID = "pool_1";

    public static final String JOB_ID = "job_7";

    public static void main(String[] args) throws IOException {
        BatchClient client = BatchClient.open(new BatchSharedKeyCredentials(
                "https://xxxxx.japaneast.batch.azure.com",
                "xxxx",
                "xxxxxx"));

        // Create Schedule SimpleJob
        DateTime startDateTime = new DateTime(2019,8,22,4,45, DateTimeZone.UTC);
        Period period = new Period(0,1,0,0);
        Schedule schedule = new Schedule().withRecurrenceInterval(period).withDoNotRunUntil(startDateTime);

        // pool
        PoolInformation poolInformation = new PoolInformation();
        poolInformation.withPoolId(POOL_ID);

        // container
        JobManagerTask task = new JobManagerTask();
        task.withId("cronscheduletask")
                .withUserIdentity(new UserIdentity().withAutoUser(new AutoUserSpecification().withElevationLevel(ElevationLevel.ADMIN).withScope(AutoUserScope.TASK)))
                .withContainerSettings(new TaskContainerSettings().withImageName("xxxxx.azurecr.io/batch:0.0.1-SNAPSHOT")
                        .withContainerRunOptions("--rm"))
                .withCommandLine("");

        JobSpecification jobSpecification = new JobSpecification().withPoolInfo(poolInformation).withJobManagerTask(task);

        client.jobScheduleOperations().createJobSchedule(JOB_ID,schedule, jobSpecification);
    }
}

Referenz

Recommended Posts

Lassen Sie uns mit Azure Batch einen Stapel in einem Container ausführen
Führen Sie Java-Anwendungen in Azure Batch aus
Stapelimplementierung in der RubyOnRails-Umgebung mit Digdag
[Rails] Führen Sie LINE Bot in einer lokalen Umgebung mit ngrok aus
Wenn Sie Ihre Container nur in der Cloud ausführen möchten, ist Azure Container Instances ganz einfach