traefik/docs/user-guide/grpc.md

151 lines
3.7 KiB
Markdown
Raw Normal View History

2017-09-16 08:56:02 +00:00
# gRPC example
This section explains how to use Traefik as reverse proxy for gRPC application with self-signed certificates.
!!! warning
2017-10-10 10:14:03 +00:00
As gRPC needs HTTP2, we need HTTPS certificates on both gRPC Server and Træfik.
2017-09-16 08:56:02 +00:00
<p align="center">
<img src="/img/grpc.svg" alt="gRPC architecture" title="gRPC architecture" />
</p>
## gRPC Server certificate
In order to secure the gRPC server, we generate a self-signed certificate for backend url:
```bash
2017-10-02 09:34:03 +00:00
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./backend.key -out ./backend.cert
2017-09-16 08:56:02 +00:00
```
That will prompt for information, the important answer is:
```
Common Name (e.g. server FQDN or YOUR name) []: backend.local
```
## gRPC Client certificate
Generate your self-signed certificate for frontend url:
```bash
2017-10-02 09:34:03 +00:00
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./frontend.key -out ./frontend.cert
2017-09-16 08:56:02 +00:00
```
with
```
Common Name (e.g. server FQDN or YOUR name) []: frontend.local
```
## Træfik configuration
At last, we configure our Træfik instance to use both self-signed certificates.
```toml
defaultEntryPoints = ["https"]
# For secure connection on backend.local
2018-04-06 07:38:03 +00:00
rootCAs = [ "./backend.cert" ]
2017-09-16 08:56:02 +00:00
[entryPoints]
[entryPoints.https]
address = ":4443"
[entryPoints.https.tls]
# For secure connection on frontend.local
[[entryPoints.https.tls.certificates]]
certFile = "./frontend.cert"
keyFile = "./frontend.key"
[api]
2017-09-16 08:56:02 +00:00
[file]
[backends]
[backends.backend1]
[backends.backend1.servers.server1]
# Access on backend with HTTPS
url = "https://backend.local:8080"
[frontends]
[frontends.frontend1]
backend = "backend1"
[frontends.frontend1.routes.test_1]
rule = "Host:frontend.local"
```
2017-10-10 10:14:03 +00:00
!!! warning
2018-04-06 07:38:03 +00:00
With some backends, the server URLs use the IP, so you may need to configure `insecureSkipVerify` instead of the `rootCAS` to activate HTTPS without hostname verification.
2017-10-10 10:14:03 +00:00
2017-09-16 08:56:02 +00:00
## Conclusion
2017-10-10 10:14:03 +00:00
We don't need specific configuration to use gRPC in Træfik, we just need to be careful that all the exchanges (between client and Træfik, and between Træfik and backend) are HTTPS communications because gRPC uses HTTP2.
2017-09-16 08:56:02 +00:00
## A gRPC example in go
We will use the gRPC greeter example in [grpc-go](https://github.com/grpc/grpc-go/tree/master/examples/helloworld)
!!! warning
In order to use this gRPC example, we need to modify it to use HTTPS
So we modify the "gRPC server example" to use our own self-signed certificate:
```go
// ...
// Read cert and key file
2017-10-02 09:34:03 +00:00
BackendCert, _ := ioutil.ReadFile("./backend.cert")
BackendKey, _ := ioutil.ReadFile("./backend.key")
2017-09-16 08:56:02 +00:00
// Generate Certificate struct
cert, err := tls.X509KeyPair(BackendCert, BackendKey)
if err != nil {
2017-10-02 09:34:03 +00:00
log.Fatalf("failed to parse certificate: %v", err)
2017-09-16 08:56:02 +00:00
}
// Create credentials
creds := credentials.NewServerTLSFromCert(&cert)
// Use Credentials in gRPC server options
serverOption := grpc.Creds(creds)
var s *grpc.Server = grpc.NewServer(serverOption)
defer s.Stop()
2017-10-02 09:34:03 +00:00
pb.RegisterGreeterServer(s, &server{})
2017-09-16 08:56:02 +00:00
err := s.Serve(lis)
// ...
```
Next we will modify gRPC Client to use our Træfik self-signed certificate:
```go
// ...
// Read cert file
2017-10-02 09:34:03 +00:00
FrontendCert, _ := ioutil.ReadFile("./frontend.cert")
2017-09-16 08:56:02 +00:00
// Create CertPool
roots := x509.NewCertPool()
roots.AppendCertsFromPEM(FrontendCert)
// Create credentials
credsClient := credentials.NewClientTLSFromCert(roots, "")
// Dial with specific Transport (with credentials)
2017-10-02 09:34:03 +00:00
conn, err := grpc.Dial("frontend.local:4443", grpc.WithTransportCredentials(credsClient))
2017-09-16 08:56:02 +00:00
if err != nil {
2017-10-02 09:34:03 +00:00
log.Fatalf("did not connect: %v", err)
2017-09-16 08:56:02 +00:00
}
defer conn.Close()
2017-10-02 09:34:03 +00:00
client := pb.NewGreeterClient(conn)
2017-09-16 08:56:02 +00:00
name := "World"
2017-10-02 09:34:03 +00:00
r, err := client.SayHello(context.Background(), &pb.HelloRequest{Name: name})
2017-09-16 08:56:02 +00:00
// ...
```