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的用途:

  1. 提供统一的环境:在本地测试其他人软件,或者把软件和环境一起打包,给其他人进行测试
  2. 提供快速拓展,弹性伸缩的云服务:比如双十一时候业务量会比平时多好几倍,为了应对提前扩容是个好办法,但是平时又不需要用到,就会造成浪费,一种方法是可以节前把机器运过来,拓展,开机,过了大型活动后下线,这种就比较麻烦。用了docker后,可以只进行简单配置,10台服务器可以变成上千台,节日时就能快速进行拓展,后续又快速的把能力进行转移下线,节省资源。有了标准化程序之后,不管在什么机器上,直接把它下载过来并启动,而无需担心有什么问题。
  3. 防止其他用户的进程把服务器资源占用过多。使用docker可以把不同内容进行隔离,对方发生的错误只会在固定范围内产生影响,不会对其他模块产生牵连

二,docker的好处:

1)可以使开发完全控制环境,之前这些操作是依赖运维的,现在就不需要依赖他们,更加灵活,也降低了风险

切换docker的数据源 docker内切换用户_服务器


切换docker的数据源 docker内切换用户_容器_02


左侧是构建出来的镜像,会被推到镜像仓库,然后测试人员会对镜像进行测试,包括集成测试,容量测试,预发测试等,这些环境未来使用的也是同一个镜像,这样我们可靠性就大大增加,维护环境的精力也大大减少。

2)部署简单,减轻运维工作量
3)节省机器资源

三,docker特点:

  1. 标准化
    1)运输方式(只需要通过命令即可把程序和环境从一个机器运到另一个机器上)
    2)存储方式(程序和环境的存储,不需要关心程序存在什么地方,只需要关心使用或停止它的时候执行对应的命令即可)
    3)API接口(不需要tomcat,rabbitmq等应用等自己的命令了,使用同样命令即可控制所有应用)
  2. 灵活:即使是最复杂的应用也可以集装箱化
  3. 轻量级:容器利用并共享主机内核
  4. 便携式:可以在本地构建,部署到云,并在任何地方运行

四,docker的组成

切换docker的数据源 docker内切换用户_docker_03


切换docker的数据源 docker内切换用户_nginx_04


1,image镜像:

本质就是文件,包括应用程序文件,运行环境等

存储联合文件系统,UnionFS,是分层文件系统,把不同文件目录挂到一个虚拟的文件系统下,具体分几层可以自己控制。每一层构建好后,下一层不再变化,上面一层是以下面一层作为基础的,最终多层组成了文件系统。

切换docker的数据源 docker内切换用户_切换docker的数据源_05


切换docker的数据源 docker内切换用户_容器_06


2,容器:

1,镜像类似于java中的类,而容器就是示例,镜像运行后就变成一个容器

2,容器的这一层是可以修改的,而镜像是不可以修改的(跑起来之后上面就会多一层可修改的层,主要修改工作都放在这一层)

切换docker的数据源 docker内切换用户_nginx_07


上面的图只有第一层是可写的,因为需要创建日志啥的,程序运行时如果要写镜像文件,可以写在这一层。其他都是只读的。比如我修改了一个系统文件,这个文件属于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举例

  1. 安装插件:yum install -y yum-utils devices-mapper-persistent-data lvm2
  2. 设置镜像为阿里云:yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
  3. 安装dokcer-ce:yum -y install docker-ce
  4. 安装完成后可以使用docker -version命令确认是否安装成功
  5. 安装完成后可以设置开机自启:systemctl start docker
  6. 配置阿里云镜像:
    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的数据源 docker内切换用户_docker_08


切换docker的数据源 docker内切换用户_容器_09

七,docker的网络模式(主要是前面2种)

  1. bridge :桥接:仿佛是docker容器和外面的宿主机搭建了一座桥,可以通过这座桥使两端进行通信,当然内部外部还是完全独立的。(90%以上使用这个)
  2. host:主机:容器不会获得独立网络,而是和我们主机使用同一个网络,容器不会虚拟出自己的网卡ip等,会直接使用宿主机上的ip和端口
  3. none:没有网络
    docker的隔离性是它的一大特点,它的网络也是隔离的,意味着里面运行的网络,外面是运行不到的。如果想对里面网络进行感知,需要用到网络配置,配置好之后可以让他们进行映射,

实操:

访问docker内的nginx,重点就是端口映射

docker run -d -p 8080:80 本机的8080端口映射到容器内部的80端口(-d:在后台启动)

配置完后记得去阿里云的安全组规则进行配置,否则无法生效

切换docker的数据源 docker内切换用户_容器_10


通过端口映射方法可以在一台服务器上去布置很多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的数据源 docker内切换用户_容器_11


执行成功后可以搜到这个

切换docker的数据源 docker内切换用户_切换docker的数据源_12


我们可以运行它

切换docker的数据源 docker内切换用户_切换docker的数据源_13

九,docker里配置nginx

  1. 下载nginx安装包
docker pull nginx:1.17.9
  1. 运行
  • -p:指定端口(第一个80表示是当前电脑的端口号,第二个80表示映射后的端口号)
docker run -p 80:80 nginx:1.17.9

浏览器输入ip地址即可实现访问

切换docker的数据源 docker内切换用户_切换docker的数据源_14

配置后台运行

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的数据源 docker内切换用户_切换docker的数据源_15

十二,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的数据源 docker内切换用户_docker_16

十三,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:里面没有内容是因为没有上传镜像

切换docker的数据源 docker内切换用户_容器_17

3,进入另一个服务器,编辑daemon.json文件,把里面配置的内容改为之前配置的服务器的ip地址+端口号并保存,如下:

{
  "insecure-registries": ["192.168.0.101:5000"]
}

4,重启服务,让服务生效

systemctl restart docker

目前是没有任何镜像的

切换docker的数据源 docker内切换用户_docker_18


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的数据源 docker内切换用户_服务器_19

十五,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内切换用户_docker_20

十五,docker与虚拟机的区别

  1. 容器与容器之间只是进程的隔离,而虚拟机是完全的自愿隔离
  2. 虚拟机的启动可能需要几分钟,docker的启动是秒级甚至更短
  3. 容器使用宿主操作系统的内核,而虚拟机使用完全独立的内核