Bagikan melalui


Kontainer layanan

Azure DevOps

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

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

Persyaratan

  • Kontainer layanan harus menentukan CMD atau ENTRYPOINT. Alur berjalan docker run untuk kontainer yang disediakan tanpa argumen apa pun.

  • Azure Pipelines dapat menjalankan kontainer Linux atau Windows. Anda dapat menggunakan kumpulan kontainer Ubuntu yang dihosting untuk kontainer Linux atau kumpulan Windows yang dihosting untuk kontainer Windows. Kumpulan macOS yang dihosting tidak mendukung kontainer yang sedang berjalan.

Catatan

Kontainer layanan tidak didukung di alur Klasik.

Pekerjaan kontainer tunggal

Contoh definisi alur YAML berikut menunjukkan satu 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 sebelumnya mengambil nginx kontainer dan buildpack-deps dari Docker Hub lalu 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 dengan menggunakan jaringan Docker. Semua kontainer di jaringan secara otomatis mengekspos semua port satu sama lain.

Pekerjaan nonkontainer tunggal

Anda juga dapat menggunakan kontainer layanan tanpa kontainer pekerjaan, seperti dalam contoh berikut.

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 sebelumnya memulai kontainer terbaru nginx . Karena pekerjaan tidak berjalan dalam kontainer, tidak ada resolusi nama otomatis. Sebagai gantinya, Anda dapat menjangkau layanan dengan menggunakan localhost. Contohnya secara eksplisit menyediakan 8080:80 port.

Pendekatan alternatif adalah membiarkan port acak ditetapkan secara dinamis pada runtime. Anda kemudian dapat mengakses port dinamis ini dengan menggunakan variabel. Variabel-variabel ini mengambil formulir: agent.services.<serviceName>.ports.<port>. Dalam skrip Bash, Anda dapat mengakses variabel dengan menggunakan lingkungan proses.

Dalam contoh sebelumnya, redis ditetapkan 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 Anda memanggil sumber daya kontainer atau kontainer sebaris, Anda dapat menentukan array ports untuk diekspos pada kontainer, seperti dalam contoh berikut.

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, ports diperlukan untuk mengakses layanan. Port mengambil formulir <hostPort>:<containerPort> atau hanya <containerPort> dengan opsional /<protocol> di akhir. Misalnya, 6379/tcp 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 pekerjaan dapat mengakses port. 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 menyimpan data di antara beberapa eksekusi pekerjaan. Anda menentukan pemasangan volume sebagai array volumes formulir <source>:<destinationPath>, di mana <source> dapat berupa volume bernama atau jalur absolut pada komputer host, dan <destinationPath> merupakan jalur absolut dalam kontainer. Volume dapat diberi nama volume Docker, volume Docker anonim, atau pemasangan ikat pada host.

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

Catatan

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

Opsi startup

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

Pemeriksaan kondisi

Jika ada kontainer layanan yang menentukan HEALTHCHECK, agen dapat secara opsional menunggu hingga kontainer sehat sebelum menjalankan pekerjaan.

Beberapa kontainer dengan contoh layanan

Contoh berikut memiliki kontainer web Django Python yang terhubung ke kontainer database PostgreSQL dan MySQL.

  • Database PostgreSQL adalah database utama, dan kontainernya diberi 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 menginstal dependensi dan kemudian pengujian Django berjalan.

Untuk menyiapkan contoh kerja, Anda memerlukan situs Django yang disiapkan dengan dua database. Contoh mengasumsikan file manage.py Anda ada di direktori akar dan proyek Django Anda juga berada dalam direktori tersebut. Jika tidak, 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