12/08/2018, 16:15

Docker intro

Docker cho phép chúng ta đóng gói phần mềm thành các các đơn vị chuẩn cho việc phát triển, vận chuyển cũng như deployment. Tất cả mọi thứ cần để cho ứng dụng chạy sẽ được include, Docker image chứa chứa code, thư viện cho hệ thống và tất cả mọi thứ cần chạy trên server. Sự khác nhau giữa Docker ...

Docker cho phép chúng ta đóng gói phần mềm thành các các đơn vị chuẩn cho việc phát triển, vận chuyển cũng như deployment. Tất cả mọi thứ cần để cho ứng dụng chạy sẽ được include, Docker image chứa chứa code, thư viện cho hệ thống và tất cả mọi thứ cần chạy trên server.

Sự khác nhau giữa Docker và Vitural machine.

Có rất nhiều các phần mềm cho phép bạn chạy VM như VirtualBox, VMWare … chúng cho phép bạn xây dựng các service độc lập nhưng nó cũng có một số hạn chế Giả sử bạn 1 GB contianer image, nếu bạn muốn sử dụng toàn bộ VM bạn cần phải cần tới (1GB * số lượng máy ảo mà bạn cần), Nhưng với Docker thì không Docker có cơ chế sharing 1GB đó giữa các container tối ưu được không gian bộ nhớ cho hệ thống.
Về mặt tốc độ thì để khởi động toàn bộ hệ thống máy ảo VMs sẽ tốn nhiều time đến vài phút trong khi với Docker chỉ mất vài giây.

Giả sử bạn có một ứng dụng Python, điều đầu tiên cần làm là cài đặt môi trường chạy trên máy nhưng bạn chỉ cần chạy ứng dụng đó chứ không cần cài đặt mọi thứ trên local. Docker sẽ giải quyết vấn đề này, bạn có thể sử dụng image Python runtime, mà không cần cài cắm gì, sau đó có thể include Python image cùng với app code của bạn. Những portalbe images đôi khi được gọi là Dockerfile Dockerfile sẽ định nghĩa những gì cần thiết bên trong container. Truy cập vào tài nguyên như network interface và disk drive được ảo hoá bên trong môi trường này (nó được tách biệt với phần còn lại của hệ thống, nên bạn có thể map port ra bên ngoài)

Dockerfile

Tạo ra một file name Dockerfile bên trong thư mục mới của bạn với nội dung dưới đây

# Use an official Python runtime as a parent image
FROM python:2.7-slim

# Set the working directory to /app
WORKDIR /app

# Copy the current directory contents into the container at /app
ADD . /app

# Install any needed packages specified in requirements.txt
RUN pip install -r requirements.txt

# Make port 80 available to the world outside this container
EXPOSE 80

# Define environment variable
ENV NAME World

# Run app.py when the container launches
CMD ["python", "app.py"]

Dockerfile này sẽ tham chiếu tới 2 file và app.py và requirement.text

requirement.text

Flask
Redis

app.py

from flask import Flask
from redis import Redis, RedisError
import os
import socket

# Connect to Redis
redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2)

app = Flask(__name__)

@app.route("/")
def hello():
    try:
        visits = redis.incr("counter")
    except RedisError:
        visits = "<i>cannot connect to Redis, counter disabled</i>"

    html = "<h3>Hello {name}!</h3>" 
           "<b>Hostname:</b> {hostname}<br/>" 
           "<b>Visits:</b> {visits}"
    return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits)

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=80)

Buil app

Hãy chắc chắn rằng bạn đã tạo ra 3 files này với lệnh ls trong folder mà bạn đã tạo Dockerfile app.py requirements.txt Chạy lệnh build docker sau để tạo ra docker image với tag name là friendlyhello

docker build -t friendlyhello .

Check docker images bằng lệnh sau

 docker images

giờ bạn có thể chạy app python bằng câu lệnh sau

docker run -p 4000:80 friendlyhello

Trên browser access vào local host với port 4000

http://localhost:4000

Share images

Bạn có thể updoad images vừa tạo để chạy chúng ở một nơi khác.

hãy chắc chắn bạn đã có tài khoản trên cloud.docker.com trước khi chạy lệnh sau

docker login

Đẩy docker của bạn bằng lệnh sau :

docker push username/repository:tag
docker push khanhhd/beginner-docker:part1

sau khi push xong bạn có thể chạy remote

 docker run -p 4000:80 khanhhd/beginner-docker:part1

Trong một ứng dụng phân tán, những phần khác nhau của app được gọi là service, ví dụ nếu bạn share một video trên site thì chắc hẳn bạn sẽ cần một service cho việc lưu data xuống db, một service cho front-end … Service thực chất nó là những containers trên production, Một service có thể chạy trên một image nhưng việc image run cũng phát sinh các vấn đề như port nào sẽ được dùng, có bao nhiêu bản sao của container nên chạy trên service. Việc scalling service làm thay đổi lượng instance của container chạy các phần của service đó.

Scalling service với Docker flaform với docker-compose.yml file

version: "3"
services:
  web:
    # thay đổi username repo  và tag của bạn
    image: khanhhd/beginner-docker:part1
    deploy:
      replicas: 5
      resources:
        limits:
          cpus: "0.1"
          memory: 50M
      restart_policy:
        condition: on-failure
    ports:
      - "80:80"
    networks:
      - webnet
networks:
  webnet:

File này sẽ nói cho docker những việc cần làm:

  • Lấy code mà ta đã upload lên repo
  • Chạy 5 instance images web service. Giới hạn mỗi instance 10% CPU ( của tất cả các cores) và 50MB RAM.
  • Restart container khi nó fails
  • Map port 80 trên host cho web service
  • Chỉ cho web container để chia sẻ port 80 thông qua load-balanced network hay còn gọi là webnet.
  • Định nghĩa webnet network với default setting

Run your new load-balanced app

docker swarm init
docker stack deploy -c docker-compose.yml your_app_name

Lúc này single service đang chạy 5 container instance, xem service id bằng câu lệnh

docker service ls 

https://docs.docker.com/get-started/

0