关于dockerfile:docker-build-报错解决

问题应用jenkins构建我的项目时,docker build过程中报错 -t, --tag" flag: invalid reference format: repository name must be lowercase如图所示: 解决排查且也通过试验,呈现该问题的起因是docker镜像命名谬误,存在大写字母 解决将镜像名全副改为小写 well-history-web 就能够了

June 6, 2023 · 1 min · jiezi

关于dockerfile:使用Dockerfile部署项目

应用Dockerfile部署我的项目以Nginx部署我的项目为例Docker装置及Docker公有仓库部署流程 Harbor在arm架构下亲测编译胜利 Linux装置Harbor亲测胜利功 制作根底镜像以公有仓库192.168.1.182:5000/centos为根底镜像,构建一个nginx根底镜像,其余环境都依赖这个根底镜像做出相应镜像 留神:dockerfile外面的装置命令尽量在一行实现,最初删除不必要的组件,以放大体积,放慢启动速度 cat Dockerfile-base ############################################# version : nginx-withssl-v1# desc : 装置nginx-1.10.2.tar.gz############################################# 设置继承镜像FROM 192.168.1.182:5000/centos# 上面是一些创建者的根本信息MAINTAINER liang "liang@xxx.com"# 设置环境变量ENV NGINX_VERSION 1.10.2 20220224RUN mkdir -p /data/apps/nginx-main && mkdir -p /data/logs/nginx-main && mkdir -p /data/temps/nginx-mainRUN yum -y install make wget zlib zlib-devel gcc-c++ libtool openssl openssl-devel && \ mkdir -p /data/software && \ cd /data/software && \ wget http://downloads.sourceforge.net/project/pcre/pcre/8.35/pcre-8.35.tar.gz && \ tar zxvf pcre-8.35.tar.gz && \ cd pcre-8.35 && \ ./configure && \ make && make install && \ pcre-config --version && \ wget -O /data/software/nginx-1.10.2.tar.gz http://nginx.org/download/nginx-1.10.2.tar.gz && \ cd /data/software && \ tar -zxvf nginx-1.10.2.tar.gz && \ cd /data/software/nginx-1.10.2 && \ ./configure --prefix=/data/apps/nginx-main \ --pid-path=/data/logs/nginx-main/nginx.pid \ --lock-path=/data/apps/nginx-main/nginx.lock \ --error-log-path=/data/logs/nginx-main/error.log \ --http-log-path=/data/logs/nginx-main/access.log \ --http-client-body-temp-path=/data/temps/nginx-main/client_body_temp \ --http-proxy-temp-path=/data/temps/nginx-main/proxy_temp \ --http-fastcgi-temp-path=/data/temps/nginx-main/fastcgi_temp \ --http-uwsgi-temp-path=/data/temps/nginx-main/uwsgi_temp \ --http-scgi-temp-path=/data/temps/nginx-main/scgi_temp \ --with-http_stub_status_module \ --with-http_ssl_module \ --with-http_realip_module \ --with-pcre=/data/software/pcre-8.35 && \ make && \ make install && \ rm -rf /pcre-8.35.tar.gz /nginx-1.10.2.tar.gz /pcre-8.35 /nginx-1.10.2 && \ yum -y remove wget git gcc-c++ libtool openssl-devel zlib-devel && \ yum clean allEXPOSE 443 80创立nginxbase 镜像$ docker build -f Dockerfile-base -t 192.168.1.182:5000/nginx-main-base .$ docker push 192.168.1.182:5000/nginx-main-base比方开发环境或者测试环境须要搭建nginx, 以nginx-main-base为根底镜像 ...

December 20, 2022 · 2 min · jiezi

关于dockerfile:Dockerfile的初次使用

什么是dockerfileDockerfile的作用与docker-compose相似,也同样是为了配置环境而存在的,那么docker-file有什么非凡之dockerFile官网文档处呢? 就目前所知,docker-compose咱们在应用时需配置image项也就是咱们须要的环境项例如咱们须要mysql环境就配置为mysql:XXX,其余同理。 咱们想要配置什么样的环境就须要在docker-hub官网网址中寻找相应的配置项,并按其示例进行配置,换句话说如果咱们所需的环境在docker-hub官网网址中不存在咱们就不能只应用docker-compose来进行配置。 比方咱们想要一键配置好运行angular单元测试的环境,咱们就无奈在docker-hub官网网址中找到对应的环境。 这时候咱们就须要本人配置镜像(image)通过Dockerfile并上传到阿里云-容器镜像服务中,从而能够在近程间接通过其公网地址加版本号(例:registry.cn-beijing.aliyuncs.com/mengyunzhi_li/node_ding_push:14.16.2)进行调用咱们自定义的image。 如何编写简略的dockerfile明确了dockerfile的性能,下一步就是要理解dockerfile如何编写dockerFile官网文档首先咱们要晓得一些根底指令1: FROM:用于指定根底镜像,在咱们自定义的镜像须要以某个镜像为根底时进行配置 例如: FROM node:14.16.0-stretch2:RUN:有多种应用形式,集体了解为在image构建时执行的命令 例如:RUN "command" "param1" "param2"留神:构建时执行指在拉取环境到本地创立容器时不会执行,因为image早曾经在阿里云镜像服务中构建完了。 3:CMD:与RUN相似,区别是其中的命令会在启动容器时执行 例如:CMD "command" "param1" "param2"留神:1、CMD在Dockerfile中只能呈现一次,有多个,只有最初一个会无效。2、其作用是在启动容器的时候提供一个默认的命令项。如果用户执行docker run的时候提供了命令项,就会笼罩掉这个命令。没提供就会应用构建时的命令。 4:COPY:复制本机文件或目录或近程文件,增加到指定的容器目录 COPY ./send-ding.sh /注:下面咱们将本地的send-ding.sh上传到了容器中,这使得咱们能够在dockerFile容器中调用此脚本docker --Dockerfile --send-ding.sh 理论问题上面我的指标是创立一个image,能够让它在被调用时主动执行指定脚本。 FROM node:14.16.0-stretchRUN apt-get updateRUN apt install -y curlRUN apt-get cleanCOPY ./send-ding.sh /RUN sh send-ding.sh -a 1ab5179dd94ed62de026d96ba61b41b1dda42357fdf79a787f11c7708449a06d -t markdown -c pipeine运行失败 -T "tiT,,le"CMD ["sh", "send-ding.sh", "-a","1ab5179dd94ed62de026d96ba61b41b1dda42357fdf79a787f11c7708449a06d", "-t", "markdown", "-c", "pipeine运行失败", "-T", "'tiT,,le'"]注:RUN 和 CMD后的指令为两种模式,理论应用时都能够 本地测试1、本地创立image sudo docker build . -t=ding-file:1.22、查看咱们创立的image sudo docker image ls3、依据image创立容器 ...

September 4, 2022 · 1 min · jiezi

关于dockerfile:如何通过Dockerfile优化Nestjs构建镜像大小

原文开始这是一篇手把手的教程,教你如何在制作nestjs镜像时,可能编写出一个优化生产依赖的Dockerfile有了这个Dockerfile,无论是在本地开发环境,还是在容器环境都能很轻松实现部署P.S 如果你想间接复制最终的Dockerfile,请间接跳到文章开端开始编写Dockerfile每个镜像都能够视为一个独自的软件包,你能够通过编写Dockerfile通知docker如何来打包镜像让咱们开始编写吧,首先,先创立一个空的文件touch Dockerfile复制代码而后把咱们的指令增加到Dockerfile外面,并且正文每一步是干什么 根底镜像FROM node:18 创立一个利用目录WORKDIR /usr/src/app 这个星号通配符意思是复制package.json和package-lock.json,复制到以后利用目录COPY package*.json ./ 装置利用依赖RUN npm install 装置结束后复制当前目录所有文件到镜像目录外面COPY . . 执行npm run build 后生成dist目录RUN npm run build 应用打包后的镜像CMD ["node","dist/main.js"]复制代码同样的,创立.gitignore文件,咱们能够把那些不须要通过docker打包的文件给疏忽掉touch .dockerignore复制代码把一下文件给排除疏忽掉Dockerfile.dockerignorenode_modulesnpm-debug.logdist复制代码在本地测试下如果你在本地装置了docker,能够在本地进行打包测试,让咱们来瞧瞧是否如预期中那样打包镜像在命令行中执行以下命令,当然,你也能够把nest-app-demo换成你想要的镜像名,须要留神的是,不要遗记前面的.号!docker build -t nest-app-demo .复制代码接着你能够在你本机执行以下命令,查看是否曾经胜利打包了镜像docker images复制代码噢,感谢上帝,曾经胜利打包成镜像了,能够看到咱们的命名nest-app-demo就像只肥硕的土拨鼠静静的躺在镜像列表外面docker imagesREPOSITORY TAG IMAGE ID CREATED SIZEnest-app-demo latest 004f7f222139 31 seconds ago 1.24GB 复制代码紧接着让咱们来把镜像给跑起来,映射到本机80端口,如果端口被占用能够应用其余端口docker run -p 80:3000 nest-app-demo复制代码这时候你就在浏览器中输出http://localhost进行拜访,能够看到容器失常启动。如果你想删除那些正在运行的容器,能够应用以下命令进行删除docker rm -f $(docker ps -aq)复制代码Dockerfile 生产环境优化好了,当初咱们对镜像包进行压缩了,因为能够看到,目前镜像大小是1.24G,噢,上帝,真是太大了!让咱们来看看之前编写的Dockerfile,看如何对它进行优化应用Alpine node镜像强烈推荐应用node:18-alpine 而不是node:18,应用alpine的镜像能够间接把镜像体积从1.24g缩小到466MB!增加 NODE_ENV 环境变量很多依赖包会依据以后的NODE_ENV环境变量而进行判断是否优化压缩,所以咱们能够在Dockerfile外面把环境变量加进去,设置为productionENV NODE_ENV production复制代码顺便提一句,如果你不晓得如何在Nestjs外面通过配置文件进行环境变量设置的话,能够看下这篇入门文章www.tomray.dev/nestjs-conf…应用npm ci 而不是npm installnpm 比拟举荐应用npm ci 而不是npm install 来打包镜像,至于起因能够点击这里查看docs.npmjs.com/cli/v8/comm… "npm ci与npm install很类似,除了当它用于自动化时,如测试平台,继续集成和部署————或者任何你想确保能有一个洁净的依赖装置环境" ...

August 17, 2022 · 1 min · jiezi

关于dockerfile:Dockfile-学习

前言好忘性不如烂笔头,边学边记,学完根底语法后,起码你能看得懂一个 Dockfile 干了哪些事儿。折腾起来。 作用Dockfile 是一个用来构建镜像的文本文件,在一个我的项目中如果有此文件,语法正确,就能够应用命令(docker build -t name:tag .)来构建一个镜像了. 1.FROM语法: FROM <image>eg: FROM node:14.17.0 // 指定node 14.17.0 版本解释: 指定一个构建镜像的根底源镜像,如果本地没有就会从公共仓库中拉取,没有指定镜像的标签会应用默认的latest 标签。 必须有。 2.WORKDIR语法: WORKDIR <工作目录门路>eg: WORKDIR /usr/src/app解释:指定工作目录。用 WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在。(WORKDIR 指定的工作目录,必须是提前创立好的)。 docker build 构建镜像过程中的,每一个 RUN 命令都是新建的一层。只有通过 WORKDIR 创立的目录才会始终存在。 3.MAINTAINER语法: MATAINER <name> <email>eg: MATAINER test test@163解释:形容镜像的创建者,名称和邮箱。不是必须的。 4.RUN用法: RUN "command" "param1" "param2"eg: RUN yarn install形容:运行一个命令,比方依赖的装置,脚本的执行等。RUN 命令能够有多个,然而能够用 && 连贯多个命令来缩小层级。例如 RUN npm install && cd /app && mkdir logs留神: Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像收缩过大。所以多个 RUN 能够应用 && 连贯。 ...

July 11, 2022 · 2 min · jiezi

关于dockerfile:N个技巧编写更高效-Dockerfile|云效工程师指北

大家好,我是陈泽锋,我在云效负责Flow流水线编排、任务调度引擎相干的工作。在云效的产品体系下,咱们服务了各种研发规模、技术深度的的企业用户,收到了十分多的用户反馈。对于应用 Flow 进行云上构建的用户来说,构建速度是大家广泛关怀的要害因素,在深入分析用户案例的过程中,咱们发现了许多通用问题,只须要批改优化本人的我的项目或工程配置,就能够大大晋升构建的性能,从而进一步减速 CICD 的效率。明天咱们会以容器镜像构建作为切入点,总结一些在理论工程中,十分实用的优化技巧。 云原生时代下软件的构建和部署离不开容器技术。提到容器,简直大家下意识都会联想到 Docker 。而 Docker 中有两个十分重要的概念,一个是Image(镜像),一个是Container(容器)。前者是一个动态视图,打包了利用的目录构造、运行环境等;后者是一个动静视图(过程),展现的是程序的运行状态(cpu、memory、storage)等信息。接下来的文章次要分享的是如何编写能使 Dockerfile 构建过程更疾速、构建镜像更小的技巧。 镜像定义首先咱们先来理解一下 Docker 镜像,它由多个只读层重叠到一起,每一层是上一层的增量批改。基于镜像创立新容器时,将在根底层的顶部增加一个新的可写层。该层通常称为“容器层”。下图展现了一个基于 docker.io/centos 根底镜像构建的利用镜像,创立出容器时的视图。 从图中咱们能够看到镜像构建、容器启动的过程。 首先是拉取根底镜像 docker.io/centos;基于 docker.io/centos 来启动一个容器,运行指令 yum update 后进行 docker commit 提交出一个新的只读层 v1(能够了解为生成了一个新的长期镜像 A,只不过用户并不会间接援用到它);基于长期镜像A启动新的容器,运行装置和配置 http server等软件后,提交出一个新的只读层 v2,也生成了这里最终被开发者援用的镜像版本 B;基于镜像版本B运行的容器,会再追加一层读写层(对容器的文件创建、批改、删除等操作,都在这一层失效);镜像起源镜像次要是 Docker 通过读取、运行 Dockerfile 的指令来生成。举官网上的一个 Dockerfile 例子: FROM ubuntu:18.04COPY . /appRUN make /appCMD python /app/app.py它的外围逻辑是定义援用的根底镜像 base image,执行如 COPY 指令从上下文 context 里复制文件到容器中,运行 RUN 执行用户自定义构建脚本,最初定义容器启动的 CMD 或 ENTRYPOINT。构建更高效的镜像也要围绕上述波及到的概念进行优化。 Dockerfile 优化技巧应用国内的根底镜像Flow 作为云上构建产品,每次构建都会给用户提供全新的构建环境,以防止环境污染导致带来过高运维老本。正因为如此,Flow 每次构建都会从新去下载 Dockerfile 中指定的根底镜像。 如果 Dockerfile 中指定根底镜像来源于 Docker Hub,则有可能因为网络延时问题导致下载迟缓,比方: ...

January 26, 2022 · 3 min · jiezi

关于dockerfile:docker进入容器失败Docker-OCI-runtime-exec-failed-exec-fail

进入容器报错: Docker OCI runtime exec failed: exec failed: container_linux.go:344: starting container process caus解决办法: docker exec -it 1e33b26152e1 /bin/sh或docker exec -it 1e33b26152e1 bash或docker exec -it 1e33b26152e1 sh

January 5, 2022 · 1 min · jiezi

关于dockerfile:基于Debian构建自定义的nginx镜像-Dockerfile模板

根底镜像 : debian:buster-slimnginx : 1.16.1nginx tar包自行网上下载# 第一行先定义根底镜像,示意以后镜像文件是基于哪个进行编辑的.FROM debian:buster-slim# 指定镜像维护者的信息.MAINTAINER @Owen 975706304@qq.com# 先备份原源配置文件RUN cp /etc/apt/sources.list /etc/apt/sources.list.bak# 而后将debian的apt源改成中科大源RUN sed -i 's/deb.debian.org/mirrors.ustc.edu.cn/g' /etc/apt/sources.listRUN sed -i 's|security.debian.org/debian-security|mirrors.ustc.edu.cn/debian-security|g' /etc/apt/sources.listRUN apt clean && apt update -y# 初始版的nginx须要的依赖:gcc zlib1g zlib1g-dev openssl libssl-dev libpcre3 libpcre3-dev# libgd-dev和libexif-dev为ngx_http_image_filter_module须要的依赖RUN apt -y install gccRUN apt -y install zlib1g zlib1g-devRUN apt -y install openssl libssl-devRUN apt -y install libpcre3 libpcre3-devRUN apt -y install libgd-devRUN apt -y install libexif-devRUN apt -y install make# 将dockerfile上下文目录中的ngx_http_image_filter_module.tar.gz文件拷贝进容器根目录并解压COPY ngx_http_image_filter_module.tar.gz /ngx_http_image_filter_module.tar.gzRUN tar zxf ngx_http_image_filter_module.tar.gz# 将dockerfile上下文目录中的nginx-1.16.1.tar.gz文件拷贝进容器根目录并解压COPY nginx-1.16.1.tar.gz /nginx-1.16.1.tar.gzRUN tar zxf nginx-1.16.1.tar.gz# 创立nginx用户,yum形式装置无需做此步骤,因为默认yum装置会主动创立nginx用户# 咱们上面命令以nginx用户运行,因而咱们须要在容器中创立nginx用户# -M(不创立主目录) -s(不容许登录)RUN useradd -M -s /sbin/nologin nginx# 切换至nginx目录WORKDIR /nginx-1.16.1# 编译装置nginx# --with-http_stub_status_module -> Nginx性能统计模块# --with-http_ssl_module -> ssl加密模块# --add-module=/ngx_http_image_filter_module -> 图片裁剪模块RUN ./configure \--prefix=/usr/local/nginx \--user=nginx \--group=nginx \--sbin-path=/usr/local/nginx/sbin/nginx \--modules-path=/usr/local/nginx/modules \--conf-path=/usr/local/nginx/conf/nginx.conf \--error-log-path=/usr/local/nginx/logs/error.log \--http-log-path=/usr/local/nginx/logs/access.log \--pid-path=/usr/local/nginx/logs/nginx.pid \--lock-path=/usr/local/nginx/logs/nginx.lock \--with-http_stub_status_module \--with-http_ssl_module \--add-module=/ngx_http_image_filter_moduleRUN make && make install# 将access.log日志重定向到docker的规范输入# 将error.log日志重定向到docker的规范谬误,这样docker logs 的时候就能够看到日志了# ln -sf a b 示意 b链接向aRUN ln -sf /dev/stdout /usr/local/nginx/logs/access.log && ln -sf /dev/stderr /usr/local/nginx/logs/error.logRUN mkdir -p /usr/local/nginx/conf.dWORKDIR /# 删除装置应用的文件和文件夹RUN rm -rf ngx_http_image_filter_module.tar.gzRUN rm -rf nginx-1.16.1.tar.gzRUN rm -rf ngx_http_image_filter_moduleRUN rm -rf nginx-1.16.1# 定义向外裸露的端口号,多个端口用空格做距离,启动容器时便于应用-p将此端口向宿主机端口映射EXPOSE 80/tcp 443/tcp# 解释 -> '-g' 'daemon off'# nginx默认是当前台模式启动的,Docker未执行自定义的CMD之前,nginx的pid是1,# 执行到CMD之后,nginx就在后盾运行,bash或sh脚本的pid变成了1,# 所以一旦执行完自定义CMD,nginx容器也就退出了,为了放弃nginx的容器不退出,应该敞开nginx后盾运行CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]

September 24, 2021 · 1 min · jiezi

关于dockerfile:dockerfile多阶段构建

FROM openresty/openresty:1.13.6.2-2-centosARG RESTY_YUM_REPO="http://mirrors.aliyun.com/repo/Centos-7.repo"ARG WORK_DIR="/usr/local/openresty/nginx"ARG USER=rootRUN sed -i 's/plugins=1/plugins=0/' /etc/yum.confRUN sed -i 's/enabled=1/enabled=0/' /etc/yum/pluginconf.d/fastestmirror.confRUN rm -rf /etc/yum.repos.d/CentOS*RUN yum clean all && yum-config-manager --add-repo ${RESTY_YUM_REPO} && yum makecache && rpm --rebuilddb && yum install -y vim net-tools iproute && yum groupinstall -y 'Development Tools'RUN luarocks --tree=${WORK_DIR}/luarocks install lua-cjson && luarocks --tree=${WORK_DIR}/luarocks install penlight && luarocks --tree=${WORK_DIR}/luarocks install version && luarocks --tree=${WORK_DIR}/luarocks install lua-resty-http && luarocks --tree=${WORK_DIR}/luarocks install luaunit && luarocks --tree=${WORK_DIR}/luarocks install ldoc && luarocks --tree=${WORK_DIR}/luarocks install lua-discount && luarocks --tree=${WORK_DIR}/luarocks install serpent && luarocks --tree=${WORK_DIR}/luarocks install luacov && luarocks --tree=${WORK_DIR}/luarocks install cluacov && luarocks --tree=${WORK_DIR}/luarocks install mmdblua && luarocks --tree=${WORK_DIR}/luarocks install lua-resty-jit-uuid && luarocks --tree=${WORK_DIR}/luarocks install luasocket FROM openresty/openresty:1.13.6.2-2-centosARG WORK_DIR="/usr/local/openresty/nginx"ARG USER=rootCOPY --from=0 ${WORK_DIR}/luarocks ${WORK_DIR}/luarocksENV LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${WORK_DIR}/c_libADD nginx/lib ${WORK_DIR}/libADD nginx/c_lib ${WORK_DIR}/c_libADD bin/go-dnsmasq /usr/local/bin/go-dnsmasqADD nginx/conf/nginx.conf.template ${WORK_DIR}/conf/nginx.conf.templateADD nginx/conf/vhosts ${WORK_DIR}/conf/vhostsADD nginx/lua ${WORK_DIR}/luaWORKDIR ${WORK_DIR}ADD entrypoint.sh /entrypoint.shENTRYPOINT /entrypoint.sh

April 6, 2021 · 1 min · jiezi

关于dockerfile:dockerDockerfile-创建镜像

Dockerfile <code>### base imagesFROM node:10.15-alpine# Create docker /home/nodejs directory, and run command in this pathWORKDIR /home/nodejs# Install app dependencies# copy local directory to docker /home/nodejs directoryCOPY . /home/nodejs# Install node dependencies from /home/nodejs/package.jsonRUN npm install# If you are building your code for production# RUN npm ci --only=production# expose the portEXPOSE 8080# docker start commandCMD [ "node", “index.js" ]</code>

February 23, 2021 · 1 min · jiezi

关于dockerfile:E-Some-index-files-failed-to-download-They-have-been

问题形容:当应用Dockerfile从蕴含cuda的镜像建设新的image的时候,显示以下bug: Step 7/8 : RUN apt-get update && DEBIAN_FRONTEND="noninteractive" apt-get install -y -q libcudnn6=$CUDNN_VERSION-1+cuda8.0 libcudnn6-dev=$CUDNN_VERSION-1+cuda8.0 && rm -rf /var/lib/apt/lists/* ---> Running in 94b890e74e5aGet:1 http://security.ubuntu.com/ubuntu xenial-security InRelease [102 kB]Ign:2 http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64 InReleaseGet:3 http://archive.ubuntu.com/ubuntu xenial InRelease [247 kB]Ign:4 http://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1604/x86_64 InReleaseGet:5 http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64 Release [564 B]Get:6 http://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1604/x86_64 Release [564 B]Get:7 http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64 Release.gpg [801 B]Get:8 http://security.ubuntu.com/ubuntu xenial-security/universe Sources [73.2 kB]Get:9 http://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1604/x86_64 Release.gpg [801 B]Get:10 http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64 Packages [98.4 kB]Get:11 http://security.ubuntu.com/ubuntu xenial-security/main amd64 Packages [589 kB]Get:12 http://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1604/x86_64 Packages [17.9 kB]Err:12 http://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1604/x86_64 Packages Hash Sum mismatchGet:13 http://archive.ubuntu.com/ubuntu xenial-updates InRelease [102 kB]Get:14 http://archive.ubuntu.com/ubuntu xenial-backports InRelease [102 kB]Get:15 http://archive.ubuntu.com/ubuntu xenial/universe Sources [9,802 kB]Get:16 http://security.ubuntu.com/ubuntu xenial-security/restricted amd64 Packages [12.7 kB]Get:17 http://security.ubuntu.com/ubuntu xenial-security/universe amd64 Packages [406 kB]Get:18 http://security.ubuntu.com/ubuntu xenial-security/multiverse amd64 Packages [3,486 B]Get:19 http://archive.ubuntu.com/ubuntu xenial/main amd64 Packages [1,558 kB]Get:20 http://archive.ubuntu.com/ubuntu xenial/restricted amd64 Packages [14.1 kB]Get:21 http://archive.ubuntu.com/ubuntu xenial/universe amd64 Packages [9,827 kB]Get:22 http://archive.ubuntu.com/ubuntu xenial/multiverse amd64 Packages [176 kB]Get:23 http://archive.ubuntu.com/ubuntu xenial-updates/universe Sources [242 kB]Get:24 http://archive.ubuntu.com/ubuntu xenial-updates/main amd64 Packages [957 kB]Get:25 http://archive.ubuntu.com/ubuntu xenial-updates/restricted amd64 Packages [13.1 kB]Get:26 http://archive.ubuntu.com/ubuntu xenial-updates/universe amd64 Packages [766 kB]Get:27 http://archive.ubuntu.com/ubuntu xenial-updates/multiverse amd64 Packages [18.5 kB]Get:28 http://archive.ubuntu.com/ubuntu xenial-backports/main amd64 Packages [5,153 B]Get:29 http://archive.ubuntu.com/ubuntu xenial-backports/universe amd64 Packages [7,705 B]Fetched 25.1 MB in 9s (2,576 kB/s)Reading package lists...E: Failed to fetch http://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1604/x86_64/Packages.gz Hash Sum mismatchE: Some index files failed to download. They have been ignored, or old ones used instead.解决方案在Dockerfile 运行这行代码 ...

December 7, 2020 · 2 min · jiezi

关于dockerfile:超级小白超级简单之springboot项目打包成docker镜像并且运行

筹备工作一个打包好的我的项目jar包一个编写好的Dockerfile文件当然打包成docker环境就必须有一个docker环境了,这里我的docker环境是放在centos中的我的项目打jar包这里我用的是idea,所以我这里说idea的我的项目打包办法在 mvn clean package # 应用Maven打包我的项目这里我打好的jar包被我重命名为gclient.jar 编写Dockerfile文件这里我是这样编写的 # 基于哪个镜像,须要用一个已有的镜像做载体来创立,这里我应用的java8镜像,如果大家的docker镜像中没有java8,它就会主动去下载FROM java:8# 将本地文件夹挂载到以后容器,指定/tmp目录并长久化到Docker数据文件夹,因为Spring Boot应用的内嵌Tomcat容器默认应用/tmp作为工作目录VOLUME /tmp# 增加本人的我的项目到 app.jar中 这里我是取了app.jar的名字,这个名字能够轻易取的,只有前面几行名字和这个对立就好了ADD gclient.jar app.jar# 这一行我还是不太分明啥意思 等我懂了我再补上RUN bash -c 'touch /app.jar'# 凋谢8761端口EXPOSE 8761# ENTRYPOINT指定容器运行后默认执行的命令ENTRYPOINT ["java","-jar","/app.jar"]#"-Djava.security.egd=file:/dev/./urandom" 这个我不晓得是啥意思,这里我就去掉了好Dockerfile编写也实现了 把Dockerfile和gclient.jar放在同一个目录上面这里我把这两个文件都放在了我的虚拟机上面的rpa文件夹下 创立镜像在这个目录下运行命令 docker build -t gclient .这里留神,gclient只是我要起的一个名字,大家创立的时候名字能够轻易写的好吧,下面的.我没有写错啊和创立的镜像的名字有一个空格的间隔。创立好的截图如上 运行容器下面的Dockerfile中我写了我要凋谢的端口8761,然而我这个我的项目启动的时候要拜访8080端口,所以我要运行这个容器就要这样写 docker run -p 8761:8080 gclient启动胜利

August 26, 2020 · 1 min · jiezi

Docker的安装和命令使用

虚拟化技术虚拟化技术是对软件基础设施、操作系统、软件等IT资源进行有效的管理,使用户不再受物理资源的限制,提高计算机资源的利用率。虚拟化技术是云计算的基础,例如阿里云的云主机、腾讯云等都应用了虚拟化技术。虚拟化技术整体上包括两个方面:硬件虚拟化和软件虚拟化,具体分为:网络虚拟化、存储虚拟化、桌面虚拟化、服务器虚拟化等,我们平常说的最多的是服务器虚拟化。服务器虚拟化就是在同一个物理服务器上运行多个虚拟机,让服务器的cpu、内存、磁盘、I/O等硬件设施为每个虚拟机服务,在每个虚拟机中运行不同的软件,虚拟机之间是隔离状态。 服务器虚拟化主要有两种技术:1、Hypervisor也叫VMM(virtual machine monitor)即虚拟机监视器Hypervisor是一种将操作系统与硬件抽象分离的方法,实现在宿主机(host machine)上能同时运行多个客户机(guest machine),每个客户机就是一个虚拟机,这些虚拟机高效地分享宿主机的硬件资源。在服务器(宿主机)上安装操作系统,并安装hypervisor虚拟机管理软件,如VMware、VirtualBox等,由hypervisor管理多个虚拟机,每个虚拟机上需要安装客户操作系统、依赖库、应用软件。 容器化技术容器技术中docker引擎取代了hypervisor,docker引擎是运行在住宿操作系统上的一个进程,该进程管理了多个docker容器,每个docker容器集成了应用软件、依赖库,容器之间相互隔离。 技术对比: 资源占用:虚拟机由于是独立的操作系统,占用资源比docker多。启动速度:虚拟机包括操作系统,启动虚拟机相当于启动一个操作系统,容器则不一样,容器中只包括操作系统的内核,启动一个容器实例相当于启动一个进程,容器的启动速度比虚拟机快。体积:容器包括操作系统内核、软件及依赖库,虚拟机不仅包括软件和依赖库还将完整的操作系统打包进去,虚拟机的体积比容器大的多。docker简介Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从Apache2.0协议开源。Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。 1、Docker daemon(Docker守护进程): Docker守护进程是部署在操作系统上,负责支撑Docker Container的运行以及本地Image的管理。2、Docker client: 用户不直接操作Docker daemon,用户通过Docker client访问Docker,Docker client提供pull、run等操作命令。3、Docker Image: Docker 镜像就是一个只读的模板。 例如:一个镜像可以包含一个完整的 ubuntu 操作系统环境,里面仅安装了 Tomcat或用户需要的其它应用程序。 镜像可以用来创建 Docker 容器。 Docker 提供了一个很简单的机制来创建镜像或者更新现有的镜像,用户甚至可以直接从其他人那里下载一个已经做好的镜像来直接使用。4、Docker Container: Docker 利用容器来运行应用。容器是从镜像创建的运行实例。它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台。打个比方,镜像相当于类,容器相当于对象。5、Docker Registry: Docker 仓库分为公开仓库(Public)和私有仓库(Private)两种形式 最大的公开仓库是Docker Hub,存放了数量庞大的镜像供用户下载。 用户也可以在本地网络内创建一个私有仓库。 当用户创建了自己的镜像之后就可以使用 push 命令将它上传到公有或者私有仓库,这样下次在另外一台机器上使用这个镜像时候,只需要从仓库上 pull 下来就可以了。docker安装Docker可以运行MAC、Windows、Centos、DEBIAN、UBUNTU等操作系统上,提供社区版和企业版,基于Centos安装Docker。Centos6对docker支持的不好,使用docker建议升级到centos7。 1、在Centos7上安装Docker,直接通过yum安装即可: yum install -y docker完成后查看docker版本:docker info 或docker -v 启动docker:systemctl start docker 常用命令使用1.镜像仓库1)docker pull : 从镜像仓库中拉取或者更新指定镜像 ...

October 17, 2019 · 2 min · jiezi

Docker入门学习

docker简介1.什么是虚拟化在计算机中,虚拟化(英语:Virtualization)是一种资源管理技术,是将计算机的各种实体资源,如服务器、网络、内存及存储等,予以抽象、转换后呈现出来,打破实体结构间的不可切割的障碍,使用户可以比原本的组态更好的方式来应用这些资源。这些资源的新虚拟部份是不受现有资源的架设方式,地域或物理组态所限制。一般所指的虚拟化资源包括计算能力和资料存储。在实际的生产环境中,虚拟化技术主要用来解决高性能的物理硬件产能过剩和老的旧的硬件产能过低的重组重用,透明化底层物理硬件,从而最大化的利用物理硬件对资源充分利用虚拟化技术种类很多,例如:软件虚拟化、硬件虚化、内存虚拟化、网络虚拟化(vip)、桌面虚拟化、服务虚拟化、虚拟机等等。 2.什么是Docker Docker是一个开源项目,诞生于2013年初,最初是dotCloud公司内部的一个业余项目。它基于Google公司推出的Go语言实现。项目后来加入了Linux基金会,遵从了Apache2.0协议,项目代码在GitHub上进行维护。 Docker自开源后受到广泛的关注和讨论,以至于dotCloud公司后来都改名为Docker Inc。Redhat已经在其RHEL6.5中集中支持Docker;Google也在其PaaS产品中广泛应用。Docker项目的目标是实现轻量级的操作系统虚拟化解决方案。Docker的基础是Linux容器(LXC)等技术。在LXC的基础上Docker进行了进一步的封装,让用户不需要去关心容器的管理,使得操作更为简便。用户操作Docker的容器就像操作一个快速轻量级的虚拟机一样简单。 3.为什么选择Docker?1)上手快用户只需要几分钟,就可以把自己的程序“Docker化”。Docker依赖于“写时复制”(copy:on-write)54681模型,使修改应用程序也非常迅速,可以说达到“随心所致,代码即改”的境界。随后,就可以创建容器来运行应用程序了。大多数Docker容器只需要不到1秒中即可启动。由于去除了管理程序的开销,Docker容器拥有很高的性能,同时同一台宿主机中也可以运行更多的容器,使用户尽可能的充分利用系统资源。2)职责的逻辑分类使用Docker,开发人员只需要关心容器中运行的应用程序,而运维人员只需要关心如何管理容器。Docker设计的目的就是要加强开发人员写代码的开发环境与应用程序要部署的生产环境一致性。从而降低那种“开发时一切正常,肯定是运维的问题(测试环境都是正常的,上线后出了问题就归结为肯定是运维的问题)”3)快速高效的开发生命周期Docker的目标之一就是缩短代码从开发、测试到部署、上线运行的周期,让你的应用程序具备可移植性,易于构建,并易于协作。(通俗一点说,Docker就像一个盒子,里面可以装很多物件,如果需要这些物件的可以直接将该大盒子拿走,而不需要从该盒子中一件件的取。)4)鼓励使用面向服务的架构Docker还鼓励面向服务的体系结构和微服务架构。Docker推荐单个容器只运行一个应用程序或进程,这样就形成了一个分布式的应用程序模型,在这种模型下,应用程序或者服务都可以表示为一系列内部互联的容器,从而使分布式部署应用程序,扩展或调试应用程序都变得非常简单,同时也提高了程序的内省性。(当然,可以在一个容器中运行多个应用程序) 4.容器与虚拟机比较下面的图片比较了Docker和传统虚拟化方式的不同之处,可见容器是在操作系统层面上实现虚拟化,直接复用本地主机的操作系统,而传统方式则是在硬件层面实现。与传统的虚拟机相比,Docker优势体现为启动速度快、占用体积小。 5.Docker服务器与客户端Docker是一个客户端-服务器(C/S)架构程序。Docker客户端只需要向Docker服务器或者守护进程发出请求,服务器或者守护进程将完成所有工作并返回结果。Docker提供了一个命令行工具Docker以及一整套RESTfulAPl。你可以在同一台宿主机上运行Docker守护进程和客户端,也可以从本地的Docker客户端连接到运行在另一台宿主机上的远程Docker守护进程。 6.Docker镜像与容器镜像是构建Docker的基石。用户基于镜像来运行自己的容器。镜像也是Docker生命周期中的构建”部分。镜像是基于联合文件系统的一种层式结构,由一系列指令一步一步构建出来。例如:执行一个命令;打开一个窗口。也可以将镜像当作容器的“源代码”。镜像体积很小,非常“便携”,易于分享、存储和更新。 Docker可以帮助你构建和部署容器,你只需要把自己的应用程序或者服务打包放进容器即可。容器是基于镜像启动起来的,容器中可以运行一个或多个进程。我们可以认为,镜像是Docker生命周期中的构建或者打包阶段,而容器则是启动或者执行阶段。容器基于镜像启动,一旦容器启动完成后,我们就可以登录到容器中安装自己需要的软件或者服务。所以Docker容器就是:一个镜像格式;一些列标准操作;一个执行环境。 Docker借鉴了标准集装箱的概念。标准集装箱将货物运往世界各地,Docker将这个模型运用到自己的设计中,唯一不同的是:集装箱运输货物,而Docker运输软件。和集装箱一样,Docker在执行上述操作时,并不关心容器中到底装了什么,它不管是web服务器,还是数据库,或者是应用程序服务器什么的。所有的容器都按照相同的方式将内容“装载”进去。Docker也不关心你要把容器运到何方:我们可以在自己的笔记本中构建容器,上传到Registry,然后下载到一个物理的或者虚拟的服务器来测试,在把容器部署到具体的主机中。像标准集装箱一样,Docker容器方便替换,可以叠加,易于分钱,并且尽量通用。 7.Registry(注册中心)Docker用Registry来保存用户构建的镜像。Registry分为公共和私有两种。Docker公司运营公共的Registry叫做Docker Hub。用户可以在Docker Hub注册账号,分享并保存自己的镜像(说明:在Docker Hub下载镜像巨慢,可以自己构建私有的Registry)。https://hub.docker.com/ Docker安装与启动1.安装Docker Docker官方建议在Ubuntu中安装,因为Docker是基于Ubuntu发布的,而且一般Docker出现的问题Ubuntu是最先更新或者打丁的。在很多版本的CentOS中是不支持更新最新的一些补丁包的。由于我们学习的环境都使用的是CentoS,因此这里我们馨诺我e头联输2-e医看裸颖这里建议安装在CentOS7.x以上的版本,在CentOS6.x的版本中,安装前需要安装其他很多的环境而且Docker很多补丁不支持更新。 yum包更新到最新 sudo yum update安装需要的软件包,yum-util 提供yum-config-manager功能,另外两个是devicemapper驱动依赖的 sudo yum instal1-y yum-utils device-mapper-persistent-data 1vm2设置yum源为阿里云 sudo yum-config-manager,-add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo安装docker-ce docker sudo yum install docker-ce安装后查看docker版本 docker-v2.设置ustc的镜像ustc是老牌的linux镜像服务提供者了,还在遥远的ubuntu5.04版本的时候就在用。ustc的docker镜像加速器速度很快。ustc docker mirror的优势之一就是不需要注册,是真正的公共服务。https:/lug.ustc.edu.cn/wiki/m...: vi/etc/docker/daemon.json在该文件中输入如下内容: “registry-mirrors":["https://docker.mirrors.ustc.edu.cn"]3.Docker的启动与停止systemctl命令是系统服务管理器指令启动docker: systemct1 start docker停止docker: systemct1 stop docker重启docker: systemct1 restart docker查看docker状态: systemct1 status docker开机启动:| systemct1 enable docker查看docker概要信息 docker info查看docker帮助文档 docker--help常用命令1.镜像相关命令查看镜像 docker images REPOSITORY:镜像名称TAG.镜像标签IIMAGEID:镜像IDCREATED:镜像的创建日期(不是获取该镜像的日期)SIZE:镜像大小这些镜像都是存储在Docker宿主机的/var/lib/docker目录下 搜索镜像如果你需要从网络中查找需要的镜像,可以通过以下命令搜索 docker search 镜像名称NAME:仓库名称DESCRIPTION:镜像描述STARS:用户评价,反应一个镜像的受欢迎程度OFFICIAL:是否官方AUTOMATED:自动构建,表示该镜像由Docker Hub自动构建流程创建的拉取镜像拉取镜像就是从中央仓库中下”本地 ...

October 13, 2019 · 2 min · jiezi

教你如何做出自己想要的PHP-Docker镜像

之前有片文章讲过如何通过Docker来构建Laravel的开发环境,其实变通一下就能够在本地电脑上用Docker运行任何PHP项目,让任何PHP项目都能运行在Docker环境中主要是需要根据PHP项目的依赖制作PHP镜像的Dockerfile。这篇文章就主要讲一下如何根据需求制作PHP的Docker镜像文件。 1. 继承基础镜像首先需要根据你的PHP项目对PHP的要求找到基础镜像,然后再在基础镜像的基础上按需安装PHP的扩展。在Dockerfile中使用FROM命令指定基础镜像。 From <image>FROM 指定构建镜像的基础源镜像,如果本地没有指定的镜像,则会自动从 Docker 的公共库 pull 镜像下来。FROM 必须是 Dockerfile 中非注释行的第一个指令,即一个 Dockerfile 从 FROM 语句开始。这里我们打算制作一个PHP7.2的包括FPM的定制化镜像,所以首先在Dockerfile中指定基础镜像: FROM php:7.2-fpm2. 安装PHP扩展定制PHP镜像的主要工作就是安装各种PHP扩展,在Dockerfile中PHP镜像安装扩展有三种方法,每种方法都有它特定的使用场景,下面依次来说。 2.1安装dockerhub中php官方提供的扩展在DockerHub中提供了一些官方的PHP扩展,可以通过docker-php-ext-install脚本命令在Dockerfile中列出要安装的扩展,下面让我们的PHP镜像安装上常用的pdo、pdo_mysql、mcrypt这些扩展。 FROM php:7.2-fpmRUN docker-php-ext-install pdo pdo_mysql mcrypt zip gd pcntl opcache bcmath如果你需要对扩展指定一些自定义的编译参数的话,docker提供了另外一个有用的脚本docker-php-ext-configure来传递编译参数(一般情况下用不到)。 FROM php:7.2-fpmRUN docker-php-ext-install pdo pdo_mysql mcrypt zip pcntl opcache bcmath\ && docker-php-ext-install -j$(nproc) iconv \ && docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \ && docker-php-ext-install -j$(nproc) gd2.2 使用PECL安装扩展DockerHub上只是提供了一部分PHP的扩展,安装这些以外的扩展仍然需要PECL, 在Docker镜像中使用pecl install下载、编译、安装扩展然后使用docker-php-ext-enable 下面使用PECL安装了PHP的redis还有grpc扩展。 RUN pecl install grpc \ && docker-php-ext-enable grpc \ && pecl install -o -f redis \ && docker-php-ext-enable redis \ && rm -rf /tmp/pear2.3 源码安装扩展有些扩展即无法使用docker-php-ext-install安装也无法通过PECL安装,只能通过源码编译安装(PHP扩展型的框架Phalcon就是这样,不过设置比较复杂,以后再讲), 在Docker中同样能够通过源码安装PHP扩展 ...

September 8, 2019 · 1 min · jiezi

docker从入门到实战实战篇

docker从入门到实战-实战篇前言本文是我通过三个星期业余时间学习后而写的文章,对docker的了解还处于入门阶段。希望本文能帮忙一些想学习docker的朋友快速入门。练习及实战代码都在github仓库中。如果我的文章能帮助到你的话,可以给我的docker项目点个赞哦 docker实战本次实战案例是todolist。技术栈为vue、node、mysql。具体代码见项目目录todolist,下面就不一一贴代码了。就讲下重点。 下面我就顺着依赖关系来讲,所以先从mysql开始讲起 构建mysql执行:docker run --name mymysql -d -p 3308:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql --name 给mysql容器设置匿名-d表示后台运行-p表示将容器的3306端口的映射到本地的3308端口,如果不设置的话,本地是无法访问该MySQL服务的。-e MYSQL_ROOT_PASSWORD 设置root的账号密码。mysql 后面不指定版本话,默认会latest版本在执行该语句之前,假如你之前没有pull过mysql镜像。docker在本地找不到你要的镜像就会帮你从docker仓库拉取mysql:latest镜像。 这个时候容器就启动成功了。 尝试下用navicat连接下试试 鼠标放入黄色小三角出现如下报错。 2013 - Lost connection to MySQL server at 'reading initial communication packet', system error: 0 "Internal error/check (Not system error)"这是因为mysql8以上,都会使用新的验证方式。 不妨查下信息: select host,user,plugin,authentication_string from mysql.user; mysql> select host,user,plugin,authentication_string from mysql.user;+-----------+------------------+-----------------------+------------------------------------------------------------------------+| host | user | plugin | authentication_string |+-----------+------------------+-----------------------+------------------------------------------------------------------------+| % | root | caching_sha2_password | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 || localhost | mysql.infoschema | caching_sha2_password | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED || localhost | mysql.session | caching_sha2_password | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED || localhost | mysql.sys | caching_sha2_password | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |)7k44VulAglQJgGpvgSG.ylA/rdbkqWjiqQJiq3DGsug5HIy3 |ord | $A$005$0pU+sGm[on+-----------+------------------+-----------------------+------------------------------------------------------------------------+plugin一栏可看到都是caching_sha2_password。 ...

July 7, 2019 · 3 min · jiezi

docker从入门到实战基础篇

docker从入门到实战-基础篇docker基础前言本文是我通过三个星期业余时间学习后而写的文章,对docker的了解还处于入门阶段。希望本文能帮忙一些想学习docker的朋友快速入门。练习及实战代码都在github仓库中。如果我的文章能帮助到你的话,可以给我的docker项目点个赞哦 介绍docker是一个开源的应用容器引擎,开发者可以打包自己的应用到容器里面,然后迁移到其他机器的docker应用中,可以实现快速部署。如果出现的故障,可以通过镜像,快速恢复服务。 举个例子,公司一般都会有多套环境,那么如何保持多套的运行环境一致,这个时候就可以用到docker。且当要求增加一套环境的时候,你无需在一个新服务器上一个个环境安装、配置。只需要运行下docker。同时官方还提供了Docker Hub,拥有大量的高质量的官方镜像。你可以将自己的镜像上传上去。有点类似于github。 安装官方提供了安装教程,挺详细的。官方安装教程 docker起步第一步:执行下docker -v确认下是否成功安装了docker 如果成功安装了,命令行将会输出入docker的版本号。如下:Docker version 18.09.2, build 6247962 docker的整个生命周期大致可分为: 镜像容器仓库这里以ubuntu镜像为例,介绍下镜像 在下载ubuntu镜像之前运行下docker images(查看镜像命令)查看下本地的镜像。如果你还没下载过镜像的话,当然会出现空。这里贴下我本地的镜像 ➜ study-docker git:(master) ✗ docker imagesREPOSITORY TAG IMAGE ID CREATED SIZEtodolist_static latest de5e325037e9 2 hours ago 1.05GBtodolist_nodejs latest 53efd80e03e1 2 hours ago 898MBubuntu 18.04 7698f282e524 4 weeks ago 69.9MBmysql latest 990386cbd5c0 5 weeks ago 443MBnode 8 a5c31320f223 6 weeks ago 895MBmysql 5.6 73829d7b6139 6 weeks ago 256MB使用拉取镜像命令docker pull 拉取ubuntu镜像:docker pull ubuntu。当你不指定版本时,默认拉取latest版本。 ...

July 7, 2019 · 2 min · jiezi

dockerdaocloud实现前端项目Vuejs自动部署

项目的自动化部署在大公司或独角兽中用得比较多,相比来进行手动部署项目来说会更加高效。那么本文结合之前学习的docker知识点以及nginx来简单实现VueJs项目的自动部署,当然针对其他项目也类似。运行环境首先需要在服务器上进行docker、nginx、node等的安装。便于进行后续的操作。通过docker拉取nginx镜像,命令docker pull nginx通过vue-cli初始化一个项目可以通过vue init webpack 项目名称初始化一个项目,这里假设项目名称是docker-vue,然后在该项目的根目录新建一个Dockerfile文件,大致内容如下: FROM nginx:latest#把当前打包工程的html复制到虚拟地址COPY dist/ /usr/share/nginx/html/#使用自定义nginx.conf配置端口和监听RUN rm /etc/nginx/conf.d/default.confADD default.conf /etc/nginx/conf.d/RUN /bin/bash -c 'echo init ok!!!'并新建一个default.conf文件,内容如下: server {项目中定义的端口号listen 8080;server_name localhost;#charset koi8-r;#access_log /var/log/nginx/log/host.access.log main;location / { root /usr/share/nginx/html; index index.html index.htm;}#error_page 404 /404.html;# redirect server error pages to the static page /50x.html#error_page 500 502 503 504 /50x.html;location = /50x.html { root html;}}自此,基本工作已完成,接下来就是对于daocloud.io的基本配置操作了 daocloud.io基本配置操作若无账号,可以先进行注册daocloud.io。接下来的操作分为: 创建项目集群管理创建镜像仓库创建项目这里需要添加项目名称,设置代码源(可以是github、gitlab)等,然后选择你所需要构建的项目,我这里选择了我自己的github仓库docker-vue,然后点击开始创建就行。 集群管理集群管理的主要目的是为了链接远程服务器,并通过命令进行daocloud.io镜像的创建。选择新建主机 由于我自己是购买了阿里云服务器了,系统是ubuntu的,所以就选择了这样的配置,然后在服务器上运行: curl -sSL https://get.daocloud.io/daomonit/install.sh | sh -s e2fa03ebead51076411388c26dff2257dae89768 来构建一个docker镜像,如: ...

July 2, 2019 · 1 min · jiezi

构建安全可靠最小化的-Docker-镜像

容器化部署越来越多的用于企业的生产环境中,如何构建可靠、安全、最小化的 Docker 镜像也就越来越重要。本文将针对该问题,通过原理加实践的方式,从头到脚帮你撸一遍。文章比较长,主要通过五个部分对容器镜像进行讲解。分别是: 镜像的构建讲解了镜像的手动构建与自动构建过程。镜像的存储与UnionFS联合文件系统讲解了镜像的分层结构以及UnionFS联合文件系统,以及镜像层在UnionFS上的实现。最小化镜像构建讲解了为什么需要最小化镜像,同时如何进行最小化构建。容器镜像的加固容器镜像加固的具体方式。容器镜像的审查高质量的项目中容器镜像也需要向代码一样进行审查。读者可以根据各自情况选择性阅读。 原文发自我的个人网站: GitDiG.com,参考链接构建安全可靠、最小化的 Docker 镜像.1. 构建镜像1.1 手动构建手动构建 Docker 镜像的流程图,如下: 现在依次按照流程采用命令行的方式手动构建一个简单的Docker 镜像。 1.1.1 创建容器并增加文件取busybox作为本次试验的基础镜像,因为它足够小,大小才 1.21MB。 $: docker run -it busybox:latest sh/ # touch /newfile/ # exit通过以上的操作,我们完成了流程图的前三步。创建了一个新容器,并在该容器上创建了一个新问题。只是,我们退出容器后,容器也不见了。当然容器不见了,并不表示容器不存在了,Docker 已经自动保存了该容器。如果在创建时,未显示设置容器名称,可以通过以下方式查找该消失的容器。 # 列出最近创建的容器$: docker container ls -n 1CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESc028c091f964 busybox:latest "sh" 13 minutes ago Exited (0) 27 seconds ago upbeat_cohen# 查询容器的详情$: docker container inspect c028c091f964...1.1.2 提交变更生成镜像手动构建镜像,很简单。先找到发生变更的容器对象,对其变更进行提交。提交完成后,镜像也就生成了。不过此时的镜像只有一个自动生成的序列号唯一标识它。为了方便镜像的检索,需要对镜像进行命名以及标签化处理。 命令行操作如下: # 提交变更, 构建镜像完成$: docker commit -a JayL -m "add newfile" c028c091f964sha256:01603f50694eb62e965e85cae2e2327240e4a68861bd0e98a4fb4ee27b403e6d# 对镜像进行命名, 原镜像ID取前几位就可以了$: docker image tag 01603f50694eb62e9 busybox:manual# 验证新镜像$: docker run busybox:manual ls -al newfile-rw-r--r-- 1 root root 0 Jun 15 05:25 newfile通过以上两步过程就完成了Docker 镜像手动创建。非常简单是不是。但是也非常麻烦,必须先创建新容器在提交变更,生成镜像。整个过程完全可以通过脚本化处理,这也是下节要说的,自动化构建Docker 镜像。 ...

June 30, 2019 · 5 min · jiezi

学习到实践六docker自定义nginxopenresty

前言为什么要使用openresty?官方说明:OpenResty® 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。所以。但openresty官方没有发布docker相关东西,所以以:结合openresty安装、参考docker-nginx官方的为原则编写。 1.依赖安装测试官方声明依赖:perl 5.6.1+, libpcre, libssl a.按nginx镜像测试# perl查找/ # apk search perl5perl-5.26.3-r0 #就一个可选/ # apk search libpcrelibpcre2-32-10.32-r1 #貌似最新版本了,32位的?pcre-dev-8.42-r1libpcre2-16-10.32-r1pcre2-dev-10.32-r1libpcre16-8.42-r1libpcre32-8.42-r1pcre2-10.32-r1pcre-8.42-r1libpcrecpp-8.42-r1/ # apk search libsslopenssl-dev-1.1.1b-r1libressl-dev-2.7.5-r0 #看起来最合适nss-3.41-r0libssl1.1-1.1.1b-r1dovecot-2.3.6-r0libressl2.7-libssl-2.7.5-r0/ # apk add perl-5.26.3-r0 libpcre2-32-10.32-r1 libressl-dev-2.7.5-r0# 完全报错,这个alpine依赖搞不了,官方https://pkgs.alpinelinux.org/包的搜索页捉襟见肘,不得不放弃“小而美”。b.容器测试参考官方选则debian,github上构建平台镜像的许多镜像选择stretch-slim精简版的,看下大小最新的只有55.3M,比较满意。环境安装测试: []:~/tmp/dk/openresty# docker run -itd --name df -v /root/tmp/dk/openresty:/tmp/host debian:stretch-slim[]:~/tmp/dk/openresty# docker exec df -it /bin/bash初始安装清华源,切换百度源(云本机),apt-get update超慢,后回归官源,后期卡死用网易源。问题:1、./configure: error: ngx_postgres addon was unable to detect version of the libpq library. apt-get libpq-dev -y2、./configure: error: the HTTP gzip module requires the zlib library. ...

June 29, 2019 · 2 min · jiezi

全栈学习实践四继续搭建集群

目前已完成:php7及扩展、redis5的Dockerfile测试版编写,稍许完善后同步上传到github,(记下这里memcached还没有剥离安装)。今天数据库,编程的一个重要原则是不要重复造轮子,php因为需要很多自定义插件、所以单独编译镜像,其实其他包括redis都应该使用官方的,直接pull就行。 一、mysql部分参考官方镜像,根据官方镜像,准备的mysql、mysql_slave文件树,添加了个数据文件夹。 []:~/tmp/dk/mysql/mysql_slave# tree ././├── config│   ├── conf.d│   │   └── docker.cnf│   └── my.cnf└── data1、创建mysql镜像 []:~/tmp/dk# docker pull mysql:8.0[]:~/tmp/dk# docker run --name mq -p 3306:3306 -v /root/tmp/dk/mysql/data:/var/lib/mysql \ -v /root/tmp/dk/mysql/config:/etc/mysql \ -v /root/tmp/dk/mysql/mysql-files:/var/lib/mysql-files -e MYSQL_ROOT_PASSWORD=123456 -d mysql:8.0[]:~/tmp/dk# docker run --name ms -p 3308:3306 -v /root/tmp/dk/mysql_slave/data:/var/lib/mysql \ -v /root/tmp/dk/mysql_slave/config:/etc/mysql \ -v /root/tmp/dk/mysql_slave/mysql-files:/var/lib/mysql-files -e MYSQL_ROOT_PASSWORD=123456 -d mysql:8.0退出后台运行的容器,按 Ctrl+D 进行退出容器,请牢记!run后运行的容器进入: a.旧式进入 []:~/tmp/dk# docker attach mqb.命令进入 []:~/tmp/dk# docker exec -it mq /bin/bash(或/bin/sh)参考《Docker容器进入的4种方式》a.普通进入:有一个问题。当多个窗口同时使用该命令进入该容器时,所有的窗口都会同步显示。如果有一个窗口阻塞了,那么其他窗口也无法再进行操作。所以docker attach命令不太适合于生产环境,平时自己开发应用时可以使用该命令。b.推荐 ...

June 27, 2019 · 1 min · jiezi

Docker实战之简单部署VueJs项目7

关于docker的优势就不多介绍了,之前的文章已经说得比较明白了,那么在学习了docker的一些知识后,现在该用它来做点事儿了,^_^,有点小兴奋。接下来就来看看docker怎样去部署一个VueJs的项目,我们从以下三点来进行:VueJs项目初始化以及打包Nginx的配置Docker镜像文件VueJs项目初始化这里通过vue-cli对一个vuejs项目进行初始化,命令如下: vue init webpack projectName这里项目名称列如是docker-web,对项目初始化组件HelloWord.vue组件进行简单的修改 然后通过npm run build命令进行项目的打包 Nginx的配置这里首先需要从docker hub上面进行nginx进行的拉取,可通过docker pull nginx进行获取,获取完后,可通过命令docker image ls 命令来查看本地已存在的镜像列表然后在项目(docker-web)的根目录新增一个nginx.conf文件,配置如下: Docker镜像文件首先在项目(docker-web)的根目录新增一个Dockerfile文件,内容如下:然后需要通过Dockerfile这个文件来进行镜像的制作、运行,可通过docker build -t 镜像名称来构建制作一个镜像,如:再次查看该镜像是否已经构建完成。最后以这个镜像为基础运行一个容器。对于这部分的内容,如有不懂的地方,可查看我之前有关于docker镜像构建的文章哦。至此,所有准备工作已完成,然后在浏览器地址栏输入localhost:3000访问网页,即可看到刚才在docker-web这个项目的HelloWord.vue组件中修改的内容。 Over,接下来会通过docker对前端项目部署进行进一步的实战。

June 22, 2019 · 1 min · jiezi

Docker学习之Container容器4

容器是 Docker 又一核心概念。简单的说,容器是独立运行的一个或一组应用,以及它们的运行态环境。对应的,虚拟机可以理解为模拟运行的一整套操作系统(提供了运行态环境和其他系统环境)和跑在上面的应用。关于容器的操作主要有: 创建启动停止导入导出删除等等启动容器启动容器有两种方式,一种是基于镜像新建一个容器并启动,另外一个是将在终止状态( stopped )的容器重新启动。因为 Docker 的容器实在太轻量级了,很多时候用户都是随时删除和新创建容器。 新建并启动所需要的命令主要为 docker run 这跟在本地直接执行 /bin/echo 'hello world' 几乎感觉不出任何区别。 下面的命令则启动一个 bash 终端,允许用户进行交互,如: docker run -t -i ubuntu:18.04 /bin/bash其中, -t 选项让Docker分配一个伪终端(pseudo-tty)并绑定到容器的标准输入上, -i 则让容器的标准输入保持打开。 那么当我们用docker run命令来创建并启动容器的时候,会发生哪些事儿呢? 检查本地是否存在指定的镜像,不存在就从公有仓库下载启动利用镜像创建并启动一个容器分配一个文件系统,并在只读的镜像层外面挂载一层可读写层从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去从地址池配置一个 ip 地址给容器执行用户指定的应用程序执行完毕后容器被终止所以当我们通过bash进入终端的时候,其实就是进入另一个系统。 启动已终止容器可以利用 docker container start 命令,直接将一个已经终止的容器启动运行。 容器的核心为所执行的应用程序,所需要的资源都是应用程序运行所必需的。除此之外,并没有其它的资源。可以在伪终端中利用 ps 或 top 来查看进程信息。 可见,容器中仅运行了指定的 bash 应用。这种特点使得 Docker 对资源的利用率极高,是货真价实的轻量级虚拟化。 后台运行更多的时候,我们会在后台运行容器,这时可以加上-d参数来实现。下面是每个1秒打印一次hello world。 docker run ubuntu:18.04 /bin/sh -c "while true; do echo hello world;sleep 1;done"如果使用了 -d 参数运行容器,则就是在后台进行运行: ...

June 19, 2019 · 1 min · jiezi

Docker学习之Dockerfile-构建镜像3

我们可以了解到,镜像的定制实际上就是定制每一层所添加的配置、文件。如果我们可以把每一层修改、安装、构建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像,那么之前提及的无法重复的问题、镜像构建透明性的问题、体积的问题就都会解决。这个脚本就Dockerfile。认识DockerfileDockerfile 是一个文本文件,其内包含了一条条的 指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。接下来以nginx为列通过Dockerfile文件来制定镜像。 在一个空白目录中,建立一个文本文件,并命名为 Dockerfile : $ mkdir mynginx$ cd mynginx$ touch Dockerfile Dockerfile内容如下:这个 Dockerfile 很简单,一共就两行。涉及到了两条指令, FROM 和 RUN 。接下来就先了解这两个指令。 Dockerfile指令之FROMFROM指令的目的就是来指定基础镜像。 所谓定制镜像,那一定是以一个镜像为基础,在其上进行定制。而FROM就是指定基础镜像,因此一个 Dockerfile 中 FROM 是必备的指令,并且必须是第一条指令。 在 Docker Hub 上有非常多的高质量的官方镜像,有可以直接拿来使用的服务类的镜像,如 nginx 、 redis 、 mongo 、 mysql 、 httpd 、 php 、 tomcat等;也有一些方便开发、构建、运行各种语言应用的镜像,如node 、 openjdk 、 python 、 ruby 、 golang 等。可以在其中寻找一个最符合我们最终目标的镜像为基础镜像进行定制。 Dockerfile指令之RUNRUN 指令是用来执行命令行命令的。由于命令行的强大能力, RUN 指令在定制镜像时是最常用的指令之一。其格式有两种: shell 格式: RUN <命令> ,就像直接在命令行中输入的命令一样。刚才写的Dockerfile 中的 RUN 指令就是这种格式。 RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.htmlexec 格式: RUN ["可执行文件", "参数1", "参数2"] ,这更像是函数调用中的格式。前面的文章有说过,Dockerfile 中每一个指令都会建立一层, RUN 也不例外。每一个RUN 的行为,就和刚才我们手工建立镜像的过程一样:新建立一层,在其上执行这些命令,执行结束后, commit 这一层的修改,构成新的镜像。 ...

June 19, 2019 · 1 min · jiezi

docker创建Dockerfile并push到dockerhub

创建 dockerfileDockerfile PS: 文件名字必须是这样Dockerfile FROM tomcat:8.0COPY index.jsp /usr/local/tomcat/webapps/ROOTEXPOSE 8080index.jsp <%out.println("Hello World, V1");%>build 并测试 The docker build command processes this file generating a Docker Image in your Local Image Cache, which you can then start-up using the docker run command, or push to a permanent Image Repository. docker build 创建一个docker镜像,这个镜像可以在你本地运行。 $docker build -t mytomcat:1.0 .$docker run -p 8080:8080 -d mytomcat:1.0$curl localhost:8080push 到 docker hub注册一个账号 Build image Docker login ...

June 14, 2019 · 1 min · jiezi

Dockerfile中容易混淆的命令详解

RUN、CMD和ENTRYPOINT命令解释RUN 执行命令并创建新的Image LayerCMD 设置容器启动后默认执行的命令和参数ENTRYPOINT 设置容器启动时运行的命令执行方式EXEC FROM debianRUN ['apt-get','install','-y','vim']CMD ['/bin/echo','hello world!!']ENTRYPOINT ['/bin/echo','hello world!!']SHELL FROM debian RUN apt-get install -y vim CMD echo 'hello world!!' ENTRYPOINT echo 'hello world!!'注意事项使用run命令构建镜像时apt-get update && apt-get install -y需要放在同一个RUN命令中,否则apt-get install会从缓存中安装软件,导致apt-get update执行毫无意义apt-get install 的软件尽量一个一行并且按照字母顺序排列,这样可以避免安装重复的命令apt-get install安装软件时可以为软件指定特定的版本apt-get install -y aufs-tools s3cmd=1.1.*命令差异CMD 容器启动时默认执行的命令docker run 指定了其他命令,CMD会被忽略如果定义了多个CMD,只有最后一个会执行ENTRYPOINT 让容器以运用程序或者服务的形式运行不会被忽略,一定会执行最佳实践,写一个shell脚本作为entrypointCOPY ./script/test.sh /usr/local/binENTRYPOINT ['test.sh']

June 12, 2019 · 1 min · jiezi

替换-Docker-或-Laradock-中-Debian-系统镜像源解决软件安装问题

Docker Debian 镜像源替换因多数默认的 Docker 镜像为国外的,而采用的镜像源也是国外的,故访问很慢,所以我们需要替换为国内的(比如阿里云或163等)。 163 - DebianAliyun - Debian注意: 不同版本的 Debian 镜像源地址不一样Debian 7.x (wheezy)# 更新apt-get源RUN echo \ deb http://mirrors.aliyun.com/debian/ wheezy main non-free contrib\ deb http://mirrors.aliyun.com/debian/ wheezy-proposed-updates main non-free contrib\ deb-src http://mirrors.aliyun.com/debian/ wheezy main non-free contrib\ > /etc/apt/sources.listDebian 8.x (jessie)# 更新apt-get源RUN echo \ deb http://mirrors.aliyun.com/debian/ jessie main non-free contrib\ deb http://mirrors.aliyun.com/debian/ jessie-proposed-updates main non-free contrib\ deb-src http://mirrors.aliyun.com/debian/ jessie main non-free contrib\ > /etc/apt/sources.listDebian 9.x (stretch)# 更新apt-get源RUN echo \ deb http://mirrors.aliyun.com/debian/ stretch main non-free contrib\ deb-src http://mirrors.aliyun.com/debian/ stretch main non-free contrib\ deb http://mirrors.aliyun.com/debian-security stretch/updates main\ deb-src http://mirrors.aliyun.com/debian-security stretch/updates main\ deb http://mirrors.aliyun.com/debian/ stretch-updates main non-free contrib\ deb-src http://mirrors.aliyun.com/debian/ stretch-updates main non-free contrib\ deb http://mirrors.aliyun.com/debian/ stretch-backports main non-free contrib\ deb-src http://mirrors.aliyun.com/debian/ stretch-backports main non-free contrib\ > /etc/apt/sources.listLaradock 镜像构建失败因为默认用的是国外 Debian 镜像源,故在执行 apt-get 等命令拉取软件包时会失败,我们需手动在对于的 Dockerfile 中添加一个 RUN 指令来替换掉默认的镜像源以下仅为示例: ...

May 9, 2019 · 1 min · jiezi

docker的centos安装操作及部分理解

前两天在本地安装了docker,熟悉了下命令之后,还是忍不住到centos上进行了一波golang镜像部署,以下是我的操作步骤和一些想法。准备:一台安装了docker的可联网的centos服务器 1、不多说,写Dockerfile(只想体验dockerfile的操作流程,所以选择了yum的安装方式)# docker build# Version 1.0#FROM centos#MAINTAINER yancoder@163.com#RUN yum install -y epel-releaseRUN yum install -y docker-ioRUN yum provides '*/applydeltarpm'RUN yum install deltarpm -yRUN yum install -y gccRUN yum install -y goRUN mkdir -p /data/gopathENV GOPATH /data/gopathADD src/ /data/gopath/srcADD pkg/ /data/gopath/pkgADD test.go /data/gopath/test.goWORKDIR /data/gopathRUN go build -o server.bin test.go#CMD /data/gopath/server.bin注释别问我在gcc和go安装之前为什么还有四个安装步骤,我特么也不知道,反正就是报错了提示要我安装 源码安装如下 FROM centosMAINTAINER yancoder@163.comENV GOROOT /usr/local/goENV GOPATH /data/gopathENV PATH $GOROOT/bin:$PATHRUN yum install -y curlRUN curl -s -o go.tar.gz https://storage.googleapis.com/golang/go1.5.1.linux-amd64.tar.gzRUN tar --remove-files -C /usr/local/ -zxf go.tar.gzRUN mkdir -p /data/goRUN ln -sv /usr/local/go/bin/go /binADD src/ /data/gopath/srcADD pkg/ /data/gopath/pkgADD test.go /data/gopath/test.goWORKDIR /data/gopathRUN go build -o server.bin test.goCMD /data/gopath/server.bin2、创建镜像(注意最后面有一个小数点)docker build -t golang:v1.0 .3、创建容器,如果要绑定端口,也在这一步进行docker run -d -p 80:80 golang:v1.04、在外部浏览器访问一下~ ...

April 28, 2019 · 1 min · jiezi

程序员笔记如何编写优雅的Dockerfile

导读Kubernetes要从容器化开始,而容器又需要从Dockerfile开始,本文将介绍如何写出一个优雅的Dockerfile文件。 文章主要内容包括: Docker容器Dockerfile使用多阶构建感谢公司提供大量机器资源及时间让我们可以实践,感谢在此专题上不断实践的部分项目及人员的支持。 一、Docker容器1.1 容器的特点我们都知道容器就是一个标准的软件单元,它有以下特点: 随处运行:容器可以将代码与配置文件和相关依赖库进行打包,从而确保在任何环境下的运行都是一致的。高资源利用率:容器提供进程级的隔离,因此可以更加精细地设置CPU和内存的使用率,进而更好地利用服务器的计算资源。快速扩展:每个容器都可作为单独的进程予以运行,并且可以共享底层操作系统的系统资源,这样一来可以加快容器的启动和停止效率。1.2 Docker容器目前市面上的主流容器引擎有Docker、Rocket/rkt、OpenVZ/Odin等等,而独霸一方的容器引擎就是使用最多的Docker容器引擎。 Docker容器是与系统其他部分隔离开的一系列进程,运行这些进程所需的所有文件都由另一个镜像提供,从开发到测试再到生产的整个过程中,Linux 容器都具有可移植性和一致性。相对于依赖重复传统测试环境的开发渠道,容器的运行速度要快得多,并且支持在多种主流云平台(PaaS)和本地系统上部署。Docker容器很好地解决了“开发环境能正常跑,一上线就各种崩”的尴尬。 Docker容器的特点: 轻量:容器是进程级的资源隔离,而虚拟机是操作系统级的资源隔离,所以Docker容器相对于虚拟机来说可以节省更多的资源开销,因为Docker容器不再需要GuestOS这一层操作系统了。快速:容器的启动和创建无需启动GuestOS,可以实现秒级甚至毫秒级的启动。可移植性:Docker容器技术是将应用及所依赖的库和运行时的环境技术改造包成容器镜像,可以在不同的平台运行。自动化:容器生态中的容器编排工作(如:Kubernetes)可帮助我们实现容器的自动化管理。二、DockerfileDockerfile是用来描述文件的构成的文本文档,其中包含了用户可以在使用行调用以组合Image的所有命令,用户还可以使用Docker build实现连续执行多个命令指今行的自动构建。 通过编写Dockerfile生磁镜像,可以为开发、测试团队提供基本一致的环境,从而提升开发、测试团队的效率,不用再为环境不统一而发愁,同时运维也能更加方便地管理我们的镜像。 Dockerfile的语法非常简单,常用的只有11个: 2.1 编写优雅地Dockerfile编写优雅的Dockerfile主要需要注意以下几点: Dockerfile文件不宜过长,层级越多最终制作出来的镜像也就越大。构建出来的镜像不要包含不需要的内容,如日志、安装临时文件等。尽量使用运行时的基础镜像,不需要将构建时的过程也放到运行时的Dockerfile里。只要记住以上三点就能写出不错的Dockerfile。 为了方便大家了解,我们用两个Dockerfile实例进行简单的对比: FROM ubuntu:16.04RUN apt-get updateRUN apt-get install -y apt-utils libjpeg-dev \ python-pipRUN pip install --upgrade pipRUN easy_install -U setuptoolsRUN apt-get cleanFROM ubuntu:16.04RUN apt-get update && apt-get install -y apt-utils \ libjpeg-dev python-pip \ && pip install --upgrade pip \ && easy_install -U setuptools \ && apt-get clean我们看第一个Dockerfile,乍一看条理清晰,结构合理,似乎还不错。再看第二个Dockerfile,紧凑,不易阅读,为什么要这么写? ...

April 28, 2019 · 2 min · jiezi

基于-Docker-GogsJenkinsKubernetes-实践工程源代码的自动构建和持续集成与部署交付

本期目标 : 基于 Centos 7.6 , 封装出一个可用于运行 php 项目的开箱即用镜像本文不讨论 dockerfile 语法 , 并且假设你懂得基本的类unix 操作系统常识并拥有类unix 运行环境 (包括但不限于安装了mac 或 linux 的实体机 , 类unix虚拟机 , 安装了 MinGW 或 CygWin 的 windows 机器) , 并且认为你懂得基本的 docker 操作和有一定的 dockerfile 阅读能力准备工作建立工作目录 mkdir ~/docker-learncd ~/docker-learn创建Dockerfile touch Dockerfile然后拷贝你常用的 nginx.conf 到工作目录 cp xxx/nginx.conf nginx.conf封装基础镜像编辑我们创建好的 Dockerfile 基础内容声明本镜像继承自 centos 最新版 FROM centos安装 nginx创建nginx源文件 由于 centos 仓库里是没有 nginx 的 , 所以我们要自力更新添加nginx的源到 docker 里复制 nginx.org 里关于 RHEL 源的内容到 nginx.repo 文件也可以本地执行以下命令创建 nginx.repo ...

April 25, 2019 · 4 min · jiezi

Docker|基础篇

简介Docker 在容器的基础上,进行了进一步的封装,从文件系统、网络互联到进程隔离等等,极大的简化了容器的创建和维护。使得 Docker 技术比虚拟机技术更为轻便、快捷。下面的图片比较了 Docker 和传统虚拟化方式的不同之处。传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。概念Docker 包括三个基本概念镜像(Image)容器(Container)仓库(Repository)如果按面向对象思想:镜像类比如类,容器类比如实例公有仓库:https://hub.docker.com/Docker 引擎Docker 引擎是一个包含以下主要组件的客户端服务器应用程序。一种服务器,它是一种称为守护进程并且长时间运行的程序。REST API用于指定程序可以用来与守护进程通信的接口,并指示它做什么。一个有命令行界面 (CLI) 工具的客户端。Docker 引擎组件的流程如下图所示:安装以下基于Centos7以上版本。centos7安装:https://www.osyunwei.com/arch…docker安装:下载安装$ curl -fsSL get.docker.com -o get-docker.sh$ sudo sh get-docker.sh –mirror Aliyun启动$ sudo systemctl enable docker$ sudo systemctl start docker配置Docker 国内加速器$ curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://f1361db2.m.daocloud.ioDocker基本操作指令下载镜像:$ docker pull tomcat解析:docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]启动容器:1.交互式运行$ docker run -it –rm tomcat bash后台运行$docker run –name webserver -d -p 8080:8080 tomcat解析: -it 指:i为交互式操作,t为终端;–rm指容器退出后随之将其删除;tomcat指你要启动的镜像;bash指tomcat中的shell控制台;–name 指定名称;-d 后台运行; -p 8080:8080 指定端口号(第一个为宿主机端口,第二个为docker的端口。交互式进入容器:docker exec -it <容器id> bash查看运行中的容器:docker ps -a删除容器:docker rm <容器id>查看容器运行日志:docker logs -f -t <容器id或容器名称>解析:-f:跟踪容器日志的最近更新;-t:显示容器日志的时间戳;清除虚悬镜像:docker image prune -a -f标记本地镜像,将其归入某一仓库docker tag [options “o”>] <image>[:tag “o”>] [repository/ “o”>][username/]name “o”>[:tag]解析:-f 覆盖已有标记。将镜像推送至远程仓库,默认为 Docker Hubdocker push name[:tag “o”>]更多命令可以参考【这里】Docker操作(基于Dockerfile)在一个/usr/local/docker文件中写一个名为Dockerfile的文件#pull down centos imageFROM centosMAINTAINER test@test.com#copy jdk and tomcat into imageADD ./apache-tomcat-7.0.70.tar.gz /rootADD ./jdk-7u80-linux-x64.tar.gz /root#set environment variableENV JAVA_HOME /root/jdk1.7.0_80ENV PATH $JAVA_HOME/bin:$PATH#define entry point which will be run first when the container starts upENTRYPOINT /root/apache-tomcat-7.0.70/bin/startup.sh && tail -F /root/apache-tomcat-7.0.70/logs/catalina.out解析:总体看来就是按照Dockerfile的命令规则进行运行shell指令关键命令:FROM: 指定基础镜像RUN: 执行命令COPY: <源路径>… <目标路径>ADD:跟COPY相似,如果源文件是tar包时,会自动解压。(一般用copy指令)CMD: 容器启动命令ENTRYPOINT: 入口点VOLUME: 定义匿名卷EXPOSE: 暴露端口WORKDIR: 指定工作目录USER : 指定当前用户ENV: 设置环境变量编译构建:docker build [选项] <上下文路径/URL/->### 最后有一个点的,它表示上下文。docker build -t app .看到 docker build 命令最后有一个 .。. 表示当前目录,而 Dockerfile 就在当前目录。-t app :指定了最终镜像的名称为app参考文档Dockerfie 官方文档Dockerfile 最佳实践文档Docker 官方镜像 DockerfileDocker操作(基于Compose)Docker Compose 将所管理的容器分为三层,工程(project) 由一组关联应用容器组成的一个完整的业务单元。服务(service) 一个应用的容器,实际上若干个运行着相同镜像的容器实例。容器(container)Compose就是通过命令对项目中的一组容器的生命周期进行便捷的管理。安装:官网地址:https://github.com/docker/com…$ sudo curl -L “https://github.com/docker/compose/releases/download/1.24.0/docker-compose-$(uname -s)-$(uname -m)” -o /usr/local/bin/docker-compose$ sudo chmod +x /usr/local/bin/docker-compose$ sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose$ docker-compose –version部署项目在/usr/local/docker目录下新建一个docker-compose.yml文件version: “3"services: web: restart: always image: tomcat container_name: web ports: - 8080:8080 volumes: - /usr/local/docker/nblog/webapps:/usr/local/tomcat/webapps mysql: restart: always image: mysql:5.7.25 container_name: mysql ports: - 3306:3306 environment: TZ: Asia/Shanghai MYSQL_ROOT_PASSWORD: root command: –character-set-server=utf8mb4 –collation-server=utf8mb4_general_ci –explicit_defaults_for_timestamp=true –lower_case_table_names=1 –max_allowed_packet=128M volumes: - db_data:/var/lib/mysqlvolumes: db_data: docker-compose.yml常用参数解析:restart:启动容器自自启动。image:镜像container_name:自定义容器名ports:端口,第一个是宿主机,第二个是docker中的端口volumes: 数据卷,就是宿主机的目录被docker共享。这里就是你将你的应用放到指定目录,它就会自动引用进docker容器中。environment:环境变量设置。更多配置:https://docs.docker.com/compo…启动$ docker-compose up -d-d:指后台运行跟踪日志$ docker-compose logs -f tomcat -f:类似于tail -f卸载$ docker-compose down后续Docker持续集成总结Docker与微服务更配哦。资源:Docker官方文档DockerHub仓库DockerCompose一些常用的镜像最后如果对 Java、大数据感兴趣请长按二维码关注一波,我会努力带给你们价值。觉得对你哪怕有一丁点帮助的请帮忙点个赞或者转发哦。 ...

April 13, 2019 · 2 min · jiezi

docker命令

docker入门主要是docker使用命令docker守护进程修改守护进程的网络sudo docker daemon -H tcp://0.0.0.0:2375 这条命令将docker守护进程//使用docker_host环境变量export DOCKER_HOST = “tcp:0.0.0:2375检查docker是否运行sudo status docker //sudo service docker status启动和关闭sudo stop docker //sudo service docker stopsudo start docker //sudo service docker startdocker容器操作查看docker是否正常工作sudo docker info运行容器sudo docker run -i -t ubuntu /bin/bash//-i标记保证容器是STDIN开启的//-t标记告诉docker要创建的容器分配一个伪tty终端//ubuntu 指定镜像// /bin/bash告诉docker容器要运行什么命令容器命名docker默认为创建的容器生成一个随机的名称,可通过--name标记来给容器命名sudo docker run --name myName -i -t ubuntu /bin/bash启动已经停止的容器sudo docker start myName //也可通过id指定//也可使用docker restart命令附着到容器上docker容器重新启动的时候,会沿用docker run命令时指定的参数来运行,因此上例中重新启动会运行一个交互式的shell,此外也可以用docker attach重新附着到该容器的会话上sudo docker attach myName //也可通过id指定创建守护式容器除了交互式运行的容器,也可以创建长期运行的容器,守护式容器没有交互式会话,非常适合运行应用程序和服务。sudo docker run --name daemon_name -d ubuntu /bin/sh -c "while true; do echo hello world;sleep 1;done"//-d 标记docker将容器放在后台运行//while循环一直打印hello world查看docker容器docker ps //查看正在运行的容器docker ps -a //查看所有的容器查看容器内部docker logs daemon_name //获取容器的日志,可通过-f来追踪日志日志驱动docker1.6开始,可通过--log-driver选项来控制docker守护线程和容器所有的日志驱动,可以在执行docker守护线程或者执行docker run命令时使用这个选项。sudo docker run --log-driver="syslog" --name daemon_name -d ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"//将daemon_name容器的日志输出到syslog,导致docker logs命令不会输出任何东西查看容器内的进程sudo docker top daemon_name在容器内部运行进程sudo docker exec -d daemon_name touch /etc/new_config_file//-d 标记运行一个后台进程 后面明智执行名气的名字以及执行的命令sudo docker exec -t -i daemon_name /bin/bash//创建TTY并捕捉STDIN关闭容器sudo docker stop daemon_name深入容器sudo docker inspect daemon_name //查看更多容器的信息//该命令也可用来查看镜像信息删除容器sudo docker rm 80430f8d0921 //通过指定容器id//删除全部容器sudo docker rm sudo docker ps -a -q` //-q标记表示只返回容器的iddocker镜像列出docker镜像sudo docker images//本地镜像都保存在docker宿主机的/var/lib/docker目录i西安,每个镜像都保存在docker所采用的存储驱动目录下面,如aufs或者devicemapper,也可以在/var/bin/docker/containers目录下看到所有容器拉取镜像sudo docker pull ubuntu:12.04运行一个带标签的docker镜像sudo docker run -t -i –name new_container ubuntu:12:04 /bin/bash查找镜像可以通过docker search命令来查找所有docker hub上公共的可用镜像sudo docker search puppetNAME DESCRIPTION STARS OFFICIAL AUTOMATEDpuppet/puppetserver A Docker Image for running Puppet Server. Wi… 75 alekzonder/puppeteer GoogleChrome/puppeteer image and screenshots… 51 [OK]仓库名镜像描述stars,用户评价official,是否官方,由上游开发者管理的镜像(如fedora镜像由fedora团队管理)。automated,自动构建,表示这个镜像由docker hub的自动构建流程构建的。构建镜像构建镜像有两种方式docker commit命令docker build命令和dockerfile文件现在并不推荐使用docker commit命令,而应该使用更灵活、更强大的dockerfile来构建docker镜像一般来说都是基于已有的基础镜像,而不是“创建”新镜像,从0开始可以参考:https://docs.docker.com/develop/develop-images/baseimages/创建docker hub账号创建完镜像之后,可以将镜像推送到docker hub或者私有的registryzhong,完成这个操作需要在docker hub上创建一个账号。https://hub.docker.com/signup登陆到docker hubsudo docker loginUsername:Password:Login Succeeded用docker commit来创建镜像//创建一个新容器sudo docker run -i -t ubuntu /bin/bash//在容器内部安装一些软件…//得到刚刚创建容器的iddocker ps -l -q9649de16bffb//提交定制容器sudo docker commit 9649de16bffb dack/apache2 //检查新创建的镜像docker images dack/apache2REPOSITORY TAG IMAGE ID CREATED SIZEdack/apache2 latest 2c5cd556c3f2 About a minute ago 209MB也可以在提交镜像时指定更多的数据(包含标签)来详细描述所做的修改sudo docker commit -m “A new custom image” -a “dack huang” 9649de16bffb dack/apache2:webserver//-m 提交信息//-a 作息信息//dack/apache2:webserver 执行镜像的用户名和仓库名,并为该镜像增加一个webserver的标签 用Dockerfile构建镜像并不推荐用docker commit构建镜像,相反推荐使用Dockerfile的定义文件和docker build来构建镜像Dockerfile使用基本的基于DSL(Domain Specific Language)语法的指令来构建一个docker镜像,对比docker commit,其更具备可重复性、透明性和幂等性。保存Dockerfile的目录称为上下文,docker会在构建镜像时将构建的上下文和该上下文的文件和目录上传到docker守护进程。这样docker守护进程就可以直接访问用户想在镜像中存储的任何代码、文件或者其他数据。dockerfile中每条指令从上到下依次执行,大体的流程如下:docker从基础镜像中运行一个容器执行一条指令,对容器做出修改执行类似docker commit的操作,提交一个新的镜像层docker再基于刚提交的镜像运行一个新容器执行下一条指令直至全部执行完毕所以尽管某一步执行失败了,还是得到一个可以使用的镜像# Version : 0.01FROM ubuntu:14.04MAINTAINER dack huang “dack_huang@163.com"RUN apt-get update && apt-get install -y nginxRUN echo ‘Hi, I am in your container’ \ >/usr/share/nginx/html/index.htmlEXPOSE 80FROM //指定基础镜像MAINTAINER //指定镜像作者RUN //在当前镜像中运行的命令,默认在shell里面使用/bin/sh -c执行EXPOSE //应用程序会使用容器指定的接口通过docker build构建镜像docker build -t=“dack/static_web”//-t设置镜像标签//从git仓库上面构建镜像//假设这个git仓库存在Dockerfiledocker build -t=“dack/static” git@github.com:dack/docker-static_web docker将每一步的构建过程都提交为镜像,所以docker会将之前的镜像层看成缓存,当修改某个步骤之后再次构建的,docker会直接从该步骤开始。可用docker build –no-cache略过缓存docker build –no-cache -t=“dack/static_web"docker history查看镜像的每一层[root@dack static_web]# docker history e5f55354c141IMAGE CREATED CREATED BY SIZE COMMENTe5f55354c141 5 hours ago /bin/sh -c #(nop) EXPOSE 80 0B 66d44cca6536 5 hours ago /bin/sh -c echo ‘Hi, I am in your container’… 27B 022c0b46f4f8 5 hours ago /bin/sh -c apt-get update && apt-get install… 34.3MB 34d2d2b790f5 5 hours ago /bin/sh -c #(nop) MAINTAINER dack huang “da… 0B 390582d83ead 3 weeks ago /bin/sh -c #(nop) CMD ["/bin/bash”] 0B <missing> 3 weeks ago /bin/sh -c mkdir -p /run/systemd && echo ‘do… 7B 参考第一本docke书 ...

April 2, 2019 · 2 min · jiezi

docker-compose 搭建 nginx/php/mysql/redis/go 环境

Dockerfiles项目路径: https://github.com/hopher/doc…用 Docker 容器服务的方式搭建 nginx/php/mysql/redis/go 环境,易于维护、升级。相关软件版本:PHP 7.2Golang 1.12MySQL 5.7Nginx 1.15Redis 3.2PHP 扩展swoole v4.3.0使用1.下载下载 zip 压缩包 && 解压wget -c https://github.com/hopher/dockerfiles/archive/master.zip -O dockerfiles.zipunzip dockerfiles.zipmv dockerfiles-master ~/app其中, ~/app 为个人工作目录,请根据自己需要更改2.docker-compose 构建项目进入 docker-compose.yml 所在目录:执行命令:docker-compose up如果没问题,下次启动时可以以守护模式启用,所有容器将后台运行:docker-compose up -d使用 docker-compose 基本上就这么简单,Docker 就跑起来了,用 stop,start 关闭开启容器服务。 更多的是在于编写 dockerfile 和 docker-compose.yml 文件。 可以这样关闭容器并删除服务:docker-compose down3. 测试将项目源码放到 src 目录下, 并运行cd srcecho “<?php phpinfo();” > index.php打开 url 访问 http://localhost/index.php4.帮助执行命令:docker-compose –help参数说明-p 指定项目名称,默认为当前目录名, 也可以直接在docker-compose.yml中设置image, container_name 这2个属性5.目录结构dockerfiles |– services # docker 相关服务 |– src # 工作源码目录, 如 nginx /usr/share/nginx/html |– docker-compose.yml # docker-compose.yml 定义 |– deprecated.sh # 已弃用 shell 脚本, 勿使用各系统软件源Ubuntu系统代号版本precise12.04trusty14.04vivid15.04xenial16.04zesty17.04Debian系统代号版本squeeze6.xwheezy7.xjessie8.xstretch9.xbuster10.x阿里源修改 /etc/apt/sources.list 为以下内容deb http://mirrors.aliyun.com/debian stretch main contrib non-freedeb-src http://mirrors.aliyun.com/debian stretch main contrib non-freedeb http://mirrors.aliyun.com/debian stretch-updates main contrib non-freedeb-src http://mirrors.aliyun.com/debian stretch-updates main contrib non-freedeb http://mirrors.aliyun.com/debian-security stretch/updates main contrib non-freedeb-src http://mirrors.aliyun.com/debian-security stretch/updates main contrib non-freeNOTE: 查询自己的Linux版本 cat /etc/issue常用shell组合# 删除所有容器docker stop docker ps -q -a | xargs docker rm# 删除所有标签为none的镜像docker images|grep &lt;none&gt;|awk ‘{print $3}’|xargs docker rmi参考资料[[官方] Compose file version 3 reference](https://docs.docker.com/compo…清华大学开源软件镜像站-Debian 镜像使用帮助[官方] mysql 镜像说明[官方] php 镜像说明 ...

March 10, 2019 · 1 min · jiezi

如何用Dockerfile构建镜像

本文旨在用通俗的语言讲述枯燥的知识前面讲到镜像的构建时,讲述的是用commit的方式构建镜像,而Dockerfile是另一种构建镜像的方式。Dockerfile构建镜像是以基础镜像为基础的,Dockerfile是一个文本文件,内容是用户编写的一些docker指令,每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。Dockerfile的基本指令有十三个,分别是:FROM、MAINTAINER、RUN、CMD、EXPOSE、ENV、ADD、COPY、ENTRYPOINT、VOLUME、USER、WORKDIR、ONBUILD从前面的内容可以看出,要构建一个容器,需要做很多的工作,设置很多的配置,如果我们可以把每一层修改、安装、构建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像,那么之前提及的无法重复的问题、镜像构建透明性的问题、体积的问题就都会解决。这个脚本就是 Dockerfile。因此学会用Dockerfile来构建镜像,是非常有必要的。学习Dockerfile之前,我们先来学习一些Dockerfile常用的指令。文章提纲:Dockerfile常用指令Dockerfile的编写用Dockerfile构建镜像彩蛋1 Dockerfile常用指令类型命令基础镜像信息FROM维护者信息MAINTAINER镜像操作指令RUN、COPY、ADD、EXPOSE、WORKDIR、ONBUILD、USER、VOLUME等容器启动时执行指令CMD、ENTRYPOINT1.1、FROM :指定基础镜像所谓定制镜像,那一定是以一个镜像为基础,在其上进行定制。就像我们之前运行了一个nginx镜像的容器,再进行修改一样,基础镜像是必须指定的。而FROM就是指定基础镜 像,因此一个Dockerfile中FROM是必备的指令,并且必须是第一条指令。如:指定ubuntu的14版本作为基础镜像FROM ubuntu:141.2、 RUN:执行命令RUN指令在新镜像内部执行的命令,如:执行某些动作、安装系统软件、配置系统信息之类,格式如下两种:1)shell格式:RUN< command > ,就像直接在命令行中输入的命令一样。如在nginx里的默认主页中写”hello“:RUN echo ‘hello ’ >/etc/nginx/html/index.html2)exec格式:RUN [“可执行文件”, “参数1”, “参数2”]如在新镜像中用yum方式安装nginx:RUN [“yum”,“install”,“nginx”]注:多行命令不要写多个RUN,原因是Dockerfile中每一个指令都会建立一层.多少个RUN就构建了多少层镜像,会造成镜像的臃肿、多层,不仅仅增加了构件部署的时间,还容易出错,RUN书写时的换行符是\1.3、COPY:复制文件COPY命令用于将宿主机器上的的文件复制到镜像内,如果目的位置不存在,Docker会自动创建。但宿主机器用要复制的目录必须是和Dockerfile文件统计目录下。格式:COPY [–chown=<user>:<group>] <源路径>… <目标路径>COPY [–chown=<user>:<group>] ["<源路径1>",… “<目标路径>"]如把宿主机中的package.json文件复制到容器中/usr/src/app/目录下:COPY package.json /usr/src/app/1.4、CMD:容器启动命令CMD命令用于容器启动时需要执行的命令,CMD在Dockerfile中只能出现一次,如果出现多个,那么只有最后一个会有效。其作用是在启动容器的时候提供一个默认的命令项。如果用户执行docker run的时候提供了命令项,就会覆盖掉这个命令,没提供就会使用构建时的命令。格式:shell 格式:CMD <命令>exec 格式:CMD [“可执行文件”, “参数1”, “参数2”…]如容器启动时进入bash:CMD /bin/bash也可以用exec写法:CMD ["/bin/bash”]1.5 MAINTAINER:指定作者用来指定dockerfile的作者名称和邮箱,主要作用是为了标识软件的所有者是谁。语法:MAINTAINER <name> <email>如:MAINTAINER autor_jiabuli 6766633@qq.com1.6、EXPOSE:暴露端口EXPOSE命名适用于设置容器对外映射的容器端口号,如tomcat容器内使用的端口8081,则用EXPOSE命令可以告诉外界该容器的8081端口对外,在构建镜像时用docker run -p可以设置暴露的端口对宿主机器端口的映射。语法:EXPOSE <端口1> [<端口2>…]如:EXPOSE 8081EXPOSE 8081 其实等价于 docker run -p 8081 当需要把8081端口映射到宿主机中的某个端口(如8888)以便外界访问时,则可以用docker run -p 8888:80811.7、WORKDIR:配置工作目录WORKDIR命令是为RUN、CMD、ENTRYPOINT指令配置工作目录。其效果类似于Linux命名中的cd命令,用于目录的切换,但是和cd不一样的是:如果切换到的目录不存在,WORKDIR会为此创建目录。语法:WORKDIR path如需要在nginx目录下创建一个hello.txt的文件:##进入/usr/local/nginx目录下WORKDIR /usr/local/nginx##进入/usr/local/nginx中的html目录下WORKDIR html## 在html目录下创建了一个hello.txt文件RUN echo ‘hello’ > hello.txt1.8、ENTRYPOINT:容器启动执行命名ENTRYPOINT的作用和用法和CMD一模一样,但是ENTRYPOINT有和CMD有2处不一样:CMD的命令会被docker run的命令覆盖而ENTRYPOINT不会CMD和ENTRYPOINT都存在时,CMD的指令变成了ENTRYPOINT的参数,并且此CMD提供的参数会被 docker run 后面的命令覆盖1.9、VOLUMEVOLUME用来创建一个可以从本地主机或其他容器挂载的挂载点。例如我们知道tomcat的webapps目录是放web应用程序代码的地方,此时我们要把webapps目录挂载为匿名卷,这样任何写入webapps中的心都不会被记录到容器的存储层,让容器存储层无状态化。格式:VOLUME [“path”]如创建tomcat的webapps目录的一个挂载点VOLUME /usr/local/tomcat/webapps这样,在运行容器时,也可以用过docker run -v来把匿名挂载点挂载都宿主机器上的某个目录,如docker run -d -v /home/tomcat_webapps:/usr/local/tomcat/webapps1.10、 USERUSER命令用于指定当前望下执行的用户,需要注意的是这个用户必须是已经存在,否则无法指定。它的用法和WORKDIR有点像,切换用户。格式:USER daemon1.11、ADD作用和使用方法和COPY一模一样,在此不重复讲述。1.12、ONBUILDONBUILD用于配置当前所创建的镜像作为其它新创建镜像的基础镜像时,所执行的操作指令。意思就是:这个镜像创建后,如果其它镜像以这个镜像为基础,会先执行这个镜像的ONBUILD命令格式:ONBUILD [INSTRUCTION]1.13、ENV:设置环境变量ENV命名用于设置容器的环境变量,这些变量以”key=value”的形式存在,在容器内被脚本或者程序调用,容器运行的时候这个变量也会保留。格式:1) 设置一个: ENV <key> <value>2) 设置多个:ENV <key1>=<value1> <key2>=<value2>…如设置一个环境变量JAVA_HOME,接下来的命名就可以使用这个变量:ENV JAVA_HOME /opt/jdkENV PATH $PATH:$JAVA_HOME/bin在使用ENV设置环境变量时,有几点需要注意:1)具有传递性,也就是当前镜像被用作其它镜像的基础镜像时,新镜像会拥有当前这个基础镜像所有的环境变量2)ENV定义的环境变量,可以在dockerfile被后面的所有指令(CMD除外)中使用,但不能被docker run 的命令参数引用如:ENV tomcat_home_name tomcat_7RUN mkdir $tomcat_home_name3)除了ENV之外,docker run -e 也可以设置环境变量传入容器内。如:docker run -d tomcat -e “tomcat_home_name=tomcat_7"这样我们进入容器内部用ENV可以看到tomcat_home_name这个环境变量。2 Dockerfile的编写我们先看一个例子#在centos上安装nginxFROM centos#标明著作人的名称和邮箱MAINTAINER jiabuli 649917837@qq.com#测试一下网络环境RUN ping -c 1 www.baidu.com#安装nginx必要的一些软件RUN yum -y install gcc make pcre-devel zlib-devel tar zlib#把nginx安装包复制到/usr/src/目录下ADD nginx-1.15.8.tar.gz /usr/src/#切换到/usr/src/nginx-1.15.8编译并且安装nginxRUN cd /usr/src/nginx-1.15.8 \ && mkdir /usr/local/nginx \ && ./configure –prefix=/usr/local/nginx && make && make install \ && ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/ \ && nginx#删除安装nginx安装目录RUN rm -rf /usr/src/nginx-nginx-1.15.8#对外暴露80端口EXPOSE 80#启动nginxCMD [“nginx”, “-g”, “daemon off;"]上面的注释已经讲的非常清楚,其实不难发现,上面的例子就是类似于在centos系统上安装一个nginx的的一个过程,因此编写Dockerfile构建镜像就和在Linux上安装软件的流程几乎是一模一样的。所以我们在编写Dockerfile来构建镜像时,可以先思考在Linux上安装该软件的流程,再用Dockerfile提供的指令转化到Dockerfile中即可。3.用Dockerfile构建镜像用Dockerfile的核心在于编写Dockerfile,但是编写完之后我们需要知道怎么使用Dockerfile来构建镜像,下面以构建nginx镜像为例来简要说明构建流程3.1 上传安装包首先我们需要把要构建的软件安装包上传到服务器中,我们可以在服务器目录上创建一个专门的文件夹,如:/var/nginx_build,然后把从nginx官网下载的nginx-1.15.8.tar.gz安装包上传到这个目录里。3.2 编写Dockerfile如何编写nginx的Dockerfile上面已经详细介绍,现在我们只需把编写好的Dockerfile上传到/var/nginx_build目录下,当然你也可以在服务器上直接编写Dockerfile,但是要记得一定保证Dockerfile文件和安装包在一个目录下。3.3 运行构建命令构建docker build 命令用于使用 Dockerfile 创建镜像。格式: docker build [OPTIONS] PATH | URL | -OPTIONS有很多指令,下面列举几个常用的:–build-arg=[] :设置镜像创建时的变量;-f :指定要使用的Dockerfile路径;–force-rm :设置镜像过程中删除中间容器;–rm :设置镜像成功后删除中间容器;–tag, -t: 镜像的名字及标签,通常 name:tag 或者 name 格式;因此我们构建nginx可以用以下命令:docker build -t nginx:v1.0 .当Dockerfile和当前执行命令的目录不在同一个时,我们也可以指定Dockerfile,如docker build -f /var/nginx_build/Dockerfile .执行命名之后,会看到控制台逐层输出构建内容,直到输出两个Successfully即为构建成功。4. 彩蛋写了很多篇docker的文章,为了方便开发者们学习和查阅docker的基础知识,我做了一份完整的docker基础整理,发布在gitchat上面,有兴趣的读者可以加入一起学习,我这里还有6个免费名额,如有需要,可以加微信:sisi-ceo 索要。觉得本文对你有帮助?请分享给更多人关注「编程无界」,提升装逼技能 ...

February 19, 2019 · 1 min · jiezi

认识docker

一、Docker工作原理二、Docker容器和虚拟机对比三、镜像容器管理1、Docker关键组件2、Docker架构3、Docker内部组件镜像(Image)——一个特殊的文件系统Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)容器(Container)——镜像运行时的实体容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等仓库(Repository)——集中存放镜像文件的地方镜像构建完成后,可以很容易的在当前宿主上运行,但是, 如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry就是这样的服务Docker采用了C/S架构。客户端和服务端可以运行在一个机器上,也可以通过socket或者RESTful API 来进行通信。Docker Daemon: 一般在宿主机后台运行,等待接收客户端的消息Docker Client:则为客户提供一系列可执行的命令, 用户使用这些命令跟docker daemon交互Docker daemon:Docker daemmon是Docker架构中的主要用户接口。首先,它提供了API Server用于接收来自Docker client的请求,其后根据不同的请求分发给Docker daemon的不同模块执行相应的工作Image managerment:需要创建DOcker容器时,可通过镜像管理(image management)部分的distribution和registry模块从Docker registry中下载镜像,并通过镜像管理的image、reference和layer存储镜像的元数据,通过镜像存储驱动graphdriver将镜像文件存储于具体的文件系统中Network:当需要为Docker容器创建网络环境时,通过网络模块network调用libnetwork创建并配置Docker容器的网络环境Volume:当需要为容器创建数据卷volume时,则通过volume模块调用某个具体的volumedrive,来创建一个数据卷并负责后续的挂载操作Execdriver:当需要限制Docker容器运行资源或执行用户指令操作时,则通过execdrive来完成Libcontainer:是对cgroups和namespace的二次封装,execdrive是通过libcontainer来实现对容器的具体管理,包括利用UTS、IPC、PID、Network、Mount、User等namespace实现容器之间的资源隔离和利用cgroups实现对容器的资源限制.当运行容器的命令执行完毕后,一个实际的容器就处于运行状态,该容器具有独立的文件系统、相对安全且相互隔离的运行环境.1、用户是使用Docker Client与Docker Daemon建立通信,并发送请求给后者2、Engine执行Docker内部的一系列工作,每一项工作都是以一个Job的形式的存在。3、Job的运行过程中,当需要容器镜像时,则从Docker Registry中下载镜像,并通过镜像管理驱动graphdriver将下载镜像以Graph的形式存储;当需要为Docker创建网络环境时,通过网络管理驱动networkdriver创建并配置Docker容器网络环境;当需要限制Docker容器运行资源或执行用户指令等操作时,则通过execdriver来完成。libcontainer是一项独立的容器管理包,networkdriver以及execdriver都是通过libcontainer来实现具体对容器进行的操作。1、容器和虚拟机对比2、Docker的优势3、Docker的劣势4、Docker的应用场景Docker 的的优势:持续部署和测试发到产品发布的整个过程中使用相同的容器来确保没有任何差异或者人工干预。Docker可以保证测试环境、开发环境、生产环境的一致性。可移植性容器可以移动到任意一台Docker主机上,而不需要过多关注底层系统。弹性伸缩更快速配合K8S可以很容易的无状态应用的弹性伸缩,只需要改一个yml的数字即可。利用docker能在几秒钟之内启动大量的容器,这是虚拟机无法办到的,快速启动,秒级和分钟级的对比。资源利用率高由于docker不需要Hypervisor实现硬件资源虚拟化,docker容器和内核交互,几乎没有性能损耗,性能优于通过Hypervisor层与内核层的虚拟化。一台机器启动上前台容器也没问题。对硬件无要求不需要CPU支持虚拟化Docker 的的劣势资源隔离docker是利用cgroup实现资源隔离的,只能限制资源消耗的最大值,而不能隔绝其他应用程序占用自己的资源; docker属于进程之间的隔离,虚拟机可实现系统级别隔离;安全性问题一个用户拥有执行docker的权限,可以删除任何用户创建的容器。兼容性问题docker目前还在版本快速更新中,细节功能调整较大,一些核心的模块依赖于高版本的内核,存在兼容性的问题。1、Docker安装2、认识镜像和容器3、镜像容器管理什么是镜像?镜像是一个多层的联合只读的文件系统。什么是容器?容器是在镜像基础上加上读写层。容器即进程。构建镜像的过程?镜像->镜像+可写层+执行命令->commit为新的镜像(新的一层)->镜像+可写层+执行命令->commit为新的镜像(新的一层)->…典型文件系统启动 :一个典型的 Linux 文件系统由 bootfs 和 rootfs 两部分组成,bootfs(boot file system) 主要包含 bootloader 和 kernel,bootloader 主要用于引导加载 kernel,当 kernel 被加载到内存中后 bootfs 会被 umount 掉rootfs (root file system)包含的就是典型 Linux 系统中的/dev,/proc,/bin,/etc 等标准目录和文件加载过程:bootfs 时会先将 rootfs 设为 read-only,然后在系统自检之后将 rootfs 从 read-only 改为 read-write,Docker文件系统启动:Docker 在 bootfs 自检完毕之后并不会把 rootfs 的 read-only 改为 read-write,而是利用 union mount(UnionFS 的一种挂载机制)将 image 中的其他的 layer 加载到之前的 read-only 的 rootfs 层之上,每一层 layer 都是 rootfs 的结构,并且是read-only 的。所以,我们是无法修改一个已有镜像里面的 layer 的!只有当我们创建一个容器,也就是将 Docker 镜像进行实例化,系统会分配一层空的 read-write 的 rootfs ,用于保存我们做的修改DockerfileFROM centosENV TZ “Asia/Shanghai"ADD echo.sh /opt/echo.shRUN chmod +x /opt/echo.shCMD ["/opt/echo.sh”]docker build -t test -f Dockerfile . 镜像工作原理:如果运行中的容器修改一个已经存在的文件,那么会将该文件从下面的只读层复制到读写层,只读层的这个文件就会覆盖(隐藏),但还存在。如果删除一个文件,在最上层会被标记隐藏,实际只读层的文件还存在。这就实现了文件系统隔离,当删除容器后,读写层的数据将会删除,只读镜像不变。查看具体的挂载逻辑[root@centos7 l]# mount|grep overlayoverlay on /var/lib/docker/overlay2/56375ce93fd54484061ef08a48a7093905be680dd14754642970616127b30fca/merged type overlay (rw,relatime,seclabel,lowerdir=/var/lib/docker/overlay2/l/A6JYT4QIFZMKOPIGY675JWKS7F:/var/lib/docker/overlay2/l/4L4SUINS3DX6XPD5BL2J54JQDT,upperdir=/var/lib/docker/overlay2/56375ce93fd54484061ef08a48a7093905be680dd14754642970616127b30fca/diff,workdir=/var/lib/docker/overlay2/56375ce93fd54484061ef08a48a7093905be680dd14754642970616127b30fca/work)Overlay和overlay2的区别overlay: 只挂载一层,其他层通过最高层通过硬连接形式共享(增加了磁盘inode的负担)overlay2: 逐层挂载(最多128层)基础镜像的层信息docker pull centostree -L 2 /var/lib/docker/overlay2/构建后镜像的层信息cd layer_dockerfile/docker build -t centos:test -f ./Dockerfile .tree -L 2 /var/lib/docker/overlay2/每一层都包含了”该层独有的文件”以及”和其低层共享的数据的连接”,在Docker 1.10之前的版本中,目录的名字和镜像的UUID相同,而Docker 1.10后则采用了新的存储方式,可以看到目录名和下载镜像的UUID并不相同Diff存放挂载点的具体的文件内容Link对应l目录的链接源的名称Lower根没有lower,其它的lower指向的父层的链接L:”l“目录包含一些符号链接作为缩短的层标识符. 这些缩短的标识符用来避免挂载时超出页面大小的限制docker run -idt –name centos_con centos:test /bin/bashtree -L 2 /var/lib/docker/overlay2/多出的两层“……”为读写层,“…..-init”为初始层。初始层:初始层中大多是初始化容器环境时,与容器相关的环境信息,如容器主机名,主机host信息以及域名服务文件等。读写层:所有对容器做出的改变都记录在读写层Diff存放挂载点的具体的文件内容Link对应l目录的链接源的名称Lower根没有lower,其它的lower指向的父层的链接Merged如果是读写层会有一个MergedCommit:容器提交为镜像docker run -idt –name test centosTouch liweidocker commit 6de test2Create:创建容器但是不启动docker create –name nginx-con -p80:80 nginx:latestStart:启动容器docker start nginx-conStop:停止容器docker stop nginx-conKill:杀掉容器,和停止相比不友好docker kill nginx-conPause:暂停容器docker pause nginx-conUnpause:恢复暂停的容器docker unpause nginx-conRun:创建且启动容器docker run -idt –restart=always –name nginx_con -v /tmp/:/mnt -p 88:80 -e arg1=arg1 nginxDocker attach nginx_conCtrl+^p+^qCP:宿主机和容器之间copy文件docker cp docker_install.sh nginx_con:/optdocker exec nginx_con ls /optdocker cp nginx_con:/opt/docker_install.sh ./1.shExec:执行命令,也可附加到容器docker exec nginx_con ls /optAttach:附加到容器docker attach nginx_condocker exec -it nginx_con /bin/bashLogs:查看容器日志docker logs –f nginx_conInspect:查看元数据,可以查看镜像和容器docker inspect nginx_conPort:查看容器端口映射docker port nginx_conTop:查看容器中正在运行的进程docker top nginx_conPs:查看容器docker psdocker ps -adocker ps -aq查看正在运行的容器,加上-a查看所有容器(包含停止和暂停状态的容器)Rm:删除容器docker rm nginx_con 删除容器docker rm -f nginx_con 强行删除容器Export:导出容器docker pull busyboxdocker run -itd busyboxdocker export 983989307eef>busybox.tarImport:导入容器docker import busybox.tar busybox:1.3Save:导出镜像docker save busybox:1.3>busybox1.3.tarLoad:导入镜像docker load -i busybox1.3.tar Tag:镜像打标签docker tag busybox:1.3 192.168.199.160/test/busybox:latestBuild:从dockerfile构建镜像FROM centosENV TZ “Asia/Shanghai"ADD echo.sh /opt/echo.shRUN chmod +x /opt/echo.shCMD ["/opt/echo.sh”]docker build -t centos:test -f Dockerfile . Pull:从 registry拉取镜像docker pull nginx 从dockerhub上拉取docker pull 192.168.199.160/test/nginx:latest 从内网harbor上拉取Push:推送镜像到仓库[第一次需要输入密码,后续不需要了]docker login 192.168.199.160adminHarbor12345docker push 192.168.199.160/test/busybox:latestInfo、version、eventsdocker info 查看docker相关信息信息Docker version 查看docker相关版本信息Docker events 查看docker事件【注】1、创建容器后防火墙不要再动2、cmd会被覆盖的问题,需要注意,可能会导致/bin/bash 把启动命令覆盖了,启动不了的问题例如docker run -idt –restart=always –name nginx_con -v /tmp/:/mnt -p 88:80 -e arg1=arg1 nginx /bin/bash3、cmd的命令都会在挂在后执行。 ...

January 30, 2019 · 2 min · jiezi

Dockerfile、Docker-Compose基本命令与介绍

一、Dockerfile基本命名指令说明备注FROM指定所创建镜像的基础镜像第一条指令必须为 FROM 指令。格式为 FROM <image> 或FROM <image>:<tag> 。MAINTAINER指定维护者信息格式为 MAINTAINER <name>RUN运行命令在镜像中要执行的命令,格式为 RUN <command> 或 RUN [“executable”, “param1”, “param2”]。前者默认将在 shell 终端中运行命令,即 /bin/bash -c ;后者则使用 exec 执行。指定使用其它终端可以通过第二种方式实现,例如 RUN [“/bin/bash”, “-c”,”echo hello”] 。每条RUN指令将在当前镜像的基础上执行指定命令,并提交为新的镜像。当命令较长时可以使用换行。例如:RUN apt-get update &amp;& apt-get install -ylibsnappy-dev zliblg-dev libbz2-dev &amp;& rm -rf /var/cache/aptCMD指定启动容器时默认执行的命令支持三种格式:1. CMD[“executable”,“param1”,“param2”] 使用 exec 执行,推荐方式;2. CMD command param1 param2 在 /bin/bash 中执行,提供给需要交互的应用;3. CMD [“param1”,“param2”] 提供给 ENTRYPOINT 的默认参数;LABEL指定生成镜像的元数据标签信息 EXPOSE声明镜像内服务所监听的端口指定容器要打开的端口ENV指定环境变量格式为 ENV <key> <value> 。 指定一个环境变量,会被后续 RUN 指令使用,并在容器运行时保持。ADD赋值指定的路径下的内容到容器中的路径下,可以为URL;如果为tar文件,会自动解压到路径下相当于 COPY,但是比 COPY 功能更强大COPY赋值本地主机的路径下的内容到容器中的路径下;一般情况下推荐使用COPY而不是ADD复制本地主机的 (为 Dockerfile 所在目录的相对路径)到容器中的ENTRYPOINT指定镜像的默认入口 VOLUME创建数据挂载点挂载目录,格式为VOLUME ["/data"]USER指定运行容器时的用户名或UID WORKDIR配置工作目录指定当前工作目录,相当于 cdARG指定镜像内使用的参数(例如版本号信息等) ONBUILD配置当前所创建的镜像作为其他镜像的基础镜像时,所执行的创建操作的命令 STOPSIGNAL容器退出的信号 HEALTHCHECK如何进行健康检查 SHELL指定使用SHELL时的默认SHELL类型 二、Dockerfile 基本结构 一般的,Dockerfile 分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令。’#’ 为 Dockerfile 中的注释。先看下面一个小例子:# This my first nginx Dockerfile# Version 1.0# Base images 基础镜像FROM centos#MAINTAINER 维护者信息MAINTAINER tianfeiyu #ENV 设置环境变量ENV PATH /usr/local/nginx/sbin:$PATH#ADD 文件放在当前目录下,拷过去会自动解压ADD nginx-1.8.0.tar.gz /usr/local/ ADD epel-release-latest-7.noarch.rpm /usr/local/ #RUN 执行以下命令 RUN rpm -ivh /usr/local/epel-release-latest-7.noarch.rpmRUN yum install -y wget lftp gcc gcc-c++ make openssl-devel pcre-devel pcre && yum clean allRUN useradd -s /sbin/nologin -M www#WORKDIR 相当于cdWORKDIR /usr/local/nginx-1.8.0 RUN ./configure –prefix=/usr/local/nginx –user=www –group=www –with-http_ssl_module –with-pcre && make && make installRUN echo “daemon off;” >> /etc/nginx.conf#EXPOSE 映射端口EXPOSE 80#CMD 运行以下命令CMD [“nginx”]三、构建镜像3.1 编写Dockerfile文件vim DockerfileFROM alpine:latestMAINTAINER troyCMD echo “Hello Workd!“3.2 构建镜像docker build -t hello_world .3.3 运行镜像docker run hello_world记:1.表示当前用户使用的shell是/bin/bash,所谓的shell你可以理解为操作系统和人之间交互的平台。例如windows系统的桌面环境就是一个shell。bin目录中基本上都是可执行的命令。启动容器并启动bash(交互方式):$docker run -i -t <image_name/continar_id> /bin/bash2.保存对容器的修改(commit) 当你对某一个容器做了修改之后(通过在容器中运行某一个命令),可以把对容器的修改保存下来,这样下次可以从保存后的最新状态运行该容器。$docker commit ID new_image_name 当然如果在保存成新镜像的时候想添加新的 dockerfile命令,比如,启动进入新的目录。docker commit -c “WORKDIR /usr/bin” 07c5f9ed32b0 test-images当然你也可以在旧镜像的基础上写一个新的dockerfile,用dockerfile生成新的镜像。Note: image相当于类,container相当于实例,不过可以动态给实例安装新软件,然后把这个container用commit命令固化成一个image。四、Docker-Compose 一句话:docker-compose 是用来做docker 的多容器控制,是一个用来把 docker 自动化的东西。有了 docker-compose 你可以把所有繁复的 docker 操作全都一条命令,自动化的完成。4.1 常用命令docker-compose up -d nginx 构建建启动nignx容器docker-compose exec nginx bash 登录到nginx容器中docker-compose down 删除所有nginx容器,镜像docker-compose ps 显示所有容器docker-compose restart nginx 重新启动nginx容器docker-compose run –no-deps –rm php-fpm php -v 在php-fpm中不启动关联容器,并容器执行php -v 执行完成后删除容器docker-compose build nginx 构建镜像 。 docker-compose build –no-cache nginx 不带缓存的构建。docker-compose logs nginx 查看nginx的日志 docker-compose logs -f nginx 查看nginx的实时日志docker-compose config -q 验证(docker-compose.yml)文件配置,当配置正确时,不输出任何内容,当文件配置错误,输出错误信息。 docker-compose events –json nginx 以json的形式输出nginx的docker日志docker-compose pause nginx 暂停nignx容器docker-compose unpause nginx 恢复ningx容器docker-compose rm nginx 删除容器(删除前必须关闭容器)docker-compose stop nginx 停止nignx容器docker-compose start nginx 启动nignx容器4.2 docker-compose.ymldepends_on在使用 Compose 时,最大的好处就是少打启动命令,但是一般项目容器启动的顺序是有要求的,如果直接从上到下启动容器,必然会因为容器依赖问题而启动失败。例如在没启动数据库容器的时候启动了应用容器,这时候应用容器会因为找不到数据库而退出,为了避免这种情况我们需要加入一个标签,就是 depends_on,这个标签解决了容器的依赖、启动先后的问题。例如下面容器会先启动 redis 和 db 两个服务,最后才启动 web 服务:version: ‘2’services: web: build: . depends_on: - db - redis redis: image: redis db: image: postgres注意的是,默认情况下使用 docker-compose up web 这样的方式启动 web 服务时,也会启动 redis 和 db 两个服务,因为在配置文件中定义了依赖关系。links还记得上面的depends_on吧,那个标签解决的是启动顺序问题,这个标签解决的是容器连接问题,与Docker client的–link一样效果,会连接到其它服务中的容器。格式如下:links: - db - db:database - redis使用的别名将会自动在服务容器中的/etc/hosts里创建。例如:172.12.2.186 db172.12.2.186 database172.12.2.187 redis相应的环境变量也将被创建。volumes挂载一个目录或者一个已存在的数据卷容器,可以直接使用 [HOST:CONTAINER] 这样的格式,或者使用 [HOST:CONTAINER:ro] 这样的格式,后者对于容器来说,数据卷是只读的,这样可以有效保护宿主机的文件系统。Compose的数据卷指定路径可以是相对路径,使用 . 或者 .. 来指定相对目录。数据卷的格式可以是下面多种形式:volumes: // 只是指定一个路径,Docker 会自动在创建一个数据卷(这个路径是容器内部的)。 - /var/lib/mysql // 使用绝对路径挂载数据卷 - /opt/data:/var/lib/mysql // 以 Compose 配置文件为中心的相对路径作为数据卷挂载到容器。 - ./cache:/tmp/cache // 使用用户的相对路径(~/ 表示的目录是 /home/<用户目录>/ 或者 /root/)。 - ~/configs:/etc/configs/:ro // 已经存在的命名的数据卷。 - datavolume:/var/lib/mysql如果你不使用宿主机的路径,你可以指定一个volume_driver。volume_driver: mydrivervolumes_from从其它容器或者服务挂载数据卷,可选的参数是 :ro或者 :rw,前者表示容器只读,后者表示容器对数据卷是可读可写的。默认情况下是可读可写的。volumes_from: - service_name - service_name:ro - container:container_name - container:container_name:rw参考文档:1. docker与dockerfile教程 2. Docker系列教程22-docker-compose.yml常用命令 ...

January 16, 2019 · 2 min · jiezi

Docker问题:Dockerfile的From之前不能使用ARG

问题在使用开源Dockerfile构建镜像时,dockerfile的From之前通过ARG定义版本,指定基础镜像,如下:ARG VERSION=lastedFROM alpine:${VERSION}执行docker build报错如下:Please provide a source image with from prior to commit原因允许这种用法是在docker 17.05.0-ce (2017-05-04)之后才引入的,查看本机版本为17.03.2-ce,所以报错很正常了,可以参见Allow using build-time args (ARG) in FROM #31352解决方案更新docker版本

January 8, 2019 · 1 min · jiezi

Kubernetes pod里一个特殊的容器:pause-amd64

大家在使用Docker容器或者Kubernetes时,遇到过这个容器么?gcr.io/google_containers/pause-amd64docker ps的命令返回的结果:[root@k8s-minion1 kubernetes]# docker ps |grep pausec3026adee957 gcr.io/google_containers/pause-amd64:3.0 “/pause” 22 minutes ago Up 22 minutes k8s_POD.d8dbe16c_redis-master-343230949-04glm_default_ce3f60a9-095d-11e7-914b-0a77ecd65f3e_66c108d5202df18d636e gcr.io/google_containers/pause-amd64:3.0 “/pause” 24 hours ago Up 24 hours k8s_POD.d8dbe16c_kube-proxy-js0z0_kube-system_2866cfc2-0891-11e7-914b-0a77ecd65f3e_c8e1a667072d3414d33a gcr.io/google_containers/pause-amd64:3.0 “/pause” 24 hours ago Up 24 hours k8s_POD.d8dbe16c_kube-flannel-ds-tsps5_default_2866e3fb-0891-11e7-914b-0a77ecd65f3e_be4b719e[root@k8s-minion1 kubernetes]#Kubernetes的官网解释:it’s part of the infrastructure. This container is started first in all Pods to setup the network for the Pod.意思是:pause-amd64是Kubernetes基础设施的一部分,Kubernetes管理的所有pod里,pause-amd64容器是第一个启动的,用于实现Kubernetes集群里pod之间的网络通讯。对这个特殊容器感兴趣的朋友,可以阅读其源代码:https://github.com/kubernetes…我们查看这个pause-amd64镜像的dockerfile,发现实现很简单,基于一个空白镜像开始:FROM scratchARG ARCHADD bin/pause-${ARCH} /pauseENTRYPOINT ["/pause"]ARG指令用于指定在执行docker build命令时传递进去的参数。这个pause container是用C语言写的:https://www.ianlewis.org/en/a…在运行的Kubernetes node上运行docker ps,能发现这些pause container:pause container作为pod里其他所有container的parent container,主要有两个职责:是pod里其他容器共享Linux namespace的基础扮演PID 1的角色,负责处理僵尸进程这两点我会逐一细说。在Linux里,当父进程fork一个新进程时,子进程会从父进程继承namespace。目前Linux实现了六种类型的namespace,每一个namespace是包装了一些全局系统资源的抽象集合,这一抽象集合使得在进程的命名空间中可以看到全局系统资源。命名空间的一个总体目标是支持轻量级虚拟化工具container的实现,container机制本身对外提供一组进程,这组进程自己会认为它们就是系统唯一存在的进程。在Linux里,父进程fork的子进程会继承父进程的命名空间。与这种行为相反的一个系统命令就是unshare:再来聊聊pause容器如何处理僵尸进程的。Pause容器内其实就运行了一个非常简单的进程,其逻辑可以从前面提到的Pause github仓库上找到:static void sigdown(int signo) { psignal(signo, “Shutting down, got signal”); exit(0);}static void sigreap(int signo) { while (waitpid(-1, NULL, WNOHANG) > 0);}int main() { if (getpid() != 1) /* Not an error because pause sees use outside of infra containers. */ fprintf(stderr, “Warning: pause should be the first process\n”); if (sigaction(SIGINT, &(struct sigaction){.sa_handler = sigdown}, NULL) < 0) return 1; if (sigaction(SIGTERM, &(struct sigaction){.sa_handler = sigdown}, NULL) < 0) return 2; if (sigaction(SIGCHLD, &(struct sigaction){.sa_handler = sigreap, .sa_flags = SA_NOCLDSTOP}, NULL) < 0) return 3; for (;;) pause(); fprintf(stderr, “Error: infinite loop terminated\n”); return 42;}这个c语言实现的进程,核心代码就28行:其中第24行里一个无限循环for(;;), 至此大家能看出来pause容器名称的由来了吧?这个无限循环里执行的是一个系统调用pause,因此pause容器大部分时间都在沉睡,等待有信号将其唤醒。接收什么信号呢?一旦收到SIGCHLD信号,pause进程就执行注册的sigreap函数。看下SIGCHLD信号的帮助:SIGCHLD,在一个进程正常终止或者停止时,将SIGCHLD信号发送给其父进程,按系统默认将忽略此信号,如果父进程希望被告知其子系统的这种状态,则应捕捉此信号。pause进程注册的信号处理函数sigreap里,调用另一个系统调用waitpid来获得子进程终止的原因。希望这篇文章对大家理解Kubernetes里的pause容器有所帮助。感谢阅读。要获取更多Jerry的原创文章,请关注公众号"汪子熙": ...

December 21, 2018 · 1 min · jiezi

容器和容器镜像的区别,您真的了解吗

很多刚刚接触容器技术的朋友,不容易弄清楚容器,容器镜像和Docker这几个词的区别和联系。我们首先来看容器和容器镜像。举个例子,执行命令行docker search nginx,搜索结果的一条条记录就是一个个容器镜像。所谓镜像,就是一个静态概念,一个镜像由若干只读层(read-only layer)构成。上图左边是Docker镜像的内部实现细节,我们能看到多个只读层叠加在一起,层与层之间通过指针关联,这些层能够在运行Docker的宿主机的文件系统上访问到。Linux的统一文件系统(union file system)技术将这些叠加的只读层合并成一个文件系统,该系统为这些只读层提供了一个统一的视角,从而为Docker的用户隐藏了多层的存在。从Docker用户的视角出发,一个Docker镜像只存在一个文件系统,即上图右边所示。这些文件系统的设计是Docker实现细节,一般情况下我们不用去深究。但如果您足够好奇,使用命令sudo tree浏览目录 /var/lib/docker即可:比如我用命令docker images浏览下载到本地的docker镜像:其中一个叫jerry-nginx的镜像,是一个web应用,它的所有内容能在/var/lib/docker目录下的这个目录查到:讲完了容器镜像,我们再来看容器。容器和容器镜像一样,也是若干层的叠加,唯一区别是所有只读层的最上面一层,是一层可读可写层,如上图绿色图例所示。初学者可以记住这个简单的公式:容器 = 容器镜像 + 可读可写层我们如果用命令docker ps –all查看本机所有容器列表,会发现有的容器处于运行状态,有的处于退出状态。因此,一个处于运行状态的容器(running container)包含一个可读写的文件系统加上隔离的进程空间。容器里的进程可以对这个可读写文件系统内的文件进行修改、删除、创建等操作。镜像里每一层其实都能在docker文件夹的containers子目录下找到:上图每一个红色文件夹代表镜像里的一层,蓝色文件包含了该层运行时的日志文件,或者网络相关配置等。做个实验:ubuntu这个容器执行结束后,使用find / -name i042416.txt文件,这说明docker运行时能对宿主机的文件系统进行写操作。下面分析几个常用的易混淆的命令。docker create <image-id>先看它的帮助文档:试着执行以下:产生一个输出id:7ee10851c3f1e53bbd35e5f196f34de560afa1a20d9bf1ced587630dbcda877bcreate创建的容器,状态变为created:docker create命令给通过命令行传入的容器镜像创建了一个新的可读可写层,从而生成了一个新的容器实例:然后再执行docker start,输入docker create创建的容器实例ID,就可以启动这个容器实例了。而docker run其实就是docker create和docker start这两个命令合二为一的版本。希望这篇文章能帮助大家理解容器和容器镜像的区别。要获取更多Jerry的原创文章,请关注公众号"汪子熙":

December 21, 2018 · 1 min · jiezi

Docker技术三大要点:cgroup, namespace和unionFS的理解

www.docker.com的网页有这样一张有意思的动画:从这张gif图片,我们不难看出Docker网站想传达这样一条信息, 使用Docker加速了build,ship和run的过程。Docker最早问世是2013年,以一个开源项目的方式被大家熟知。Docker的奠基者是dotcloud,一家开发PaaS平台的技术公司。不过可惜的是,这家公司把Docker开源之后,于2016年倒闭了,因为其主业务PaaS无法和微软,亚马逊等PaaS业界巨头竞争,不禁让人唏嘘。Docker其实是容器化技术的具体技术实现之一,采用go语言开发。很多朋友刚接触Docker时,认为它就是一种更轻量级的虚拟机,这种认识其实是错误的,Docker和虚拟机有本质的区别。容器本质上讲就是运行在操作系统上的一个进程,只不过加入了对资源的隔离和限制。而Docker是基于容器的这个设计思想,基于Linux Container技术实现的核心管理引擎。为什么资源的隔离和限制在云时代更加重要?在默认情况下,一个操作系统里所有运行的进程共享CPU和内存资源,如果程序设计不当,最极端的情况,某进程出现死循环可能会耗尽CPU资源,或者由于内存泄漏消耗掉大部分系统资源,这在企业级产品场景下是不可接受的,所以进程的资源隔离技术是非常必要的。我当初刚接触Docker时,以为这是一项新的技术发明,后来才知道,Linux操作系统本身从操作系统层面就支持虚拟化技术,叫做Linux container,也就是大家到处能看到的LXC的全称。LXC的三大特色:cgroup,namespace和unionFS。cgroup:CGroups 全称control group,用来限定一个进程的资源使用,由Linux 内核支持,可以限制和隔离Linux进程组 (process groups) 所使用的物理资源 ,比如cpu,内存,磁盘和网络IO,是Linux container技术的物理基础。namespace:另一个维度的资源隔离技术,大家可以把这个概念和我们熟悉的C++和Java里的namespace相对照。如果CGroup设计出来的目的是为了隔离上面描述的物理资源,那么namespace则用来隔离PID(进程ID),IPC,Network等系统资源。我们现在可以将它们分配给特定的Namespace,每个Namespace里面的资源对其他Namespace都是透明的。不同container内的进程属于不同的Namespace,彼此透明,互不干扰。我们用一个例子来理解namespace的必要。假设多个用户购买了一台Linux服务器的Nginx服务,每个用户在该服务器上被分配了一个Linux系统的账号。我们希望每个用户只能访问分配给其的文件夹,这当然可以通过Linux文件系统本身的权限控制来实现,即一个用户只能访问属于他本身的那些文件夹。但是有些操作仍然需要系统级别的权限,比如root,但我们肯定不可能给每个用户都分配root权限。因此我们就可以使用namespace技术:我们能够为UID = n的用户,虚拟化一个namespace出来,在这个namespace里面,该用户具备root权限,但是在宿主机上,该UID =n的用户还是一个普通用户,也感知不到自己其实不是一个真的root用户这件事。同样的方式可以通过namespace虚拟化进程树。在每一个namespace内部,每一个用户都拥有一个属于自己的init进程,pid = 1,对于该用户来说,仿佛他独占一台物理的Linux服务器。对于每一个命名空间,从用户看起来,应该像一台单独的Linux计算机一样,有自己的init进程(PID为1),其他进程的PID依次递增,A和B空间都有PID为1的init进程,子容器的进程映射到父容器的进程上,父容器可以知道每一个子容器的运行状态,而子容器与子容器之间是隔离的。从图中我们可以看到,进程3在父命名空间里面PID 为3,但是在子命名空间内,他就是1.也就是说用户从子命名空间 A 内看进程3就像 init 进程一样,以为这个进程是自己的初始化进程,但是从整个 host 来看,他其实只是3号进程虚拟化出来的一个空间而已。看下面的图加深理解。父容器有两个子容器,父容器的命名空间里有两个进程,id分别为3和4, 映射到两个子命名空间后,分别成为其init进程,这样命名空间A和B的用户都认为自己独占整台服务器。Linux操作系统到目前为止支持的六种namespace:unionFS:顾名思义,unionFS可以把文件系统上多个目录(也叫分支)内容联合挂载到同一个目录下,而目录的物理位置是分开的。要理解unionFS,我们首先要认识bootfs和rootfs。1. boot file system (bootfs):包含操作系统boot loader 和 kernel。用户不会修改这个文件系统。一旦启动完成后,整个Linux内核加载进内存,之后bootfs会被卸载掉,从而释放出内存。同样内核版本的不同的 Linux 发行版,其bootfs都是一致的。2. root file system (rootfs):包含典型的目录结构,包括 /dev, /proc, /bin, /etc, /lib, /usr, and /tmp就是我下面这张图里的这些文件夹:等再加上要运行用户应用所需要的所有配置文件,二进制文件和库文件。这个文件系统在不同的Linux 发行版中是不同的。而且用户可以对这个文件进行修改。Linux 系统在启动时,roofs 首先会被挂载为只读模式,然后在启动完成后被修改为读写模式,随后它们就可以被修改了。不同的Linux版本,实现unionFS的技术可能不一样,使用命令docker info查看,比如我的机器上实现技术是overlay2:看个实际的例子。新建两个文件夹abap和java,在里面用touch命名分别创建两个空文件:新建一个mnt文件夹,用mount命令把abap和java文件夹merge到mnt文件夹下,-t执行文件系统类型为aufs:sudo mount -t aufs -o dirs=./abap:./java none ./mntmount完成后,到mnt文件夹下查看,发现了来自abap和java文件夹里总共4个文件:现在我到java文件夹里修改spring,比如加上一行spring is awesome, 然后到mnt文件夹下查看,发现mnt下面的文件内容也自动被更新了。那么反过来会如何呢?比如我修改mnt文件夹下的aop文件:而java文件夹下的原始文件没有受到影响:实际上这就是Docker容器镜像分层实现的技术基础。如果我们浏览Docker hub,能发现大多数镜像都不是从头开始制作,而是从一些base镜像基础上创建,比如debian基础镜像。而新镜像就是从基础镜像上一层层叠加新的逻辑构成的。这种分层设计,一个优点就是资源共享。想象这样一个场景,一台宿主机上运行了100个基于debian base镜像的容器,难道每个容器里都有一份重复的debian拷贝呢?这显然不合理;借助Linux的unionFS,宿主机只需要在磁盘上保存一份base镜像,内存中也只需要加载一份,就能被所有基于这个镜像的容器共享。当某个容器修改了基础镜像的内容,比如 /bin文件夹下的文件,这时其他容器的/bin文件夹是否会发生变化呢?根据容器镜像的写时拷贝技术,某个容器对基础镜像的修改会被限制在单个容器内。这就是我们接下来要学习的容器 Copy-on-Write 特性。容器镜像由多个镜像层组成,所有镜像层会联合在一起组成一个统一的文件系统。如果不同层中有一个相同路径的文件,比如 /text,上层的 /text 会覆盖下层的 /text,也就是说用户只能访问到上层中的文件 /text。假设我有如下这个dockerfile:FROM debianRUN apt-get install emacsRUN apt-get install apache2CMD ["/bin/bash"]执行docker build .看看发生了什么。生成的容器镜像如下:当用docker run启动这个容器时,实际上在镜像的顶部添加了一个新的可写层。这个可写层也叫容器层。容器启动后,其内的应用所有对容器的改动,文件的增删改操作都只会发生在容器层中,对容器层下面的所有只读镜像层没有影响。要获取更多Jerry的原创文章,请关注公众号"汪子熙": ...

December 21, 2018 · 1 min · jiezi

docker指令学习记录

前言本文为学习整理和参考文章,不具有教程的功能。其次,后面将会陆续更新各种应用的容器化部署的实践,如MySQL容器化,Jenkins容器化,以供读者参考。镜像获取docker pull [options] [Docker Registry地址]<仓库名>:<标签>-a, –all-tags: 下载该镜像的所有版本Docker Registry地址默认为Docker Hub,一般格式为IP:端口号仓库名为两段式 <用户名>:<软件名> 默认用户名为library标签不填则默认为latest列出镜像docker images [options] [Repository[:tag]]默认情况会展示所有最终镜像,如果加上了镜像名,则会展示该镜像的所有信息-a, –all: 展示所有镜像,包括中间层-f, –filter filter: 根据某种条件对镜像进行筛选–format string: 使用go的模板语法-q, –quiet: 只返回镜像的IDdocker images -f since=mongo:3.2 #查看mongo3.2版本之后建立的镜像,如果是要在之前,则使用beforedocker images –format “{{.ID}}:{{.Repository}}” #输出结构为ID:Repository虚悬镜像虚悬镜像是指既没有仓库名,也没有标签的镜像。这种镜像的产生常常由于当前的仓库名和标签被更新版本占用,导致当前境像失效。docker images -f danling=true #列出所有虚悬镜像docker rmi $(docker images -q -f dangling=true) #利用复合指令删除虚悬镜像commit镜像commit会将容器的存储层保存下来成为新的镜像docker commit [options] <容器ID或容器名> [<仓库名>[:<标签>]]-a, –author string: 容器所有者-c, –change list: 在容器上执行Dockerfile指令-m, –message string: 提交信息-p, –pause: 提交过程中停止容器的运行,默认为truedocker history IMAGE #显示镜像的历史记录docker diff CONTAINER #查看容器的改动尽量不要使用commit指令构建镜像Dockerfile构建镜像利用Dockerfile构建镜像。docker build [options] PATH | URL | –f, –file string: Dockerfile的路径–rm: 成功构建后删除中间镜像-t, –tag: 以name:tag的形式为镜像命名docker build -t nginx:v3 . #执行当前目录下的Dockerfile并构建镜像,新的镜像名为nginx:v3docker build https://…… #直接从github构建,会自动clone这个项目,切换到指定分支(默认为master),并进入指定目录进行构建最后的路径是指镜像构建的上下文,docker在build的时候会把该上下文中的而所有内容全部打包上传给docker引擎。当在Dockerfile中需要引用相对路径时,就是以该上下文作为当前指令执行的目录。可以编写.dockerignore文件来剔除无需打包的文件。在默认情况下,如果不指定Dockerfile的位置,就会从构建的上下文寻找Dockerfile来执行FROM指定基础镜像,Dockerfile的第一行必须制定基础镜像RUN执行命令。RUN指令会新建一层并在其上执行指令,指令完成之后再commit该镜像。所以RUN指令中的内容应当尽可能合并,并且记得清除冗余的内容如缓存等。RUN <指令>RUN [“可执行文件”, “参数1”, “参数2”]RUN mkdir newDir \ && touch newFileCOPY将构建上下文中源路径中的内容复制到目标路径之下。可以使用通配符。如果目标目录不存在,容器会帮助创建。复制过程不改变文件属性。COPY 源路径 目标路径COPY [“源路径”,…,“目标路径”]COPY hom* /mydir/CMD默认的容器的主进程的启动命令,在运行时可以指定新的命令来替代镜像设置中的默认命令。比如ubuntu的默认指令是/bin/bash。如果使用第一种形式,则会以sh -c的形式执行,这样就能够得到环境变量。容器中的应用都应该前台执行。CMD <命令>CMD [“可执行文件”, “参数一”, “参数二”, …]CMD [“参数一”, “参数二”…]CMD [“nginx”, “-g”, “daemon off;"]docker run -it ubuntu #直接进入bash,因为默认指令为/bin/bashdocker run -it ubuntu /etc/os-release #默认指令变成/etc/os-releaseENTRYPOINT指定容器启动程序及参数,当指定了ENTRYPOINT之后,CMD的含义就变成了ENTRYPOINT的参数。从而实现我们在build镜像时可以根据配置修改启动指令的参数。在docker run运行时可以用–entrypoint覆盖ENTRYPOINT “CMD"ENTRYPOINT [“可执行文件”, “参数一”, “参数二”…]ENV设置环境变量ENV KEY VALUEENV KEY1=VALUE2 KEY2=VALUE2ARG同ENV,设置环境变量并为其提供默认值,不同的是在容器运行时,这些值将不存在。在运行时可以用–build-arg <参数名>:<值>覆盖ARG <参数名>[=默认值]VOLUMN指定匿名卷,防止用户忘记挂载,运行时用-v HOST_DIR/CONTAINER_DIR进行覆盖VOLUMN PATHEXPOSE声明运行时容器提供的服务端口,运行时应用并不会因为这个声明而打开这个端口。docker run -P时会对声明的端口随机映射EXPOSE 端口一 端口二WORKDIR指定容器之后各层的工作目录。因为本层的cd并不会顺带到下一层。WORKDIR PATHUSER改变之后层执行RUN,ENTRYPOINT等指令的身份RUN groupadd -r redis && useradd -r -g redis redisUSER redisRUN [“redis-server”]ONBUILDONBUILD 其它指令用于构建基础镜像,被引用是才会真正执行。可以提取出重复的部分,方便维护删除docker rmi [options] <image1> [<image2>….] #删除镜像docker rm [options] <container1> [<container2>…] #删除容器进入容器docker attach CONTAINER_NAME查看数据卷信息docker inspect CONTAINER_NAME匿名的数据卷默认位于/var/lib/docker/volumes之下查看容器docker logs [-f] container查看端口映射配置docker port container container_port容器链接–link container_name:alias ...

October 19, 2018 · 1 min · jiezi