Professional Documents
Culture Documents
Báo cáo tìm hiểu Docker - TamTD4
Báo cáo tìm hiểu Docker - TamTD4
5. Docker daemon
Docker daemon (dockerd) listen Docker API requests và quản lý Docker objects
như images, containers, networks, và volumes. Một daemon có thể communicate
với daemons khác để quản lý Docker services
Docker client (docker) là cách chính mà nhiều Docker users tương tác với Docker.
Khi dùng commands như docker run, client send những commands tới dockerd,
thực hiện chúng. Docker dùng Docker API. Docket client có thể communicate với
nhiều hơn một daemon.
6. Docker registries
Docker registry store Docker images. Docker Hub là pubic registry mà bất cứ ai có
thể dùng, và Docker được cấu hình để tìm images trên Docker Hub mặc định. Nếu
bạn dùng Docker Datacenter (DDC), nó bao gồm Docker Trusted Registry (DTR).
Khi dùng docker pull hoặc docker run command, images được yêu cầu được pull
từ registry được cấu hình. Khi dùng docker push command, image được push tới
registry được cấu hình.
7. Docker object
a) Image
Một image là read-only template với instruction để tạo Docker container. Thường,
một image được dựa trên một image khác, với một số thay đổi thêm. Ví dụ, bạn có
thể build một image dựa trên Ubuntu image, nhưng install apache web server và
application, cũng như cấu hình chi tiết cần thiết để application run.
Bạn có thể tạo image cho mình hoặc bạn có thể dùng những images được tạo bởi
người khác hoặc được publish trên registry. Để build một image, bạn tạo một
Dockerfile với syntax đơn giản để define những bước cần để tạo image và run nó.
Mỗi instruction trong Dockerfile tạo một layer trong image. Khi bạn thay đổi
Dockerfile và rebuild image, chỉ những layer đã thay đổi mới được rebuild.
b) Container
Một container là runnable instance của một image. Bạn có thể create, start, stop,
move hoặc delete một container dùng Docker API hoặc CLI. Bạn có thể connect
một container tới một hoặc nhiều network, attach storage tới nó hoặc thậm chí tạo
new image dựa trên trạng thái hiện tại.
Mặc định, một container là isolated tương đối tốt với các container khác và host
machine của nó. Bạn có thể tách biệt network, storage, hoặc subsystem bên dưới từ
các container khác hoặc từ host machine.
Một container được định nghĩa bởi images cũng như bất kỳ option cấu hình nào mà
bạn cung cấp khi tạo hoặc start nó. Khi một container được remove, bất kỳ thay đổi
tới state không được store trong persistent storage biến mất.
docker run -i -t ubuntu /bin/bash
Khi run command này:
1. Nếu bạn chưa có Ubuntu image ở local, Docker pull nó từ registry được cấu
hình, mặc dù bạn run docker pull Ubuntu bằng thủ công.
2. Docker tạo một container mới, mặc dù bạn phải run docker container create
command manually.
3. Docker cấp phát read-write filesystem vào container, như layer cuối cùng.
Điều đó cho phép một container đang chạy để tạo hoặc chỉnh sửa files hoặc
directories trong local filesystem.
4. Docker tạo một network interface để connect container tới default network,
bởi vì bạn không chỉ định bất networking options nào. Điều này bao gồm
assigne một IP address vào container. Mặc định, container có thể connect tới
external network và dùng network connection của host machine.
5. Docker start container và thực thi /bin/bash. Bởi vì container đang running
có thể tương tác và attach vào terminal (bởi vì flag -i và -t), bạn có thể cung
cấp input sử dụng keyboard trong khi output được logged vào terminal.
6. Khi bạn nhập exit để terminate /bin/bash command, container stop những
chưa được remove. Bạn có thể start lại hoặc remove nó
8. Namespace
Docker dùng công nghệ gọi là namespace để cung cấp isolated workspace được gọi
là container. Khi bạn run một container, Docker tạo một tập namespace cho
container này. Những namespace này cung cấp một layer isolation. Mỗi khía cạnh
của một container chạy trong một namespace riêng biệt và truy cập của chúng
được giới hạn namespace đó.
Docker Engine dùng namespace:
Pip namespace: process isolation (PID: Process ID)
Net namespace: manage network interfaces (NET: networking).
Ipc namespace: manage access tới IPC resources (IPC: Interprocess
communication).
Mnt namespace: quản lý filesystem moun point (MNT: Mount)
Uts namespace: tách kernel và version identifiers (UTS: Unix Timesharing
System).
9. Control groups
Docker Engine trên Linux phụ thuộc vào một công nghệ khác được gọi là control
groups (cgroups). Một cgroup giới hạn một application tới một tập resource.
Control group cho phép Docker Engine share available hardware resource tới
container và áp đặt giới hạn và ràng buộc. Ví dụ bạn có thể giới hạn memory có
sẵn tới một container cụ thể.
Trong cột OFFICIAL, OK ám chỉ image được build và support bởi công ty phía
sau project đó.
Bạn có thể download docker đó bằng pull command.
docker pull centos
Sau khi docker được cài download, bạn có thể thực thi nó với run command.
docker run centos
Xem docker được download trên computer.
docker images
EXPOSE 80
VOLUME /var/www/html
ENTRYPOINT [ "/usr/sbin/httpd" ]
CMD ["-D", "FOREGROUND"]
Launching container
mkdir data
docker run -td -p 80:80 -v /root/web/data:/var/www/html --name=web
mycentos:httpdv1.0
docker ps
Đặt index.html trong /root/web/data tương đương với đặt nó trong container “web”
ở “/var/www/html”.
EXPOSE 80/tcp
vi index.html
Welcome to my website
Build images
docker build --build-arg http_proxy=http://proxy.fpt.vn:80 --build-arg
https_proxy=http://proxy.fpt.vn:80 -t mycentos:nginxv1.0 .
Kiểm tra
Run Docker
docker run -itd -p 80:80 --name=web mycentos:nginxv1.0
Kiểm tra
[Service]
Restart=always
ExecStart=/usr/bin/docker start -a my-www
ExecStop=/usr/bin/docker stop -t 2 my-www
[Install]
WantedBy=local.target
Sau khi edit file, close, reload systemd daemon và start container
systemctl daemon-reload
systemctl start apache-docker.service
systemctl status apache-docker.service
import redis
from flask import Flask
app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)
def get_hit_count():
retries = 5
while True:
try:
return cache.incr('hits')
except redis.exceptions.ConnectionError as exc:
if retries == 0:
raise exc
retries -= 1
time.sleep(0.5)
@app.route('/')
def hello():
count = get_hit_count()
return 'Hello World! I have been seen {} times.\n'.format(count)
vi Dockerfile
FROM python:3.7-alpine
WORKDIR /code
ENV FLASK_APP app.py
ENV FLASK_RUN_HOST 0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
COPY . .
CMD ["flask", "run"]
Nội dung của Dockerfile:
Build image với Python 3.7 image
Set working directory /code
Set environment variable được dùng vởi flask command.
Cài đặt gcc Python package như MarkupSafr và SQLAlchemy có thể
compile nhanh hơn.
Sao chép requirements.txt và install Python dependencies.
Sao chép current directory . trong project vào workdir . trong image.
Set default command trong container flask run .
vi docker-compose.yml
version: '3'
services:
web:
build:
context: .
args:
- http_proxy=http://proxy.fpt.vn:80
- https_proxy=http://proxy.fpt.vn:80
ports:
- "5000:5000"
redis:
image: "redis:alpine"
Compose file định nghĩa hai services: web và redis.
Web service: dùng một image được build từ Dockerfile trong thư mục hiện hành.
Sau đó nó binds container và host machine tới exposed port, 5000.
Redis service: dùng public Redis image được pull từ Docker Hub registry
iv. Build và run app với Compose
Từ thư mục project, start application bằng cách chạy docker-compose up
Compose pull Redis image, build một image từ code của bạn, start service bạn
define. Trong trường hợp này, code được sao chép vào image lúc build.
Truy cập http://0.0.0.0:5000 trên browse để xem application running.
Stop application, hoặc chạy docker-compose down nằm trong thư mục project
trong terminal thứ hai, hoặc nhấn Ctrl + C trong terminal ban đầu nơi start app.
2) Refresh app trong browser. Lời chào được cập nhật counter vẫn tăng.
docker-compose ps
version: '3'
services:
test_1:
container_name: test_1
image: some:image
networks:
testing_net:
ipv4_address: 172.28.1.1
test_2:
container_name: test_2
image: some:image
networks:
testing_net:
ipv4_address: 172.28.1.2
test_3:
container_name: test_3
image: some:image
networks:
testing_net:
ipv4_address: 172.28.1.3
networks:
testing_net:
ipam:
driver: default
config:
- subnet: 172.28.0.0/16
Dùng ipam để định nghĩa CIDR block cụ thể cho new network, attach mỗi
container vào network này, bạn có thể chỉ định IP address của range này.
X. Docker volume
Docker images được store như một chuỗi read-only layers. Khi bạn start container,
Docker lấy read-only images và add read-write layer trên đỉnh (on top). Nếu
running container thay đổi một file đang tồn tại, file được copy từ bên dưới read-
only layer vào bên trên read-write layer khi những thay đổi được áp dụng. Version
trong read-write layer ẩn những file bên dưới nhưng không destroy chung – chúng
vẫn tồn tại ở layer bên dưới. Khi một Docker container được xóa, relauch image sẽ
start fresh container mà không có bất kỳ sự thay đổi trong running container trước
đó – những thay đổi đã bị mất. Docker gọi sự bao gồm read-only layer với read-
write layer là Union File System.
Docker volumes hữu ích khi bạn cần persist data trong Docker container hoặc
share data giữa containers. Volume là directory (hoặc files) mà nằm ngoài Union
File System và tồn tại như directory và file bình thường trên host filesystem.
Docker volumes quan trọng bởi vì khi Docker container bị destroy, toàn bộ
filesystem cũng bị destroy. Vậy vậy nếu bạn muốn giữa data này, bạn cần sử dụng
Docker volumes.
Docker volumes được attach vào container thông qua docker run command bằng
cách dùng -v flag.
1. Bind mounts
Bind mount là map một directory trên host machine vào directory trên
container. Tuy nhiên khi container bị remove, nó không ảnh hưởng đến
directory này.
docker run -d --name adonis \
-v /path/to/app/directory:/var/www \
stephenafamo/adonisjs:1.0.0
2. Docker volumes
Volume là cơ chế được ưa thích để persist data được tạo và dùng vởi Docker
containers. Trong khi bind mount được độc lập trên cấu trúc directory trên
host machine, volume hoàn toàn được quản lý bởi Docker. Volume có nhiều
thuận lợi hơn bind mounts:
Voumes dễ dàng back up hoặc migrate hơn bind mount.
Bạn có thể dễ quản lý volumes bằng cách dùng Docker CLI command
hoặc Docker API.
Volume có thể làm việc cả Linux và Windows containers.
Volumes có thể share một cách an toàn giữa nhiều containers.
Volume driver cho phép bạn store volumes trên remote hosts hoặc
cloud providers, để encrypt nội dụng volumes, hoặc thêm những
function khác.
Thêm vào đó, volumes thường là sự lựa chọn tốt hơn persist data trong writable
layer của container, bởi vì dùng volume không tăng size của container dùng nó, và
content của volume tồn tại bên ngoài lifecycle của container cụ thể.
3. Cú pháp
Tạo và remove Docker volume
docker volume create <volume name>
Note: nếu bạn chỉ định một volume mà chưa tồn tại, nó sẽ được tạo ra
4. Dùng mount ở read-only mode
Bởi vì Docker volume (hoặc bind mount) có thể được attach vào nhiều container,
sẽ hữu ích khi chỉ một số container có thể write vào nó.
Để đạt được điều đó, bạn cần attach volume vào container khác ở read-only mode
(them ro option)
docker run -d --name adonis \
-v adonis_vol:/var/www:ro \
stephenafamo/adonisjs:1.0.0
docker run --env HTTP_PROXY=http://proxy.fpt.vn:80 \
--env HTTPS_PROXY=http://proxy.fpt.vn:80 \
--network=my-net --privileged --name nginx1.0 \
-v /sys/fs/cgroup:/sys/fs/cgroup:ro \
-v /code -p 80:80 -d mycentos:nginx1.0
Lệnh trên sẽ tạo thư mục /code bên trong container và nằm bên ngoài Union File
System và có thể truy cập trực tiếp trên host.
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php-fpm1.0:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
vi Dockerfile
#FROM centos/systemd
FROM centos
RUN yum -y install --setopt=tsflags=nodocs epel-release \
&& yum -y install --setopt=tsflags=nodocs nginx \
&& yum clean all
#&& systemctl enable nginx.service
EXPOSE 80
1. Nginx
Thành phần:
File config web zabbix: zabbix.conf
Dockerfile Nginx: Dockerfile
Thực hiện:
mkdir nginx
cd nginx
vi zabbix.conf
server {
listen 80;
server_name myzabbix.com;
root /usr/share/zabbix;
location / {
index index.php index.html index.htm;
}
location ~ \.php$ {
fastcgi_pass php-fpm:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME
$document_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_param PHP_VALUE "
max_execution_time = 300
memory_limit = 128M
post_max_size = 16M
upload_max_filesize = 2M
max_input_time = 300
date.timezone = Europe/Moscow
always_populate_raw_post_data = -1
";
fastcgi_buffers 8 256k;
fastcgi_buffer_size 128k;
fastcgi_intercept_errors on;
fastcgi_busy_buffers_size 256k;
fastcgi_temp_file_write_size 256k;
}
}
Docker-compose
vi Dockerfile
FROM centos
RUN yum -y install --setopt=tsflags=nodocs epel-release \
&& yum -y install --setopt=tsflags=nodocs nginx \
&& yum clean all
EXPOSE 80
2. Php-fpm
Thành phần:
File cấu hình pool php-fpm: www.conf
File cấu hình php web interface cho zabbix server: zabbix.conf.php
Dockerfile cho php-fpm: Dockerfile
Thực hiện:
vi Dockerfile
FROM centos
RUN rpm -Uvh https://repo.zabbix.com/zabbix/4.0/rhel/7/x86_64/zabbix-
release-4.0-1.el7.noarch.rpm \
&& yum -y install --setopt=tsflags=nodocs epel-release \
&& yum -y install --setopt=tsflags=nodocs php-fpm \
&& yum -y install --setopt=tsflags=nodocs zabbix-web-mysql \
&& yum clean all
VOLUME /usr/share/zabbix
EXPOSE 9000
3. Mariadb
Thành phần:
Scheme DB zabbix: create.sql
File khởi tạo cấu hình mariadb: my.cnf
File start, stop service: start.sh, stop.sh
Dockerfile cho mariadb: Dockerfile
FROM centos
USER tam
WORKDIR /home/tam
ENTRYPOINT ["/home/tam/start.sh"]
4. Zabbix-server
Thành phần:
File cấu hình zabbix server: zabbix_server.conf
Dockerfile cho zabbix server: Dockerfile
FROM centos/systemd
CMD ["/usr/sbin/init"]
5. Docker-compose
vi docker-compose
version: '3'
services:
mariadb:
build:
context: mariadb
args:
- http_proxy=http://proxy.fpt.vn:80
- https_proxy=http://proxy.fpt.vn:80
user: root
ports:
- "3306:3306"
environment:
- HTTP_PROXY=http://proxy.fpt.vn:80
- HTTPS_PROXY=http://proxy.fpt.vn:80
- MYSQL_ROOT_PASSWORD=password
- MYSQL_USER=zabbix
- MYSQL_DATABASE=zabbix
- MYSQL_PASSWORD=password
- DUMP=create.sql
zabbix:
build:
context: zabbix-server
args:
- http_proxy=http://proxy.fpt.vn:80
- https_proxy=http://proxy.fpt.vn:80
ports:
- "10051:10051"
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:ro
environment:
- HTTP_PROXY=http://proxy.fpt.vn:80
- HTTPS_PROXY=http://proxy.fpt.vn:80
privileged: true
nginx:
build:
context: nginx
args:
- http_proxy=http://proxy.fpt.vn:80
- https_proxy=http://proxy.fpt.vn:80
ports:
- "80:80"
volumes:
- "myvolume:/usr/share/zabbix"
environment:
- HTTP_PROXY=http://proxy.fpt.vn:80
- HTTPS_PROXY=http://proxy.fpt.vn:80
privileged: true
php-fpm:
build:
context: php-fpm
args:
- http_proxy=http://proxy.fpt.vn:80
- https_proxy=http://proxy.fpt.vn:80
ports:
- "9000:9000"
volumes:
- "myvolume:/usr/share/zabbix"
environment:
- HTTP_PROXY=http://proxy.fpt.vn:80
- HTTPS_PROXY=http://proxy.fpt.vn:80
privileged: true
networks:
default:
external:
name: my-net
volumes:
myvolume:
Docker Swarm control những chức năng sau để bạn deloy container dễ dàng:
Health checks trên container.
Launch một tập container với Docker images cụ thể.
Scale số container up and down phụ thuộc load.
Thực hiện roll update của software khắp containers.
Một node là một instance của Docker engine tham gia trong swarm
Worker Node là node run container theo chỉ dẫn của Master Node.
Master node chỉ dẫn Worker Node container status. Trong Docker Swarm có nhiều
manager và worker nodes. Mục đích có nhiều manager node để duy trì high
availability cho Manager nodes. Do đó, một node được chọn như Leader node thực
hiện phối hợp containers. Leader node được chọn bởi algorithm được biết đến như
Raft consensus algorithm. Manager node có thể hoạt động như Worker node mặc
định.
Manager node chịu trách nhiệm những công việc sau:
Duy trì cluster state
Scheduling services
Phục vụ swarm mode HTTP API endpoints