Setup a simple web application with rancher 2

I’m struggeling with setting up a simple rancher 2 on a single server.

  • I setup rancher 2 (with docker 17.03.2-ce)

    docker run -p 80:80 -p 443:443 rancher/rancher:latest --acme-domain cluster.somedomain

  • then i setup a cluster and add a note

  • I add a worload (simple apache server with self signed ssl cert using port 80/443), i map the ports to random ports in the cluster

  • when i test the generated ports i get the expected behaviour also with the domain (somedomain:32176 is working)

  • now i add an ingress rule with the host “somedomain” no path and connect it to my workload, no matter what port i configure (80,443 or the random generated) i always get a SSL_Error “acme/autocert: host not configured”

I tried several things with letsencrypt, certificates, custom paths, but nothing is working.

Me too. I actually tried this exact thing. Also, pretty much anything I try to one-click install from the Catalogs (Library/Helm) doesn’t work on first attempt. Granted, I’m totally new to Rancher/Kubernetes but man you hit the wall pretty quick when trying this stuff out for the first time. If it wasn’t so damn cool I’d probably have bailed on it by now.

1 Like

This was my initial working setup on Digitalocean:

  1. Setup rancher as you already did (rancher 2.0.4 or later)
  2. Setup a cluster with 1 etcd + control node and 1 or more worker nodes. It’s very important that all the nodes have at least 4gb ram and 2 cores/vcpu. The first time I tested with 1gb ram and 1vcpu and after a while the cluster started throwing errors. Using the same node as worker and etcd/control can cause out of memory errors and lost communication to the cluster.
  3. Deploy a workload with apache, do not configure ports for the workload and do not configure ssl in apache. SSL will be handled by the Ingress, communication between the Ingress (load balancer) and the workload will use unencrypted http.
  4. In Load balancing Add Ingress and select the workload in the Target field, port 80 (this is the port on the target workload, there is no way to specify the source port). Generate xip.io domain or specify hostname. Do not add more than 1 rule. I read somewhere it’s not supported. You need to create another ingress if you need more rules.
  5. If a certificate already exists in the rancher project (Resources->Certificates) select it in SSL/TLS Certificates and specify again the same hostname as specified in the rule.
  6. After the workload is running you should be able to access the default page.

Note: Everything is easier if all is in the same namespace (default) including the certificate, workload and ingress since resources are not shared between namespaces.

The other hard thing for me to set up was using Let’s encrypt to create ssl certificates. So here’s what worked for me:

I used cloudflare for certificate validation. You can check other validation methods in the cert-manager docs, I couldn’t make them work so I used dns validation and also with dns validation you can get wildcard certificates.

  1. Install cert-manager from Catalog Apps.
  2. Create a secret (Resources -> Secrets) with the cloudflare api key, available to the cert-manager namespace
  3. Create a ClusterIssuer
  4. Create a Certificate for each certificate you want Lets Encrypt to generate
  5. It takes a while for cert-manager to create and validate the certificate. If everything was setup properly in about 20 to 30 minutes the certificate will be available in Resources -> Certificates.

You can create the Secret, ClusterIssuer and Certificate using the Import YAML button in the Rancher Project and the following YAML, configure it according to your environment.

apiVersion: v1
kind: Secret
metadata:
  name: cloudflare-api-key-secret
  namespace: cert-manager
stringData:
  api-key: "YOURAPIKEY"
---
apiVersion: certmanager.k8s.io/v1alpha1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    dns01:
      providers:
      - cloudflare:
          apiKeySecretRef:
            key: api-key
            name: cloudflare-api-key-secret
          email: YOURCLOUDFLAREACCOUNTEMAIL
        name: prod-cloudflare
    email: YOURLETSENCRYPTEMAIL
    privateKeySecretRef:
      name: lets-encrypt-prod-key
    server: https://acme-v02.api.letsencrypt.org/directory
---
apiVersion: certmanager.k8s.io/v1alpha1
kind: Certificate
metadata:
  name: MYNEWCERTNAME
  namespace: default
spec:
  acme:
    config:
    - dns01:
        provider: prod-cloudflare
      domains:
      - '*.MYDOMAIN.COM'
      - MYDOMAIN.COM
  commonName: '*.MYDOMAIN.COM'
  dnsNames:
  - MYDOMAIN.com
  issuerRef:
    kind: ClusterIssuer
    name: letsencrypt-prod
  secretName: wildcard-MYDOMAIN-COM-tls

thank you for sharing your setup. So I removed the ssl from apache and not forwarding any port in the workload.

At the moment I only have one physical node to test with. I tried to setup 2 (etc+control) and a worker on one machine but that was resulting in a merge and a bunch of errors.
So I tried everything without using the letsencrypt for rancher (so without the --acme startup parameter). When i now go to “somedomain” i don’t get an ssl error but it just links me to the rancher login.

Now I tried to run rancher on a diffrent port (88/4444). When i had no port forrwarding i got “503 Service Temporarily Unavailable”. After i added the 80/port it was working. I dont’t know why it works that way and everything seems very random and confusing. I actually wanted “cluster.somedomain” to be the rancher site and “somedomain” something inside the cluster.

In your case when you install rancher and kubernetes worker node on same host, you have to take care of following steps:

  1. Run rancher on other port say 8080, ( no tls port needed 8443), because ingress will take control of 80, 443 ports on every node.
  2. create a k8s Service that point to rancher external IP and port 8080 (like below)
  3. add ingress for above service and let ingress handle traffic to rancher. use cluster.somedomain here.
apiVersion: v1
kind: Service
metadata:
  name: rancher-external-service
  namespace: rancher-external
  annotations:
    field.cattle.io/ipAddresses: '["1.2.3.4"]'  # rancher external ip
spec:
  clusterIP: None
  ports:
  - protocol: TCP
    port: 8080
    targetPort: 8080
  type: ClusterIP
  sessionAffinity: None

thank you very much for the clarification.