共5 个小时13分钟
docker run不时候要修改容器的默认端口号, 不然网络不通;
IDEA 配置dockerca的时候disconnected before any data was received:
- 配置白名单的时候需要加入服务器自身的ip;echo subjectAltName =IP:139.129.118.96,IP:0.0.0.0>> extfile.cnf
★★上传到远程服务器的时候一定要上加TLSv1.2;mvn clean package docker:build -Djdk.tls.client.protocols=TLSv1.2
不然会报证书扩展名错误 [extension (5) should not be presented in certificate_request]
解决方案:水平扩展(不断加服务器) , 满足高并发.
maven:
Docker
IaaS:Infrastrcure as a service 基础设施即服务PaaS:Platform as a service 平台即服务SaaS:Software as a service 软件即服务
实现原来技术不同
使用资源不同
| 特性 | 容器 | 虚拟机 |
|---|---|---|
| 启动 | 秒级 | 分钟级 |
| 硬盘使用 | 一般为MB | 一般为GB |
| 性能 | 接近原生 | 弱于 |
| 形同支持量 | 单机支持上千个容器 | 一般几十个 |
镜像 容器 仓库
| docker | 面向对象 | |
|---|---|---|
| 容器 | 对象 | |
| 镜像 | 类 |
docker镜像 仓库:
分层存储
保存镜像
官方提供了docker registry 镜像
)
Either pass the --registry-mirror option when starting dockerd manually, or edit /etc/docker/daemon.json and add the registry-mirrors key and value, to make the change persistent.
{"registry-mirrors": ["https://<my-docker-mirror-host>"]}
阿里云加速器
daocloud加速器
docker pull [选项] [Docker Registry 地址[:端口]/] 仓库名[:标签]docker pull tomcat:版本号 (不写版本号 则laster版本)docker image ls docker imagesdocker images -q :查看id docker image prune删除前须确认没有被任何容器使用
docker image rm [选项] <镜像1> [<镜像2>....]docker image rmi 镜像id
docker psdocker ps -a //全部容器 包括运行和退出的docker container lsdocker container ls -a
docker run --rm -d --name tomcat001 -p 10082:8080 tomcat-i 保持docker和同容器内的交互,启动容器时候,运行的命令经书后,容器依然存活,没有退出 (默认是会退出的)以交互模式运行容器,通常与 -t 同时使用;-t 为容器重新分配一个伪输入终端,通常与 -i 同时使用;-d 后台运行容器--rm 容器启动后 执行完成停止命令 或程序后就销毁--name 给容器起个名字-p 宿主机:内部端口
docker start <id> // 停止正在运行的容器 或者ctrl +cdocker container stop <id|name>
docker start <id>
docker restart <id>
docker rm <id>
docker exec -it 容器id(name ) bash
-i -t 参数
退出: exit
docker cp [options] container:path localpath 容器复制到宿主机docker cp [options] localpath container:path 宿主机复制到容器中
# 复制到容器docker cp /data/files2.jpeg tomcat001:/usr/local/tomcat/webapps/ROOT/1.jpeg# 把容器中的复制出来docker cp tomcat001:/usr/local/tomcat/webapps/ROOT/index.jsp ./# 修改后再复制回去docker cp index.jsp tomcat001:/usr/local/tomcat/webapps/ROOT/
docker logs 容器id/name
docker logs -f -t --since="2021-06-04" --tail=10 tomcat004
—since :指定输出日志的开始日期
-f 查看实时日志
-t 查看日志的产生日期
-tail=10 查看最后10条日志
tomcat004 容器ming
1. 上传项目2. 关闭已经启动的tomcatdocker stop id1 id2docker ps -adocker rm iddocker imagesdocker run --rm -d --name test1 -p8080:8080 tomcatdocker run --rm -d --name test2 -p8081:8081 tomcatdocker run --rm -d --name test3 -p8082:8082 tomcatdocker exec -it test1 basedocker cp test test1:/usr/local/tomcat/test1/webapps/
docker stop id 会销毁 —rm 启动的容器的文件/
docker volume create vol1
查看所有的数据卷 docker volume ls
docker inspect vol1-v 宿主机目录 容器id:docker目录
docker run --rm -d --name test1 -p8080:8080 -v /data/docker/test110 test1:/usr/local/webapps/test001 tomcat
docker pull nginxdocker run --name nginx8001 -p 8001:80 -d nginx
docker run --rm -d -p 8001:80 --name nginx8001 \-v /data/docker-data/vo1001/nginx8001/html:/usr/share/nginx/html \-v /home/nginx/conf/nginx.conf:/etc/nginx/nginx.conf \-v /data/docker-data/vo1001/nginx8001/logs:/var/log/nginx \nginx
docker run --rm -d -p 8081:80 --name nginx-test-web \-v /home/nginx/www:/usr/share/nginx/html \-v /home/nginx/conf/nginx.conf:/etc/nginx/nginx.conf \-v /home/nginx/logs:/var/log/nginx \nginx
命令说明:
—rm:容器终止运行后,自动删除容器文件。
-p 8081:80: 将容器的 80 端口映射到主机的 8082 端口.
—name nginx-test-web:将容器命名为 nginx-test-web
-v /home/nginx/www:/usr/share/nginx/html:将我们自己创建的 www 目录挂载到容器的 /usr/share/nginx/html。
-v /home/nginx/conf/nginx.conf:/etc/nginx/nginx.conf:将我们自己创建的 nginx.conf 挂载到容器的 /etc/nginx/nginx.conf。
-v /home/nginx/logs:/var/log/nginx:将我们自己创建的 logs 挂载到容器的 /var/log/nginx。
官网查看: https://hub.docker.com/
下载镜像: docker pull mysql:5.7
创建并启动mysql
docker run -d --name mysql5.7-3308 -p 3308:3306 -e MYSQL_ROOT_PASSWORD='root' mysql:5.7
外部登录: mysql -h 127.0.0.1 -P 3308 -uroot -p
内部登录
授权远程访问:
grant all privileges on *.* to 'root'@'%' identified by 'root' with grant option;
flush privileges;
- 从已经创建的容器中更新镜像,并且提交这个景象
- 使用dockerfile指令来创建一个新的镜像
镜像的定制实际上就是定制每一层锁添加的配置, 文件.
把每一层修改, 安装, 构建, 操作的命令都写入一个脚本, 用这个脚本来构建,定制镜像, 那么之前提及的无法重复,的问题, 体积的问题就都会解决. 这个脚本就是Dockerfile.
Dockerfile是一个文本文件, 其内包含一条条指令(Instruction), 每一条指令构建一层, 因此每一条指令的内容, 就是描述该层应当如何构建.
基础镜像不存在会在docker hub上拉取(一般会是文件的第一个指令)
使用格式:
FROM <镜像>:[tag]
FROM <镜像>@digest[校验码]
当前主机没有此镜像时, 会自动去官网hub下载
[逐渐废弃]
LABEL — 替代MAINTAINER
具体使用:
LABEL maintainer=”作者信息”
使用格式:
MAINTAINER "lcxm <xuduochoua@163.com>"
LABEL maintainer="NGINX Docker Maintainers <docker-maint@nginx.com>"LABEL "com.example.vendor"="acme incorpor ated"LABEL "com.example.label-with-value"="foo"LABEL version="1.0"LABEL description=" this text illustrates \thatlabe-values惨审判multiplelines"
设置的环境变量查看: docker inspect
修改环境变量: docker run —env <key>=<value>
具体用法
ENV JAVA_HOME /usr/local/jdk
ENV JRE_HHOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/lib;$JRE_HOME/lib/
ENV PATH $PATH;$JAVA_HOME/bin/
docker默认的工作目录是 /, 只有run能执行cd命令切换目录, 而且还是作用在当下的run, 也就是说每个run都是独立运行的.
如果想让其他指令在指定的目录下执行, 就用workdir. rowrkdir动作的目录改变是持久的.
workdir /usr/local/tomcat
卷: 只能定义docker管理的卷
volume/data/mysql 运行的时候回随机在宿主机的目录下生成一个卷目录
文件要在dockerfile工作目录
src: 源文件,
- 支持通配符
- 通常项目路径
dest: 目标路径
- 通常绝对路径
add 将文件从路径 <src> 复制添加到容器内部路径<dest>
<src> 必须是相对于源文件夹的一个文件或目录, 也可以是一个远程url
<dest>是目标容器中的绝对路径. 所有的新文件和文件夹都会创建UID和GID.
事实上如果<src>是一个远程文件ur, 那么目标文件的权限将会是600;
使用格式:
EXPOSE 80/tcp 23/udp
不加协议默认为tcp
不加协议默认为tcp
使用-P选项可以暴露这里指定的端口
但是宿主的关联至这个端口的端口是随机的
由于命令行的强大能力, run指令在定制镜像时是最常用的指令之一.
其格式有两种:
- shell格式: run <命令> 就像直接在命令行输入命令一样
- exec格式: run [“可执行文件”,”参数1”,”参数2”] , 这更像是函数调用中的格式
使用格式
run <command>
run [“<executable>“, “param1”, “param2”]
# 1 创建dockerfile /usr/local/docker/demo1vim Dockerfile# 2 写入内容FROM tomcat //指定tomcat最新版本镜像LABEL MAINTAINER "lcxm <xuduochoua@163.com>"RUN echo 'hello world' > /usr/local/tomcat/webapps/ROOT/index.html# 3 构建镜像 -t 镜像名称 demo1:1.0docker build -t demo1 .# 4 运行镜像docker run -d --rm --name demo1-8081 -p 8081:8080 demo1
删除ROOT下的其他所有文件
Dockerfile
from tomcatLABEL MAINTAINER "lcxm <xuudochoua@163.com>"WORKDIR /usr/local/tomcat/webapps/ROOT/RUN rm -rf *WORKDIR /usr/local/tomcatRUN echo 'hello world 002' > /usr/local/tomcat/webapps/ROOT/index.html
docker build -t demo002 .
docker run -d —rm —name demo002-8082 -p 8082:8080 demo002
基于上一个镜像, 外部复制一个文件,复制到容器中 并且能够访问
加一句命令
COPY 1.png /usr/local/tomcat/webapps/ROOT
FROM tomcatLABEL MAINTAINER "lcxm <xuudochoua@163.com>"WORKDIR /usr/local/tomcat/webapps/ROOT/RUN rm -rf *WORKDIR /usr/local/tomcat/webappsCOPY 1.png /usr/local/tomcat/webapps/ROOTRUN echo 'hello world 002' > /usr/local/tomcat/webapps/ROOT/index.html
利用Dockerfile 将一个war包生成生成镜像的Dockerfile
FROM tomcatLABEL MAINTAINER "lcxm <xuudochoua@163.com>"WORKDIR /usr/local/tomcat/webapps/ROOT/RUN rm -rf *WORKDIR /usr/local/tomcat/webapps# 复制到root下COPY test.zip /usr/local/tomcat/webapps/ROOT# 解压 然后删除原zipRUN unzip test.zipRUN rm -rf text.zipWORKDIR /usr/local/tomcat
准备好打包好的jar: test-1.0.0.jar
在同目录下创建Dockerfile文件
# 基础镜像 即运行环境FROM java:8LABEL MAINTAINER "lcxm <xuudochoua@163.com>"# 创建tmp目录并持久化到docker数据文件夹,因springboot使用内嵌tomcat容器默认使用/tmp作为工作目录VOLUME /temp# 复制文件并重命名ADD test-1.0.0.jar test.jar#并非真正的发布端口,这个只是容器部署人员之间的交流,即简历image的人员告诉容器部署人员容器应该映射那个端口给外界EXPOSE 8080#容器启动时运行的命令,相当于命令行输入java -jar xxx.jar, 为了缩短tomcta启动时间,添加java.security.egd的系统属性指向/dev/./urandom作为ENTRYPOINTENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar", "/test.jar"]
希望能完成以下工作:
- 在IDEA中开发代码
- 代码达成jar
- 部署到linux服务器上
- 如果用docker(编写dockerfile文件)
- 构建镜像
- 运行容器
#修改docker服务文件vim /lib/systemd/system/docker.service#修改ExecStart这行ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock# 修改为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 http://127.0.0.1:2375/info
file - setting - plugins - install ….
docker integration
传统过程中: 打包, 部署, 上传到linux, 编写dockerfile, 构建镜像, 创建容器运行
在持续集成过程中,
docker-maven-plugin插件: 在maven工程中,通过简单的配置,自动生成镜像,并推送到仓库中
pom.xml
<properties><docker.image.prefix>lcxm</docker.image.prefix></properties><build><plugins><plugin><groupId>com.spotify</groupId><artifactId>docker-maven-plugin</artifactId><version>1.0.0</version><configuration><!-- 镜像名称 --><imageName>${docker.image.prefix}/${project.artifactId}</imageName><!-- 指定标签 --><imageTags><imageTag>lastest</imageTag></imageTags><!--基础镜像 jdk1.8 --><baseImage>java</baseImage><maintainer>lcxm xuduochoua@163.com</maintainer><!-- 切换到ROOT目录 --><workdir>/ROOT</workdir><cmd>["java", "-version"]</cmd><entryPoint>["java", "-jar", "${project.build.finalName}.jar"]</entryPoint><!-- 指定dockerfile路径 --><!--<dockerDirectory>${project.basedir}/src/main/docker</dockerDirectory>--><!--指定远程docker api地址 --><dockerHost>http://xuqiudong.cn:2375</dockerHost><!-- 这里是复制 jar 包到 docker 容器指定目录配置 类似add中的target --><resources><resource><targetPath>/ROOT</targetPath><!-- 用于指定需要复制的根目录 ${project.build.directory} 表示target目录--><directory>${project.build.directory}</directory><!--用于指定需要复制的文件${project.build.finalName}.jar指的是打包后的jar包文件 类似add中的 目标 --> <include>${project.build.finalName}.jar</include></resource></resources></configuration></plugin></plugins></build>
FROM javaLABEL MAINTAINER "lcxm <xuudochoua@163.com>"WORKDIR /ROOTADD /ROOT/xxx.jar /ROOT/ENTRYPOINT ["java","-jar", "xxx.jar"]CMD ["java", "-version"]
打包.并构建镜像到docker上去
mvn clean package docker:build
在打包的时候就实现并构建镜像到docker上去
<executions><!-- 当执行mvn package 时 执行mvn clean package docker:build --><execution><id>build-image</id><phase>package</phase><goals><goal>build</goal></goals></execution><!-- 当执行mvn package时 回对镜像进行标签设定 --><execution><id>tag-image</id><phase>package</phase><goals><goal>tag</goal></goals></execution></executions>
官方demo示例:https://docs.docker.com/engine/security/protect-access/
Now that you have a CA, you can create a server key and certificate signing request (CSR). Make sure that “Common Name” matches the hostname you use to connect to Docker:
echo subjectAltName = DNS:$HOST,IP:10.10.10.20,IP:127.0.0.1 >> extfile.cnf
After generating
cert.pemandserver-cert.pemyou can safely remove the two certificate signing requests and extensions config files:
To protect your keys from accidental damage, remove their write permissions. To make them only readable by you, change file modes as follows:
Certificates can be world-readable, but you might want to remove write access to prevent accidental damage:
复制证书到
/etc/docker/下
Now you can make the Docker daemon only accept connections from clients providing a certificate trusted by your CA:
修改docker服务文件
vim /lib/systemd/system/docker.serviceExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock
修改为:
ExecStart=/usr/bin/dockerd —tlsverify —tlscacert=/data/docker-data/dockerca/ca.pem —tlscert=/data/docker-data/dockerca/server-cert.pem —tlskey=/data/docker-data/dockerca/server-key.pem -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock
# 1 创建目录存放ca的公钥和私钥,并进入 /data/docker-data/dockerca/# 2生成ca私钥和公钥 phrase pass: 654321openssl genrsa -aes256 -out ca-key.pem 4096# 3 补全ca证书信息 654321 cn anhui hefei pers pers pers pers xuduochoua@163.comopenssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem#4 生成server-key.pemopenssl genrsa -out server-key.pem 4096#5 ca 来签公钥openssl req -subj "/CN=139.129.118.96" -sha256 -new -key server-key.pem -out server.csr# 6 配置白名单 需要加入服务器本身的ip地址 不然报错disconnected before any data was receivedecho subjectAltName =IP:139.129.118.96,IP:0.0.0.0>> extfile.cnf#7 将docker守护程序秘钥的扩展使用属性设置为服务器身份验证echo extendedKeyUsage = serverAuth >> extfile.cnf# 8 生成签名证书 654321openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem \-CAcreateserial -out server-cert.pem -extfile extfile.cnf#9 生成客户端的key.pemopenssl genrsa -out key.pem 4096openssl req -subj '/CN=client' -new -key key.pem -out client.csr#10要使秘钥适合客户端身份验证echo extendedKeyUsage = clientAuth > extfile.cnfecho extendedKeyUsage = clientAuth > extfile-client.cnf#11 现在 生成签名证书 654321openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem \-CAcreateserial -out cert.pem -extfile extfile-client.cnf#12 删除不要需要的文件, 两个证书签名请求rm -v client.csr server.csr extfile.cnf extfile-client.cnf#13 可修改权限chmod -v 0400 ca-key.pem key.pem server-key.pemchmod -v 0444 ca.pem server-cert.pem cert.pem#14 归集服务器证书cp server-*pem /etc/docker/cp ca.pem /etc/docker/# 15 修改docker配置vim /lib/systemd/system/docker.serviceExecStart=/usr/bin/dockerd --tlsverify --tlscacert=/data/docker-data/dockerca/ca.pem --tlscert=/data/docker-data/dockerca/server-cert.pem --tlskey=/data/docker-data/dockerca/server-key.pem -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock# 16 重新加载damnon 并重启dockersystemctl daemon-reloadsystemctl restart docker# 17 开发2375端口/sbin/iptables -I INPUT -p tcp --dport 2375 -j ACCEPT# 18 重启dockersystemctl restart docker
ca.pem ca-key.pem cert.pem key.pem
tcp://xuqiudong.cn:2375
改为:
并且配置秘钥的文件夹
修改pom.xml中的dockerhost 对应的ip为https
<plugin><groupId>com.spotify</groupId><artifactId>docker-maven-plugin</artifactId><version>1.2.2</version><executions><execution><id>build-image</id><!--将插件绑定在package这个phase上。也就是说,用户只需执行mvn package ,就会自动执行mvn docker:build --><phase>package</phase><goals><goal>build</goal></goals></execution></executions><configuration><!-- 镜像名称 --><imageName>${docker.image.prefix}/${project.artifactId}</imageName><!-- 指定标签 --><imageTags><imageTag>lastest</imageTag></imageTags><!--基础镜像 jdk1.8 --><baseImage>java</baseImage><maintainer>lcxm xuduochoua@163.com</maintainer><!-- 切换到ROOT目录 --><workdir>/ROOT</workdir><cmd>["java", "-version"]</cmd><entryPoint>["java", "-jar", "${project.build.finalName}.jar"]</entryPoint><!-- 指定dockerfile路径 --><!----><dockerDirectory>${project.basedir}</dockerDirectory><!--指定远程docker api地址 --><dockerHost>https://139.129.118.96:2375</dockerHost><dockerCertPath>D:\tools\data\docker\ca\</dockerCertPath><!--<dockerHost>http://localhost:2375/</dockerHost>--><!-- 这里是复制 jar 包到 docker 容器指定目录配置 类似add中的target --><resources><resource><targetPath>/ROOT</targetPath><!-- 用于指定需要复制的根目录 ${project.build.directory} 表示target目录--><directory>${project.build.directory}</directory><!--用于指定需要复制的文件${project.build.finalName}.jar指的是打包后的jar包文件 类似add中的 目标 --> <include>${project.build.finalName}.jar</include></resource></resources></configuration></plugin>
<plugin><groupId>com.spotify</groupId><artifactId>dockerfile-maven-plugin</artifactId><version>1.4.10</version><executions><execution><id>default</id><goals><goal>build</goal><goal>push</goal></goals></execution></executions><configuration><repository>139.129.118.96/${project.artifactId}</repository><tag>${project.version}</tag><buildArgs><JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE><JAR_EXPOSE>8082</JAR_EXPOSE></buildArgs></configuration></plugin>
查看已经开放的端口
firewall-cmd --list-ports
开放端口
firewall-cmd--zone=public --add-port=8080/tcp --permanent
重启防火墙
firewall-cmd --reload# 停止firewall systemctl stop firewalld.service# 禁止开机启动firewall systemctl disabled1 firewalld.service