Приложение Kubernetes с GCP Cloud SQL не принимает никаких подключений. Полный исходный код доступен на Github
Я создал пример приложения Rails 5, которое использует Google Cloud PostgreSQL. Я могу запустить приложение локально с docker-compose up
, но я не могу подключиться к нему удаленно при развертывании его в GCP. Я пытался скопировать https://cloud.google.com/ruby/tutorials/bookshelf-on-kubernetes-engine где они используют targetPort: http-server
Приложение рельсы опубликовано на Github. Я делаю что-то явно неправильно?:-|
Запуск приложения локально работает
git clone git@github.com:stabenfeldt/k8s-colors.git
docker-compose up -d
docker-compose run colors rake db:create db:migrate
open http://localhost:3000
Создать кластер GKE
gcloud container clusters create color-cluster --num-nodes=2
Настройка PostgreSQL Cloud SQL
Я следовал инструкциям из https://cloud.google.com/sql/docs/postgres/connect-kubernetes-engine?authuser=1 и обновил мои config/database.yml и k8s/colors.yml этими значениями.
Развернуто, но застряло на ContainerCreating
kubectl apply -f k8s/colors.yml
kubectl get pods
NAME READY STATUS RESTARTS AGE
colors-d9f744dc-d5l5v 0/2 ContainerCreating 0 5m
colors-d9f744dc-spmws 0/2 ContainerCreating 0 5m
kubectl logs d9f744dc-d5l5v -c colors # => Nothing logged
kubectl получить развертывание
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
colors 2 2 2 0 7m
Но не удается подключиться к приложению
kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
colors LoadBalancer 10.55.245.192 35.228.111.217 80:30746/TCP 1h
kubernetes ClusterIP 10.55.240.1 <none> 443/TCP 1h
curl 35.228.111.217 # => Нет ответа!: - /
kubectl описать цвета SVC
Name: colors
Namespace: default
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"colors","namespace":"default"},"spec":{"ports":[{"port":80,"targetPort":3000}]...
Selector: app=colors
Type: LoadBalancer
IP: 10.55.252.91
LoadBalancer Ingress: 35.228.203.46
Port: <unset> 80/TCP
TargetPort: 3000/TCP
NodePort: <unset> 30964/TCP
Endpoints: <none>
Session Affinity: None
External Traffic Policy: Cluster
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Type 1m service-controller ClusterIP -> LoadBalancer
Normal EnsuringLoadBalancer 1m service-controller Ensuring load balancer
Normal EnsuredLoadBalancer 30s service-controller Ensured load balancer
K8S / service.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: colors
labels:
app: colors
spec:
replicas: 2
selector:
matchLabels:
app: colors
template:
metadata:
labels:
app: colors
spec:
containers:
- name: colors
image: docker.io/stabenfeldt/colors:latest
ports:
- name: http-server
containerPort: 3000
env:
- name: POSTGRES_HOST
value: 127.0.0.1:5432
- name: POSTGRES_USER
valueFrom:
secretKeyRef:
name: cloudsql-db-credentials
key: username
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: cloudsql-db-credentials
key: password
- name: cloudsql-proxy
image: gcr.io/cloudsql-docker/gce-proxy:1.11
command: ["/cloud_sql_proxy",
"-instances=PROJECT_ID:europe-west1:staging=tcp:5432",
"-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
---
apiVersion: v1
kind: Service
metadata:
name: colors
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 3000
selector:
app: colors
kubectl описать развертывание
Name: colors
Namespace: default
CreationTimestamp: Fri, 13 Jul 2018 10:37:06 +0200
Labels: app=colors
Annotations: deployment.kubernetes.io/revision=1
kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"labels":{"app":"colors"},"name":"colors","namespace":"default"},"spec":{"repl...
Selector: app=colors
Replicas: 2 desired | 2 updated | 2 total | 0 available | 2 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app=colors
Containers:
colors:
Image: docker.io/stabenfeldt/colors:latest
Port: 3000/TCP
Environment:
POSTGRES_HOST: 127.0.0.1:5432
POSTGRES_USER: <set to the key 'username' in secret 'cloudsql-db-credentials'> Optional: false
POSTGRES_PASSWORD: <set to the key 'password' in secret 'cloudsql-db-credentials'> Optional: false
Mounts: <none>
cloudsql-proxy:
Image: gcr.io/cloudsql-docker/gce-proxy:1.11
Port: <none>
Command:
/cloud_sql_proxy
-instances=MY-INSTANCE:europe-west1:staging=tcp:5432
-credential_file=/secrets/cloudsql/credentials.json
Environment: <none>
Mounts:
/secrets/cloudsql from cloudsql-instance-credentials (ro)
Volumes:
cloudsql-instance-credentials:
Type: Secret (a volume populated by a Secret)
SecretName: cloudsql-instance-credentials
Optional: false
Conditions:
Type Status Reason
---- ------ ------
Available False MinimumReplicasUnavailable
Progressing True ReplicaSetUpdated
OldReplicaSets: <none>
NewReplicaSet: colors-d9f744dc (2/2 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 1m deployment-controller Scaled up replica set colors-d9f744dc to 2
kubectl описать сервис
Name: colors
Namespace: default
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"colors","namespace":"default"},"spec":{"ports":[{"port":80,"targetPort":3000}]...
Selector: app=colors
Type: LoadBalancer
IP: 10.55.252.91
LoadBalancer Ingress: 35.228.203.46
Port: <unset> 80/TCP
TargetPort: 3000/TCP
NodePort: <unset> 30964/TCP
Endpoints: <none>
Session Affinity: None
External Traffic Policy: Cluster
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Type 4m service-controller ClusterIP -> LoadBalancer
Normal EnsuringLoadBalancer 4m service-controller Ensuring load balancer
Normal EnsuredLoadBalancer 3m service-controller Ensured load balancer
Name: kubernetes
Namespace: default
Labels: component=apiserver
provider=kubernetes
Annotations: <none>
Selector: <none>
Type: ClusterIP
IP: 10.55.240.1
Port: https 443/TCP
TargetPort: 443/TCP
Endpoints: 35.228.79.249:443
Session Affinity: ClientIP
Events: <none>
3 ответа
Я не вижу в этом ничего плохого, но вот несколько советов, как проверить, что ваши объекты Kubernetes выглядят так, как будто они должны сравниваться с вашими ямлами:
Используйте команду description, чтобы получить больше информации об объектах и убедиться, что они установлены правильно.
Например, если вы делаете kubectl describe deployment <deployment_name>
Вы должны убедиться в наличии следующей строки:
Port: 3000/TCP
И для вашего обслуживания - kubectl describe service <service_name>
:
LoadBalancer Ingress: <PUBLIC_IP>
Port: <unset> 80/TCP
TargetPort: 3000/TCP
Наконец, я не уверен, хотите ли вы применить следующее в вашем LoadBalancer:
labels:
app: colors
Поскольку вы используете этот ярлык в качестве селектора, он может делать что-то необычное и пытаться загрузить баланс для себя вместо ваших контейнеров с приложениями в нем.
Кроме того, в качестве дополнительного примечания к вашей терминологии GCP (Google Cloud Platform) - это общее название Служб Google, а GKE (Google Kubernetes Engine) - это служба, предоставляющая вам управляемый кластер Kuberenetes.
Надеюсь это поможет.
Рабочая установка может быть в моем примере приложения Rails на Github.
K8S /colors.yml
# Remember to update MY-INSTANCE
apiVersion: v1
kind: Service
metadata:
name: colors-frontend
labels:
app: colors
tier: frontend
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: http-server
selector:
app: colors
tier: frontend
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: colors-frontend
labels:
app: colors
tier: frontend
spec:
replicas: 3
template:
metadata:
labels:
app: colors
tier: frontend
spec:
volumes:
- name: cloudsql-instance-credentials
secret:
secretName: cloudsql-instance-credentials
containers:
- name: cloudsql-proxy
image: gcr.io/cloudsql-docker/gce-proxy:1.11
command: ["/cloud_sql_proxy",
"-instances=MY-INSTANCE:europe-west1:development=tcp:5432",
"-credential_file=/secrets/cloudsql/credentials.json"]
volumeMounts:
- name: cloudsql-instance-credentials
mountPath: /secrets/cloudsql
readOnly: true
- name: colors-app
image: docker.io/stabenfeldt/colors:1
imagePullPolicy: Always
env:
- name: RAILS_LOG_TO_STDOUT
value: "true"
- name: RAILS_ENV
value: development
- name: POSTGRES_HOST
value: 127.0.0.1
- name: POSTGRES_USERNAME
valueFrom:
secretKeyRef:
name: cloudsql-db-credentials
key: username
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: cloudsql-db-credentials
key: password
ports:
- name: http-server
containerPort: 3000
Ваша переменная среды POSTGRES_HOST должна быть localhost вместо 127.0.0.01:5432. Вам не нужно добавлять порт в POSTGRES_HOST