Docker实战指南 0x05 Docker进阶
Docker仓库(私有仓库)
阿里云
开通阿里云容器镜像服务
#阿里云下载镜像,需要填写前缀
docker pull registry.cn-shenzhen.aliyuncs.com/ali/mysql:[镜像版本号]
ali:命名空间
mysql:镜像仓库
- 创建命名空间
- 创建镜像仓库
Harbor
网络高级
#安装Es+kibana;kibana得指定es地址,
#sb-book-crud-service mysql
Docker使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0),Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址,称为Container-IP,同时Docker网桥是每个容器的默认网关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的Container-IP直接通信。
Docker容器网络就很好的利用了Linux虚拟网络技术,在本地主机和容器内分别创建一个虚拟接口,并让他们彼此联通(这样一对接口叫veth pair);
Docker中的网络接口默认都是虚拟的接口。虚拟接口的优势就是转发效率极高(因为Linux是在内核中进行数据的复制来实现虚拟接口之间的数据转发,无需通过外部的网络设备交换),对于本地系统和容器系统来说,虚拟接口跟一个正常的以太网卡相比并没有区别,只是他的速度快很多。
原理:
1、每一个安装了Docker的linux主机都有一个docker0的虚拟网卡。桥接网卡
2、没启动一个容器linux主机多了一个虚拟网卡。
3、docker run -d -P --name tomcat --net bridge tomcat:8
#1、docker0网络的特点。,
默认
域名访问不通
--link 域名通了,但是删了又不行
#2、可以让容器创建的时候使用自定义网络
1、自定义创建的默认default "bridge"
2、自定义创建一个网络网络
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
所有东西实时维护好,直接域名ping同
3、理解网络。
docker network connect [OPTIONS] NETWORK CONTAINER
跨网络连接别人就用
docker network connect mynet tomcat
效果:
1、自定义网络,默认都可以用主机名访问通
2、跨网络连接别人就用 docker network connect mynet tomcat
1、容器启动,指定容器ip。 docker run --ip 192.168.0.3 --net 自定义网络
2、网络。docker network create --subnet 指定子网范围 --driver bridge 所有东西实时维护好,直接域名ping同
3、docker compose。
1、网络的创建过程
Docker创建一个容器的时候,会具体执行以下操作:
- 创建一对虚拟接口,分别放到本地主机和新容器的命名空间中
- 本地主机一段的虚拟接口连接到默认的docker0网桥或者指定网桥上,并具有一个以veth开头的唯一名字
- 容器一段的虚拟接口将放到新创建的容器中,并修改名字为eth0。这个接口只在容器的命名空间可见
- 从网桥的可用地址段中获取一个空闲的地址分配给容器的eth0(如:172.17.0.2/16),并配置默认路由网关为docker0网卡的内部接口docker0的IP地址(如:172.17.42.1/16)
完成以上,容器就可以使用它所能看到的eth0虚拟网卡来连接其他容器和访问外部网络。
网络模式
网络模式 | 配置 | 说明 |
---|---|---|
bridge模式 | --net=bridge | 默认值,在Docker网桥docker0上为容器创建新的网络栈 |
none模式 | --net=none | 不配置网络,用户可以稍后进入容器,自行配置 |
container模式 | --net=container:name/id | 容器和另外一个容器共享Network namespace。 kubernetes中的pod就是多个容器共享一个Network namespace。 |
host模式 | --net=host | 容器和宿主机共享Network namespace |
用户自定义 | --net=自定义网络 | 用户自己使用network相关命令定义网络, 创建容器的时候可以指定为自己定义的网络 |
实验测试网络互连
- 大家重点理解veth pair技术
- --link是容器在默认网络模式下,可以互相使用容器名ping通的
- 如果容器创建时使用自定义网络,不使用--link也是可以ping通相互的容器名
- --link 生产一般不用,我们可以使用自定义网络的方式
- docker network connect
部署一个集群(redis)
Dockerfile
Dockerfile指南:https://docs.docker.com/engine/reference/builder/
事情:nginx。tomcat。mysql。镜像从哪里来?
我们自己如何做一个镜像。微服务。SpringBoot。上云部署。最方便是Docker。
微服务打包成镜像。任何装了Docker。都可以下载使用。
应用-->Dockerfile--->打包成镜像--->上传到仓库(公有仓库,私有仓库)--->下载镜像--->启动运行。
移植:扩充服务器。
如何得到一个镜像
1、自己做的Dockefile
https://docs.docker.com/engine/reference/builder/
#nginx Dockerfile的示例
#alpine:3.11超迷你的linux 4mb;
#alpine:3.11 linux全目录 基于宿主机linux的一个统一接口。cpu,mem。主机。
FROM alpine:3.11
LABEL maintainer="NGINX Docker Maintainers <[email protected]>"
#环境
ENV NGINX_VERSION 1.18.0
ENV NJS_VERSION 0.4.0
ENV PKG_RELEASE 1
RUN set -x \
# create nginx user/group first, to be consistent throughout docker variants
&& addgroup -g 101 -S nginx \
&& adduser -S -D -H -u 101 -h /var/cache/nginx -s /sbin/nologin -G nginx -g nginx nginx \
&& apkArch="$(cat /etc/apk/arch)" \
&& nginxPackages=" \
nginx=${NGINX_VERSION}-r${PKG_RELEASE} \
nginx-module-xslt=${NGINX_VERSION}-r${PKG_RELEASE} \
nginx-module-geoip=${NGINX_VERSION}-r${PKG_RELEASE} \
nginx-module-image-filter=${NGINX_VERSION}-r${PKG_RELEASE} \
nginx-module-njs=${NGINX_VERSION}.${NJS_VERSION}-r${PKG_RELEASE} \
" \
&& case "$apkArch" in \
x86_64) \
# arches officially built by upstream
set -x \
&& KEY_SHA512="e7fa8303923d9b95db37a77ad46c68fd4755ff935d0a534d26eba83de193c76166c68bfe7f65471bf8881004ef4aa6df3e34689c305662750c0172fca5d8552a *stdin" \
&& apk add --no-cache --virtual .cert-deps \
openssl \
&& wget -O /tmp/nginx_signing.rsa.pub https://nginx.org/keys/nginx_signing.rsa.pub \
&& if [ "$(openssl rsa -pubin -in /tmp/nginx_signing.rsa.pub -text -noout | openssl sha512 -r)" = "$KEY_SHA512" ]; then \
echo "key verification succeeded!"; \
mv /tmp/nginx_signing.rsa.pub /etc/apk/keys/; \
else \
echo "key verification failed!"; \
exit 1; \
fi \
&& apk del .cert-deps \
&& apk add -X "https://nginx.org/packages/alpine/v$(egrep -o '^[0-9]+\.[0-9]+' /etc/alpine-release)/main" --no-cache $nginxPackages \
;; \
*) \
# we're on an architecture upstream doesn't officially build for
# let's build binaries from the published packaging sources
set -x \
&& tempDir="$(mktemp -d)" \
&& chown nobody:nobody $tempDir \
&& apk add --no-cache --virtual .build-deps \
gcc \
libc-dev \
make \
openssl-dev \
pcre-dev \
zlib-dev \
linux-headers \
libxslt-dev \
gd-dev \
geoip-dev \
perl-dev \
libedit-dev \
mercurial \
bash \
alpine-sdk \
findutils \
&& su nobody -s /bin/sh -c " \
export HOME=${tempDir} \
&& cd ${tempDir} \
&& hg clone https://hg.nginx.org/pkg-oss \
&& cd pkg-oss \
&& hg up -r 474 \
&& cd alpine \
&& make all \
&& apk index -o ${tempDir}/packages/alpine/${apkArch}/APKINDEX.tar.gz ${tempDir}/packages/alpine/${apkArch}/*.apk \
&& abuild-sign -k ${tempDir}/.abuild/abuild-key.rsa ${tempDir}/packages/alpine/${apkArch}/APKINDEX.tar.gz \
" \
&& cp ${tempDir}/.abuild/abuild-key.rsa.pub /etc/apk/keys/ \
&& apk del .build-deps \
&& apk add -X ${tempDir}/packages/alpine/ --no-cache $nginxPackages \
;; \
esac \
# if we have leftovers from building, let's purge them (including extra, unnecessary build deps)
&& if [ -n "$tempDir" ]; then rm -rf "$tempDir"; fi \
&& if [ -n "/etc/apk/keys/abuild-key.rsa.pub" ]; then rm -f /etc/apk/keys/abuild-key.rsa.pub; fi \
&& if [ -n "/etc/apk/keys/nginx_signing.rsa.pub" ]; then rm -f /etc/apk/keys/nginx_signing.rsa.pub; fi \
# Bring in gettext so we can get `envsubst`, then throw
# the rest away. To do this, we need to install `gettext`
# then move `envsubst` out of the way so `gettext` can
# be deleted completely, then move `envsubst` back.
&& apk add --no-cache --virtual .gettext gettext \
&& mv /usr/bin/envsubst /tmp/ \
\
&& runDeps="$( \
scanelf --needed --nobanner /tmp/envsubst \
| awk '{ gsub(/,/, "\nso:", $2); print "so:" $2 }' \
| sort -u \
| xargs -r apk info --installed \
| sort -u \
)" \
&& apk add --no-cache $runDeps \
&& apk del .gettext \
&& mv /tmp/envsubst /usr/local/bin/ \
# Bring in tzdata so users could set the timezones through the environment
# variables
&& apk add --no-cache tzdata \
# Bring in curl and ca-certificates to make registering on DNS SD easier
&& apk add --no-cache curl ca-certificates \
# forward request and error logs to docker log collector
&& ln -sf /dev/stdout /var/log/nginx/access.log \
&& ln -sf /dev/stderr /var/log/nginx/error.log \
# make default server listen on ipv6
&& sed -i -E 's,listen 80;,listen 80;\n listen [::]:80;,' \
/etc/nginx/conf.d/default.conf
EXPOSE 80
STOPSIGNAL SIGTERM
CMD ["nginx", "-g", "daemon off;"]
# Dockerfile复原了我们在linux上安装nginx的过程。
2、别人给我们准备好的文件。xxx.tar。可以通过硬盘传输使用。
1、创建项目dockerfile
2、上传项目到服务器。
3、进入项目,构建镜像到本地仓库;
docker build -t nginx:1.0 -f ./Dockerfile .
别忘了最后的小数点。- docker images 查看镜像
- docker exec -it 容器id /bin/bash;进入容器,修改容器
docker commit -a “icoding” -m “nginxxx” 容器id mynginx:2.0
- docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
OPTIONS说明:
- -a :提交的镜像作者;
- -c :使用Dockerfile指令来创建镜像;
- -m :提交时的说明文字;
- -p :在commit时,将容器暂停。
docker login : 登陆到一个Docker镜像仓库,如果未指定镜像仓库地址,默认为官方仓库 Docker Hub
- docker login -u 用户名 -p 密码
- docker logout : 登出一个Docker镜像仓库,如果未指定镜像仓库地址,默认为官方仓库 Docker Hub
4、推送镜像到docker hub
- 标记镜像,docker tag local-image:tagname username/new-repo:tagname
- 上传镜像,docker push username/new-repo:tagname
5、保存镜像,加载镜像
- 可以保存镜像为tar,使用u盘等设备复制到任意docker主机,再次加载镜像
- 保存:docker save spring-boot-docker -o /home/spring-boot-docker.tar
- 加载:docker load -i spring-boot-docker.tar
6、阿里云操作
登录阿里云,密码就是开通镜像仓库时 的密码
- docker login --username=icoding registry.cn-hangzhou.aliyuncs.com
拉取镜像
- docker pull registry.cn-hangzhou.aliyuncs.com/icoding/i-nginx:v1.0
推送镜像
- docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/icoding/icoding-nginx:v2
- docker push registry.cn-hangzhou.aliyuncs.com/icoding/icoding-nginx:v2
2、Dockerfile详解
Dockerfile由一行行命令语句组成,并且支持以#开头的注释行。
一般而言,Dockerfile可以分为四部分
基础镜像信息
维护者信息
镜像操作指令
启动时执行指令
指令 | 说明 |
---|---|
FROM | 指定基础镜像 |
MAINTAINER | 指定维护者信息,已经过时,可以使用LABEL maintainer=xxx 来替代 |
RUN | 运行命令 v |
CMD | 指定启动容器时默认的命令 v |
LABEL | 指定生成镜像的元数据标签信息 v |
EXPOSE | 声明镜像内服务监听的端口 v |
ENV | 指定环境变量,可以在docker run的时候使用-e改变 v |
ADD | 复制指定的src路径下的内容到容器中的dest路径下,src可以为url会自动下载,可以为tar文件,会自动解压 |
COPY | 复制本地主机的src路径下的内容到镜像中的dest路径下,但不会自动解压等 |
ENTRYPOINT | 指定镜像的默认入口.运行命令 v |
VOLUME | 创建数据卷挂载点 |
USER | 指定运行容器时的用户名或UID |
WORKDIR | 配置工作目录,为后续的RUN、CMD、ENTRYPOINT指令配置工作目录 |
ARG | 指定镜像内使用的参数(如版本号信息等),可以在build的时候,使用--build-args改变 v |
OBBUILD | 配置当创建的镜像作为其他镜像的基础镜像是,所指定的创建操作指令 |
STOPSIGNAL | 容器退出的信号值 |
HEALTHCHECK | 健康检查 |
SHELL | 指定使用shell时的默认shell类型 |
1、RUN、CMD、ENTRYPOINT区别
- RUN 执行命令并创建新的镜像层RUN 经常用于安装软件包(在构建镜像时运行的)。
- CMD 设置容器启动后默认执行的命令及其参数但 CMD 能够被
docker run
后面跟的命令行参数替换。- ENTRYPOINT 配置容器启动时运行的命令。
- 以上命令都可以使用shell或者exec方式执行
CMD ["executable","param1","param2"]
(exec form, this is the preferred form)CMD ["param1","param2"]
(as default parameters to ENTRYPOINT)CMD command param1 param2
(shell form)2、shell和exec方式
1. shell 是 /bin/sh -c <command>的方式, 2. exec ["/bin/sh","-c",command] 的方式== shell方式
eg:shell方式
ENV name icoding
ENTRYPOINT echo "Hello, $name"
#输出 Hello icoding
ENTRYPOINT ["/bin/echo", "Hello, $name"]
#输出 Hello $name
ENTRYPOINT ["/bin/sh", "-c", "echo Hello, $name"]
#输出 Hello icoding
##建议:CMD 和 ENTRYPOINT 推荐使用 Exec 格式因为指令可读性更强更容易理解。RUN 则两种格式都可以。exec的时候要获取环境变量等值,就用/bin/sh -c 即可。
No ENTRYPOINT | ENTRYPOINT exec_entry p1_entry | ENTRYPOINT [“exec_entry”, “p1_entry”] | |
---|---|---|---|
No CMD | error, not allowed | /bin/sh -c exec_entry p1_entry | exec_entry p1_entry |
CMD [“exec_cmd”, “p1_cmd”] | exec_cmd p1_cmd | /bin/sh -c exec_entry p1_entry | exec_entry p1_entry exec_cmd p1_cmd |
CMD [“p1_cmd”, “p2_cmd”] | p1_cmd p2_cmd | /bin/sh -c exec_entry p1_entry | exec_entry p1_entry p1_cmd p2_cmd |
CMD exec_cmd p1_cmd | /bin/sh -c exec_cmd p1_cmd | /bin/sh -c exec_entry p1_entry | exec_entry p1_entry /bin/sh -c exec_cmd p1_cmd |
3、实战Dockerfile
#1、ping命令小工具。
编写Dockerfile-->打包镜像--->根据这个镜像启动容器使用容器的功能
docker build -t hello .
-t:tag标签。镜像名字
.:在当前目录下工作
默认.这个目录下就得有一个 Dockerfile
FROM alpine
CMD ping baidu.com
#2、文件名不是Dockerfile。用-f 指定
docker build -f Dockerfile2 -t hello:v1.0 .
docker run -d --name hello hello;
#3、默认构建出来的镜像,放到了我们的本地镜像仓库。
1)、登陆到dockerhub
2)、dockehub国外,就算能Push,非常慢。阿里云加速的是下载。
#4、把这个镜像发布到Docker hub
1)、docker login -u icodingallen;登陆到docker hub
2)、docker push nginx:v1.0;推送过去。
太慢了
#5、搭建私有的镜像仓库。使用阿里云的镜像仓库(免费)。
1)、docker login [email protected] registry.cn-hangzhou.aliyuncs.com
为了团队自治。只能看到自己的仓库的所有镜像。namespace;
创建镜像仓库。保存镜像各种版本,book: 1 2 3 4 5
docker tag hello:v1.0 registry.cn-hangzhou.aliyuncs.com/icodingdocker/hello:v1.3
docker push registry.cn-hangzhou.aliyuncs.com/icodingdocker/hello:v1.3
docker.io/libarary/hello:latest
registry.cn-hangzhou.aliyuncs.com/icodingdocker/hello:v1.0
镜像---》打包--》上传。
5、Dockerfile区分一些易混淆的指令
1、USER 执行cmd等之类命令的使用那个用户
alpine sudo gosu
FROM centos
RUN groupadd -r abc && useradd -r -g abc aaa
USER aaa
CMD whoami
# CMD 就是容器启动以后要执行的命令
2、ARG、ENV
- The
ARG
instruction defines a variable that users can pass at build-time to the builder with thedocker build
:arg在构建期间。docker build - The environment variables set using
ENV
will persist when a container is run from the resulting image. You can view the values usingdocker inspect
, and change them usingdocker run --env =
. env在运行是可以用到的
FROM alpine
ARG bbb haha
ENV abc 666
CMD echo $bbb
容器运行的时候arg的东西拿不到
CMD echo $abc
容器运行的时候env的能拿到
FROM alpine
ARG bbb haha
ENV abc=$bbb
CMD echo $abc
ARG指定的值,在镜像构建的后面位置,构建期间都可以使用到。
改变这些值行不行
docker build -f Dockerfile-arg-env -t file-arg --build-arg bbb=888 --build-arg abc=777 .
结果888
# 构建时 bbb=888 abc=777 ,cmd打印888.原因 构建时不能改变env
# 运行时
\ | ARG | ENV |
---|---|---|
build时 | √。--build-arg改变 构建参数(ARG声明) | 生效,能不能改(不能) |
运行时 | 不生效 | 生效。能改 -e abc |
最佳实战:
ARG:定义一些版本信息
FROM alpine
ARG version=1
RUN yum install nginx:$version
Env:运行时的环境变量。
ENV env = --spring.profile.active=prod
-e修改。sb java -jar xxx.jar $env
3、ADD和COPY
#构建了一个SpringBoot镜像。 xxx.jar
/opt
docker build -t hello .
ADD:将当前目录下的内容放到镜像里面一起打包。
COPY:将当前目录下的内容放到镜像里面一起打包。
ADD ["<src1>","<src2>","<dest>"] dest:容器里面的目录
可以指定很多种路径地址。自动下载,解压复制。
FROM alpine
ADD hello.tar /opt/hello
COPY hello.tar /opt/world/
CMD echo "1234"
这个东西构建的镜像为什么docker run -d 不行。因为容器运行的是ech 1234;
没有一个守护进程一直运行。
CMD ping baidu.com
4、VOLUME和WORKDIR
VOLUME:指定容器需要挂载的卷
WORKDIR:工作目录。
1、以后的其他命令在这个目录里面运行
2、exec进去都默认来到了 WORKDIR 指定的目录。sh
docker run -it --rm file-volume sh
WORKDIR
WORKDIR /root == RUN cd /root
挂载麻烦。自动挂载。
FROM alpine
WORKDIR /opt/a
VOLUME /opt/b
COPY hello.txt .
ADD hello.tar /opt/b
CMD whoami
volume声明的挂载目录,即使容器运行的时候,不用-v进行挂载。docker也会自动的进行匿名挂载。
nginx:
5、RUN、CMD、ENTRYPOINT
相同点:运行命令
不同点:
RUN:在构建镜像的时候运行的命令
CMD、ENTRYPOINT:在容器启动运行的命令
测试RUN;
#想构建一个具有git功能的镜像。
FROM centos
RUN yum install -y git
WORKDIR /opt/data
RUN git clone https://gitee.com/lanoox/luject.git
VOLUME /opt/data
CMD echo "git clone success"
#CMD 容器运行的时候CMD的命令才执行。
相同的镜像layer层发生变化,只有这层变化。
- -RUN指令的所有命令都在镜像docker build期间就执行
CMD和ENTRYPOINT在容器启动时运行
- CMD 容器运行的时候CMD的命令才执行。docker run -it --rm file-run bash 能进容器中
- 替换为ENTRYPOINT。虽然指令运行了。但是 docker run -it --rm file-run bash 。最后的bash没有进去,失效了。
无论是CMD还是ENTRYPOINT还是RUN
RUN
(shell form, the command is run in a shell, which by default is/bin/sh -c
on Linux orcmd /S /C
on Windows) RUN yum install -y git;/bin/sh -c
可以动态获取一些变量RUN ["executable", "param1", "param2"]
(exec form);无法动态获取一些变量
FROM centos
ARG soft=git
RUN ["yum install","-y","$soft"] #这是错误的。因为非`/bin/sh -c`方式,用不到前面声明的ARG,ENV
WORKDIR /opt/data
RUN git clone https://gitee.com/lanoox/luject.git
VOLUME /opt/data
ENTRYPOINT echo "git clone success"
# bash-c 和 数组方式的区别, 修改后的;安装正确。
FROM centos
ARG soft=git
RUN ["/bin/sh","-c","yum install -y $soft"]
#-c command:后免是完整命令
WORKDIR /opt/data
RUN git clone https://gitee.com/lanoox/luject.git
VOLUME /opt/data
ENTRYPOINT echo "git clone success"
RUN、CMD、ENTRYPOINT都支持一下两种方式
The exec form, which is the preferred form:
ENTRYPOINT ["executable", "param1", "param2"]
The shell form:
ENTRYPOINT command param1 param2
总结:
- 如果运行命令是。[]方式,默认不是bash -c就无法用变化,普通的方式RUN yum -install -y $soft可以使用变量。
CMD、ENTRYPOINT的最佳实战
- Dockerfile文件必须至少有一个
CMD
或者ENTRYPOINT
命令. ENTRYPOINT
用来定义容器如何运行.CMD
应该被用来作为给ENTRYPOINT
传递。默认参数的一种方式CMD
将会被覆盖,容器运行时指定参数的时候.ENTRYPOINT
命令不会被覆盖。- CMD多个只会有一个生效。
ENTRYPOINT
:不被传入的指令覆盖,但是多个也只有一个生效。
为什么我的指令Dockerfile写CMD的时候,docker run -it --rm file-run bash可以进控制台,而
ENTRYPOINT
不行?运行效果:
- Dockerfile是CMD;没打印git clone success。但是bash生效。
- Dockerfile 是 ENTRYPOINT;打印了git clone success但是没有进容器(bash没生效)
- Dockerfile文件必须至少有一个
- 混写。CMD +
ENTRYPOINT
FROM centos
ARG soft=git
RUN ["/bin/bash","-c","yum install -y $soft"]
WORKDIR /opt/data
RUN git clone https://gitee.com/lanoox/luject.git
VOLUME /opt/data
CMD ["nginx"] #CMD给entrypoint提供参数
ENTRYPOINT ["yum","install","-y"]
运行:
docker run -it --rm file-run maven
FROM centos
ARG soft=git
RUN ["/bin/bash","-c","yum install -y $soft"]
WORKDIR /opt/data
RUN git clone https://gitee.com/lanoox/luject.git
VOLUME /opt/data
CMD ["","","",""] #可以放空
ENTRYPOINT ["/bin/sh","-c","yum install -y"]
#容器启动就是yum install -y "";自己启动命令加上git
CMD 后面有N参数。传了参数替换N个还是最后一个?
docker run -it --rm file-run maven CMD ["maven"] 对
docker run -it --rm file-run maven CMD [“”,“”,"maven"] 错
目的:构建镜像。SpringBoot编写的微服务,怎么做镜像?
1、运行的业务的目标环境?SB服务。java环境。FROM
2、怎么启动业务的。得到jar包,java -jar xxx.jar --spring.profile.active=prod --server.port=8080;决定镜像的ENTRYPOINT怎么写。docker exec?docker run(第一次容器启动要执行)?
docker exec haha -it bash【和entrypoint,cmd没啥关系】;
3、业务运行的时候需要啥?java。jar。jar包就想办法放进镜像中。COPY 。ADD
4、业务的那些数据是需要做持久化。VOLUME怎么写。
FROM java:8
#服务器只有dockerfile和jar在一起
COPY *.jar /app.jar
#即使运行没有-v,也会匿名挂载
VOLUME ["/logs"]
CMD ["--server.port=8080"]
EXPOSE ["8080"]
ENTRYPOINT ["java","-jar","/app.jar"]
4、idea快速整合使用
作为一个了解。
1、 Docker开启远程访问
#修改该Docker服务文件
vi /lib/systemd/system/docker.service
#修改ExecStart这行,将原来注释,加上这个命令
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock
#重新加载配置文件
systemctl daemon-reload
#重启服务
systemctl restart docker.service
#查看端口是否开启
netstat -nlpt #如果找不到netstat命令,可进行安装。yum install net-tools
#直接curl看是否生效
curl http://127.0.0.1:2375/info
2、IDEA安装Docker插件
3、IDEA配置docker
4、也可以整合自己的私有镜像仓库
==可以提供非常方便的部署功能==
docker build -t hello-java . && docker run -p 88:8080 -v /logs:/logs --name hello-666 hello-java
Dockerfile解耦应用的开发与部署。
maven插件再把部署流程一配置就不解耦。,
应用。代码变了改应用。部署只改Dockerfile。
maven。代码部署放在了一个完整的生命周期。运维人员想要改网络部署等配置,还得改pom。CICD只需要一个Dockerfile。
5、docker-maven-plugin
市面上docker-maven-plugin太多,我们推荐一个 docker-maven-plugin,照着文档使用就行。不管使用哪一种docker插件来构造image,都比不上直接用Dockerfile编写简单,而且可复用,不用学习不同插件不同的构造规则。
最好给自己的Docker服务器配置阿里云镜像加速,否则经常导致镜像下载不来的情况
fabric8io的有两大功能:
- 构造并推送Docker镜像
- 启动和停止Docker容器
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.33.0</version>
<!--全局配置-->
<configuration>
<!--这一部分是为了实现对远程docker容器的控制-->
<!--docker主机地址,用于完成docker各项功能,注意是tcp不是http!-->
<dockerHost>tcp://公网IP:2376</dockerHost>
<!--docker远程访问所需证书地址,如果docker远程主机没有启用TLS验证则不需要配证书-->
<certPath>${project.basedir}/docker/ssh</certPath>
<!--这一部分是为了实现docker镜像的构建和推送-->
<!--registry地址,用于推送,拉取镜像,我这里用的是阿里的registry-->
<registry>registry.cn-shenzhen.aliyuncs.com</registry>
<!--认证配置,用于私有registry认证,如果忘记了可以去阿里的registry查看-->
<authConfig>
<push>
<username>这里填registry的用户名</username>
<password>这里填registry的密码</password>
</push>
</authConfig>
<!--镜像相关配置,支持多镜像-->
<images>
<!-- 单个镜像配置 -->
<image>
<!--镜像名(含版本号)-->
<name>命名空间/仓库名称:镜像版本号</name>
<!--别名:用于容器命名和在docker-compose.yml文件只能找到对应名字的配置-->
<alias>${project.name}</alias>
<!--镜像build相关配置-->
<build>
<!--使用dockerFile文件-->
<dockerFile>${project.basedir}/docker/${project.name}</dockerFile>
</build>
<!--配置docker-compose文件-->
<external>
<type>compose</type>
<basedir>${project.basedir}/docker</basedir>
<composeFile>docker-compose.yml</composeFile>
</external>
<!--容器run相关配置-->
<run>
<!--配置运行时容器命名策略为:别名,如果不指定则默认为none,即使用随机分配名称-->
<namingStrategy>alias</namingStrategy>
</run>
</image>
</images>
</configuration>
</plugin>
maven指令 | 功能 |
---|---|
docker:start | 创建和启动容器 |
docker:stop | 停止并销毁容器 |
docker:build | 构建镜像 |
docker:watch | 自动进行重建和重启 |
docker:push | 将镜像推送到registry |
docker:remove | 从本地docker主机删除镜像 |
docker:logs | 显示容器日志 |
docker:source | 将docker build archive附加到Maven项目 |
docker:save | 将镜像保存到文件 |
docker:volume-create | 创建卷以在容器之间共享数据 |
docker:volume-remove | 删除创建的卷 |
#打包到容器运行的完整流程
mvn clean package docker:stop docker:remove docker:build docker:run
#不是每一次运行都要推送镜像,如果要的话可以单独调用docker:push
mvn docker:push
#示例配置
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.33.0</version>
<configuration>
<dockerHost>tcp://111.229.61.54:2375</dockerHost>
<registry>registry.cn-shenzhen.aliyuncs.com</registry>
<authConfig>
<push>
<username>icodingallen</username>
<password>icoding123</password>
</push>
</authConfig>
<images>
<image>
<name>icoding/icoding-docker:v1.2</name>
<build>
<!--使用dockerFile文件 <dockerFile>${project.basedir}/docker/${project.name}</dockerFile>-->
<dockerFile>${project.basedir}/Dockerfile</dockerFile>
</build>
<run>
<ports>
<port>8080:8080</port>
</ports>
</run>
</image>
</images>
</configuration>
</plugin>
FROM java:8
LABEL maintainer=icoding
ADD target/*.jar /app.jar
EXPOSE 8080
CMD ["java","-jar","app.jar"]
@RestController
public class HelloController {
@Value("${project.version}")
String ver;
@Value("${project.name}")
String name;
@GetMapping("/")
public String hello(){
return "Hello Docker!"+ver+"=>"+name;
}
}
#获取maven pom对象的相关属性值。在springboot中获取如下
[email protected]@
[email protected]@
#在pom文件中直接使用${project.xxxx},按照对象属性关系获取即可