K8S 6: Using Postgresql Run Outside Cluster (in Another Host Ec2)
If you delete the database pod all data is lost. We'll fix this by using a database that lives externally to our cluster.
Table of Contents
If you delete the database pod all data is lost. We’ll fix this by using a database that lives externally to our cluster.
Yêu cầu
Workplace: Amazon EC2 Linux
Đã tạo môi trường, cluster của riêng bạn, có thể dùng eksctl
tạo từ file cluster.yaml
sau
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: base-project
region: us-east-1
availabilityZones: ["us-east-1a", "us-east-1d"]
nodeGroups:
- name: nodegrp-1
instanceType: t2.medium
desiredCapacity: 1
ssh: # import public key from file
publicKeyPath: /home/ec2-user/.ssh/id_rsa.pub
Chú ý:
Sử dụng ssh-keygen
để generate ra bộ key (id_rsa.pub, id_rsa) dùng để SSH vào Node
Tạo cluster
eksctl create cluster -f cluster.yaml
Clone project
cd ~
git clone https://github.com/hoangmnsd/kubernetes-series
cd kubernetes-series
ll
Bài này sẽ dựa trên 2 folder spring-maven-postgres-docker-k8s-helm
và spring-maven-postgres-docker-k8s
Cuối cùng sẽ lưu lại sản phẩm trong folder spring-maven-postgres-docker-k8s-helm-externaldb
Cách làm
Khái quát
trước tiên mục tiêu mình sẽ để PostgreSQL DB chạy trên con workplace EC2 bằng docker. Rồi trên cluster sẽ chỉ chạy app Spring boot thôi, và app đó sẽ chọc vào PostgreSQL DB mình đã tạo
Cụ thể
Chuẩn bị biến môi trường
export AWS_DEFAULT_REGION=us-east-1
export DOCKER_USERNAME=AAAAAA
export DOCKER_PASSWORD=BBBBBB
export DOCKER_USER_ID=CCCCCC
docker login -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD"
Giờ sẽ chạy con postgreSQL DB
Trong trường hợp chưa có image thì cần build docker image trước:
cd spring-maven-postgres-docker-k8s/docker/postgres
docker build -f Dockerfile -t $DOCKER_USERNAME/docker_postgres .
Vì cái image Postgres cần truyền vào các biến môi trường env nên mình chạy lệnh sau:
docker run --env POSTGRES_USER=dbuser --env POSTGRES_PASSWORD=password --env POSTGRES_DB=store -d -p 5432:5432 hoangmnsd/docker_postgres
Sau khi chạy xong muốn check việc tạo db đã ok chưa thì ssh vào container đó
docker ps
docker exec -it <CONTAINER_NAME> bash
su postgres
psql -p 5432 store -U dbuser
# show all database
\list
# show all table
\d
Nếu thấy database “store” và table “product” có nghĩa là đã run db thành công
root@7b00518cc6c3:/# su postgres
postgres@7b00518cc6c3:/$ psql -p 5432 store -U dbuser
psql (12.0 (Debian 12.0-2.pgdg100+1))
Type "help" for help.
store=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+--------+----------+------------+------------+-------------------
postgres | dbuser | UTF8 | en_US.utf8 | en_US.utf8 |
store | dbuser | UTF8 | en_US.utf8 | en_US.utf8 | =Tc/dbuser +
| | | | | dbuser=CTc/dbuser
template0 | dbuser | UTF8 | en_US.utf8 | en_US.utf8 | =c/dbuser +
| | | | | dbuser=CTc/dbuser
template1 | dbuser | UTF8 | en_US.utf8 | en_US.utf8 | =c/dbuser +
| | | | | dbuser=CTc/dbuser
(4 rows)
store=# \d
List of relations
Schema | Name | Type | Owner
--------+--------------------+----------+--------
public | hibernate_sequence | sequence | dbuser
public | product | table | dbuser
(2 rows)
Giờ nên test connection giữa Node và Host (Workplace EC2) xem đã connect dc tới DB hay chưa
SSH vào Node
ssh -i ~/.ssh/id_rsa ec2-user@<EC2-NODE-PUBLIC-IP>
Bởi vì Node là Amazon linux 2, nên cần install psql client bằng command sau:
sudo amazon-linux-extras install postgresql10 -y
Sau đó dùng psql
để connect vào DB đang chạy trên Workplace xem được ko
# psql -h <EC2-PUBLIC-IP> -p 5432 <DB_NAME> <DB_USER>
psql -h 34.238.123.20 -p 5432 store dbuser
nhập password la` “password” (cái này mình define trong biến môi trường khi truyền vào và run docker image postgres)
Nếu connect thành công thử list db và list table xem
\list
\d
Nếu thấy database “store” và table “product” có nghĩa là đã connect db thành công
Nếu ko thấy nghĩa là connect ko thành công thì nên check Security Group xem Workplace đã mở port 5432 cho con Node connect vào chưa
Giờ cần sửa project Spring và Helm chart để khi deploy lên cluster nó có thể connect vào DB đang ở 1 máy EC2 khác (chính là máy workplace của mình)
nano spring-maven-postgres-docker-k8s/src/main/resources/application.yml
sửa URL của PostgreSQL DB như sau:
#below is config for Docker compose
#ENV_DATASOURCE_URL: jdbc:postgresql://postgres/store
#below is config for postgresql in local windows
#ENV_DATASOURCE_URL: jdbc:postgresql://localhost:5432/store
#below is config for k8s, using service_name:5432 to connect db
#ENV_DATASOURCE_URL: jdbc:postgresql://docker-postgres:5432/store
#below is config for k8s, using a external db running in another machine
ENV_DATASOURCE_URL: jdbc:postgresql://34.238.123.20:5432/store #đây là EC2-PUBLIC-IP của con máy mà mình đang run Postgres DB
sau đó build là file jar và đóng docker image mới
cd spring-maven-postgres-docker-k8s
mvn clean package
docker build -f Dockerfile -t $DOCKER_USERNAME/docker_spring-boot-containers .
cần push lên Docker Hub để sau này helm chart pull về
docker push $DOCKER_USERNAME/docker_spring-boot-containers
Tiếp là sửa helm chart, đầu tiên sửa file Service của Postgres
nano spring-maven-postgres-docker-k8s-helm/templates/docker_postgres-service-external.yaml
apiVersion: v1
kind: Service
metadata:
name: docker-postgres
labels:
app: docker-postgres
spec:
type: ExternalName
externalName: {{ .Values.postgresService.externalName }}
selector:
app: docker-postgres
bởi vì ko tạo pod cho Postgresql mà sẽ dùng bên ngoài nên cần xóa file docker_postgres-deployment.yaml
, bạn sẽ thấy file đó ko còn trong folder spring-maven-postgres-docker-k8s-helm-externaldb
nữa
cần sửa file values.yaml
nữa
postgresService:
type: ClusterIP
port: 5432
targetPort: 5432
externalName: 34.238.123.20 #đây là IP của con máy mà mình đang run Postgres DB
vậy là chuẩn bị xong giờ có thể install helm chart
cd spring-maven-postgres-docker-k8s-helm
helm install -n spring-postgres .
$ kubectl get pods,svc -A
NAMESPACE NAME READY STATUS RESTARTS AGE
default pod/docker-spring-boot-containers-54566ddbc8-8dpkf 1/1 Running 0 39s
kube-system pod/aws-node-jpx87 1/1 Running 0 27m
kube-system pod/coredns-8455f84f99-7wzm8 1/1 Running 0 32m
kube-system pod/coredns-8455f84f99-dpxld 1/1 Running 0 32m
kube-system pod/kube-proxy-r9tsx 1/1 Running 0 27m
kube-system pod/tiller-deploy-586965d498-58gn9 1/1 Running 0 50s
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default service/docker-postgres ExternalName <none> 34.238.123.20 <none> 39s
default service/docker-spring-boot-containers NodePort 10.100.248.57 <none> 12345:32594/TCP 39s
default service/kubernetes ClusterIP 10.100.0.1 <none> 443/TCP 32m
kube-system service/kube-dns ClusterIP 10.100.0.10 <none> 53/UDP,53/TCP 32m
kube-system service/tiller-deploy ClusterIP 10.100.5.254 <none> 44134/TCP 50s
Check logs của pod nếu ko có lỗi kết nối DB là thành công
kubectl logs pod/docker-spring-boot-containers-54566ddbc8-8dpkf
vì ở trên Spring pod đang dùng kiểu NodePort nên cần forward port để mọi nơi có thể dùng:
kubectl port-forward -n default service/docker-spring-boot-containers 32594:12345 --address 0.0.0.0
Sau đó có thể insert DB bằng cách dùng POSTMAN send POST request đến http://<EC2-PUBLIC-IP>:32594/v1/product
với body:
{"name":"product001"}
Bây giờ khi xóa cluster tạo lại thì DB vẫn còn đó, bởi vì nó đc giữ ở 1 con EC2 khác
Tuy nhiên trên workplace nếu mình stop docker thì DB sẽ mất, nên cần mount volume dể lưu DB ra bên ngoài docker
việc này thuộc về kĩ thuật dùng docker
tất cả những thay đổi vừa xong được lưu trong folder spring-maven-postgres-docker-k8s-helm-externaldb
CREDIT
https://github.com/red-gate/ks/blob/master/ks8-2/ks8-2.md https://stackoverflow.com/questions/49573258/installing-postgresql-client-v10-on-aws-amazon-linux-ec2-ami https://stackoverflow.com/questions/37694987/connecting-to-postgresql-in-a-docker-container-from-outside https://severalnines.com/database-blog/using-kubernetes-deploy-postgresql https://stackoverflow.com/questions/26040493/how-to-show-data-in-a-table-by-using-psql-command-line-interface
Thank You!
Your comment has been submitted. It will appear on this page shortly! OKYikes, Sorry!
Error occured. Couldn't submit your comment. Please try again. Thank You! OK