lan1note

[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

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

Leave a Reply

Your email address will not be published. Required fields are marked *