GKE 어플리케이션과 클라우드 SQL 데이터베이스 간 연결 보호
IAM 서비스 계정
Workload Identity는 GKE에서 실행되는 앱에서 구글 클라우드 서비스에 접근하는 것을 추천하는 방식이다.
With Workload Identity, you can configure a Kubernetes service account to act as a Google service account. Pods running as the Kubernetes service account will automatically authenticate as the Google service account when accessing Google Cloud APIs.
이 구글 서비스 계정을 만들어 봅시다.파일을 만듭니다infra/plan/service-account.tf
.
resource "google_service_account" "web" {
account_id = "cloud-sql-access"
display_name = "Service account used to access cloud sql instance"
}
resource "google_project_iam_binding" "cloudsql_client" {
role = "roles/cloudsql.client"
members = [
"serviceAccount:cloud-sql-access@${data.google_project.project.project_id}.iam.gserviceaccount.com",
]
}
data "google_project" "project" {
}
그리고 infra/k8s/data/service-account.yaml
의 관련 Kubernetes 서비스 계정:
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
iam.gke.io/gcp-service-account: cloud-sql-access@<PROJECT_ID>.iam.gserviceaccount.com
name: cloud-sql-access
업데이트된 terraform을 실행합니다.
cd infra/plan
terraform apply
Kubernetes 서비스 계정을 만들려면 다음과 같이 하십시오.
gcloud container clusters get-credentials private --region $REGION --project $PROJECT_ID
$ kubectl create namespace wordpress
sed -i "s/<PROJECT_ID>/$PROJECT_ID/g;" infra/k8s/data/service-account.yaml
$ kubectl create -f infra/k8s/data/service-account.yaml -n wordpress
클라우드 SQL 에이전트 배치는 Kubernetes 서비스 계정을 사용하여 클라우드 SQL 실례에 접근할 것입니다.
Kubernetes 서비스 계정이 둘 사이의 IAM 정책을 통해 시뮬레이션된 Google 서비스 계정을 연결할 수 있도록 합니다.
gcloud iam service-accounts add-iam-policy-binding \
--role roles/iam.workloadIdentityUser \
--member "serviceAccount:$PROJECT_ID.svc.id.goog[wordpress/cloud-sql-access]" \
cloud-sql-access@$PROJECT_ID.iam.gserviceaccount.com
클라우드 SQL 에이전트
Cloud SQL Auth 에이전트를 사용하여 네트워크를 위임하거나 SSL을 구성할 필요 없이 Cloud SQL 인스턴스에 대한 액세스를 보호합니다.
리소스 배포부터 시작하겠습니다.infra/k8s/data/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: cloud-sql-proxy
name: cloud-sql-proxy
spec:
selector:
matchLabels:
app: cloud-sql-proxy
strategy: {}
replicas: 3
template:
metadata:
labels:
app: cloud-sql-proxy
spec:
serviceAccountName: cloud-sql-access
containers:
- name: cloud-sql-proxy
image: gcr.io/cloudsql-docker/gce-proxy:1.23.0
ports:
- containerPort: 3306
protocol: TCP
envFrom:
- configMapRef:
name: cloud-sql-instance
command:
- "/cloud_sql_proxy"
- "-ip_address_types=PRIVATE"
- "-instances=$(CLOUD_SQL_PROJECT_ID):$(CLOUD_SQL_INSTANCE_REGION):$(CLOUD_SQL_INSTANCE_NAME)=tcp:0.0.0.0:3306"
securityContext:
runAsNonRoot: true
resources:
requests:
memory: 2Gi
cpu: 1
자원을 배치하는 것은 이전에 만들어진 서비스 계정을 가리킨다.Kubernetes 구성 매핑에서 클라우드 SQL 인스턴스 세부 정보를 읽어들이려면 다음과 같이 하십시오.infra/k8s/data/config-map.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: cloud-sql-instance
data:
CLOUD_SQL_INSTANCE_NAME: <CLOUD_SQL_INSTANCE_NAME>
CLOUD_SQL_INSTANCE_REGION: <CLOUD_SQL_REGION>
CLOUD_SQL_PROJECT_ID: <CLOUD_SQL_PROJECT_ID>
Google은 Kubernetes 서비스를 사용하여 자원을 공개적으로 배치합니다.infra/k8s/data/service.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app: cloud-sql-proxy
name: cloud-sql-proxy
spec:
ports:
- port: 3306
protocol: TCP
name: cloud-sql-proxy
targetPort: 3306
selector:
app: cloud-sql-proxy
리소스를 만들고 연결이 설정되었는지 확인합니다.
cd infra/plan
sed -i "s/<CLOUD_SQL_PROJECT_ID>/$PROJECT_ID/g;s/<CLOUD_SQL_INSTANCE_NAME>/$(terraform output cloud-sql-instance-name | tr -d '"')/g;s/<CLOUD_SQL_REGION>/$REGION/g;" ../k8s/data/config-map.yaml
$ kubectl create -f ../k8s/data -n wordpress
$ kubectl get pods -l app=cloud-sql-proxy -n wordpress
NAME READY STATUS RESTARTS AGE
cloud-sql-proxy-fb9968d49-hqlwb 1/1 Running 0 4s
cloud-sql-proxy-fb9968d49-wj498 1/1 Running 0 5s
cloud-sql-proxy-fb9968d49-z95zw 1/1 Running 0 4s
$ kubectl logs cloud-sql-proxy-fb9968d49-hqlwb -n wordpress
2021/06/23 14:43:21 current FDs rlimit set to 1048576, wanted limit is 8500. Nothing to do here.
2021/06/23 14:43:25 Listening on 0.0.0.0:3306 for <PROJECT_ID>:<REGION>:<CLOUD_SQL_INSTANCE_NAME>
2021/06/23 14:43:25 Ready for new connections
좋아요!Wordpress 응용 프로그램으로 이동합니다.
Wordpress 응용 프로그램
리소스 배포부터 시작하겠습니다.infra/k8s/web/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress
labels:
app: wordpress
spec:
selector:
matchLabels:
app: wordpress
strategy:
type: Recreate
template:
metadata:
labels:
app: wordpress
spec:
containers:
- image: wordpress
name: wordpress
env:
- name: WORDPRESS_DB_HOST
value: cloud-sql-proxy:3306
- name: WORDPRESS_DB_USER
value: wordpress
- name: WORDPRESS_DB_NAME
value: wordpress
- name: WORDPRESS_DB_PASSWORD
valueFrom:
secretKeyRef:
name: mysql
key: password
ports:
- containerPort: 80
name: wordpress
volumeMounts:
- name: wordpress-persistent-storage
mountPath: /var/www/html
livenessProbe:
initialDelaySeconds: 30
httpGet:
port: 80
path: /wp-admin/install.php # at the very beginning, this is the only accessible page. Don't forget to change to /wp-login.php
readinessProbe:
httpGet:
port: 80
path: /wp-admin/install.php
resources:
requests:
cpu: 1000m
memory: 2Gi
limits:
cpu: 1200m
memory: 2Gi
volumes:
- name: wordpress-persistent-storage
persistentVolumeClaim:
claimName: wordpress
infra/k8s/web/service.yaml
apiVersion: v1
kind: Service
metadata:
name: wordpress
annotations:
cloud.google.com/neg: '{"ingress": true}'
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
selector:
app: wordpress
The cloud.google.com/neg
annotation specifies that port 80 will be associated with a zonal network endpoint group (NEG). See Container-native load balancing for information on the benefits, requirements, and limitations of container-native load balancing.
Wordpress를 위한 PVC를 만들었습니다.infra/k8s/web/volume-claim.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: wordpress
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
Kubernetes 입구 자원을 초기화함으로써 이 부분을 완성합니다.이 자원은 인터넷에서Wordpress 프로그램에 접근할 수 있도록 합니다.
파일 생성infra/k8s/web/ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.global-static-ip-name: "wordpress"
kubernetes.io/ingress.class: "gce"
name: wordpress
spec:
defaultBackend:
service:
name: wordpress
port:
number: 80
rules:
- http:
paths:
- path: /*
pathType: ImplementationSpecific
backend:
service:
name: wordpress
port:
number: 80
The kubernetes.io/ingress.global-static-ip-name
annotation specifies the name of the global IP address resource to be associated with the HTTP(S) Load Balancer. [2]
리소스를 만들고 Wordpress 응용 프로그램을 테스트합니다.
cd infra/k8s
$ kubectl create secret generic mysql \
--from-literal=password=$(gcloud secrets versions access latest --secret=wordpress-admin-user-password --project $PROJECT_ID) -n wordpress
gcloud compute addresses create wordpress --global
$ kubectl create -f web -n wordpress
$ kubectl get pods -l app=wordpress -n wordpress
NAME READY STATUS RESTARTS AGE
wordpress-6d58d85845-2d7x2 1/1 Running 0 10m
$ kubectl get ingress -n wordpress
NAME CLASS HOSTS ADDRESS PORTS AGE
wordpress <none> * 34.117.187.51 80 16m
누구나 이 프로그램에 접근할 수 있습니다.데이터 흐름을 유일하게 권한을 부여받은 네트워크로 제한하는 클라우드 장갑 보안 정책을 만듭니다.
운장갑 안전 전략
외부 HTTP(S) 로드 밸런서에 전송되는 전송 트래픽을 필터링하기 위해 Cloud Armor security policy를 사용합니다.
생성ìnfra/plan/cloud-armor.tf
:
resource "google_compute_security_policy" "wordpress" {
name = "wordpress"
rule {
action = "allow"
priority = "1000"
match {
versioned_expr = "SRC_IPS_V1"
config {
src_ip_ranges = var.authorized_source_ranges
}
}
description = "Allow access to authorized source ranges"
}
rule {
action = "deny(403)"
priority = "2147483647"
match {
versioned_expr = "SRC_IPS_V1"
config {
src_ip_ranges = ["*"]
}
}
description = "default rule"
}
}
업데이트된 terraform을 실행합니다.
cd infra/plan
terraform apply
Kubernetes에서 백엔드 설정을 만들고 보안 정책을 참고하십시오.
BackendConfig custom resource definition (CRD) allows us to further customize the load balancer. This CRD allows us to define additional load balancer features hierarchically, in a more structured way than annotations. [3]
infra/k8s/web/backend.yaml
apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
name: wordpress
spec:
securityPolicy:
name: wordpress
kubectl create -f infra/k8s/web/backend.yaml -n wordpress
wordpress 서비스에 메모 추가cloud.google.com/backend-config: '{"default": "wordpress"}'
:
kubectl apply -f infra/k8s/web/service.yaml -n wordpress
HTTP 로드 밸런서에 보안 정책이 추가되었는지 확인합니다.
괜찮아 보여요.테스트를 해보겠습니다.
만약 우리가 거절당한다면, 나쁜 IP를 테스트하십시오
gcloud compute security-policies rules update 1000 \
--security-policy wordpress \
--src-ip-ranges "85.56.40.96"
curl http://34.117.187.51/
<!doctype html><meta charset="utf-8"><meta name=viewport content="width=device-width, initial-scale=1"><title>403</title>403 Forbidden
올바른 IP 주소를 입력하십시오.
gcloud compute security-policies rules update 1000 \
--security-policy wordpress \
--src-ip-ranges $(curl -s http://checkip.amazonaws.com/)
curl http://34.117.187.51/
<!doctype html>
<html lang="en-GB" >
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>admin – Just another WordPress site</title>
좋아요!
이 백엔드 설정을 통해 같은 사무실의 직원만 이 프로그램에 접근할 수 있습니다.현재 우리는 그들도 신분 검증을 통해 응용 프로그램에 접근할 수 있기를 바란다.우리는 Identity Aware Proxy (Cloud IAP)를 사용하여 이 점을 실현할 수 있다.
클라우드 IAP 사용
IAP를 사용하여 HTTPS를 통해 액세스하는 Wordpress 응용 프로그램의 중앙 승인 계층을 구성합니다.
IAP is integrated through Ingress for GKE. This integration enables you to control resource-level access for employees instead of using a VPN. [1]
GCP 문서에 설명된 지침을 따르십시오.
With Workload Identity, you can configure a Kubernetes service account to act as a Google service account. Pods running as the Kubernetes service account will automatically authenticate as the Google service account when accessing Google Cloud APIs.
resource "google_service_account" "web" {
account_id = "cloud-sql-access"
display_name = "Service account used to access cloud sql instance"
}
resource "google_project_iam_binding" "cloudsql_client" {
role = "roles/cloudsql.client"
members = [
"serviceAccount:cloud-sql-access@${data.google_project.project.project_id}.iam.gserviceaccount.com",
]
}
data "google_project" "project" {
}
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
iam.gke.io/gcp-service-account: cloud-sql-access@<PROJECT_ID>.iam.gserviceaccount.com
name: cloud-sql-access
cd infra/plan
terraform apply
gcloud container clusters get-credentials private --region $REGION --project $PROJECT_ID
$ kubectl create namespace wordpress
sed -i "s/<PROJECT_ID>/$PROJECT_ID/g;" infra/k8s/data/service-account.yaml
$ kubectl create -f infra/k8s/data/service-account.yaml -n wordpress
gcloud iam service-accounts add-iam-policy-binding \
--role roles/iam.workloadIdentityUser \
--member "serviceAccount:$PROJECT_ID.svc.id.goog[wordpress/cloud-sql-access]" \
cloud-sql-access@$PROJECT_ID.iam.gserviceaccount.com
Cloud SQL Auth 에이전트를 사용하여 네트워크를 위임하거나 SSL을 구성할 필요 없이 Cloud SQL 인스턴스에 대한 액세스를 보호합니다.
리소스 배포부터 시작하겠습니다.
infra/k8s/data/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: cloud-sql-proxy
name: cloud-sql-proxy
spec:
selector:
matchLabels:
app: cloud-sql-proxy
strategy: {}
replicas: 3
template:
metadata:
labels:
app: cloud-sql-proxy
spec:
serviceAccountName: cloud-sql-access
containers:
- name: cloud-sql-proxy
image: gcr.io/cloudsql-docker/gce-proxy:1.23.0
ports:
- containerPort: 3306
protocol: TCP
envFrom:
- configMapRef:
name: cloud-sql-instance
command:
- "/cloud_sql_proxy"
- "-ip_address_types=PRIVATE"
- "-instances=$(CLOUD_SQL_PROJECT_ID):$(CLOUD_SQL_INSTANCE_REGION):$(CLOUD_SQL_INSTANCE_NAME)=tcp:0.0.0.0:3306"
securityContext:
runAsNonRoot: true
resources:
requests:
memory: 2Gi
cpu: 1
자원을 배치하는 것은 이전에 만들어진 서비스 계정을 가리킨다.Kubernetes 구성 매핑에서 클라우드 SQL 인스턴스 세부 정보를 읽어들이려면 다음과 같이 하십시오.infra/k8s/data/config-map.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: cloud-sql-instance
data:
CLOUD_SQL_INSTANCE_NAME: <CLOUD_SQL_INSTANCE_NAME>
CLOUD_SQL_INSTANCE_REGION: <CLOUD_SQL_REGION>
CLOUD_SQL_PROJECT_ID: <CLOUD_SQL_PROJECT_ID>
Google은 Kubernetes 서비스를 사용하여 자원을 공개적으로 배치합니다.infra/k8s/data/service.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app: cloud-sql-proxy
name: cloud-sql-proxy
spec:
ports:
- port: 3306
protocol: TCP
name: cloud-sql-proxy
targetPort: 3306
selector:
app: cloud-sql-proxy
리소스를 만들고 연결이 설정되었는지 확인합니다.cd infra/plan
sed -i "s/<CLOUD_SQL_PROJECT_ID>/$PROJECT_ID/g;s/<CLOUD_SQL_INSTANCE_NAME>/$(terraform output cloud-sql-instance-name | tr -d '"')/g;s/<CLOUD_SQL_REGION>/$REGION/g;" ../k8s/data/config-map.yaml
$ kubectl create -f ../k8s/data -n wordpress
$ kubectl get pods -l app=cloud-sql-proxy -n wordpress
NAME READY STATUS RESTARTS AGE
cloud-sql-proxy-fb9968d49-hqlwb 1/1 Running 0 4s
cloud-sql-proxy-fb9968d49-wj498 1/1 Running 0 5s
cloud-sql-proxy-fb9968d49-z95zw 1/1 Running 0 4s
$ kubectl logs cloud-sql-proxy-fb9968d49-hqlwb -n wordpress
2021/06/23 14:43:21 current FDs rlimit set to 1048576, wanted limit is 8500. Nothing to do here.
2021/06/23 14:43:25 Listening on 0.0.0.0:3306 for <PROJECT_ID>:<REGION>:<CLOUD_SQL_INSTANCE_NAME>
2021/06/23 14:43:25 Ready for new connections
좋아요!Wordpress 응용 프로그램으로 이동합니다.Wordpress 응용 프로그램
리소스 배포부터 시작하겠습니다.infra/k8s/web/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress
labels:
app: wordpress
spec:
selector:
matchLabels:
app: wordpress
strategy:
type: Recreate
template:
metadata:
labels:
app: wordpress
spec:
containers:
- image: wordpress
name: wordpress
env:
- name: WORDPRESS_DB_HOST
value: cloud-sql-proxy:3306
- name: WORDPRESS_DB_USER
value: wordpress
- name: WORDPRESS_DB_NAME
value: wordpress
- name: WORDPRESS_DB_PASSWORD
valueFrom:
secretKeyRef:
name: mysql
key: password
ports:
- containerPort: 80
name: wordpress
volumeMounts:
- name: wordpress-persistent-storage
mountPath: /var/www/html
livenessProbe:
initialDelaySeconds: 30
httpGet:
port: 80
path: /wp-admin/install.php # at the very beginning, this is the only accessible page. Don't forget to change to /wp-login.php
readinessProbe:
httpGet:
port: 80
path: /wp-admin/install.php
resources:
requests:
cpu: 1000m
memory: 2Gi
limits:
cpu: 1200m
memory: 2Gi
volumes:
- name: wordpress-persistent-storage
persistentVolumeClaim:
claimName: wordpress
infra/k8s/web/service.yaml
apiVersion: v1
kind: Service
metadata:
name: wordpress
annotations:
cloud.google.com/neg: '{"ingress": true}'
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
selector:
app: wordpress
The cloud.google.com/neg
annotation specifies that port 80 will be associated with a zonal network endpoint group (NEG). See Container-native load balancing for information on the benefits, requirements, and limitations of container-native load balancing.
Wordpress를 위한 PVC를 만들었습니다.infra/k8s/web/volume-claim.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: wordpress
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
Kubernetes 입구 자원을 초기화함으로써 이 부분을 완성합니다.이 자원은 인터넷에서Wordpress 프로그램에 접근할 수 있도록 합니다.
파일 생성infra/k8s/web/ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.global-static-ip-name: "wordpress"
kubernetes.io/ingress.class: "gce"
name: wordpress
spec:
defaultBackend:
service:
name: wordpress
port:
number: 80
rules:
- http:
paths:
- path: /*
pathType: ImplementationSpecific
backend:
service:
name: wordpress
port:
number: 80
The kubernetes.io/ingress.global-static-ip-name
annotation specifies the name of the global IP address resource to be associated with the HTTP(S) Load Balancer. [2]
리소스를 만들고 Wordpress 응용 프로그램을 테스트합니다.
cd infra/k8s
$ kubectl create secret generic mysql \
--from-literal=password=$(gcloud secrets versions access latest --secret=wordpress-admin-user-password --project $PROJECT_ID) -n wordpress
gcloud compute addresses create wordpress --global
$ kubectl create -f web -n wordpress
$ kubectl get pods -l app=wordpress -n wordpress
NAME READY STATUS RESTARTS AGE
wordpress-6d58d85845-2d7x2 1/1 Running 0 10m
$ kubectl get ingress -n wordpress
NAME CLASS HOSTS ADDRESS PORTS AGE
wordpress <none> * 34.117.187.51 80 16m
누구나 이 프로그램에 접근할 수 있습니다.데이터 흐름을 유일하게 권한을 부여받은 네트워크로 제한하는 클라우드 장갑 보안 정책을 만듭니다.
운장갑 안전 전략
외부 HTTP(S) 로드 밸런서에 전송되는 전송 트래픽을 필터링하기 위해 Cloud Armor security policy를 사용합니다.
생성ìnfra/plan/cloud-armor.tf
:
resource "google_compute_security_policy" "wordpress" {
name = "wordpress"
rule {
action = "allow"
priority = "1000"
match {
versioned_expr = "SRC_IPS_V1"
config {
src_ip_ranges = var.authorized_source_ranges
}
}
description = "Allow access to authorized source ranges"
}
rule {
action = "deny(403)"
priority = "2147483647"
match {
versioned_expr = "SRC_IPS_V1"
config {
src_ip_ranges = ["*"]
}
}
description = "default rule"
}
}
업데이트된 terraform을 실행합니다.
cd infra/plan
terraform apply
Kubernetes에서 백엔드 설정을 만들고 보안 정책을 참고하십시오.
BackendConfig custom resource definition (CRD) allows us to further customize the load balancer. This CRD allows us to define additional load balancer features hierarchically, in a more structured way than annotations. [3]
infra/k8s/web/backend.yaml
apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
name: wordpress
spec:
securityPolicy:
name: wordpress
kubectl create -f infra/k8s/web/backend.yaml -n wordpress
wordpress 서비스에 메모 추가cloud.google.com/backend-config: '{"default": "wordpress"}'
:
kubectl apply -f infra/k8s/web/service.yaml -n wordpress
HTTP 로드 밸런서에 보안 정책이 추가되었는지 확인합니다.
괜찮아 보여요.테스트를 해보겠습니다.
만약 우리가 거절당한다면, 나쁜 IP를 테스트하십시오
gcloud compute security-policies rules update 1000 \
--security-policy wordpress \
--src-ip-ranges "85.56.40.96"
curl http://34.117.187.51/
<!doctype html><meta charset="utf-8"><meta name=viewport content="width=device-width, initial-scale=1"><title>403</title>403 Forbidden
올바른 IP 주소를 입력하십시오.
gcloud compute security-policies rules update 1000 \
--security-policy wordpress \
--src-ip-ranges $(curl -s http://checkip.amazonaws.com/)
curl http://34.117.187.51/
<!doctype html>
<html lang="en-GB" >
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>admin – Just another WordPress site</title>
좋아요!
이 백엔드 설정을 통해 같은 사무실의 직원만 이 프로그램에 접근할 수 있습니다.현재 우리는 그들도 신분 검증을 통해 응용 프로그램에 접근할 수 있기를 바란다.우리는 Identity Aware Proxy (Cloud IAP)를 사용하여 이 점을 실현할 수 있다.
클라우드 IAP 사용
IAP를 사용하여 HTTPS를 통해 액세스하는 Wordpress 응용 프로그램의 중앙 승인 계층을 구성합니다.
IAP is integrated through Ingress for GKE. This integration enables you to control resource-level access for employees instead of using a VPN. [1]
GCP 문서에 설명된 지침을 따르십시오.
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress
labels:
app: wordpress
spec:
selector:
matchLabels:
app: wordpress
strategy:
type: Recreate
template:
metadata:
labels:
app: wordpress
spec:
containers:
- image: wordpress
name: wordpress
env:
- name: WORDPRESS_DB_HOST
value: cloud-sql-proxy:3306
- name: WORDPRESS_DB_USER
value: wordpress
- name: WORDPRESS_DB_NAME
value: wordpress
- name: WORDPRESS_DB_PASSWORD
valueFrom:
secretKeyRef:
name: mysql
key: password
ports:
- containerPort: 80
name: wordpress
volumeMounts:
- name: wordpress-persistent-storage
mountPath: /var/www/html
livenessProbe:
initialDelaySeconds: 30
httpGet:
port: 80
path: /wp-admin/install.php # at the very beginning, this is the only accessible page. Don't forget to change to /wp-login.php
readinessProbe:
httpGet:
port: 80
path: /wp-admin/install.php
resources:
requests:
cpu: 1000m
memory: 2Gi
limits:
cpu: 1200m
memory: 2Gi
volumes:
- name: wordpress-persistent-storage
persistentVolumeClaim:
claimName: wordpress
apiVersion: v1
kind: Service
metadata:
name: wordpress
annotations:
cloud.google.com/neg: '{"ingress": true}'
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
selector:
app: wordpress
The cloud.google.com/neg
annotation specifies that port 80 will be associated with a zonal network endpoint group (NEG). See Container-native load balancing for information on the benefits, requirements, and limitations of container-native load balancing.
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: wordpress
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.global-static-ip-name: "wordpress"
kubernetes.io/ingress.class: "gce"
name: wordpress
spec:
defaultBackend:
service:
name: wordpress
port:
number: 80
rules:
- http:
paths:
- path: /*
pathType: ImplementationSpecific
backend:
service:
name: wordpress
port:
number: 80
The kubernetes.io/ingress.global-static-ip-name
annotation specifies the name of the global IP address resource to be associated with the HTTP(S) Load Balancer. [2]
cd infra/k8s
$ kubectl create secret generic mysql \
--from-literal=password=$(gcloud secrets versions access latest --secret=wordpress-admin-user-password --project $PROJECT_ID) -n wordpress
gcloud compute addresses create wordpress --global
$ kubectl create -f web -n wordpress
$ kubectl get pods -l app=wordpress -n wordpress
NAME READY STATUS RESTARTS AGE
wordpress-6d58d85845-2d7x2 1/1 Running 0 10m
$ kubectl get ingress -n wordpress
NAME CLASS HOSTS ADDRESS PORTS AGE
wordpress <none> * 34.117.187.51 80 16m
외부 HTTP(S) 로드 밸런서에 전송되는 전송 트래픽을 필터링하기 위해 Cloud Armor security policy를 사용합니다.
생성
ìnfra/plan/cloud-armor.tf
:resource "google_compute_security_policy" "wordpress" {
name = "wordpress"
rule {
action = "allow"
priority = "1000"
match {
versioned_expr = "SRC_IPS_V1"
config {
src_ip_ranges = var.authorized_source_ranges
}
}
description = "Allow access to authorized source ranges"
}
rule {
action = "deny(403)"
priority = "2147483647"
match {
versioned_expr = "SRC_IPS_V1"
config {
src_ip_ranges = ["*"]
}
}
description = "default rule"
}
}
업데이트된 terraform을 실행합니다.cd infra/plan
terraform apply
Kubernetes에서 백엔드 설정을 만들고 보안 정책을 참고하십시오.
BackendConfig custom resource definition (CRD) allows us to further customize the load balancer. This CRD allows us to define additional load balancer features hierarchically, in a more structured way than annotations. [3]
infra/k8s/web/backend.yaml
apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
name: wordpress
spec:
securityPolicy:
name: wordpress
kubectl create -f infra/k8s/web/backend.yaml -n wordpress
wordpress 서비스에 메모 추가cloud.google.com/backend-config: '{"default": "wordpress"}'
:kubectl apply -f infra/k8s/web/service.yaml -n wordpress
HTTP 로드 밸런서에 보안 정책이 추가되었는지 확인합니다.괜찮아 보여요.테스트를 해보겠습니다.
만약 우리가 거절당한다면, 나쁜 IP를 테스트하십시오
gcloud compute security-policies rules update 1000 \
--security-policy wordpress \
--src-ip-ranges "85.56.40.96"
curl http://34.117.187.51/
<!doctype html><meta charset="utf-8"><meta name=viewport content="width=device-width, initial-scale=1"><title>403</title>403 Forbidden
올바른 IP 주소를 입력하십시오.gcloud compute security-policies rules update 1000 \
--security-policy wordpress \
--src-ip-ranges $(curl -s http://checkip.amazonaws.com/)
curl http://34.117.187.51/
<!doctype html>
<html lang="en-GB" >
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>admin – Just another WordPress site</title>
좋아요!이 백엔드 설정을 통해 같은 사무실의 직원만 이 프로그램에 접근할 수 있습니다.현재 우리는 그들도 신분 검증을 통해 응용 프로그램에 접근할 수 있기를 바란다.우리는 Identity Aware Proxy (Cloud IAP)를 사용하여 이 점을 실현할 수 있다.
클라우드 IAP 사용
IAP를 사용하여 HTTPS를 통해 액세스하는 Wordpress 응용 프로그램의 중앙 승인 계층을 구성합니다.
IAP is integrated through Ingress for GKE. This integration enables you to control resource-level access for employees instead of using a VPN. [1]
GCP 문서에 설명된 지침을 따르십시오.
IAP is integrated through Ingress for GKE. This integration enables you to control resource-level access for employees instead of using a VPN. [1]
CLIENT_ID_KEY=<CLIENT_ID_KEY>
CLIENT_SECRET_KEY=<CLIENT_SECRET_KEY>
kubectl create secret generic wordpress --from-literal=client_id=$CLIENT_ID_KEY \
--from-literal=client_secret=$CLIENT_SECRET_KEY \
-n wordpress
백엔드 구성 업데이트apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
name: wordpress
spec:
iap:
enabled: true
oauthclientCredentials:
secretName: wordpress
securityPolicy:
name: wordpress
변경 사항 적용:kubectl apply -f infra/k8s/web/backend-config.yaml -n wordpress
테스트 해달래요.
좋아요!
SSL 인증서
도메인 이름이 있으면 CRDManagedCertificate를 사용하여 구글이 관리하는 SSL 인증서를 사용할 수 있습니다.
Google-managed SSL certificates are Domain Validation (DV) certificates that Google Cloud obtains and manages for your domains. They support multiple hostnames in each certificate, and Google renews the certificates automatically. [4]
파일 생성infra/k8s/web/ssl.yaml
apiVersion: networking.gke.io/v1
kind: ManagedCertificate
metadata:
name: wordpress
spec:
domains:
- <DOMAIN_NAME>
Terraform을 사용하여 도메인 이름을 만들거나 gcloud 명령만 사용할 수 있습니다.
export PUBLIC_DNS_NAME=
export PUBLIC_DNS_ZONE_NAME=
gcloud dns record-sets transaction start --zone=$PUBLIC_DNS_ZONE_NAME
gcloud dns record-sets transaction add $(gcloud compute addresses list --filter=name=wordpress --format="value(ADDRESS)") --name=wordpress.$PUBLIC_DNS_NAME. --ttl=300 --type=A --zone=$PUBLIC_DNS_ZONE_NAME
gcloud dns record-sets transaction execute --zone=$PUBLIC_DNS_ZONE_NAME
sed -i "s/<DOMAIN_NAME>/wordpress.$PUBLIC_DNS_NAME/g;" infra/k8s/web/ssl.yaml
kubectl create -f infra/k8s/web/ssl.yaml -n wordpress
포털 리소스에 주석networking.gke.io/managed-certificates: "wordpress"
을 추가합니다.
테스트 해달래요.
좋아요!
모든 HTTP 트래픽을 HTTPS로 리디렉션하려면 FrontendConfig을 만들어야 합니다.
파일 생성infra/k8s/web/frontend-config.yaml
apiVersion: networking.gke.io/v1beta1
kind: FrontendConfig
metadata:
name: wordpress
spec:
redirectToHttps:
enabled: true
responseCodeName: MOVED_PERMANENTLY_DEFAULT
kubectl create -f infra/k8s/web/frontend-config.yaml -n wordpress
포털 리소스에 주석networking.gke.io/v1beta1.FrontendConfig: "wordpress"
을 추가합니다.
테스트 해달래요.
curl -s http://wordpress.<HIDDEN>.stack-labs.com/
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="https://wordpress.<HIDDEN>.stack-labs.com/">here</A>.
</BODY></HTML>
그래!
결론
축하합니다!너는 이미 이 긴 세미나를 완성했다.이 시리즈의 내용은 다음과 같습니다.
Google-managed SSL certificates are Domain Validation (DV) certificates that Google Cloud obtains and manages for your domains. They support multiple hostnames in each certificate, and Google renews the certificates automatically. [4]
apiVersion: networking.gke.io/v1
kind: ManagedCertificate
metadata:
name: wordpress
spec:
domains:
- <DOMAIN_NAME>
export PUBLIC_DNS_NAME=
export PUBLIC_DNS_ZONE_NAME=
gcloud dns record-sets transaction start --zone=$PUBLIC_DNS_ZONE_NAME
gcloud dns record-sets transaction add $(gcloud compute addresses list --filter=name=wordpress --format="value(ADDRESS)") --name=wordpress.$PUBLIC_DNS_NAME. --ttl=300 --type=A --zone=$PUBLIC_DNS_ZONE_NAME
gcloud dns record-sets transaction execute --zone=$PUBLIC_DNS_ZONE_NAME
sed -i "s/<DOMAIN_NAME>/wordpress.$PUBLIC_DNS_NAME/g;" infra/k8s/web/ssl.yaml
kubectl create -f infra/k8s/web/ssl.yaml -n wordpress
apiVersion: networking.gke.io/v1beta1
kind: FrontendConfig
metadata:
name: wordpress
spec:
redirectToHttps:
enabled: true
responseCodeName: MOVED_PERMANENTLY_DEFAULT
kubectl create -f infra/k8s/web/frontend-config.yaml -n wordpress
curl -s http://wordpress.<HIDDEN>.stack-labs.com/
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="https://wordpress.<HIDDEN>.stack-labs.com/">here</A>.
</BODY></HTML>
축하합니다!너는 이미 이 긴 세미나를 완성했다.이 시리즈의 내용은 다음과 같습니다.
이렇게!
깨끗했어
NEG 리소스를 제거합니다.너는 Compute Engine > Network Endpoint Group
에서 그것들을 찾을 수 있다.
다음 명령을 실행합니다.
terraform destroy
gcloud dns record-sets transaction remove $(gcloud compute addresses list --filter=name=wordpress --format="value(ADDRESS)") --name=wordpress.$PUBLIC_DNS_NAME. --ttl=300 --type=A --zone=$PUBLIC_DNS_ZONE_NAME
gcloud dns record-sets transaction execute --zone=$PUBLIC_DNS_ZONE_NAME
gcloud compute addresses delete wordpress
gcloud secrets delete wordpress-admin-user-password
마지막 말
The source code is available on Gitlab .
질문이나 피드백이 있으면 언제든지 댓글을 달아주세요.
그렇지 않으면 GKE Autopilot를 클라우드 SQL에 연결하고 네트워크와 신분 검증 층에서pod급 심도 있는 방어 보안 정책을 제공하는 데 대한 난제에 대한 답변을 도와드렸으면 합니다.
겸사겸사 한마디 하자면 또래와 나누는 것을 주저하지 마라😊
읽어주셔서 감사합니다!
문서
[1] https://cloud.google.com/iap/docs/enabling-kubernetes-howto
[2] https://cloud.google.com/kubernetes-engine/docs/tutorials/configuring-domain-name-static-ip
[3] https://cloud.google.com/kubernetes-engine/docs/how-to/ingress-features#configuring_ingress_features
[4] https://cloud.google.com/load-balancing/docs/ssl-certificates/google-managed-certs
Reference
이 문제에 관하여(GKE 어플리케이션과 클라우드 SQL 데이터베이스 간 연결 보호), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/stack-labs/securing-the-connectivity-between-a-gke-application-and-a-cloud-sql-database-4d6b
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
terraform destroy
gcloud dns record-sets transaction remove $(gcloud compute addresses list --filter=name=wordpress --format="value(ADDRESS)") --name=wordpress.$PUBLIC_DNS_NAME. --ttl=300 --type=A --zone=$PUBLIC_DNS_ZONE_NAME
gcloud dns record-sets transaction execute --zone=$PUBLIC_DNS_ZONE_NAME
gcloud compute addresses delete wordpress
gcloud secrets delete wordpress-admin-user-password
The source code is available on Gitlab .
질문이나 피드백이 있으면 언제든지 댓글을 달아주세요.
그렇지 않으면 GKE Autopilot를 클라우드 SQL에 연결하고 네트워크와 신분 검증 층에서pod급 심도 있는 방어 보안 정책을 제공하는 데 대한 난제에 대한 답변을 도와드렸으면 합니다.
겸사겸사 한마디 하자면 또래와 나누는 것을 주저하지 마라😊
읽어주셔서 감사합니다!
문서
[1] https://cloud.google.com/iap/docs/enabling-kubernetes-howto
[2] https://cloud.google.com/kubernetes-engine/docs/tutorials/configuring-domain-name-static-ip
[3] https://cloud.google.com/kubernetes-engine/docs/how-to/ingress-features#configuring_ingress_features
[4] https://cloud.google.com/load-balancing/docs/ssl-certificates/google-managed-certs
Reference
이 문제에 관하여(GKE 어플리케이션과 클라우드 SQL 데이터베이스 간 연결 보호), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/stack-labs/securing-the-connectivity-between-a-gke-application-and-a-cloud-sql-database-4d6b
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(GKE 어플리케이션과 클라우드 SQL 데이터베이스 간 연결 보호), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/stack-labs/securing-the-connectivity-between-a-gke-application-and-a-cloud-sql-database-4d6b텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)