{"id":1672,"date":"2018-10-13T16:19:32","date_gmt":"2018-10-13T13:19:32","guid":{"rendered":"https:\/\/artem.services\/?p=55"},"modified":"2020-03-15T19:16:50","modified_gmt":"2020-03-15T16:16:50","slug":"1672","status":"publish","type":"post","link":"https:\/\/artem.services\/?p=1672&lang=en","title":{"rendered":"Docker Swarm over TLS"},"content":{"rendered":"<p><img loading=\"lazy\" class=\"size-full wp-image-27 aligncenter\" src=\"https:\/\/artem.services\/wp-content\/uploads\/2018\/10\/Docker-Logo.png\" alt=\"\" width=\"1800\" height=\"531\" srcset=\"https:\/\/artem.services\/wp-content\/uploads\/2018\/10\/Docker-Logo.png 1800w, https:\/\/artem.services\/wp-content\/uploads\/2018\/10\/Docker-Logo-300x89.png 300w, https:\/\/artem.services\/wp-content\/uploads\/2018\/10\/Docker-Logo-768x227.png 768w, https:\/\/artem.services\/wp-content\/uploads\/2018\/10\/Docker-Logo-1024x302.png 1024w, https:\/\/artem.services\/wp-content\/uploads\/2018\/10\/Docker-Logo-954x281.png 954w, https:\/\/artem.services\/wp-content\/uploads\/2018\/10\/Docker-Logo-1354x399.png 1354w\" sizes=\"(max-width: 1800px) 100vw, 1800px\" \/><\/p>\n<p>In this example, there are 3 servers with <strong>Docker<\/strong> installed on it. If docker is not installed, you can see the installation <a href=\"https:\/\/artem.services\/?p=1665&amp;lang=en\" target=\"_blank\" rel=\"noopener noreferrer\">here.<\/a><\/p>\n<p>There will be one manager and two workers:<\/p>\n<p><strong>Master<\/strong> &#8212; manager (IP: 1.1.1.1)<br \/>\n<strong>Slave_1<\/strong> &#8212; worker (IP: 1.1.2.1)<br \/>\n<strong>Slave_2<\/strong> &#8212; worker (IP: 1.1.2.2)<\/p>\n<p>Required ports for<strong> Docker Swarm<\/strong> to work: <strong>2376<\/strong> and <strong>2377<\/strong> (<strong>TCP<\/strong>). Make sure that the swarm participants are allowed to interact.<\/p>\n<h3>Creating Docker Swarm<\/h3>\n<p>On the <strong>Master<\/strong> server, do the following:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\ndocker swarm init --advertise-addr 1.1.1.1\r\n<\/pre>\n<p>We get a message like:<\/p>\n<pre>Swarm initialized: current node (ssmj2qyqxejd72p6sa9jinnza) is now a manager.\r\n\r\nTo add a worker to this swarm, run the following command:\r\n\r\ndocker swarm join \\\r\n--token SWMTKN-1-3qg9vovt2mxyfu1dfj2nocmkzd3i351z1z0aapd9jxxu7mafff-93r77xv8mrqsgfkf9nei902zk \\\r\n1.1.1.1:2377\r\n\r\nTo add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.<\/pre>\n<p>Swarm is created and there is one manager in it. Information on the swarm can be viewed with the command:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\ndocker info\r\n<\/pre>\n<p><!--more--><\/p>\n<p>Add workers to the swarm, for this we will execute the command that we received earlier when creating the swarm on the <strong>Master<\/strong> server on the <strong>Slave_1<\/strong> and <strong>Slave_2<\/strong> servers:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\ndocker swarm join \\\r\n--token SWMTKN-1-3qg9vovt2mxyfu1dfj2nocmkzd3i351z1z0aapd9jxxu7mafff-93r77xv8mrqsgfkf9nei902zk \\\r\n1.1.1.1:2377\r\n<\/pre>\n<p>If everything is ok, it will display the following message:<\/p>\n<pre>This node joined a swarm as a worker.<\/pre>\n<p>On the swarm manager (<strong>Master<\/strong> server), you can see a list of all the nodes in the swarm:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\ndocker node ls\r\n<\/pre>\n<p>That&#8217;s it, <strong>Docker Swarm<\/strong> is up, now it remains to add the certificates.<\/p>\n<h3>Certificate generation<\/h3>\n<p>We return to the <strong>Master<\/strong> server.<\/p>\n<p>Create a folder for storing certificates and generate a private <strong>CA<\/strong> key:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nopenssl genrsa -aes256 -out ca-key.pem 4096\r\n<\/pre>\n<p>Enter <strong>pass phrase<\/strong>, this is a required parameter.<\/p>\n<p>Now generate the public <strong>CA<\/strong> key:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nopenssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem\r\n<\/pre>\n<p>Here we need to enter the <strong>FQDN<\/strong> of the <strong>Master<\/strong> server<\/p>\n<p>Create a private key for the server:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nopenssl genrsa -out server-key.pem 4096\r\n<\/pre>\n<p>We create a request for signing an <strong>SSL<\/strong> certificate:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nopenssl req -subj &quot;\/CN=SERVER_MASTER_FQDN&quot; -sha256 -new -key server-key.pem -out server.csr\r\n<\/pre>\n<p>Where <strong>SERVER_MASTER_FQDN<\/strong> is the <strong>FQDN<\/strong> of the <strong>Master<\/strong> server<\/p>\n<p>For access not only through the domain name, <strong>IP<\/strong> addresses can be listed as follows:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\necho subjectAltName = DNS:SERVER_MASTER_FQDN,IP:1.1.1.1,IP:127.0.0.1 &gt;&gt; extfile.cnf\r\n<\/pre>\n<p>Create a signed key for the server:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nopenssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem \\\r\n-CAcreateserial -out server-cert.pem -extfile extfile.cnf\r\n<\/pre>\n<p>Create a client key to access the docker:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nopenssl genrsa -out key.pem 4096\r\n<\/pre>\n<p>We will create a request for signature and additionally indicate the type of key use &#8212; for authorization:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nopenssl req -subj '\/CN=client' -new -key key.pem -out client.csr\r\necho extendedKeyUsage = clientAuth &gt;&gt; extfile.cnf\r\n<\/pre>\n<p>Get the signed client key:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nopenssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem -extfile extfile.cnf\r\n<\/pre>\n<p>Delete request files:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nrm -v client.csr server.csr\r\n<\/pre>\n<p>We set the necessary rights to files:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nchmod -v 0400 ca-key.pem key.pem server-key.pem\r\nchmod -v 0444 ca.pem server-cert.pem cert.pem\r\n<\/pre>\n<p>Verify startup with <strong>TLS<\/strong>. If the docker service is running, then it should be stopped:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\ndockerd --tlsverify --tlscacert=ca.pem --tlscert=server-cert.pem --tlskey=server-key.pem \\\r\n-H=0.0.0.0:2376\r\n<\/pre>\n<p>If everything is successful, then you can specify the <strong>TLS<\/strong> options in the docker configuration file, as shown <a href=\"https:\/\/artem.services\/?p=1668&amp;lang=en\" target=\"_blank\" rel=\"noopener noreferrer\">here.<\/a><\/p>\n<h3>Setting workers<\/h3>\n<p>Create a directory for certificates:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nmkdir \/etc\/docker\/certs\r\n<\/pre>\n<p>Copy files from the <strong>Master<\/strong> server to this directory:<\/p>\n<pre>ca.pem\r\ncert.pem\r\nkey.pem<\/pre>\n<p>Also, change the docker daemon, following the example of the server, just note that <strong>cert<\/strong> and <strong>key<\/strong> are different for client and server. &quot;<strong>server-cert.pem<\/strong>&quot; and &quot;<strong>cert.pem<\/strong>&quot;, &quot;<strong>server-key.pem<\/strong>&quot; and &quot;<strong>key.pem<\/strong>&quot;<\/p>\n<p>After restarting the docker daemon, you can run it on the worker:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\ndocker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem -H=1.1.1.1:2376 version\r\n<\/pre>\n<p>If everything is correct, the version of the worker docker and the version of the server docker will be displayed.<\/p>\n<p>That&#8217;s it, now we have <strong>Docker Swarm<\/strong>, which interacts with each other using <strong>TLS<\/strong>. Correctly, for each node in the swarm, you need to write out your keys and certificates.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this example, there are 3 servers with Docker installed on it. If docker is not installed, you can see the installation here. There will be one manager and two workers: Master &#8212; manager (IP: 1.1.1.1) Slave_1 &#8212; worker (IP: 1.1.2.1) Slave_2 &#8212; worker (IP: 1.1.2.2) Required ports for Docker Swarm to work: 2376 and &hellip; <a href=\"https:\/\/artem.services\/?p=1672&#038;lang=en\" class=\"more-link\">\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c \u0447\u0438\u0442\u0430\u0442\u044c<span class=\"screen-reader-text\"> &quot;Docker Swarm over TLS&quot;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[399,975],"tags":[855,771,1331,1333,375],"_links":{"self":[{"href":"https:\/\/artem.services\/index.php?rest_route=\/wp\/v2\/posts\/1672"}],"collection":[{"href":"https:\/\/artem.services\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/artem.services\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/artem.services\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/artem.services\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1672"}],"version-history":[{"count":2,"href":"https:\/\/artem.services\/index.php?rest_route=\/wp\/v2\/posts\/1672\/revisions"}],"predecessor-version":[{"id":1674,"href":"https:\/\/artem.services\/index.php?rest_route=\/wp\/v2\/posts\/1672\/revisions\/1674"}],"wp:attachment":[{"href":"https:\/\/artem.services\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1672"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/artem.services\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1672"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/artem.services\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1672"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}