Een Docker-gids voor Java

1. Overzicht

In dit artikel kijken we naar een andere gevestigde platformspecifieke API - Java API Client voor Docker.

In het hele artikel begrijpen we de manier waarop we verbinding kunnen maken met een actieve Docker-daemon en wat voor soort belangrijke functionaliteit de API biedt aan Java-ontwikkelaars.

2. Maven Afhankelijkheid

Ten eerste moeten we de belangrijkste afhankelijkheid toevoegen aan onze pom.xml het dossier:

 com.github.docker-java docker-java 3.0.14 

Op het moment van schrijven van het artikel, de nieuwste versie van de API is 3.0.14. Elke release kan worden bekeken vanaf de GitHub-releasepagina of vanuit de Maven-repository.

3. Met behulp van de Docker Client

DockerClient is waar we een verbinding kunnen maken tussen een Docker-engine / daemon en onze applicatie.

Standaard is de Docker-daemon alleen toegankelijk op het unix: ///var/run/docker.sock het dossier. We kunnen lokaal communiceren met de Docker-engine luistert op de Unix-socket, tenzij anders geconfigureerd.

Hier zijn we van toepassing op de DockerClientBuilder class om een ​​verbinding te maken door de standaardinstellingen te accepteren:

DockerClient dockerClient = DockerClientBuilder.getInstance (). Build ();

Op dezelfde manier kunnen we een verbinding openen in twee stappen:

DefaultDockerClientConfig.Builder config = DefaultDockerClientConfig.createDefaultConfigBuilder (); DockerClient dockerClient = DockerClientBuilder .getInstance (config) .build ();

Omdat motoren op andere kenmerken kunnen vertrouwen, is de client ook configureerbaar met verschillende omstandigheden.

De bouwer accepteert bijvoorbeeld een server-URL, dat wil zeggen, we kunnen de verbindingswaarde bijwerken als de engine beschikbaar is op poort 2375:

DockerClient dockerClient = DockerClientBuilder.getInstance ("tcp: //docker.baeldung.com: 2375") .build ();

Merk op dat we vooraf moeten gaan de verbindingsreeks met unix: // of tcp: // afhankelijk van het verbindingstype.

Als we nog een stap verder gaan, kunnen we eindigen met een meer geavanceerde configuratie met behulp van de DefaultDockerClientConfig klasse:

DefaultDockerClientConfig config = DefaultDockerClientConfig.createDefaultConfigBuilder () .withRegistryEmail ("[email protected]") .withRegistryPassword ("baeldung") .withRegistryUsername ("baeldung") .withDockerCertPath ("/ home". "/home/baeldung/.docker/") .withDockerTlsVerify ("1") .withDockerHost ("tcp: //docker.baeldung.com: 2376") .build (); DockerClient dockerClient = DockerClientBuilder.getInstance (config) .build ();

Evenzo kunnen we dezelfde aanpak uitvoeren met Eigendommen:

Eigenschappen properties = nieuwe Eigenschappen (); properties.setProperty ("registry.email", "[email protected]"); properties.setProperty ("registry.password", "baeldung"); properties.setProperty ("registry.username", "baaldung"); properties.setProperty ("DOCKER_CERT_PATH", "/home/baeldung/.docker/certs"); properties.setProperty ("DOCKER_CONFIG", "/home/baeldung/.docker/"); properties.setProperty ("DOCKER_TLS_VERIFY", "1"); properties.setProperty ("DOCKER_HOST", "tcp: //docker.baeldung.com: 2376"); DefaultDockerClientConfig config = DefaultDockerClientConfig.createDefaultConfigBuilder () .withProperties (eigenschappen) .build (); DockerClient dockerClient = DockerClientBuilder.getInstance (config) .build ();

Een andere keuze, tenzij we de instellingen van de engine in de broncode configureren, is om overeenkomstige omgevingsvariabelen in te stellen zodat we alleen de standaardinstantie van DockerClient in het project:

export DOCKER_CERT_PATH = / home / baeldung / .docker / certs export DOCKER_CONFIG = / home / baeldung / .docker / export DOCKER_TLS_VERIFY = 1 export DOCKER_HOST = tcp: //docker.baeldung.com: 2376

4. Containerbeheer

De API biedt ons een scala aan keuzes op het gebied van containerbeheer. Laten we ze allemaal eens bekijken.

4.1. Lijst met containers

Nu we een verbinding hebben, kunnen we alle actieve containers op de Docker-host weergeven:

Lijst met containers = dockerClient.listContainersCmd (). Exec ();

Op voorwaarde dat het tonen van de lopende containers niet aanspreekt, kunnen we gebruik maken van de geboden mogelijkheden om containers te bevragen.

In dit geval geven we containers weer met de status "verlaten":

Lijstcontainers = dockerClient.listContainersCmd () .withShowSize (true) .withShowAll (true) .withStatusFilter ("exited"). Exec ()

Het is een equivalent van:

$ docker ps -a -s -f status = verlaten # of $ docker container ls -a -s -f status = verlaten

4.2. Maak een container

Het maken van een container wordt geserveerd met de createContainerCmd methode. We kunnen een complexere aangifte doen gebruik makend vande beschikbare methoden beginnend met de “met" voorvoegsel.

Laten we aannemen dat we een havenarbeidercreëren opdracht voor het definiëren van een hostafhankelijke MongoDB-container die intern luistert op poort 27017:

$ docker create --name mongo \ --hostname = baeldung \ -e MONGO_LATEST_VERSION = 3.6 \ -p 9999: 27017 \ -v / Users / baeldung / mongo / data / db: / data / db \ mongo: 3.6 --bind_ip_all

We kunnen dezelfde container samen met zijn configuraties programmatisch opstarten:

CreateContainerResponse container = dockerClient.createContainerCmd ("mongo: 3.6") .withCmd ("- bind_ip_all") .withName ("mongo") .withHostName ("baeldung") .withEnv ("MONGO_LATEST_VERSION = 3.6"). PortwithPort. parse ("9999: 27017")) .withBinds (Bind.parse ("/ Users / baeldung / mongo / data / db: / data / db")). exec ();

4.3. Start, stop en dood een container

Zodra we de container hebben gemaakt, kunnen we deze starten, stoppen en doden met respectievelijk naam of id:

dockerClient.startContainerCmd (container.getId ()). exec (); dockerClient.stopContainerCmd (container.getId ()). exec (); dockerClient.killContainerCmd (container.getId ()). exec ();

4.4. Inspecteer een container

De inspectContainerCmd methode duurt een Draad argument dat de naam of id van een container aangeeft. Met behulp van deze methode kunnen we de metadata van een container rechtstreeks observeren:

InspectContainerResponse container = dockerClient.inspectContainerCmd (container.getId ()). Exec ();

4.5. Maak een momentopname van een container

Net als bij de docker vastleggen opdracht, kunnen we een nieuwe afbeelding maken met behulp van de commitCmd methode.

In ons voorbeeld is het scenario, hebben we eerder een alpine: 3.6-container uitgevoerd waarvan de id is "3464bb547f88" en geïnstalleerd git daar bovenop.

Nu willen we een nieuwe momentopname van een afbeelding maken vanuit de container:

String snapshotId = dockerClient.commitCmd ("3464bb547f88") .withAuthor ("Baeldung <[email protected]>") .withEnv ("SNAPSHOT_YEAR = 2018") .withMessage ("add git support") .withCmd ("git", " version ") .withRepository (" alpine ") .withTag (" 3.6.git "). exec ();

Sinds onze nieuwe afbeelding gebundeld met git blijft op de host, we kunnen het zoeken op de Docker-host:

$ docker afbeelding ls alpine --format "table {{.Repository}} {{.Tag}}" REPOSITORY TAG alpine 3.6.git

5. Beeldbeheer

Er zijn een paar toepasselijke opdrachten die we krijgen om beeldbewerkingen te beheren.

5.1. Lijst met afbeeldingen

Om alle beschikbare afbeeldingen, inclusief hangende afbeeldingen op de Docker-host weer te geven, moeten we een aanvraag indienen voor het listImagesCmd methode:

Lijst met afbeeldingen = dockerClient.listImagesCmd (). Exec ();

Als we twee afbeeldingen op onze Docker Host hebben, we zouden het Beeld objecten van hen tijdens runtime. De afbeeldingen die we zoeken zijn:

$ docker afbeelding ls --format "table {{.Repository}} {{.Tag}}" REPOSITORY TAG alpine 3.6 mongo 3.6

Daarnaast, om de tussenliggende afbeeldingen te zien, moeten we dit expliciet aanvragen:

Lijst afbeeldingen = dockerClient.listImagesCmd () .withShowAll (true) .exec ();

Als alleen de bungelende afbeeldingen worden weergegeven, is de metDanglingFilter methode moet worden overwogen:

Lijst afbeeldingen = dockerClient.listImagesCmd () .withDanglingFilter (true) .exec ();

5.2. Bouw een afbeelding

Laten we ons concentreren op de manier om een ​​afbeelding te bouwen met behulp van de API. De buildImageCmd methode bouwt Docker-images van een Dockerfile. In ons project hebben we al een Dockerfile die een Alpine-image geeft met geïnstalleerde git:

FROM alpine: 3.6 RUN apk --update add git openssh && \ rm -rf / var / lib / apt / lists / * && \ rm / var / cache / apk / * ENTRYPOINT ["git"] CMD ["--help "]

De nieuwe afbeelding wordt gemaakt zonder cache te gebruiken en voordat het bouwproces wordt gestart, zal de Docker-engine in elk geval proberen de nieuwere versie van alpine: 3.6. Als alles goed gaat, zouden we uiteindelijk de afbeelding met de opgegeven naam moeten zien,alpine: git:

String imageId = dockerClient.buildImageCmd () .withDockerfile (nieuw bestand ("pad / naar / Dockerfile")) .withPull (true) .withNoCache (true) .withTag ("alpine: git") .exec (nieuw BuildImageResultCallback ()) .awaitImageId ();

5.3. Inspecteer een afbeelding

We kunnen de low-level informatie over een afbeelding inspecteren dankzij de inspectImageCmd methode:

InspectImageResponse afbeelding = dockerClient.inspectImageCmd ("161714540c41"). Exec ();

5.4. Tag een afbeelding

Het toevoegen van een tag aan onze afbeelding is vrij eenvoudig met de havenarbeiderlabel commando, dus de API is geen uitzondering. We kunnen dezelfde intentie uitvoeren met de tagImageCmd methode ook. Om een ​​Docker-afbeelding te taggen met id 161714540c41 in de baeldung / alpine repository met git:

String imageId = "161714540c41"; String repository = "baeldung / alpine"; String tag = "git"; dockerClient.tagImageCmd (imageId, repository, tag) .exec ();

We zouden de nieuw gemaakte afbeelding vermelden, en daar is het:

$ docker afbeelding ls --format "table {{.Repository}} {{.Tag}}" REPOSITORY TAG baeldung / alpine git

5.5. Push een afbeelding

Voordat een image naar een registerservice wordt verzonden, moet de docker-client worden geconfigureerd om samen te werken met de service, omdat het werken met registers vooraf moet worden geverifieerd.

Omdat we aannemen dat de client is geconfigureerd met Docker Hub, kunnen we het baeldung / alpine afbeelding naar het baeldung DockerHub-account:

dockerClient.pushImageCmd ("baeldung / alpine") .withTag ("git") .exec (nieuw PushImageResultCallback ()) .awaitCompletion (90, TimeUnit.SECONDS);

We moeten ons houden aan de duur van het proces. In het voorbeeld we wachten 90 seconden.

5.6. Trek een afbeelding

Om afbeeldingen van registry services te downloaden, maken we gebruik van de pullImageCmd methode. Bovendien, als de afbeelding wordt opgehaald uit een privéregister, moet de klant onze inloggegevens kennen, anders eindigt het proces met een fout. Hetzelfde als het ophalen van een afbeelding, specificeren we een callback samen met een vaste periode om een ​​afbeelding op te halen:

dockerClient.pullImageCmd ("baeldung / alpine") .withTag ("git") .exec (nieuw PullImageResultCallback ()) .awaitCompletion (30, TimeUnit.SECONDS);

Om te controleren of de genoemde afbeelding op de Docker-host bestaat nadat deze is opgehaald:

$ docker afbeeldingen baeldung / alpine --format "table {{.Repository}} {{.Tag}}" REPOSITORY TAG baeldung / alpine git

5.7. Verwijder een afbeelding

Een andere eenvoudige functie onder de rest is de removeImageCmd methode. We kunnen een afbeelding met zijn korte of lange ID verwijderen:

dockerClient.removeImageCmd ("beaccc8687ae"). exec ();

5.8. Zoek in het register

Om een ​​afbeelding van Docker Hub te zoeken, wordt de client geleverd met het searchImagesCmd methode met een String-waarde die een term aangeeft. Hier verkennen we afbeeldingen die verband houden met een naam die ‘Java' in Docker Hub:

Lijstitems = dockerClient.searchImagesCmd ("Java"). Exec ();

De uitvoer retourneert de eerste 25 gerelateerde afbeeldingen in een lijst met SearchItem voorwerpen.

6. Volumebeheer

Als Java-projecten moeten communiceren met Docker voor volumes, moeten we ook rekening houden met deze sectie. In het kort kijken we naar de fundamentele technieken van volumes die worden geleverd door de Docker Java API.

6.1. Lijst met volumes

Alle beschikbare volumes, inclusief met en zonder naam, worden vermeld met:

ListVolumesResponse volumesResponse = dockerClient.listVolumesCmd (). Exec (); Lijstvolumes = volumesResponse.getVolumes ();

6.2. Inspecteer een volume

De inspectVolumeCmd methode is het formulier om de gedetailleerde informatie van een volume weer te geven. We inspecteren het volume door de korte id op te geven:

InspectVolumeResponse volume = dockerClient.inspectVolumeCmd ("0220b87330af5"). Exec ();

6.3. Maak een volume

De API biedt twee verschillende opties om een ​​volume te maken. De niet-arg createVolumeCmd methode maakt een volume aan waar de naam wordt gegeven door Docker:

CreateVolumeResponse unnamedVolume = dockerClient.createVolumeCmd (). Exec ();

In plaats van het standaardgedrag te gebruiken, wordt de hulpmethode aangeroepen withName laat ons een naam voor een volume instellen:

CreateVolumeResponse namedVolume = dockerClient.createVolumeCmd (). WithName ("myNamedVolume"). Exec ();

6.4. Verwijder een volume

We kunnen intuïtief een volume van de Docker-host verwijderen met behulp van de removeVolumeCmd methode. Het is belangrijk om op te merken dat we een volume niet kunnen verwijderen als het in gebruik is vanuit een container. We verwijderen het volume, myNamedVolume, uit de volumelijst:

dockerClient.removeVolumeCmd ("myNamedVolume"). exec ();

7. Netwerkbeheer

Onze laatste sectie gaat over het beheren van netwerktaken met de API.

7.1. Lijst netwerken

We kunnen de lijst met netwerkeenheden weergeven met een van de conventionele API-methoden, te beginnen met lijst:

Lijst netwerken = dockerClient.listNetworksCmd (). Exec ();

7.2. Creëer een netwerk

Het equivalent van de docker-netwerk maken commando wordt uitgevoerd met de createNetworkCmd methode. Als we een dertig-partij of een aangepaste netwerkdriver hebben, is de met Driver methode kan ze accepteren naast de ingebouwde stuurprogramma's. Laten we in ons geval een bridge-netwerk maken met de naam baeldung:

CreateNetworkResponse networkResponse = dockerClient.createNetworkCmd () .withName ("baeldung") .withDriver ("bridge"). Exec ();

Bovendien lost het maken van een netwerkeenheid met de standaardinstellingen het probleem niet op, we kunnen andere hulpmethoden toepassen om een ​​geavanceerd netwerk te bouwen. Dus, om het standaardsubnetwerk te overschrijven met een aangepaste waarde:

CreateNetworkResponse networkResponse = dockerClient.createNetworkCmd () .withName ("baeldung") .withIpam (nieuwe Ipam () .withConfig (nieuwe Config () .withSubnet ("172.36.0.0/16") .withIpRange ("172.36.5.0/24" ))) .withDriver ("bridge"). exec ();

Dezelfde opdracht die we kunnen uitvoeren met de havenarbeider commando is:

$ docker network create \ --subnet = 172.36.0.0 / 16 \ --ip-range = 172.36.5.0 / 24 \ baeldung

7.3. Inspecteer een netwerk

Het weergeven van de details op laag niveau van een netwerk wordt ook behandeld in de API:

Netwerknetwerk = dockerClient.inspectNetworkCmd (). WithNetworkId ("baeldung"). Exec ();

7.4. Verwijder een netwerk

We kunnen een netwerkeenheid met zijn naam of id veilig verwijderen met behulp van de removeNetworkCmd methode:

dockerClient.removeNetworkCmd ("baeldung"). exec ();

8. Conclusie

In deze uitgebreide tutorial hebben we de verschillende functies van het Java Docker API-client, samen met verschillende implementatiebenaderingen voor implementatie- en beheerscenario's.

Alle voorbeelden die in dit artikel worden geïllustreerd, zijn te vinden op GitHub.