我正在尝试完成以下教程,以在GKE上部署Wordpress: https://cloud.google.com/kubernetes-engine/docs/tutorials/persistent-disk
我已经使用terraform来配置gcp资源,而不是本教程建议的gcp。这是导致CrashLoopBackOff状态的部署。
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress
labels:
app: wordpress
spec:
replicas: 1
selector:
matchLabels:
app: wordpress
template:
metadata:
labels:
app: wordpress
spec:
containers:
- image: wordpress
name: wordpress
env:
- name: WORDPRESS_DB_HOST
value: 127.0.0.1:3306
# These secrets are required to start the pod.
- name: WORDPRESS_DB_USER
valueFrom:
secretKeyRef:
name: cloudsql-db-credentials
key: username
- name: WORDPRESS_DB_PASSWORD
valueFrom:
secretKeyRef:
name: cloudsql-db-credentials
key: password
ports:
- containerPort: 80
name: wordpress
volumeMounts:
- name: wordpress-persistent-storage
mountPath: /var/www/html
# Change archtek-wordpress:us-west1:archtek-wordpress-postgres-instance here to include your GCP
# project, the region of your Cloud SQL instance and the name
# of your Cloud SQL instance. The format is
# ::
- name: cloudsql-proxy
image: gcr.io/cloudsql-docker/gce-proxy:1.11
command: ["/cloud_sql_proxy",
"-instances=archtek-wordpress:us-west1:archtek-wordpress-mysql-instance=tcp:3306",
# If running on a VPC, the Cloud SQL proxy can connect via Private IP. See:
# https://cloud.google.com/sql/docs/mysql/private-ip for more info.
# "-ip_address_types=PRIVATE",
"-credential_file=/secrets/cloudsql/key.json"]
securityContext:
runAsUser: 2 # non-root user
allowPrivilegeEscalation: false
volumeMounts:
- name: cloudsql-instance-credentials
mountPath: /secrets/cloudsql
readOnly: true
imagePullPolicy: Always
volumes:
- name: wordpress-persistent-storage
persistentVolumeClaim:
claimName: wordpress-volumeclaim
- name: cloudsql-instance-credentials
secret:
secretName: cloudsql-instance-credentials
当我描述吊舱时,我在日志中看到以下内容:
wordpress-54c68dbf59-5djfx wordpress MySQL Connection Error: (2002) Connection refused
要排除凭据无效的想法,我使用了用于创建cloudsql-db-credentials
(在部署yaml中引用的k8s机密)的用户名和密码,然后运行了该密码。
$: gcloud sql connect archtek-wordpress-mysql-instance -u wordpress
我可以连接,没问题。但是我发现我也无法做到这一点:
$: mysql -u wordpress -p'$CLOUD_SQL_PASSWORD' \ ()
-h 35.197.7.98 -P 3306 \
-D archtek-wordpress:us-west1:archtek-wordpress-mysql-instance -v
返回:
ERROR 2003 (HY000): Can't connect to MySQL server on '35.197.7.98' (60)
我知道,当使用gcloud
客户端连接到cloudsql数据库时,它会在身份验证之前的5分钟内将IP列入白名单,这也许可以解释为什么mysql
客户端无法身份验证的原因。但是,我不确定这个理由是否可以支持我在集群中的部署。是否也需要将白名单列入cloudsql以接受身份验证请求?
这是用于配置cloudsql实例的terraform文件:
resource "google_sql_database_instance" "postgres" {
name = "archtek-wordpress-mysql-instance"
database_version = "MYSQL_5_7"
settings {
tier = "db-f1-micro"
availability_type = "ZONAL"
}
}
答案 0 :(得分:2)
在尝试从/* 1 */
{
"_id" : ObjectId("5f4c93478ac8f4f9d79151bd"),
"property" : "prop_1",
"created" : ISODate("2020-01-01T22:00:00.000Z")
}
群集进行外部连接时遇到的错误:
ERROR 2003(HY000):无法连接到'35 .197.7.98'(60)上的MySQL服务器
这是因为您所连接的站点(IP)没有被授权这样做。使用:
GKE
允许在5分钟内连接到$ gcloud sql connect ...
实例。
在SQL
中使用CloudSQL proxy
时,无需授权您要连接的网络。
您可以在GKE
中看到授权部分。
此外,您还可以查看Pod(GCP -> SQL -> Instance -> Connections
和wordpress
)的日志,以确定哪个Pod引起了问题(cloudsql-proxy
除外):
$ kubectl describe
有关$ kubectl logs POD_NAME -c wordpress
和CloudSQL
的更多参考:
假设您在github页面上使用sql-proxy
文件为CloudSQL
实例创建了用户,则可能是失败的原因。负责创建用户.tf
的部分的主机参数错误(下面的示例已编辑):
wordpress
我无法使用以下参数连接到服务器:resource "google_sql_user" "users" {
name = "wordpress"
instance = google_sql_database_instance.postgres.name
# host = "*" <- BAD
host = "%" # <- GOOD
password = random_password.password.result
}
。将其从host = "*"
更改为"*"
解决了我的问题。
我设法创建了"%"
文件,这些文件与官方.tf
指南中的部分类似:
将Terraform连接到GKE
项目的指南:
使用的文件:
GCP
main.tf
-创建一个vpc.tf
(基于评论中链接的github)VPC
-在新的gke.tf
GKE
集群
VPC
-创建一个mysql.tf
实例和一个用户CloudSQL
wordpress
-为pvc.tf
部署创建PVC
Wordpress
-创建一个sa.tf
并将其绑定到访问ServiceAccount
实例所需的权限CloudSQL
-为上方secret.tf
创建密钥,并为ServiceAccount
和Kubernetes
吊舱创建Wordpress
机密CloudSQL
-创建将运行deployment.tf
和Wordpress
每次添加新文件时(按上述顺序),我都会执行以下命令:
cloudsql-proxy
$ terraform init
$ terraform apply
:
main.tf
provider "google" {
project = "ENTER-YOUR-PROJECT-ID"
region = "europe-west3"
zone = "europe-west3-c"
}
variable project {
type = string
default = "ENTER-YOUR-PROJECT-ID"
}
variable zone {
type = string
default = "europe-west3-c"
}
variable region {
type = string
default = "europe-west3"
}
:
vpc.tf
resource "google_compute_network" "terraform-network" {
name = "terraform-network"
auto_create_subnetworks = "false"
}
resource "google_compute_subnetwork" "terraform-subnet" {
name = "terraform-subnet"
region = var.region
network = google_compute_network.terraform-network.name
ip_cidr_range = "10.0.0.0/24"
}
:
gke.tf
我也跑了:
resource "google_container_cluster" "gke-terraform" {
name = "gke-terraform"
location = var.zone
initial_node_count = 1
network = google_compute_network.terraform-network.name
subnetwork = google_compute_subnetwork.terraform-subnet.name
}
$ gcloud container clusters get-credentials gke-terraform --zone=europe-west3-c
mysql.tf
resource "google_sql_database_instance" "cloudsql" {
name = "cloudsql-terraform"
database_version = "MYSQL_5_7"
settings {
tier = "db-f1-micro"
availability_type = "ZONAL"
}
}
data "google_sql_database_instance" "cloudsql" {
name = "cloudsql-terraform"
}
resource "random_password" "wordpress-cloudsql-password" {
length = 18
special = true
override_special = "_%@"
}
resource "local_file" "password-file" {
content = random_password.wordpress-cloudsql-password.result
filename = "./password-file"
}
resource "google_sql_user" "cloudsql-wordpress-user" {
name = "wordpress"
instance = google_sql_database_instance.cloudsql.name
host = "%"
password = random_password.wordpress-cloudsql-password.result
}
:
pvc.tf
resource "google_compute_disk" "terraform-pd" {
name = "terraform-disk"
type = "pd-standard"
zone = "europe-west3-c"
}
resource "kubernetes_persistent_volume" "terraform-pv" {
metadata {
name = "wordpress-pv"
}
spec {
capacity = {
storage = "10Gi"
}
storage_class_name = "standard"
access_modes = ["ReadWriteOnce"]
persistent_volume_source {
gce_persistent_disk {
pd_name = google_compute_disk.terraform-pd.name
}
}
}
}
resource "kubernetes_persistent_volume_claim" "terraform-pvc" {
metadata {
name = "wordpress-pvc"
}
spec {
access_modes = ["ReadWriteOnce"]
storage_class_name = "standard"
resources {
requests = {
storage = "10Gi"
}
}
volume_name = kubernetes_persistent_volume.terraform-pv.metadata.0.name
}
}
:
sa.tf
resource "google_service_account" "cloudsql-proxy-terraform" {
account_id = "cloudsql-proxy-terraform"
display_name = "cloudsql-proxy-terraform"
}
data "google_service_account" "cloudsql-proxy-terraform" {
account_id = "cloudsql-proxy-terraform"
}
resource "google_project_iam_binding" "cloudsql-proxy-binding" {
project = var.project
role = "roles/cloudsql.client"
members = [
"serviceAccount:${google_service_account.cloudsql-proxy-terraform.email}",
]
}
:
secret.tf
resource "google_service_account_key" "cloudsql-proxy-key" {
service_account_id = google_service_account.cloudsql-proxy-terraform.name
}
resource "kubernetes_secret" "cloudsql-instance-credentials-terraform" {
metadata {
name = "cloudsql-instance-credentials-terraform"
}
data = {
"key.json" = base64decode(google_service_account_key.cloudsql-proxy-key.private_key)
}
}
resource "kubernetes_secret" "cloudsql-db-credentials-terraform" {
metadata {
name = "cloudsql-db-credentials-terraform"
}
data = {
"username" = "wordpress"
"password" = random_password.wordpress-cloudsql-password.result
}
}
:
deployment.tf
在检查资源是否正确创建(resource "kubernetes_deployment" "wordpress-deployment" {
metadata {
name = "wordpress-deployment"
labels = {
app = "wordpress"
}
}
spec {
replicas = 1
selector {
match_labels = {
app = "wordpress"
}
}
template {
metadata {
labels = {
app = "wordpress"
}
}
spec {
container {
image = "wordpress"
name = "wordpress"
env {
name = "WORDPRESS_DB_HOST"
value = "127.0.0.1:3306"
}
env {
name = "WORDPRESS_DB_USER"
value_from {
secret_key_ref {
name = kubernetes_secret.cloudsql-db-credentials-terraform.metadata.0.name
key = "username"
}
}
}
env {
name = "WORDPRESS_DB_PASSWORD"
value_from {
secret_key_ref {
name = kubernetes_secret.cloudsql-db-credentials-terraform.metadata.0.name
key = "password"
}
}
}
port {
name = "http"
container_port = 80
protocol = "TCP"
}
volume_mount {
mount_path = "/var/www/html"
name = "wordpress-persistent-storage"
}
}
container {
image = "gcr.io/cloudsql-docker/gce-proxy:1.11"
name = "cloudsql-proxy"
command = ["/cloud_sql_proxy",
"-instances=${google_sql_database_instance.cloudsql.connection_name}=tcp:3306",
"-credential_file=/secrets/cloudsql/key.json"]
security_context {
run_as_user = 2
allow_privilege_escalation = "false"
}
volume_mount {
mount_path = "/secrets/cloudsql"
name = "cloudsql-instance-credentials-terraform"
read_only = "true"
}
}
volume {
name = "wordpress-persistent-storage"
persistent_volume_claim {
claim_name = "wordpress-pvc"
}
}
volume {
name = "cloudsql-instance-credentials-terraform"
secret {
secret_name = "cloudsql-instance-credentials-terraform"
}
}
}
}
}
}
)之后,可以使用以下内容公开$ kubectl logs POD_NAME -c CONTAINER_NAME
:
Wordpress