Bagikan melalui


Kontainer layanan

Azure DevOps Services

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 sistem pipeline Anda bergantung pada. 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 dalam kontainer.

Persyaratan

  • Kontainer layanan harus menentukan CMD atau ENTRYPOINT. Pipeline menjalankan 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 menjalankan kontainer.

Catatan

Kontainer layanan tidak didukung dalam alur Klasik.

Pekerjaan kontainer tunggal

Contoh definisi alur YAML berikut mengilustrasikan satu tugas 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 kontainer nginx dan buildpack-deps dari Docker Hub lalu memulai kontainer tersebut. Kontainer-kontainer tersebut terhubung dalam jaringan sehingga kontainer tersebut dapat saling menjangkau dengan menggunakan services namanya.

Dari dalam kontainer pekerjaan ini, nama host nginx diarahkan 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 tugas tidak berjalan dalam kontainer, tidak ada penyelesaian 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

Pelabuhan

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 berbentuk <hostPort>:<containerPort> atau <containerPort> dengan /<protocol> opsional 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 dengan format agent.services.<serviceName>.ports.<port> agar pekerjaan ini dapat mengakses port. Misalnya, agent.services.redis.ports.6379 berfungsi sebagai port yang ditetapkan secara acak pada mesin host.

Volume

Volume berguna untuk berbagi data antar layanan atau untuk menyimpan data di antara beberapa eksekusi pekerjaan. Anda menentukan volume mount sebagai array volumes dalam bentuk <source>:<destinationPath>, di mana <source> dapat berupa volume bernama atau jalur absolut pada mesin host, dan <destinationPath> adalah jalur absolut dalam kontainer. Volume bisa dinamai sebagai volume Docker, volume anonim Docker, atau bind mounts 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 menggunakan 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 jalur /__w/1/s/ 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