Terraform and Helm config for *.k.maelvls.dev
Infra-as-code (terraform + helm 3) for creating a Kubernetes cluster with:
- ExternalDNS is only used to set up
ns.k.maelvls.devsince I delegatek.maelvls.devto my own name server. I used to use ExternalDNS directly but it would litter the maelvls.dev zone. - I use a special instance of CoreDNS that runs
k8s_gateway). This instance of
CoreDNS does not replace the "kube-dns"-compatible CoreDNS instance that
run the
kubernetesplugin. - The zone delegated to this instance of CoreDNS is
*.k.maelvls.dev - For maelvls.dev itself, I was using Cloudflare and a domain at Godaddy. Now, I use a Google Domain and Google Cloud DNS.
- Letsencrypt certificates rotated automatically on a per-ingress basis
using cert-manager.
⚠️ Since the DNS zone that cert-manager wants to update in order to pass the DNS-01 challenges is now handled by CoreDNS and that CoreDNS isn't supported yet (and doesn't support rfc2136), I can't issue wildcard domains anymore and my
*.minio.k.maelvls.devper-bucket domains is now broken. One idea could be to use Ricardo Katz' rikatz/acme-solver which fakes cert-manager's DNS provider and instead uses the Order and Challenge objects to set CoreDNS records using its proxying-through-grpc mechanism.
Then:
# Prerequisite: # - have a Kubernetes cluster with the context "boring_wozniak". # - have the Google Cloud project "august-period-234610" on us-east1 (use the legacy way `gcloud auth application-default login`, not the new `gcloud auth login` since the gcloud terraform module uses the application-default method) # - have Terraform initialized (`terraform init`) # - have .envrc set with the env variables (see .envrc.example). terraform apply # idempotent ./helm_apply # idempotent
Launch the Traefik dashboard
$ kubectl proxy Starting to serve on 127.0.0.1:8001
Then, open: http://127.0.0.1:8001/api/v1/namespaces/traefik/services/http:traefik-dashboard:80/proxy
Or using port-forwaring:
kubectl -n traefik port-forward $(kubectl get pod -l app.kubernetes.io/name=traefik -oname -n traefik) 9000:9000 & open http://127.0.0.1:9000/dashboard/
Launching the Kubernetes Dashboard
Instructions: https://github.com/kubernetes/dashboard/wiki/Creating-sample-user
kubectl apply -f k8s/kubernetes-dashboard-user.yaml
kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep admin-user | awk '{print $1}')
kubectl proxy
open http://127.0.0.1:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:443/proxyKubernetes config management
https://blog.argoproj.io/the-state-of-kubernetes-configuration-management-d8b06c1205
- plain kubectl yaml in git
- templated kubectl yaml (terraform, ansible)
- specialized templated kubectl yaml (kustomize, ksonnet)
- config-as-javascript (pulumi)
FAQ
Error with some ingress+service
Error while evaluating the ingress spec: service is type "ClusterIP", expected "NodePort" or "LoadBalancer"
I realized this is because, in the Ingress, the portNumber must be a name, not a number. See: https://stackoverflow.com/questions/51572249
EXTERNAL-IP is pending on GKE
I disabled the embeded LB (see addon http_load_balancing) as I try to use
traefik instead. Info:
http://blog.chronos-technology.nl/post/disabling-gke-load-balancer-in-kubernetes
SOLUTION: I could only have one external IP at any time because of the free trial. For some reason, I had already created a static IP in GCP. As soon as I removed it, the LoadBalancer got an external IP.
Traefik does not register an Ingress
{
"level": "warning",
"msg": "Endpoints not available for kube-system/grafana",
"time": "2019-04-23T02:13:17Z"
}I think this is because the endpoints have notReadyAddresses status:
kubectl get endpoints -n kube-system grafana -o yaml
apiVersion: v1 kind: Endpoints metadata: labels: app: grafana chart: grafana-3.3.1 heritage: Tiller release: grafana name: grafana namespace: kube-system subsets: - notReadyAddresses: - ip: 10.0.0.19 nodeName: gke-august-period-234610-worker-bea0349b-gjtw targetRef: kind: Pod name: grafana-69df5dfc5c-mkfwh namespace: kube-system ports: - name: service port: 3000 protocol: TCP
{
"level": "error",
"msg": "Error configuring TLS for ingress kube-system/grafana: secret kube-system/grafana-example-tls does not exist",
"time": "2019-04-23T15:17:42Z"
}ACME not refreshing LetsEncrypt certs
In order to refresh the certificate issued by LetsEncrypt, just remove the corresponding secret:
kubectl delete secret -n kube-system prometheus-example-tls
Quick & dirty Kubernetes dashboard
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/master/aio/deploy/head.yaml kubectl proxy # Paste the content of that in the dashboard: kubectl -n kubernetes-dashboard get secret $(kubectl -n kubernetes-dashboard get sa kubernetes-dashboard -ojsonpath='{.secrets[*].name}') -ojsonpath='{.data.token}' | base64 -d | pbcopy