[Kubernetes][GCP] GKE kết nối với Cloud Sql thông qua Cloud Sql Proxy
Bài viết chia sẻ cách kết nối với SQL từ kubernetes cluster thông qua Cloud SQL Proxy
Trên thực tế, từ GKE hay GAE vẫn kết nối trực tiếp vào được SQL, nhưng phải thông qua IP của SQL. Bài viết này chia sẻ cách kết nối thông qua CloudSQL Proxy.
Tại sao lại cần dùng CloudSQL Proxy?
- Dữ liệu được truyền đi giữa app vs sql sẽ được mã hoá – đảm bảo tính bảo mật an toàn.
- Ưu điểm thứ 2 là không cần quan tâm địa chỉ IP của cloud sql. Theo như hình minh hoạ trên, thì Rails(app) và CloudSQL Proxy cùng nằm trong một container, nên khai báo host kết nối đến Cloud sql sẽ là 127.0.0.1
1| Chuẩn bị môi trường
- Cài đặt docker ở local → Tham khảo tại đây
- Cài đặt kubernetes ở local → Tham khảo tại đây
- Cài đặt Google Cloud SDK ở local → Tham khảo tại đây
- Tạo project trên Google Cloud Platform Console. Lưu lại Project ID vì sẽ cần dùng.
2| Kết nối với Project từ local thông qua gloud sdk
gcloud init
Sau khi chạy câu lệnh trên, bạn cần khai báo một vài thông tin như account google, project name, v.v…
2| Cấu hình Cloud Sql
-
2|1 Tạo Cloud Sql
Tạo một cơ sở dữ liệu tên là
cakephp-dev-sql-instance
. Phần tạo này có thể tạo trực tiếp trên màn hình console. Ở đây chia sẻ cách tạo bằng command line.
gcloud sql instances create cakephp-dev-sql-instance \
--database-version=MYSQL_5_6 \
--activation-policy=always \
--tier=db-n1-standard-1
-
2|2 Tạo user có tên là proxyuser
Phần đặt tên là tuỳ ý. Ở đây lấy tên là proxyuser cho dễ hiểu.
・-i
: tên của cơ sở dữ liệu đã tạo ở bước trên
gcloud sql users create proxyuser -i cakephp-dev-sql-instance --host=cloudsqlproxy~% --password=root
-
2|3 Tạo key
gcloud iam service-accounts create proxy-user --display-name "proxy-user"
gcloud projects add-iam-policy-binding [PROJECT_ID] --member \
serviceAccount:[SERVICE_ACCOUNT_EMAIL] --role roles/cloudsql.client
gcloud iam service-accounts keys create key.json --iam-account [SERVICE_ACCOUNT_EMAIL]
kubectl create secret generic cloudsql-instance-credentials --from-file=credentials.json=key.json
kubectl create secret generic cloudsql-db-credentials --from-literal=username=proxyuser --from-literal=password=root
-
2|4 Thử truy cập vs cloud sql tại local bằng cloud_sql_proxy
# cài đặt cloud_sql_proxy
wget https://dl.google.com/cloudsql/cloud_sql_proxy.linux.amd64 -O cloud_sql_proxy
chmod +x cloud_sql_proxy
# lấy instance name
gcloud sql instances describe memegen-db | grep connectionName
# mở kết nối đến cloud sql
./cloud_sql_proxy -instances=freenance-dev:us-central1:cakephp-dev-sql-instance=tcp:30180 -credential_file=key.json &
# truy cập vào mysql
mysql -u proxyuser -p --host 127.0.0.1 --port 30180
CREATE DATABASE study_demo;
USE study_demo;
CREATE TABLE example ( id smallint unsigned not null auto_increment, name varchar(20) not null, constraint pk_example primary key (id) );
INSERT INTO example ( id, name ) VALUES ( null, 'Sample data 1' );
INSERT INTO example ( id, name ) VALUES ( null, 'Sample data 2' );
INSERT INTO example ( id, name ) VALUES ( null, 'Sample data 3' );
3| Tạo cluster
# tạo cluster
gcloud container clusters create frnc-dev-cluster --machine-type=n1-standard-1 --min-nodes=1
# connect to cluster
gcloud container clusters get-credentials frnc-dev-cluster --zone asia-northeast2-a --project freenance-dev
4| Tạo container từ image apache
docker run -tid -p 32157:80 --name apache_server nimmis/apache-php5
# docker run --name mynginx1 -P -d nginx
5| Truy cập vào container và tạo file index.php
docker exec -it apache_server bash
vi /var/www/html/index.php
# index.php
$servername = "127.0.0.1:30180";
$username = "proxyuser";
$password = "root";
$dbname = "study_demo";
// Create connection
$conn = mysqli_connect($servername, $username, $password, $dbname);
// Check connection
if (!$conn) {
die("Connection failed: " . mysqli_connect_error());
}
$sql = "select * from example";
$result = mysqli_query($conn, $sql);
if (mysqli_num_rows($result) > 0) {
// output data of each row
while($row = mysqli_fetch_assoc($result)) {
echo "id: " . $row["id"]. " - Name: " . $row["name"]. "<br>";
}
} else {
echo "0 results";
}
mysqli_close($conn);
6| Tạo image từ container vừa tạo trên
docker commit apache_server gcr.io/my-project/study_apache_server
7| Đẩy image lên container registry của GCP
gcloud docker -- push gcr.io/my-project/study_apache_server
8| Tạo script cho deployment
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: php-myapp
image: gcr.io/my-project/study_apache_server
resources:
requests:
cpu: 100m
memory: 100Mi
ports:
- containerPort: 80
- name: cloudsql-proxy
image: gcr.io/cloudsql-docker/gce-proxy:1.11
command: ["/cloud_sql_proxy", "-instances=freenance-dev:us-central1:cakephp-dev-sql-instance=tcp:30180", "-credential_file=/secrets/cloudsql/credentials.json"]
volumeMounts:
- name: cloudsql-instance-credentials
mountPath: /secrets/cloudsql
readOnly: true
volumes:
- name: cloudsql-instance-credentials
secret:
secretName: cloudsql-instance-credentials
- name: cloudsql
emptyDir:
8| Tạo script cho service
# service.yaml
apiVersion: v1
kind: Service
metadata:
name: myservice
labels:
app: myservice
spec:
type: LoadBalancer
ports:
- port: 80
selector:
app: myapp
9| Deploy lên GCP
kubectl create -f deployment.yml
kubectl create -f service.yml
10| Xem thông tin của EXTERNAL-IP
kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
myservice LoadBalancer 10.43.250.127 35.xxx.xxx.52 80:31530/TCP 12d
Tham khảo
- https://logz.io/blog/deploying-kubernetes-gke/
- https://www.youtube.com/watch?v=bN000CEg7IM
- https://www.jhipster.tech/tips/018_tip_kubernetes_and_google_cloud_sql.html
- https://medium.com/@nithinmallya4/using-the-cloudsql-proxy-to-talk-to-mysql-from-your-gke-rails-application-aa53f2611b78
- https://blog.risingstack.com/deploying-a-stateful-application-on-google-cloud-kubernetes-engine/
- https://codelabs.developers.google.com/codelabs/cloud-postgresql-gke-memegen/#0