gRPC services (developed in springboot) deployed as docker container on AWS linux (ec2). Started the docker image with port forwarding -p6565:6565.
Now when directly hit via BloomRPC on laptop, it worked : ec2.IP:6565 Package.Service.Method
Configured service & route in Kong:
{
"host": "ec2.IP",
"created_at": 1588403433,
"connect_timeout": 60000,
"id": "e657d8df-6247-458a-a8e8-bec00c41e03c",
"protocol": "grpc",
"name": "aws-grpc1",
"read_timeout": 60000,
"port": 6565,
"path": null,
"updated_at": 1588403433,
"retries": 5,
"write_timeout": 60000,
"tags": null,
"client_certificate": null
}
Route:
{
"strip_path": false,
"path_handling": "v0",
"updated_at": 1588403452,
"destinations": null,
"headers": null,
"protocols": [
"grpc",
"grpcs"
],
"created_at": 1588403452,
"snis": null,
"service": {
"id": "e657d8df-6247-458a-a8e8-bec00c41e03c"
},
"name": "aws-grpc1-route1",
"methods": null,
"preserve_host": false,
"regex_priority": 0,
"paths": [
"/grpc2"
],
"sources": null,
"id": "5739297e-3be7-4a0d-8afb-cfa8ed01cec2",
"https_redirect_status_code": 426,
"hosts": null,
"tags": null
}
Now hitting it via grpcurl -> its not working:
grpcurl -v -d "{}" -insecure ec2.ip:8443 package.service.pingMethod
Error invoking method "package.service.ping": target server does not expose service "package.service"
Here is kong config which looks related:
"proxy_listen": [
"0.0.0.0:8000 reuseport backlog=16384",
"0.0.0.0:8443 **http2** ssl reuseport backlog=16384"
],
So here are queries:
(1) can 8000 also be configured for https as insecure -> via passing a env KONG_PROXY_LISTEN variable at time of kong-container start by
-e "KONG_PROXY_LISTEN=0.0.0.0:8000 http2, 0.0.0.0:8443 http2 ssl"
Is this good to do?
(2) How to enable server side reflection? OR what is use of /grpc.reflection.v1alpha.ServerReflection/ServerReflectionInfo ?
You need to expose HTTP2 Proxy Listener for Kong.
You can refer to this one: https://konghq.com/blog/manage-grpc-services-kong/
In short, you need to add env variable details for KONG_PROXY_LISTEN like so:
-e "KONG_PROXY_LISTEN=0.0.0.0:8000 http2, 0.0.0.0:8443 http2 ssl, 0.0.0.0:9080 http2, 0.0.0.0:9081 http2 ssl"
Note: apparently Kong uses the ports 9080 for HTTP2 and 9081 for HTTP2 SSL. But I think this can be changed.
And also expose those 9080 and 9081 ports like so, this is example for docker run command:
-p 127.0.0.1:9080:9080 \
-p 127.0.0.1:9081:9081
And use the 9080 port in grpcurl when you try to request, like so:
grpcurl -v -d '{"name": "Ken"}' -plaintext localhost:9080 facade.GreetingService/SayHello
More updates:
gRPC deployed behind kong.ingress is working fine:
grpcurl -v -d "{\"greeting\":\"111\"}" -insecure acfb0xxxxx.elb.us-east-2.amazonaws.com:443 hello.HelloService.SayHello
Response:
Resolved method descriptor:
rpc SayHello ( .hello.HelloRequest ) returns ( .hello.HelloResponse );
Request metadata to send:
(empty)
Response headers received:
content-type: application/grpc
date: Sat, 02 May 2020 07:00:17 GMT
server: openresty
trailer: Grpc-Status
trailer: Grpc-Message
trailer: Grpc-Status-Details-Bin
via: kong/2.0.3
x-kong-proxy-latency: 1
x-kong-upstream-latency: 9
Response contents:
{
"reply": "hello 111"
}
Response trailers received:
(empty)
Sent 1 request and received 1 response
when configured on kong-API-gateway, it is not working:
grpcurl -v -d "{\"greeting\":\"111\"}" -insecure kong.ce-gateway.ip:8443 hello.HelloService.SayHello
Error invoking method "hello.HelloService.SayHello": failed to query for service descriptor "hello.HelloService": rpc error: code = Internal desc = An invalid response was received from the upstream server
Http2 is now enabled by default for Kong, but if you are having issues, a good place to start is to inspect the proxy_listeners section of the global config. In my case, I found that http2 was only enabled for the SSL port, and not for the non SSL. A good way to see the global config is to send a GET request to the root url of the admin api, for example GET http://localhost:8001/.
Related
I have been following an article on Medium to deploy Cloud Endpoints v1 in front of a Cloud Run service hosting a REST API and everything works well.
I now have a requirement to enable CORS support and I've added the below configuration to my endpoints YAML file but get an error saying "This service does not allow CORS traffic" when my browser tries to make a pre-flight request (I've tested this with Postman too with the same error). I know there's a flag to enable CORS --cors_preset=basic using environment variables but I'm not sure what key to set with. Any ideas or help is appreciated.
Endpoints YAML snipper:
swagger: '2.0'
info:
title: Cloud Endpoints with Cloud Run
description: Testing Cloud Endpoints with Cloud Run
version: 1.0.0
host: endpoint-<hash>-uc.a.run.app
x-google-endpoints:
- name: endpoint-<hash>-uc.a.run.app
allowCors: true
schemes:
- https
produces:
- application/json
Error:
{
"code": 7,
"message": "The service does not allow CORS traffic.",
"details": [
{
"#type": "type.googleapis.com/google.rpc.DebugInfo",
"stackEntries": [],
"detail": "service_control"
}
]
}
PS: Thanks Guillaum Blaquiere for the awesome article.
UPDATE:
I ended up testing with an incomplete URL and hence received the above error as my backend service wasn't configured to respond to all pre-flight request URLs. Having fixed this, I now get the below error only on the CORS pre-flight configured URL.
{
"code": 13,
"message": "INTERNAL_SERVER_ERROR",
"details": [
{
"#type": "type.googleapis.com/google.rpc.DebugInfo",
"stackEntries": [
],
"detail": "application"
}
]
}
and logs:
invalid URL prefix in "", client: <CLIENT_IP>, server: , request: "OPTIONS /api/v1/<REMAINING_URL> HTTP/1.1", host: "endpoint-<HASH>-uc.a.run.app"
I would say it's necesary to add ESPv2 Config, I've noticed that the note regarding the ESPv2 config was added since last april, and the Medium document was published on 2019, so I think such required step was not mentioned before.
Later in the same section it's mentioned that the flags for cors are passed by the "--set-env-vars" flag of the deploy command.
You can find more about the ESPv2 Beta startup options in here.
I managed to resolve the issue by defining OPTIONS operations in my YAML file with no security, for each path that I had already defined. See below example YAML file for an endpoint path '/api/v1/hello' with GET and OPTIONS operations defined.
swagger: '2.0'
info:
title: Cloud Endpoints with Cloud Run
description: Testing Cloud Endpoints with Cloud Run
version: 1.0.0
host: endpoint-randomhash-uc.a.run.app
x-google-endpoints:
- name: endpoint-randomhash-uc.a.run.app
allowCors: true
schemes:
- https
produces:
- application/json
x-google-backend:
address: https://backend-randomhash-uc.a.run.app
path_translation: APPEND_PATH_TO_ADDRESS
security:
- auth0_jwk: []
paths:
/api/v1/hello:
get:
summary: Say hello
operationId: helloName
parameters:
- name: "name"
in: "query"
description: "Your name"
type: "string"
responses:
'200':
description: Successful operation
schema:
type: string
options:
summary: CORS pre-flight for say hello
operationId: helloNameOptions
parameters:
- name: "name"
in: "query"
description: "Your name"
type: "string"
responses:
'200':
description: Successful operation
schema:
type: string
security: []
securityDefinitions:
auth0_jwk:
authorizationUrl: ""
flow: "implicit"
type: "oauth2"
x-google-issuer: "https://project.auth0.com/"
x-google-jwks_uri: "https://project.auth0.com/.well-known/jwks.json"
x-google-audiences: "firebase-application-host"
As Sergio pointed out in his comment to a SO question, the other option in my case is to use Firebase Hosting proxy to use the same domain and avoid CORS.
After authenticating, if I call any method, like os.compute().flavors().list() or os.images().list(), I get connect timed out. Why is this happening?
I set up a OpenStack with RDO packstack at a GoogleCloudsPlataform VM. I am doing auth with domain and project. Ive tried authing without project, and method calls did not timed out, but the responses were wrong, e.g, if I called list flavors, return none flavor.
If I do those calls with API endpoints, it works; if I auth with the same infos (user, pass, domain, project) and call flavors or images, it works.
Auth code:
OSClient.OSClientV3 os = OSFactory.builderV3()
.endpoint("http://host:5000/v3")
.credentials("admin", "pass", domain)
.scopeToProject(project)
.authenticate();
os.compute().flavors().list(); // "connection timed out" code
Endpoint auth call (that works):
curl -i \
-H "Content-Type: application/json" \
-d '
{ "auth": {
"identity": {
"methods": ["password"],
"password": {
"user": {
"name": "admin",
"domain": { "id": "default" },
"password": "pass"
}
}
},
"scope": {
"project": {
"name": "admin",
"domain": { "id": "default" }
}
}
}
}' \
"http://host:5000/v3/auth/tokens" ; echo
Endpoint images call:
curl -v -i -H "Content-Type: application/json" -H "X-Auth-Token:token" "http://host:8774/v2/images"; echo
In general, if you are getting timeouts on HTTP requests, the things to check are:
Are you using the correct hostname or IP address?
Are you using the correct port?
Is access being blocked by a firewall (somewhere)?
Is access being thwarted by misconfigured network routing (somewhere)?
Since you are using openstack4j, you can probably get more insights as to what is going on by turning on logging of the HTTP requests:
OSFactory.enableHttpLoggingFilter(true);
Check that it is sending requests to the V2 glance endpoint.
If that fails, use your IDE's Java debugger to figure out what requests are being sent to which service endpoints.
I am trying to use lets encrypt with docker in order to put my website in https.
I use docker with nginx proxy and nginx companion. I have set up everything correctly regarding documentation. My containers are running.
Now, i have an issue with lets encrypt here is the debug file provided :
{
"identifier": {
"type": "dns",
"value": "jack-world.com"
},
"status": "invalid",
"expires": "2017-12-20T18:42:39Z",
"challenges": [
{
"type": "tls-sni-01",
"status": "pending",
"uri": "https://acme-v01.api.letsencrypt.org/acme/challenge/G_0PYv_VpnEEUbV1PUjpJZyOIeP6b0zPxXeAlyYXclE/2728472678",
"token": "fXuUQ77koLDDTuAqEgeqQA1q_DHinF2wanQReSrgIdk"
},
{
"type": "dns-01",
"status": "pending",
"uri": "https://acme-v01.api.letsencrypt.org/acme/challenge/G_0PYv_VpnEEUbV1PUjpJZyOIeP6b0zPxXeAlyYXclE/2728472680",
"token": "iab5h37N-Io6lzfi8-DKmccXsF8_Y5Ws_RYCcwzREBw"
},
{
"type": "http-01",
"status": "invalid",
"error": {
"type": "urn:acme:error:unauthorized",
"detail": "The key authorization file from the server did not match this challenge [fnFwM8VZXXjIkSOci-z5_w4W2mN8oOIXA_d74gScLo0.K6eBCVMCFTPDy-GGls8jpd0O75tW9kFA9tsX7dEU_Zw] != [fnFwM8VZXXjIkSOci-z5_w4W2mN8oOIXA_d74gScLo0.4E3VCTFsySjUrqnCg0ooULx-3kbdPBygi0aWkvg5Gd8]",
"status": 403
},
"uri": "https://acme-v01.api.letsencrypt.org/acme/challenge/G_0PYv_VpnEEUbV1PUjpJZyOIeP6b0zPxXeAlyYXclE/2728472682",
"token": "fnFwM8VZXXjIkSOci-z5_w4W2mN8oOIXA_d74gScLo0",
"keyAuthorization": "fnFwM8VZXXjIkSOci-z5_w4W2mN8oOIXA_d74gScLo0.K6eBCVMCFTPDy-GGls8jpd0O75tW9kFA9tsX7dEU_Zw",
"validationRecord": [
{
"url": "http://jack-world.com/.well-known/acme-challenge/fnFwM8VZXXjIkSOci-z5_w4W2mN8oOIXA_d74gScLo0",
"hostname": "jack-world.com",
"port": "80",
"addressesResolved": [
"149.202.73.189",
"2001:41d0:301::21"
],
"addressUsed": "2001:41d0:301::21",
"addressesTried": []
}
]
}
],
"combinations": [
[
0
],
[
1
],
[
2
]
]
}
Here is logs from companion :
argos#jackworld:~/JackProxy$ sudo docker exec jackproxy_nginx-proxy-companion_1 /app/force_renew -v --help
/etc/nginx/certs/jack-world.com /app
Creating/renewal jack-world.com certificates... (jack-world.com)
2017-12-13 19:03:34,715:INFO:simp_le:1538: Retrieving Let's Encrypt latest Terms of Service.
2017-12-13 19:03:36,629:INFO:simp_le:1455: Generating new certificate private key
2017-12-13 19:03:37,221:ERROR:simp_le:1421: CA marked some of the authorizations as invalid, which likely means it could not access http://example.com/.well-known/acme-challenge/X. Did you set correct path in -d example.com:path or --default_root? Are all your domains accessible from the internet? Please check your domains' DNS entries, your host's network/firewall setup and your webserver config. If a domain's DNS entry has both A and AAAA fields set up, some CAs such as Let's Encrypt will perform the challenge validation over IPv6. If you haven't setup correct CAA fields or if your DNS provider does not support CAA, validation attempts after september 8, 2017 will fail. Failing authorizations: https://acme-v01.api.letsencrypt.org/acme/authz/Xw790v5P8mgdjsh-A-_wvwcmAFRIu-6UxlT2l5I7JB8
Challenge validation has failed, see error log.
Debugging tips: -v improves output verbosity. Help is available under --help.
/app
I need some help to figure out why http-01 is invalid, and if this is the only issue.
Thanks by advance
I am using meteor up to deploy to a vps. I get the error in the title during the "Start Meteor" stage of mup deploy, along with a long list of
Error response from daemon: endpoint (appname) not found
Error response from daemon: No such container: (appname)-frontend
etc.
I have tried changing the imagePort value for docker in mup.js but I still get the same error, still for 0.0.0.0:80
In your case there is already an application that uses port 80. You can either remove that app and go ahead and redeploy, or you can change the port that your meteor application is going to be using, like so:
module.exports = {
servers: { ... },
meteor: {
name: ...,
path: ...
buildOptions: ...
env: {
PORT: 3000,
ROOT_URL: 'http://<your server ip>:3000',
MONGO_URL: ...
},
deployCheckWaitTime: 120,
enableUploadProgressBar: true,
}
};
In my mup settings I have
"env": {
"ROOT_URL": "http://localhost",
"PORT": 3000,
"UPSTART_UID" : "meteoruser",
"MAIL_URL": "smtp://username:password#smtp.sendgrid.net:587",
"METEOR_ENV": "production"
},
I am following this.
http://johngibby.com/blog/How_to_deploy_your_meteor.js_app_on_Digital_Ocean
Should the port be 3000 or 80 and should the URL be my url?
ROOT_URL should be the url of your DigitalOcean droplet, which leads to your app. For example, if your droplet has an IP of 83.132.230.12, you could do:
"env": {
"ROOT_URL": "http://83.132.230.12",
"PORT": 3000,
"UPSTART_UID" : "meteoruser",
"MAIL_URL": "smtp://username:password#smtp.sendgrid.net:587",
"METEOR_ENV": "production" }
But it will be quite impractical for visitors to connect to http://83.132.230.12 in their web browser. It's better to have a domain name assigned to your droplet, in order to do:
"env": {
"ROOT_URL": "http://www.yourdomainname.com",
"PORT": 3000,
"UPSTART_UID" : "meteoruser",
"MAIL_URL": "smtp://username:password#smtp.sendgrid.net:587",
"METEOR_ENV": "production" }
PORT should be the port on which you want people to access your app. For example, if you give a 3000 port, your app will be accessed through http://www.yourdomainname.com:3000, which looks also impractical. On the other hand, web browsers use port 80 by default. So if you use "PORT": 80, your app will be accessible through http://www.yourdomainname.com (no port required in the url)