docker学习

Docker

Docker概述

为什么出现Docker?

解决项目带上环境部署的问题,同时解决某些环境不能跨平台问题。

核心思想

隔离机制(沙箱)

核心组件

镜像:Image,Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。 相当与应该包含最核心的小的系统。

容器:Container,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的 命名空间。

仓库:Repository,每个仓库可以包含多个标签 (Tag );每个标签对应一个镜像。

什么是镜像?

一种轻量级、可执行的独立软件包,用来打包运行环境及基于运行环境开发的软件,它包含某个软件运行所需要的所有内容,包括代码、运行时、库、环境变量及配置文件。

镜像的唯一标识是其 ID 和摘要,而一个镜像可以有多个标签。

Docker镜像加载原理

UnionFS(联合文件系统)

是一种分层、轻量级并且高性能的文件系统,它支持文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。

Docker镜像加载原理

分层加载

数据持久化

容器中的管理数据主要有两种方式:

在加一个:挂在到本机

数据卷 Data Volumes 容器内数据直接映射到本地主机环境;
数据卷容器(Data Volume Containers) 使用特定容器维护数据卷;

还有最原始的copy方式:最原始的copy方式管理数据:

#宿主机文件 copy to 容器内
docker cp 需要拷贝的文件或者目录 容器名称:容器目录
#实例:
docker cp /zking/monitorlogs/ db3:/javaxl/software

卷 (Docker Volume) 是受控存储,是由 Docker 引擎进行管理维护的。因此使用卷,你可以不必处理 uid、SELinux 等各种权限问题,Docker 引擎在建立卷时会自动添加安全规则,以及根据挂载点调整权限。并且可以统一列表、添加、删除。另外,除了本地卷外,还支持网络卷、分布式卷。

而挂载目录而挂载目录那就没人管了,属于用户自行维护。你就必须手动处理所有权限问题。特别是在 CentOS 上,很多人碰到 Permission Denied,就是因为没有使用卷,而是挂载目录,而且还对 SELinux 安全权限一无所知导致。

这个设置可以在运行时覆盖。通过 docker run 的 -v 参数或者 docker-compose.yml 的 volumes 指定。使用命名卷的好处是可以复用,其它容器可以通过这个命名数据卷的名字来指定挂载,共享其内容(不过要注意并发访问的竞争问题)。

比如,Dockerfile 中说 VOLUME /data,那么如果直接 docker run,其 /data 就会被挂载为匿名卷,向 /data 写入的操作不会写入到容器存储层,而是写入到了匿名卷中。但是如果运行时 docker run -v mydata:/data,这就覆盖了 /data 的挂载设置,要求将 /data 挂载到名为 mydata 的命名卷中。所以说 Dockerfile 中的 VOLUME 实际上是一层保险,确保镜像运行可以更好的遵循最佳实践,不向容器存储层内进行写入操作。

容器数据卷

数据卷(Data Volumes)
数据卷是一个可供一个或多个容器使用的特殊目录,它将主机操作系统目录直接映射进容器,
它可以提供很多有用的特性:
1.数据卷 可以在容器之间共享和重用
2.对数据卷的修改会立马生效
3.对数据卷的更新,不会影响镜像
4.数据卷 默认会一直存在,即使容器被删除

Docker中数据存储在容器(小系统)中,若容器删除,则数据丢失,需要数据可持久化。

容器与容器之间需要有一个数据共享技术,即将Docker中产生的数据同步到本地。

其本质为目录挂载,将容器内的目录挂载到本机上。

创建数据卷

docker volume create my-vol
 #此时,数据卷默认会放到/var/lib/docker/volumes路径下,会发现所新建的数据卷位置,查看命令如下:
 ## 参数可以为数字“1”,字母L:大小写均可,但效果不一样 
 
 ls -1 /var/lib/docker/volumes

使用数据卷

在启动镜像时挂载

分为具名挂载、匿名挂载和指定路径挂载

# 具名挂载
-v [卷名:容器内目录]
# 匿名挂载
-v [容器内目录]
# 指定路径挂载
-v [宿主机目录:容器内目录]
# 方式一:直接使用命令挂载。示例:
#docker run -it -v [宿主机目录:容器内目录] [容器名] /bin/bash

docker run -d 
				  -p 3306:3306 
				  --name matt_mysql 
				  -v /home/mysql/conf:/etc/mysql/conf 
				  -v /home/mysql/data:/var/lib/mysql 
				  -e MYSQL_ROOT_PASSWORD=dEn@45NMx76 mysql:5.7
				  


# 方式二:使用dockerfile文件挂载

# 1.写dockerfile文件

FROM centos
VOLUME["volume_01","volume_02"]
CMD echo "--------------end-------------"
CMD /bin/bash

# 2.docker build命令生成镜像
-f		# dockerfile文件
-t		# target生成
docker build -f /home/docker-test-volume/dockerfile 
			 -t matt_centos:1.0 .

# 方式三:通过数据卷容器挂载
# 通过--volumes-from实现
docker run -it f77539c3b452 
			--name docker02 
			--volumes-from docker01 matt_centos:1.0

# 查看所有卷相关信息

create	# 创建卷
ls		# 查看卷
inspect	# 查看具体卷的路径
docker volume

删除数据卷

有名字的
docker volume rm my-vol

先查看所有的容器,没有名字,只能带着容器一起删了
# docker ps -a

docker rm -v e3274a72e8d6

查看对应容器的数据卷

docker inspect container_name(容器名) | grep Mounts -A 20

docker volume ls

数据卷容器

即两个容器间通过数据卷进行数据同步

Docker安装

安装步骤

free -m 查看虚拟机的剩余内存

#1.卸载旧版本
yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine
#2.安装工具包
yum install -y yum-utils
#3.设置镜像仓库  阿里云镜像地址  http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum-config-manager \
    --add-repo \
    http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
#4.更新yum软件包索引
yum makecache fast
# 安装
yum install -y docker-ce docker-ce-cli containerd.io
#5.启动(并设置为开机自启动)
systemctl start docker

systemctl enable docker
#6.测试启动
docker version

刚装完的docker没有直接进行第8部
#7.run hello-world
docker run hello-world

#8.查看下载的镜像
docker images

# Docker卸载
yum remove docker-ce docker-ce-cli containerd.io
rm -rf /var/lib/docker
rm -rf /var/lib/containerd

# 9.配置镜像加速器
sudo mkdir -p /etc/docker

sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://xvx84460.mirror.aliyuncs.com"]
}
EOF
#10.重启docker后台线程
sudo systemctl daemon-reload
#11.重启docker的服务
sudo systemctl restart docker

Docker命令

基础命令

docker version		 # Docker版本信息
docker info			 # Docker系统信息,包括镜像和容器数量
docker stats 		 # 查看内存状态
docker 命令 --help 	# 万能命令

镜像命令

docker images		 # 查询本机所有镜像(-a 列出所有镜像;-q 只显示镜像ID)
docker search 		 # 搜索 例:docker search mysql
docker pull 		 # 下载镜像 例:docker pull mysql:5.7
docker rmi -f 		 # 镜像删除
docker push [作者名/镜像名:tag] 		 # 发布镜像 先使用docker login登陆

容器命令

# 启动命令:docker run 只在第一次运行时使用,将镜像放到容器中,以后再次启动这个容器时,只需要使用命令docker start即可。docker run相当于执行了两步操作:将镜像放入容器中(docker create),然后将容器启动,使之变成运行时容器(docker start)。而docker start的作用是,重新启动已存在的镜像。也就是说,如果使用这个命令,我们必须事先知道这个容器的ID,或者这个容器的名字,我们可以使用docker ps找到这个容器的信息。
简单来说,run是启动镜像,start是启动容器

# 参数说明 
docker run [可选参数] image
--name="name" # 容器名称
-d 			 # 后台运行
-it 		 # 终端交互方式运行,指可以进入容器查看内容

-p 81:80	 # 大P,指定端口
				# -P ip:主机端口:容器端口
				# -P 主机端口:容器端口
				# -P 容器端口
				# 容器端口
-p			 # 随机指定端口
-e MYSQL_ROOT_PASSWORD=my-secret-pw   # 修改配置文件(以MySql为例)

# 查看运行中的容器
docker ps # 查看容器
docker ps -a #查看所有经运行的容器+历史运行的容器
docker image ls --digests	#查看镜像摘要
# 进入容器
docker container exec -it f0b1c8ab3633 #f0b1c8ab3633容器的id

#导入导出内容
docker export container > file

cat ubuntu.tar | docker import - test/ubuntu:v1.0

# 退出容器
exit		  # 停止并退出容器
Ctrl + p + q   # 退出容器

# 删除容器,不能删除运行中容器,可以使用 rm -f 强制删除。可选参数可以为 镜像短 ID 、 镜像长 ID 、 镜像名,镜像摘要。一般取前3个字符以上,只要足够区分于别的镜像就可以了。
docker rm [可选参数] # docker rm -f [$(docker -aq)] 传参删除

# 运行\停止容器
docker start xx	#id和名字都可以
docker restart xx
docker kill
docker stop

常用命令

# 后台启动
# 常见问题:Docker使用后台运行时,必须要有至少一个前台进程,若没有,Docker认为没有发现应用,会自动自杀
docker run -d image
# 日志查看
-t 显示时间戳
-f format
--tail num 显示条数
docker logs -tf --tail num [容器ID]

# 查看容器中进程信息
docker top [容器ID]
# 查看镜像元数据
docker inspect [容器ID]

# 进入正在运行的容器,开启新的终端,可以进行操作
docker exec -it [容器ID] /bin/bash
# 进入正在运行的容器,进入容器正在执行的终端
docker attach [容器ID]

# 新建文件
touch [文件名.文件类型]
# 从容器其中拷贝到主机上
docker cp [容器ID]:[/容器上文件位置] [/主机上文件位置]

不常用命令

#检查容器文件系统上文件或目录的更改情况,主要是在自定义镜像之后使用

docker diff CONTAINER

练习

对于中间件不懂的命令可以参考,docker hub 的官方文档

Docker安装Mysql

格式是有问题的,若出错,先看看格式
docker run -p 3306:3306 --name mysql -v /mydata/mysql/log:/var/log/mysql -v /mydata/mysql/data:/var/lib/mysql -v /mydata/mysql/conf:/etc/mysql -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7

启动成功标志b242689f2c16a50dde9007d9e5b195bf76c1b27ef8393ddf8dfdce53b9c4c1e2


//创建容器时,最后mysql:5.7表示mysql镜像的版本
-v挂载文件(方便修改配置
-e设置属性
-d后台运行
\换行

修改配置
vi mydata/mysql/conf/my.cnf

重启mysql
docker restart mysql

使用交互模式,进入mysql的工作台
docker exec -it mysql /bin/bash

cat 查看

退出
exit


Docker启动Redis

docker会将所有的名字看成目录
先创建文件之后在挂载
mkdir -p /mydata/redis/conf/
touch redis.conf
一步到胃
touch /mydata/redis/conf/redis.conf

挂载
docker run -p 6379:6379 --name redis -v /mydata/redis/data:/data -v /mydata/redis/conf/redis.conf:/etc/redis/redis.conf -d redis redis-server /etc/redis/redis.conf
成功
36fac819c4b5dc88c138517a5292c927a67c7603469bb3075bf16d0c7606ac85

并没有配置配置文件,使用时需要配置配置文件

测试客户端(这就是客户端)
docker exec -it redis redis-cli

docker安装es和kibanna

es
docker pull elasticsearch:7.4.2
可视化软件
docker pull kibana:7.4.2
    
在虚拟机中创建挂载文件夹
    mkdir -p /mydata/elasticsearch/config
    mkdir -p /mydata/elasticsearch/data
在配置文件中写入(host:要有空格
    echo "http.host: 0.0.0.0"  /mydata/elasticsearch/config/elasticsearch.yml
启动,挂载,9200发送请求,9300集群交互,-e 单节点 -e初始64m最大128m
    docker run --name elasticsearch -p 9200:9200 -p 9300:9300 \
        -e "discovery.type=single-node" \
        -e ES_JAVA_OPTS="-Xms64m -Xmx128m" \
        -v /mydata/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
        -v /mydata/elasticsearch/data:/usr/share/elasticsearch/data \
        -v /mydata/elasticsearch/plugins:/usr/share/elasticsearch/plugins \
        -d elasticsearch:7.4.2
  成功  cd7cc0ae814733280a341195a6ddd9defdcca3e035f7d3374f6c7ea3661aaa54

    docker logs 应用名
    查看日志
            
    修改权限
            chmod -R 777 /mydata/elasticsearch
            
            安装kibanna
    docker run --name kibana -e ELASTICSEARCH_HOSTS=http://192.168.102.129:9200 -p 5601:5601 \
-d kibana:7.4.2
    成功e54b11dbcb948820868036531b8a04fab311e80e1d14c2ca043cf704f3fce95b
    
    打开虚拟机地址加中间件端口号,查看可视化界面

Docker安装Nginx

# 搜索Nginx
docker search nginx
# 下载镜像
docker pull nginx
# 运行
-d 				# 后台运行
--name 			# 自定义容器名称
-p 				# 宿主机端口:容器内端口
docker run -d --name matt_nginx -p 9001:80 nginx
# 测试访问
curl localhost:9001
# 进入容器
docker exec -it matt_nginx /bin/bash


设置自动启动

docker update redis --restart=always

设置redis自动启动

可视化工具

Portainer

Docker图形管理工具,提供一个供操作的后台面板

(61条消息) Portainer 安装与配置_acherson的专栏-CSDN博客_portainer安装

Rancher

Rancher是一个开源的企业级容器管理平台。通过Rancher,企业再也不必自己使用一系列的开源软件去从头搭建容器服务平台。Rancher提供了在生产环境中使用的管理Docker和Kubernetes的全栈化容器部署与管理平台。

(61条消息) Rancher简介与安装_菲宇运维-CSDN博客_rancher安装

docker commit 创建自己的镜像

docker commit

但是,不要使用 docker commit 定制镜像,定制镜像应该使用 Dockerfile 来完成。

镜像是多层存储,每一层是在前一层的基础上进行的修改; 而容器同样也是多层存储,是在以镜像为基础层,在其基础上加一层作为容器运行时的存储 层。

# commit命令
# docker commit -m="提交的描述信息" 
#				-a="作者" 
#				[容器ID] [目标镜像名:tag]
docker commit -m ="add txt to webapps" -a="Matt" 3619e1af9613 matt_tomcat_commit_test:1.0



# 创建自己的镜像
$ docker run --name webserver -d -p 80:80 nginx 
#这条命令会用 nginx 镜像启动一个容器,命名为 webserver ,并且映射了 80 端口,这样我们可以用浏览器去访问这个 nginx 服务器。

现在,假设我们非常不喜欢这个欢迎页面,我们希望改成欢迎 Docker 的文字,我们可以使用 docker exec 命令进入容器,修改其内容。

$ docker exec -it webserver bash

root@3729b97e8226:/# echo '

root@3729b97e8226:/# exit exit

现在我们再刷新浏览器的话,会发现内容被改变了。我们修改了容器的文件,也就是改动了容器的存储层。我们可以通过 docker diff 命令看到具体的改动。

$ docker diff webserver	#查看容器的具体改动

现在我们定制好了变化,我们希望能将其保存下来形成镜像。 当我们运行一个容器的时候(如果不使用卷的

话),我们做的任何文件修改都会被 记录于容器存储层里。而 Docker 提供了一个 docker commit 命令,可以将

容器的存储层保 存下来成为镜像。换句话说,就是在原有镜像的基础上,再叠加上容器的存储层,并构成新的镜

像。以后我们运行这个新镜像的时候,就会拥有原有容器最后的文件变化。

$ docker commit \ --author "Tao Wang  \ --message "修改了默认网页" \ webserver \ nginx:v2 sha256:07e33465974800ce65751acc279adc6ed2dc5ed4e0838f8b86f0c87aa1795214

$ docker image ls nginx	#查看镜像的详细版本

docker history 	#查看镜像的历史记录

#运行新镜像

问题

使用 docker commit 命令虽然可以比较直观的帮助理解镜像分层存储的概念,但是实际环境 中并不会这样使用。

首先,如果仔细观察之前的 docker diff webserver 的结果,你会发现除了真正想要修改的 /usr/share/nginx/html/index.html 文件外,由于命令的执行,还有很多文件被改动或添加 了。这还仅仅是最简单的操作,如果是安装软件包、编译构建,那会有大量的无关内容被添 加进来,如果不小心清理,将会导致镜像极为臃肿。

此外,使用 docker commit 意味着所有对镜像的操作都是黑箱操作,生成的镜像也被称为黑 箱镜像,换句话说,就是除了制作镜像的人知道执行过什么命令、怎么生成的镜像,别人根 本无从得知。

而且,即使是这个制作镜像的人,过一段时间后也无法记清具体在操作的。虽 然 docker diff 或许可以告诉得到一些线索,但是远远不到可以确保生成一致镜像的地步。 这种黑箱镜像的维护工作是非常痛苦的。

而且,回顾之前提及的镜像所使用的分层存储的概念,除当前层外,之前的每一层都是不会 发生改变的,换句话说,任何修改的结果仅仅是在当前层进行标记、添加、修改,而不会改 动上一层。

如果使用 docker commit 制作镜像,以及后期修改的话,每一次修改都会让镜像 更加臃肿一次,所删除的上一层的东西并不会丢失,会一直如影随形的跟着这个镜像,即使 根本无法访问到。这会让镜像更加臃肿。

DockerFile

镜像的定制实际上就是定制每一层所添加的配置、文件。如果我们可以把每一层修改、安装、构建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像,那么之前提及的无法重复的问题、镜像构建透明性的问题、体积的问题就都会解决。这个脚本就是 Dockerfile。

用来构建Docker镜像

构建步骤:

1.编写DocjerFile文件;

$ mkdir mynginx 
$ cd mynginx 
$ touch Dockerfile

#内容
FROM nginx 
RUN echo '

/usr/share/nginx/html/index.html

解释

FROM ——》指定基础镜像 所谓定制镜像,那一定是以一个镜像为基础,在其上进行定制。就像我们之前运行了一个 nginx 镜像的容器,再进行修改一样,基础镜像是必须指定的。而 FROM 就是指定基础镜 像,因此一个 Dockerfile 中 FROM 是必备的指令,并且必须是第一条指令。 在 Docker Store 上有非常多的高质量的官方镜像,有可以直接拿来使用的服务类的镜像,如 nginx 、 redis 、 mongo 、 mysql 、 httpd 、 php 、 tomcat 等;也有一些方便开发、构 建、运行各种语言应用的镜像,如 node 、 openjdk 、 python 、 ruby 、 golang 等。可以 在其中寻找一个最符合我们最终目标的镜像为基础镜像进行定制。 如果没有找到对应服务的镜像,官方镜像中还提供了一些更为基础的操作系统镜像,如 ubuntu 、 debian 、 centos 、 fedora 、 alpine 等,这些操作系统的软件库为我们提供了 更广阔的扩展空间。 除了选择现有镜像为基础镜像外,Docker 还存在一个特殊的镜像,名为 scratch 。这个镜像 是虚拟的概念,并不实际存在,它表示一个空白的镜像。 使用 Dockerfile 定制镜像 FROM scratch … 如果你以 scratch 为基础镜像的话,意味着你不以任何镜像为基础,接下来所写的指令将作 为镜像第一层开始存在。

FROM scratch

1.1RUN 执行命令

shell 格式: RUN <命令 ,命令行中输入的命令一样。刚才写的 Dockerfile 中 的 RUN 指令就是这种格式。

exec 格式: RUN [“可执行文件”, “参数1”, “参数2”] ,这更像是函数调用中的格式。

RUN echo '

/usr/share/nginx/html/index.html

Dockerfile 中每一个指令都会建立一层, RUN 也不例外。每一个 RUN 的行为, 就和刚才我们手工建立镜像的过程一样:新建立一层,在其上执行这些命令,执行结束后, commit 这一层的修改,构成新的镜像。

下面是文件的内容

FROM debian:jessie 

RUN apt-get update 
RUN apt-get install -y gcc libc6-dev make 
RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-3.2.5.tar.gz" 
RUN mkdir -p /usr/src/redis 
RUN tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1 RUN make -C /usr/src/redis 
RUN make -C /usr/src/redis install



#方式二
FROM debian:jessie 
RUN buildDeps='gcc libc6-dev make' \ 
&& apt-get update \ 
&& apt-get install -y $buildDeps \ 
&& wget -O redis.tar.gz "http://download.redis.io/releases/redis-3.2.5.tar.gz" \ 
&& mkdir -p /usr/src/redis \ 
&& tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1 \ 
&& make -C /usr/src/redis \ 
&& make -C /usr/src/redis install \ 
&& rm -rf /var/lib/apt/lists/* \ 
&& rm redis.tar.gz \ 
&& rm -r /usr/src/redis \ 
&& apt-get purge -y --auto-remove $buildDeps

第一种写法创建了 7 层镜像,构造redis。这是完全没有意义的,而且很多运行时不需要的东 西,都被装进了镜像里,比如编译环境、更新的软件包等等。结果就是产生非常臃肿、非常 多层的镜像,不仅仅增加了构建部署的时间,也很容易出错。 这是很多初学 Docker 的人常 犯的一个错误。 Union FS 是有最大层数限制的,比如 AUFS,曾经是最大不得超过 42 层,现在是不得超过 127 层。

首先,之前所有的命令只有一个目的,就是编译、安装 redis 可执行文件。因此没有必要建立 很多层,这只是一层的事情。因此,这里没有使用很多个 RUN 对一一对应不同的命令,而是 仅仅使用一个 RUN 指令,并使用 && 将各个所需命令串联起来。将之前的 7 层,简化为了 1 层。在撰写 Dockerfile 的时候,要经常提醒自己,这并不是在写 Shell 脚本,而是在定义每 一层该如何构建。

2.docker build构建成为一个镜像;

在dockerfile文件的所在的目录执行

$ docker build -t nginx:v3 . 

#bash结果
Sending build context to Docker daemon 2.048 kB 
Step 1 : FROM nginx ---> e43d811ce2f4 
Step 2 : RUN echo '

Hello, Docker!

'
> /usr/share/nginx/html/index.html ---> Running in 9cdc27646c7b ---> 44aa4490ce2c Removing intermediate container 9cdc27646c7b Successfully built 44aa4490ce2c

从命令的输出结果中,我们可以清晰的看到镜像的构建过程。在 Step 2 中,如同我们之前 所说的那样, RUN 指令启动了一个容器 9cdc27646c7b ,执行了所要求的命令,并最后提交 了这一层 44aa4490ce2c ,随后删除了所用到的这个容器 9cdc27646c7b 。

docker build的原理

​ Docker 在运行时分为 Docker 引擎(也就是服 务端守护进程)和客户端工具。Docker 的引擎提供了一组 REST API,被称为 Docker Remote API,而如 docker 命令这样的客户端工具,则是通过这组 API 与 Docker 引擎交 互,从而完成各种功能。

因此,虽然表面上我们好像是在本机执行各种 docker 功能,但实 际上,一切都是使用的远程调用形式在服务端(Docker 引擎)完成。也因为这种 C/S 设计, 让我们操作远程服务器的 Docker 引擎变得轻而易举。 当我们进行镜像构建的时候,并非所有定制都会通过 RUN 指令完成,经常会需要将一些本地 文件复制进镜像,比如通过 COPY 指令、 ADD 指令等。而 docker build 命令构建镜像,其 实并非在本地构建,而是在服务端,也就是 Docker 引擎中构建的。

那么在这种客户端/服务 端的架构中,如何才能让服务端获得本地文件呢? 这就引入了上下文的概念。当构建的时候,用户会指定构建镜像上下文的路径, docker build 命令得知这个路径后,会将路径下的所有内容打包,然后上传给 Docker 引擎。这样 Docker 引擎收到这个上下文包后,展开就会获得构建镜像所需的一切文件。

一般习惯性的会使用默认的文件名 Dockerfile ,以及会将其置于镜像构建上下文目录中。

3.docker run运行镜像;

4.docker push发布镜像(DockerHub/阿里云镜像仓库)

常用指令

# 指定基础镜像
FROM
# 维护者信息
MAINTAINER
# 镜像构建时需要运行的命令
RUN
# 步骤 --  添加内容
ADD
# 设置当前工作目录
WORKDIR
# 挂载的目录
VOLUME
# 暴露端口
EXPOSE
# 指定容器启动时要运行的命令,只有最后一个生效,可被替代
CMD
# 指定容器启动时要运行的命令,可以追加
ENTRYPOINT
# 将文件拷贝到镜像中
COPY
# 构建时设置环境变量
ENV

例子

FROM golang:1.9-alpine 

RUN apk --no-cache add git ca-certificates 
#指定工作目录
WORKDIR /go/src/github.com/go/helloworld/ 
#赋值app.go到镜像中
COPY app.go . 

RUN go get -d -v github.com/go-sql-driver/mysql \ 
 && CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app . \ 
 && cp /go/src/github.com/go/helloworld/app /root 
 
WORKDIR /root/ 

CMD ["./app"]



#build
$ docker build -t go/helloworld:1 -f Dockerfile.one .

多层次DockerFile

另一种方式,就是我们事先在一个 Dockerfile 将项目及其依赖库编译测试打包好后,再将其拷贝到运行环境中,这种方式需要我们编写两个 Dockerfile 和一些编译脚本才能将其两个阶段自动整合起来,这种方式虽然可以很好地规避第一种方式存在的风险,但明显部署过程较复杂。

Docker网络原理

外部访问容器

容器中可以运行一些网络应用,要让外部也可以访问这些应用,可以通过 -P 或 -p 参数来指定端口映射。

容器互联

容器之间的通信等。

自定义网络

# 创建网卡
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 [net名称]
-d 参数指定 Docker 网络类型,有 bridge overlay 。其中 overlay 网络类型用于 Swarm mode,在本小节中你可以忽略它。
--subnet 选项 创建子网而言,bridge网络只能指定一个子网,而overlay网络支持多个子网。

# 加入网络
docker run -d --name mysql-net --net [net名称] -e MYSQL_ROOT_PASSWORD=my-secret-pw mysql:5.7


#连接容器
docker run -it --rm --name busybox1 --network my-net busybox sh

网络联通

# 容器连接网络
docker network connect [net名称] [容器名称]


# 容器从mynet网络中断开(它将无法再网络中的容器container3通讯)
docker network disconnect mynet container2

# 移除网络,要求网络中所有的容器断开或者关闭
docker network rm mynet

Docker Compose

window的Docker自带。

概念

定义运行多个容器,以此来高效管理容器。是Docker 官方编排(Orchestration)项目之一,负责快速在集群中部署分布式应用。

我们知道使用一个 Dockerfile 模板文件,可以让用户很方便的定义一个单独的应用容器。然而,在日常工作中,经常会碰到需要多个容器相互配合来完成某项任务的情况。例如要实现一个 Web 项目,除了 Web 服务容器本身,往往还需要再加上后端的数据库服务容器,甚至还包括负载均衡容器等。

Compose 恰好满足了这样的需求。它允许用户通过一个单独的 docker-compose.yml 模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project)。

Compose 中有两个重要的概念:

服务 ( service ):一个应用的容器,实际上可以包括若干运行相同镜像的容器实例。

项目 ( project ):由一组关联的应用容器组成的一个完整业务单元,在 docker-compose.yml 文件中定义。

Compose 的默认管理对象是项目,通过子命令对项目中的一组容器进行便捷地生命周期管理。

模板文件

模板文件是使用 Compose 的核心,默认的模板文件名称为 docker-compose.yml ,格式为 YAML 格式。

基本命令

# 启动
docker-compose up -d [yaml文件名]

Docker Machine

Docker Machine 是 Docker 官方编排(Orchestration)项目之一,负责在多种平台上快速安装 Docker 环境。

Docker Swarm

Docker Swarm 是 Docker 官方三剑客项目之一,提供 Docker 容器集群服务,是 Docker 官方对容器云生态进行

支持的核心方案。使用它,用户可以将多个 Docker 主机封装为单个大型的虚拟 Docker 主机,快速打造一套容器云平台。Docker 1.12.0+ Swarm mode 已经内嵌入 Docker 引擎,成为了 docker 子命令 docker swarm

基本概念

swarm

集群的管理和编号,即docker初始化的集群,可以允许其他节点加入,节点分为manager和worker。

node

是一个docker节点,多个节点组成了网络集群。

service

是一个服务,随机运行在工作节点或管理节点,一组任务从集合。两种模式

replicated services 按照一定规则在各个工作节点上运行指定个数的任务。

global services 每个工作节点上运行一个任务

task

容器内命令,细节节点,每个task为一个副本。单个容器

Raft协议

Raft协议:保证大多数节点存活才可以使用。(所以集群服务器至少要大于三台)

创建服务器集群

# 初始化节点
docker swarm init --advertise-addr [ip地址]
# 加入一个节点
docker swarm join --token [令牌]
# 获取令牌
docker swarm join-token [manager/worker]
# 获取节点
docker node ls
# 离开节点
docker swarm leave

动态扩缩容

# 创建服务 --  类似 docker run 命令
# 与 docker run 相比,docker service 具有扩缩容功能
docker service create [参数] [服务名]
# 查看所有服务
docker service ls
# 查看服务下容器
docker service ps [服务名]
# 扩缩容
docker service scale [服务名]=[num]
# 修改服务
--replicas [num] 	# 创建副本(扩缩容)
docker service update [服务名]
# 移除服务
docker service rm [服务名]

管理配置

Docker 新增了 docker config 子命令来管理集群中的配置信息,以后你无需将配置文件放入镜像或挂载到容器中就可实现对服务的配置。

Docker仓库

仓库( Repository )是集中存放镜像的地方。

一个容易混淆的概念是注册服务器( Registry )。实际上注册服务器是管理仓库的具体服务 器,每个服务器上可

以有多个仓库,而每个仓库下面有多个镜像。从这方面来说,仓库可以 被认为是一个具体的项目或目录。例如对

于仓库地址 dl.dockerpool.com/ubuntu 来 说, dl.dockerpool.com 是注册服务器地址, ubuntu 是仓库名。 大

部分时候,并不需要严格区分这两者的概念。

其他

RedisCluster集群搭建

# 编写Redis配置
for port in $(seq 1 6); \
do \
mkdir -p /data/docker_data/redis/node-${port}/conf
touch /data/docker_data/redis/node-${port}/conf/redis.conf
cat <<EOF  /data/docker_data/redis/node-${port}/conf/redis.conf
port 6379
bind 0.0.0.0
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 172.38.0.1${port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF
done

# 启动容器
docker run -p 637[9]:6379 -p 1637[9]:16379 --name redis-[1] \
-v /data/docker_data/redis/node-[1]/data:/data \
-v /data/docker_data/redis/node-[1]/conf/redis.conf:/etc/redis/redis.conf \
-d --net huanghe-redis --ip 172.38.0.1[1] redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf

# 进入Redis控制台
docker exec -it redis-1 /bin/sh
# 创建cluster
-replicas # 切片
redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1
# 连接集群
redis-cli -c

cluster info	# 查看集群信息
cluster nodes	# 查看节点信息

提升

涉及到安全,网络,云计算等。

没看

你可能感兴趣的:(笔记,docker,学习,容器)