avatarLiejun Tao

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

8300

Abstract

<pre><span class="hljs-comment"># check log</span> <span class="hljs-string">$</span> <span class="hljs-string">kubectl</span> <span class="hljs-string">-n</span> <span class="hljs-string">consul</span> <span class="hljs-string">logs</span> <span class="hljs-string">-f</span> <span class="hljs-string">consul-0</span> <span class="hljs-string">-c</span> <span class="hljs-string">consul</span> <span class="hljs-string">bootstrap_expect</span> <span class="hljs-string">&gt;</span> <span class="hljs-attr">0:</span> <span class="hljs-string">expecting</span> <span class="hljs-number">3</span> <span class="hljs-string">servers</span> <span class="hljs-string">==&gt;</span> <span class="hljs-string">Starting</span> <span class="hljs-string">Consul</span> <span class="hljs-string">agent...</span> <span class="hljs-string">==&gt;</span> <span class="hljs-string">Consul</span> <span class="hljs-string">agent</span> <span class="hljs-string">running!</span> <span class="hljs-attr">Version:</span> <span class="hljs-string">'v1.5.0'</span> <span class="hljs-attr">Node ID:</span> <span class="hljs-string">'159adb35-0cfd-2c58-ea51-8e3a6b64ee4c'</span> <span class="hljs-attr">Node name:</span> <span class="hljs-string">'consul-0'</span> <span class="hljs-attr">Datacenter:</span> <span class="hljs-string">'dc1'</span> <span class="hljs-string">(Segment:</span> <span class="hljs-string">'&lt;all&gt;'</span><span class="hljs-string">)</span> <span class="hljs-attr">Server:</span> <span class="hljs-literal">true</span> <span class="hljs-string">(Bootstrap:</span> <span class="hljs-literal">false</span><span class="hljs-string">)</span> <span class="hljs-attr">Client Addr:</span> [<span class="hljs-number">0.0</span><span class="hljs-number">.0</span><span class="hljs-number">.0</span>] <span class="hljs-string">(HTTP:</span> <span class="hljs-number">8500</span><span class="hljs-string">,</span> <span class="hljs-attr">HTTPS:</span> <span class="hljs-number">8443</span><span class="hljs-string">,</span> <span class="hljs-attr">gRPC:</span> <span class="hljs-number">-1</span><span class="hljs-string">,</span> <span class="hljs-attr">DNS:</span> <span class="hljs-number">8600</span><span class="hljs-string">)</span> <span class="hljs-attr">Cluster Addr:</span> <span class="hljs-number">10.0</span><span class="hljs-number">.210</span><span class="hljs-number">.154</span> <span class="hljs-string">(LAN:</span> <span class="hljs-number">8301</span><span class="hljs-string">,</span> <span class="hljs-attr">WAN:</span> <span class="hljs-number">8302</span><span class="hljs-string">)</span> <span class="hljs-attr">Encrypt: Gossip:</span> <span class="hljs-literal">true</span><span class="hljs-string">,</span> <span class="hljs-attr">TLS-Outgoing:</span> <span class="hljs-literal">true</span><span class="hljs-string">,</span> <span class="hljs-attr">TLS-Incoming:</span> <span class="hljs-literal">true</span></pre></div><div id="6454"><pre><span class="hljs-comment"># forward consul to localhost</span>

<span class="hljs-variable"></span>kubectl -n consul port-forward consul-<span class="hljs-number">0</span> <span class="hljs-number">8500</span>:<span class="hljs-number">8500</span> &amp;</pre></div><div id="5b9e"><pre><span class="hljs-comment"># run this command in different console to maintain the connection</span> <span class="hljs-keyword">while</span> <span class="hljs-literal">true</span>; <span class="hljs-keyword">do</span> consul members && <span class="hljs-built_in">sleep</span> 20; <span class="hljs-keyword">done</span></pre></div><div id="e899"><pre>$ consul members Node Address Status <span class="hljs-keyword">Type</span> Build Protocol DC Segment consul<span class="hljs-number">-0</span> <span class="hljs-number">10.0</span><span class="hljs-number">.210</span><span class="hljs-number">.154</span>:<span class="hljs-number">8301</span> alive <span class="hljs-keyword">server</span> <span class="hljs-number">1.5</span><span class="hljs-number">.0</span> <span class="hljs-number">2</span> dc1 <<span class="hljs-keyword">all</span>> consul<span class="hljs-number">-1</span> <span class="hljs-number">10.0</span><span class="hljs-number">.143</span><span class="hljs-number">.30</span>:<span class="hljs-number">8301</span> alive <span class="hljs-keyword">server</span> <span class="hljs-number">1.5</span><span class="hljs-number">.0</span> <span class="hljs-number">2</span> dc1 <<span class="hljs-keyword">all</span>> consul<span class="hljs-number">-2</span> <span class="hljs-number">10.0</span><span class="hljs-number">.181</span><span class="hljs-number">.84</span>:<span class="hljs-number">8301</span> alive <span class="hljs-keyword">server</span> <span class="hljs-number">1.5</span><span class="hljs-number">.0</span> <span class="hljs-number">2</span> dc1 <<span class="hljs-keyword">all</span>> </pre></div><p id="e474">Browse to <a href="http://localhost:8500">http://localhost:8500</a> for the consul UI</p><figure id="a019"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*OwZda7AMxw6vcQwNhyxmAA.png"><figcaption>Consul services</figcaption></figure><figure id="ab5a"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*kzz8hllXsSBOWfzDddPtzw.png"><figcaption>Consul nodes</figcaption></figure><figure id="2928"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*uytqGW3ZWl13IjiNCw0GvQ.png"><figcaption>Consul K/V store, now empty</figcaption></figure><h2 id="03c0">Import traefik.toml into Consul</h2><p id="359d">I have this traefik.toml.sample as template. Fill in proper email address and domain name to generate a file traefik.toml.</p> <figure id="e5ef"> <div> <div>

            <iframe class="gist-iframe" src="/gist/liejuntao001/0209124571d0d369d524061217f95f85.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
          </div>
        </div>
    </figure></iframe></div></div></figure><p id="22f7">Import traefik.toml with ‘traefik storeconfig’ command.</p><div id="c2e0"><pre><span class="hljs-comment"># Generate from template</span>

<span class="hljs-attribute">EMAIL</span>[email protected] <span class="hljs-attribute">DOMAIN</span>=example.com envsubst &lt; traefik.toml.kv.sample &gt; traefik.toml</pre></div><div id="39d0"><pre><span class="hljs-comment"># forward consul to localhost</span> <span class="hljs-variable"> </span>kubectl -n consul port-forward consul-<span class="hljs-number">0</span> <span class="hljs-number">8500</span>:<span class="hljs-number">8500</span> &</pre></div><div id="8d2c"><pre><span class="hljs-comment"># magic time</span> $ traefik storeconfig --consul --consul.<span class="hljs-attribute">endpoint</span>=localhost:8500 --file.<span class="hljs-attribute">filename</span>=./traefik.toml <span class="hljs-built_in">..</span>. Writing<span class="hljs-built_in"> config </span><span class="hljs-keyword">to</span> KV</pre></div><p id="77d1">If properly imported, check the values in Consul K/V store</p><figure id="7361"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*z27gviv45MWFjI3iLHeURw.png"><figcaption>K/V store after import</figcaption></figure><p id="14f8">After above importing steps, a manual change for the value of key traefik/consul/endpoint is needed. As shown in below screenshot, to ‘<a href="https://consul.consul.svc.cluster.local:8443">https://consul.consul.svc.cluster.local:8443</a>’, which is the URL to the consul service.</p><figure id="9c0b"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*PgVe1D9RAMM1FRT-D1edWQ.png"><figcaption>manually modify this valule</figcaption></figure><p id="e185">If there are existing Let’sEncrypt certificates in a file acme.json, simply un-comment the line</p><div id="a877"><pre><span class="hljs-meta">#storageFile = <span class="hljs-string">"./acme.json"</span></span></pre></div><p id="9996">from file traefik.toml and do the import. It will also get imported into Consul.</p><p id="bdda">Then delete the key traefik/acme/account/lock, to a

Options

llow the Traefik Ingress pods get the lock.</p><h2 id="d658">Deploy Traefik Ingress Controller cluster</h2><p id="b428">Create TLS secret for traefik cluster. It’s used to access Consul.</p><div id="9f18"><pre>cd ca kubectl -n kube-system create secret generic traefik-consul
<span class="hljs-meta prompt_">></span> <span class="language-javascript"> --<span class="hljs-keyword">from</span>-file=ca.<span class="hljs-property">pem</span> </span> <span class="hljs-meta prompt_">></span> <span class="language-javascript"> --<span class="hljs-keyword">from</span>-file=traefik.<span class="hljs-property">pem</span> </span> <span class="hljs-meta prompt_">></span> <span class="language-javascript"> --<span class="hljs-keyword">from</span>-file=traefik-key.<span class="hljs-property">pem</span></span> secret/traefik-consul created</pre></div><p id="531d">Create traefik dashboard secret.</p><div id="ef15"><pre>kubectl -n kube-<span class="hljs-keyword">system</span> create secret <span class="hljs-keyword">generic</span> kubesecret --<span class="hljs-keyword">from</span>-file auth</pre></div><p id="4e65">File ‘auth’ is created from this command. The username/password will be used to access the traefik dashboard</p><div id="ced9"><pre> htpasswd -c ./auth <span class="hljs-tag">&lt;username&gt;</span> New password: Re-<span class="hljs-keyword">type</span> new password: Adding password for <span class="hljs-keyword">user</span> <span class="hljs-title">testaaa</span></pre></div><p id="3693">Now deploy it.</p><p id="47e7">The example traefik_kv.yaml will deploy to master nodes. If this is not desired, adjust the “nodeAffinity” part.</p><div id="d7cd"><pre>DOMAIN=example.com envsubst &lt; traefik_kv.yaml | <span class="hljs-type">kubectl</span> <span class="hljs-built_in">apply</span> -f -</pre></div><p id="ff41">There are 3 pods for traefik-ingress-controller.</p><div id="e19a"><pre> kubectl <span class="hljs-operator">-</span>n kube<span class="hljs-operator">-</span><span class="hljs-keyword">system</span> <span class="hljs-keyword">get</span> pod <span class="hljs-operator">-</span>o wide traefik<span class="hljs-operator">-</span>ingress<span class="hljs-operator">-</span>controller<span class="hljs-number">-5</span>dlbz <span class="hljs-number">1</span><span class="hljs-operator">/</span><span class="hljs-number">1</span> <span class="hljs-keyword">Running</span> <span class="hljs-number">0</span> <span class="hljs-number">5</span>m21s <span class="hljs-number">10.0</span><span class="hljs-number">.142</span><span class="hljs-number">.69</span> master3 traefik<span class="hljs-operator">-</span>ingress<span class="hljs-operator">-</span>controller<span class="hljs-number">-9</span>nxqt <span class="hljs-number">1</span><span class="hljs-operator">/</span><span class="hljs-number">1</span> <span class="hljs-keyword">Running</span> <span class="hljs-number">0</span> <span class="hljs-number">6</span>m34s <span class="hljs-number">10.0</span><span class="hljs-number">.123</span><span class="hljs-number">.196</span> master2
traefik<span class="hljs-operator">-</span>ingress<span class="hljs-operator">-</span>controller<span class="hljs-operator">-</span>xzkzd <span class="hljs-number">1</span><span class="hljs-operator">/</span><span class="hljs-number">1</span> <span class="hljs-keyword">Running</span> <span class="hljs-number">0</span> <span class="hljs-number">5</span>m34s <span class="hljs-number">10.0</span><span class="hljs-number">.255</span><span class="hljs-number">.14</span> master1 </pre></div><p id="6368">Add labels to the nodes which has Ingress Controller deployed, as I will use the label to handle the cluster reboot sequence. Refer to my article “How to reboot highly available Kubernetes Cluster” (<a href="https://readmedium.com/how-to-reboot-highly-available-kubernetes-cluster-5a9df4daecf">link</a>).</p><div id="6933"><pre><span class="hljs-comment"># for all nodes that has Ingress Controller</span> kubectl label nodes master1 <span class="hljs-keyword">node</span><span class="hljs-title">-role</span>.kubernetes.io/<span class="hljs-attr">ingress-controller=</span></pre></div><div id="8e0d"><pre> kubectl get nodes NAME STATUS ROLES AGE <span class="hljs-keyword">VERSION</span> master1 Ready ingress-controller,<span class="hljs-keyword">master</span> <span class="hljs-title">49d</span> v1.<span class="hljs-number">14.1</span> master2 Ready ingress-controller,<span class="hljs-keyword">master</span> <span class="hljs-title">49d</span> v1.<span class="hljs-number">14.1</span> master3 Ready ingress-controller,<span class="hljs-keyword">master</span> <span class="hljs-title">49d</span> v1.<span class="hljs-number">14.1</span> worker1 Ready <span class="hljs-tag"><none></span> <span class="hljs-number">49</span>d v1.<span class="hljs-number">14.1</span> worker2 Ready <span class="hljs-tag"><none></span> <span class="hljs-number">48</span>d v1.<span class="hljs-number">14.1</span> worker3 Ready <span class="hljs-tag"><none></span> <span class="hljs-number">48</span>d v1.<span class="hljs-number">14.1</span></pre></div><h2 id="52ea">Add Haproxy rules</h2><p id="a016">When the traefik cluster is ready, add haproxy rules to both primary and backup haproxy hosts. Basically, forward port 80 and 443.</p> <figure id="7fc6"> <div> <div>

            <iframe class="gist-iframe" src="/gist/liejuntao001/651490c9033b0980a9ff778fa117d372.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
          </div>
        </div>
    </figure></iframe></div></div></figure><p id="6ac9">As the DNS for the domain point to the haproxy, now the traefik dashboard h<a href="https://traefik.example.com/">ttps://traefik.k8s.example.com/</a> is accessible, with the username/password created above.</p><h2 id="c67b">Export acme from consul</h2><p id="a690">I’d like to check/backup the Let’sEncrypt certificates that the Traefik cluster has got for the services. I couldn’t find clear instructions and below is my steps after some tries.</p><div id="17e1"><pre><span class="hljs-comment"># Connect to consul</span>

<span class="hljs-attribute">kubectl</span> -n consul port-forward consul-<span class="hljs-number">0</span> <span class="hljs-number">8500</span>:<span class="hljs-number">8500</span> &</pre></div><div id="c76b"><pre><span class="hljs-comment"># Keep the consul connection open</span> <span class="hljs-keyword">while</span> <span class="hljs-literal">true</span>; <span class="hljs-keyword">do</span> consul members && <span class="hljs-built_in">sleep</span> 10; <span class="hljs-keyword">done</span></pre></div><div id="a4e2"><pre><span class="hljs-comment"># retrieve compressed acme object</span> consul kv <span class="hljs-built_in">get</span> traefik/acme/account/object > acme.gz</pre></div><div id="92ee"><pre><span class="hljs-meta"># gunzip</span> cat acme.gz <span class="hljs-string">| gunzip > acme.json</span></pre></div><div id="65c0"><pre># <span class="hljs-keyword">Format</span> cat acme.json | jq <span class="hljs-string">'.'</span> > acme.json.formatted</pre></div><h2 id="a69e">Backup/Restore consul</h2><p id="d12f">I hit a case that I want to change the Persistent volumes for the consul cluster. So I need destroy the consul cluster and recreate it. Obviously I don’t want to lose the existing KV values. I found it is pretty easy with the consul snapshot backup/restore.</p><ol><li>Create a snapshot as backup</li><li>Destroy the consul statefulsets and pvc</li><li>Re-create with new consul configs</li><li>Restore from snapshot</li></ol><div id="80be"><pre><span class="hljs-meta"># backup</span> consul snapshot <span class="hljs-keyword">save</span> backup.snap</pre></div><div id="85c8"><pre># <span class="hljs-built_in">restore</span> consul snapshot <span class="hljs-built_in">restore</span> backup.snap</pre></div><p id="30b3">Thanks for reading.</p></article></body>

Traefik cluster as Ingress Controller for Kubernetes

Traefik cluster as Ingress Controller for Kubernetes

Introduction

Ingress Controller is the portal to the services running on Kubernetes cluster. To get a highly available cluster, there should be multiple Ingress Controllers working together as a cluster.

Traefik is one of the Ingress Controllers. I use it for its dynamic configuration and automatic LetsEncrypt certificates. There are many instructions to deploy a single Traefik Ingress Controller but not so much details for a Traefik cluster as Ingress Controller. The official document is quite brief, so I’d like to share my experience in this article.

A working HA Kubernetes cluster has at least 3 master nodes and some workers. I have shared my experience here. By adding Traefik cluster, the architecture of the cluster is like below diagram.

Here I deploy Ingress Controllers on the master nodes, which I think is suitable for a low traffic cluster. More instances could be deployed to worker nodes, if the cluster need serve high traffic.

Architecture

Updated 1/9/2020

Traefik uses Consul Cluster as storage back end. To make it secure/stable, I shared my recent experience about running Consul in Kubernetes for production in this article.

Prerequisite

consul command line, example as below

cd /tmp && wget   https://releases.hashicorp.com/consul/1.5.1/consul_1.5.1_linux_amd64.zip && unzip consul_1.5.1_linux_amd64.zip && sudo mv consul /usr/local/bin

traefik command line, example as below

cd /tmp && wget https://github.com/containous/traefik/releases/download/v1.7.11/trae  fik_linux-amd64 && chmod +x traefik_linux-amd64 && mv traefik_linux-amd64 traefik && sudo mv traefik /usr/local/bin

go environment, cfssl, cfssljson

# Install gimme
$ curl -sL -o ~/bin/gimme https://raw.githubusercontent.com/travis-ci/gimme/master/gimme
$ chmod +x ~/bin/gimme
# Install go
$ eval `gimme stable`
# Install cfssl, cfssljson
go get -u github.com/cloudflare/cfssl/cmd/cfssl
go get -u github.com/cloudflare/cfssl/cmd/cfssljson

Sources used in this article

github link

Deploy Consul

Consul is used as KV store for Traefik, while it’s actually much more powerful.

I’m following first half of this tutorial to deploy a 3-replicas consul cluster.

Generate CA and certificate for consul

$ cd ca
# Generate CA
$ cfssl gencert -initca config/ca-csr.json | cfssljson -bare ca
# Generate certs
$ cfssl gencert \
    -ca=ca.pem \
    -ca-key=ca-key.pem \
    -config=config/ca-config.json \
    -profile=default \
    config/consul-csr.json | cfssljson -bare consul
$ cfssl gencert \
    -ca=ca.pem \
    -ca-key=ca-key.pem \
    -config=config/ca-config.json \
    -profile=default \
    config/traefik-csr.json | cfssljson -bare traefik

Deploy consul

As Consul need persistent volume, adjust storageClassName in consul/consul_statefulset.yml properly.

If the cluster has less than 3 worker nodes, remove the “podAntiAffinity” from consul/consul_statefulset.yml. However to get highly available Consul cluster, it’s better to have 3 or 5 replicas running on different nodes.

kubectl apply -f consul/

Generate consul secrets

$ cd ca
# Generate gossip key
$ export GOSSIP_ENCRYPTION_KEY=$(consul keygen)
# consul
$ kubectl -n consul create secret generic consul \
  --from-literal="gossip-encryption-key=${GOSSIP_ENCRYPTION_KEY}" \
  --from-file=ca.pem \
  --from-file=consul.pem \
  --from-file=consul-key.pem

If things go well, we should have the 3 consul pods up.

$ kubectl -n consul get pod
NAME       READY   STATUS    RESTARTS   AGE
consul-0   2/2     Running   0          17s
consul-1   2/2     Running   0          14s
consul-2   2/2     Running   0          11s
# check log
$ kubectl -n consul logs -f consul-0 -c consul
bootstrap_expect > 0: expecting 3 servers
==> Starting Consul agent...
==> Consul agent running!
           Version: 'v1.5.0'
           Node ID: '159adb35-0cfd-2c58-ea51-8e3a6b64ee4c'
         Node name: 'consul-0'
        Datacenter: 'dc1' (Segment: '<all>')
            Server: true (Bootstrap: false)
       Client Addr: [0.0.0.0] (HTTP: 8500, HTTPS: 8443, gRPC: -1, DNS: 8600)
      Cluster Addr: 10.0.210.154 (LAN: 8301, WAN: 8302)
           Encrypt: Gossip: true, TLS-Outgoing: true, TLS-Incoming: true
# forward consul to localhost
$ kubectl -n consul port-forward consul-0 8500:8500 &
# run this command in different console to maintain the connection
$ while true; do consul members && sleep 20; done
$ consul members
Node      Address            Status  Type    Build  Protocol  DC   Segment
consul-0  10.0.210.154:8301  alive   server  1.5.0  2         dc1  <all>
consul-1  10.0.143.30:8301   alive   server  1.5.0  2         dc1  <all>
consul-2  10.0.181.84:8301   alive   server  1.5.0  2         dc1  <all>

Browse to http://localhost:8500 for the consul UI

Consul services
Consul nodes
Consul K/V store, now empty

Import traefik.toml into Consul

I have this traefik.toml.sample as template. Fill in proper email address and domain name to generate a file traefik.toml.

Import traefik.toml with ‘traefik storeconfig’ command.

# Generate from template
$ EMAIL[email protected] DOMAIN=example.com envsubst < traefik.toml.kv.sample  > traefik.toml
# forward consul to localhost
$ kubectl -n consul port-forward consul-0 8500:8500 &
# magic time
$ traefik storeconfig  --consul --consul.endpoint=localhost:8500 --file.filename=./traefik.toml
...
Writing config to KV

If properly imported, check the values in Consul K/V store

K/V store after import

After above importing steps, a manual change for the value of key traefik/consul/endpoint is needed. As shown in below screenshot, to ‘https://consul.consul.svc.cluster.local:8443’, which is the URL to the consul service.

manually modify this valule

If there are existing Let’sEncrypt certificates in a file acme.json, simply un-comment the line

#storageFile = "./acme.json"

from file traefik.toml and do the import. It will also get imported into Consul.

Then delete the key traefik/acme/account/lock, to allow the Traefik Ingress pods get the lock.

Deploy Traefik Ingress Controller cluster

Create TLS secret for traefik cluster. It’s used to access Consul.

$ cd ca
$ kubectl -n kube-system create secret generic traefik-consul \
>     --from-file=ca.pem \
>     --from-file=traefik.pem \
>     --from-file=traefik-key.pem
secret/traefik-consul created

Create traefik dashboard secret.

kubectl -n kube-system create secret generic kubesecret --from-file auth

File ‘auth’ is created from this command. The username/password will be used to access the traefik dashboard

$ htpasswd -c ./auth <username>
New password:
Re-type new password:
Adding password for user testaaa

Now deploy it.

The example traefik_kv.yaml will deploy to master nodes. If this is not desired, adjust the “nodeAffinity” part.

DOMAIN=example.com envsubst < traefik_kv.yaml | kubectl apply -f -

There are 3 pods for traefik-ingress-controller.

$ kubectl -n kube-system get pod -o wide
traefik-ingress-controller-5dlbz          1/1     Running   0          5m21s   10.0.142.69       master3
traefik-ingress-controller-9nxqt          1/1     Running   0          6m34s   10.0.123.196      master2   
traefik-ingress-controller-xzkzd          1/1     Running   0          5m34s   10.0.255.14       master1   

Add labels to the nodes which has Ingress Controller deployed, as I will use the label to handle the cluster reboot sequence. Refer to my article “How to reboot highly available Kubernetes Cluster” (link).

# for all nodes that has Ingress Controller
$ kubectl label nodes master1 node-role.kubernetes.io/ingress-controller=
$ kubectl get nodes
NAME      STATUS   ROLES                       AGE   VERSION
master1   Ready    ingress-controller,master   49d   v1.14.1
master2   Ready    ingress-controller,master   49d   v1.14.1
master3   Ready    ingress-controller,master   49d   v1.14.1
worker1   Ready    <none>                      49d   v1.14.1
worker2   Ready    <none>                      48d   v1.14.1
worker3   Ready    <none>                      48d   v1.14.1

Add Haproxy rules

When the traefik cluster is ready, add haproxy rules to both primary and backup haproxy hosts. Basically, forward port 80 and 443.

As the DNS for the domain point to the haproxy, now the traefik dashboard https://traefik.k8s.example.com/ is accessible, with the username/password created above.

Export acme from consul

I’d like to check/backup the Let’sEncrypt certificates that the Traefik cluster has got for the services. I couldn’t find clear instructions and below is my steps after some tries.

# Connect to consul
kubectl -n consul port-forward consul-0 8500:8500 &
# Keep the consul connection open
while true; do consul members && sleep 10; done
# retrieve compressed acme object
consul kv get traefik/acme/account/object > acme.gz
# gunzip
cat acme.gz | gunzip > acme.json
# Format
cat acme.json | jq '.' > acme.json.formatted

Backup/Restore consul

I hit a case that I want to change the Persistent volumes for the consul cluster. So I need destroy the consul cluster and recreate it. Obviously I don’t want to lose the existing KV values. I found it is pretty easy with the consul snapshot backup/restore.

  1. Create a snapshot as backup
  2. Destroy the consul statefulsets and pvc
  3. Re-create with new consul configs
  4. Restore from snapshot
# backup
consul snapshot save backup.snap
# restore
consul snapshot restore backup.snap

Thanks for reading.

Docker
Kubernetes
DevOps
Ingress
Traefik
Recommended from ReadMedium