1
0
mirror of https://github.com/funkypenguin/geek-cookbook/ synced 2025-12-13 01:36:23 +00:00
Files
geek-cookbook/site/ha-docker-swarm/docker-swarm-mode/index.html
2017-07-30 13:19:02 +12:00

976 lines
31 KiB
HTML

<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="description" content="A short description of my project">
<link rel="canonical" href="https://geeks-cookbook.funkypenguin.co.nz/ha-docker-swarm/docker-swarm-mode/">
<meta name="author" content="David Young">
<link rel="shortcut icon" href="../../assets/images/favicon.png">
<meta name="generator" content="mkdocs-0.16.3, mkdocs-material-1.7.4">
<title>Docker Swarm Mode - Funky Penguin's Geek's Cookbook</title>
<script src="../../assets/javascripts/modernizr-1df76c4e58.js"></script>
<link rel="stylesheet" href="../../assets/stylesheets/application-769c285a91.css">
<link rel="stylesheet" href="../../assets/stylesheets/application-02c2a4388f.palette.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,400i,700|Roboto+Mono">
<style>body,input{font-family:"Roboto","Helvetica Neue",Helvetica,Arial,sans-serif}code,kbd,pre{font-family:"Roboto Mono","Courier New",Courier,monospace}</style>
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
</head>
<body data-md-color-primary="indigo" data-md-color-accent="indigo">
<svg class="md-svg">
<defs>
</defs>
</svg>
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="drawer">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="search">
<label class="md-overlay" data-md-component="overlay" for="drawer"></label>
<header class="md-header" data-md-component="header">
<nav class="md-header-nav md-grid">
<div class="md-flex">
<div class="md-flex__cell md-flex__cell--shrink">
<a href="https://geeks-cookbook.funkypenguin.co.nz" title="Funky Penguin's Geek's Cookbook" class="md-logo md-header-nav__button">
<img src="../../images/site-logo.png" width="24" height="24">
</a>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<label class="md-icon md-icon--menu md-header-nav__button" for="drawer"></label>
</div>
<div class="md-flex__cell md-flex__cell--stretch">
<span class="md-flex__ellipsis md-header-nav__title">
<span class="md-header-nav__parent">
Essential
</span>
Docker Swarm Mode
</span>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<label class="md-icon md-icon--search md-header-nav__button" for="search"></label>
<div class="md-search" data-md-component="search">
<label class="md-search__overlay" for="search"></label>
<div class="md-search__inner">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" required placeholder="Search" accesskey="s" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="query">
<label class="md-icon md-search__icon" for="search"></label>
<button type="reset" class="md-icon md-search__icon" data-md-component="reset">close</button>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" data-md-scrollfix>
<div class="md-search-result" data-md-component="result" data-md-lang-search="">
<div class="md-search-result__meta" data-md-lang-result-none="No matching documents" data-md-lang-result-one="1 matching document" data-md-lang-result-other="# matching documents">
Type to start searching
</div>
<ol class="md-search-result__list"></ol>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</nav>
</header>
<div class="md-container">
<main class="md-main">
<div class="md-main__inner md-grid" data-md-component="container">
<div class="md-sidebar md-sidebar--primary" data-md-component="navigation">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary" data-md-level="0">
<label class="md-nav__title md-nav__title--site" for="drawer">
<i class="md-logo md-nav__button">
<img src="../../images/site-logo.png">
</i>
Funky Penguin's Geek's Cookbook
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../.." title="Home" class="md-nav__link">
Home
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-2" type="checkbox" id="nav-2">
<label class="md-nav__link" for="nav-2">
Introduction
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-2">
Introduction
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../README/" title="README" class="md-nav__link">
README
</a>
</li>
<li class="md-nav__item">
<a href="../../whoami/" title="whoami" class="md-nav__link">
whoami
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-3" type="checkbox" id="nav-3" checked>
<label class="md-nav__link" for="nav-3">
Essential
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-3">
Essential
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../design/" title="Design" class="md-nav__link">
Design
</a>
</li>
<li class="md-nav__item">
<a href="../vms/" title="VMs" class="md-nav__link">
VMs
</a>
</li>
<li class="md-nav__item">
<a href="../shared-storage-ceph/" title="Shared Storage (Ceph)" class="md-nav__link">
Shared Storage (Ceph)
</a>
</li>
<li class="md-nav__item">
<a href="../shared-storage-gluster/" title="Shared Storage (GlusterFS)" class="md-nav__link">
Shared Storage (GlusterFS)
</a>
</li>
<li class="md-nav__item">
<a href="../keepalived/" title="Keepalived" class="md-nav__link">
Keepalived
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="toc">
<label class="md-nav__link md-nav__link--active" for="toc">
Docker Swarm Mode
</label>
<a href="./" title="Docker Swarm Mode" class="md-nav__link md-nav__link--active">
Docker Swarm Mode
</a>
<nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="#ingredients" title="Ingredients" class="md-nav__link">
Ingredients
</a>
</li>
<li class="md-nav__item">
<a href="#preparation" title="Preparation" class="md-nav__link">
Preparation
</a>
<nav class="md-nav">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#release-the-swarm" title="Release the swarm!" class="md-nav__link">
Release the swarm!
</a>
</li>
<li class="md-nav__item">
<a href="#create-registry-mirror" title="Create registry mirror" class="md-nav__link">
Create registry mirror
</a>
</li>
<li class="md-nav__item">
<a href="#enable-registry-mirror-and-experimental-features" title="Enable registry mirror and experimental features" class="md-nav__link">
Enable registry mirror and experimental features
</a>
</li>
<li class="md-nav__item">
<a href="#setup-automated-cleanup" title="Setup automated cleanup" class="md-nav__link">
Setup automated cleanup
</a>
</li>
<li class="md-nav__item">
<a href="#tweaks" title="Tweaks" class="md-nav__link">
Tweaks
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#setup-registry" title="Setup registry" class="md-nav__link">
Setup registry
</a>
</li>
<li class="md-nav__item">
<a href="#__comments" title="Comments" class="md-nav__link md-nav__link--active">
Comments
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../traefik/" title="Traefik" class="md-nav__link">
Traefik
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-4" type="checkbox" id="nav-4">
<label class="md-nav__link" for="nav-4">
Recommended
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-4">
Recommended
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../recipies/mail/" title="Mail Server" class="md-nav__link">
Mail Server
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="toc">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="#ingredients" title="Ingredients" class="md-nav__link">
Ingredients
</a>
</li>
<li class="md-nav__item">
<a href="#preparation" title="Preparation" class="md-nav__link">
Preparation
</a>
<nav class="md-nav">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#release-the-swarm" title="Release the swarm!" class="md-nav__link">
Release the swarm!
</a>
</li>
<li class="md-nav__item">
<a href="#create-registry-mirror" title="Create registry mirror" class="md-nav__link">
Create registry mirror
</a>
</li>
<li class="md-nav__item">
<a href="#enable-registry-mirror-and-experimental-features" title="Enable registry mirror and experimental features" class="md-nav__link">
Enable registry mirror and experimental features
</a>
</li>
<li class="md-nav__item">
<a href="#setup-automated-cleanup" title="Setup automated cleanup" class="md-nav__link">
Setup automated cleanup
</a>
</li>
<li class="md-nav__item">
<a href="#tweaks" title="Tweaks" class="md-nav__link">
Tweaks
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#setup-registry" title="Setup registry" class="md-nav__link">
Setup registry
</a>
</li>
<li class="md-nav__item">
<a href="#__comments" title="Comments" class="md-nav__link md-nav__link--active">
Comments
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content">
<article class="md-content__inner md-typeset">
<h1 id="docker-swarm-mode">Docker Swarm Mode<a class="headerlink" href="#docker-swarm-mode" title="Permanent link">&para;</a></h1>
<p>For truly highly-available services with Docker containers, we need an orchestration system. Docker Swarm (as defined at 1.13) is the simplest way to achieve redundancy, such that a single docker host could be turned off, and none of our services will be interrupted.</p>
<h2 id="ingredients">Ingredients<a class="headerlink" href="#ingredients" title="Permanent link">&para;</a></h2>
<ul>
<li>3 x CentOS Atomic hosts (bare-metal or VMs). A reasonable minimum would be:</li>
<li>1 x vCPU</li>
<li>1GB repo_name</li>
<li>10GB HDD</li>
<li>Hosts must be within the same subnet, and connected on a low-latency link (i.e., no WAN links)</li>
</ul>
<h2 id="preparation">Preparation<a class="headerlink" href="#preparation" title="Permanent link">&para;</a></h2>
<h3 id="release-the-swarm">Release the swarm!<a class="headerlink" href="#release-the-swarm" title="Permanent link">&para;</a></h3>
<p>Now, to launch my swarm:</p>
<p><code class="codehilite">docker swarm init</code></p>
<p>Yeah, that was it. Now I have a 1-node swarm.</p>
<table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
2
3
4
5
6
7
8
9
10
11
12</pre></div></td><td class="code"><div class="codehilite"><pre><span></span>[root@ds1 ~]# docker swarm init
Swarm initialized: current node (b54vls3wf8xztwfz79nlkivt8) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join \
--token SWMTKN-1-2orjbzjzjvm1bbo736xxmxzwaf4rffxwi0tu3zopal4xk4mja0-bsud7xnvhv4cicwi7l6c9s6l0 \
202.170.164.47:2377
To add a manager to this swarm, run &#39;docker swarm join-token manager&#39; and follow the instructions.
[root@ds1 ~]#
</pre></div>
</td></tr></table>
<p>Run <code class="codehilite">docker node ls</code> to confirm that I have a 1-node swarm:</p>
<table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4</pre></div></td><td class="code"><div class="codehilite"><pre><span></span>[root@ds1 ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
b54vls3wf8xztwfz79nlkivt8 * ds1.funkypenguin.co.nz Ready Active Leader
[root@ds1 ~]#
</pre></div>
</td></tr></table>
<p>Note that when I ran <code class="codehilite">docker swarm init</code> above, the CLI output gave me a command to run to join further nodes to my swarm. This would join the nodes as <strong>workers</strong> (as opposed to <strong>managers</strong>). Workers can easily be promoted to managers (and demoted again), but since we know that we want our other two nodes to be managers too, it's simpler just to add them to the swarm as managers immediately.</p>
<p>On the first swarm node, generate the necessary token to join another manager by running <code class="codehilite">docker swarm join-token manager</code>:</p>
<table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5
6
7
8</pre></div></td><td class="code"><div class="codehilite"><pre><span></span>[root@ds1 ~]# docker swarm join-token manager
To add a manager to this swarm, run the following command:
docker swarm join \
--token SWMTKN-1-2orjbzjzjvm1bbo736xxmxzwaf4rffxwi0tu3zopal4xk4mja0-cfm24bq2zvfkcwujwlp5zqxta \
202.170.164.47:2377
[root@ds1 ~]#
</pre></div>
</td></tr></table>
<p>Run the command provided on your second node to join it to the swarm as a manager. After adding the second node, the output of <code class="codehilite">docker node ls</code> (on either host) should reflect two nodes:</p>
<table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5</pre></div></td><td class="code"><div class="codehilite"><pre><span></span>[root@ds2 davidy]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
b54vls3wf8xztwfz79nlkivt8 ds1.funkypenguin.co.nz Ready Active Leader
xmw49jt5a1j87a6ihul76gbgy * ds2.funkypenguin.co.nz Ready Active Reachable
[root@ds2 davidy]#
</pre></div>
</td></tr></table>
<p>Repeat the process to add your third node. <strong>You need a new token for the third node, don't re-use the manager token you generated for the second node</strong>.</p>
<div class="admonition warning">
<p class="admonition-title">Seriously. Don't use a token more than once, else it's swarm-rebuilding time.</p>
</div>
<p>Finally, <code class="codehilite">docker node ls</code> should reflect that you have 3 reachable manager nodes, one of whom is the "Leader":</p>
<table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5
6</pre></div></td><td class="code"><div class="codehilite"><pre><span></span>[root@ds3 ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
36b4twca7i3hkb7qr77i0pr9i ds1.openstack.dev.safenz.net Ready Active Reachable
l14rfzazbmibh1p9wcoivkv1s * ds3.openstack.dev.safenz.net Ready Active Reachable
tfsgxmu7q23nuo51wwa4ycpsj ds2.openstack.dev.safenz.net Ready Active Leader
[root@ds3 ~]#
</pre></div>
</td></tr></table>
<h3 id="create-registry-mirror">Create registry mirror<a class="headerlink" href="#create-registry-mirror" title="Permanent link">&para;</a></h3>
<p>Although we now have shared storage for our persistent container data, our docker nodes don't share any other docker data, such as container images. This results in an inefficiency - every node which participates in the swarm will, at some point, need the docker image for every container deployed in the swarm.</p>
<p>When dealing with large container (looking at you, GitLab!), this can result in several gigabytes of wasted bandwidth per-node, and long delays when restarting containers on an alternate node. (<em>It also wastes disk space on each node, but we'll get to that in the next section</em>)</p>
<p>The solution is to run an official Docker registry container as a <a href="https://docs.docker.com/registry/recipes/mirror/">"pull-through" cache, or "registry mirror"</a>. By using our persistent storage for the registry cache, we can ensure we have a single copy of all the containers we've pulled at least once. After the first pull, any subsequent pulls from our nodes will use the cached version from our registry mirror. As a result, services are available more quickly when restarting container nodes, and we can be more aggressive about cleaning up unused containers on our nodes (more later)</p>
<p>The registry mirror runs as a swarm stack, using a simple docker-compose.yml. Customize <strong>your mirror FQDN</strong> below, so that Traefik will generate the appropriate LetsEncrypt certificates for it, and make it available via HTTPS.</p>
<table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22</pre></div></td><td class="code"><div class="codehilite"><pre><span></span>version: &quot;3&quot;
services:
registry-mirror:
image: registry:2
networks:
- traefik
deploy:
labels:
- traefik.frontend.rule=Host:&lt;your mirror FQDN&gt;
- traefik.docker.network=traefik
- traefik.port=5000
ports:
- 5000:5000
volumes:
- /var/data/registry/registry-mirror-data:/var/lib/registry
- /var/data/registry/registry-mirror-config.yml:/etc/docker/registry/config.yml
networks:
traefik:
external: true
</pre></div>
</td></tr></table>
<div class="admonition note">
<p class="admonition-title">Unencrypted registry</p>
<p>We create this registry without consideration for SSL, which will fail if we attempt to use the registry directly. However, we're going to use the HTTPS-proxied version via Traefik, leveraging Traefik to manage the LetsEncrypt certificates required.</p>
</div>
<p>Create registry/registry-mirror-config.yml as follows:
<table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22</pre></div></td><td class="code"><div class="codehilite"><pre><span></span><span class="n">version</span><span class="o">:</span> <span class="mf">0.1</span>
<span class="n">log</span><span class="o">:</span>
<span class="n">fields</span><span class="o">:</span>
<span class="n">service</span><span class="o">:</span> <span class="n">registry</span>
<span class="n">storage</span><span class="o">:</span>
<span class="n">cache</span><span class="o">:</span>
<span class="n">blobdescriptor</span><span class="o">:</span> <span class="n">inmemory</span>
<span class="n">filesystem</span><span class="o">:</span>
<span class="n">rootdirectory</span><span class="o">:</span> <span class="sr">/var/lib/</span><span class="n">registry</span>
<span class="n">delete</span><span class="o">:</span>
<span class="n">enabled</span><span class="o">:</span> <span class="kc">true</span>
<span class="n">http</span><span class="o">:</span>
<span class="n">addr</span><span class="o">:</span> <span class="o">:</span><span class="mi">5000</span>
<span class="n">headers</span><span class="o">:</span>
<span class="n">X</span><span class="o">-</span><span class="n">Content</span><span class="o">-</span><span class="n">Type</span><span class="o">-</span><span class="n">Options</span><span class="o">:</span> <span class="o">[</span><span class="n">nosniff</span><span class="o">]</span>
<span class="n">health</span><span class="o">:</span>
<span class="n">storagedriver</span><span class="o">:</span>
<span class="n">enabled</span><span class="o">:</span> <span class="kc">true</span>
<span class="n">interval</span><span class="o">:</span> <span class="mi">10</span><span class="n">s</span>
<span class="n">threshold</span><span class="o">:</span> <span class="mi">3</span>
<span class="n">proxy</span><span class="o">:</span>
<span class="n">remoteurl</span><span class="o">:</span> <span class="n">https</span><span class="o">://</span><span class="n">registry</span><span class="o">-</span><span class="mi">1</span><span class="o">.</span><span class="na">docker</span><span class="o">.</span><span class="na">io</span>
</pre></div>
</td></tr></table></p>
<h3 id="enable-registry-mirror-and-experimental-features">Enable registry mirror and experimental features<a class="headerlink" href="#enable-registry-mirror-and-experimental-features" title="Permanent link">&para;</a></h3>
<p>To tell docker to use the registry mirror, and in order to be able to watch the logs of any service from any manager node (<em>an experimental feature in the current Atomic docker build</em>), edit <strong>/etc/docker-latest/daemon.json</strong> on each node, and change from:</p>
<table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4</pre></div></td><td class="code"><div class="codehilite"><pre><span></span>{
&quot;log-driver&quot;: &quot;journald&quot;,
&quot;signature-verification&quot;: false
}
</pre></div>
</td></tr></table>
<p>To:</p>
<table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5
6</pre></div></td><td class="code"><div class="codehilite"><pre><span></span>{
&quot;log-driver&quot;: &quot;journald&quot;,
&quot;signature-verification&quot;: false,
&quot;experimental&quot;: true,
&quot;registry-mirrors&quot;: [&quot;https://&lt;your registry mirror FQDN&gt;&quot;]
}
</pre></div>
</td></tr></table>
<div class="admonition tip">
<p>Note the extra comma required after "false" above</p>
</div>
<h3 id="setup-automated-cleanup">Setup automated cleanup<a class="headerlink" href="#setup-automated-cleanup" title="Permanent link">&para;</a></h3>
<p>This needs to be a docker-compose.yml file, excluding trusted images (like glusterfs, traefik, etc)
<table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4</pre></div></td><td class="code"><div class="codehilite"><pre><span></span>docker run -d \
-v /var/run/docker.sock:/var/run/docker.sock:rw \
-v /var/lib/docker:/var/lib/docker:rw \
meltwater/docker-cleanup:latest
</pre></div>
</td></tr></table></p>
<h3 id="tweaks">Tweaks<a class="headerlink" href="#tweaks" title="Permanent link">&para;</a></h3>
<p>Add some handy bash auto-completion for docker. Without this, you'll get annoyed that you can't autocomplete <code class="codehilite">docker stack deploy &lt;blah&gt; -c &lt;blah.yml&gt;</code> commands.</p>
<table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2</pre></div></td><td class="code"><div class="codehilite"><pre><span></span>cd /etc/bash_completion.d/
curl -O https://raw.githubusercontent.com/docker/cli/b75596e1e4d5295ac69b9934d1bd8aff691a0de8/contrib/completion/bash/docker
</pre></div>
</td></tr></table>
<p>Install some useful bash aliases on each host
<table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3</pre></div></td><td class="code"><div class="codehilite"><pre><span></span>cd ~
curl -O https://gitlab.funkypenguin.co.nz/funkypenguin/geeks-cookbook-recipies/raw/master/bash/gcb-aliases.sh
echo &#39;source ~/gcb-aliases.sh&#39; &gt;&gt; ~/.bash_profile
</pre></div>
</td></tr></table></p>
<table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5</pre></div></td><td class="code"><div class="codehilite"><pre><span></span>mkdir ~/dockersock
cd ~/dockersock
curl -O https://raw.githubusercontent.com/dpw/selinux-dockersock/master/Makefile
curl -O https://raw.githubusercontent.com/dpw/selinux-dockersock/master/dockersock.te
make &amp;&amp; semodule -i dockersock.pp
</pre></div>
</td></tr></table>
<h2 id="setup-registry">Setup registry<a class="headerlink" href="#setup-registry" title="Permanent link">&para;</a></h2>
<p>docker run -d \
-p 5000:5000 \
--restart=always \
--name registry \
-v /mnt/registry:/var/lib/registry \
registry:2</p>
<p>{
"log-driver": "journald",
"signature-verification": false,
"experimental": true,
"registry-mirrors": ["<a href="https://registry-mirror.funkypenguin.co.nz">https://registry-mirror.funkypenguin.co.nz</a>"]
}</p>
<p>registry-mirror:
image: registry:2
ports:
- 5000:5000
environment:
volumes:
- /var/data/registry:/var/lib/registry</p>
<table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5
6
7
8</pre></div></td><td class="code"><div class="codehilite"><pre><span></span> [root@ds1 dockersock]# docker swarm join-token manager
To add a manager to this swarm, run the following command:
docker swarm join \
--token SWMTKN-1-09c94wv0opw0y6xg67uzjl13pnv8lxxn586hrg5f47spso9l6j-6zn3dxk7c4zkb19r61owasi15 \
192.168.31.11:2377
[root@ds1 dockersock]#
</pre></div>
</td></tr></table>
<h2 id="__comments">Comments</h2>
<div id="disqus_thread"></div>
<script>
var disqus_config = function () {
this.page.url = "https://geeks-cookbook.funkypenguin.co.nz/ha-docker-swarm/docker-swarm-mode/";
this.page.identifier =
"/ha-docker-swarm/docker-swarm-mode/";
};
(function() {
var d = document, s = d.createElement("script");
s.src = "//geeks-cookbook.disqus.com/embed.js";
s.setAttribute("data-timestamp", +new Date());
(d.head || d.body).appendChild(s);
})();
</script>
</article>
</div>
</div>
</main>
<footer class="md-footer">
<div class="md-footer-nav">
<nav class="md-footer-nav__inner md-grid">
<a href="../keepalived/" title="Keepalived" class="md-flex md-footer-nav__link md-footer-nav__link--prev" rel="prev">
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-back md-footer-nav__button"></i>
</div>
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
Previous
</span>
Keepalived
</span>
</div>
</a>
<a href="../traefik/" title="Traefik" class="md-flex md-footer-nav__link md-footer-nav__link--next" rel="next">
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
Next
</span>
Traefik
</span>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-forward md-footer-nav__button"></i>
</div>
</a>
</nav>
</div>
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-footer-copyright">
<div class="md-footer-copyright__highlight">
Copyright &copy; 2016 - 2017 David Young
</div>
powered by
<a href="http://www.mkdocs.org" title="MkDocs">MkDocs</a>
and
<a href="http://squidfunk.github.io/mkdocs-material/" title="Material for MkDocs">
Material for MkDocs</a>
</div>
<div class="md-footer-social">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<a href="https://github.com/funkypenguin" class="md-footer-social__link fa fa-github"></a>
<a href="https://twitter.com/funkypenguin" class="md-footer-social__link fa fa-twitter"></a>
</div>
</div>
</div>
</footer>
</div>
<script src="../../assets/javascripts/application-c35428f87f.js"></script>
<script>app.initialize({url:{base:"../.."}})</script>
<script src="../../extras/javascript/piwik.js"></script>
<script>!function(e,t,a,n,o,c,i){e.GoogleAnalyticsObject=o,e[o]=e[o]||function(){(e[o].q=e[o].q||[]).push(arguments)},e[o].l=1*new Date,c=t.createElement(a),i=t.getElementsByTagName(a)[0],c.async=1,c.src=n,i.parentNode.insertBefore(c,i)}(window,document,"script","https://www.google-analytics.com/analytics.js","ga"),ga("create","UA-139253-18","auto"),ga("set","anonymizeIp",!0),ga("send","pageview");var links=document.getElementsByTagName("a");Array.prototype.map.call(links,function(e){e.host!=document.location.host&&e.addEventListener("click",function(){var t=e.getAttribute("data-md-action")||"follow";ga("send","event","outbound",t,e.href)})});var query=document.forms.search.query;query.addEventListener("blur",function(){if(this.value){var e=document.location.pathname;ga("send","pageview",e+"?q="+this.value)}})</script>
</body>
</html>