标签:目的 数据共享 mod dep 包括 block 姓名 独立 elastic
date: 2020-11-30 15:23:00
updated: 2020-12-07 15:35:00
$ docker --help
用法: docker COMMAND
A self-sufficient runtime for containers
选项:
--config string Location of client config files (default
"C:\\Users\\junchow\\.docker")
-D, --debug 开启debug模式
-H, --host list Daemon socket(s) to connect to
-l, --log-level string 设置日志级别,级别分为debug|info|warn|error|fatal,默认为info。
--tls Use TLS; implied by --tlsverify
--tlscacert string Trust certs signed only by this CA (default
"C:\\Users\\junchow\\.docker\\machine\\machines\\default\\ca.pem")
--tlscert string Path to TLS certificate file (default
"C:\\Users\\junchow\\.docker\\machine\\machines\\default\\cert.pem")
--tlskey string Path to TLS key file (default
"C:\\Users\\junchow\\.docker\\machine\\machines\\default\\key.pem")
--tlsverify Use TLS and verify the remote (default true)
-v, --version 终端打印显示版本信息并退出
管理命令:
config 管理Docker配置
container 管理容器
image 管理镜像
network 管理网络
node 管理Swarm节点
plugin 管理插件
secret 管理Docker安全
service 管理服务
swarm 管理Swarm集群
system 管理Docker系统
trust Manage trust on Docker images
volume 管理卷
命令:
attach 将标准输入和标准输出连接到正在运行的容器
build 使用dockerfile文件创建镜像
commit 从容器的修改项中创建新的镜像
cp 将容器的目录或文件复制到本地文件系统中
create 创建一个新的镜像
diff 检查容器文件系统的修改
events 实时输出docker服务器中发生的事件
exec 从外部运行容器内部的命令
export 将容器的文件系统到处为tat文件包
history 显示镜像的历史
images 输出镜像列表
import 从压缩为tar文件的文件系统中创建镜像
info 显示当前系统信息、docker容器与镜像个数、设置信息等
inspect 使用JSON格式显示容器与镜像的详细信息
kill 向容器发送kill信号关闭容器
load 从tar文件或标准输入中加载镜像
login 登录docker注册服务器
logout 退出docker注册服务器
logs 输出容器日志信息
pause 暂停容器中正在运行的所有进程
port 查看容器的端口是否处于开放状态
ps 输出容器列表
pull 从注册服务器中拉取一个镜像或仓库
push 将镜像推送到docker注册服务器
rename 重命名一个容器
restart 重启一个或多个容器
rm 删除一个或多个容器,若没有指定标签则删除lastest标签。
rmi 删除一个或多个镜像,若没有指定标签则删除lastest标签。
run 在一个新容器中中运行命令,用于指定镜像创建容器。
save 将一个或多个镜像保存为tar包
search 从Docker Hub中搜索镜像
start 启动一个或多个已经停止的容器
stats 查看各个容器占用内存、CPU的情况
stop 停止一个或多个正在运行的容器
tag 设置镜像标签
top 显示容器中正在运行的进程信息
unpause 重启pause命令暂停的容器
update 更新一个或多个容器的配置
version 显示docker版本信息
wait 等待容器终止然后输出退出码
Run ‘docker COMMAND --help‘ for more information on a command.
docker images # 查询本机上所有的镜像
# 可选项
-a 显示全部
-q 只显示镜像ID
docker search 镜像名
# 可选项
-f=stars=3000 # 搜索STARS大于3000的
docker pull 镜像名[:tag]
针对不同版本,如果有一样的镜像文件,就不需要重复下载了
docker imi -f 镜像id # 删除指定镜像
docker imi -f 镜像id 镜像id 镜像id # 删除多个镜像
docker imi -f $(docker images -q) # 把$里面当成参数传递进去,获取所有的镜像id,然后全部删除
docker run [可选参数] image
# 参数说明
--name="Name" 容器名字,用来区分容器
-d 后台方式运行
-i -t 使用交互方式运行,进入容器查看内容
-p 指定容器的端口 -p 8080:8000
-p 主机端口:容器端口 # 进行映射
-p 容器端口
-P 随机指定端口
docker ps # 列出所有正在运行的容器
# 可选项
-a # 列出所有容器
-n=? # 列出前n个容器
-q # 只显示容器ID
exit 退出容器并停止
ctrl+P+Q 大写模式下,退出容器且不停止
dcoker rm 容器ID
docker rm -f $(docker ps -q) 删除所有的容器ID
docker start 容器ID
docker restart 容器ID
docker stop 容器ID
docker kill 容器ID # 强制停止容器
通过 docker run -d 镜像名
来启动,然后通过 docker ps
会发现容器停止了
=> docker 容器使用后台运行,就必须要有一个前台进程,docker 发现没有应用,就会自动停止
eg:nginx 容器启动后发现没有提供服务就会自动停止
docker logs # 查看日志
# 可选项
-t # 时间戳
-f # 持续输出日志
--tail number # 显示最后的number条日志
docker top 容器ID # 查看容器中的进程信息,其中pid是进程id,ppid是父进程id
docker inspect 容器ID/镜像ID # 查看容器/镜像元数据,在下面有一个 layers 里面是镜像文件的每一层文件
很多容器都是后台运行,需要进入容器,修改一些配置
方式一:
docker exec -it 容器ID /bin/bash # 以命令行的方式来进行交互
# 进入容器后会开启一个新的终端,可以在终端里操作
方式二:
docker attach 容器ID # 会进入到正在执行的终端,不会启动新的进程
docker cp 容器ID:容器内的路径 主机路径 # 将容器中的文件拷贝到主机中
docker pull tomcat
docker run -d -p 主机端口:8080 --name tomcat01 tomcat
访问主机端口,发现404
docker exec -it tomcat01 /bin/bash
进入到webapps文件夹下面,发现是空的,原因是官方镜像删减了很多功能,只留下了能运行的最基本的功能
解决方法:可以把 webapps.dist 下面的内容复制到 webapps 文件夹下即可
但是这样的解决方法又太麻烦了,不能每次上线都进入容器部署 => 数据卷
docker stats # 查看各个容器占用内存、CPU的情况
∵ es非常耗内存 ∴ 可以修改配置文件,来增加内存的限制,-e 设置最小内存和最大内存
docker run -d --name elasticserch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms256m -Xms512m" elasticsearch:7.6.2
一个可视化管理方案,直接用docker来安装即可,做好主机端口映射
镜像是一种轻量级、可执行的独立软件包,包含某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。
UFS(UnionFS) 联合文件系统,是一种分层、轻量级并且高性能的文件系统,支持对文件系统的修改作为一次提交来一层层的叠加。类似于Git版本控制,每一次提交(操作)都记为一层。如果连个软件有共用的某一层文件,比如都基于linux,那么都可以去挂在这一层的linux的文件,就可以复用。
ufs里面包含比如
/dev, /proc, /bin, /etc
等标准目录和文件 => 比如linux的容器,占的内存很小,是因为镜像文件只需要包含rootfs里最基本的命令、工具即可,可以使用主机的kernel,这样的话可以提高效率所有的镜像都起始于一个基础镜像层,当进行修改或增加新的内容的时候,就会在当前镜像层之上,创建一个新的镜像层
镜像都是只读的,当容器启动时,一个新的可写层(容器层)就会加载到镜像层的顶部
通过 commit 来将容器层和镜像层进行合并打包,变成一个新的镜像文件
docker commit -m="提交的描述信息" -a="作者" 容器ID 目标镜像名[:tag]
=> 在容器外部提供一个映射路径,类似于数据共享技术,通过卷技术,也就是目录的挂载,将容器内的目录,挂在到linux上面,来实现容器数据的持久化和同步操作,容器之间也可以数据共享。
容器里面的目录就像是快捷方式,宿主机的文件才是真实的
实现方式:
docker run -it -v 主机目录:容器内目录 镜像名 /bin/bash
docker run --name mysql02 -e MYSQL_ROOT_PASSWORD=123456 -p 3310:3306 -v testconf2:/etc/mysql/conf.d -v /Users/mxxct/mysqldata:/var/lib/mysql -d mysql:5.7
通过 docker inspect 容器ID
查看元数据,在 Mounts
里可以看到挂载的详细信息
-v 容器内目录
-v 主机目录:容器内目录
-v xxx:容器内目录
这时候会默认映射到主机 /var/lib/docker/volumes/xxx/_data
这个文件夹下面(在MacOS下面没找到这个路径)docker volume ls # 查看所有的卷
docker volume inspect 卷名字 # 查看具体数据卷的信息,这里卷名字是指具名挂载的那个名字
可以在容器内目录后面添加权限控制
eg: -v 主机目录:容器内目录:ro/rw
ro readonly; rw readwrite 默认是rw,如果是ro就表示这个路径只能从主机上来操作,容器内只是读权限
这里是一个匿名挂载
FROM centos
VOLUME ["vol1", "vol2"]
CMD echo "---- end ----"
CMD /bin/bash
直接创建文件然后执行 docker build
可能会提示 error checking context:can‘t stat xxx
错误,这个提示基本是权限不够外加目录结构不对
解决:
mkdir dockerfile
chmod 777 dockerfile
touch file1
vi file1
docker build -f /Users/mxxct/dockerfile/file1 -t test/centos:1.0 .
(base) localhost:dockerfile mxxct$ docker build -f /Users/mxxct/dockerfile/file1 -t test/centos:1.0 .
Sending build context to Docker daemon 2.048kB
Step 1/4 : FROM centos
latest: Pulling from library/centos
3c72a8ed6814: Pull complete
Digest: sha256:76d24f3ba3317fa945743bb3746fbaf3a0b752f10b10376960de01da70685fbd
Status: Downloaded newer image for centos:latest
---> 0d120b6ccaa8
Step 2/4 : VOLUME ["vol1", "vol2"]
---> Running in 7cc3997837d7
Removing intermediate container 7cc3997837d7
---> b55d348b6981
Step 3/4 : CMD echo "---- end ----"
---> Running in 083ad85879af
Removing intermediate container 083ad85879af
---> 11c45d147425
Step 4/4 : CMD /bin/bash
---> Running in e7d39262c201
Removing intermediate container e7d39262c201
---> ee8398f6597c
Successfully built ee8398f6597c
Successfully tagged test/centos:1.0
创建好镜像后,执行
docker run -it ee8398f6597c /bin/bash
[root@2adb0cbdc19f /]# ls -l
total 56
lrwxrwxrwx 1 root root 7 May 11 2019 bin -> usr/bin
drwxr-xr-x 5 root root 360 Dec 1 06:23 dev
drwxr-xr-x 1 root root 4096 Dec 1 06:23 etc
drwxr-xr-x 2 root root 4096 May 11 2019 home
lrwxrwxrwx 1 root root 7 May 11 2019 lib -> usr/lib
lrwxrwxrwx 1 root root 9 May 11 2019 lib64 -> usr/lib64
drwx------ 2 root root 4096 Aug 9 21:40 lost+found
drwxr-xr-x 2 root root 4096 May 11 2019 media
drwxr-xr-x 2 root root 4096 May 11 2019 mnt
drwxr-xr-x 2 root root 4096 May 11 2019 opt
dr-xr-xr-x 159 root root 0 Dec 1 06:23 proc
dr-xr-x--- 2 root root 4096 Aug 9 21:40 root
drwxr-xr-x 11 root root 4096 Aug 9 21:40 run
lrwxrwxrwx 1 root root 8 May 11 2019 sbin -> usr/sbin
drwxr-xr-x 2 root root 4096 May 11 2019 srv
dr-xr-xr-x 12 root root 0 Dec 1 06:23 sys
drwxrwxrwt 7 root root 4096 Aug 9 21:40 tmp
drwxr-xr-x 12 root root 4096 Aug 9 21:40 usr
drwxr-xr-x 20 root root 4096 Aug 9 21:40 var
drwxr-xr-x 2 root root 4096 Dec 1 06:23 vol1
drwxr-xr-x 2 root root 4096 Dec 1 06:23 vol2
这里有 vol1 和 vol2 两个目录,然后去查看容器的元数据信息,会发现在 Mounts 这里已经把两个卷给挂在出去了
"Mounts": [
{
"Type": "volume",
"Name": "baeff06c4bf78f14c8135dbdc5ae238bb513cf8375af699b47c602d3e3a0a529",
"Source": "/var/lib/docker/volumes/baeff06c4bf78f14c8135dbdc5ae238bb513cf8375af699b47c602d3e3a0a529/_data",
"Destination": "vol1",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
},
{
"Type": "volume",
"Name": "4cbbd6edd2093b5098b6d9994bc380c992445842c1b19a942816b090a8841e13",
"Source": "/var/lib/docker/volumes/4cbbd6edd2093b5098b6d9994bc380c992445842c1b19a942816b090a8841e13/_data",
"Destination": "vol2",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
容器数据卷是容器实现数据持久化的一种机制,数据卷容器是一种特殊的容器
这个主要是通过类似,用于容器间的数据同步,不是容器和主机之间。
docker run -it --name docker01 imageID
docker run -it --name docker02 --volumes-from docker01 imageID
docker01中有挂载的文件夹
通过 --volumes-from 让docker02继承docker01的挂载文件夹,此时docker01挂载出去的文件夹里的数据的任何修改在docker02也可以看到,同时在docker02上做的修改docker01也可以看到。docker01就是数据卷容器。
删除docker01的话,挂载的文件夹数据依然存在,本质是因为他们都挂载到主机的目录下,只要主机对应目录存在,数据就不会丢失
docker01相当于映射主机数据目录的地址(想成一个快捷方式),docker02拿到这个映射地址(快捷方式),放到自己的mount里面
通过 docker history imageID 可以查看一个镜像的构建过程
基础知识
#
是注释指令说明
FROM # 指定基础镜像
MAINtAINER # 指定维护者信息,姓名+邮箱
RUN # 镜像构建的时候需要运行的命令
ADD # 添加内容,会自动解压,比如tomcat压缩包
WORKDIR # 镜像的工作目录
VOLUME # 设置卷,挂载主机目录
EXPOSE # 指定暴露的端口,或者通过 -p 指定
CMD # 指定容器启动时要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT # 指定容器启动时要运行的命令,可以追加命令
ONBUILD # 当构建一个被继承 DockerFile 这个时候会运行ONBUILD的指令,触发指令
COPY # 类似ADD,将文件拷贝到镜像中
ENV # 构建的时候设置环境变量
CMD ["ls", "-a"]
这时候的命令相当于 "ls -a"。只有当执行 docker run imageID
的时候才会执行最后一个CMD的命令。(docker run -it imageID
这时候是通过命令行交互,所以不会执行CMD)
如果执行 docker run imageID -l
想执行 ls -al
命令会报错,即CMD命令会被替代,不会追加。
换成 ENTRYPOINT
再执行 docker run imageID -l
就可以执行 ls -al
COPY 主机路径/readme.txt 容器内路径
ADD 主机路径/xxxx.tar 容器内路径 # ADD添加的文件会自动解压
RUN yum -y install vim
ENV MYPATH /user/local
WORKDIR $MYPATH
ENV JAVA_HOME /user/local/jdk1.8.0_11
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /user/local/apache-tomcat-9.0.22
ENV CATALINA_BASH /user/local/apache-tomcat-9.0.22
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
EXPOSE 8080
CMD /user/local/apache-tomcat-9.0.22/bin/startup.sh && tail -f /user/local/apache-tomcat-9.0.22/bin/logs/catalinas.out
每次启动一个程序,Linux 就会相应创建一个新的网卡地址 => veth-pair 一对虚拟设备接口,一端连着协议,一端彼此相连 => 每启动一个容器,docker会创建一对网卡连接地址,一端在主机,一端在容器
Linux 虚拟网络设别 veth-pair。三个经典实验,直接相连、通过 Bridge 相连和通过 OVS 相连
两个docker容器进行通信,需要先走到docker0,也就是类似于docker的路由器,通过广播或注册的方式,路由器会知道下一个容器的网络地址,然后转发请求连接。Docker0就相当于一个网桥的角色。
docker run --link 通过link可以将两个容器网络连接起来,但是这是单向的,A link B, 只是A可以连接B,想B连接A的话还需要再配置B
link 操作相当于在容器内的 hosts 文件中写进去映射关系
不推荐 --link
。因为 link 用的是 docker0,而docker0不支持容器名称映射,只能写死ip,如果牵扯到ip迁移,就需要重新配置一遍
docker network ls # 查看所有的docker网络
网络模式
docker run --net bridge # 不写的话也默认有这个bridge
自定义创建网络
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
创建的容器基于各自不同的网络,可以保证同一类容器使用的是自己的网络ip。但是如果是两类容器想互相连接呢?网络打通。
docker network connect [option] container network # 将一个容器连接到一个网关上,相当于一个容器两个ip地址。
目的:定义运行多个容器,避免一个个的运维容器
步骤:
docker-compose up
配置项里有一个 deploy.replicas 可以设置副本,集群部署的时候使用这个参数
单机
相当于是搭建一个小集群,有manager有worker。
集群
docker swarm init # 初始化节点
docker swarm join-token manager # 加入一个节点,并将该节点作为manager
docker swarm join-token worker # 加入一个节点,并将该节点作为worker
拜占庭将军问题:很久很久以前,拜占庭是东罗马帝国的首都。那个时候罗马帝国国土辽阔,为了防御目的,因此每个军队都分隔很远,将军与将军之间只能靠信使传递消息。在打仗的时候,拜占庭军队内所有将军必需达成一致的共识,才能更好地赢得胜利。但是,在军队内有可能存有叛徒,扰乱将军们的决定。这时候,在已知有成员不可靠的情况下,其余忠诚的将军需要在不受叛徒或间谍的影响下达成一致的协议。莱斯利·兰伯特( Leslie Lamport )通过这个比喻,表达了计算机网络中所存在的一致性问题。这个问题被称为拜占庭将军问题。
二将军问题:白军驻扎在沟渠里,蓝军则分散在沟渠两边。白军比任何一支蓝军都更为强大,但是蓝军若能同时合力进攻则能够打败白军。他们不能够远程的沟通,只能派遣通信兵穿过沟渠去通知对方蓝军协商进攻时间。是否存在一个能使蓝军必胜的通信协议,这就是两将军问题。
二将军问题探讨的是不可靠信道下两方的通信准确性问题,而拜占庭将军问题探讨的是多方通信结果一致性和决策正确性的问题。
准确性是指发送的是什么,接收的就是什么;一致性是在节点更多的情况下的准确性;正确性是无论收到的通信结果是否有干扰(不完全满足一致性),正常工作的节点能够做出正确的决策。
=> 二将军问题可以通过TCP3次握手来解决;拜占庭将军问题可以通过Raft/Paxos(谷哥Chubby)/ZAB(zookeeper)/PBFT(区块链)几种算法解决。另外 PS:raft,zab,paxos解决的是节点故障问题,而非拜占庭问题(节点故意欺骗)。PBFT解决了拜占庭问题。
Raft 协议的具体流程:
这里需要说明一点,每个节点的超时时间都是不一样的。比如A节点的超时时间是3秒,B节点的超时时间是5秒,C节点的超时时间是4秒。这样一来,A节点将会最先发起投票请求,而不是所有节点同时发起。为什么这样设计呢?设想如果所有节点同时发起投票,必然会导致大家的票数差不多,形成僵局,谁也当不成老大。
那么,成为Leader的节点是否就坐稳了老大的位置呢?并不是。Leader节点需要每隔一段时间向集群其他节点发送心跳通知,表明你们的老大还活着。一旦Leader节点挂掉,发不出通知,那么计时达到了超时时间的Follower节点会转变为Candidate节点,发起选主投票,周而复始......
数据同步的流程:
docker service create -p ip:端口 --name my-service xxx
# 和 docker run 的区别是,run是容器启动,不具备扩缩容的概念;service是服务启动,可以自动扩缩容
docker service ps my-service # 查看服务进程
docker service ls # 查看服务列表,这里有一个 replicas,表示当前服务的副本
docker servie update --replicas N my-service # 将 my-service 自动扩容到 N 个副本
docker service scale my-service=N # 将 my-service 自动扩容到 N 个副本
有一个 --mode 参数,默认是 replicated,可以改成 global
replicated 只能在worker节点中运行,global的话manager节点也可以运行
灰度发布:金丝雀发布
命令 -> manager节点调用api -> schedule api -> worker节点创建并维护容器服务
镜像使用的os版本不统一,比如Linux基于的os不一样,版本不一样,命令缺失,阉割版和增肥版都不统一,数据文件可能都修改了位置等等
标签:目的 数据共享 mod dep 包括 block 姓名 独立 elastic
原文地址:https://www.cnblogs.com/mxxct/p/14158325.html