项从辗转于不同环境,因环境导致不可预知的问题。
而使用docker可以将环境一起打包,就解决了环境问题,而且他还有其他优点:
对于开发的优点:
docker使用C/S架构,Client通过接口与server进程通信实现容器的构建,运行和发布,如图:
操作系统64位,Centos的内核版本3.1及以上
查看内核版本:
uname -r
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PRABZCOy-1588084686371)(en-resource://database/4164:1)]
yum最新
sudo yum update
安装安装需要的软件包
yum-util 提供yum-config-manager功能,另外两个是devicemapper驱动依赖的
yum install -y yum-utils device-mapper-persistent-data lvm2
#安装前可查看device-mapper-persistent-data和lvm2是否已经安装
rpm -qa|grep device-mapper-persistent-data
rpm -qa|grep lvm2
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum makecache fast
yum list docker-ce -y
#查看docker版本
docekr version 或者 docker -v
systemctl start docker
#开机启动
systemctl enable docker
出现下面语句就OK了
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.
{ “registry-mirrors”: [“https://5258x07n.mirror.aliyuncs.com”] }
记住更改完要重启docker
systemctl restart docker
docker run --name 容器名 -i -t -d -p 主机端口:容器端口 -v 主机目录:容器目录 镜像名称
–name 启动后的容器名称
-i 交互模式运行
-t 分配一个伪终端,常与-i组合使用
-d 后台运行
-v 指定挂卷目录
从官方下载的镜像,往往需要我们自定义很多东西,而为了能够将我们自定义的东西保存下来,就是将其制作为一个镜像
更新镜像:
docker commit -a 作者名 -m 描述信息 容器ID或名称:版本 镜像名
构建镜像:
docker build -f 目录文件 -t 镜像名和版本 .
#-f 指定dockerfile文件路径,不指定,默认Dockerfile
#-t 指定镜像名称和版本
#. 指当前目录,这里实际上需要一个上下文路径
我打包了一个jar测试:
#java基础镜像
FROM java:8
#作者
MAINTAINER ali
#复制文件到镜像
ADD sso-eureka-server-1.0-SNAPSHOT.jar /sso-eureka-server-1.0-SNAPSHOT.jar
#暴露端口
EXPOSE 8000
#启动后执行命令
CMD ["java","-jar","sso-eureka-server-1.0-SNAPSHOT.jar"]
#下面这句也是一样的
#ENTRYPOINT ["java","-jar","sso-eureka-server-1.0-SNAPSHOT.jar"]
构建:
docker build -f ./DockerFile -t sso-eureka .
运行:
FROM
第一行必须是 FROM ,指定基础镜像
MAINTAINER
作者信息
LABEL
给镜像指定元数据,可以有多个
COPY
用于从宿主机复制文件到创建的新镜像文件
COPY <src>...<dest>
COPY ["" ,..."" ]
#:要复制的源文件或者目录,可以使用通配符
#:目标路径,即正在创建的image的文件系统路径;建议使用绝对路径,否则COPY指令则以WORKDIR为其起始路径
注意:如果你的路径中有空白字符,通常会使用第二种格式
规则:
必须是build上下文中的路径,不能是其父目录中的文件(当前目录下)
如果是目录,则其内部文件或子目录会被递归复制,但目录自身不会被复制
如果指定了多个,或在中使用了通配符,则必须是一个目录,则必须以/符号结尾
如果不存在,将会被自动创建,包括其父目录路径
ADD
基本用法和COPY指令一样,ADD支持使用TAR文件和URL路径
ADD <src>...<dest>
ADD ["" ,..."" ]
WORKDIR
用于为Dockerfile中所有的RUN、CMD、ENTRYPOINT、COPY和ADD指定设定工作目录,只会影响当前WORKDIR之后的指令。
在Dockerfile文件中,WORKDIR可以出现多次,路径可以是相对路径,但是它是相对于前一个WORKDIR指令指定的路径另外,WORKDIR可以是ENV指定定义的变量
VOLUME
用来创建挂载点,可以挂载宿主机上的卷或者其他容器上的卷
EXPOSE
用于给容器打开指定要监听的端口以实现和外部通信
语法:
EXPOSE <port>[/<protocol>] [<port>[/<protocol>]...]
protocol>用于指定传输层协议,可以是TCP或者UDP,默认是TCP协议
EXPOSE可以一次性指定多个端口,例如:EXPOSE 80/tcp 80/udp
ENV
用来给镜像定义所需要的环境变量,并且可以被Dockerfile文件中位于其后的其他指令(如ENV、ADD、COPY等)所调用
ENV
ENV =...
第一种格式中,之后的所有内容都会被视为的组成部分,所以一次只能设置一个变量
第二种格式可以一次设置多个变量,如果当中有空格可以使用 \ 进行转义或者对加引号进行标识;另外 \ 也可以用来续行
CMD
容器启动时运行的命令
CMD
CMD ["","",""]
CMD ["",""]
前两种语法和RUN相同
第三种语法用于为ENTRYPOINT指令提供默认参数
RUN和CMD区别:
RUN
指定docker build过程中运行的指令
用法:
RUN shell命令
#这种写法和上面不一样
RUN ["/bin/bash","-c","命令"]]
ENTRYPOINT
类似CMD功能,用于指定容器默认运行的程序。
ENTRYPOINT<command> ENTRYPOINT["<executable>","<param1>","<param2>"]
和CMD不同的是ENTRYPOINT启动的程序不会被docker run命令指定的参数所覆盖,而且,这些命令行参数会被当做参数传递给ENTRYPOINT指定的程序(但是,docker run命令的–entrypoint参数可以覆盖ENTRYPOINT)docker run命令传入的参数会覆盖CMD指令的内容并且附加到ENTRYPOINT命令最后作为其参数使用同样,Dockerfile中可以存在多个ENTRYPOINT指令,但是只有最后一个会生效Dockerfile中如果既有CMD又有ENTRYPOINT,并且CMD是一个完整可执行命令,那么谁在最后谁生效
阿里云官网:https://cr.console.aliyun.com/cn-hangzhou/repositories
$ sudo docker login [email protected] registry.cn-hangzhou.aliyuncs.com
用于登录的用户名为阿里云账号全名,密码为开通服务时设置的密码。您可以在访问凭证页面修改凭证密码。
2. 从Registry中拉取镜像
$ sudo docker pull registry.cn-hangzhou.aliyuncs.com/alry/sso:[镜像版本号]
$ sudo docker login [email protected] registry.cn-hangzhou.aliyuncs.com
$ sudo docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/alry/sso:[镜像版本号]
$ sudo docker push registry.cn-hangzhou.aliyuncs.com/alry/sso:[镜像版本号]
请根据实际镜像信息替换示例中的[ImageId]和[镜像版本号]参数。
#docker网络
Docker允许通过外部访问容器或容器互联的方式来提供网络服务。
安装Docker时,会自动安装一块Docker网卡称为docker0,用于Docker各容器及宿主机的网络通信,网段为172.0.0.1。
Docker网络中有三个核心概念:沙盒(Sandbox)、网络(Network)、端点(Endpoint)。
Docker服务在启动的时候会创建三种网络,bridge、host和none,还有一种共享容器的模式container
桥接模式,主要用来对外通信的,docker容器默认的网络使用的就是bridge。
使用bridge模式配置容器自定的网络配置
#配置容器的主机名
docker run --name t1 --network bridge -h [自定义主机名] -it --rm busybox
#自定义DNS
docker run --name t1 --network bridge --dns 114.114 -it --rm busybox
#给host文件添加一条
docker run --name t1 --network bridge --add-host [hostname]:[ip] -it --rm busybox
这里我们将之前搭建的jenkins和sonar加入同一个网络使它们能够互相连接
#新建bridge
docker network create dep_network
#将之前我们的jenkins加入该网络
docker network connect dep_network jenkins
#将之前的sonar加入该网络
docker network connect dep_network sonarqube
在建立了网络之后,我们
docker inspect jenkins
和docker inspect sonarqube
查看jenkins和sonar的容器网络,可以看到他们已经在172.19.0.0网段了。
进入jenkins容器,ping sonar的地址
如果要更深入的了解bridge的设置:docker bridge
host类型的网络就是主机网络的意思,绑定到这种网络上面的容器,内部使用的端口直接绑定在主机上对应的端口,而如果容器服务没有使用端口,则无影响。
从某种意义上来说,none应该算不上网络了,因为它不使用任何网络,会形成一个封闭网络的容器
共享另外一个容器的network namespace,和host模式差不多,只是这里不是使用宿主机网络,而是使用的容器网络
/etc/docker/daemon.json文件
{
"bip": "192.168.5.5/16",
"fixed-cidr": "10.20.0.0/16",
"fixed-cidr-v6": "2001:db8::/64",
"mtu": 1500,
"default-gateway": "10.20.1.1",
"default-gateway-v6": "2001:db8:abcd::89",
"dns": ["10.20.1.2","10.20.1.3"]
}
核心选项为bip,即bridge ip之意,用于指定docker0桥自身的IP地址;其它选项可通过此地址计算得出
创建自定义的桥网络
docker network create -d bridge --subnet "172.26.0.0/16" --gateway "172.26.0.1" mybr0
Dockerfile模板文件来快速构建一个自己的镜像并运行为应用容器。但是在平时工作的时候,我们会碰到多个容器要互相配合来使用的情况,比如数据库加上咱们Web应用等等。这种情况下,每次都要一个一个启动容器设置命令变得麻烦起来,所以Docker Compose诞生了。
Compose的作用是“定义和运行多个Docker容器的应用”。使用Compose,你可以在一个配置文件(yaml格式)中配置你应用的服务,然后使用一个命令,即可创建并启动配置中引用的所有服务。
Compose中两个重要概念:
Compose项目是用Python写的,可以使用Python-pip安装,也可以通过GitHub下载二进制文件进行安装。
安装Python-pip
yum install -y epel-release
yum install -y python-pip
安装docker-compose
pip install docker-compose
验证是否安装
docker-compose --version
卸载
pip uninstall docker-compose
curl -L https://github.com/docker/compose/releases/download/1.25.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
给二进制下载文件可执行的权限
chmod +x /usr/local/bin/docker-compose
可能没有启动程序,设置软连接,比如:
ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
验证是否安装
docker-compose --version
卸载
如果是二进制包方式安装的,删除二进制文件即可。
rm /usr/local/bin/docker-compose
知识参考:https://www.cnblogs.com/minseo/p/11548177.html
通过定义一个docker-compse.yml模板文件来定义一组相关联的应用容器为一个项目。
标准的模板应该包含:version、services、networks三大部分,最关键的是services和networks两个部分。
这里借用《 持续集成篇四 搭建sonar》
的步骤创建一个搭建soanrQube平台的docker-compose.yml
version: '2'
services:
pgdb2:
image: postgres
ports:
- 5433:5432
volumes:
- /data/pgdata:/var/lib/postgresql/data
environment:
POSTGRES_USER: sonar
POSTGRES_PASSWORD: "sonar"
sonarqube2:
image: sonarqube
ports:
- 9001:9000
volumes:
- /data/sonarqube2/conf:/opt/sonarqube/conf
- /data/sonarqube2/data:/opt/sonarqube/data
- /data/sonarqube2/logs:/opt/sonarqube/logs
- /data/sonarqube2/extensions:/opt/sonarqube/extensions
depends_on:
- pgdb2
links:
- pgdb2:db
environment:
SONARQUBE_JDBC_URL: jdbc:postgresql://db:5432/sonar
SONARQUBE_JDBC_USERNAME: sonar
SONARQUBE_JDBC_PASSWORD: "sonar"
ES_JAVA_OPTS: "-Xms1g -Xmx1g"
container_name: sonarqube2
该段是对上面yaml文件的解析和说明
指定服务的镜像名称或ID,如果本地不存在,则拉取
和image不同,image是基于镜像,build是基于dockerFile;docker-compose必须定义image和build中的一个,其他都是可选的。
在version 1中,不允许同时使用image和build,但是version 2是可以的,如果指定了这两个,那么build出来的镜像会打上image的标签。
build目录指定可以是绝对路径,也可以是相对路径。
可以覆盖容器启动后默认执行的命令
compose的容器不指定名称时的名称格式是:<项目名称>_<服务名称>_<序号>
这里的项目名称在启动时没有指定则用默认的文件目录名称为项目名。
使用该标签指定名称;
启动需要顺序(依赖)的容器需要设置该属性
这个和depends_on有些不同,links是连接到其他服务中的容器,详细看注释
#services下的服务(省略部分代码)
#数据库服务postgres
pgdb2:
image: postgres
ports:
#我这边暴露的端口是5433,内部容器端口是5432,注意看下面的连接时5432
- 5433:5432
#sonarqube服务
sonarqube2:
image: sonarqube
ports:
#暴露对外的端口,访问9001
- 9001:9000
#依赖postgres服务
depends_on:
- pgdb2
#连接pgdb2服务内部容器
links:
#链接到postgres数据库,另起别名“db”
- pgdb2:db
environment:
#请注意这里连接的地址,我使用使用的是pgdb2的别名db,然后端口是pgdb2的内部端口,没有使用外部端口
SONARQUBE_JDBC_URL: jdbc:postgresql://db:5432/sonar
端口映射
ports:
- "8000:8000"
挂卷设置;
volumes:
#容器内创建目录
- /var/lib/mysql
#主机路径映射到容器路径
- /opt/data:/var/lib/mysql
#以compose当前目录为为准
- ./cache:/tmp/cache
#以用户路径为准
- ~/configs:/etc/configs/:ro
暴露端口,不做端口映射,仅指定容器端口。
expose:
- "3000"
环境变量:
environment:
POSTGRES_USER: sonar
#这里不用引号也可以,如果中间有空格就需要使用双引号
POSTGRES_PASSWORD: "sonar"