GNU/Linux >> Belajar Linux >  >> Panels >> Docker

Cara Menyebarkan Layanan Mikro dengan Docker

Apa itu Layanan Mikro?

Layanan mikro adalah arsitektur yang semakin populer untuk membangun aplikasi skala besar. Daripada menggunakan satu basis kode monolitik, aplikasi dipecah menjadi kumpulan komponen yang lebih kecil yang disebut layanan mikro. Pendekatan ini menawarkan beberapa manfaat, termasuk kemampuan untuk menskalakan layanan mikro individu, menjaga basis kode lebih mudah dipahami dan diuji, dan memungkinkan penggunaan bahasa pemrograman, database, dan alat lain yang berbeda untuk setiap layanan mikro.

Docker adalah alat yang sangat baik untuk mengelola dan menerapkan layanan mikro. Setiap layanan mikro dapat dipecah lebih lanjut menjadi proses yang berjalan di wadah Docker terpisah, yang dapat ditentukan dengan file konfigurasi Dockerfiles dan Docker Compose. Dikombinasikan dengan alat penyediaan seperti Kubernetes, setiap layanan mikro kemudian dapat dengan mudah digunakan, diskalakan, dan dikolaborasikan oleh tim pengembang. Menentukan lingkungan dengan cara ini juga memudahkan untuk menautkan layanan mikro bersama-sama untuk membentuk aplikasi yang lebih besar.

Panduan ini menunjukkan cara membuat dan menerapkan layanan mikro contoh menggunakan Docker dan Docker Compose.

Sebelum Anda Mulai

  1. Jika Anda belum melakukannya, buat akun Linode dan Compute Instance. Lihat panduan Memulai Linode dan Membuat Instans Komputasi.

  2. Ikuti panduan Menyiapkan dan Mengamankan Instans Komputasi untuk memperbarui sistem Anda. Anda mungkin juga ingin mengatur zona waktu, mengkonfigurasi nama host Anda, membuat akun pengguna terbatas, dan memperkuat akses SSH.

Catatan Panduan ini ditulis untuk pengguna non-root. Perintah yang memerlukan hak istimewa yang lebih tinggi diawali dengan sudo . Jika Anda tidak terbiasa dengan sudo perintah, Anda dapat memeriksa panduan Pengguna dan Grup kami.

Instal Docker

Untuk menginstal Docker CE (Edisi Komunitas), ikuti petunjuk dalam salah satu panduan di bawah ini:

  • Menginstal dan Menggunakan Docker di Ubuntu dan Debian

  • Memasang dan Menggunakan Docker di CentOS dan Fedora

Untuk petunjuk lengkap tentang distribusi Linux lainnya, lihat bagian Instal Docker Engine dari dokumentasi resmi Docker.

Instal Docker Compose

  1. Unduh versi terbaru Docker Compose. Periksa halaman rilis dan ganti 1.25.4 pada perintah di bawah ini dengan versi yang ditandai sebagai Rilis terbaru :

     sudo curl -L https://github.com/docker/compose/releases/download/1.25.4/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
    
  2. Setel izin file:

     sudo chmod +x /usr/local/bin/docker-compose
    

Siapkan Lingkungan

Bagian ini menggunakan Dockerfiles untuk mengonfigurasi image Docker. Untuk informasi selengkapnya tentang sintaks Dockerfile dan praktik terbaik, lihat panduan Cara Menggunakan Dockerfiles kami dan panduan Praktik Terbaik Dockerfile Docker.

  1. Buat direktori untuk layanan mikro:

     mkdir flask-microservice
    
  2. Buat struktur direktori untuk komponen layanan mikro dalam direktori baru:

     cd flask-microservice
     mkdir nginx postgres web
    

NGINX

  1. Di dalam nginx . yang baru subdirektori, buat file Docker untuk gambar NGINX:

    File:nginx /Dockerfile
    1
    2
    
    from nginx:alpine
    COPY nginx.conf /etc/nginx/nginx.conf
  2. Buat nginx.conf direferensikan di Dockerfile:

    File:/ nginx/nginx.conf
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    
    user  nginx;
    worker_processes 1;
    error_log  /dev/stdout info;
    error_log off;
    pid        /var/run/nginx.pid;
    
    events {
        worker_connections  1024;
        use epoll;
        multi_accept on;
    }
    
    http {
        include       /etc/nginx/mime.types;
        default_type  application/octet-stream;
    
        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                          '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for"';
    
        access_log  /dev/stdout main;
        access_log off;
        keepalive_timeout 65;
        keepalive_requests 100000;
        tcp_nopush on;
        tcp_nodelay on;
    
        server {
            listen 80;
            proxy_pass_header Server;
    
            location / {
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
    
                # app comes from /etc/hosts, Docker added it for us!
                proxy_pass http://flaskapp:8000/;
            }
        }
    }

PostgreSQL

Gambar PostgreSQL untuk layanan mikro ini akan menggunakan postgresql resmi image di Docker Hub, jadi tidak diperlukan Dockerfile.

Di postgres subdirektori, buat init.sql berkas:

File:postgres /init.sql
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SET check_function_bodies = false;
SET client_min_messages = warning;
SET row_security = off;
CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog;
COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language';
SET search_path = public, pg_catalog;
SET default_tablespace = '';
SET default_with_oids = false;
CREATE TABLE visitors (
    site_id integer,
    site_name text,
    visitor_count integer
);

ALTER TABLE visitors OWNER TO postgres;
COPY visitors (site_id, site_name, visitor_count) FROM stdin;
1 	linodeexample.com  	0
\.
Hati-hati Di Baris 22 dari init.sql , pastikan editor teks Anda tidak mengonversi tab menjadi spasi. Aplikasi tidak akan berfungsi tanpa tab di antara entri di baris ini.

Web

web gambar akan menampung contoh aplikasi Flask. Tambahkan file berikut ke web direktori untuk menyiapkan aplikasi:

  1. Buat .python-version file untuk menentukan penggunaan Python 3.6:

     echo "3.6.0" >> web/.python-version
    
  2. Buat Dockerfile untuk web gambar:

    File:web /Dockerfile
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    
    from python:3.6.2-slim
    RUN groupadd flaskgroup && useradd -m -g flaskgroup -s /bin/bash flask
    RUN echo "flask ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
    RUN mkdir -p /home/flask/app/web
    WORKDIR /home/flask/app/web
    COPY requirements.txt /home/flask/app/web
    RUN pip install --no-cache-dir -r requirements.txt
    RUN chown -R flask:flaskgroup /home/flask
    USER flask
    ENTRYPOINT ["/usr/local/bin/gunicorn", "--bind", ":8000", "linode:app", "--reload", "--workers", "16"]
  3. Buat web/linode.py dan tambahkan contoh skrip aplikasi:

    File:web /linode.py
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    
    from flask import Flask
    import logging
    import psycopg2
    import redis
    import sys
    
    app = Flask(__name__)
    cache = redis.StrictRedis(host='redis', port=6379)
    
    # Configure Logging
    app.logger.addHandler(logging.StreamHandler(sys.stdout))
    app.logger.setLevel(logging.DEBUG)
    
    def PgFetch(query, method):
    
        # Connect to an existing database
        conn = psycopg2.connect("host='postgres' dbname='linode' user='postgres' password='linode123'")
    
        # Open a cursor to perform database operations
        cur = conn.cursor()
    
        # Query the database and obtain data as Python objects
        dbquery = cur.execute(query)
    
        if method == 'GET':
            result = cur.fetchone()
        else:
            result = ""
    
        # Make the changes to the database persistent
        conn.commit()
    
        # Close communication with the database
        cur.close()
        conn.close()
        return result
    
    @app.route('/')
    def hello_world():
        if cache.exists('visitor_count'):
            cache.incr('visitor_count')
            count = (cache.get('visitor_count')).decode('utf-8')
            update = PgFetch("UPDATE visitors set visitor_count = " + count + " where site_id = 1;", "POST")
        else:
            cache_refresh = PgFetch("SELECT visitor_count FROM visitors where site_id = 1;", "GET")
            count = int(cache_refresh[0])
            cache.set('visitor_count', count)
            cache.incr('visitor_count')
            count = (cache.get('visitor_count')).decode('utf-8')
        return 'Hello Linode!  This page has been viewed %s time(s).' % count
    
    @app.route('/resetcounter')
    def resetcounter():
        cache.delete('visitor_count')
        PgFetch("UPDATE visitors set visitor_count = 0 where site_id = 1;", "POST")
        app.logger.debug("reset visitor count")
        return "Successfully deleted redis and postgres counters"
  4. Tambahkan requirements.txt file dengan dependensi Python yang diperlukan:

    File:web /requirements.txt
    1
    2
    3
    4
    
    flask
    gunicorn
    psycopg2-binary
    redis

Tulisan Docker

Docker Compose akan digunakan untuk menentukan koneksi antara container dan pengaturan konfigurasinya.

Buat docker-compose.yml file di flask-microservice direktori dan tambahkan berikut ini:

File:buruh pelabuhan -compose.yml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
version: '3'
services:
 # Define the Flask web application
 flaskapp:

   # Build the Dockerfile that is in the web directory
   build: ./web

   # Always restart the container regardless of the exit status; try and restart the container indefinitely
   restart: always

   # Expose port 8000 to other containers (not to the host of the machine)
   expose:
     - "8000"

   # Mount the web directory within the container at /home/flask/app/web
   volumes:
     - ./web:/home/flask/app/web

   # Don't create this container until the redis and postgres containers (below) have been created
   depends_on:
     - redis
     - postgres

   # Link the redis and postgres containers together so they can talk to one another
   links:
     - redis
     - postgres

   # Pass environment variables to the flask container (this debug level lets you see more useful information)
   environment:
     FLASK_DEBUG: 1

   # Deploy with three replicas in the case one of the containers fails (only in Docker Swarm)
   deploy:
     mode: replicated
     replicas: 3

 # Define the redis Docker container
 redis:

   # use the redis:alpine image: https://hub.docker.com/_/redis/
   image: redis:alpine
   restart: always
   deploy:
     mode: replicated
     replicas: 3

 # Define the redis NGINX forward proxy container
 nginx:

   # build the nginx Dockerfile: http://bit.ly/2kuYaIv
   build: nginx/
   restart: always

   # Expose port 80 to the host machine
   ports:
     - "80:80"
   deploy:
     mode: replicated
     replicas: 3

   # The Flask application needs to be available for NGINX to make successful proxy requests
   depends_on:
     - flaskapp

 # Define the postgres database
 postgres:
   restart: always
   # Use the postgres alpine image: https://hub.docker.com/_/postgres/
   image: postgres:alpine

   # Mount an initialization script and the persistent postgresql data volume
   volumes:
     - ./postgres/init.sql:/docker-entrypoint-initdb.d/init.sql
     - ./postgres/data:/var/lib/postgresql/data

   # Pass postgres environment variables
   environment:
     POSTGRES_PASSWORD: linode123
     POSTGRES_DB: linode

   # Expose port 5432 to other Docker containers
   expose:
     - "5432"

Uji Layanan Mikro

  1. Gunakan Docker Compose untuk membuat semua gambar dan memulai layanan mikro:

    cd flask-microservice/ && docker-compose up
    

    Anda akan melihat semua layanan dimulai di terminal Anda.

  2. Buka jendela terminal baru dan buat permintaan ke aplikasi contoh:

    curl localhost
    
    Hello Linode! This page has been viewed 1 time(s).
  3. Setel ulang penghitung klik halaman:

    curl localhost/resetcounter
    
    Successfully deleted redis and postgres counters
  4. Kembali ke jendela terminal tempat Docker Compose mulai melihat log keluar standar:

    flaskapp_1  | DEBUG in linode [/home/flask/app/web/linode.py:56]:
    flaskapp_1  | reset visitor count

Menggunakan Container dalam Produksi:Praktik Terbaik

Kontainer yang digunakan dalam contoh layanan mikro dimaksudkan untuk menunjukkan praktik terbaik berikut untuk menggunakan kontainer dalam produksi:

Wadah harus:

  1. Efemeral :Seharusnya mudah untuk menghentikan, menghancurkan, membangun kembali, dan menerapkan ulang container dengan penyiapan dan konfigurasi minimal.

    Layanan mikro Flask adalah contoh ideal untuk ini. Seluruh layanan mikro dapat dinaikkan atau diturunkan menggunakan Docker Compose. Tidak ada konfigurasi tambahan yang diperlukan setelah container berjalan, yang memudahkan untuk memodifikasi aplikasi.

  2. Sekali pakai :Idealnya, wadah tunggal apa pun dalam aplikasi yang lebih besar harus dapat gagal tanpa memengaruhi kinerja aplikasi. Menggunakan restart: on-failure opsi di docker-compose.yml file, serta memiliki jumlah replika, memungkinkan beberapa wadah dalam contoh layanan mikro gagal dengan baik saat masih melayani aplikasi web – tanpa penurunan ke pengguna akhir.

    Catatan Arahan jumlah replika hanya akan efektif bila konfigurasi ini diterapkan sebagai bagian dari aDocker Swarm, yang tidak tercakup dalam panduan ini.
  3. Cepat untuk memulai :Menghindari langkah penginstalan tambahan di file Docker, menghapus dependensi yang tidak diperlukan, dan membangun image target yang dapat digunakan kembali adalah tiga langkah terpenting dalam membuat aplikasi web yang memiliki waktu inisialisasi cepat di dalam Docker. Aplikasi contoh menggunakan Dockerfiles yang singkat, ringkas, dan telah dibuat sebelumnya untuk meminimalkan waktu inisialisasi.

  4. Cepat berhenti :Memvalidasi bahwa docker kill --signal=SIGINT {APPNAME} menghentikan aplikasi dengan anggun. Ini, bersama dengan kondisi restart dan kondisi replika, akan memastikan bahwa ketika container gagal, container akan dikembalikan online secara efisien.

  5. Ringan :Gunakan wadah dasar terkecil yang menyediakan semua utilitas yang diperlukan untuk membangun dan menjalankan aplikasi Anda. Banyak gambar Docker didasarkan pada Alpine Linux, distribusi Linux yang ringan dan sederhana yang hanya membutuhkan 5MB dalam gambar Docker. Menggunakan distro kecil menghemat jaringan dan overhead operasional, dan sangat meningkatkan kinerja container. Aplikasi contoh menggunakan gambar alpine jika berlaku (NGINX, Redis, dan PostgreSQL), dan gambar dasar python-slim untuk aplikasi Gunicorn / Flask.

  6. Tanpa kewarganegaraan :Karena bersifat sementara, container biasanya tidak boleh mempertahankan statusnya. Status aplikasi harus disimpan dalam volume data persisten yang terpisah, seperti halnya penyimpanan data PostgreSQL layanan mikro. Penyimpanan nilai kunci Redis memang memelihara data di dalam wadah, tetapi data ini tidak penting untuk aplikasi; penyimpanan Redis akan gagal kembali dengan anggun ke database jika wadah tidak dapat merespons.

  7. Portabel :Semua dependensi aplikasi yang diperlukan untuk runtime container harus tersedia secara lokal. Semua contoh dependensi layanan mikro dan skrip startup disimpan di direktori untuk setiap komponen. Ini dapat diperiksa ke dalam kontrol versi, sehingga memudahkan untuk berbagi dan menerapkan aplikasi.

  8. Modular :Setiap wadah harus memiliki satu tanggung jawab dan satu proses. Dalam layanan mikro ini, setiap proses utama (NGINX, Python, Redis, dan PostgreSQL) dikerahkan dalam wadah terpisah.

  9. Mencatat Log :Semua kontainer harus masuk ke STDOUT . Keseragaman ini memudahkan untuk melihat log untuk semua proses dalam satu aliran.

  10. Tangguh :Aplikasi contoh memulai ulang wadahnya jika keluar karena alasan apa pun. Ini membantu memberikan aplikasi Dockerized Anda ketersediaan dan kinerja yang tinggi, bahkan selama periode pemeliharaan.

Informasi Lebih Lanjut

Anda mungkin ingin berkonsultasi dengan sumber daya berikut untuk informasi tambahan tentang topik ini. Meskipun ini disediakan dengan harapan dapat bermanfaat, harap perhatikan bahwa kami tidak dapat menjamin keakuratan atau ketepatan waktu materi yang dihosting secara eksternal.

  • Repositori Github untuk Contoh Layanan Mikro
  • Menggunakan Container untuk Membangun Arsitektur Layanan Mikro

Docker
  1. Cara Menyebarkan Modsecurity dengan Nginx di Ubuntu 20.04 LTS

  2. Cara Menginstal Jenkins dengan Docker

  3. Cara Menyebarkan PostgreSQL sebagai Wadah Docker

  1. Cara Menyebarkan Server DNS Dinamis dengan Docker di Debian 10

  2. Cara Menyebarkan Aplikasi dengan Rancher

  3. Cara Menyebarkan Wadah nginx dengan Docker di Linode

  1. Cara Menyebarkan Proksi Terbalik NGINX di Docker

  2. Cara Menyebarkan dan Mengelola MongoDB dengan Docker

  3. Cara Menyebarkan Aplikasi React ke Produksi Menggunakan Docker dan NGINX dengan Proksi API