Doker从0-1
1、docker思想:
它是一种集装箱的思想,,在以前我们部署一个项目上线的时候,我们要部署各种各样的环境、配置、依赖等,各种各样的环境的配置是十分麻烦的,所以就有了docker。他就是将我们的项目和环境配置一起打包,然后发给部署人员进行部署。将每一个项目都打包成一个独立的包,包与包之间又是隔离的,我们只需要将我们的包发布,别人就可以直接拿上我们的包去运行,就能很快速的将项目部署起来。我们将打号的包叫镜像。就像一个箱子一样把他们装在一起。docker思想也是虚拟机的思想,不过与虚拟机有些许的差异。docker是容器化技术,不完全是虚拟机技术。
2、虚拟机技术与docker容器化技术:
虚拟机技术:虚拟出完整的操作系统,包括硬件接口驱动内核等。占用的资源多,冗余的步骤多,启动慢。
容器化技术:不是完全模拟一个完整的操作系统。他是直接运行仔宿主机的内核上,容器是没有内核的。每个容器都是相互隔离的,互不影响,并且每个容器都有自己的文件系统。
3、docker的组成:
客户端:操作docker
服务器端:docker
仓库:存放镜像的地方
基本运行方式:先去仓库拉去镜像,然后仔docker的服务器端运行镜像,运行起来的镜像叫做容器
镜像就是我们打包好的想的项目,运行起来后我们也可以在里面放上自己的东西,还能做成我们自己的镜像。他就像一个模板,我们呢可以通过一个镜像运行多个容器,每个容器的是互不干扰的。
4、安装docker:
卸载老版本:
sudo yum remove docker \
docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine
安装依赖
$ sudo yum install -y yum-utils \
device-mapper-persistent-data \
lvm2
设置源
$ sudo yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
#安装docker
$ sudo yum install docker-ce docker-ce-cli containerd.io
#启动docker
$ sudo systemctl start docker
配置镜像源
创建或修改 /etc/docker/daemon.json 文件,修改为如下形式
{
"registry-mirrors": [
"http://hub-mirror.c.163.com",
"https://docker.mirrors.ustc.edu.cn",
"https://registry.docker-cn.com"
]
}
docker启动镜像的流程:
docker底层原理:
docker是一个C/S结构的系统设计,他通过守护进程的方式运行在主机上,通过socket从客户端访问,docker-server接收docker-client的命令,然后执行命令。
5、docker常用命令和镜像命令:
docker version :查看docker的版本信息
docker info :查看docker的详细的信息
docker 命令 --help :查看该命令的帮助手册
镜像命令:
docker images :查看我们本地所有的镜像
docker images -aq :查看我们所有镜像的ID号
docker search 镜像名 :搜索镜像(共有仓库搜索)
docker pull 镜像名 :从远程仓库拉取镜像到本地
docker rmi 镜像名/id :删除镜像
6、docker容器的命令:
docker run 参数 镜像名/id /bin/bash :创建一个容器并启动他 // 参数:--name(给容器起一个名字),-d(后台方式运行),-it(交互式运行并进入容器),-p(指定端口号:端口映射)
exit 退出容器
docker ps -a :查看运行及曾运行的容器
docker rm 容器名/id :删除容器(无法删除运行中的容器,加-f选项可以强制删除)
docker start 容器名/id :启动一个容器
docker restart 容器名/id :重启一个容器
docker stop 容器名/id :停止一个容器
docker kill 容器名/id :强制停止
docker logs -ft 容器名/id :查看容器的日志
docker top 容器名/id :查看容器内的进程信息
docker inspect 容器名/id :查看容器的详细信息详情
docker exec -it 容器名/id /bin/bash :进入到正在运行中的容器
docker cp 容器名/id:容器内的文件地址 主机文件地址 :将容器内的文件拷贝到外面的主机上
docker cp 主机文件地址 容器名/id:容器内的文件地址 :将主机上的文件拷贝到容器内
7、使用docker安装一个Nginx:
docker pull nginx :拉取nginx镜像,默认拉取最新版本,可在后面加版本号:版本号拉取其他的版本
docker run -it --name nginx_01 -p 8888:80 nginx :使用nginx镜像开启一个名叫nginx_01的容器,容器内部80端口映射到外部的8888端口。
8、镜像的原理:
他是一种联合文件系统,联合问价系统是一种轻量级,分层并具有高性能的文件系统,支持对文件系统的修改以及层级的叠加。所以镜像就是一个联合文件系统。不同的镜像如果具有相同的层级部分,那么他们是可以共享的,这就极大的节省的空间。所有的镜像都是层级的叠加,每添加一个镜像就在联合文件系统上添加一层。
注意:docker的镜像都是只读的,也就是说源镜像层我们是无法改变的,但是当镜像启动的时候,一个新的可写层被添加到镜像的顶部,然后我们在可写层添加我们的东西,可以重新打包成一个新的镜像。
打包一个自己的镜像:docker commit -m=‘‘镜像的描述信息’’ -a=‘’作者‘’ 容器名/id(原来的) 作者名/容器名(新的镜像):版本号
我们可以通这种方式来保存当前容器的状态,可以当作快照功能来用。
9、容器的数据卷
当我们的服务在容中跑起来的时候,会产生一些数据(如mysql),但是当我们删除容器的时候我们的数据就会同步的删除,所有我们要做容器与数据分离的操作。docker用到的就是数据卷技术,数据卷技术本质就是挂载,将容器中的目录挂载到物理机上,从而达到一种数据的同步,即使我们的容器被删了,但是我们在物理机上的数据还存在的。保证数据的持久性。一旦做了数据卷挂载,那么数据的操作就是双向的,也就是外面对数据修改也会同步到容器内,而且处于未运行的容器数据也会同步(也就是只要容器还在数据就会同步)。
使用数据卷:docker run -it -v 挂载的主机的目录:容器内部的目录 :将容器内部该目录下的所有数据同步到主机的该目录下。(通过-v参数)
说明:数据卷挂载有三种方式:
1)、指定目录挂载:-v 挂载的主机的目录:容器内部的目录 :挂载到该目录下
2)、匿名挂载:-v 容器内部地址 :随机生成一个挂载目录名(挂载与/var/lib/docker/volumes/随机挂载名字/_data)将数据挂载到这里
3)、具名挂载:-v 挂载名 :(挂载与/var/lib/docker/volumes/挂载名/_data)将数据挂载到这里
特别:-v 挂载的主机的目录:容器内部的目录:ro或者rw :表示只可读或者可读可写(表示权限)
10、容器间的数据卷:
容器可以与主机进行数据共享同步,那么容器之间如何数据共享?可以通过数据拷贝的方式来实现我们容器之间的数据共享。如:
docker run -d -v 内路径 --name 容器1 镜像名 /bin/bash
docker run -d -v 内路径 --name 容器2 --volumes-from 容器1 镜像名 /bin/bash
容器1为辐容器,容器2为子容器,将容器2挂载到容器1上去,就实现了容器间的数据共享。(关键字:--volumes-from)
11、Dockerfile:
Dockerfile:构建镜像的文件(相当于构建镜像的源码),我们通过Dockerfile构建自己的镜像。文件里面是一些命令参数的脚本。
构建镜像的步骤:编写Dockerfile文件;通过docker build命令运行Dockerfile文件形成一个镜像;docker run我们生成的镜像;可以通过docker pull发布我们自己的镜像。
Dockerfile语法要点:
所有的关键字(指令)都必须要大写;从上到下一次执行;#为注释;每个指令都会创建一个新的层并提交。
Dockerfile的指令:
FROM :指定基础镜像,一切从这里开始(就是在该基础镜像上构建镜像)
MAINTAINER :镜像的作者
RUN :构建镜像的时候镜像运行的指令,如:RUN yum -y install vim (构建镜像的时候就会去给我们安装vim,我们的镜像中就会有vim工具)
ADD :往镜像里面添加东西,如:ADD /test1.txt /home/test1.txt.bak(构建镜像时将/text文件copy到/home/test.txt.bat)
WORKDIR :镜像的工作目录
VLOUME :在主机上挂载的卷位置
EXPOSE :镜像启动默认暴露的端口,没有设置则启动时通过-p参数设置
CMD :指定容器启动时运行的命令(默认只要最后一个有效)切不可追加命令
ENTRYPOINT :指定容器启动时运行的命令,不可追加命令
COPY :类似于ADD
ENV :构建镜像时设置环境变量
Dockerfile例子:
FROM ${base_img}
FROM ${base_img} RUN mkdir -p /etcd /opt/etcd/data; \ chown -R csmp.csmp /opt/etcd; \ curl -sL http://10.47.0.26/${arch}/etcd-v3.5.1-linux-${arch}.tar.gz -o /etcd/etcd.tgz; \ tar --strip=1 -C /etcd -xzvf /etcd/etcd.tgz;\ cp /etcd/etcd /usr/local/bin/; \ cp /etcd/etcdctl /usr/local/bin/; \ cp /etcd/etcdutl /usr/local/bin/; \ /usr/local/bin/etcd --version; \ /usr/local/bin/etcdctl version; \ rm -rf /etcd/etcd.tgz /etcd COPY files/etcd.yaml /opt/etcd/etcd.yaml ENV ETCD_DATA_DIR=/opt/etcd/data EXPOSE 2379 2380 USER csmp WORKDIR /opt/etcd CMD “----end----”
编写好我们的Dockerfile文件时,可以通过docker build -f Dockerfile文件的路径 -t 生成的镜像名 :来生成我们的镜像
我们可以通过docker history 镜像名/id :来查看我们的构建镜像的步骤(和我们写的Dockerfile里面的步骤一样)
12、docker的网络
每当运行一个容器的时候,docker会给这个容器分配一个IP地址,物理机可以通过docker作为跳板与容器通信。特别:容器与docker或者与其他容器之间通信时通过双网卡实现的,也就是说容器的网卡是成对出现的,成对出现的网卡技术叫evth-pair技术,一段连着协议,一段连着彼此。从而达到通信的功能。所有所有的容器都是都可以与docker通信,而容器间又是通过docker做为中间桥梁来做数据转发通信的(此时docker相当于路由器)。
docker是与物理机直接相连的(通过桥接模式),docker的默认网卡是docker0,如果不指定容器的网络,那么docker容器就会默认连接docker0网络(通过evth-piar技术)。
docker0网络所具有的问题(docker的默认网络):不支持一容器名来通信,只能通过容器的IP地址来通信。(可以在启动是加--link 容器名)来解决这个问题,原理:就是在host文件中添加ip地址到容器名的映射。弊端:需要两个容器都要添加才能互相以容器名来通信,虽然可以解决但是过于笨重。这就是docker默认网络的问题。
解决docker网络的不足:(自定义网络)
我们可以通过自定义网络啦解决容器间不能以容器名来通问题。docker network ls :查看所有docker网络命令
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet :通过桥接模式创建一个网络名叫mynet,网段为92.168.0.0/16,网关为--gateway 192.168.0.1 。以后每加入一个容器在这个网络中,就给他分配一个该网络的IP地址。
将一个容器加入到该网络:docker run -d -P --name tomcat-net-02 --net mynet lengcz/tomcat:1.0 :(关键字:--net mynet)
我们自定义的网络就可以以容器名来进行通信了。
注意:两个自定义网络中的容器如何通信? 由于两个自定义的网络不是同一个网段,无法通信。解决:就是将mynet1中的容器加入到mynet2中,这是mynet2会给这个容器分配一个自己网络的IP地址,这是这个容器既有了mynet1中的IP地址又有了mynet2中的IP地址(双IP),所有就实现了容器间的跨网络通信。
命令:docker network connect mynet2网络 mynet1中的容器名 :将mynet1中的噶容器加入到mynet2的网络中。
--------------------------以上为docker的基础部分-----------------------------
--------------------------下面是docker的进阶部分-----------------------------
Docker compose和Docker Swarm
1、docker compose:
docker compose是一个用来管理容器的工具,可以一键启停容器:比如有一百个容器需要启动或者关闭,那么我们原始的方法是手动的运行100次docker run命令,但是我们使用docker compose工具就能启动着一百个容器。对容器的管理是非常的方便。
他是通过一个运行YAML文件来统一管理容器的。所以说YMAL文件时docker compose的一个核心。
下载docker compose:下载下来他是一个文件,把他放一个目录里面,然后给他赋权限(可读可写可执行),然后把他加到环境变量中。就可以使用docker compose命令了。使用docker compose -v 查看他的版本信息。
YMAL文件编写规则:可以将他的结构概括有三层,第一层是版本号(所有版本号都向下兼容),第二层是服务层(所有的服务和服务的配置都在这一层),第三层是其他配置(像一些网络、卷等配置)
如:
第一层:version:’版本号‘
第二层:services:
服务1:web
web服务的配置
服务1:redis
redis服务的配置
。。。。
第三层:volumes:
networks:
。。。。
说明:服务的配置里面,docker的所有的命令都可以在这里面运行
案例:使用docker compose部署一个开源的博客系统(workpress):
1)创建一个目录:mkdir workpress
2)进入该目录
3)编写YAML文件:vim workpress.yml(该文件一定是yml为后缀)
4)将docker官网的这个yml文件拷下来:
version: '3.7' services: db: image: mysql:8.0.19 command: '--default-authentication-plugin=mysql_native_password' restart: always volumes: - db_data:/var/lib/mysql environment: - MYSQL_ROOT_PASSWORD=somewordpress - MYSQL_DATABASE=wordpress - MYSQL_USER=wordpress - MYSQL_PASSWORD=wordpress wordpress: image: wordpress:latest ports: - 80:80 restart: always environment: - WORDPRESS_DB_HOST=db - WORDPRESS_DB_USER=wordpress - WORDPRESS_DB_PASSWORD=wordpress - WORDPRESS_DB_NAME=wordpress volumes: db_data:
5)通过docker compose up -d 运行yml文件就OK了
总结:这里我们部署了一个博客系统,里面有mysql和一个wordpress镜像,运行的时候它会自动的给我们拉取镜像爬起来,就不要我们自己去一个一个run。简单快捷。
2、Docker Swarm(docker集群)
docker swarm是一个docker集群。就是可以让多个docker在一个集群里面。docker swarm集群有两部分,一部分是管理结点(Manager)一部分是工作结点(Worker),管理结点又可以工作,但是工作结点不具有管理结点的功能,
Docker Swarm 和 Docker Compose 一样,都是 Docker 官方容器编排项目,但不同的是,Docker Compose 是一个在单个服务器或主机上创建多个容器的工具,而 Docker Swarm 则可以在多个服务器或主机上创建容器集群服务,对于微服务的部署,显然 Docker Swarm 会更加适合。
Swarm deamon只是一个调度器(Scheduler)加路由器(router),Swarm自己不运行容器,它只是接受Docker客户端发来的请求,调度适合的节点来运行容器,这就意味着,即使Swarm由于某些原因挂掉了,集群中的节点也会照常运行,放Swarm重新恢复运行之后,他会收集重建集群信息。
操作:
1)初始化一个swarm集群:docker swarm init --advertise-addr 该服务器的地址 :此时就开启了一个swarm集群,该集群中现在就只有一个docker结点(默认为manager)。
2)使用该结点生成worktoken或者managertoken:用来给别的docker加入该集群的钥匙:docker swarm jion-token worker或者manager :生成token。
3)将生成的token复制到其他的docker上运行就OK了,此时这个docker结点也加入到了这个集群了。
特别:swarm集群为了保证该可用性,所有要保证大多数的manager的存活。为了保证一致性和高可用性,swarm使用了Raft一致性算法。
重要:swarm的一个特性,可以动态的扩缩容,也就是说可以按照需求动态的运行服务器,需求大就在docker集群中多运行几个相应的服务器。
在单个服务器上开启服务使用命令:docker run 。。。。
1)在集群中开启服务(在manager结点上):docker service 。。。
如:docker service create -p 8888:80 --name mynginx nginx :表示在这个集群中开启了一个服务。
他是不一定运行在当前的manager结点上,可能在其他的docker结点上运行这个服务(随机的运行某个结点上)。
2)通过docker service ps myngingx :查看启动的服务的状态信息
通过docker service ls :可以查看服务的副本数量等信息
3)动态扩容,使用:docker service update --replicas 3 mynginx :就是将该集群中运行的mynginx服务由原来的1个变成现在的3个(也就是说现在这个集群中由三个一摸一样的mynginx服务在运行)。而且这些运行的服务都是一样的,无论访问哪一个都是一样,哪怕这个服务没有在某个结点上运行,用这个服务器的IP访问这个服务,一样可以访问到,只要这个结点在这个集群里面就行。
--------------------docker ----完结------------------------(>_<)