I have the https being generated for frontend https for flytime.io (cloud run)
Now I want to use this for https support for backend (multi-ingress gke autopilot), from the following manual, intended to used the api.flytime.io domain:
https://cloud.google.com/kubernetes-engine/docs/how-to/multi-cluster-ingress#https_support
But how should I configure the PATH_TO_KEYFILE and PATH_TO_CERTFILE with the manual (or there are other ways to do that)? If using the Google managed certification is not possible (why?), how do I generate a certificate for host name of api.flytime.io and get PATH_TO_KEYFILE and PATH_TO_CERTFILE?
If you are using GKE managed certificates, you don't use the secret method for setting up SSL in your Ingress. You have to create a ManagedCertificate object and then use the object's name in your Ingress in the networking.gke.io/managed-certificates annotation.
Here's an example. First, create the ManagedCertificate object.
apiVersion: networking.gke.io/v1
kind: ManagedCertificate
metadata:
name: managed-cert
spec:
domains:
- DOMAIN_NAME1 #<===== must be valid a domain you are owning
Now, reference this in your Ingress as follows:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: managed-cert-ingress
annotations:
kubernetes.io/ingress.global-static-ip-name: ADDRESS_NAME
networking.gke.io/managed-certificates: managed-cert #<=== HERE IS YOUR CERT
kubernetes.io/ingress.class: "gce"
spec:
defaultBackend:
service:
name: mc-service
port:
number: SERVICE_PORT
You can find more information on this docs page.
Related
Is it possible to use cert-manager to generate a certificate for a workload only in a cluster with ACME server in one of the namespaces? As far I understood cert-manager tries to reach dns name via egressing the cluster and ingressing the cluster to make a http chalange, but what if I do not want to leave the cluster? I do not want cert-manager to create Ingress resource. Let the whole challenge takes place inside the cluster.
My case:
I've got ACME server (step-ca) inside one of my namespaces
I need to create certificate for my POD in another namespace, e.g. common name "${app}.${namespace}"
Remarks: In my case the problem is more complicated due to istio on board. For ingress traffic cert-manager works fine with internal ACME server but for egress traffic I need to go over stunnel (in each POD) to reach Squid outside and I need those certs for stunnel.
The only way I came up with:
Each app has it's own Issuer
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: k8s-acme-local
namespace: ${APP_NS}
spec:
acme:
email: some#email
privateKeySecretRef:
name: k8s-acme-local
server: https://${ACME_SVC}.${ACME_NS}/acme/acme/directory
solvers:
- http01:
ingress:
podTemplate:
metadata:
labels:
app: ${APP}
ingressTemplate: {}
serviceType: ClusterIP
Before creating Certificate resource I create Service to take over the traffic to ${APP}.{APP_NS}
apiVersion: v1
kind: Service
metadata:
name: ${APP}
namespace: ${APP_NS}
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 8089
selector:
app: ${APP}
sessionAffinity: None
type: ClusterIP
And then the Certificate resource:
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: ${APP}
namespace: ${APP_NS}
spec:
secretName: ${APP}
issuerRef:
name: k8s-acme-local
kind: Issuer
group: cert-manager.io
commonName: ${APP}.${APP_NS}
dnsNames:
- ${APP}.${APP_NS}
Now Acme server will do the chalange over my Service not by Ingress (and cer-manager service) which stays unused. I don't like it but it works. This method has one critical drawback. Everyone in the cluster can do it and impersonate any existing or not existing app. I'm looking forward your opinions and tips.
Why my "Certificate" object and "Ingress" both are creating Certificates ?
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: blog-app-crt
spec:
secretName: blog-app-crt-sec
issuerRef:
kind: ClusterIssuer
name: letsencrypt-prod
commonName: blog.mydomain.com
dnsNames:
- blog.mydomain.com
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
# Email address used for ACME registration
email: myemailid#gmail.com
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
# Name of a secret used to store the ACME account private key
name: letsencrypt-production-private-key
# Add a single challenge solver, HTTP01 using nginx
solvers:
- http01:
ingress:
class: nginx
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-service
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /$1
cert-manager.io/cluster-issuer: "letsencrypt-prod"
nginx.ingress.kubernetes.io/ssl-redirect: 'true'
spec:
tls:
- hosts:
- blog.mydomain.com
secretName: blog-app-crt-sec
rules:
- host: blog.mydomain.com
http:
paths:
- pathType: Prefix
path: "/?(.*)"
backend:
service:
name: app-1-endpoint
port:
number: 5000
- pathType: Prefix
path: "/tribute/?(.*)"
backend:
service:
name: app-2-endpoint
port:
number: 5001
When I create above objects, it is creating 2 Certificate ojects, both pointing to same secret.
blog-app-crt-sec
blog-app-crt
How can I create Only 1 Certificate ? If I create only a ClusterIssuer without any custom certificate, then of course that will solve the issue, but I want to create a Custom certificate to control the renewal stuff.
There is a component of cert-manager called ingress-shim that watches Ingress resources and automatically creates Certificate objects for you when some annotations are present. This way, you wouldn’t even need to create the Certificate object on your own.
Please check your ingress definition for corresponding cert-manager.io scoped annotations and either use those or the manually created certificate. I assume you refer to the secret named blog-app-crt in your ingress definition. This needs to match what is defined in the cert spec secretName if you don’t use the automated creation!
For details on automatic certificate creation, please check the cert-manager docs on ingress: https://cert-manager.io/docs/usage/ingress/
In your case:
Annotation cert-manager.io/cluster-issuer tells that Ingress for generating certificates to your host (annotation on Ingress configuration plays a big role in the background).
That certificate configuration with kind: Certificate is also telling you to generate the certificate for your host.
You can either choose one of them on your configuration.
The best one for you is to drop that kind: Certificate configuration.
When do we drop the annotation and use the certificate?
For example, you have a.host.com, b.host.com, c.host.com and want to generate a single certificate and use it in multiple places, i.e. either in Ingress or in other TCP SSL configurations.
I have a EKS cluster configured with Iitio ingress gateway and my dns domain (test.com) is hosted in route53. I would like to generate the Letsencrypt certificate for my domain. I'm using the following version certmanager(0.14.1), Istio (1.6), Kubernetes (1.17). Can you please provide me the list of steps to be followed.
I am not much aware on how the setup has to be done for istio, but for ingress it's the following way, hope the same should work there too.
You can download the cert-manager helm chart from here and then you have to create the ingress rules for traffic routing, and for doing the TLS termination there you can follow this stackoverflow link
Kindly use
apiVersion: cert-manager.io/v1alpha2
in clusterissuer, if the apiVersion for clusterIssuer present in that stackoverflow post is not acceptable
There is related documentation about integration cert-menager and istio.
cert-manager
Configuration
Consult the cert-manager installation documentation to get started. No special changes are needed to work with Istio.
Usage
Istio Gateway
cert-manager can be used to write a secret to Kubernetes, which can then be referenced by a Gateway. To get started, configure a Certificate resource, following the cert-manager documentation. The Certificate should be created in the same namespace as the istio-ingressgateway deployment. For example, a Certificate may look like:
apiVersion: cert-manager.io/v1alpha2
kind: Certificate
metadata:
name: ingress-cert
namespace: istio-system
spec:
secretName: ingress-cert
commonName: my.example.com
dnsNames:
- my.example.com
...
Once we have the certificate created, we should see the secret created in the istio-system namespace. This can then be referenced in the tls config for a Gateway under credentialName:
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 443
name: https
protocol: HTTPS
tls:
mode: SIMPLE
credentialName: ingress-cert # This should match the Certifcate secretName
hosts:
- my.example.com # This should match a DNS name in the Certificate
Kubernetes Ingress
cert-manager provides direct integration with Kubernetes Ingress by configuring an annotation on the Ingress object. If this method is used, the Ingress must reside in the same namespace as the istio-ingressgateway deployment, as secrets will only be read within the same namespace.
Alternatively, a Certificate can be created as described in Istio Gateway, then referenced in the Ingress object:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress
annotations:
kubernetes.io/ingress.class: istio
spec:
rules:
- host: my.example.com
http: ...
tls:
- hosts:
- my.example.com # This should match a DNS name in the Certificate
secretName: ingress-cert # This should match the Certifcate secretName
Additionally there is an example made by #chrisnyc on istio discuss.
Hope you find this useful.
I am hosting an application on GKE and would like to be able to let users from my organization access this application from the web. I would like them to be able to log-in using their Google Account IAM credentials.
Is there a way to configure a service exposing the clusters web endpoint such that to access this service the user simply needs to login with their google account?
For example, when testing a service I can easily do a web-preview in the cloud-shell and then access the web application in my browser.
Is there a way to configure this such that any users authorized in my organization can access the web interface of my application?
(Note, I asked the same question on DevOps but I feel like that site is not yet as active as it should be so I ask here as well)
Okay, I managed to make it work perfectly. But it took a few steps. I am including the manifest here that is required to setup the IAP using an ingress. It requires a few things which I listed in the manifest below. Hopefully this can help others since I could not find a single source that had all of this put together. Essentially all you need to do is run kubectl apply -f secure-ingress.yaml to make everything work (as long as you have all the depenedencies) and then you just need to configure your IAP as you like it.
secure-ingress.yaml
# Configure IAP security using ingress automatically
# requirements: kubernetes version at least 1.10.5-gke.3
# requirements: service must respond with 200 at / endpoint (the healthcheck)
# dependencies: need certificate secret my-secret-cert
# dependencies: need oath-client secret my-secret-oath (with my.domain.com configured)
# dependencies: need external IP address my-external-ip
# dependencies: need domain my.domain.com to point to my-external-ip IP
# dependencies: need an app (deployment/statefulset) my-app
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-secure-ingress
namespace: default
annotations:
kubernetes.io/ingress.class: "gce"
kubernetes.io/ingress.allow-http: "false"
kubernetes.io/ingress.global-static-ip-name: my-external-ip
spec:
tls:
- secretName: my-secret-cert
backend:
serviceName: my-service-be-web
servicePort: 1234
---
kind: Service
apiVersion: v1
metadata:
name: my-service-be-web
namespace: default
annotations:
beta.cloud.google.com/backend-config:
'{"default": "my-service-be-conf"}'
spec:
type: NodePort
selector:
app: my-app
ports:
- protocol: TCP
port: 1234
targetPort: 1234
name: my-port-web
---
apiVersion: cloud.google.com/v1beta1
kind: BackendConfig
metadata:
name: my-service-be-conf
namespace: default
spec:
iap:
enabled: true
oauthclientCredentials:
secretName: my-secret-oath
I'm trying to get a GKE ingress to require basic auth like this example from github.
The ingress works fine. It routes to the service. But the authentication isn't working. Allows all traffic right through. Has GKE not rolled this feature out yet? Something obviously wrong in my specs?
Here's the ingress:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: super-ingress
annotations:
ingress.kubernetes.io/auth-type: basic
ingress.kubernetes.io/auth-secret: basic-auth
ingress.kubernetes.io/auth-realm: "Authentication Required"
spec:
rules:
- host: zzz.host.com
http:
paths:
- backend:
serviceName: super-service
servicePort: 9000
path: /*
And the basic-auth secret:
$ kubectl get secret/basic-auth -o yaml
apiVersion: v1
data:
auth: XXXXXXXXXXXXXXXXXXX
kind: Secret
metadata:
creationTimestamp: 2016-10-03T21:21:52Z
name: basic-auth
namespace: default
resourceVersion: "XXXXX"
selfLink: /api/v1/namespaces/default/secrets/basic-auth
uid: XXXXXXXXXXX
type: Opaque
Any insights are greatly appreciated!
The example you linked to is for nginx ingress controller. GKE uses GLBC, which doesn't support auth.
You can deploy an nginx ingress controller in your gke cluster. Note that you need to annotate your ingress to avoid the GLBC claiming the ingress. Then you can expose the nginx controller directly, or create a glbc ingress to redirect traffic to the nginx ingress (see this snippet written by bprashanh).