Docker从入门到放弃
- 一,docker的用途:
- 二,docker的好处:
- 三,docker特点:
- 四,docker的组成
- 五、docker安装
- 六,常用命令
- 七,docker的网络模式(主要是前面2种)
- 八,使用dockerfile生成docker
- 九,docker里配置nginx
- 十,docker部署mysql
- 十一,docker部署testlink
- 十二,docker部署Jenkins
- 十三,docker-compose简介
- 十四,docker的registry
- 十五,docker镜像构建
- 十五,docker与虚拟机的区别
一,docker的用途:
- 提供统一的环境:在本地测试其他人软件,或者把软件和环境一起打包,给其他人进行测试
- 提供快速拓展,弹性伸缩的云服务:比如双十一时候业务量会比平时多好几倍,为了应对提前扩容是个好办法,但是平时又不需要用到,就会造成浪费,一种方法是可以节前把机器运过来,拓展,开机,过了大型活动后下线,这种就比较麻烦。用了docker后,可以只进行简单配置,10台服务器可以变成上千台,节日时就能快速进行拓展,后续又快速的把能力进行转移下线,节省资源。有了标准化程序之后,不管在什么机器上,直接把它下载过来并启动,而无需担心有什么问题。
- 防止其他用户的进程把服务器资源占用过多。使用docker可以把不同内容进行隔离,对方发生的错误只会在固定范围内产生影响,不会对其他模块产生牵连
二,docker的好处:
1)可以使开发完全控制环境,之前这些操作是依赖运维的,现在就不需要依赖他们,更加灵活,也降低了风险
左侧是构建出来的镜像,会被推到镜像仓库,然后测试人员会对镜像进行测试,包括集成测试,容量测试,预发测试等,这些环境未来使用的也是同一个镜像,这样我们可靠性就大大增加,维护环境的精力也大大减少。
2)部署简单,减轻运维工作量
3)节省机器资源
三,docker特点:
- 标准化
1)运输方式(只需要通过命令即可把程序和环境从一个机器运到另一个机器上)
2)存储方式(程序和环境的存储,不需要关心程序存在什么地方,只需要关心使用或停止它的时候执行对应的命令即可)
3)API接口(不需要tomcat,rabbitmq等应用等自己的命令了,使用同样命令即可控制所有应用) - 灵活:即使是最复杂的应用也可以集装箱化
- 轻量级:容器利用并共享主机内核
- 便携式:可以在本地构建,部署到云,并在任何地方运行
四,docker的组成
1,image镜像:
本质就是文件,包括应用程序文件,运行环境等
存储:联合文件系统,UnionFS,是分层文件系统,把不同文件目录挂到一个虚拟的文件系统下,具体分几层可以自己控制。每一层构建好后,下一层不再变化,上面一层是以下面一层作为基础的,最终多层组成了文件系统。
2,容器:
1,镜像类似于java中的类,而容器就是示例,镜像运行后就变成一个容器
2,容器的这一层是可以修改的,而镜像是不可以修改的(跑起来之后上面就会多一层可修改的层,主要修改工作都放在这一层)
上面的图只有第一层是可写的,因为需要创建日志啥的,程序运行时如果要写镜像文件,可以写在这一层。其他都是只读的。比如我修改了一个系统文件,这个文件属于apache这层的,这样可能就产生2个文件。处理方式是在找这个文件的时候,会从上往下开始找,如果上面没有才会找到下面这层。由于我们已经修改了上层的apache文件,而且原来文件是只读的,不可写,所以修改实际意味着把文件复制一份,然后放到最上层中,这样会在最上层中有一个变化的副本,未来想找文件时候,就可以一下子找到这个变化过的文件,修改也就生效的。
3,同一个镜像可以生成多个容器独立运行,而他们之间没有任何的干扰。
3,仓库:
1)相当于一个中转站,类似百度网盘,把文件上传上去,如果要使用就自己去下载
2)地址:
- 国外:hub.docker.com
- 国内:https://c.163yun.com/hub#/m/home/
3)也分为公有和私有
可以自己搭建一个镜像中心
4,client和deamon
- client:客户端,提供给用户一个终端,用户输入docker提供的命令来管理本地或远程的服务器
- deamon:服务端守护进程,接收client发送的命令并执行相应的操作
五、docker安装
本章以centos举例
- 安装插件:yum install -y yum-utils devices-mapper-persistent-data lvm2
- 设置镜像为阿里云:yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
- 安装dokcer-ce:yum -y install docker-ce
- 安装完成后可以使用docker -version命令确认是否安装成功
- 安装完成后可以设置开机自启:systemctl start docker
- 配置阿里云镜像:
1)进入阿里云官网,搜索容器镜像服务,如截图
2) 配置镜像
- 进入docker目录:cd /etc/docker
- 新建deamon.json文件:vim deamon.json
- 插入内容并保存:
{
"registry-mirrors": ["https://xcj4c1zv.mirror.aliyuncs.com"]
}
- 重启使配置生效: systemctl restart docker
- 测试:我们可以使用docker pull nginx进行验证是否安装成功
六,常用命令
ps:docker命令是区分大小写的!
命令 | 作用 |
systemctl start docker | 启动docker |
systemctl enable docker | 设置开机自启动 |
docker version | 查看docker版本 |
docker info | 查看具体信息 |
docker images | 查看镜像 |
docker network ls | 查看网络 |
docker create xx | 创建容器网络(不同容器想要互相通信必须在一个网络,所以需要新建容器网络) |
docker search busybox | 搜索镜像 |
docker pull xx | 拉取镜像(默认下载最新版本,也可以加上版本号下载指定版本,比如docker pull nginx:1.17.10,推荐这种) |
docker run xx | 运行镜像 |
docker run -d --name=influxdb --network grafana -p 8086:8086 -v ${PWD}/influxdb/:/var/lib/influxdb/ influxdb:1.7.10 | 让docker容器在后台运行 (-d 后台运行,–name:相当于域名,我们可以通过名字找到容器实际的ip地址,–network:指定具体网络,-p:指定端口号,jmeter通过这个端口写入数据到influxdb,-v:把容器的数据库文件挂载在当前目录的influxdb目录) |
docker save busybox > busybox.tar/docker save busybox -o busybox.tar | 导出(后面也可以带上版本号进行特定版本的删除) |
docker load < busybox.tar | 导入 |
docker rmi busybox:latest/具体版本号 | 删除(如果有容器正在使用这个是无法删除的,这个时候需要先rm -f xxx) |
docker tag busybox:latest busybox:test | 更改镜像名 |
docker history busybox | 查看镜像创建历史(如果查不到后面可以加具体版本号进行查询 docker history busybox:1.17.0) |
docker ps 或者docker ps -a | 查看当前容器列表 |
docker stats busybox | 查看资源占用 |
docker top busybox | 查看容器中运行的进程 |
docker start/restart/stop/kill id/name | 启动/重启/停止运行/杀掉容器 |
docker pause/unpause busybox | 暂停容器 |
docker exec -it [OPTIONS] CONTAINER COMMAND [ARG…] | 访问容器内部 exec:执行一个命令, it:把容器内部终端映射到当前终端 。比如:docker exec -it name ls 查看容器内部 |
docker cp busybox:/etc/hosts hosts | 复制文件 |
docker logs -f busybox | 查看容器日志 |
docker inspect 容器id | 查看容器/镜像的元信息 |
docker rm -f busybox | 强制删除容器(正在运行的程序可以使用这个命令强制删除) |
docker inspect -f ‘{{.Id}}’ 容器id | 格式化输出(提取内容里的id) |
docker diff busybox | 查看容器内的文件结构 |
七,docker的网络模式(主要是前面2种)
- bridge :桥接:仿佛是docker容器和外面的宿主机搭建了一座桥,可以通过这座桥使两端进行通信,当然内部外部还是完全独立的。(90%以上使用这个)
- host:主机:容器不会获得独立网络,而是和我们主机使用同一个网络,容器不会虚拟出自己的网卡ip等,会直接使用宿主机上的ip和端口
- none:没有网络
docker的隔离性是它的一大特点,它的网络也是隔离的,意味着里面运行的网络,外面是运行不到的。如果想对里面网络进行感知,需要用到网络配置,配置好之后可以让他们进行映射,
实操:
访问docker内的nginx,重点就是端口映射
docker run -d -p 8080:80 本机的8080端口映射到容器内部的80端口(-d:在后台启动)
配置完后记得去阿里云的安全组规则进行配置,否则无法生效
通过端口映射方法可以在一台服务器上去布置很多docker,每个docker是独立的并且可以通过一个端口来实现和外界的映射关系,实现了隔离和资源分配的目的。我们可以把ngnix换成任何我们想要的服务器,tomcat,springboot程序等。
如果一个容器对外暴露的端口很多,一个个写笔记繁琐,有个更方便的方法。
docker run -d -P xxx :创建容器并随机生成不同端口
-P:自动分配端口号,并把内部容器所有端口都进行映射
-p:手动指定端口映射关系
八,使用dockerfile生成docker
- dockerfile:文本文件,用来配置镜像用的
- 我们往往是在已有镜像上添砖加瓦,形成自己的镜像(一个镜像往往是通过继承另一个镜像得来的)
- 使用dockerfile的好处:
1)把文件放在版本控制下,这样我们对环境做的修改可以被追踪到。
2)有了这个文档后,可以清楚知道程序运行所需的环境,软件,配置等。
3)保证文档是最新的,新来的小伙伴可以很方便的知道具体的环境配置
关键字 | 作用 |
FROM | 基础镜像,FROM命令必须是dockerfile的首个命令 |
LABEL | 为镜像生成元数据标签信息,比如软件版本,作者信息之类的 |
USER | 指定运行容器时的用户名或UID,后续RUN也会使用指定用户,默认是管理员用户 |
RUN | RUN命令是dockerfile命令的核心部分,它接受命令作为参数并用于创建镜像。每条RUN 命令在当前基础镜像上执行,并且会提交一个新的镜像层 |
WORKERDIR | 设置CMD指明的命令的运行目录,为后续的RUN,CMD,ENTRYPOINT,ADD指令配置工作目录 |
ENV | 容器启动的环境变量,比如软件版本之类的 |
ARG | 构建环境的环境变量,针对dockerfile |
COPY | 复制文件,比如当前目录有很多配置文件需要复制到容器里,就可以使用 |
CMD | 容器运行时执行的默认命令,有个缺陷:使用docker run去执行容器的时候,如果后面加上一些别的指令,CMD里面的指令会被覆盖掉 |
ENTRYPOINT | 指定容器的入口,使用docker run去执行容器的时候,如果加上 --entrypoint参数,指令不会被覆盖掉 |
HEALTHCHECK | 容器健康状态检查, |
示例:使用dockerfile构建nginx容器,添加容器健康检查
1,新建一个dockerfile
# 基于 nginx:1.17.9镜像构建
FROM nginx:1.17.9
# 指定信息
LABEL maintainer="234333@qq.com"
# 设置环境变量
ENV NGINX_VERSION 1.17.9
ARG work_pwd=/data/html/
# 切换 root 用户
USER root
# 执行命令,安装curl 软件,设置软连接把nginx服务的日志显示
RUN apt-get -yq update && apt-get install -y curl && \
ln -sf /dev/stdout /var/log/nginx/access.log && \
ln -sf /dev/stderr /var/log/nginx/error.log
# 挂载类
VOLUME ["/data"]
# 设置工作目录
WORKDIR $work_pwd
# 复制index.html 文件到WORKDIR目录下
COPY index.html .
# 映射 80 端口
EXPOSE 80
# 此处CMD 作为 ENTRYPOINT 的参数
CMD ["nginx","-g","daemon off;"]
STOPSIGNAL SIGRTMAX
# 检查容器健康,通过访问NGINX服务80端口,来判断容器服务是否健康
HEALTHCHECK --interval=5s --timeout=3s \
CMD curl -fs http://localhost/ || exit 1
2,构建镜像
# -t:指定一个tag,这里指定标签为n,1表示版本号。后面那个“.”表示在当前目录下进行构建的
docker build -t n:1 .
成功后如图所示
执行成功后可以搜到这个
我们可以运行它
九,docker里配置nginx
- 下载nginx安装包
docker pull nginx:1.17.9
- 运行
- -p:指定端口(第一个80表示是当前电脑的端口号,第二个80表示映射后的端口号)
docker run -p 80:80 nginx:1.17.9
浏览器输入ip地址即可实现访问
配置后台运行
docker run -d --name docker -p 80:80 nginx:1.17.9
ps:正在运行的容器无法删除,除非强制删:docker rm -f nginx
十,docker部署mysql
1,下载mysql
docker pull mysql
2,配置后台运行
- -p 3306:3306:让宿主机的3306端口映射到容器的3306端口
- --name=xxx:自定义容器名称
- --privileged=true:让容器内的root真正拥有宿主机的权限
- -e xxx:e表示env,配置参数就加这个,这里是设置mysql的密码
docker run -d -p 3306:3306 --name mysql --privileged=true -e MYSQL_ROOT_PASSWORD=123456 mysql:latest
3,进入到容器内部,输入用户名密码,其他操作同mysql,不一一概述
docker exec -it mysql bash
mysql -u root -p
输入密码
十一,docker部署testlink
1,下载
docker pull bitnami/testlink
2,创建docker网络
docker network create testlink
ps:查看已有的容器网络:docker network ls
3,安装数据库
- -v ${PWD}/mariadb:/bitnami:把数据库里的数据持久化放在当前电脑上的目录,以防容器停止或者被删除的时候造成数据丢失
docker run -d --name mariadb -e MARIADB_ROOT_PASSWORD=mariadb -e MARIADB_USER=bn_testlink -e MARIADB_PASSWORD=bn_testlink -e MARIADB_DATABASE=bitnami_testlink --net testlink -v ${PWD}/mariadb:/bitnami bitnami/mariadb:10.3.22
3,运行testlink(docker -p 宿主机端口号:容器端口号)
- 第一个端口表示http的端口,第二个端口表示https的端口
docker run -d -p 8080:8080 -p 8443:8443 --name testlink -e TESTLINK_DATABASE_USER=bn_testlink -e TESTLINK_DATABASE_PASSWORD=bn_testlink -e TESTLINK_DATABASE_NAME=bitnami_testlink --net testlink -v ${PWD}/testlink:/bitnami bitnami/testlink:1.9.20
十二,docker部署Jenkins
1,拉取镜像(这里建议用最新版!!不要用lts,否则安装插件时候会因为版本不够高导致很多插件下载不了,血泪教训!!!)
docker pull jenkins/jenkins:latest
2,创建docker的文件映射卷
docker volume create jenkins
3,创建实例
# 8080端口:Jenkins对外服务端口
# 50000端口:slave节点与Jenkins的通信端口
docker run -d --name=jenkins -p 8080:8080 -p 50000:50000 -v jenkins:/var/jenkins_home jenkins/jenkins:latest
查看日志:这步可以获取密码,当然也可以用下面的查看的方式找到密码
# 容器id:之前启动成功时候那一长串号码
docker logs -f 容器id
4,获取初识密码
docker exec -it cat /var/jenkins_home/secrets/initialAdminPassword
如果走了3,4步还是没看到,可以 docker exec -it container_id /bin/bash
进入docker内部,然后cat /var/jenkins_home/secrets/initialAdminPassword
查看密码
5,打开浏览器,输入网址(ip:端口号)把密码输入进去
6,手动部署
- 简易部署:java -jar jenkins.war(不推荐)
- 正式部署:
1)调参:调增jvm参数
2)应用容器:使用tomcat,jetty启动
3)反向代理:使用nginx设置域名,https
二,Jenkins配置
- 修改时区:
1,删除已有实例
docker rm -f jenkins
2,重新创建实例并设置时区
docker run -d --name jenkins -p 8080:8080 -p 50000:50000 \
-v jenkins:/var/jenkins_home \
-e JAVA_OPTS=-Duser.timezone=Asia/Shanghai \
jenkins/jenkins:lts
- slave节点连接方式
1,什么时候使用节点和节点的作用?
当我们使用多台服务器时,并且配置了tomcat或jboss集群服务,可通过jenkins的节点配置,将jenkins项目发布在不同服务器上(分布jenkins工作空间,部署项目到不同服务器的tomcat或jboss),这就形成了jenkins的分布式。节点服务器不需要安装jenkins(只需要运行一个slave节点服务),构建事件的分发由master端(jenkins主服务)来执行。
2,具体操作:
创建完一个节点后,可以使用如下命令进行连接
wget http://ip:端口号/jnlnJars/agent.jar \
java -jar agent.jar\
-jnlpUrl http://ip:端口号/computer/demo/slave-agent.jnlp \
-workDir "/tmp/jenkins/"
具体配置:
十三,docker-compose简介
docker-compose是用于定义和运行多容器的docker应用程序的工具,通过docker compose,可以使用yaml文件来配置应用程序的服务
compose的使用一般分为三步:
1,使用dockerfile定义应用程序的环境,以便可以在任何地方复制它
2,在docker-compose.yml中定义组成应用程序的服务,以便他们可以在隔离环境中一起运行
3,运行 docker-compose up,然后compose启动并运行您的整个应用程序
十四,docker的registry
- registry是docker官方用来托管私有镜像的仓库。
- 运行pull,push,search时,是通过docker daemon 与docker registry通信。有时候使用docker hub这样的公共仓库可能不方便,我们可以通过registry创建一个本地仓库
- 因为docker服务器在国外,我们下载东西会比较慢,我们可以通过把镜像下载到本地,然后放在registry里面,本地局域网其他服务器都可以通过访问这个registry去下载之前下载过的镜像,提高下载速度,或者是存放公司通过dockerfile构建的镜像。
1,运行registry
docker run -d -p 5000:5000 -v ${PWD}/registry:/var/lib/registry --restart always --name registry registry:2.7.1
2,访问:http://ip:端口号/v2/_catalog 验证是否成功
ps:里面没有内容是因为没有上传镜像
3,进入另一个服务器,编辑daemon.json文件,把里面配置的内容改为之前配置的服务器的ip地址+端口号并保存,如下:
{
"insecure-registries": ["192.168.0.101:5000"]
}
4,重启服务,让服务生效
systemctl restart docker
目前是没有任何镜像的
5,切回本地搭建registry服务的终端,下载一个镜像,并使用docker tag命令给镜像打个标签
docker tag nginx:1.18.0 192.168.0.101:5000/nginx:1.18.0
6,推到本地仓库
docker push 192.168.0.101:5000/nginx:1.18.0
7,切换另一台要下载东西的服务器,下载刚刚推到registry的nginx
docker pull 192.168.0.101:5000/nginx:1.18.0
这个时候查看之前打开的网址,会看到nginx在上面了
十五,docker镜像构建
在日常工作中,常常需要制作自己项目的镜像,一般通过以下2种方式制作:docker commit ,dockerfile。
1.docker commit 一般是从一个运行状态的容器来创建一个新的镜像。定制镜像应该使用dockerfile来完成。默认commit镜像,对外不可解释,不方便排查问题,可维护性差。
2,docker commit 容器名 新镜像名:tag 只推荐临时使用。
docker commit nginx n:2
3,dockerfile文件还需要通过docker build 进行构建
4,docker build配置:
参数 | 作用 |
.dockerignore | 忽略文件 |
docker build -f | 指定文件 |
docker build -t | 添加标签 |
docker build --no-cache | 不使用缓存 |
docker build --build-arg | 构建时变量 |
ARG指令变量 | |
十五,docker与虚拟机的区别
- 容器与容器之间只是进程的隔离,而虚拟机是完全的自愿隔离
- 虚拟机的启动可能需要几分钟,docker的启动是秒级甚至更短
- 容器使用宿主操作系统的内核,而虚拟机使用完全独立的内核