Tạo môi trường phát triển K8s bằng Minikube
Yêu cầu trước khi bắt đầu
Môi trường cần thiết là Windows 10 (đối với tôi) hoặc Windows 11 tùy các bạn.
Tải xuống các công cụ cần thiết
Hãy cài đặt Minikube từ liên kết sau:
- Minikube Installation Guide: https://minikube.sigs.k8s.io/docs/
Chúng ta sẽ sử dụng virtualbox làm driver cho Minikube.
Hãy cài đặt VirtualBox từ đây:
- VirtualBox Downloads: http://virtualbox.org/wiki/Downloads
Chúng ta cũng sẽ sử dụng Git. Hãy cài đặt Git từ đây:
- Git Downloads: https://git-scm.com/downloads
Hãy cài đặt Skaffold từ liên kết sau:
- Skaffold Installation Guide: https://skaffold.dev/docs/install/
Tiếp theo, hãy cài đặt Kubernetes từ đây:
- Kubernetes Installation Guide for Windows: https://kubernetes.io/docs/tasks/tools/install-kubectl-windows/
(Nếu bạn sử dụng choco hoặc scoop, việc cài đặt sẽ dễ dàng hơn)
Xác minh cài đặt
Sau khi cài đặt xong, hãy kiểm tra xem bạn có thể truy cập Minikube từ PowerShell không.
Mở PowerShell và chạy lệnh sau:
minikube version
Bạn sẽ nhận được thông tin về phiên bản Minikube:
minikube version: v1.35.0
commit: dd5d320e41b5451cdf3c01891bc4e13d189586ed-dirty
Tương tự, hãy kiểm tra phiên bản Git:
git -v
git version 2.47.1.windows.2
Chạy các lệnh sau trong PowerShell để tạo một dự án mẫu:
cd Documents
mkdir projects
cd projects
mkdir test-project
cd test-project
Bắt đầu Minikube Cluster
1. Một số thuật ngữ quan trọng
Container là gì?
- Containers là môi trường runtime nhẹ, độc lập, đóng gói ứng dụng cùng với tất cả các phụ thuộc của nó. Containers giúp đảm bảo tính nhất quán trên nhiều môi trường khác nhau.
Pod là gì?
- Pod là đơn vị triển khai nhỏ nhất trong Kubernetes, hoạt động như một lớp bọc chứa một hoặc nhiều container.
Cluster là gì?
- Cluster là thành phần cấp cao nhất trong Kubernetes, bao gồm nhiều worker node chạy các Pod.
2. Khởi động Minikube Cluster
Chạy lệnh sau để khởi động Minikube:
minikube start --driver=virtualbox
Minikube sẽ bắt đầu chạy. Nếu bạn sử dụng Docker driver, bạn có thể sử dụng tùy chọn mount như sau:
minikube start --mount --mount-string="$HOME:/src" --driver=docker
Tuy nhiên, với VirtualBox, tùy chọn mount không khả dụng. (Nhưng VirtualBox miễn phí, trong khi Docker Desktop có giới hạn...)
Bây giờ, hãy cài đặt Kubernetes thông qua Minikube:
minikube kubectl -- version
Sau khi Kubernetes được cài đặt, bạn sẽ thấy thông tin về phiên bản của nó:
minikube kubectl -- version
Client Version: v1.32.0
Kustomize Version: v5.5.0
Server Version: v1.32.0
Tạo Pods
Chúng ta sẽ thiết lập môi trường PHP, Nginx, MariaDB.
1. Bật Ingress
Trước tiên, hãy bật Ingress để quản lý routing trong Kubernetes:
minikube addons enable ingress
Sau đó, vui lòng lưu phần sau dưới dạng php-mariadb.yaml
. Tệp này chứa định nghĩa về các container trong pod. Xin lưu ý rằng bạn phải sử dụng "LF" cho các ngắt dòng của tệp này chứ không phải "CRLF":
# MariaDB Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
# Deployment name
name: mariadb
# Labels for identifying the deployment
labels:
app: mariadb
spec:
# Number of MariaDB instances
replicas: 1
selector:
# Matching labels for pods
matchLabels:
app: mariadb
template:
metadata:
labels:
app: mariadb
spec:
containers:
- name: mariadb
# Docker image for MariaDB
image: mariadb:11.3
# Port on which MariaDB runs
ports:
- containerPort: 3306
# Environment variables for MariaDB
env:
- name: MYSQL_ROOT_PASSWORD
value: "rootpassword"
- name: MYSQL_DATABASE
value: "mydatabase"
- name: MYSQL_USER
value: "myuser"
- name: MYSQL_PASSWORD
value: "mypassword"
# Volume mounting for MariaDB data storage
volumeMounts:
- name: mariadb-storage
mountPath: /var/lib/mysql
# Definition of volumes
volumes:
- name: mariadb-storage
emptyDir: {}
---
# MariaDB Service
apiVersion: v1
kind: Service
metadata:
# Service name for MariaDB
name: mariadb
spec:
ports:
- port: 3306
selector:
# Selector for connecting to MariaDB pods
app: mariadb
---
# PHP Application Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
# Deployment name
name: php-app
# Labels for identifying the PHP deployment
labels:
app: php-app
spec:
# Number of PHP application instances
replicas: 1
selector:
matchLabels:
app: php-app
template:
metadata:
labels:
app: php-app
spec:
containers:
- name: php-app
# Docker image for PHP application
image: php:8.3-apache
# Port on which PHP Apache runs
ports:
- containerPort: 80
# Volume mounting for PHP application code from host machine
volumeMounts:
- name: php-app-code
mountPath: /var/www/html
- name: apache-config
mountPath: /etc/apache2/sites-enabled/000-default.conf
subPath: default
# Definition of volumes
volumes:
- name: php-app-code
hostPath:
path: "/mnt/project"
type: Directory
- name: apache-config
configMap:
name: apache-config
---
# ConfigMap for Apache Configuration
apiVersion: v1
kind: ConfigMap
metadata:
name: apache-config
data:
default: |
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
<Directory "/var/www/html">
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
DirectoryIndex index.html index.php
</Directory>
ErrorLog /var/log/apache2/error.log
CustomLog /var/log/apache2/access.log combined
</VirtualHost>
---
# PHP Application Service
apiVersion: v1
kind: Service
metadata:
# Service name for PHP application
name: php-app-service
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
selector:
# Selector for connecting to PHP pods
app: php-app
---
# Ingress resource for PHP Application
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: php-app-ingress
spec:
ingressClassName: nginx
rules:
- host: localhost
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: php-app-service
port:
number: 80
Sau đó, vui lòng lưu nội dung sau dưới dạng skaffold.yaml
:
apiVersion: skaffold/v4beta12
kind: Config
metadata:
name: php-mariadb-app
deploy:
kubectl: {}
manifests:
rawYaml:
- php-mariadb.yaml
Bây giờ môi trường của chúng ta đã sẵn sàng!
Trước khi bắt đầu môi trường, hãy tạo một thư mục mount:
mkdir mounttest
minikube mount "$Home\\Documents\\projects\\test-project\\mounttest:/mnt/project"
Lệnh mount này sẽ tiếp tục chạy. Đối với các lệnh tiếp theo, vui lòng mở một terminal mới và chạy các lệnh trên đó.
Vui lòng chạy lệnh này (vui lòng đảm bảo rằng bạn đang ở trong thư mục test-project):
cd {the test-project directory}
skaffold delete
skaffold run --force
Lệnh này sẽ tiếp tục chạy. Đối với các lệnh tiếp theo, vui lòng mở một terminal mới và chạy các lệnh trên đó.
Vui lòng đợi một lúc... Môi trường kubernetes của bạn đang được tạo trong cụm Minikube. Việc này sẽ mất thời gian một chút.
Bây giờ PHP và MariaDB của bạn sẽ chạy. Hãy kiểm tra bằng cách sử dụng lệnh kubectl get pods
:
kubectl get pods
NAME READY STATUS RESTARTS AGE
mariadb-998f96ddb-84kqs 1/1 Running 0 64s
php-app-bf6f77579-454jl 1/1 Running 0 64s
Nếu tất cả đều là "Ready 1/1", điều đó có nghĩa là môi trường của bạn đang chạy mà không có vấn đề gì.
Nhân tiện, chúng được gọi là pod:
mariadb-998f96ddb-84kqs (pod)
php-app-bf6f77579-454jl (pod)
Các containers được định nghĩa trong tệp YAML sẽ được triển khai bên trong các Pods. Một Pod có thể chứa nhiều Containers.
Đôi khi, chúng ta cần một container riêng biệt để ghi log hoặc thực hiện một chức năng bổ sung. Khi đặt container này vào cùng một Pod với container PHP, nó được gọi là Sidecar Container.
Nếu có bất kỳ Pod nào không sẵn sàng, bạn có thể kiểm tra thông tin chi tiết bằng lệnh sau:
kubectl describe pod php-app-bf6f77579-454jl
Hoặc kiểm tra logs của Pod bằng lệnh:
kubectl logs php-app-bf6f77579-454jl
Để xem thông tin trên toàn bộ Cluster, hãy sử dụng:
kubectl get events --sort-by='.metadata.creationTimestamp'
Sau khi các Pods đã được tạo thành công, để truy cập Minikube từ máy host, hãy chạy lệnh sau:
minikube tunnel
Lệnh này sẽ chạy liên tục để duy trì kết nối. Để thực hiện các lệnh khác trong khi tunnel đang chạy, bạn cần mở một terminal mới để tiếp tục nhập lệnh.
Mount /var/www/html
lên máy Host và truy cập qua Ingress
Chạy lệnh sau để kiểm tra thông tin Ingress và nhận kết quả trả về:
kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
php-app-ingress <none> localhost 192.168.59.100 80 103s
Sau đó, truy cập 192.168.59.100 từ trình duyệt. Nếu bạn thấy lỗi 404, nghĩa là cấu hình ingress đã hoạt động.
Chạy lại lệnh kiểm tra Ingress để xác nhận địa chỉ IP:
kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
php-app-ingress nginx localhost 192.168.59.100 80 93s
Với địa chỉ 192.168.59.100, hãy cập nhật lại tệp php-mariadb.yaml để định cấu hình ingress.
# Ingress resource for PHP Application
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: php-app-ingress
spec:
ingressClassName: nginx
rules:
- host: 192.168.59.100.nip.io #!!! Change here !!!!
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: php-app-service
port:
number: 80
Chúng ta đã mount thư mục mounttest
của host PC vào /mnt/project
của Minikube. Đồng thời, /mnt/project
lại được mount vào /var/www/html
của Pod php-apache.
Hãy tạo tệp index.php
trong thư mục mounttest
của dự án:
<?php
echo "Hello World!";
Lưu tệp này vào thư mục mounttest
của bạn trên máy host.
Bây giờ, hãy mở trình duyệt và truy cập:
http://192.168.59.100.nip.io/
Bạn sẽ thấy dòng chữ Hello World! hiển thị trên màn hình.
- Nếu bạn thay đổi mã PHP, bạn sẽ thấy sự thay đổi ngay lập tức.
- Nếu thay đổi không phản ánh ngay, hãy tắt opcache trong php.ini:
opcache.enable=0
opcache.validate_timestamps=1
opcache.revalidate_freq=0
Cấu hình MariaDB để truy cập từ Máy Host
Bây giờ, hãy thay đổi dịch vụ MariaDB để có thể truy cập trực tiếp từ host PC.
# MariaDB Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
# Deployment name
name: mariadb
# Labels for identifying the deployment
labels:
app: mariadb
spec:
# Number of MariaDB instances
replicas: 1
selector:
# Matching labels for pods
matchLabels:
app: mariadb
template:
metadata:
labels:
app: mariadb
spec:
containers:
- name: mariadb
# Docker image for MariaDB
image: mariadb:11.3
# Port on which MariaDB runs
ports:
- containerPort: 3306
# Environment variables for MariaDB
env:
- name: MYSQL_ROOT_PASSWORD
value: "rootpassword"
- name: MYSQL_DATABASE
value: "mydatabase"
- name: MYSQL_USER
value: "myuser"
- name: MYSQL_PASSWORD
value: "mypassword"
# Volume mounting for MariaDB data storage
volumeMounts:
- name: mariadb-storage
mountPath: /var/lib/mysql
# Definition of volumes
volumes:
- name: mariadb-storage
emptyDir: {}
---
kind: Service
apiVersion: v1
metadata:
name: mariadb
spec:
type: NodePort
selector:
app: mariadb
ports:
- port: 3306
targetPort: 3306
protocol: TCP
nodePort: 30036 # for example (must be within the allowed range, e.g., 30000-32767)
---
# PHP Application Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
# Deployment name
name: php-app
# Labels for identifying the PHP deployment
labels:
app: php-app
spec:
# Number of PHP application instances
replicas: 1
selector:
matchLabels:
app: php-app
template:
metadata:
labels:
app: php-app
spec:
containers:
- name: php-app
# Docker image for PHP application
image: php:8.3-apache
# Port on which PHP Apache runs
ports:
- containerPort: 80
# Volume mounting for PHP application code from host machine
volumeMounts:
- name: php-app-code
mountPath: /var/www/html
- name: apache-config
mountPath: /etc/apache2/sites-enabled/000-default.conf
subPath: default
# Definition of volumes
volumes:
- name: php-app-code
hostPath:
path: "/mnt/project"
type: Directory
- name: apache-config
configMap:
name: apache-config
---
# ConfigMap for Apache Configuration
apiVersion: v1
kind: ConfigMap
metadata:
name: apache-config
data:
default: |
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
<Directory "/var/www/html">
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
DirectoryIndex index.html index.php
</Directory>
ErrorLog /var/log/apache2/error.log
CustomLog /var/log/apache2/access.log combined
</VirtualHost>
---
# PHP Application Service
apiVersion: v1
kind: Service
metadata:
# Service name for PHP application
name: php-app-service
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
selector:
# Selector for connecting to PHP pods
app: php-app
---
# Ingress resource for PHP Application
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: php-app-ingress
spec:
ingressClassName: nginx
rules:
- host: 192.168.59.100.nip.io #!!! Change here !!!!
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: php-app-service
port:
number: 80
Dịch vụ MariaDB trong Minikube hiện đang sử dụng NodePort, giúp chúng ta có thể truy cập từ máy host.
Tiếp theo, hãy dừng quá trình Skaffold đang chạy bằng cách nhấn CTRL + C trong terminal đã khởi chạy lệnh.
Sau đó, điều hướng đến thư mục dự án và chạy lại Skaffold:
cd {the test-project directory}
skaffold delete
skaffold run --force
Lệnh này sẽ xóa tài nguyên cũ và chạy lại toàn bộ quá trình triển khai.
Kế đến, chạy lệnh sau để lấy địa chỉ IP của Minikube:
minikube ip
Ví dụ, nếu địa chỉ IP trả về là 192.168.59.100, ta sẽ sử dụng nó để kết nối đến MariaDB.
Nó sẽ cung cấp cho bạn địa chỉ IP của minikube. Bạn có thể sử dụng IP này và NodePort để truy cập MariaDB.
Với tôi, địa chỉ IP là 192.168.59.100. NodePort được định nghĩa là 30036 trong tệp yaml.
Vì vậy, bằng cách sử dụng cả 192.168.59.100:30036, bạn có thể truy cập MariaDB.
Xin lưu ý rằng môi trường của MariaDB được cấu hình theo cách này:
- name: MYSQL_ROOT_PASSWORD
value: "rootpassword"
- name: MYSQL_DATABASE
value: "mydatabase"
- name: MYSQL_USER
value: "myuser"
- name: MYSQL_PASSWORD
value: "mypassword"
Bạn có thể sử dụng các thông tin trên để truy cập MariaDB từ ứng dụng PHP hoặc từ máy host.
Hy vọng thông tin trong bài sẽ giúp ích cho các bạn trong việc tạo môi trường phát triển K8s bằng Minikube.
Nếu bạn quan tâm tới Kubernetes, có thể tham khảo thêm bài viết sau: Kubernetes (K8s) là gì? Tìm hiểu cơ bản về Kubernetes
All rights reserved