Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 46

Tìm hiểu Docker

Người thực hiện: TamTD4


I. Docker
1. Khái niệm
Docker là open platform để developing, shipping, running applications. Docker
cho phép bạn tách biệt applications khỏi infrastructure, do đó bạn có thể deliver
software nhanh chóng.
2. Docker platform
Docker hỗ trợ khả năng package và run một application trong môi trường tách biệt
được gọi là container. Việc tách biệt và security cho phép bạn run nhiều container
đồng thời. Container là lightweight bởi vì nó không cần thêm load của hypervisor,
nhưng có thể run trực tiếp trên kernel của host machine.
3. Docker Engine
Docker Engine là client-server application với những thành phần chính:
 Một server có kiểu long-running program được gọi là daemon process
(dockerd command).
 REST API chỉ định interface mà program có thể dùng để nói chuyện với
daemon và hướng dẫn cần làm gì.
 Command line interface (CLI) client (docker command).
CLI dùng Docker REST API để control hoặc tương tác với Docker daemon thông
qua script hoặc CLI command trực tiếp.
Daemon tạo và quản lý Docker objects như images, containers, networks, và
volumes.
4. Docker architecture
Docker dùng client-server architecture. Docker talks với Docker daemon, mà
build, run, distribute Docker container. Docker client và deamon có thể run cùng
một hệ thống, hoặc có thể kết nối tới remote Docker daemon. Docker client và
deamon communicate dùng REST API, qua Unix socket hoặc network interface.

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ể.

II. Build Docker images với Docker file


1. Dockerfile
Dockerfile là text-file mà chứa một danh sách các commands mà Docker client gọi
khi tạo một image.
Một Dockerfile dùng những command sau để build images:
 ADD – copy files từ một source trên host tới filesystem của container ở đích
được đặt.
 CMD – thực thi một command cụ thể trong container.
 ENTRYPOINT – một tập default application được dùng mỗi lần container
được tạo với image.
 ENV – tập environment variables.
 EXPOSE – bảo Docker running container listen ở một port cố định. Expose
sẽ không cho phép communication qua port được define tới container bên
ngoài cùng network hoặc tới host machine. Để cho phép điều đó xảy ra bạn
cần publish port.
 FROM – define base image được dùng để bắt đầu quá trình build.
 MAINTAINER – define full name và email address của người tạo image.
 RUN – central executing directive cho Dockerfiles.
 USER – set UID (username) mà sẽ run container.
 VOLUME – cho phép truy cập từ container tới directory trên host machine.
 WORKDIR – set path nơi command, được define với CMD, được thực thi.
2. Cấu trúc Dockerfile thông thường
Cấu trúc cơ bản của Dockerfile
1. Chỉ định base image, dùng FROM keyword.
2. Write commands copy files và install dependencies.
3. Chỉ định port number cần expose.
4. Write command để run application, dùng CMD command.
Khi bạn có Dockerfile, bạn có thể tạo build image. docker build command để tạo
Docker image từ một Dockerfile.
Run image
Publish port và map chúng tới host
Có vài flags bạn có thể dùng khi dùng docker run command để publish một port
của container bên network của container và map chúng vào port của host machine.
Có flags –p, -P và chúng khác nhau khi bạn muốn publish một hoặc nhiều ports.
 -p flag trên docker run để publish và map một hoặc nhiều ports
 -P flag để publish tất cả exposed ports và map chúng high-order ports.
docker run -p 80:80/tcp -p 80:80/udp my_app
theo sau –p flag là host port, tiếp theo là container port.

III. Cài đặt Docker


1. Install Docker
Add Docker repository và download lastet Docker và install nó
curl -fsSL https://get.docker.com/ | sh
Sau khi cài đặt xong, start Docker
systemctl start docker
Verify nó đang running
systemctl status docker
Make sure nó start mỗi khi reboot
systemctl enable docker
2. Cấu hình docker
a) Thực thi docker command without sudo
usermod -aG docker $(whoami)
b) Thực thi Docker
c) Add proxy vào docker
mkdir -p /etc/systemd/system/docker.service.d
vi /etc/systemd/system/docker.service.d/http-proxy.conf
[Service]
Environment="HTTP_PROXY=http://proxy.fpt.vn:80/"
Environment="HTTPS_PROXY=http://proxy.fpt.vn:80/"
Flush changes
systemctl daemon-reload
systemctl restart docker
Verify configuration đã thay đổi
systemctl show --property=Environment docker

d) Làm việc với docker


docker run hello-world

Search image có sẵn trên Docker Hub

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

3. Run docker container


Thử run một container dùng lastest image centos. -i và -t cho phép bạn tương tác
với tương tác shell trong container
docker run -it centos

Như hình container id: ce16c824a58c


Thử run command trong container.
docker run -it --env HTTP_PROXY=http://proxy.fpt.vn:80 --env
HTTPS_PROXY=http://proxy.fpt.vn:80 centos
Giả sử cài đặt MariDB server trong running container. Không cần prefix sudo, bởi
vì bạn đang hoạt động bên trong container với root privileges.
4. Truy cập bash shell trong container
a) Dùng Docker Attach
Bạn có thể truy cập bash shell bên trong docker container với attach command.
docker attach <CONTAINER ID/NAME>
b) Dùng Docker Exec
Nếu docker container mà chưa start với /bin/bash command, do đó bạn
không thể dùng attach command. Bạn có thể dùng exec command để tạo
bash bên trong container.
Cú pháp để truy cập shell của docker container
docker exec -it <CONTAINER ID/NAME> bash
-i (interactive) flag để giữa stdin mở
-t cấp phát terminal
Delete tất cả containers mà có status exited
docker rm $(docker ps -a -q -f status=exited)
Sự khác biệt giữa base image và child image
 Base images là những images mà không có image, thường images với
OS như Ubuntu, busybox hoặc debian.
 Child images là những image được build trên base image và thêm một
số chức năng.
Bạn có thể thoát khỏi container mà không stop nó
“Ctrl + P + Q”
Bạn có thể stop và thoát khỏi container qua “Ctrl + D”
Running docker trên background
docker start
Check process đang run trong container
docker top id/name

IV. Tạo apache image


mkdir /root/web
cd web
vi Dockerfile
FROM centos

LABEL project="ITzGeek Demo image"


LABEL maintainer "itzgeek.web@gmail.com"

RUN yum -y install httpd

EXPOSE 80

VOLUME /var/www/html

ENTRYPOINT [ "/usr/sbin/httpd" ]
CMD ["-D", "FOREGROUND"]

Build docker image


docker build --build-arg http_proxy=http://proxy.fpt.vn:80 --build-arg
https_proxy=http://proxy.fpt.vn:80 -t mycentos:httpdv1.0 .
-t: Docker image tag. Bạn có thể đặt tên và một tag.
“.”: chỉ định vị trí của Dockerfile mà bạn tạo. Bởi vì bạn tạo Dockerfile trong cùng
thư mục mà bạn đang run docker build, bạn chỉ định thư mục hiện tại.
Kiểm tra
docker images

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”.

Truy cập web: 192.168.222.144

Remove các container đã exit


docker rm $(docker ps -a -f status=exited -q)

V. Thử build images nginx


vi Dockerfile
FROM centos

LABEL project="ITzGeek Demo image"


LABEL maintainer "itzgeek.web@gmail.com"

RUN yum -y install epel-release && \


yum -y install nginx && \
yum clean all
COPY index.html /usr/share/nginx/html/index.html

EXPOSE 80/tcp

CMD ["nginx", "-g daemon off;"]

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

VI. Tạo system-wide configuration file cho Docker container


Trên Centos/RHEL 7, bạn có thể tạo một systemd configuration file và quản lý
container.
Ví dụ tạo một systemd file được đặt tên apache-docker.services
vi /etc/systemd/system/apache-docker.service
[Unit]
Description=apache container
Requires=docker.service
After=docker.service

[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

VII. Docker best practices


1. Minimize số steps trong Dockerfile
Minimizing số step trong image để cải thiện build và pull performance. Thực tiễn
tốt nhất gộp nhiều bước thành một dòng, vì vậy bạn chỉ cần một image trung gian.
FROM alpine:3.4

RUN apk update && \


apk add curl && \
apk add vim && \
apk add git
Sau khi build Dockerfile này bạn sẽ thấy chỉ cần 2 bước thay vì 4, mà sẽ dẫn đến 1
new image thay vì 3.
Lưu ý: chỉ RUN, COPY và ADD chỉ tạo layer.
2. Sort multi-line instructions
Đây là ý kiến hay để sắp xếp nhiều dòng instruction theo cách thức con người dễ
đọc. Một ví dụ bên trên là chưa optimal, bởi vì tôi đang cài đặt không theo thứ tự.
Thay vì tôi nên viết một file, trong đó packages theo thứ tự chữ cái.
FROM alpine:3.4
RUN apk update && \
apk add curl && \
apk add git && \
apk add vim
Bạn có thể bỏ apk add ở 3 dòng cuối
FROM alpine:3.4

RUN apk update && apk add \


curl \
git \
vim
Bắt đầu Dockerfile với những bước ít thay đổi
1. Install những tools cần thiết để build application
2. Install dependencies, libraries và packages.
3. Build application.
One container một trách nhiệm
Container là một thực thể chịu trách nhiệm một khía cạnh của project. Vì vậy thiết
kế application như web server, database, in-memory cache và các thành phần khác
có container chuyên dụng.
3. FROM
Dockerfile thường bắt đầu với From instruction theo hình thức FROM
<image>[:tag]. Nó sẽ set base image của Dockerfile, điều này có nghĩa các
instruction tiếp theo sẽ áp dụng vào base image.
Tag value là optional, nếu bạn không chỉ định tag, Docker sẽ dùng tag latest và sẽ
thử và dùng hoặc pull version mới nhất của base image trong suốt lúc build.
Note:
 Có một instruction mà bạn có thể đặt trước FROM trong Dockerfile, đó là
ARG. ARG được dùng để chỉ định tham số cho docker build command với –
build-arg <varname>=<value> flag.
 Bạn có thể có nhiều hơn một FROM instruction trong Dockerfile. Bạn sẽ
dùng tính năng này, ví dụ khi bạn dùng một image để build application và
một image khác để run nó.
Đó gọi là multi-stage build.
Mỗi section thường bắt đầu với FROM trong Dockerfile là được gọi là build
stage (thậm chí trong trường hợp đơn giản nhất chỉ có một FROM instruction
Không cài đặt debug tools như vim/curl
4. Thêm rm -rf /var/lib/apt/lists/* cùng layer như apt-get installs
Thêm rm -rf /var/lib/apt/lists/* ở cuối apt-get -y install để clean sau khi cài đặt
packages.
Với yum, thêm yum clean all
Nếu bạn install với wget và curl để download một số package, nhớ gộp chúng
trong một RUN statement. Sau đó ở cuối RUN statement, apt-get remove curl
hoặc wget khi bạn không cần chúng

VIII. Docker compose


1. Cài đặt docker compose
Chạy command này để tải bản stable hiện tại của Docker Compose
curl -L "https://github.com/docker/compose/releases/download/1.24.0/docker-
compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
Set executable permisstion vào binary
sudo chmod +x /usr/local/bin/docker-compose
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
Kiểm tra version
docker-compose –version
2. Làm quen với Docker compose
i. Setup
a) Tạo thư mục cho project
mkdir composetest
cd composetest

b) Tạo file app.py trong thư mục project


import time

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)

c) Tạo file requirements.txt trong thư mục project


flask
redis

ii. Tạo Dockerfile

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 .

iii. Define services trong Dockerfile


Tạo file docker-compose.yml trong project directory

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.

v. Chỉnh sửa Compose file để add một bind mount


Chỉnh sửa docker-compose.yml trong thư mục project để thêm bind mount
cho web service:
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"
volumes:
- .:/code
environment:
FLASK_ENV: development
redis:
image: "redis:alpine"
volumes mount mount project directory (current directory) trên host vào /code bên
trong container cho phép bạn chỉnh sửa code on the fly mà không cần rebuild
image. enviroment set biến môi trường FLASK_ENV, bảo flask run để run trong
chế độ development và reload code thay đổi. Mode này chỉ được dùng trong phát
triển.
vi. Rebuild và run app với Compose
Kiểm tra Hello World message trong web browser, refresh để thấy biến đếm
tăng lên

vii. Cập nhật application


Bởi vì application code được mount trong container dùng một volume, bạn
có thể thay đổi code và xem sự thay đổi liên tục, mà không cần rebuild
images
1) Thay đổi lời chào trong app.py và lưu lại. Ví dụ thay đổi “Hello World”
thành “Hello from Docker!”:
return 'Hello from Docker! I have been seen {} times.\n'.format(count)

2) Refresh app trong browser. Lời chào được cập nhật counter vẫn tăng.

viii. Thử nghiệm với một số command khác


Nếu bạn muốn run services trong background, bạn có thể truyền -d flag
(detach mode) để docker-compose up và dùng docker-compose ps để xem
những gì đang diễn ra.
docker-compose up -d

docker-compose ps

Kiểm tra enviroment variable có mặt ở web service


Remove toàn bộ container với down command. Truyền --volumes để
remove data volume được dùng vởi Redis container.
docker-compose down --volumes
 Đặt tên container cho mỗi service
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"
volumes:
- .:/code
environment:
FLASK_ENV: development
container_name: app_flask
redis:
image: "redis:alpine"
container_name: app_redis

View container logs


docker-compose logs {service-name}

IX. Docker network


Docker tạo 3 network tự động khi cài đặt: bridge, none và host.
1. Bridge

docker run -d --name web1 -p 8081:80 jonlangemak/docker:webinstance1


docker run -d --name web2 -p 8082:80 jonlangemak/docker:webinstance2
Khi bạn run default bridge mode và mapping vào container. Run hai containers
này, bạn sẽ thấy hai web server trên port 8081 và 8082.
2. Host

docker run -d --name web1 --net=host jonlangemak/docker:webinstance1


Thực thi command trên sẽ launch web server với containers network stack được
map trực tiếp tới host. Khi container đang chạy, bạn có thể truy cập trực tiếp tới
web server thông qua Docker host ip address.
Lưu ý: bạn hoặc cần disable firewall trên Docker host hoặc thêm một số rules thích
hợp.
3. None
docker run -d --name web1 --net=none jonlangemak/docker:webinstance1
4. Cú pháp
 Liệt kê tất cả Docker networks
docker network ls

 Xem chi tiết về network liên kết với Docker


docker network inspect <network name>
 Network name: tên network mà bạn cần xem
 Tạo new network
Tạo một network trong Docker trước khi launch containers.
docker network create --driver <driver name> --subnet <subnet name>
<name>
 --driver name: chỉ định dãy mạng sẽ thuộc kiểu nào: bridge, host hoặc
none.
 --subnet: chỉ định địa chỉ mạng (không bắt buộc)
 Name: tên network
Ví dụ:
docker network create --driver bridge new_nw
Sau khi tạo network new_nw, bạn có thể attach khi launch containers. Chỉ
định network một container sẽ dùng với --net flag.
docker run --it --network=new_nw ubuntu:latest /bin/bash

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>

Liệt kê tất cả volume


docker volume ls

Xóa docker volume


docker volume rm <volume name>

Attach docker volume vào container


Bạn có thể dùng -v hoặc --volume flag để attach một Docker volume vào
container. Tuy nhiên thay vì đặt path của directory trên host machine mà bạn bind
mount, chúng ta chỉ đơn giản đặt volume name.
docker run -d --name adonis \
-v adonis_vol:/var/www \
stephenafamo/adonisjs:1.0.0

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.

5. Tìm volume nằm trên host


docker inspect -f "{{json .Mounts}}" <container name or id> | jq .
Install jq nếu jq command not found
yum install -y epel-release
yum install -y jq
6. Dùng chỉ thị VOLUME trong Dockerfile
FROM debian:wheezy
VOLUME /data
Attach volume vào container lúc runtime
docker run -d -v my-vol:/data debian
0794c8abf033192bff4df665f6c34b71f240146146c1e3654569c8c0a656c24f
Ví dụ này sẽ mount my-vol lume vào /data bên trong container.
*Dùng docker cp tên_container:tên_thư_mục (lưu ý thư mục được mount từ host
vào container, khi copy file trên đó ra ngoài sẽ lỗi)

XI. Hướng dẫn build nginx và php-fpm docker


7. Nginx
mkdir nginx
cd nginx
vi new.conf
server {
index index.php index.html;
server_name 192.168.222.141;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /code;

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

COPY zabbix.conf /etc/nginx/conf.d/

EXPOSE 80

CMD ["nginx", "-g daemon off;"]


#CMD ["/usr/sbin/init"]
 Tạo thư mục source để bind mount
mkdir /root/nginx/source-nginx
vi index.php
<?php
echo phpinfo();
 Tạo network để docker nginx và docker php-fpm có thể làm việc với nhau

 Build Docker nginx với repository: “mycentos” và tag: “nginx1.0”


docker build --build-arg http_proxy=http://proxy.fpt.vn:80 --build-arg
https_proxy=http://proxy.fpt.vn:80 --rm --no-cache -t mycentos:nginx1.0 .
 Run Docker nginx với image: “mycentos:nginx1.0”, bind mount
“/sys/fs/cgroup:/sys/fs/cgroup:ro”, “/root/nginx/source-nginx:/code”, expose
port “80:80” với privileged = true
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 /root/nginx/source-nginx:/code -p
80:80 -d mycentos:nginx1.0
 Kiểm tra service nginx
docker exec -it nginx1.0 /bin/bash -c "systemctl status nginx"
8. Php-fpm run trên systemd
mkdir php-fpm
cd php-fpm
vi Dockerfile
FROM centos/systemd
RUN yum -y install epel-release ; yum -y install php-fpm ; yum clean all;
systemctl enable php-fpm.service
COPY ./www.conf /etc/php-fpm.d/www.conf
EXPOSE 9000
CMD ["/usr/sbin/init"]

 Build Docker php-fpm với repository: “mycentos” và tag: “php-fpm1.0”


docker build --build-arg http_proxy=http://proxy.fpt.vn:80 --build-arg
https_proxy=http://proxy.fpt.vn:80 --rm --no-cache -t mycentos:php-fpm1.0 .
 Run Docker nginx với image: “mycentos:php-fpm1.0”, bind mount
“/sys/fs/cgroup:/sys/fs/cgroup:ro”, “/root/nginx/source-nginx:/code”, expose
port “9000:9000” với privileged = true
docker run --env HTTP_PROXY=http://proxy.fpt.vn:80 \
--env HTTPS_PROXY=http://proxy.fpt.vn:80 \
--network=my-net --privileged --name php-fpm1.0 \
-v /sys/fs/cgroup:/sys/fs/cgroup:ro \
-v /root/nginx/source-nginx:/code -p 9000:9000 \
-d mycentos:php-fpm1.0
 Kiểm tra service nginx
docker exec -it php-fpm1.0 /bin/bash

XII. Hướng dẫn build docker Zabbix Server

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

COPY zabbix.conf /etc/nginx/conf.d/

EXPOSE 80

CMD ["nginx", "-g daemon off;"]

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

COPY ./www.conf /etc/php-fpm.d/www.conf


COPY zabbix.conf.php /etc/zabbix/web

VOLUME /usr/share/zabbix

EXPOSE 9000

CMD ["php-fpm", "-F"]

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

RUN yum -y install mariadb-server \


&& yum clean all \
&& useradd -ms /bin/bash tam

# Place VOLUME statement below all changes to /var/lib/mysql


VOLUME /var/lib/mysql

COPY sbin/start.sh sbin/stop.sh create.sql /home/tam/


RUN chmod +x /home/tam/start.sh \
&& chmod +x /home/tam/stop.sh

USER tam
WORKDIR /home/tam

COPY conf/my.cnf /etc/my.cnf


EXPOSE 3306

ENTRYPOINT ["/home/tam/start.sh"]

docker build --build-arg http_proxy=http://proxy.fpt.vn:80 --build-arg


https_proxy=http://proxy.fpt.vn:80 -t mycentos:mariadb .

docker run --env HTTP_PROXY=http://proxy.fpt.vn:80 \


--env HTTPS_PROXY=http://proxy.fpt.vn:80 --network=my-net \
--name mariadb -p 3306:3306 -u 0 \
-e MYSQL_ROOT_PASSWORD=password \
-e MYSQL_USER=zabbix \
-e MYSQL_DATABASE=zabbix \
-e MYSQL_PASSWORD=password \
-d mycentos:mariadb
docker exec -it mariadb /bin/bash

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

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 zabbix-server-mysql \
&& yum -y install zabbix-agent \
&& systemctl enable zabbix-server.service \
&& systemctl enable zabbix-agent.service
COPY zabbix_server.conf /etc/zabbix/zabbix_server.conf
EXPOSE 10051

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

You might also like