Docker 使用 Google 公司推出的 Go 语言 进行开发实现,基于 Linux 内核的 cgroup,namespace,以及 AUFS 类的 Union FS 等技术,对进程进行封装隔离
,属于 操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为 容器 。最初实现是基于 LXC,从 0.7 版本以后开始去除 LXC,转而使用自行开发的 libcontainer,从 1.11 开始,则进一步演进为使用 runC 和 containerd。
Docker 在容器的基础上,进行了进一步的封装,从文件系统、网络互联到进程隔离等等,极大的简化了容器的创建和维护。使得 Docker 技术比虚拟机技术更为轻便、快捷。
Docker与传统虚拟机技术的不同之处:
传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而容器内的应用进程直接运行于宿主的内核
,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便
。
更高效的利用系统资源
由于容器不需要进行硬件虚拟以及运行完整操作系统等额外开销
,Docker 对系统资源的利用率更高。无论是应用执行速度、内存损耗或者文件存储速度,都要比传统虚拟机技术更高效。因此,相比虚拟机技术,一个相同配置的主机,往往可以运行更多数量的应用。
更快速的启动时间
传统的虚拟机技术启动应用服务往往需要数分钟,而 Docker 容器应用,由于直接运行于宿主内核
,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间。大大的节约了开发、测试、部署的时间。
一致的运行环境**
开发过程中一个常见的问题是环境一致性问题。由于开发环境、测试环境、生产环境不一致,导致有些 bug 并未在开发过程中被发现。而 Docker 的镜像提供了除内核外完整的运行时环境
,确保了应用运行环境一致性,从而不会再出现 「这段代码在我机器上没问题啊」 这类问题。
一次构建,到处运行
持续交付和部署
对开发和运维(DevOps)人员来说,最希望的就是一次创建或配置,可以在任意地方正常运行。
使用 Docker 可以通过定制应用镜像来实现持续集成、持续交付、部署。开发人员可以通过 Dockerfile
来进行镜像构建,并结合 持续集成(Continuous Integration) 系统进行集成测试,而运维人员则可以直接在生产环境中快速部署该镜像,甚至结合 持续部署(Continuous Delivery/Deployment) 系统进行自动部署。
而且使用 Dockerfile
使镜像构建透明化,不仅仅开发团队可以理解应用运行环境,也方便运维团队理解应用运行所需条件,帮助更好的生产环境中部署该镜像。
更轻松的迁移
由于 Docker 确保了执行环境的一致性,使得应用的迁移更加容易
。Docker 可以在很多平台上运行,无论是物理机、虚拟机、公有云、私有云,甚至是笔记本,其运行结果是一致的。因此用户可以很轻易的将在一个平台上运行的应用,迁移到另一个平台上,而不用担心运行环境的变化导致应用无法正常运行的情况。
更轻松的维护和扩展
Docker 使用的分层存储以及镜像的技术
,使得应用重复部分的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得非常简单。此外,Docker 团队同各个开源项目团队一起维护了一大批高质量的 官方镜像,既可以直接在生产环境使用,又可以作为基础进一步定制,大大的降低了应用服务的镜像制作成本。
特性 | 容器 | 虚拟机 |
---|---|---|
启动 | 秒级 | 分钟级 |
硬盘使用 | 一般为 MB |
一般为 GB |
性能 | 接近原生 | 弱于 |
系统支持量 | 单机支持上千个容器 | 一般几十个 |
容器化的好处 ( 进程间隔离 ):
服务器版
平台 | x86_64 / amd64 | ARM | ARM64 / AARCH64 | IBM Power (ppc64le) | IBM Z (s390x) |
---|---|---|---|---|---|
CentOS | ✔ | ✔ | |||
Debian | ✔ | ✔ | ✔ | ||
Fedora | ✔ | ✔ | |||
Ubuntu | ✔ | ✔ | ✔ | ✔ | ✔ |
卸载旧版本
apt-get remove docker docker-engine docker.io containerd
使用 apt 进行安装
apt install docker.io
查看是否安装成功 docker version
https://cr.console.aliyun.com/cn-shanghai/instances/mirrors
进入阿里云控制台,搜索 容器镜像服务
找到专属加速服务
通过修改 daemon 配置文件 /etc/docker/daemon.json
来使用加速器
全部把xxxxxxx替换成上面那张图涂掉的那部分,然后全部 copy 然后回车
tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://xxxxxxx.mirror.aliyuncs.com"]
}
EOF
重启 docker :systemctl daemon-reload
systemctl restart docker
验证:docker info
基于虚拟的环境下如果想要使用 tomcat,则需要先装 jdk ,然后再装 tomcat;而基于容器化环境,则可以直接安装 tomcat 进行使用
通过下载 tomcat9.0.x 镜像的webapps目录为空。。因此可能会遇到以下巨坑,这里有两种解决方案 ( 推荐第二种 )
方案1:https://blog.csdn.net/yl405001832/article/details/104351039
方案2 https://www.cnblogs.com/canglongdao/p/12162269.html
Docker 引擎是一个包含以下主要组件的客户端服务器应用程序
Docker | 面向对象 |
---|---|
容器 | 对象 |
镜像 | 类 |
docker run 若在本地没有找到镜像,则会去仓库中找并下载该镜像,然后基于该镜像再创建一个容器
标题 | 说明 |
---|---|
镜像(Images) | Docker 镜像是用于创建 Docker 容器的模板。 |
容器(Container) | 容器是独立运行的一个或一组应用。 |
客户端(Client) | Docker 客户端通过命令行或者其他工具使用 Docker API (https://docs.docker.com/reference/api/docker_remote_api) 与 Docker 的守护进程通信。 |
主机(Host) | 一个物理或者虚拟的机器用于执行 Docker 守护进程和容器。 |
仓库(Registry) | Docker 仓库用来保存镜像,可以理解为代码控制中的代码仓库。Docker Hub(https://hub.docker.com) 提供了庞大的镜像集合供使用。 |
Docker Machine | Docker Machine是一个简化Docker安装的命令行工具,通过一个简单的命令行即可在相应的平台上安装Docker,比如VirtualBox、 Digital Ocean、Microsoft Azure。 |
docker pull [选项] [Docker Registry 地址[:端口号]]/仓库名[:标签]
EG:docker pull ubuntu:18.04
这个命令等同于:docker pull registry.hub.docker.com/ubuntu:12.04
相当于从默认注册服务器 registry.hub.docker.com 中的 ubuntu 仓库上下载了标签为 12.04 的 ubuntu 镜像
从官方下载比较慢时,可以通过 指定注册服务器 来从其他仓库进行下载
EG:docker pull dl.dockerpool.com:5000/ubuntu:18.04
docker images
列信息
其中镜像的 ID
唯一标识了镜像, 具有相同的镜像 ID
的两个镜像,实际上是同一镜像。
TAG
信息用来标记来自同一个仓库的不同镜像。例如 ubuntu
仓库中有多个镜像,通过 TAG
信息来区分发行版本,例如 10.04
、12.04
、12.10
、13.04
、14.04
等。例如下面的命令指定使用镜像 ubuntu:14.04
来启动一个容器。
可以看到,上面有个 TAG 为 none 的镜像,这在镜像又被称为 虚悬镜像
显示镜像体积
docker system df
中间层镜像
docker image ls -a
为了加速镜像构建,重复利用资源,Docker 会利用 中间层镜像 ,所以在使用一段时间后,可能会看到一些依赖的中间层镜像
移除本地镜像使用
docker rmi 镜像名:[标签] / 镜像ID
docker rm 是删除容器的
注意:在删除镜像之前要先用 docker rm 删掉依赖于这个镜像的所有容器
清除所有虚悬镜像
docker image prune
docker commit -m="提交描述信息" -a="作者" 容器id 生成镜像名[:tag]
显示运行中的容器
docker ps
显示所有容器,包括运行的和没运行的
docker ps -a
docker 本身形成了一个内网,因此 docker 需要网卡
docker的网卡
同时,每个容器本身又相当于一台内网中的服务器,因此也需要网卡
容器的网卡
docker run
docker本身形成了一个内网,因此想要访问 docker 内的容器,就需要指定容器端口
EG:docker run -p 8088:8080 -d tomcat
参数 -p
表示进行端口映射,宿主机端口 : 容器端口,用户访问宿主机的端口时,会**路由到指定的容器端口**,从而进行访问。不使用该参数则会进行默认映射 ( 如tomcat会默认进行8080的映射 )
参数 -d
表示后台运行该容器 ( daemon 守护态运行)
当时用 docker run 来创建容器时,Docker 在后台运行的标准操作包括
检查本地是否存在指定的镜像,不存在就从公有仓库下载
利用镜像创建并启动一个容器
分配一个文件系统,并在只读的镜像层外面挂载一层可读写层
从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去
从地址池配置一个 ip 地址给容器
执行用户指定的应用程序
执行完毕后容器被终止
docker start 已停止运行的容器的ID
docker stop 容器ID
普通删除
docker rm 容器ID / 容器名
无法删除正在运行的容器
强制删除 (先停掉再删除)
docker rm -f 容器ID / 容器名
就跟操作 Linux 中的文件一样操作容器里面的文件 ( 使用 bash 操作容器 )
docker exec -it 容器ID/容器名 /bin/bash
退出容器
ctrl + d
docker logs -f 容器名
查看所有已经创建的,包括终止状态的容器
docker container ls -a
清除所有处于终止状态的容器
docker container prune
docker logs [OPTIONS] container_name
Options:
--details 显示更多的信息
-f, --follow 跟踪实时日志
--since string 显示自某个timestamp之后的日志,或相对时间,如42m(即42分钟)
--tail string 从日志末尾显示多少行日志, 默认是all
-t, --timestamps 显示时间戳
--until string 显示自某个timestamp之前的日志,或相对时间,如42m(即42分钟)
DockFile 是一个文本文件,其中包含了一条一条的指令,每一条指令构建一层,因此每一条指令的内容就是描述该层该如何构建
名字必须为Dockfile)
vim Dockerfile
先来看一个很简单的 DockFile 配置文件
FROM tomcat
COPY index.jsp /usr/local/tomcat/webapps/ROOT
这段代码的意思就是,继承 tomcat 镜像,然后将当前目录下的 index.jsp 文件复制到镜像的指定目录下
docker build -t myTomcat .
这样就构建出了一个叫 myTomcat 的新镜像,具有 tomcat 的所有功能 ( 继承 ) ,但 /usr/local/tomcat/webapps/ROOT 中的 index.jsp 文件使我们指定的 copy 的 index.jsp 文件
在第二步构建新镜像中,使用到了一个 .
,这个 . 有两个作用
在当前目录找到 Dockerfile 配置文件
指定 Dockerfile 的上下文目录打包并传递 —> Docker Server,真正的打包过程是在 Docker Server 中进行的
因此对文件而言,应该指定的不是其在宿主机中的路径,而是在上下文中的路径 ( 指定 COPY 的文件应该和 Dockerfile 同级或同级目录下,即COPY的是相对路径 )
当构建时,用户指定构建镜像上下文的路径,docker build 命令得知这个路径后,会将这个路径下 并且被 Dockerfile 使用的文件进行打包,然后上传给 Docker Server, 这样 Docker Server 在收到这个上下文包后,就会对相应内容进行打包并制作成镜像
RUN
运行 shell 指令
COPY
COPY <源路径> <目标路径>
COPY ["<源路径>" "<目标路径>"]
COPY 指令将从构建上下文目录中的 <源路径> 中的文件/目录复制到新的一层镜像内的 <目标路径>
COPY package.json /usr/src/app
<源路径> 可以是多个,甚至可以是通配符,其通配符规则满足 go 的 filepath.Math 规则
COPY hom* /mydir/
COPY hom?.txt /mydir/
<目标路径>是容器内的绝对路径,也可以是相对于工作目录的相对路径 ( 工作目录可以通过 WORKDIR 指令来指定 ),目标路径不需要事先创建,如果目录不存在会在复制文件前先行创建确实目录
COPY 指令,会将源文件的各种元数据进行保留,比如读,写,执行权限,创建时间等
ADD
和 COPY 的格式和性质基本一样
,但是在 COPY 的基础上增加了一些功能
tar 压缩文件
,压缩格式为 gzip,bzip2 以及 xz
的情况下, ADD 指令会自动解压缩这个文件
到 <目标路径>CMD
CMD <命令>
CMD ["可执行文件", "参数1", "参数2"...]
普通的 CMD 指令只能执行一次
命令
ENTRYPOINT
ENTRYPOINT 的格式和 RUN 格式一样,分为 exec 格式和 shell 格式
ENTRYPOINT 的目的和 CMD 一样,都是在指定容器启动程序及参数,ENTRYPOINT 在运行时也可以替代,不过比 CMD 要略显繁琐,需要通过 docker run 的参数 --entrypoint 来指定
当指定 ENTRYPOINT 后,CMD 的含义就发生了改变,不再是直接运行其命令,而是将 CMD 的内容作为参数传给 ENTRYPOINT 指令
<ENTRYPOINT> ""
因此 ENTRYPOINT 就解决了普通 CMD 指令只能执行一次的情况
但是~,ENTRYPOINT 也只准用一次
因此,当 CMD 命令比较多时,一般会把 CMD 弄成一个 shell 文件,然后用 ENTRYPOINT 来执行这个 shell 文件
ENV
ENV
ENV = =...
设置环境变量
ENV MYSQL_VERSION 5.7.2
VOLUME
数据卷,后面会说
EXPOSE
EXPOSE <端口1> [<端口2>...]
EXPOSE 指令是声明运行时容器提供服务的端口,只是一个声明。在运行时并不会因为这个声明,应用就会开启这个端口的服务。
WORKDIR
WORKDIR <工作目录路径>
使用 WORKDIR 指令可以指定工作目录 (又称为当前目录),就是指定哪个目录下运行后面的 shell
也是指定容器的 初始目录 (就是进入容器以后在哪)
看一个完整一点的例子
FROM tomcat
#删除ROOT目录下所有东西
RUN rm -fr /usr/local/tomcat/webapps/ROOT/*
#复制到指定目录
COPY myTest.tar.gz /usr/local/tomcat/webapps/ROOT
#指定工作目录
WORKDIR /usr/local/tomcat/webapps/ROOT
#已经指定了工作目录,因此这个解压并删除是在工作目录下进行的
RUN tar -zxvf myTesy.tar.gz \
&& rm -rf myTest.tar.gz
#暴露端口
EXPOSE 8080
这个例子也可以写成这种格式
FROM tomcat
WORKDIR /usr/local/tomcat/webapps/ROOT
RUN rm -fr *
COPY myTest.tar.gz .
RUN tar -zxvf myTest.tar.gz \
&& rm -rf myTest.tar.gz
EXPOSE 8080
镜像的定制就是对 Dockerfile 进行命令的堆叠
Compose 项目是 Docker 官方的开源项目,负责实现对 Docker 容器集群的快速编排 (简化 Docker 操作
)。从功能上看,跟 OpenStack 中的 Heat 十分类似
Docker Hub
Compose 定位是 「定义和运行多个 Docker 容器的应用(Defining and running multi-container Docker applications)」,其前身是开源项目 Fig
Compose 支持 Linux、macOS、Windows 10 三大平台。在 Linux 上的也安装十分简单,从Docker官网下载最新稳定版处直接下载编译好的二进制文件即可
下载太慢可以切换到国内源
curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.5/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
下载完后执行提权
sudo chmod +x /usr/local/bin/docker-compose
最后验证
docker-compose version
克隆两台虚拟机 ,一台命名为 deploy,一套命名为 Paas
1.固定IP 地址
vim /etc/netplan/50-cloud-init.yaml
network:
ethernets:
ens33:
addresses: [192.168.224.129/24]
#网关地址为VMware中虚拟网络编辑里面的网关地址
gateway4: 192.168.224.2
nameservers:
#同网关地址
addresses: [192.168.224.2]
version: 2
生效配置
netplan apply
2.修改主机名
修改 cloud.cfg 防止重启后主机名还原
vim /etc/cloud/cloud.cfg
#将下面的值改为true即可
preserve_hostname: true
修改主机名
#修改主机名
hostnamectl set-hostname deployment
#配置 hosts
cat >> /etc/hosts << EOF
192.168.224.132 services
EOF
3.修改 DNS
vim /etc/systemd/resolved.conf
取消 DNS 行的注释,配置一个 114.114.114.114 的 DNS 服务器,然后重启
在 /usr/local 目录下创建 /docker/tomcat/ 目录用于进行测试,并进入 tomcat 目录下
yml
的配置文件命名为 docker-compose.yml
version: '3.1'
services:
tomcat:
restart: always
image: tomcat
container_name: tomcat
ports:
- 8080:8080
分析一下这个配置文件都干了些什么
tomcat :服务名
image:使用的镜像名称
container_name:命名容器
restart:重新启动策略,填 always 时系统重启时也会重启
no
是默认的重启策略,在任何情况下都不会重启容器。 on-failure
表示发生错误时进行重启
restart: "no"
restart: always
restart: on-failure
restart: unless-stopped
守护态运行
docker-compose up -d
docker-compose down
注意: yml 配置文件区分制表符和空格
,对齐必须使用空格
使用 docker-compose 指定数据卷
volumes:
- ./webapps:/usr/local/tomcat/webapps.dist
volumes
即创建数据卷,右边是容器里面的目录,左边是宿主机目录,指定了数据卷的位置为 ./webapps
,即对 docker-compose.yml 而言的当前目录下的webapps中,两个目录是同步的
数据卷是一个可供一个或多个容器使用的特殊目录,它绕过 UFS (联合文件系统),可以提供很多有用的特性:
联合文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下 (unite several directories into a single virtual filesystem)。
联合文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
另外,不同 Docker 容器就可以共享一些基础的文件系统层,同时再加上自己独有的改动层,大大提高了存储的效率。
Docker 中使用的 AUFS(AnotherUnionFS)就是一种联合文件系统。 AUFS 支持为每一个成员目录(类似 Git 的分支)设定只读(readonly)、读写(readwrite)和写出(whiteout-able)权限,同时 AUFS 里有一个类似分层的概念,对只读权限的分支可以逻辑上进行增量地修改 (不影响只读部分的)。
Docker 目前支持的联合文件系统种类包括 AUFS, btrfs, vfs 和 DeviceMapper。
在用 docker run
命令的时候,使用 -v
标记来创建一个数据卷并挂载到容器里。在一次 run 中多次使用可以挂载多个数据卷。
下面创建一个 web 容器,并加载一个数据卷到容器的 /webapp
目录。
docker run -d -P --name web -v /webapp training/webapp python app.py
注意:也可以在 Dockerfile 中使用
VOLUME
来添加一个或者多个新的卷到由该镜像创建的任意容器。或者是在 docker-compose 中指定 volumes 属性,左边为宿主机文件夹,右边为容器文件夹
使用 -v
标记也可以指定挂载一个本地主机的目录到容器中去。
run -d -P --name web -v /src/webapp:/opt/webapp training/webapp python app.py
上面的命令加载主机的 /src/webapp
目录到容器的 /opt/webapp
目录。这个功能在进行测试的时候十分方便,比如用户可以放置一些程序到本地目录中,来查看容器是否正常工作。本地目录的路径必须是绝对路径,如果目录不存在 Docker 会自动为你创建它。
注意:Dockerfile 中不支持这种用法,这是因为 Dockerfile 是为了移植和分享用的。然而,不同操作系统的路径格式不一样,所以目前不支持。
Docker 挂载数据卷的默认权限是读写,用户也可以通过 :ro
指定为只读。
docker run -d -P --name web -v /src/webapp:/opt/webapp:ro
training/webapp python app.py
加了 :ro
之后,就挂载为只读了。
-v
标记也可以从主机挂载单个文件到容器中
sudo docker run --rm -it -v ~/.bash_history:/.bash_history ubuntu /bin/bash
这样就可以记录在容器输入过的命令了。
注意:如果直接挂载一个文件,很多文件编辑工具,包括
vi
或者sed --in-place
,可能会造成文件 inode 的改变,从 Docker 1.1 .0 起,这会导致报错误信息。所以最简单的办法就直接挂载文件的父目录。
docker-compose.yml
services:
tomcat:
restart: always
image: tomcat
container_name: tomcat
ports:
- 8080:8080
volumes:
- ./webapps:/usr/local/tomcat/webapps.dist
environment:
TZ: Asia/Shanghai
然后守护态启动
version: '3.1'
services:
db:
# 目前 latest 版本为 MySQL8.x
image: mysql
restart: always
environment:
#初始化密码
MYSQL_ROOT_PASSWORD: 123456
command:
#为制作的MySQL镜像指定参数
--default-authentication-plugin=mysql_native_password
--character-set-server=utf8mb4
--collation-server=utf8mb4_general_ci
--explicit_defaults_for_timestamp=true
--lower_case_table_names=1
ports:
- 3306:3306
volumes:
- ./data:/var/lib/mysql
然后守护态启动
需要先将 SpringBoot 项目中连接的数据库地址改为 宿主机IP:3306
然后成 jar 包
将 jar 包移动到服务器的一个目录下,在相同目录下通过 Dockerfile 制作一个镜像
FROM mysql
#内置jdk
FROM tomcat
# VOLUME 指定了临时文件目录为/tmp。
# 其效果是在主机 /var/lib/docker 目录下创建了一个临时文件,并链接到容器的/tmp
VOLUME /tmp
# 将jar包添加到容器中并更名为app.jar
ADD demo-0.0.1-SNAPSHOT.jar app.jar
# 运行jar包
ENTRYPOINT ["java","-jar","app.jar"]
docker build -t blog .
然后制作 docker-compose.yml 方便启动
version: '3.1'
services:
blog:
restart: always
#选择刚才制作的镜像
image: blog
container_name: myblog
#右边是容器内的服务端口,即访问SpringBoot项目的端口;左边是映射到宿主机上,即外部访问的端口
ports:
- 80:8083
然后
docker-compose up -d
启动后访问 宿主机 IP : 80 端口即可
这里所有环境的搭建基于上面创建好的 Paas 虚拟机
使用 Docker 来安装和运行 GitLab 中文版, docker-compose.yml 配置如下:
version: '3'
services:
gitlab:
image: 'twang2218/gitlab-ce-zh'
restart: always
#宿主机ip地址,或域名
hostname: '192.168.224.131'
environment:
TZ: 'Asia/Shanghai'
GITLAB_OMNIBUS_CONFIG: |
#gitlab进行拉取时的http地址
external_url 'http://192.168.224.131'
gitlab_rails['time_zone'] = 'Asia/Shanghai'
#GitLab项目中使用SSH进行拉取时的端口
gitlab_rails['gitlab_shell_ssh_port'] = 2222
unicorn['port'] = 8888
#使用nginx进行解析
nginx['listen_port'] = 80
ports:
#右边容器端口要与gitlab进行http拉取时的端口号一致,因为是80,所以上面可以不写
- '80:80'
- '443:443'
- '2222:22'
volumes:
- ./config:/etc/gitlab
- ./data:/var/opt/gitlab
- .logs:/var/log/gitlab
然后访问 192.168.224.131 ,会要求初始化密码,初始化密码后使用用户名 root 和密码
登录即可
https://tortoisegit.org/download/
下载对应版本和对应汉化包
先安装第一个,可以一路默认,也可以更改安装位置
然后安装第二个进行汉化
右击任意位置
然后设置为中文,应用并重新打开
使用这个链接,最好新建一个专门用来推送和克隆的空白文件夹
在协同开发的持续集成和持续交付中,一般不采用输入账户名和密码的方式进行平台的登录,因为会导致平台的同步并阻塞,一旦有一个人没有输入账号和密码,后面登录的人就会一直排队
因此使用 SSH 进行免密登录更为常用
前往安装 Git 的目录下:D:\Git\usr\bin
找到这个文件
在该目录下启动 cmd,输入命令
ssh-keygen -t rsa -C "you_email"
因为我已经生成过秘钥,所以这里就选了 n,到生成 key 的目录下
特别注意!!!慎重选择在生成秘钥时是否设置密码
打开 .pub 复制里面的内容,回到 GitLab
生成 SSH
回到项目中,项目变为默认使用 SSH
删除原来拉取下来的项目,重新使用 SSH 的方式进行拉取
可能会有个报错:Disconnected no supported authentication methods available(server sent: publickey)
解决方法:修改乌龟 git 里面的 ssh 客户端为你自己的客户端
在拉取的时候可能会要你输入密码短语 ( 取决于生成秘钥时是否设置了密码 )
最后:
Nexus 是强大的 Maven 仓库管理器 ( 私服 ),简化了内部仓库的维护和外部仓库的访问。
将内部使用的依赖上传到私服,提高了安全性也提高了协同开发的效率
这样 maven 进行依赖下载时,顺序如下
制作 docker-compose
version: '3.1'
services:
nexus:
restart: always
image: sonatype/nexus3
container_name: nexus
ports:
- 8081:8081
volumes:
- ./data:/nexus-data
启动发现报错
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A7xGcN2c-1600656635523)(…/mdPicture/image-20200502104857181.png)]
解决方案1
:这是由于 /data/instances 目录没有权限造成的,因此进入 data 目录,修改 instances 的权限
chmod 777 instances
解决方案2
:修改 docker-compose 为
version: '3.1'
services:
nexus:
restart: always
image: sonatype/nexus3
container_name: nexus
ports:
- 8081:8081
volumes:
- nexus-data:/nexus-data
#外部指定数据卷位置
volumes:
nexus-data:
这种方法中的数据卷位置为 /var/lib/你的nexus父目录/volumes
下,该目录下的 docker_compose的目录名_nexus-data(即自己的命名)
这个目录就是数据卷
访问一下
右上角进行登录,发现如下提示
到 data 目录下找到该文件,复制内容,回到 Nexus 进行登录,用户名为 amdin,密码即为刚才的内容。登陆后会要求设置新密码,设置后全部 next 即可
第三方仓库
版本策略
布局策略 ( Layout Policy )
根据语义化规范,版本号蕴意如下
EG:V2.0.4
2 | 0 | 4 |
---|---|---|
改架构的次数 | 改功能的次数 | 改bug的次数 |
任意一位 +1 时,后面的所有位退回为 0
上传规则:在 pom 中,若 0.0.1-SNAPSHOT 后面跟 SNAPSHOT 则为快照版,否则为发行版,Nexus 会根据后缀判断应该放到哪个仓库里
打开项目使用的 maven 的 settings 文件,在 中添加
<server>
<id>maven-releasesid>
<username>adminusername>
<password>123456password>
server>
<server>
<id>maven-snapshotsid>
<username>adminusername>
<password>123456password>
server>
这里的 id 需要等下和 pom 文件中对应,username 和 passwd 即上一步设置的用户名和密码
在 pom 中进行管理配置,id 要和上一步中配置的 中的 id 相同
<distributionManagement>
<repository>
<id>maven-releasesid>
<name>nexus releases reponame>
<url>http://192.168.224.131:8081/repository/maven-releases/url>
repository>
<snapshotRepository>
<id>maven-snapshotsid>
<name>nexus snapshots reponame>
<url>http://192.168.224.131:8081/repository/maven-snapshots/url>
snapshotRepository>
distributionManagement>
在 pom.xml 中配置代理仓库
<repositories>
<repository>
<id>nexusid>
<name>nexus respositoryname>
<url>http://192.168.224.131:8081/repository/maven-public/url>
<snapshots>
<enabled>trueenabled>
snapshots>
<releases>
<enabled>trueenabled>
releases>
repository>
repositories>
<pluginRepositories>
<pluginRepository>
<id>nexusid>
<name>nexus pluginname>
<url>http://192.168.224.131:8081/repository/maven-public/url>
<snapshots>
<enabled>trueenabled>
snapshots>
<releases>
<enabled>trueenabled>
releases>
pluginRepository>
pluginRepositories>
找到本地的 maven 仓库,删掉一些项目中所用的依赖,重新打包一下项目
回到 nexus 查看中央仓库
mvn deploy
deploy 指令包含了 install,install 指令包含了 package。因此会在本地仓库生成一个和 对应的路径,该路径下的会有一个和 同名的路径,然后进入 会有一个和 同名的路径,其中有一个 jar 包
回到 Nexus,可以看见成功上传
因为我的 pom 文件中版本为 snapshot,因此上传到了 snapshots 的仓库
PS:Harbor 是一个典型的分布式架构,因此在重启虚拟机后一定要去 harbor 的目录下使用 docker compose 启动没有启动的项目
Harbor 是一个用于存储和分发 Docker 镜像的企业级 Registry 服务器,通过添加一些企业必须的功能特性,例如安全,标识和管理等,扩展了开源 Docker Distribution。作为企业级的私有 Registy 服务器,Harbor 提供了更好的性能和安全性,提升用户使用 Registy 构建和运行环境时传输镜像的效率。Harbor 支持安装在多个 Registy 节点的镜像资源复制,镜像全部保存在私有 Registry 中,确保数据和知识产权在公司内部网络中管控,Harbor 也提供了用户管理,访问控制,活动审计的高级安全特性
前后端分离
)监控
)授权鉴权
)同步复制集群
)tar -zxvf harbor-offline-installer-v1.10.2.tgz
vim harbor.yml
#修改为服务器 IP (即Paas的ip)
hostname: reg.mydomain.com
如果没有 https 的证书请注释掉这一块,不然安装会报错
./install.sh
安装好以后会在当前目录下自动生成一个 docker-compose,启动即可
访问配置文件中的 hostname : port
所有有关harbor的配置信息都在harbor.yml下。用户名默认为 admin,密码为 Harbor12345
/etc/docker/daemon.json
中内容如下{
"registry-mirrors": ["https://9b35jrsu.mirror.aliyuncs.com"],
//harbor的hostname:port
"insecure-registries": ["192.168.224.131:9999"]
}
systemctl restart docker
docker info
docker login 192.168.224.131:9999
#或者使用命令
docker login 192.168.224.131:9999 -u admin -p Harbor12345
#先标记,tag source_image[:tag] /new_image_name[:tag]
docker tag mytest 192.168.224.131:9999/blog/mytest
#再推送
docker push 192.168.224.131:9999/blog/mytest
复制命令
docker pull 192.168.224.131:9999/blog/nginx:latest
然后先把原来的镜像删了
然后再进行拉取
拉取成功
mvn deploy
打包项目并上传到 Nexus创建一个目录,然后上传打包好的项目的 jar 包,使用 Dockerfile 构建镜像
FROM mysql
FROM tomcat
# VOLUME 指定了临时文件目录为/tmp。
# 其效果是在主机 /var/lib/docker 目录下创建了一个临时文件,并链接到容器的/tmp
VOLUME /tmp
# 将jar包添加到容器中并更名为app.jar
ADD demo-0.0.1-SNAPSHOT.jar app.jar
# 运行jar包
ENTRYPOINT ["java","-jar","app.jar"]
docker build -t blog .
version: '3.1'
services:
myblog:
image: blog
container_name: blog
ports:
- 8089:8083
docker-compose up -d
docker tag blog 192.168.224.131:9999/blog/myblog
docker push 192.168.224.131:9999/blog/myblog
让 /etc/docker/daemon.json
中内容如下
{
"registry-mirrors": ["https://9b35jrsu.mirror.aliyuncs.com"],
//harbor的hostname:port
"insecure-registries": ["192.168.224.131:9999"]
}
先登录
docker login 192.168.224.131:9999 -u admin -p Harbor12345
再拉取
docker pull 192.168.224.131:9999/blog/myblog:latest
规范点,在 /usr/local/docker 目录下创建一个 myblog 的文件夹,编写一个 docker compose文件
version: '3.1'
services:
myblog:
image: 192.168.224.131:9999/blog/myblog
container_name: myblog
ports:
- 8999:8083
运行成功
由于 docker 的隔离机制,不同的容器其实是在不同的局域网当中
默认情况下,compose 会为应用创建一个网络,服务中的每个容器都会加入该网络中。这样,溶剂就可以被该网络中的其它容器访问。同时,该容器还能以服务名称作为 Hostname 被其它容器访问
默认情况下,应用程序的默认网络名基于 compose 的工程名称,而项目名称基于 docker-compose.yml 所在目录的名称
EG:一应用程序在名为 myapp 的目录中,并且 docker-compose.yml
如下所示
version: '3.1'
services:
web:
build: .
ports:
- 8000:8000
db:
image: postgres
当我们运行这个 docker-compose.yml
时,会执行以下几步:
myapp default
的默认网络web
这个名称加入网络 myapp defaultdb
这个名称加入网络 myapp default因此,这两个容器其实是在同一个网络中的,可使用服务名称 (web / db) 作为Hostname 相互访问。EG:web 这个服务可以使用postgres://db:5432 访问 db 容器
由于不同的 compose 在启动时会在不同的网络下,因此我们可以自己创建一个网络,然后在想要互通的 compose 中指定加入的自定义网络
docker network create myblog_netword
networks:
default:
external:
#网络名
name: myblog_netword
没有了端口映射,此时已经不准外网连接了
网络中的服务名:端口号
,对另一个服务进行访问重新打包项目,上传到 Paas 虚拟机的 /usr/local/docker/myblog 目录下,进入 Paas 虚拟机下对应目录,构建镜像
推送镜像
docker tag myblog 192.168.224.131:9999/blog/myblog
docker push 192.168.224.131:9999/blog/myblog
docker pull 192.168.224.131:9999/blog/myblog:latest
暴露端口给宿主机在进行开发时常用,但实际上上线的时候不应该暴露端口给宿主机,因为这样是不安全的