istio: Can't connect to Google Cloud Sql
Describe the bug Can’t connect to Cloud SQL (postgres 9.6) using istio in Google Container Engine (Kubernetes). The service uses the cloudsql proxy sidecar along with istio in the same pod. Tested with a docker container with psql installed to test the connection.
In vanilla kubernetes I can connect to the database:
root@auth-66c4bf88df-bs7q2:/app# psql -h 127.0.0.1 -U auth -d passport
Password for user auth:
psql (9.6.7, server 9.6.6)
Type "help" for help.
passport=>
But, with istio I got:
root@auth-7f769bc877-fbzp4:/app# psql -h 127.0.0.1 -U auth -d passport
psql: server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
In the early tries I got blocked by the container (Cloud Proxy), and trying to connect to googleapis.com
and accounts.google.com
$ cat <<EOF | istioctl create -f -
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: account-google-serviceentry-rule
spec:
hosts:
- accounts.google.com
ports:
- number: 443
name: https
protocol: HTTPS
EOF
$ cat <<EOF | istioctl create -f -
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: googleapis-serviceentry-rule
spec:
hosts:
- www.googleapis.com
ports:
- number: 443
name: https
protocol: HTTPS
EOF
Expected behavior Successful connection to the database
Steps to reproduce the bug
- Create a Cloud SQL database instance (postgres 9.6)
- Create a service account with Cloud Client role enabled and Cloud Sql account following the GCloud tutorial
- Install istio following the Quick Start page without auth enabled
- Deploy a service (based on debian stretch with psql installed)
- Try to connect to the Database using the credential provided in the previous steps. For example:
$ psql -h 127.0.0.1 -U auth -d passport
Version
$ istioctl version
Version: 0.8.0
GitRevision: 6f9f420f0c7119ff4fa6a1966a6f6d89b1b4db84
User: root@48d5ddfd72da
Hub: docker.io/istio
GolangVersion: go1.10.1
BuildStatus: Clean
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"10", GitVersion:"v1.10.4", GitCommit:"5ca598b4ba5abb89bb773071ce452e33fb66339d", GitTreeState:"clean", BuildDate:"2018-06-06T08:13:03Z", GoVersion:"go1.9.3", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"10+", GitVersion:"v1.10.4-gke.2", GitCommit:"eb2e43842aaa21d6f0bb65d6adf5a84bbdc62eaf", GitTreeState:"clean", BuildDate:"2018-06-15T21:48:39Z", GoVersion:"go1.9.3b4", Compiler:"gc", Platform:"linux/amd64"}
Is Istio Auth enabled or not? Installing following the Quick Start page without auth enabled
$ kubectl apply -f install/kubernetes/istio-demo.yaml
Environment Kubernetes Engine in Google Cloud Tested with version 1.9.7 and 1.10.4-gke.2
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 12
- Comments: 41 (12 by maintainers)
I confirm that solution suggested by @veryhumble works.
It’s actually documented at https://istio.io/blog/2018/egress-tcp/
Here is the complete configuration that works for me:
Using the cloudsql proxy does provide the benefit of automating the SSL cert setup to your SQL instance vs directly connecting to private IP.
I’ve been using cloudsql proxy w/ istio 1.4+ for a while now as both a deployment + sidecar approach, one of the problems that i’ve seen is the race condition during startup that leads to the
connection refused
errors for the proxy trying to talk to google APIs during startup.The workaround i’ve been using until sidecars KEP is available is to simply use shell/curl to wait until the proxy is ready before starting up
cloud_sql_proxy
(rather then just adding asleep 10
delay)Unless you are running with a restricted mesh
REGISTRY_ONLY
you then don’t need to create anyServiceEntry
unless you want additional observability context.Note: Recent 1.16+ proxy releases have moved to distroless/no shell so you either need to build your custom image until https://github.com/GoogleCloudPlatform/cloudsql-proxy/issues/371 or use a older image.
This should be kept open; there’s no solution to it.
sigh
This issue shouldn’t be closed as there is no solution yet. Can someone (@vadimeisenbergibm ?) reopen?
I’m currently stuck with the
https://www.googleapis.com/sql/v1beta4/projects/pc-internal-dev/instances/pc-internal-dev-1?alt=json&prettyPrint=false: oauth2: cannot fetch token: Post https://oauth2.googleapis.com/token: dial tcp 172.217.212.95:443: connect: connection refused
issue.I’m using Istio 1.2-release on 1.13.11-gke.9
I’m also using mTLS. I’m not currently using the private IP approach - but if I we’re, since I’m using mTLS in Istio, and my CloudSQL is using SSL - I’m not sure the best way to set this up?
Any update on this? I am experiencing the same problem using the
cloudsql-proxy
sidecar.Edit: I got the connection somehow working. I added a sidecar with the postgres client and tried connecting from there manually. In the logs of the
cloudsql-proxy
i saw that it’s trying to connect to the postgresql db using port3307
. So I added the followingServiceEntry
:It now prompts correctly the password after
psql -h 127.0.0.0 -U proxyuser -d test
. But its stuck on that password prompt. So not quite resolved yet.Leaving a checklist that probably will save few hours for someone like me.
containerPort
defined:tcp
:UPDATE: I got it working with a slightly different configuration using jdbc Socket Factory connecting to CloudSQL Mysql 2.Gen.
Difference to @yskopets @veryhumble configuration:
@vadimeisenbergibm I can confirm this works without the
istio-proxy
as a sidecar. All the proposed workarounds are using ServiceEntry to allow this URLs, but if the outboundTrafficPolicy.mode is set to ALLOW_ANY, why are all this steps needed?Is there another way to tell the sidecar to allow all egress traffic?
If it helps the ones that are stuck; using TCP connection with cloud_sql_proxy worked for me:
But removing the TCP option and trying to use Unix Socket, always failed:
With this error on the Cloud SQL logs:
Get https://www.googleapis.com/sql/v1beta4/projects/<instance-name>?alt=json&prettyPrint=false: oauth2: cannot fetch token: Post https://oauth2.googleapis.com/token: dial tcp 74.125.141.95:443: connect: connection refused
Using both; private or public IP and with any ServiceEntry combination given on this post so far didn’t work while using Unix Socket
@Kampe I don’t think listing IP address in hosts field is possible (istio version 1.1.8), how did you get around that. also do you have the case where you enable SSL on cloudSQL side? did you manage to get that done somehow?
@ermik The first question is if you need to direct the egress traffic thru a gateway, or you can just direct the traffic directly from the sidecar.
If you need the gateway, and you want to use wildcard hosts like
*.googleapis.com
, see this example how to do it: https://preliminary.istio.io/docs/examples/advanced-gateways/wildcard-egress-hosts/