Kontainer layanan

Azure DevOps

Jika alur Anda memerlukan dukungan satu atau beberapa layanan, dalam banyak kasus Anda mungkin ingin membuat, menyambungkan, dan membersihkan setiap layanan berdasarkan per pekerjaan. Misalnya, alur dapat menjalankan pengujian integrasi yang memerlukan akses ke database dan cache memori. Database dan cache memori perlu dibuat baru untuk setiap pekerjaan dalam alur.

Kontainer menyediakan cara yang sederhana dan portabel untuk menjalankan layanan yang bergantung pada alur Anda. Kontainer layanan memungkinkan Anda untuk secara otomatis membuat, membuat jaringan, dan mengelola siklus hidup layanan dalam kontainer Anda. Setiap kontainer layanan hanya dapat diakses oleh pekerjaan yang membutuhkannya. Kontainer layanan dapat digunakan untuk semua jenis pekerjaan, tetapi paling sering digunakan untuk pekerjaan kontainer.

Persyaratan

Kontainer layanan harus menentukan CMD atau ENTRYPOINT. Alur akan berjalan docker run untuk kontainer yang disediakan tanpa argumen tambahan.

Azure Pipelines dapat menjalankan Kontainer Linux atau Windows. Gunakan Ubuntu yang dihosting untuk kontainer Linux, atau kumpulan Kontainer Windows yang Dihosting untuk kontainer Windows. (Kumpulan macOS yang dihosting tidak mendukung kontainer yang sedang berjalan.)

Pekerjaan kontainer tunggal

Contoh sederhana menggunakan pekerjaan kontainer:

resources:
  containers:
  - container: my_container
    image: buildpack-deps:focal
  - container: nginx
    image: nginx


pool:
  vmImage: 'ubuntu-latest'

container: my_container
services:
  nginx: nginx

steps:
- script: |
    curl nginx
  displayName: Show that nginx is running

Alur ini mengambil nginx kontainer dan buildpack-deps dari Docker Hub dan kemudian memulai kontainer. Kontainer dijaring bersama sehingga mereka dapat menjangkau satu sama lain dengan services namanya.

Dari dalam kontainer pekerjaan ini, nginx nama host diselesaikan ke layanan yang benar menggunakan jaringan Docker. Semua kontainer di jaringan secara otomatis mengekspos semua port satu sama lain.

Pekerjaan tunggal

Anda juga dapat menggunakan kontainer layanan tanpa kontainer pekerjaan. Contoh sederhana:

resources:
  containers:
  - container: nginx
    image: nginx
    ports:
    - 8080:80
    env:
      NGINX_PORT: 80
  - container: redis
    image: redis
    ports:
    - 6379

pool:
  vmImage: 'ubuntu-latest'

services:
  nginx: nginx
  redis: redis

steps:
- script: |
    curl localhost:8080
    echo $AGENT_SERVICES_REDIS_PORTS_6379

Alur ini memulai kontainer terbaru nginx . Karena pekerjaan tidak berjalan dalam kontainer, tidak ada resolusi nama otomatis. Contoh ini menunjukkan bagaimana Anda dapat menjangkau layanan dengan menggunakan localhost. Dalam contoh di atas, kami menyediakan port secara eksplisit (misalnya, 8080:80).

Pendekatan alternatif adalah membiarkan port acak ditetapkan secara dinamis saat runtime. Anda kemudian dapat mengakses port dinamis ini dengan menggunakan variabel. Dalam skrip Bash, Anda dapat mengakses variabel dengan menggunakan lingkungan proses. Variabel-variabel ini mengambil formulir: agent.services.<serviceName>.ports.<port>. Dalam contoh di atas, redis diberi port acak yang tersedia pada host. Variabel agent.services.redis.ports.6379 berisi nomor port.

Beberapa pekerjaan

Kontainer layanan juga berguna untuk menjalankan langkah yang sama terhadap beberapa versi layanan yang sama. Dalam contoh berikut, langkah yang sama berjalan terhadap beberapa versi PostgreSQL.

resources:
  containers:
  - container: my_container
    image: ubuntu:22.04
  - container: pg15
    image: postgres:15
  - container: pg14
    image: postgres:14

pool:
  vmImage: 'ubuntu-latest'

strategy:
  matrix:
    postgres15:
      postgresService: pg15
    postgres14:
      postgresService: pg14

container: my_container

services:
  postgres: $[ variables['postgresService'] ]
steps:
- script: printenv

Port

Saat menentukan sumber daya kontainer atau kontainer sebaris, Anda dapat menentukan array ports untuk diekspos pada kontainer.

resources:
  containers:
  - container: my_service
    image: my_service:latest
    ports:
    - 8080:80
    - 5432

services:
  redis:
    image: redis
    ports:
    - 6379/tcp

Menentukan ports tidak diperlukan jika pekerjaan Anda berjalan dalam kontainer karena kontainer pada jaringan Docker yang sama secara otomatis mengekspos semua port satu sama lain secara default.

Jika pekerjaan Anda berjalan di host, maka ports diperlukan untuk mengakses layanan. Port mengambil formulir <hostPort>:<containerPort> atau hanya <containerPort>, dengan opsional /<protocol> di akhir, misalnya 6379/tcp untuk mengekspos tcp melalui port 6379, terikat ke port acak pada komputer host.

Untuk port yang terikat ke port acak pada komputer host, alur membuat variabel formulir agent.services.<serviceName>.ports.<port> sehingga dapat diakses oleh pekerjaan. Misalnya, agent.services.redis.ports.6379 menyelesaikan port yang ditetapkan secara acak pada komputer host.

Volume

Volume berguna untuk berbagi data antar layanan, atau untuk mempertahankan data di antara beberapa eksekusi pekerjaan.

Anda dapat menentukan pemasangan volume sebagai array .volumes Volume dapat diberi nama volume Docker, volume Docker anonim, atau pemasangan ikatan pada host.

services:
  my_service:
    image: myservice:latest
    volumes:
    - mydockervolume:/data/dir
    - /data/dir
    - /src/dir:/dst/dir

Volume mengambil formulir <source>:<destinationPath>, di mana <source> dapat berupa volume bernama atau jalur absolut pada komputer host, dan <destinationPath> merupakan jalur absolut dalam kontainer.

Catatan

Jika Anda menggunakan kumpulan kami yang dihosting, maka volume Anda tidak akan bertahan di antara pekerjaan karena komputer host dibersihkan setelah pekerjaan selesai.

Opsi lain

Kontainer layanan berbagi sumber daya kontainer yang sama dengan pekerjaan kontainer. Ini berarti Anda dapat menggunakan opsi tambahan yang sama.

Pemeriksaan kesehatan

Secara opsional, jika ada kontainer layanan yang menentukan HEALTHCHECK, agen menunggu hingga kontainer sehat sebelum menjalankan pekerjaan.

Beberapa kontainer dengan contoh layanan

Dalam contoh ini, ada kontainer web Django Python yang terhubung ke dua kontainer database - PostgreSQL dan MySQL. Database PostgreSQL adalah database utama dan kontainernya memiliki nama db. Kontainer db menggunakan volume /data/db:/var/lib/postgresql/data dan ada tiga variabel database yang diteruskan ke kontainer melalui env. Kontainer mysql menggunakan port 3306:3306 dan ada juga variabel database yang diteruskan melalui env. Kontainer web terbuka dengan port 8000. Dalam langkah-langkahnya, pip instal dependensi dan kemudian uji Django dijalankan. Jika Anda ingin menyiapkan contoh kerja, Anda memerlukan situs Django yang disiapkan dengan dua database. Contoh ini mengasumsikan file Anda manage.py berada di direktori akar dan proyek Django Anda berada dalam direktori tersebut. Anda mungkin perlu memperbarui /__w/1/s/ jalur di /__w/1/s/manage.py test.

resources:
  containers:
    - container: db
      image: postgres
      volumes:
          - '/data/db:/var/lib/postgresql/data'
      env:
        POSTGRES_DB: postgres
        POSTGRES_USER: postgres
        POSTGRES_PASSWORD: postgres
    - container: mysql
      image: 'mysql:5.7'
      ports:
         - '3306:3306'
      env:
        MYSQL_DATABASE: users
        MYSQL_USER: mysql
        MYSQL_PASSWORD: mysql
        MYSQL_ROOT_PASSWORD: mysql
    - container: web
      image: python
      volumes:
      - '/code'
      ports:
        - '8000:8000'

pool:
  vmImage: 'ubuntu-latest'

container: web
services:
  db: db
  mysql: mysql

steps:
    - script: |
        pip install django
        pip install psycopg2
        pip install mysqlclient
      displayName: set up django
    - script: |
          python /__w/1/s/manage.py test