Chủ Nhật, 1 tháng 8, 2021

Bài 1: Tạo lập sẵn công cụ quản lý cơ sở dữ liệu – Database Management System – dùng chung độc lập môi trường phát triển

Xây dựng môi trường hỗ trợ làm việc nhóm với Docker

Bài 1: Tạo lập sẵn công cụ quản lý cơ sở dữ liệu – Database Management System – dùng chung độc lập môi trường phát triển

Kiều Trọng Khánh, Nguyễn Lê Nhật Trường

 

Mục đích: Loạt bài viết về xây dựng môi trường làm việc cùng team trong việc phát triển phần mềm với mục tiêu chia sẻ cho người đọc về các sử dụng docker-compose để cấu hình service và tạo các image để tránh mất thời gian cho các thành viên trong team cài đặt các công cụ - ide, các server/container giả lập, cấu hình các framework cho đến các service  mà trên môi trường máy tính khác nhau (từ hệ điều hành, đến các service chạy ngầm, ứng dụng trong máy tính, …) sẽ tạo ra rất nhiều vấn đề trong thực tế. Ngoài ra, loạt bài này cũng định hướng trong việc tạo ra môi trường thử nghiệm trong quá trình học tập, tiếp cận lập trình, xây dựng ứng dụng theo cách thuận lợi, đơn giản mà không mất quá nhiều thời gian cấu hình và cài đặt môi trường phát triển. Trong loạt bài này, chúng ta sẽ xây dựng một môi trường lập trình ứng dụng web đơn giản – chạy hoàn toàn ở server được host tại local và bao gồm đầy đủ các thành phần cần thiết như web container và database server. Các thành phần này sẽ được cấu hình và đóng gói, sẵn sàng triển khai (deploy) lên máy các thành viên trong nhóm qua vài thao tác cơ bản. Các thành viên có thể nhanh chóng phát triển ứng dụng ở các máy tính khác nhau với cùng một thiết lập môi trường với chung và khả năng backup, recovery thuận lợi nhất. Ở bài đầu tiên này, chúng ta sẽ đi tìm hiểu cách xây dựng và cấu hình services về công cụ quản lý cơ sở dữ liệu để có thể tạo ra môi trường phát triển chung trên tất cả các máy của thành viên của team trong việc phát triển dự án hay trên máy tính của người học lập trình ứng dụng

Yêu cầu về kiến thức cơ bản

·         Nắm vững các kiến thức về docker từ khái niệm đến việc cài đặt docker desktop (tham khảo tại địa chỉ Docker Documentation | Docker Documentation) (Nội dung về cấu hình về mặt tip,trick sẽ được cung cấp trong các bài tiếp theo)

·         Nắm vững kiến thức và các sử dụng tài nguyên trên Docker Hub (tham khảo tại địa chỉ Docker Hub - Container Image Library | Docker )

·         Tìm hiểu các lệnh docker-compose (tham khảo tại địa chỉ Compose file | Docker Documentation)

·         Tìm hiểu cú pháp lệnh của tập tin YAML (tham khảo tại địa chi YAML Ain’t Markup Language (YAML™) Version 1.2)

Công cụ thực hiện

·         Để thực hiện và thao táo trong quá trình xây dựng services – tool Microsoft Visual Code (Download Visual Studio Code - Mac, Linux, Windows)

·         Docker Desktop (Docker Desktop for Mac and Windows | Docker)

·         Microsoft SQL Server Management Studio (Download SQL Server Management Studio (SSMS) - SQL Server Management Studio (SSMS) | Microsoft Docs) hay DBeaver (DBeaver Community | Free Universal Database Tool) hay bất kỳ công cụ hỗ trợ kết nối dữ liệu với DBMS (tool Netbeans IDE cũng hỗ trợ trong Services/Database)

Kiến thức tổng quát

·         Components

o   Ứng dụng của chúng ta khi phát triển có thể chia thành nhiều components hay các sub-system khác nhau. Mỗi thành phần này có thể deploy và execute trên các môi trường khác nhau và tương tác với nhau để tạo thành hệ thống chúng ta đang mong muốn xây dựng

o   Chúng ta lấy ví dụ trên một ứng dụng web đơn giản thực hiện hoàn toàn ở phía server thì chúng ta nhận thấy ứng dụng bao gồm

§  Phần web application được phát triển để deploy và thực thi trên một web container (ví dụ như tomcat)

§  Phần lưu trữ dữ liệu được deploy và quản lý bởi Database Management System (DBMS) cũng là một container (ví dụ như Microsoft SQL Server, MySQL, Postgre, ...)

o   Việc thiết lập, cài đặt, cấu hình các môi trường phát triển cụ thể 02 container trên sẽ gặp một số ít khó khăn khi bắt đầu tiến hành phát triển ứng dụng, có vấn đề về thiết bị xây dựng ứng dụng trong quá trình phát triển, việc đồng nhất giữa các thành viên trong team về máy tính lẫn môi trường làm việc. Do vậy, cần một cách thức cấu hình để có thể cấu hình sẵn và thực thi các container giống nhau trên mỗi máy của team trong quá trình xây dựng dự án.

·         docker-compose

o   Đây là một công cụ hỗ trợ docker khởi tạo các thành phần như image, container, volume, network, … và cách các thành phần này tương tác với nhau dựa theo file cấu hình (docker-compose.yml)

o   Là một giải pháp để chúng ta có thể cấu hình môi trường làm việc cho toàn bộ thành viên và không cần cài đặt quá nhiều và giống nhau giữa tất cả mọi người theo định hướng

§  Xác định các container từ việc breakdown các thành phần trong kiến trúc của toàn bộ ứng à từng container sẽ được xem như là services docker trong file cấu hình

§  Trong quá trình cấu hình, chúng ta thiết lập các nơi lưu trữ, nơi chứa dữ liệu để có thể truy xuất, backup, thao tác trên dữ liệu à cái này gọi là volumns

§  Thực hiện việc kết nối giữa các thành phần services/container độc lập và liên kết dynamic trong quá trình phát triển à cái này gọi là network

o   Cho phép thực hiện cấu hình docker container dựa trên các service trong file YAML để có thể start tất cả các service mong muốn trong một dự án với duy nhất một dòng lệnh

o   Việc sử dụng compose sẽ thực hiện theo 03 bước

§  Định nghĩa các service container mà chúng ta mong muốn có trong môi trường phát triển/thực thi ứng dụng sử dụng tập tin Dockerfile à tập tin này cũng là cơ sở để sau khi cấu hình xong chúng ta có thể tạo ra các image để sử dụng trên các máy tính khác nhau trong ứng dụng của Docker

§  Thiết lập các service kết nối với các Dockerfile đã định nghĩa bước một trong file yaml để xác định các thành phần sẽ được thực thi và sự tương tác giữa chúng

§  Thực hiện start service container và chạy ứng dụng

o   Công cụ compose sẽ đi tìm và thực thi tập tin docker-compose.yml

o   Tập tin docker-compse.yml chỉ là một text file viết theo cú pháp của ngôn ngữ thẻ YAML (tham khảo thêm tại YAML Ain’t Markup Language (YAML™) Version 1.2)

·         docker-file

o   Là một text file chức các lệnh và các bước để tạo nên docker image. Image này sẽ được dùng để khởi tạo các container   và sử dụng ở các nơi khác trong ứng dụng docker

o   Docker thực hiện build các image thông qua việc đọc các lệnh trong file Dockerfile (chúng ta có thể tham khảo thêm chi tiết tại Dockerfile reference | Docker Documentation)

o   Các thứ tự lệnh trong Dockerfile thể hiện lệnh thực hiện tuần tự và các lệnh phía sau sẽ được thừa hưởng từ kết quả của lệnh trước đó trong quá trình tạo ra docker image.

Xây dựng service-docker cho việc quản lý cơ sơ dữ liệu

·         Chúng ta bắt đầu khai báo service container chứa Microsoft sql server được khởi tạo sẵn một DB schema và dữ liệu ban đầu.

·         Chúng ta xem như việc tạo ra các services container và kết nối chúng với nhau để trở thành môi trường cho việc lập trình ứng dụng cho các thành viên trong team là một project services docker được mô hình theo các bước thực thi như sau

o   Chúng ta tạo một thư mục với tên tùy ý. Trong bài viết này, chúng ta tạm đặt tên theo mục tiêu của project là SQLServerTomcatDocker

o   Trong thư mục này, chúng ta sẽ tạo thư mục prepare sẽ nơi chưa các docker file và các resource có liên quan hỗ trợ service container khởi tạo các các cấu trúc khung theo mục tiêu của dự án phát triển như tạo DB và các thành phần cấu trúc trong DB

o   Ngoài ra, chúng ta sẽ tạo phải cấu hình YAML với tên docker-compose.yml vì tool compose sẽ tìm kiếm đọc file này để thực thi

o   Cấu trúc thư mục project sẽ có dạng như sau

o   Chúng ta thực hiện mở tool Microsoft VS Code với truy cập đến thư mục vừa chuẩn bị.

·         Bước 1: Chuẩn bị cấu hình Microsoft sql server chứa DB schema và dữ liệu ban đầu

o   Chúng ta thực hiện tạo dockerfile với các nội dung cấu hình thiết lập service container của chúng ta, cụ thể trong bài này đó là thiết lập Microsoft SQL Server 2017.

o   Chúng ta thực hiện tạo dockerfile với tên gọi tùy chúng ta muốn với đuôi là Dockerfile. Trong bài viết này, chúng ta tạm đặt tên là db.Dockerfile với nội dung như sau

o   Chúng ta tìm hiểu qua một chút cấu trúc và nội dung trong file Dockerfile cấu hình đã đề cập ở trên

§  Dòng lệnh FROM <<imageName>> được dùng để yêu cầu Docker tạo ra một docker container từ docker image có tên là <<imageName>>

·         imageName này là tên của các image được build cục bộ trong máy cục bộ hay được đặt sẵn public trên docker hub (địa chỉ truy cập Docker Hub) với định dạng tên là name:tag

·         Chúng ta vào trang docker hub và tìm kiếm từ khóa “sql server” trong ô search, chúng ta nhận được kết quả như sau

·         Chúng ta click vào Microsoft SQL Server, chúng ta sẽ thấy các image name với các phiên bản khác nhau

·         Chúng ta lựa chọn phiên bản phù hợp với mục đích của từng người. Bài viết này chọn bảng image với tag 2017-latest.

o   Do chúng ta đang build image và không thực thi image trực tiếp để tạo container trực tiếp trên docker, chúng ta lấy giá trị image name theo cấu trúc mô tả là phần phía sau lệnh pull

o   Cụ thể ở đây, chúng ta sẽ lấy mcr.microsoft.com/mssql/server:2017-latest

§  Câu lệnh ENV (Enviroment variable) tiếp theo được giới thiệu trong bài viết này được định hướng cấu hình để đạt được mục tiêu cấu hình được Microsoft SQL Server (các biến môi trường khác quí vị có thể tham chiếu đọc thêm tại Configure environment variables for SQL Server on Linux - SQL Server | Microsoft Docs)

·         Đây là biến chứa các giá trị cấu hình mà container sẽ thực thi khi nạp container

·         Ở đây, biến ACCEPT_EULA giá trị Y dùng để xác nhận người sử dụng đồng ý các điều khoản qui định về end user  license - https://go.microsoft.com/fwlink/?LinkId=746388

·         Tiếp theo, biến SA_PASSWORD với giá trị cấu hình mật khẩu cho quyền super administrator để truy cập DB. Password quí vị tự đặt theo ý quí vị để có thể truy cập về sau

·         Kế tiếp, biến MSSQL_PID với giá trị xác định phiên bản SQL Server chúng ta dự tính sử dụng. Bài viết này đang sử dụng bản Express

·         Cuối cùng, biến MSSQL_TCP_PORT với con số cụ thể để cấu hình port mà SQL Server container sẽ được host khi nạp thành công

·         Các giá trị biến môi trường khác dành cho sql server, chúng ta có thể tham khảo tại địa chỉ Configure environment variables for SQL Server on Linux - SQL Server | Microsoft Docs khi cần dùng

§  Câu lệnh COPY dùng để copy file và thư mục trong build context đến vị trí trong file image

·         Build context là thư mục được chỉ định khi build một dockerfile thành docker image.

o   Khi tiến hành build image, docker sẽ quét và đánh dấu các file trong thư mục này nhằm phục vụ cho các lệnh như COPY hoặc ADD. 

o   Các file không nằm trong build context sẽ không thể truy cập được trong quá trình build image.

o   Trong bài viết này, chúng ta đang chỉ định thư mục prepare làm build context trong file docker-compose.yml

·         Trong bài viết này, chúng ta mong muốn thực hiện chạy các câu lệnh SQL để tạo DB, tạo Table và insert các dữ liệu mẫu. Toàn bộ SQL Script này chúng ta đặt trong tập tin dbscript.sql

·         Chúng ta đặt tập tin này trong thư mục prepare của project, , tương ứng với thư mục hiện hành của build context. Do vậy, chúng ta dùng đường dẫn ./ nghĩa là nằm trong prepare

·         Chúng ta copy tập tin sql script này và đưa vào thư mục hiện hành của container

·         Chúng ta có tập tin dbscript.sql nằm trong thư mục prepare với nội dung như sau

·         Cấu trúc thư mục project của chúng ta hiện nay như sau

§  Cuối cùng, câu lệnh RUN dùng để thực thi lệnh tại thời điểm build image

·         Trong bài viết này, câu lệnh (/opt/mssql/bin/sqlservr --accept-eula & ) | grep -q "Service Broker manager has started"   dùng để thực hiện start sql server sau khi container đã nạp image xong và chấp nhận mọi qui định trong điều khoản qui định với end user và grep để chúng ta sẽ thấy dòng chuổi này khi image được thực thi

·         Trong câu lệnh bash shell không có dấu chấm phẩy kết thúc lệnh như chúng ta viết code lập trình trong compiler nên đôi lúc câu lệnh quá dài, chúng ta cần tách xuống hàng cho dễ nhìn và đọc. Chúng ta enter xuống hàng và ký hiệu lệnh vẫn còn với dấu “\”

·         Lệnh tiếp theo mà chúng ta thực thi là /opt/mssql-tools/bin/sqlcmd -S 127.0.0.1 -U sa -P 'Trongkhanh@28' -d master -i dbscript.sql thể hiện chúng ta dùng command tool của sql server để thực hiện sql script. Như chúng ta đã biết, trong sql server, muốn thực hiện lệnh thì chúng ta phải thực hiện từ db master và phải có quyền của super administrator (sa)

o   Chúng ta vừa hoàn thành dockerfile đế cấu hình service container cho DB với tập lệnh nạp dữ liệu và thực thi những thành phần mong muốn

·         Bước 2: Thiết lập service vào trong file cấu hình docker-compose.yml

o   Chúng ta mở file docker-compose.yml trong thư mục project đã tạo sẵn, chúng ta bổ sung các nội dung cấu hình như sau

§  Chúng ta cùng đi tìm hiểu các nội dung chúng ta đã cấu hình

·         Dòng version 3.3 nghĩa là chúng ta đang dùng cú pháp lệnh theo tool compose tương ứng

·         Dòng 3, services dùng để khai báo các service khác nhau thông qua các tên trong cấp độ index bên trong (ví dụ ở đây là web-db)

·         Chúng ta khai báo service đầu tiên theo định hướng của bài viết này là quản lý cơ sở dữ liệu

o   Chúng ta khai báo tên service tùy ý theo ý định. Bài viết này, chúng ta tạm khai báo là web-db

o   Với dòng image, chúng ta mong muốn image đang được build sẽ có name:tag theo định dạng. Ở đây chúng ta đang đặt tên là web-db:1.0.0. Lưu ý đây chỉ là tên image sẽ build ở local, chúng ta sẽ thực hiện build image và public trên docker hub ở các bài sau

o   Với dòng build, chúng ta đang xác định service được build từ file docker file đang được chị định và xác định thư mục đang làm việc trong quá trình build (build context) thông qua dòng context. Do vậy, chúng ta có thể hiểu dòng này theo cách là tạo container SQL Server theo cấu hình trong tập tin db.Dockerfile được chứa trong thư mục prepare và build context là thư mục prepare.

o   Bởi vì sql server đa số đang được host port 1433 nhưng với khái niệm container được tạo ra đang run trong docker với port 1433. Tuy nhiên, chúng ta ở môi trường ngoài docker muốn tương tác thì chúng ta mong muốn container sẽ map ra bên ngoài để chúng ta truy cập. Bên cạnh đó, môi trường máy tính chúng ta vẫn đang host một container SQL server đang ở post 1433 à việc mapping sẽ tạo nên xung đột nên chúng ta mapping ra port 1434 để có thể truy cập. Nếu quí vị không có xung đột có thể vẫn để nguyên port 1433 theo định dạng port_của_máy_tính:port_trong_container (ví dụ 1433:1433)

o   Dòng tty thể hiện các lệnh sẽ được thực thi trong command line hay terminal trong quá trình nạp và chạy nền

o   Dòng environment tương tự như nội dung cấu hình trong Dockerfile đã nêu ở phần trên

o   Volumes là cách thức để chúng ta mapping dữ liệu từ docker host theo khái niệm là khi container kích hoạt thì docker host (ứng dụng docker) sẽ tạo ra vùng chứa dữ liệu (tương tự phân vùng ổ cứng) và sẽ cung cấp cơ chế cho container mapping tới sử dụng. Tuy nhiên, việc tương tác với docker host để lấy dữ liệu backup hay đổ thêm dữ liệu vào sẽ khá phức tạp nên chúng ta sẽ ánh xạ song song nó ra nơi lưu trữ ở máy thật qua dòng cấu hình volumes ở bên dưới với đường dẫn cụ thể trong device

o   Tại mục volumes ở dòng 36, chúng ta đang cấu hình mapping với ổ cứng thật thông qua driver là local. Với driver_opts là type là mặc định không quan tâm dạng file format của hệ điều hành và o là bind – ánh xạ đồng bộ với đường dẫn cụ thể được liệt kê trong device

·         Bước 3 : Thực hiện run docker compose để có kết quả

o   Tại màn hình terminal trong Microsoft VS Code, chúng ta thực hiện build image bằng lệnh docker-compse build <<tên service muốn build>>

§  Lưu ý: đường dẫn của terminal phải là đường dẫn đến thư mục project của chúng ta

§  Tên service trong bài này được cấu hình ở dòng số 5

§  Màn hình terminal khi bắt đầu

§  Chúng ta nhập lệnh sau dấu nhắc, cụ thể docker-compose build web-db

§  Chúng ta nhấn enter, chúng ta thấy được kết quả như sau

o   Chúng ta kiểm tra image được build ở local bằng lệnh docker image ls

o   Tiếp theo chúng ta thực hiện nạp container bằng lệnh docker-compose up và nhấn enter

o   Kết quả màn hình thực hiện như sau

§  Khởi tạo

§  Start dịch vụ và nạp các db

§  Các thành phần khởi tạo kể cả tạo DB schema

o   Chúng ta có thể kiểm tra với màn hình docker desktop

o   Chúng ta có thể kiểm tra bởi dòng lệnh trong terminal của Microsoft VS Code bằng cách mở thêm một terminal bằng dấu “+” và nhập lệnh docker ps

o   Chúng ta có thể kiểm tra kết nối bằng Microsoft SQL Server Management Studio (lưu ý việc nhập port được phân cách bằng dấu phẩy (“,”) không phải dấu “:”

§  Kết quả kết nối

o   Kiểm tra kết nối với dịch vụ database của Netbeans

§  Chúng ta cần phải nạp Drivers và tạo connection trong DB

§  Thực hiện kết nối để test

§  Kiểm tra dữ liệu

§  Chúng ta vừa hoàn tất quá trình kích hoạt để nạp container hỗ trợ cơ sở dữ liệu và nạp sẵn dữ liệu ban đầu

§  Việc thao tác với DB tương tự như chúng ta tương tác cục bộ và đồng bộ dữ liệu tương tự như chúng ta tương tác với SQL Server được cài đặt trên hệ điều hành của máy cục bộ và không tốn quá nhiều thời gian cài đặt

§  Ngoài ra, dữ liệu của DB cũng được mapping ra máy local ở bên ngoài cụ thể tại đường dẫn device chúng ta thiết lập trong file yml à việc này có thể nói đang hỗ trợ chúng ta backup dữ liệu mà không cần tương tác vào bên trong ứng dụng docker

Các lưu ý trong quá trình thực hiện

·         Để stop container đang được chạy mà không remove nó ra khỏi ứng dụng docker chúng ta dùng lệnh docker-compose stop hay trên terminal đang chạy chúng ta nhấn tổ hợp phím Ctrl + C

·         Trong quá trình nạp container vào ứng dụng docker, nếu có bất kỳ vấn đề lỗi nào xảy ra, chúng ta có dừng và remove container ra khỏi docker bằng lệnh docker-compose down

o   Chúng ta sẽ nhìn thấy kết quả trên docker desktop

·         Trong quá trình build các image nếu chúng ta

o   Chỉnh sửa các nội dung trong thư mục build context thì chúng ta phải thực hiện lệnh docker-compose build để tạo lại image

o   Chỉ chỉnh sửa file yml thì chúng ta không cần phải thực hiện build lại image

·         Chúng ta có thể loại bỏ image trong ứng dụng docker bằng cách dùng lệnh docker image rm <<tên image:tag_name> (nội dung này chúng ta có thể thấy được bằng cách liệt kê các image theo cách đã nêu trong các phần trên)

·         Trong quá trình nạp container, có một số vấn đề mà việc cấu hình và nạp sẵn dữ liệu không giống như việc chúng ta cấu hình, chúng ta có thể xem log bằng lệnh docker-compose logs -f

 

Chúc mừng quí vị đã hoàn tất việc tiếp cận build một docker image với service cung cấp quản lý cơ sở dữ liệu và nạp dữ liệu ban đầu

Ở bài tiếp theo, chúng ta sẽ thực hiện build tiếp một docker image với service cung cấp web container cụ thể ở đây là tomcat server. Rồi từ đó chúng ta sẽ tích hợp với service về quản lý cơ sở dữ liệu ở bài này để tạo thành một môi trường phát triển ứng dụng web đơn giản chạy ở local server. Trong bài tiếp theo này, chúng ta sẽ tạo service web container cùng với deploy ứng dụng web MVC2 phát triển bằng JavaEE có kết nối dữ liệu được trong trong service quản lý cơ sơ dữ liệu ở bài này.

Ngoài ra, các định nghĩa và cơ chế của ứng dụng docker và docker container sẽ được giới tiếp trong series này để giúp quí vị có thể tạo ra môi trường làm việc nhóm chung cho cả team trong dự án một cách đơn giản nhất khi triển khai hay môi trường nghiên cứu công nghệ mới lẫn môi trường học tập.

Rất mong sự góp ý chân thành và chia sẻ của quí vị về loạt series này.


Không có nhận xét nào:

Đăng nhận xét