搜索词>>

docker ������������

耗时0.0150
  • java c++通用DES/AES对称加密算法(包含源代码)

    java c++通用DES加密算法(包含源代码),本来觉得DES、AES这种流行加密算法,使用起来应该很简单。但研究后发现有两个变数:1分块的方式。加密是逐块进行的。2.padding的方式。当数据的位数不及块的大小时,需要填充。<h2>一说明</h2> 本来觉得DES、AES这种流行加密算法,使用起来应该很简单。但研究后发现有两个变数: <ul> <li>分块的方式。加密是逐块进行的。分块方法有:CBC、ECB、CFB……</li> <li>padding的方式。当数据的位数不及块的大小时,需要填充。填充方式有:NoPadding、PKCS5Padding……</li> </ul> 如果加解密端采用不同的分块方式或padding方式,即使都是采用DES/AES算法,同样无法解密成功。上次需要C端和Java端进行密文传输,就跪在这一点上(那时候没时间研究)。<br /> 参考文章:<a href="http://my.oschina.net/u/267094/blog/174035" rel="external nofollow" target="_blank">Java AES算法和openssl配对</a> ,主要通过其了解openssl里比较高级的EVP系列API(其默认padding和java一样都是PKCS5Padding),节约了搜索时间。<br /> 贴代码了,以下代码测试通过了。Java和C++均可以正确解密对方的密文。<br /> 约定:分块和padding采用Java默认的 ECB + PKCS5Padding。 <h2>二 DES加解密</h2> <h3>Java端DES加解密</h3> <pre> <code class="language-java">import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; public class DESUtil { /** 默认算法格式 **/ static String default_transformation = "DES/ECB/PKCS5Padding"; /** * 根据key获取加密器 * * @param keyData * key 8byte * @return 加密器 * @throws Exception * 异常 */ private static Cipher getEncryptCipher(byte[] keyData) throws Exception { if (keyData.length != 8) { throw new Exception("Key Data Must 8 byte!"); } SecretKeySpec key = new SecretKeySpec(keyData, "DES"); // 指定分块ECB模式,填充PKCS5Padding模式 Cipher encryptCipher = Cipher.getInstance(default_transformation); // 初始化加密的容器 encryptCipher.init(Cipher.ENCRYPT_MODE, key); return encryptCipher; } /** * 根据key获取解码器 * * @return 解码器 * @throws Exception * 异常 */ private static Cipher getDecryptCipher(byte[] keyData) throws Exception { if (keyData.length != 8) { throw new Exception("Key Data Must 8 byte!"); } SecretKeySpec key = new SecretKeySpec(keyData, "DES"); Cipher decryptCipher = Cipher.getInstance(default_transformation); // 初始化解密的容器 decryptCipher.init(Cipher.DECRYPT_MODE, key); return decryptCipher; } /** * DES加密 * * @param data * 待加密数据 * @param keyData * key值 * @return 加密后的数据 * @throws Exception * 异常 */ public static byte[] encrypt(byte[] data, byte[] keyData) throws Exception { return getEncryptCipher(keyData).doFinal(data); } /** * DES解密 * * @param data * 加密后的数据 * * @param keyData * key值 * @return 解密数据 * @throws Exception * 异常 */ public static byte[] decrypt(byte[] data, byte[] keyData) throws Exception { return getDecryptCipher(keyData).doFinal(data); } /** * 测试 * * @param args */ public static void main(String[] args) { try { byte[] data = "测试123456".getBytes(); byte[] keyData = "12345678".getBytes(); System.out.println("原文:" + new String(data)); byte[] enData = encrypt(data, keyData); System.out.println("加密后:" + new String(enData)); byte[] deData = decrypt(enData, keyData); System.out.println("解密后:" + new String(deData)); } catch (Exception e) { e.printStackTrace(); } } } </code></pre> <strong><span style="color:#27ae60">说明:Java必须指定填充模式和padding模式。DES/ECB/PKCS5Padding,好与C++同步</span></strong><br /> 测试执行结果: <pre> <code class="language-html">原文:测试123456 加密后:�a���O���?I�]�Y 解密后:测试123456</code></pre> <h3>C++端DES加解密</h3> c++DES加密代码 <pre> <code class="language-cpp">#include <string> #include <iostream> #include <stdio.h> #include <assert.h> #include <openssl/objects.h> #include <openssl/evp.h> // 注意:参数和返回值全部是二进制数据 std::string desEncrypt(const std::string& source, const std::string& key) {     EVP_CIPHER_CTX ctx;     EVP_CIPHER_CTX_init(&ctx);     int ret = EVP_EncryptInit_ex(&ctx, EVP_des_ecb(), NULL, (const unsigned char*)key.data(), NULL);     assert(ret == 1);     unsigned char* result = new unsigned char[source.length() + 64]; // 弄个足够大的空间     int len1 = 0;     ret = EVP_EncryptUpdate(&ctx, result, &len1, (const unsigned char*)source.data(), source.length());     assert(ret == 1);     int len2 = 0;     ret = EVP_EncryptFinal_ex(&ctx, result+len1, &len2);      assert(ret == 1);     std::cout << len1 << "," << len2 << std::endl;     ret = EVP_CIPHER_CTX_cleanup(&ctx);     assert(ret == 1);     std::string res((char*)result, len1+len2);     delete[] result;     return res; } int main() {     std::string key("hellodes", 8);    // 二进制数据,而不是以0结尾的字符串     // 读取文件内容(简单起见认为文件内容<100K)     char buf[1024*100];     FILE* fp = fopen("src.txt", "rb");     int bytes = fread(buf, 1, 1024*100, fp);     fclose(fp);     std::string source(buf, bytes); // 二进制数据     // 加密     std::string enc = desEncrypt(source, key);     std::cout << "desEncrypt:" << source.length() << "->" << enc.length() << std::endl;     // 输出到文件     fp =  fopen("enc.bin", "wb");     fwrite(enc.data(), 1, enc.length(), fp);     fclose(fp); }</code></pre> c++DES解密 <pre> <code class="language-cpp">#include <string> #include <iostream> #include <stdio.h> #include <assert.h> #include <openssl/objects.h> #include <openssl/evp.h> // 注意:参数和返回值全部是二进制数据 std::string desDecrypt(const std::string& ciphertext, const std::string& key) {     EVP_CIPHER_CTX ctx;     EVP_CIPHER_CTX_init(&ctx);     int ret = EVP_DecryptInit_ex(&ctx, EVP_des_ecb(), NULL, (const unsigned char*)key.data(), NULL);     assert(ret == 1);     unsigned char* result = new unsigned char[ciphertext.length() + 64]; // 弄个足够大的空间     int len1 = 0;     ret = EVP_DecryptUpdate(&ctx, result, &len1, (const unsigned char*)ciphertext.data(), ciphertext.length());     assert(ret == 1);     int len2 = 0;     ret = EVP_DecryptFinal_ex(&ctx, result+len1, &len2);      assert(ret == 1);     std::cout << len1 << "," << len2 << std::endl;     ret = EVP_CIPHER_CTX_cleanup(&ctx);     assert(ret == 1);     std::string res((char*)result, len1+len2);     delete[] result;     return res; } int main() {     std::string key("hellodes", 8);    // 二进制数据,而不是以0结尾的字符串     // 读取文件内容(简单起见认为文件内容<100K)     char buf[1024*100];     FILE* fp = fopen("enc.bin", "rb");     int bytes = fread(buf, 1, 1024*100, fp);     fclose(fp);     std::string data(buf, bytes); // 二进制数据     // 加密     std::string dec = desDecrypt(data, key);     std::cout << "desDecrypt:" << data.length() << "->" << dec.length() << std::endl;     // 输出到文件     fp =  fopen("dec.txt", "wb");     fwrite(dec.data(), 1, dec.length(), fp);     fclose(fp); }</code></pre> <br /> 说明:DES、AES加密算法都是针对数据块,Java加解密函数参数使用byte数组。C++用std::string,那是因为这是C++中使用byte数组的最简单方式(std::string可以存储二进制数据,很多人没想到吧),缺点是拷贝内存的次数可能会略多些。如果想要优化拷贝效率,可以使用自己封装的Buffer类来代替std::string。 <h2>三 AES加解密</h2> <h3>Java端AES加解密</h3> <pre> <code class="language-java">import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; /** * DES加解密算法工具类 * * @author xqlee * */ public class AESUtil { /** 默认算法格式 **/ static String default_transformation = "AES/ECB/PKCS5Padding"; /** * 根据key获取加密器 * * @param keyData * key 8byte * @return 加密器 * @throws Exception * 异常 */ private static Cipher getEncryptCipher(byte[] keyData) throws Exception { if (keyData.length != 16) { throw new Exception("Key Data Must 8 byte!"); } SecretKeySpec key = new SecretKeySpec(keyData, "AES"); // 指定分块ECB模式,填充PKCS5Padding模式 Cipher encryptCipher = Cipher.getInstance(default_transformation); // 初始化加密的容器 encryptCipher.init(Cipher.ENCRYPT_MODE, key); return encryptCipher; } /** * 根据key获取解码器 * * @return 解码器 * @throws Exception * 异常 */ private static Cipher getDecryptCipher(byte[] keyData) throws Exception { if (keyData.length != 16) { throw new Exception("Key Data Must 8 byte!"); } SecretKeySpec key = new SecretKeySpec(keyData, "AES"); Cipher decryptCipher = Cipher.getInstance(default_transformation); // 初始化解密的容器 decryptCipher.init(Cipher.DECRYPT_MODE, key); return decryptCipher; } /** * AES加密 * * @param data * 待加密数据 * @param keyData * key值 * @return 加密后的数据 * @throws Exception * 异常 */ public static byte[] encrypt(byte[] data, byte[] keyData) throws Exception { return getEncryptCipher(keyData).doFinal(data); } /** * AES解密 * * @param data * 加密后的数据 * * @param keyData * key值 * @return 解密数据 * @throws Exception * 异常 */ public static byte[] decrypt(byte[] data, byte[] keyData) throws Exception { return getDecryptCipher(keyData).doFinal(data); } /** * 测试 * * @param args */ public static void main(String[] args) { try { byte[] data = "测试123456".getBytes(); byte[] keyData = "1234567887654321".getBytes(); System.out.println("原文:" + new String(data)); byte[] enData = encrypt(data, keyData); System.out.println("加密后:" + new String(enData)); byte[] deData = decrypt(enData, keyData); System.out.println("解密后:" + new String(deData)); } catch (Exception e) { e.printStackTrace(); } } } </code></pre> <h3>C++端AES加解密</h3> 加密: <pre> <code class="language-cpp">#include <string> #include <iostream> #include <stdio.h> #include <assert.h> #include <openssl/objects.h> #include <openssl/evp.h> // 注意:参数和返回值全部是二进制数据 std::string aesEncrypt(const std::string& source, const std::string& key) {     EVP_CIPHER_CTX ctx;     EVP_CIPHER_CTX_init(&ctx);     int ret = EVP_EncryptInit_ex(&ctx, EVP_aes_128_ecb(), NULL, (const unsigned char*)key.data(), NULL);     assert(ret == 1);     unsigned char* result = new unsigned char[source.length() + 64]; // 弄个足够大的空间     int len1 = 0;     ret = EVP_EncryptUpdate(&ctx, result, &len1, (const unsigned char*)source.data(), source.length());     assert(ret == 1);     int len2 = 0;     ret = EVP_EncryptFinal_ex(&ctx, result+len1, &len2);      assert(ret == 1);     std::cout << len1 << "," << len2 << std::endl;     ret = EVP_CIPHER_CTX_cleanup(&ctx);     assert(ret == 1);     std::string res((char*)result, len1+len2);     delete[] result;     return res; } int main() {     std::string key("helloaeshelloaes", 16);    // 二进制数据,而不是以0结尾的字符串     // 读取文件内容(简单起见认为文件内容<100K)     char buf[1024*100];     FILE* fp = fopen("src.txt", "rb");     int bytes = fread(buf, 1, 1024*100, fp);     fclose(fp);     std::string source(buf, bytes); // 二进制数据     // 加密     std::string enc = aesEncrypt(source, key);     std::cout << "aesEncrypt:" << source.length() << "->" << enc.length() << std::endl;     // 输出到文件     fp =  fopen("enc.bin", "wb");     fwrite(enc.data(), 1, enc.length(), fp);     fclose(fp); }</code></pre> 解密: <pre> <code class="language-cpp">#include <string> #include <iostream> #include <stdio.h> #include <assert.h> #include <openssl/objects.h> #include <openssl/evp.h> // 注意:参数和返回值全部是二进制数据 std::string aesDecrypt(const std::string& ciphertext, const std::string& key) {     EVP_CIPHER_CTX ctx;     EVP_CIPHER_CTX_init(&ctx);     int ret = EVP_DecryptInit_ex(&ctx, EVP_aes_128_ecb(), NULL, (const unsigned char*)key.data(), NULL);     assert(ret == 1);     unsigned char* result = new unsigned char[ciphertext.length() + 64]; // 弄个足够大的空间     int len1 = 0;     ret = EVP_DecryptUpdate(&ctx, result, &len1, (const unsigned char*)ciphertext.data(), ciphertext.length());     assert(ret == 1);     int len2 = 0;     ret = EVP_DecryptFinal_ex(&ctx, result+len1, &len2);      assert(ret == 1);     std::cout << len1 << "," << len2 << std::endl;     ret = EVP_CIPHER_CTX_cleanup(&ctx);     assert(ret == 1);     std::string res((char*)result, len1+len2);     delete[] result;     return res; } int main() {     std::string key("helloaeshelloaes", 16);    // 二进制数据,而不是以0结尾的字符串     // 读取文件内容(简单起见认为文件内容<100K)     char buf[1024*100];     FILE* fp = fopen("enc.bin", "rb");     int bytes = fread(buf, 1, 1024*100, fp);     fclose(fp);     std::string data(buf, bytes); // 二进制数据     // 加密     std::string dec = aesDecrypt(data, key);     std::cout << "aesDecrypt:" << data.length() << "->" << dec.length() << std::endl;     // 输出到文件     fp =  fopen("dec.txt", "wb");     fwrite(dec.data(), 1, dec.length(), fp);     fclose(fp); }</code></pre>
  • docker 常用命令整理

    docker 常用命令整理(持续更新)docker运行容器资源相关 查看所有运行docker的资源消耗情况docker stats 查看指定运行容器资源消耗情况docker stats 容器ID/容器名称查看docker容器日志dockerdocker 常用命令整理(持续更新)docker运行容器资源相关 查看所有运行docker的资源消耗情况docker stats 查看指定运行容器资源消耗情况docker stats 容器ID/容器名称查看docker容器日志docker logs -f --tail 50 容器ID/容器名称--tail 50 表示从最后50行开始  docker容器docker ps 查看运行和运行状态的所有容器docker ps -a 删除容器docker rm -f 容器名称/容器iddocker镜像信息 查看所有镜像docker images 删除镜像docker rmi -f 镜像名称:版本/镜像id构建镜像docker build --name 镜像名称:版本 ./注意构建目录需要有Dockerfile文件导出镜像到文件docker save -o /path/to/save/image-name.tar image-name:tag载入本地镜像文件docker load -i /path/to/save/image-name.tar
  • docker入门使用教程linux系统docker制作教程

    docker入门使用教程/linux(centos)系统docker制作教程<h2>Docker简介</h2> Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。 <h2>Docker 安装及使用</h2> <h2>①资源准备</h2> <ol> <li>docker-engine-1.7.1-1.el6.x86_64.rpm[非必须](docker引擎,也可以通过yum安装)</li> </ol> <img alt="docker入门使用教程/linux(centos)系统docker制作教程" class="img-thumbnail" src="/assets/upload/blog/thumbnail/2017-01/f5ab2b77-0a42-4648-9aa9-0dcd6f01e546.png" /> <ol> <li>docker-centos6.8-tomcat-image.zip[必须](docker制作好的景象文件【最后讲解制作方法】)</li> </ol> <img alt="docker入门使用教程/linux(centos)系统docker制作教程" class="img-thumbnail" src="/assets/upload/blog/thumbnail/2017-01/557337cb-d34f-4e77-94c3-0ca6521dd4f7.png" /> <p><strong>注意安装docker的系统如果是centos6,请将内核升级到3.X版本2.X版本可能会出现意想不到的问题</strong></p> <h2>②安装docker</h2> 命令: <pre> <code>@注意,在cenos7版本安装的名字是docker,所以命令是yum install docker,可先通过yum list|grep docker查看安装版本 #yum install docker</code></pre> <br /> 或者 <pre> <code>@这是通过下载rpm文件安装的方式 #yum install https://get.docker.com/rpm/1.7.1/centos-6/RPMS/x86_64/docker-engine-1.7.1-1.el6.x86_64.rpm</code></pre>   <h2>③启动/停止/查看</h2> 启动命令: <pre> <code>#service docker start</code></pre> <br /> <img alt="docker入门使用教程/linux(centos)系统docker制作教程" class="img-thumbnail" src="/assets/upload/blog/thumbnail/2017-01/fd526343-2ed7-4d2a-a543-21c63f575812.png" /><br /> 查看docker信息命令: <pre> <code># docker info</code></pre> <img alt="docker入门使用教程/linux(centos)系统docker制作教程" class="img-thumbnail" src="/assets/upload/blog/thumbnail/2017-01/4fa55562-0fba-4855-852c-5ed8fce9c92b.png" /><br /> 停止docker命令 <pre> <code>#service docker stop</code></pre> <br /> <img alt="docker入门使用教程/linux(centos)系统docker制作教程" class="img-thumbnail" src="/assets/upload/blog/thumbnail/2017-01/a6b36881-1959-4320-b97a-ca1c3f9cbe1a.png" /> <h2>④修改docker默认存储位置</h2> <pre> <code>#cd /var/lib # cp -rf docker docker.bak # cp -rf docker /data/docker/ # ln -s /data/docker docker </code></pre> <h2>⑤镜像准备</h2> 将镜像上传至服务器/data/images<br /> 解压上传的景象文件 <pre> <code># unzip docker-centos6.8-tomcat-image.zip</code></pre> <img alt="docker入门使用教程/linux(centos)系统docker制作教程" class="img-thumbnail" src="/assets/upload/blog/thumbnail/2017-01/2e5999d4-240b-4ba7-ac83-b9ea8212d90f.png" /> <h2>⑥启动docker服务</h2> <pre> <code>#service docker start</code></pre> <h2>⑦Docker创建/载入景象<br /> 切换至解压的景象目录</h2> <pre> <code>#cd centos6_tomcat/</code></pre> <img class="img-thumbnail" src="/assets/upload/blog/thumbnail/2017-01/1c74d8ab-fd0a-4798-8d71-1fe12d959641.png" />Docker执行创建镜像 <pre> <code># docker build -t tomcat ./</code></pre> 最后结果图:<br /> <img class="img-thumbnail" src="/assets/upload/blog/thumbnail/2017-01/130dd457-9be7-48d2-b3dd-52f39248fee1.png" /><br /> <span style="color:#ff0000">[注意:]step不一定都是29</span> <h2>⑧创建一个docker容器</h2> 命令: <pre> <code># docker run -d -p 2000:22 -p 8000:8080 tomcat </code></pre> <img alt="⑧创建一个docker容器" class="img-thumbnail" src="/assets/upload/blog/thumbnail/2017-01/4418d97f-8332-4eaf-b60d-a765287e8be4.png" /> <h2>⑨挂载docker一个共享目录,共享于主机方式开启一个docker</h2> 命令 <pre> <code>[root@MiWiFi-R1CM-srv share]# docker run -d -p 2008:22 -p 8008:8080 -v /data/share:/opt/share --privileged=true tomcat ccc238337fe92d05b806d996f252e2ecc8747d509af435d06fd2de3058de7b83 [root@MiWiFi-R1CM-srv share]# ll</code></pre>   <pre> <code>参数说明: -p 2008:22 docker里面的22端口对应主机的2008端口,用于外部SSH访问 -p 8008:8080 -v /data/share:/opt/share 主机的/data/share共享给docker/opt/share目录,类似于mount挂载 tomcat 镜像名称 --privileged=true 解决因selinux引起的docker容器内部对共享目录的权限不足问题,如果不加这个参数请关闭selinux</code></pre> 登录docker,切换到共享目录写一个文件<br /> <img alt="1" class="img-thumbnail" src="/assets/upload/blog/thumbnail/2017-01/4c461325-5f83-4221-8456-ff85072b3ba4.png" /><br /> 回主机查看:<br /> <img alt="2" class="img-thumbnail" src="/assets/upload/blog/thumbnail/2017-01/122a5ae1-f1e0-45c3-88ec-3b9be2eb0acd.png" /><br /> 由此便可以共享目录<br /> <strong>共享目录的好处:<br /> 1.方便主机上数据备份<br /> 2.将应用数据放于共享目录,如果docker不幸挂了,没事儿数据还在主机上,提高容错性<br /> <br /> 其他运行参数:</strong> <h2>Usage</h2> <pre> <code>docker run [OPTIONS] IMAGE [COMMAND] [ARG...] </code></pre> <h2>Options</h2> <table> <thead> <tr> <td>Name, shorthand</td> <td>Default</td> <td>Description</td> </tr> </thead> <tbody> <tr> <td><code>--add-host</code></td> <td> </td> <td>Add a custom host-to-IP mapping (host:ip)</td> </tr> <tr> <td><code>--attach , -a</code></td> <td> </td> <td>Attach to STDIN, STDOUT or STDERR</td> </tr> <tr> <td><code>--blkio-weight</code></td> <td> </td> <td>Block IO (relative weight), between 10 and 1000, or 0 to disable (default 0)</td> </tr> <tr> <td><code>--blkio-weight-device</code></td> <td> </td> <td>Block IO weight (relative device weight)</td> </tr> <tr> <td><code>--cap-add</code></td> <td> </td> <td>Add Linux capabilities</td> </tr> <tr> <td><code>--cap-drop</code></td> <td> </td> <td>Drop Linux capabilities</td> </tr> <tr> <td><code>--cgroup-parent</code></td> <td> </td> <td>Optional parent cgroup for the container</td> </tr> <tr> <td><code>--cidfile</code></td> <td> </td> <td>Write the container ID to the file</td> </tr> <tr> <td><code>--cpu-count</code></td> <td> </td> <td>CPU count (Windows only)</td> </tr> <tr> <td><code>--cpu-percent</code></td> <td> </td> <td>CPU percent (Windows only)</td> </tr> <tr> <td><code>--cpu-period</code></td> <td> </td> <td>Limit CPU CFS (Completely Fair Scheduler) period</td> </tr> <tr> <td><code>--cpu-quota</code></td> <td> </td> <td>Limit CPU CFS (Completely Fair Scheduler) quota</td> </tr> <tr> <td><code>--cpu-rt-period</code></td> <td> </td> <td><a href="https://docs.docker.com/engine/api/v1.25/" rel="external nofollow" target="_blank">API 1.25+</a><br /> Limit CPU real-time period in microseconds</td> </tr> <tr> <td><code>--cpu-rt-runtime</code></td> <td> </td> <td><a href="https://docs.docker.com/engine/api/v1.25/" rel="external nofollow" target="_blank">API 1.25+</a><br /> Limit CPU real-time runtime in microseconds</td> </tr> <tr> <td><code>--cpu-shares , -c</code></td> <td> </td> <td>CPU shares (relative weight)</td> </tr> <tr> <td><code>--cpus</code></td> <td> </td> <td><a href="https://docs.docker.com/engine/api/v1.25/" rel="external nofollow" target="_blank">API 1.25+</a><br /> Number of CPUs</td> </tr> <tr> <td><code>--cpuset-cpus</code></td> <td> </td> <td>CPUs in which to allow execution (0-3, 0,1)</td> </tr> <tr> <td><code>--cpuset-mems</code></td> <td> </td> <td>MEMs in which to allow execution (0-3, 0,1)</td> </tr> <tr> <td><code>--detach , -d</code></td> <td> </td> <td>Run container in background and print container ID</td> </tr> <tr> <td><code>--detach-keys</code></td> <td> </td> <td>Override the key sequence for detaching a container</td> </tr> <tr> <td><code>--device</code></td> <td> </td> <td>Add a host device to the container</td> </tr> <tr> <td><code>--device-cgroup-rule</code></td> <td> </td> <td>Add a rule to the cgroup allowed devices list</td> </tr> <tr> <td><code>--device-read-bps</code></td> <td> </td> <td>Limit read rate (bytes per second) from a device</td> </tr> <tr> <td><code>--device-read-iops</code></td> <td> </td> <td>Limit read rate (IO per second) from a device</td> </tr> <tr> <td><code>--device-write-bps</code></td> <td> </td> <td>Limit write rate (bytes per second) to a device</td> </tr> <tr> <td><code>--device-write-iops</code></td> <td> </td> <td>Limit write rate (IO per second) to a device</td> </tr> <tr> <td><code>--disable-content-trust</code></td> <td><code>true</code></td> <td>Skip image verification</td> </tr> <tr> <td><code>--dns</code></td> <td> </td> <td>Set custom DNS servers</td> </tr> <tr> <td><code>--dns-opt</code></td> <td> </td> <td>Set DNS options</td> </tr> <tr> <td><code>--dns-option</code></td> <td> </td> <td>Set DNS options</td> </tr> <tr> <td><code>--dns-search</code></td> <td> </td> <td>Set custom DNS search domains</td> </tr> <tr> <td><code>--entrypoint</code></td> <td> </td> <td>Overwrite the default ENTRYPOINT of the image</td> </tr> <tr> <td><code>--env , -e</code></td> <td> </td> <td>Set environment variables</td> </tr> <tr> <td><code>--env-file</code></td> <td> </td> <td>Read in a file of environment variables</td> </tr> <tr> <td><code>--expose</code></td> <td> </td> <td>Expose a port or a range of ports</td> </tr> <tr> <td><code>--group-add</code></td> <td> </td> <td>Add additional groups to join</td> </tr> <tr> <td><code>--health-cmd</code></td> <td> </td> <td>Command to run to check health</td> </tr> <tr> <td><code>--health-interval</code></td> <td> </td> <td>Time between running the check (ms|s|m|h) (default 0s)</td> </tr> <tr> <td><code>--health-retries</code></td> <td> </td> <td>Consecutive failures needed to report unhealthy</td> </tr> <tr> <td><code>--health-start-period</code></td> <td> </td> <td><a href="https://docs.docker.com/engine/api/v1.29/" rel="external nofollow" target="_blank">API 1.29+</a><br /> Start period for the container to initialize before starting health-retries countdown (ms|s|m|h) (default 0s)</td> </tr> <tr> <td><code>--health-timeout</code></td> <td> </td> <td>Maximum time to allow one check to run (ms|s|m|h) (default 0s)</td> </tr> <tr> <td><code>--help</code></td> <td> </td> <td>Print usage</td> </tr> <tr> <td><code>--hostname , -h</code></td> <td> </td> <td>Container host name</td> </tr> <tr> <td><code>--init</code></td> <td> </td> <td><a href="https://docs.docker.com/engine/api/v1.25/" rel="external nofollow" target="_blank">API 1.25+</a><br /> Run an init inside the container that forwards signals and reaps processes</td> </tr> <tr> <td><code>--interactive , -i</code></td> <td> </td> <td>Keep STDIN open even if not attached</td> </tr> <tr> <td><code>--io-maxbandwidth</code></td> <td> </td> <td>Maximum IO bandwidth limit for the system drive (Windows only)</td> </tr> <tr> <td><code>--io-maxiops</code></td> <td> </td> <td>Maximum IOps limit for the system drive (Windows only)</td> </tr> <tr> <td><code>--ip</code></td> <td> </td> <td>IPv4 address (e.g., 172.30.100.104)</td> </tr> <tr> <td><code>--ip6</code></td> <td> </td> <td>IPv6 address (e.g., 2001:db8::33)</td> </tr> <tr> <td><code>--ipc</code></td> <td> </td> <td>IPC mode to use</td> </tr> <tr> <td><code>--isolation</code></td> <td> </td> <td>Container isolation technology</td> </tr> <tr> <td><code>--kernel-memory</code></td> <td> </td> <td>Kernel memory limit</td> </tr> <tr> <td><code>--label , -l</code></td> <td> </td> <td>Set meta data on a container</td> </tr> <tr> <td><code>--label-file</code></td> <td> </td> <td>Read in a line delimited file of labels</td> </tr> <tr> <td><code>--link</code></td> <td> </td> <td>Add link to another container</td> </tr> <tr> <td><code>--link-local-ip</code></td> <td> </td> <td>Container IPv4/IPv6 link-local addresses</td> </tr> <tr> <td><code>--log-driver</code></td> <td> </td> <td>Logging driver for the container</td> </tr> <tr> <td><code>--log-opt</code></td> <td> </td> <td>Log driver options</td> </tr> <tr> <td><code>--mac-address</code></td> <td> </td> <td>Container MAC address (e.g., 92:d0:c6:0a:29:33)</td> </tr> <tr> <td><code>--memory , -m</code></td> <td> </td> <td>Memory limit</td> </tr> <tr> <td><code>--memory-reservation</code></td> <td> </td> <td>Memory soft limit</td> </tr> <tr> <td><code>--memory-swap</code></td> <td> </td> <td>Swap limit equal to memory plus swap: ‘-1’ to enable unlimited swap</td> </tr> <tr> <td><code>--memory-swappiness</code></td> <td><code>-1</code></td> <td>Tune container memory swappiness (0 to 100)</td> </tr> <tr> <td><code>--mount</code></td> <td> </td> <td>Attach a filesystem mount to the container</td> </tr> <tr> <td><code>--name</code></td> <td> </td> <td>Assign a name to the container</td> </tr> <tr> <td><code>--net</code></td> <td> </td> <td>Connect a container to a network</td> </tr> <tr> <td><code>--net-alias</code></td> <td> </td> <td>Add network-scoped alias for the container</td> </tr> <tr> <td><code>--network</code></td> <td> </td> <td>Connect a container to a network</td> </tr> <tr> <td><code>--network-alias</code></td> <td> </td> <td>Add network-scoped alias for the container</td> </tr> <tr> <td><code>--no-healthcheck</code></td> <td> </td> <td>Disable any container-specified HEALTHCHECK</td> </tr> <tr> <td><code>--oom-kill-disable</code></td> <td> </td> <td>Disable OOM Killer</td> </tr> <tr> <td><code>--oom-score-adj</code></td> <td> </td> <td>Tune host’s OOM preferences (-1000 to 1000)</td> </tr> <tr> <td><code>--pid</code></td> <td> </td> <td>PID namespace to use</td> </tr> <tr> <td><code>--pids-limit</code></td> <td> </td> <td>Tune container pids limit (set -1 for unlimited)</td> </tr> <tr> <td><code>--platform</code></td> <td> </td> <td><a href="https://docs.docker.com/engine/reference/commandline/dockerd/#daemon-configuration-file" rel="external nofollow" target="_blank">experimental (daemon)</a><a href="https://docs.docker.com/engine/api/v1.32/" rel="external nofollow" target="_blank">API 1.32+</a><br /> Set platform if server is multi-platform capable</td> </tr> <tr> <td><code>--privileged</code></td> <td> </td> <td>Give extended privileges to this container</td> </tr> <tr> <td><code>--publish , -p</code></td> <td> </td> <td>Publish a container’s port(s) to the host</td> </tr> <tr> <td><code>--publish-all , -P</code></td> <td> </td> <td>Publish all exposed ports to random ports</td> </tr> <tr> <td><code>--read-only</code></td> <td> </td> <td>Mount the container’s root filesystem as read only</td> </tr> <tr> <td><code>--restart</code></td> <td><code>no</code></td> <td>Restart policy to apply when a container exits</td> </tr> <tr> <td><code>--rm</code></td> <td> </td> <td>Automatically remove the container when it exits</td> </tr> <tr> <td><code>--runtime</code></td> <td> </td> <td>Runtime to use for this container</td> </tr> <tr> <td><code>--security-opt</code></td> <td> </td> <td>Security Options</td> </tr> <tr> <td><code>--shm-size</code></td> <td> </td> <td>Size of /dev/shm</td> </tr> <tr> <td><code>--sig-proxy</code></td> <td><code>true</code></td> <td>Proxy received signals to the process</td> </tr> <tr> <td><code>--stop-signal</code></td> <td><code>SIGTERM</code></td> <td>Signal to stop a container</td> </tr> <tr> <td><code>--stop-timeout</code></td> <td> </td> <td><a href="https://docs.docker.com/engine/api/v1.25/" rel="external nofollow" target="_blank">API 1.25+</a><br /> Timeout (in seconds) to stop a container</td> </tr> <tr> <td><code>--storage-opt</code></td> <td> </td> <td>Storage driver options for the container</td> </tr> <tr> <td><code>--sysctl</code></td> <td> </td> <td>Sysctl options</td> </tr> <tr> <td><code>--tmpfs</code></td> <td> </td> <td>Mount a tmpfs directory</td> </tr> <tr> <td><code>--tty , -t</code></td> <td> </td> <td>Allocate a pseudo-TTY</td> </tr> <tr> <td><code>--ulimit</code></td> <td> </td> <td>Ulimit options</td> </tr> <tr> <td><code>--user , -u</code></td> <td> </td> <td>Username or UID (format: <name|uid>[:<group|gid>])</td> </tr> <tr> <td><code>--userns</code></td> <td> </td> <td>User namespace to use</td> </tr> <tr> <td><code>--uts</code></td> <td> </td> <td>UTS namespace to use</td> </tr> <tr> <td><code>--volume , -v</code></td> <td> </td> <td>Bind mount a volume</td> </tr> <tr> <td><code>--volume-driver</code></td> <td> </td> <td>Optional volume driver for the container</td> </tr> <tr> <td><code>--volumes-from</code></td> <td> </td> <td>Mount volumes from the specified container(s)</td> </tr> <tr> <td><code>--workdir , -w</code></td> <td> </td> <td>Working directory inside the container</td> </tr> </tbody> </table>   <h2>⑩其他docker命令</h2> 1.查看正在运行的容器 <pre> <code>#docker ps</code></pre> <img alt="查看正在运行的容器" class="img-thumbnail" src="/assets/upload/blog/thumbnail/2017-01/84400554-b91c-4d09-a533-5509b5eb2ab6.png" /><br /> #docker ps -a为查看所有的容器,包括已经停止的。<br /> 2.    容器的启动,停止,杀死<br /> 启动容器 <pre> <code># docker start <容器名orID></code></pre> 停止容器 <pre> <code># docker stop <容器名orID></code></pre> 杀死容器 <pre> <code> #docker kill <容器名orID></code></pre> 3.    删除容器<br /> 通过容器ID删除 <pre> <code>#docker rm –f <容器名orID></code></pre> 删除所有容器 <pre> <code> # docker rm -f $(docker ps -a -q)</code></pre> 4.查看镜像 <pre> <code># docker images</code></pre> <br /> <img alt="查看镜像" class="img-thumbnail" src="/assets/upload/blog/thumbnail/2017-01/07c49eeb-50d2-4972-b565-53f32f0f62a5.png" /><br /> 删除所有镜像 <pre> <code> #docker rmi -f $(docker images -q)</code></pre> Docker Tomcat基础镜像制作<br /> 本案例采用centos6.8进行在线制作<br /> [centos/redhat系列工具为febootstrap]<br /> [debian/ubuntu系列工具debootstrap] <h2>Centos 6.8 tomcat运行环境docker镜像制作</h2> <h3>①资源准备</h3> 1.epel源安装包<br /> <img alt="epel源安装包" class="img-thumbnail" src="/assets/upload/blog/thumbnail/2017-01/e76b59b0-faf1-4a06-bb15-40bc5f25e92d.png" /><br />  EPEL 是yum的一个软件源,里面包含了许多基本源里没有的软件。<br /> ​2.febootstrap安装包<br /> 一般使用yum命令在线安装 <h3>②安装相关工具</h3> 1.如果当前运行系统版本为centos6.X需要安装epel源 <strong><em> </em></strong> <pre> <code># yum install epel-release-6-8.noarch.rpm -y</code></pre> <img alt="安装相关工具" class="img-thumbnail" src="/assets/upload/blog/thumbnail/2017-01/10bf5746-f91f-459e-9856-2f98da46101d.png" /><br /> 2.安装febootstrap <pre> <code># yum install febootstrap –y</code></pre> <img alt="安装febootstrap" class="img-thumbnail" src="/assets/upload/blog/thumbnail/2017-01/1104e8ce-b73c-4235-a660-0de4be51b363.png" /> <h3>③使用febootstrap创建一个类似虚拟机的系统</h3> 创建空白环境命令 <pre> <code>#febootstrap -i bash  -i yum -i iputils -i iproute -i man -i vi -i openssh-server -i openssh-clients -i tar -i gzip -i unzip -i passwd  centos6.8 centos6.8-image http://mirrors.aliyun.com/centos/6.8/os/x86_64/</code></pre> 创建httpd+php环境 <pre> <code> febootstrap -i bash -i yum -i iputils -i iproute -i man -i vi -i openssh-server -i openssh-clients -i tar -i gzip -i unzip -i passwd -i httpd -i httpd-devel -i php -i php-devel -i php-mysql -i php-gd -i php-imap -i php-ldap -i php-odbc -i php-pear -i php-xml -i php-xmlrpc CentOS7.3 centos7.3-image http://mirrors.aliyun.com/centos/6.9/os/x86_64/</code></pre> <br /> 创建Java8环境 <pre> <code> febootstrap -i bash -i yum -i iputils -i iproute -i man -i vi -i openssh-server -i openssh-clients -i tar -i gzip -i unzip -i passwd -i java-1.8.0-openjdk.x86_64 CentOS7.3 centos7.3-image http://mirrors.aliyun.com/centos/6.9/os/x86_64/</code></pre> <br /> <br /> 其中 <br /> –i表示要安装的工具包<br /> centos6.8 系统版本<br /> centos6.8-image 等会执行完成后将在当前目录生成一个名字为centos6.8-image的文件夹<br /> http://mirrors.aliyun.com/centos/6.8/os/x86_64/ 镜像来源参照,这里使用的阿里的镜像库<br /> 命令执行完成将生成一个centos6.8-image文件夹,其内部结构似一个系统的结构<br /> <br /> <img alt="使用febootstrap创建一个类似虚拟机的系统" class="img-thumbnail" src="/assets/upload/blog/thumbnail/2017-01/075165f8-fd11-4200-a2d6-e4924b64c11f.png" /><br /> 将当前系统的root用户目录下的.bash开头的文件复制到/root目录<br /> <img alt="使用febootstrap创建一个类似虚拟机的系统" class="img-thumbnail" src="/assets/upload/blog/thumbnail/2017-01/4428ae07-db97-4a04-b69b-2fc13afc1ef5.png" /><br /> 命令 <pre> <code>#cp /root/.bash*  存放路径/centos6.8-image/root</code></pre> 打包镜像目录<br /> 首先进入镜像目录 <pre> <code>#cd cd centos6.8-image/</code></pre> <img alt="使用febootstrap创建一个类似虚拟机的系统" class="img-thumbnail" src="/assets/upload/blog/thumbnail/2017-01/38c0854b-2d44-403e-9a00-c96a27262087.png" /><br /> 使用tar打包,注意不能使用z参数启用gzip <pre> <code>#tar -cvf centos6.8.tar ./</code></pre> <img alt="使用febootstrap创建一个类似虚拟机的系统" class="img-thumbnail" src="/assets/upload/blog/thumbnail/2017-01/8bca9b1f-7570-42a2-8180-f1862ce41b38.png" /><br /> 查看当前tar包大小<br /> 命令: <pre> <code>#du -h centos6.8.tar</code></pre> <img alt="使用febootstrap创建一个类似虚拟机的系统" class="img-thumbnail" src="/assets/upload/blog/thumbnail/2017-01/31fae0cf-8e8a-47a8-98bc-4af79a038825.png" /><br /> 执行xz命令进行再次高效率压缩,执行xz命令需要一段时间 <pre> <code>#xz centos6.8.tar</code></pre> <img alt="使用febootstrap创建一个类似虚拟机的系统" class="img-thumbnail" src="/assets/upload/blog/thumbnail/2017-01/1ff8e4f9-fcc8-408b-bf2a-697d8e7a6803.png" /><br /> 使用xz命令效果还是明显的,396MB压缩到83MB <h3>④创建docker镜像</h3> 首先创建一个docker的配置文件名字必须为Dockerfile<br /> 将上面生成的centos6.8文件复制到同一个目录,将jdk以及tomcat也复制到同一个目录<br /> <img alt="创建docker镜像" class="img-thumbnail" src="/assets/upload/blog/thumbnail/2017-01/fb5732e8-3bd1-4c85-9775-695c4d6129c6.png" /><br /> Jdk为linux免安装版本打包成zip,Tomcat由linux版本的tar包解压打包成的zip包<br /> 接下来就是Dockerfile的配置 <pre> <code># # 安装: docker build -t tomcat ./ # 运行: docker run -d -p 8822:22 -p 8888:8080 tomcat # 挂载: docker run -d -p 8822:22 -p 8888:8080 -v /mnt/data/vr:/opt/tomcat/webapps/ROOT -h java-test --name java-dev tomcat #其他参数: #-a stdin: 指定标准输入输出内容类型,可选 STDIN/STDOUT/STDERR 三项; #-d: 后台运行容器,并返回容器ID; #-i: 以交互模式运行容器,通常与 -t 同时使用; #-t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用; #--name="nginx-lb": 为容器指定一个名称; #--dns 8.8.8.8: 指定容器使用的DNS服务器,默认和宿主一致; #--dns-search example.com: 指定容器DNS搜索域名,默认和宿主一致; #-h "mars": 指定容器的hostname; #-e username="ritchie": 设置环境变量; #--env-file=[]: 从指定文件读入环境变量; #--cpuset="0-2" or --cpuset="0,1,2": 绑定容器到指定CPU运行; #-m :设置容器使用内存最大值; #--net="bridge": 指定容器的网络连接类型,支持 bridge/host/none/container: 四种类型; #--link=[]: 添加链接到另一个容器; #--expose=[]: 开放一个端口或一组端口; #安装本地Centos FROM scratch MAINTAINER The CentOS Project <1441023520@qq.com> #添加基础镜像到根目录 ADD centos6.8.tar.xz / LABEL Vendor="CentOS" LABEL License=GPLv2 CMD ["/bin/bash"] #安装需要安装的额外软件 #安装openssh和unzip工具 #RUN yum install unzip -y #RUN yum install openssh-server -y #生成ssh的登陆证书 RUN ssh-keygen -q -t rsa -b 2048 -f /etc/ssh/ssh_host_rsa_key -N '' RUN ssh-keygen -q -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -N '' RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_ed25519_key -N '' RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key -N '' #修改ssh-server的配置 RUN sed -i "s/#UsePrivilegeSeparation.*/UsePrivilegeSeparation no/g" /etc/ssh/sshd_config RUN sed -i "s/UsePAM.*/UsePAM no/g" /etc/ssh/sshd_config #修改当前系统的ROOT密码 RUN echo "root:root" > /tmp/tmp.pass RUN chpasswd < /tmp/tmp.pass #外部工具相关 ADD tomcat.zip /tmp/tomcat.zip ADD jdk.zip /tmp/jdk.zip #解压相关项目 RUN unzip /tmp/tomcat.zip -d /opt RUN unzip /tmp/jdk.zip -d /opt #设置环境变量 RUN echo "" >> /etc/profile RUN echo "JAVA_HOME=/opt/jdk" >> /etc/profile RUN echo "PATH=/opt/jdk/bin:$PATH" >> /etc/profile RUN echo "CLASSPATH=.:/opt/jdk/lib/dt.jar:/opt/jdk/lib/tools.jar" >> /etc/profile RUN echo "export JAVA_HOME" >> /etc/profile RUN echo "export PATH" >> /etc/profile RUN echo "export CLASSPATH" >> /etc/profile #设置系统时区 RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime ENV JAVA_HOME /opt/jdk ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/jdk/bin:/opt/tomcat/bin #设置语言,解决乱码 RUN echo "export LC_ALL=zh_CN.UTF-8" >> /etc/profile #设置读写权限 RUN chmod -R 755 /opt #设置进入启动项 ENTRYPOINT /opt/tomcat/bin/startup.sh & /usr/sbin/sshd -D </code></pre> <br /> 注意:最后的启动项一定要配置sshd的。否则docker容器将无法使用SSH工具连入<br /> 以上便是一个运行Tomcat的环境的基础镜像制作方法. <h2>Alpine linux tomcat环境docker镜像</h2> ①Dockerfile: <pre> <code>FROM alpine:3.4 MAINTAINER cSphere <docker@csphere.cn> #安装 bash curl ca-certificates工具 RUN apk add --no-cache --update-cache bash RUN apk add --no-cache --update-cache curl ca-certificates   #证书 RUN curl -Lo  /etc/apk/keys/sgerrand.rsa.pub https://raw.githubusercontent.com/sgerrand/alpine-pkg-glibc/master/sgerrand.rsa.pub #下载glibc相关包 RUN curl -Lo /etc/apk/keys/sgerrand.rsa.pub https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.23-r3/sgerrand.rsa.pub RUN curl -Lo glibc-2.23-r3.apk  https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.23-r3/glibc-2.23-r3.apk RUN curl -Lo glibc-bin-2.23-r3.apk  https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.23-r3/glibc-bin-2.23-r3.apk RUN curl -Lo glibc-i18n-2.23-r3.apk  https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.23-r3/glibc-i18n-2.23-r3.apk #安装glibc RUN apk add  glibc-2.23-r3.apk glibc-bin-2.23-r3.apk glibc-i18n-2.23-r3.apk   #安装SSH RUN apk update RUN apk --no-cache add openssh   #生成ssh的登陆证书 RUN ssh-keygen -q -t rsa -b 2048 -f /etc/ssh/ssh_host_rsa_key -N '' RUN ssh-keygen -q -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -N '' RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_ed25519_key  -N '' RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key -N ''   #修改当前系统的ROOT密码 RUN echo "root:root" > /tmp/tmp.pass RUN chpasswd < /tmp/tmp.pass   CMD ["/bin/bash"]   #Java环境 ADD tomcat.zip /opt/tomcat.zip ADD jdk.zip /opt/jdk.zip #解压 RUN unzip  /opt/tomcat.zip -d /opt RUN unzip  /opt/jdk.zip -d /opt #设置环境变量 RUN echo "" >> /etc/profile RUN echo "JAVA_HOME=/opt/jdk" >> /etc/profile RUN echo "PATH=/opt/jdk/bin:$PATH" >> /etc/profile RUN echo "CLASSPATH=.:/opt/jdk/lib/dt.jar:/opt/jdk/lib/tools.jar" >> /etc/profile RUN echo "export JAVA_HOME" >> /etc/profile RUN echo "export PATH" >> /etc/profile RUN echo "export CLASSPATH" >> /etc/profile   #设置时区 ADD Chongqing /etc/localtime     #设置进入启动项 ENTRYPOINT  /usr/sbin/sshd -D</code></pre>  
  • Docker-Compose 简介及安装和常用命令

    一. Docker-Compose 简介1. Docker-Compose 简介Docker-Compose项目是Docker官方的开源项目,负责实现对Docker容器集群的快速编排。Docker-Compose将所管理的容器分为三层,分别一. Docker-Compose 简介1. Docker-Compose 简介Docker-Compose项目是Docker官方的开源项目,负责实现对Docker容器集群的快速编排。Docker-Compose将所管理的容器分为三层,分别是工程(project),服务(service)以及容器(container)。Docker-Compose运行目录下的所有文件(docker-compose.yml,extends文件或环境变量文件等)组成一个工程,若无特殊指定工程名即为当前目录名。一个工程当中可包含多个服务,每个服务中定义了容器运行的镜像,参数,依赖。一个服务当中可包括多个容器实例,Docker-Compose并没有解决负载均衡的问题,因此需要借助其它工具实现服务发现及负载均衡。 Docker-Compose的工程配置文件默认为docker-compose.yml,可通过环境变量COMPOSE_FILE或-f参数自定义配置文件,其定义了多个有依赖关系的服务及每个服务运行的容器。使用一个Dockerfile模板文件,可以让用户很方便的定义一个单独的应用容器。在工作中,经常会碰到需要多个容器相互配合来完成某项任务的情况。例如要实现一个Web项目,除了Web服务容器本身,往往还需要再加上后端的数据库服务容器,甚至还包括负载均衡容器等。Docker-Compose允许用户通过一个单独的docker-compose.yml模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project)。 Docker-Compose项目由Python编写,调用Docker服务提供的API来对容器进行管理。因此,只要所操作的平台支持Docker API,就可以在其上利用Compose来进行编排管理。2. Docker-Compose安装sudo curl -L "https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-composesudo chmod +x /usr/local/bin/docker-compose sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose检查安装结果$ docker-compose --version docker-compose version 1.27.4, build 1110ad01二. Docker-Compose常用命令1. Docker-Compose 命令格式docker-compose [-f <arg>] [options][command][args]常用命令选项如下:-f -file FILE 可指定Compose 模版文件,默认为 docker-compose.yml-p -project-name NAME指定项目名称,默认将使用所在目录名称为项目名-v --version 打印版本并退出-verbose 输出调试信息-x-network-driver 使用 Docker 的可插拔网络后端特性(需要 Docker 1.9+版本,可操作性有待商榷)-x-network-deover DRIVER指定网络后端的驱动,默认为 bridge(需要 Docker 1.9+版本)2. Docker-Compose 拉取服务镜像docker-compose pull [options] [SERVICE...]命令选项如下:–ignore-pull-failures,忽略拉取镜像过程中的错误 –parallel,多个镜像同时拉取 –quiet,拉取镜像过程中不打印进度信息拉取服务依赖的镜像docker-compose pull3. Docker-Compose 构建服务docker-compose build [options] [--build-arg key=val...] [SERVICE...]命令选项包括: –compress 通过gzip压缩构建上下环境 –force-rm 删除构建过程中的临时容器 –no-cache 构建镜像过程中不使用缓存 –pull 始终尝试通过拉取操作来获取更新版本的镜像 -m, –memory MEM为构建的容器设置内存大小 –build-arg key=val为服务设置build-time变量 服务容器一旦构建后,将会带上一个标记名。可以随时在项目目录下运行docker-compose build来重新构建服务4. Docker-Compose 启动容器docker-compose start [SERVICE...]启动已经存在的服务容器docker-compose start5. Docker-compose 构建并启动容器docker-compose up [option][--scale SERVICE=NUM...][SERVICE...]常用命令选项如下:-d 在后台运行服务器-t -timeout TIMEOUT 停止容器是的超时(默认为 10 秒)-f -file FILE 可指定Compose 模版文件,默认为 docker-compose.yml-build 在启动容器前自动构建服务镜像-no-build 不自动构建缺失的镜像常用命令实例启动所有服务docker-compose up在后台启动所有服务docker-compose up -d重新构建镜像docker-compose up -d --build-f 使用指定的 Compose 模版文件启动服务,默认为 docker-compose.yml 文件docker-compose -f docker-compose.yml up6. Docker-Compose 查看容器docker-compose ps [options][SERVICE...]查看项目中运行中的容器docker-compose ps查看当前项目中的所有容器docker-compose ps -a7. Docker-Compose 停止容器docker-compose stop [options] [SERVICE...]命令选项如下:-t —timeout TIMEOUT停止容器时候的超时(默认为 10 秒)停止正在运行的容器docker-compose stop可使用以下命令再次启动docker-compose start通过发送 SIGKILL 信号强制停止服务容器docker-compsoe kill [options] [SERVICE]命令选项如下:-s 指定发送的信号8. Docker-Compose 移除容器docker-compose rm [options] [SERVICE...]命令选项如下:–f, –force,强制直接删除,包括非停止状态的容器 -v 删除容器所挂载的数据卷先停止容器docker-compose stop删除所有停止状态下的容器docker-compose rm9. Docker-Compose 停用移除所有容器以及网络相关docker-compose down [options]命令选项如下:-rmi type,删除镜像、类型必须是:all,删除 compose 文件中定义的所有镜像local, 删除镜像名为空的镜像-v -volumes 删除已经在 compose 文件中定义的和匿名的附在容器上的数据卷-remove-orphans 删除服务中没有在 compose 中定义的容器10. Docker-Compose 查看输出日志docker-compose logs [options][SERVICE...]默认情况下,docker-compsoe 将对不同的服务输出使用不同的颜色用以区分,但是可以通过-no-color 关闭颜色查看服务容器的输出docker-compose logs11. Docker-Compose 重启服务docker-compose restart [options] [SERVICE...]命令选项如下:-t –timeout TIMEOUT 指定重启前停止容器的超时(默认为10秒)重启项目服务docker-compose restart12. Docker-Compose 暂停、恢复容器暂停容器docker-compose pause [SERVICE...]恢复处于暂停状态的容器docker-compsoe unpause [SERVICE...]13. Docker-Compose 执行命令docker-compose run [options] [-v VOLUME...] [-p PORT...] [-e KEY=VAL...] SERVICE [COMMAND] [ARGS...]在指定容器执行 ping 命令docker-compose run Ubuntu ping www.baidu.com14. Docker-Compose 指定运行容器数量设置指定服务运行的容器个数docker-compose scale web=3 db=215. Docker-Compose 推送镜像docker-compsoe push [options][SERVICE...]命令选项如下:–ignore-push-failures 忽略推送镜像过程中的错误三.Docker-Compose配置文件docker-compose.yml案例一:tomcat镜像docker-compose.yaml:version: "3.8" ​ networks: vRouter: # 定义网络名:因使用已经存在的网络,所以名称与已经存在的bridge网络名称相同   external: true #使用外部(已存在)的网络 ​ services: app-xs-1:   image: tomcat:8  #镜像名称和版本   container_name: app-xs-01 # 等同于 --name app-xs   hostname: app-xs-01 #等同于 --hostname app-xs   ports:     - "8001:8080" #等同于 -p 8001:8080 ​   networks:     vRouter: #等同于 --network vRouter (注意这里的vRouter必须在顶层networks定义)       aliases:         - app-xs-01.server #等同于 --network-alias app-xs-01.server ​   volumes:     - "/data/upload:/data/xs_uploadFile"     - "/data/app/ROOT:/opt/tomcat/webapps/ROOT" # -v /data/app/ROOT:/opt/tomcat/webapps/ROOT ​   deploy:     resources:       limits:         memory: 1568M # -m 1568M 内存限制 ​案例二:MySQLdocker-compose.yaml:version: "3.8" ​ networks: mysql-net:  # 定义网络名:##因使用已经存在的网络,所以名称与已经存在的bridge网络名称相同 ​ ​ services: mysql5732:   image: harbor.ifok.net:10202/ifok/mysql:5.7.32-Shanghai   container_name: mysql5732 # 等同于 --name mysql5732   hostname: mysql5732 #等同于 --hostname mysql5732   ports:     - "13306:3306"  #等同于 -p 13306:3306 ​   networks:     mysql-net:  #等同于 --network vRouter (注意这里的vRouter必须在顶层networks定义)       aliases:         - mysql5732.server #等同于 --network-alias mysql5732.server   command: [        '--character-set-server=utf8mb4',      '--collation-server=utf8mb4_unicode_ci'    ]   environment:     - MYSQL_ROOT_PASSWORD=root   volumes:     - "/data/mysql5732/data:/var/lib/mysql"       - "/data/mysql5732/conf.d:/etc/mysql/conf.d"    #   - "./init/:/docker-entrypoint-initdb.d/" #挂载初始化的脚本目录 ​ ​   deploy:     resources:       limits:         memory: 2048M ​ ​案例三 : 其他version: "3.8" ​ #定义网络相关 networks:  #网络名称(可以定义多个网络) vRouter:    #外部网络:(false : 加入已存在网络, 可以先通过命令 docker network create vRouter 创建网络,执行docker-compose down 时候不会删除该网络)   external: true router:    #外部网络:(true : 创建网络,通过 docker network ls 查看创建的一般为“名称_default”,例如下面的“router_app”,    #注意该网络会在docker-compose down命令执行时候删除)   external: false    #配置了name则,网络名为 router_app (默认name为default)   name: app   driver: bridge   ipam:     driver: default     config:        # 注意子网ip不能与已存在的冲突       - subnet: 172.1.0.1/24 ​ #定义服务 services: mysql57:    #镜像选择,私服则直接写全路径,如:harbor.ifok.net:10202/ifok/mysql:5.7.32-Shanghai   image: mysql:5.7.32    #容器名称,与docker run --name mysql57相似   container_name: mysql57    #重启机制   restart: always    #文件挂载 与 docker run -v /data/mysql57/data:/var/lib/mysql 功能相同   volumes:     - "/data/mysql57/data:/var/lib/mysql"     - "/data/mysql57/conf.d:/etc/mysql/conf.d"    #网络(可以加入多个网络也可以只加入一个网络)   networks:      #外部网络,如果不配置则自动获取ip等网络信息     vRouter:       aliases:          #等同于 --network-alias mysql5732.server         - mysql5732.server      #内部网络     router:        #分配网络地址给MySQL服务注意同一个网络中不要冲突       ipv4_address: 172.1.0.2 ​   deploy:     resources:       limits:          # -m 1568M 内存限制         memory: 1568M    #容器健康检查   healthcheck:      #grep -v grep 是不显示grep查询这个进程      #test: ["CMD-SHELL", "ps -ef|grep mysqld|grep -v grep && exit 0|| exit 1"]      #下面是访问某个url,HTTP状态码(500、404、403 错误代码)会失败(200成功); exit 0 (健康)失败exit 1 (不健康)     test: ["CMD-SHELL", "curl -f http://localhost:8080 && exit 0 || exit 1"]      #间隔时间     interval: 30s      #超时时间     timeout: 10s      #重试次数     retries: 3      #初始化时间(启动时间)     start_period: 10s ​ ​ ​ ​ ​ ​案例四:bingpuversion: "3.8" ​ networks: bingpu-net: ​ services: mysql5732:   image: harbor.ifok.net:10202/ifok/mysql:5.7.32-Shanghai   container_name: mysql5732 # 等同于 --name mysql5732   hostname: mysql5732    #重启策略   restart: always #   ports: #     - "3306:3306" #等同于 -p 13306:3306 ​   networks:     bingpu-net:       aliases:         - mysql5732.server #等同于 --network-alias mysql5732.server   volumes:     - "/data/bingpu/mysql5732/data:/var/lib/mysql"     - "/data/bingpu/mysql5732/conf.d:/etc/mysql/conf.d" ​   environment:     - MYSQL_ROOT_PASSWORD=root ​   command: [      '--character-set-server=utf8mb4',      '--collation-server=utf8mb4_unicode_ci'    ] ​   deploy:     resources:       limits:         memory: 1024M ​ bingpu-web:   image: bingpu:1.0   build:     context: ./     dockerfile: Dockerfile   container_name: bingpu-web   hostname: bingpu-web   restart: always    #依赖的服务,配置好后会决定services的服务启动顺序   depends_on:     - mysql5732   ports:     - "8080:8080"   networks:     bingpu-net:       aliases:         - bingpu-web.server   volumes:     - "/data/bingpu/logs:/var/bingpu/logs"     - "/data/bingpu/file:/var/bingpu/file"   deploy:     resources:       limits:         memory: 512M案例五 webdavversion: "3.8"   networks: vRouter:  # 定义网络名:##因使用已经存在的网络,所以名称与已经存在的bridge网络名称相同   external: true ​ services: webdav:   image: harbor.ifok.net:10202/ifok/webdav:bytemark-2.4   container_name: webdav-2.4 # 等同于 --name webdav-2.4   hostname: webdav-2.4 #等同于 --webdav-2.4   restart: always #重启机制   ports:     - "7000:80"   networks:     vRouter:  #等同于 --network vRouter (注意这里的vRouter必须在顶层networks定义)       aliases:         - webdav.server #等同于 --network-alias webdav.server   volumes:     - "./data:/var/lib/dav"     - "../leftso/data/resources/assist:/var/lib/dav/data/leftso/assist"     - "../mysql/backup:/var/lib/dav/data/mysql/backup"   environment:     - AUTH_TYPE=Digest     - USERNAME=root     - PASSWORD=root   deploy:     resources:       limits:         memory: 150M
  • unknown flag: --iidfile docker-compose报错

    docker-compose 报错:[root@VM_0_17_centos gateway]# docker-compose up Building gatewayServer unknown flag: --iidfile See 'ddocker-compose 报错:[root@VM_0_17_centos gateway]# docker-compose up Building gatewayServer unknown flag: --iidfile See 'docker build --help'. ERROR: Service 'gatewayServer' failed to build : Build failed 解决办法:降低docker-compse版本当前版本为:[root@VM_0_17_centos gateway]# docker-compose -v docker-compose version 1.29.2, build 5becea4c降低至1.26.2即可[root@VM_0_17_centos gateway]# docker-compose -v docker-compose version 1.26.2, build eefe0d31docker-compose 下载快速网盘下载: (访问密码:9987)docker-compose-Linux-x86_64-1.26.2
  • Ubuntu 在线安装 Docker

    安装篇国外:curl -fsSL https://get.docker.com | bash国内:curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun卸载旧版本安装篇国外:curl -fsSL https://get.docker.com | bash国内:curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun卸载旧版本$ sudo apt-get remove docker docker-engine docker.io containerd runc
  • docker stack 多项目网络互通案例

    环境准备docker swarm 集群环境NFS服务资源文件docker-mutil-stack.zip(访问密码: 9987)1.创建overlay网络网络名称:stackMutilNetwork sudo docker network 环境准备docker swarm 集群环境NFS服务资源文件docker-mutil-stack.zip(访问密码: 9987)1.创建overlay网络网络名称:stackMutilNetwork sudo docker network create \   --driver overlay \   --subnet=172.168.0.0/24 \   --gateway=172.168.0.1 \   stackMutilNetwork 执行示例:创建overlay网络2.所有宿主机挂载共享目录sudo mount -t nfs 192.168.79.129:/nfs /share3.上传demo.jar 将demo.jar上传到共享目录/share/demo.jar4.部署stack服务4.1部署MySQLsudo docker stack deploy -c mysql.yml mysql 成功后,登录MySQL执行下面初始化数据SQLcreate table `user` (     id int primary key ,     `name` varchar(8) ); insert  into user(id,name)values (1,'张三');数据初始化4.2部署appsudo docker stack deploy -c app.yml app  4.3部署web  sudo docker stack deploy -c nginx.yml web5.浏览器调用服务测试浏览器访问ngin所在主机ip第一次访问第二次访问第三次访问可以看到每次访问的ip不同,通过overlay网络实现了负载均衡,默认好像是轮询6.部署信息查看docker stack部署信息6.运行日志查看 MySQL:MySQL运行日志查看 app:app console输出日志查看文件日志,通过文件方式直接查看web:web访问日志 可以看到测试点击访问时候的nginx的访问日志
  • docker 删除过期镜像<none>

    在执行多次docker-compose build 之后,我们通过命令`docker images`可以看到很多的REPOSITORY 为<none>l; 且tag 也是<none>l;的过期镜像docker 官方文档中被称作dangling im在执行多次docker-compose build 之后,我们通过命令`docker images`可以看到很多的REPOSITORY 为<none> 且tag 也是<none>的过期镜像docker 官方文档中被称作dangling images清理命令:docker image prunedocker image prune [OPTIONS]<选项>--all , -a Remove all unused images, not just dangling ones -----删除所有未使用的映像,而不仅仅是悬空映像--filter Provide filter values (e.g. ‘until=') -----提供过滤值(例如'until =“)--force , -f Do not prompt for confirmation -----不要提示确认
  • docker与docker-compose配置文件版本对应关系

    docker与docker-compose配置文件版本对应关系Compose file version 3 reference  Compose file formatDocker Engine releaseCompose specifidocker与docker-compose配置文件版本对应关系Compose file version 3 reference  Compose file formatDocker Engine releaseCompose specification19.03.0+3.819.03.0+3.718.06.0+3.618.02.0+3.517.12.0+3.417.09.0+3.317.06.0+3.217.04.0+3.11.13.1+3.01.13.0+2.417.12.0+2.317.06.0+2.21.13.0+2.11.12.0+2.01.10.0+ Compose file version 2 referenceCompose file formatDocker Engine releaseCompose specification19.03.0+3.819.03.0+3.718.06.0+3.618.02.0+3.517.12.0+3.417.09.0+3.317.06.0+3.217.04.0+3.11.13.1+3.01.13.0+2.417.12.0+2.317.06.0+2.21.13.0+2.11.12.0+2.01.10.0+参考: Compose file version 3 reference | Docker Documentation
  • windows 如何更改Docker镜像目录

    背景Windows版本(Windows 10)docker 默认程序安装到c盘,数据存放于 C:\Users\当前用户名\AppData\Local\Docker\wsl\data\ext4.vhdx 这样会导致docker使用量上去C盘的背景Windows版本(Windows 10)docker 默认程序安装到c盘,数据存放于 C:\Users\当前用户名\AppData\Local\Docker\wsl\data\ext4.vhdx 这样会导致docker使用量上去C盘的空间越来越大。为了解决这个问题我们一般习惯性将数据部分移动到其他盘。WSL 2 版本Docker切换盘位操作详细1.停止docker通过windows系统的界面操作停止​打开cmd窗口。查看停止情况:C:\Users\xqlee-mobile>wsl --list -v NAME                   STATE           VERSION * docker-desktop-data   Stopped         2 docker-desktop         Stopped         22.备份导出目前已有的数据C:\Users\xqlee-mobile>wsl --export docker-desktop-data "D:\Docker\wsl\data\docker-desktop-data.tar"命令说明:将目前已有的数据备份到D:\Docker\wsl\data\目录下,并命名为docker-desktop-data.tar3.删除原有数据C:\Users\xqlee-mobile>wsl --unregister docker-desktop-data 正在注销... 说明:解除当前的docker 数据虚拟盘映射,该操作后会删除原有的ext4.vhdx (数据未备份前请谨慎操作)4.导入数据到新盘C:\Users\xqlee-mobile>wsl --import docker-desktop-data "D:\Docker\wsl\data" "D:\Docker\wsl\data\docker-desktop-data.tar" --version 2说明:将备份数据导入到新的虚拟盘,且指定虚拟盘的存放路径为D:\Docker\wsl\data,导入完成后在该目录下会存在一个ext4.vhdx的虚拟磁盘路径5.启动Docker在开始菜单中找到docker点击启动即可最后备份的文件D:\Docker\wsl\data\docker-desktop-data.tar可根据情况删除 图像 小部件