文章目录
- 安装
- 镜像
- 制作镜像
- 容器
- 编排工具
- Compose
- Swarm
- 数据卷
- 网络类型
安装
docker是什么?
docker 是一个软件,运行在操作系统上
docker里运行很多的容器 container,一个容器里跑(运行)一个程序(app)
docker是容器的管理程序
docker也是一个虚拟化软件,里面的虚拟机是container 容器
容器才是底层真正干活的软件
一个容器相当于一个虚拟机,里面会运行一个微型的操作系统和程序代码
docker是一个轻量级的虚拟化软件,是一个容器平台
Container --> 容器 --> 其实本质上是一个进程,进程里跑一个应用。
docker是一个容器技术的软件平台
所有的容器都是使用相同的操作系统,相同的底层硬件
What is a Container? 什么是容器?
A standardized unit of software 标准化软件单元
docker和虚拟机的区别
docker的优势
启动速度块
资源消耗小 --> 资源可以控制
扩展方便 --> 快速的复制
虚拟机的优势
更加的安全
隔离更加的彻底 --> 不同的app是使用不同的操作系统的
层次不一样 --> 虚拟机多一层封装
docker底层的隔离机制
name space 命名空间
kernel lxc --> LXC-Linux Containers --> 对容器进行管控的软件
Control Groups --> 对资源进行限制,例如:cpu,内存、磁盘、带宽等 --> cgroups
docker的官方源
可以获得最新稳定的docker的版本
推荐 使用阿里云的源
https://docs.docker.com/engine/install/centos/
centos的源
版本稍微旧点
准备2台虚拟机
docker官方源安装
centos官方源去安装
[root@docker_el8 ~]# cat /etc/centos-release
CentOS Linux release 8.2.2004 (Core)
[root@docker_el8 ~]# uname -r
4.18.0-193.el8.x86_64
1 .如果以前安装过docker,先卸载旧版的
yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine
2 .下载docker官方的repo文件
[root@docker_el8 ~]# yum install yum-utils -y #注:安装yum源的管理工具
[root@docker_el8 ~]# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
#注:下载docker官方提供的repo文件到/etc/yum.repos.d目录下,文件名叫docker-ce.repo
推荐使用阿里云的源
添加一个国内的阿里云的源,下载会快很多 --> 推荐使用
yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
#注:使用docker官方的yum源安装的docker
[root@docker-offical yum.repos.d]# yum install docker-ce docker-ce-cli containerd.io
在另外一台机器上使用centos官方源来操作的,不需要去下载docker-ce.repo文件,直接安装就可以
[root@docker-centos ~]# yum install docker -y
[root@docker-centos ~]# rpm -qa |grep docker
……
3 .启动docker
[root@docker_el8 ~]# systemctl start docker
[root@docker_el8 ~]# ps aux|grep docker
……
4 .设置docker开机启动
示例:设置docker开机启动
[root@docker ~]# systemctl enable docker
[root@docker_el8 ~]# docker --version #注:查看docker的版本
Docker version 20.10.3, build 48d30b5
[root@docker_el8 ~]# docker run hello-world #注:运行 hello-world 镜像,启动一个容器
[root@docker_el8 ~]# docker images #注:查看本机上有哪些docker镜像
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest bf756fb1ae65 13 months ago 13.3kB
概念
镜像:image --> 相当于安装系统的系统盘 --> centos8.iso
组成:程序代码、基础系统、依赖关系的软件包、系统库、工具
nginx的镜像:nginx程序代码,centos系统,gcc、基本库,工具等 --> 包含了软件的微型的系统
镜像是人制作出来的 --> 在企业都是自己去制作镜像
容器:container --> 运行镜像的地方 --> 背后就是起一个进程来运行这个镜像
仓库:hub.docker.com --> 集中存放镜像的地方 repository
[root@docker_el8 ~]# docker --version #注:查看docker版本
Docker version 20.10.3, build 48d30b5
[root@docker_el8 ~]# docker -v
[root@docker_el8 ~]# docker images #注:查看本机docker里有哪些镜像
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest bf756fb1ae65 13 months ago 13.3kB
[root@docker_el8 ~]# docker pull nginx #注:下载nginx镜像文件
[root@docker_el8 ~]# docker pull nginx:1.19.7 #注:下载nginx 1.19.7版本的镜像文件
[root@docker_el8 ~]# docker search nginx #注:镜像搜索
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
nginx Official build of Nginx. 14466 [OK]
star星的个数 判断好坏
参考手册
https://docs.docker.com/reference/
国内的源 --> 加速的作用
[root@docker_el8 ~]# vim /etc/docker/daemon.json
{
"registry-mirrors": [
"https://registry.docker-cn.com",
"http://hub-mirror.c.163.com",
"https://docker.mirrors.ustc.edu.cn"
]
}
[root@docker_el8 ~]# service docker restart
[root@docker_el8 ~]# systemctl restart docker.service
如何启动容器?
[root@docker_el8 ~]# docker run --name sc_nginx_1 -p 80:80 -d nginx
访问本机的80端口 映射到容器里的80端口 (容器的ip地址为172.17.*.*开头)
-d 作为后台的进程运行 daemon
-p 端口映射 80:80 访问本机(宿主机)的80端口,映射到容器里的80端口 port -->iptables 的DNAT
--name 容器的名字
[root@docker_el8 ~]# docker ps -a #注:查看所有的容器,包括没有启动的容器
……
[root@docker_el8 ~]# docker rm 50c156a0a7aa #注:删除容器
[root@docker_el8 ~]# docker network ls #注:查看本机docker里的网络类型
NETWORK ID NAME DRIVER SCOPE
6bb37f30033c bridge bridge local
[root@docker_el8 ~]# docker network inspect 6bb37f30033c #注:查看容器的网络详细信息(含ip)
[root@docker_el8 ~]# docker run --name sc_nginx_2 -p 8080:80 -d nginx
d75617aa88e84df31863fcfa02e06d5dfa4c48302074bb4893b64eeb75f46453 #注:容器的id
[root@docker_el8 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d75617aa88e8 nginx "/docker-entrypoint.…" 18 minutes ago Up 18 minutes 0.0.0.0:8080->80/tcp sc_nginx_2
30c36362c2c5 nginx "/docker-entrypoint.…" 25 minutes ago Up 25 minutes 0.0.0.0:80->80/tcp sc_nginx_1
# 进入容器
[root@docker_el8 ~]# docker exec -it sc_nginx_2 /bin/bash
root@d75617aa88e8:/#
root@d75617aa88e8:/# cat /etc/issue
Debian GNU/Linux 10 \n \l #注:容器 内部跑的是Debian系统
总结
1 .启动容器
[root@docker_el8 ~]# docker ps #注:查看启动的docker容器
[root@docker_el8 ~]# docker run -d -p 8090:80 --name sc_nginx_3 nginx
[root@docker_el8 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c3119faf29d6 nginx "/docker-entrypoint.…" 25 seconds ago Up 23 seconds 0.0.0.0:8090->80/tcp sc_nginx_3
2 .查看开放的端口
[root@docker_el8 ~]# netstat -anplut
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:8090 0.0.0.0:* LISTEN 2864/docker-proxy
3 .访问本机的8090端口,会去访问到sc_nginx_3
[root@docker_el8 ~]# curl 192.168.1.13:8090
4 .进入容器
[root@docker_el8 ~]# docker exec -it sc_nginx_3 /bin/bash
root@c3119faf29d6:/#
[root@docker_el8 ~]# docker exec --help
Options:
-i, --interactive Keep STDIN open even if not attached #注:交互式的方式进入容器
--privileged Give extended privileges to the command
-t, --tty Allocate a pseudo-TTY #注:开启一个终端
在容器里,不是所有的命令都会有,因为镜像文件不能做的太大了,不需要的命令不安装的
root@c3119faf29d6:/# cat /etc/issue
Debian GNU/Linux 10 \n \l #注:Debian系统
root@c3119faf29d6:/# cd /usr/share/nginx/html/
root@c3119faf29d6:/usr/share/nginx/html# echo "cPen" >>index.html #注:修改首页的内容
root@c3119faf29d6:/usr/share/nginx/html# exit #注:退出容器
exit
[root@docker_el8 ~]# docker network ls #注:查看本机docker里的网络类型
NETWORK ID NAME DRIVER SCOPE
3398313e1f51 bridge bridge local
[root@docker_el8 ~]# docker network inspect 3398313e1f51 #注:查看容器的网络的情况
[root@docker_el8 ~]# docker network inspect bridge #注:查看bridge桥接网络的详细信息
"Name": "sc_nginx_1",
"IPv4Address": "172.17.0.2/16",
……
[root@docker_el8 ~]# docker stop sc_nginx_3 #注:将容器停掉
docker run ……
[root@docker_el8 ~]# docker ps -a #注:查看所有的容器,包括没有启动的容器
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c3119faf29d6 nginx "/docker-entrypoint.…" 18 minutes ago Exited (0) 9 seconds ago sc_nginx_3
[root@docker_el8 ~]# docker start sc_nginx_3 #注:启动容器
[root@docker_el8 ~]# docker rm sc_nginx_3 #注:删除容器 (先stop)
[root@docker_el8 ~]# docker container inspect sc_nginx_1 #注:查看容器的详细信息
1 .去docker官方网站去下载redis的镜像,启动这个容器
2 .去docker官方网站去下载flask的镜像,启动这个容器
3 .启动5个nginx的容器,具体名字和映射端口自己定义
4 .停止2个nginx容器,然后再启动下,然后删除一些nginx的容器
[root@docker ~]# docker search redis
[root@docker ~]# docker pull redis
[root@docker ~]# docker run --name sc_redis -p 6379:6379 -d redis
[root@docker ~]# docker search flask
[root@docker ~]# docker pull jcdemo/flaskapp
[root@docker ~]# docker run --name sc_flask -p 5000:5000 -d jcdemo/flaskapp
[root@docker ~]# docker run --name sc_nginx_1 -p 8081:80 -d nginx
……
[root@docker ~]# docker stop sc_nginx_1
[root@docker ~]# docker stop sc_nginx_2
[root@docker ~]# docker start sc_nginx_1
[root@docker ~]# docker start sc_nginx_2
[root@docker ~]# docker stop sc_nginx_1
[root@docker ~]# docker rm sc_nginx_3
示例:对资源进行限制
[root@docker ~]# docker run -d --name liangluyao -p:6697:80 -c 2 -m 20000000 nginx
[root@docker ~]# docker container inspect liangluyao #注:查看容器的详细信息
[root@docker ~]# docker exec -it sc_redis_1 /bin/bash #注:进入容器
root@fa4a000ab091:/data# exit #注:退出容器
[root@docker ~]# docker top sc_redis_1 #注:查看容器内部的进程
镜像
镜像
镜像仓库,可以自己搭建
示例:导出镜像(是docker本地 静态的)
[root@docker ~]# docker save redis >redis.tar
或 [root@docker ~]# docker save -o redis.tar.2 redis
[root@docker ~]# ls
redis.tar
[root@docker ~]# scp redis.tar 192.168.1.9:/root #注:传过去
示例:导出文件系统(是动态的)
导出正在运行的容器里的文件系统成一个归档文件
恢复 $ docker run --rm --volumes-from dbstore -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata
https://docs.docker.com/storage/volumes/
[root@docker ~]# docker export -o sc_nginx.tar sc_nginx_1
[root@docker ~]# ls
sc_nginx.tar
示例:导入镜像
[root@docker_el7 ~]# ls
anaconda-ks.cfg redis.tar
[root@docker_el7 ~]# service docker start
#示例:导入镜像
[root@docker_el7 ~]# docker load -i redis.tar
制作镜像
https://blog.51cto.com/liuleis/2070461
docker容器里面,底层依靠Linux真实机器的内核进行隔离。所以容器只起了用户的进程
[root@docker_el8 ~]# docker start chenpeng
[root@docker_el8 ~]# docker top chenpeng #注:查看容器内部的进程
……
nginx: master process nginx -g daemon off;
nginx: worker process
镜像的原理
https://blog.51cto.com/liuleis/2070461
base 镜像提供的是最小安装的 Linux 发行版
支持运行多种 Linux OS
不同 Linux 发行版的区别主要就是 rootfs
上图 Debian 和 BusyBox上层提供各自的 rootfs,底层共用 Docker Host 的 kernel
容器只能使用 Host 的 kernel,并且不能修改。所有容器都共用 host 的 kernel,在容器中没办法对 kernel 升级
docker里的镜像的制作
镜像可以理解为由很多不同的层的软件组成的
base镜像 --> centos --> nginx --> vim
dockerfile:其实就是制作docker镜像的配方文件(配置文件)
https://github.com/docker/getting-startedhttps://www.runoob.com/docker/docker-dockerfile.html 解析配置文件里的指令https://docs.docker.com/develop/develop-images/dockerfile_best-practices/
指令
FROM 指定基础镜像
WORKDIR 指定进入容器的时候,在哪个目录下 --> 工作目录
COPY 复制宿主机里的文件或者目录到容器里的某个目录下
RUN 就是在容器运行命令 --> 在制作镜像的时候运行的
RUN 是在 docker build
CMD docker在启动容器时 运行的第1个程序命令
CMD 在docker run 时运行 --> 启动容器的时候运行命令的
ENV 定义环境变量
ENV NGINX_VERSION 1.19.7 --> 将1.19.7这个数值赋值NGINX_VERSION这个变量
EXPOSE 声明开放的端口号
ENTRYPOINT 启动容器的时候运行命令的
docker run的时候传递参数到容器
类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖
ARG argument(参数)
传递参数 --> 在制作镜像的时候,使用
VOLUME 在容器里使用卷
作用:将容器里的某个路径挂载到宿主机的卷上
STOPSIGNAL 阻止信号的
http://blog.sina.com.cn/s/blog_7ee0ece50100z6yj.html #注:linux系统的里信号类型
CMD ["nginx", "-g", "daemon off;"]
#注:在前台启动nginx程序 ,-g daemon off 将off值赋给daemon这个变量,告诉nginx不要在后台启动,在前台启动
daemon是守护进程 --> 默认在后台运行
nginx -g选项的作用是 设置一个全局的变量 ,给它赋值
CMD和RUN的区别
CMD
类似于 RUN 指令,用于运行程序,但二者运行的时间点不同:
CMD 在docker run 时运行。
RUN 是在 docker build。
RUN是在制作镜像的时候用的
CMD是在启动进行时用的
示例:RUN案例 ( 和 && 与 \ )
RUN yum install nginx -y
RUN mkdir /feng
RUN touch /feng/sanchuang.txt
RUN yum install nginx -y && mkdir /feng && touch /feng/sanchuang.txt
RUN yum install nginx -y \
&& mkdir /feng \
&& touch /feng/sanchuang.txt
可以减少镜像文件的层次的数量,推荐使用&&
镜像制作 实践
参考资料
https://docs.docker.com/get-started/02_our_app
第1步:下载app源代码
https://github.com/docker/getting-started
在windows里下载,然后上传到linux里
第2步:解压app源代码压缩包
[root@docker_el8 ~]# unzip getting-started-master.zip
第3步:进入app目录,去新建一个Dockerfile
[root@docker_el8 ~]# cd getting-started-master/app/
[root@docker_el8 app]# vim Dockerfile
FROM node:12-alpine
WORKDIR /app
COPY . .
RUN yarn install --production
CMD ["node", "src/index.js"]
第4步:制作镜像
[root@docker_el8 app]# docker build -t getting-started .
#注:-t getting-started 是指定制作的镜像的名字,名字可以自己定义
[root@docker_el8 app]# docker images #注:查看制作的镜像
REPOSITORY TAG IMAGE ID CREATED SIZE
getting-started latest 8acf0fcede90 2 minutes ago 179MB
第5步:启动自己制作的镜像的容器
[root@docker_el8 app]# docker run -dp 3000:3000 getting-started
[root@docker_el8 app]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6d77afa48777 getting-started "docker-entrypoint.s…" 32 seconds ago Up 30 seconds 0.0.0.0:3000->3000/tcp dazzling_shtern
第6步:打开浏览器去访问容器里的网站
http://192.168.31.163:3000/
使用centos基础镜像,编译安装一个nginx,做成自己的镜像,里面可以使用netstat,vim,ping,ip等命令
自己的镜像里有nginx(编译安装)
额外安装netstat,vim,ping,ip
镜像名字:sc-centos-nginx
[root@docker ~]# mkdir /sc-centos-nginx
[root@docker ~]# cd /sc-centos-nginx/
[root@docker sc-centos-nginx]#
1 .准备好一键编译安装nginx的脚本和nginx的源代码
[root@docker sc-centos-nginx]# ls
nginx-1.19.6.tar.gz onekey_install_nginx.sh
[root@docker sc-centos-nginx]# vim onekey_install_nginx.sh
#!/bin/bash
#解决软件的依赖关系,需要安装的软件包
yum -y install zlib zlib-devel openssl openssl-devel pcre pcre-devel gcc gcc-c++ autoconf automake make
#download nginx
mkdir -p /nginx
cd /nginx
#解压 下载的nginx的源码包
tar xf nginx-1.19.6.tar.gz
cd nginx-1.19.6
#生成编译前配置工作 --> Makefile
./configure --prefix=/usr/local/nginx1 --with-threads --with-http_ssl_module --with-http_realip_module --with-http_v2_module --with-file-aio --with-http_stub_status_module --with-stream
#编译
make
#编译安装 --> 将编译好的二进制程序安装到指定目录 /usr/local/nginx1
make install
2 .编写Dockerfile文件
[root@docker sc-centos-nginx]# vim Dockerfile
FROM centos:latest
ENV NGINX_VERSION 1.19.6
ENV OS_VERSION 1.0
LABEL maintainer="chenpeng
WORKDIR /nginx
COPY . .
RUN bash onekey_install_nginx.sh; \
yum install net-tools iproute iputils vim -y
EXPOSE 80
STOPSIGNAL SIGQUIT
ENV PATH /usr/local/nginx1/sbin:$PATH
CMD ["nginx", "-g", "daemon off;"]
或ENV写法
ENV PATH="$PATH:/usr/local/nginx1/sbin"
3 .创建我们自己的镜像
[root@docker sc-centos-nginx]# docker build -t sc-centos-nginx:1.6 .
[root@docker sc-centos-nginx]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
sc-centos-nginx 1.6 451ec7a97a45 5 minutes ago 521MB
4 .启动我们自己制作的镜像的容器
[root@docker sc-centos-nginx]# docker run -dp 9900:80 --name yuanyue sc-centos-nginx:1.6
[root@docker sc-centos-nginx]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
be429617b598 sc-centos-nginx:1.6 "nginx -g 'daemon of…" 5 seconds ago Up 4 seconds 0.0.0.0:9900->80/tcp yuanyue
5 .去浏览器里访问验证是否成功
http://192.168.0.164:9900/
示例:排错 --> 查看容器日志
检查Dockerfile和脚本里的问题
[root@docker sc-centos-nginx]# docker logs yuanyue #注:查看容器日志 --> 排错
nginx: [emerg] getpwnam("lixinhai") failed
示例:删镜像 docker rmi
[root@docker sc-centos-nginx]# docker rmi sc-centos-nginx:1.5
[root@docker sc-centos-nginx]# docker rmi a00ec21dd31c
容器
案例:启动mysql的容器
#步骤:起容器
[root@docker sc-centos-nginx]# docker run -d -p 3306:3306 --name sc-mysql-1 mysql
[root@docker sc-centos-nginx]# docker ps -a #注:容器没起来,排查故障
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2b9489d22752 mysql "docker-entrypoint.s…" About a minute ago Exited (1) About a minute ago sc-mysql-1
[root@docker sc-centos-nginx]# docker logs sc-mysql-1 #注:查看logs,看为什么没起
2021-03-01 03:08:55+00:00 [ERROR] [Entrypoint]: Database is uninitialized and password option is not specified
You need to specify one of MYSQL_ROOT_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD and MYSQL_RANDOM_ROOT_PASSWORD
Entrypoint 启动容器的时候运行命令的、docker run的时候传递参数到容器
初始化MySQL时出错
#步骤:起容器,-e 给Entrypoint传参
[root@docker sc-centos-nginx]# docker run -d -p 3306:3306 --name sc-mysql-1 -e MYSQL_ROOT_PASSWORD='Sanchuang123#' mysql
6f9dc399a36439be15b5144662bbc9320d40c085f61f4d4e9111ab07b7e25ebd
#步骤:再起个容器,指定版本
[root@docker sc-centos-nginx]# docker run -d -p 3307:3306 --name sc-mysql-2 -e MYSQL_ROOT_PASSWORD='Sanchuang123#' mysql:5.7.33
[root@docker sc-centos-nginx]# docker ps #注:容器起来了
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
440dceeae838 mysql:5.7.33 "docker-entrypoint.s…" 52 seconds ago Up 50 seconds 33060/tcp, 0.0.0.0:3307->3306/tcp sc-mysql-2
#步骤:安装mariadb软件 可以得到mysql客户端连接数据库的命令
[root@docker sc-centos-nginx]# yum install mariadb -y
[root@docker sc-centos-nginx]# mysql -h 192.168.0.161 -P 3307 -uroot -p'Sanchuang123#' #注:连接过去
MySQL [(none)]> #注:进来了,说明mysql起成功了
[root@docker sc-centos-nginx]# docker stop sc-mysql-2 #注:停止容器
[root@docker sc-centos-nginx]# docker start sc-mysql-2 #注:开启容器
在MySQL容器里创建相应的库、表 即使容器重启 数据保存,因为保存在相应的数据卷里了
常见的文件的作用
/var/lib/docker/containers 目录下
config.v2.json 存放着容器的配置的数据
hostname 主机名
resolv.conf DNS解析 --> 容器里的dns服务器的地址使用的是宿主机里的dns的配置
hosts 域名解析 通过主机名访问 --> ip 映射 域名(主机名)
示例:–link 多容器之间的链接
[root@docker volumes]# docker run -d -p 9933:80 --name pengyifan --link sc-mysql-2:mysql sc-centos-nginx:1.6
[root@docker volumes]# docker ps #注:容器起来了
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b97cb932b551 sc-centos-nginx:1.6 "nginx -g 'daemon of…" 5 seconds ago Up 3 seconds 0.0.0.0:9933->80/tcp pengyifan
--link sc-mysql-2:mysql
前面表示容器的名字,后面mysql表示写到hosts文件里的主机名
sc-mysql-2 是容器名
mysql 是hosts文件里的主机名
[root@docker volumes]# docker exec -it pengyifan /bin/bash #注:进入容器
[root@b97cb932b551 nginx]# #注:工作目录 Dockerfile WORKDIR指定
[root@b97cb932b551 nginx]# ls
Dockerfile nginx-1.19.6 nginx-1.19.6.tar.gz onekey_install_nginx.sh
[root@b97cb932b551 nginx]# ip add #注:ip命令可以用
[root@b97cb932b551 nginx]# ping www.baidu.com #注:ping命令可以用
[root@b97cb932b551 nginx]# vim Dockerfile #注:vim命令可以用
[root@b97cb932b551 nginx]# cat /etc/hosts #注:在容器的hosts文件里添加名字对应的ip地址
172.17.0.2 mysql 440dceeae838 sc-mysql-2
[root@b97cb932b551 nginx]# ping mysql #注:可以ping通,容器之间可以链接
容器监控
监控
prometheus
https://prometheus.io/ 官网
文档 从零搭建Prometheus监控报警系统
官网教程
https://prometheus.io/docs/prometheus/latest/installation/
[root@docker server]# docker run -p 9090:9090 prom/prometheus #注:简单的启动容器
[root@docker server]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
75301f91cbe8 prom/prometheus "/bin/prometheus --c…" 21 seconds ago Up 19 seconds 0.0.0.0:9090->9090/tcp determined_haibt
访问 192.168.0.164:9090,服务起来了
基于docker 搭建Prometheus+Grafana
步骤1:安装运行Prometheus(docker版)
步骤1.1:安装docker
yum install -y docker-io
步骤1.2:下载镜像包
[root@docker_el7 ~]# docker pull prom/node-exporter
[root@docker_el7 ~]# docker pull prom/prometheus
[root@docker_el7 ~]# docker pull grafana/grafana
步骤1.3:启动node-exporter
docker run -d -p 9100:9100 \
-v "/proc:/host/proc:ro" \
-v "/sys:/host/sys:ro" \
-v "/:/rootfs:ro" \
--net="host" \
prom/node-exporter
步骤:等待几秒钟,查看端口是否起来了
[root@docker_el7 ~]# netstat -anplut
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp6 0 0 :::9100 :::* LISTEN 3960/node_exporter
步骤:访问url
http://192.168.0.163:9100/metrics
步骤1.4:启动prometheus
新建目录prometheus,编辑配置文件prometheus.yml
[root@docker_el7 ~]# mkdir /opt/prometheus
[root@docker_el7 ~]# cd /opt/prometheus/
[root@docker_el7 prometheus]# vim prometheus.yml
global:
scrape_interval: 60s
evaluation_interval: 60s
scrape_configs:
- job_name: prometheus
static_configs:
- targets: ['localhost:9090']
labels:
instance: prometheus
- job_name: linux
static_configs:
- targets: ['192.168.0.163:9100']
labels:
instance: localhost
#注:192.168.0.163是本机地址
步骤:启动prometheus
#注:前提 确保docker开启 service docker start
docker run -d \
-p 9090:9090 \
-v /opt/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml \
prom/prometheus
步骤:等待几秒钟,查看端口状态
[root@docker_el7 prometheus]# netstat -anplut
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:9090 0.0.0.0:* LISTEN 4723/docker-proxy
tcp6 0 0 :::9100 :::* LISTEN 4839/node_exporter
步骤:访问url
效果如下
http://192.168.0.163:9090/graph
步骤:访问targets,url如下
效果如下
http://192.168.0.163:9090/targets
步骤1.5:启动grafana
新建空文件夹grafana-storage,用来存储数据
[root@docker_el7 prometheus]# mkdir /opt/grafana-storage
设置权限
[root@docker_el7 prometheus]# chmod 777 -R /opt/grafana-storage
因为grafana用户会在这个目录写入文件,直接设置777,比较简单粗暴!
启动grafana
docker run -d \
-p 3000:3000 \
--name=grafana \
-v /opt/grafana-storage:/var/lib/grafana \
grafana/grafana
等待几秒钟,查看端口状态
[root@docker_el7 prometheus]# netstat -anlput
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:9090 0.0.0.0:* LISTEN 4723/docker-proxy
tcp 0 0 0.0.0.0:3000 0.0.0.0:* LISTEN 4885/docker-proxy
tcp6 0 0 :::9100 :::* LISTEN 4839/node_exporter
访问url:
http://192.168.0.163:3000/
默认会先跳转到登录页面,默认的用户名和密码都是admin
登录之后,它会要求你重置密码。你还可以再输次admin密码
密码设置完成之后,就会跳转到首页
点击Add data source,由于使用的是镜像方式,所以版本比较新。和网络上的文章展示的图片不一样
name名字写Prometheus
type 选择Prometheus,因为数据都从它那里获取
url 输入Prometheus的ip+端口
编排工具
Compose
Compose
在单台机器(本机)上起多个容器,容器编排工具
https://docs.docker.com/compose/install/ 安装教程https://docs.docker.com/compose/gettingstarted/ 使用教程https://www.runoob.com/docker/docker-compose.html
作用:容器编排的工具
Compose 是 Docker 容器进行编排的工具,定义和运行多容器的应用,可以一条命令启动多个容器
安装Compose
官网教程
https://docs.docker.com/compose/install/
#步骤:下载Docker Compose的当前稳定版本
[root@docker docker]# curl -L "https://github.com/docker/compose/releases/download/1.28.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
#注:没有可执行权限,which不到
#步骤:对二进制文件应用可执行权限
[root@docker docker]# chmod +x /usr/local/bin/docker-compose
[root@docker docker]# which docker-compose
/usr/local/bin/docker-compose
#步骤:创建链接 --> 创建到/usr/bin或路径中任何其他目录的符号链接
[root@docker docker]# ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
#步骤:查看版本,测试是否能跑起来
[root@docker docker]# docker-compose --version
docker-compose version 1.28.4, build cabd5cfb
使用Compose
官网教程
https://docs.docker.com/compose/gettingstarted/
Step 1:Setup 设置
定义应用程序依赖关系
步骤1.1:为项目创建目录
[root@docker docker]# mkdir /composetest
[root@docker docker]# cd /composetest
步骤1.2:在项目目录中创建一个名为app.py的文件
[root@docker composetest]# vim app.py
import time
import redis
from flask import Flask
app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)
def get_hit_count():
retries = 5
while True:
try:
return cache.incr('hits')
except redis.exceptions.ConnectionError as exc:
if retries == 0:
raise exc
retries -= 1
time.sleep(0.5)
@app.route('/')
def hello():
count = get_hit_count()
return 'Hello World! I have been seen {} times.\n'.format(count)
步骤1.3:在项目目录中创建另一个名为requirements.txt的文件
[root@docker composetest]# vim requirements.txt
flask
redis
Step 2:创建一个Dockerfile
[root@docker composetest]# vim Dockerfile
FROM centos:latest
WORKDIR /code
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
RUN yum install gcc python3 -y
COPY requirements.txt requirements.txt
RUN pip3 install -r requirements.txt
EXPOSE 5000
COPY . .
CMD ["flask", "run"]
Step 3:在Compose文件中定义服务
[root@docker composetest]# vim docker-compose.yml
version: "3.9"
services:
web:
build: .
ports:
- "5000:5000"
redis:
image: "redis:alpine"
Compose定义了2个服务:web和reids
Step 4:使用Compose构建并运行app
步骤4.1:从项目目录中,启动应用程序
[root@docker composetest]# docker-compose up
[root@docker composetest]# docker-compose up -d #注:作为后台程序启动
步骤4.2:在浏览器中输入http://localhost:5000/可以看到应用程序正在运行
#步骤:测试效果 --> Chrome 192.168.0.164:5000/
镜像制作好了,容器起来了
[root@docker composetest]# docker ps #注:起了2个镜像,名字自定义为composetest_redis_1、web_1
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
aa1d812d748c redis:alpine "docker-entrypoint.s…" 21 minutes ago Up 21 minutes 6379/tcp composetest_redis_1
a485913bddca composetest_web "flask run" 21 minutes ago Up 21 minutes 0.0.0.0:5000->5000/tcp composetest_web_1
[root@docker composetest]# docker-compose ps #注:2个镜像起来了
Name Command State Ports
composetest_redis_1 docker-entrypoint.sh redis ... Up 6379/tcp
composetest_web_1 flask run Up 0.0.0.0:5000->5000/tcp
[root@docker composetest]# docker-compose down #注:将容器停止,并删除
Step 5: Edit the Compose file to add a bind mount
编辑Compose文件去添加挂载
[root@docker composetest]# vim docker-compose.yml
version: "3.9"
services:
web:
build: .
ports:
- "5000:5000"
volumes: #注:指定数据卷
- .:/code #注:添加的部分
environment: #注:添加的部分
FLASK_ENV: development
redis:
image: "redis:alpine"
Step 6: Re-build and run the app with Compose
使用Compose文件 re-build 和 run
[root@docker composetest]# docker-compose up -d
Step 7: Update the application--> 更新应用程序
[root@docker composetest]# vim app.py
……
return 'Hello World!sanchuang docker I have been seen {} times.\n'.format(count)
效果:在浏览器中刷新应用程序。问候语应该更新,计数器应该仍在递增。
#问:为什么 同步现象?
因为使用了数据卷,将容器的工作目录/code里的东西挂到宿主机当前目录,在宿主机里更新代码,容器里面马上更新
命令总结
docker-compose up
docker-compose down
docker-compose ps
docker-compose stop
Swarm
Compose 在单台机器(本机)上起多个容器,容器编排的工具
多台机器的容器编排:swarm、k8s
compose --> 一台宿主机上编排容器
swarm --> 多态宿主机上编排容器
Swarm
容器编排工具、跨主机的编排、docker集群的管理软件
Swarm是Docker公司推出的用来管理docker集群的软件,几乎全部用GO语言来完成的开发的
https://docs.docker.com/engine/swarm/swarm-tutorial/
Swarm的几个关键概念
1 .Swarm
集群的管理和编排
2 .Node
manager节点、worker节点
3 .Service
一个服务是任务的定义,管理机或工作节点上执行。它是群体系统的中心结构,是用户与群体交互的主要根源
4 .Task
任务是在docekr容器中执行的命令,Manager节点根据指定数量的任务副本分配任务给worker节点
实验:Dcoker Swarm 集群部署
相关端口
2377/tcp(管理端口)、7946/udp(节点间通信端口)、4789/udp(overlay 网络端口)端口
机器环境(三台机器,centos系统)
IP:192.168.0.93 主机名:manager93 担任角色:swarm manager
IP:192.168.31.43 主机名:node43 担任角色:swarm node
IP:192.168.31.109 主机名:node109 担任角色:swarm node
#步骤1:准备工作
#步骤1.1:修改主机名
[root@manager93 ~]# hostnamectl set-hostname manager93 #注:永久修改主机名
[root@node43 ~]# hostnamectl set-hostname node43
[root@node109 ~]# hostnamectl set-hostname node109
#步骤1.2:配置hosts文件(可配置可不配置)
[root@manager93 ~]# vim /etc/hosts
192.168.0.93 manager93
192.168.0.43 node43
192.168.0.109 node109
# 使用scp复制到node主机
[root@manager93 ~]# scp /etc/hosts root@192.168.0.43:/etc/hosts
[root@manager93 ~]# scp /etc/hosts root@192.168.0.109:/etc/hosts
#步骤1.3:设置防火墙
[root@manager93 ~]# systemctl disable firewalld.service
[root@manager93 ~]# systemctl stop firewalld.service
#步骤1.4:安装docker并配置加速器
yum -y install docker
#步骤2:创建Swarm并添加节点
端口
2377/tcp(管理端口)、7946/udp(节点间通信端口)、4789/udp(overlay 网络端口)端口
#步骤2.1:创建Swarm集群 #注:对外宣告 它就是manager
[root@manager93 ~]# docker swarm init --advertise-addr 192.168.0.93
Swarm initialized: current node (tnwimewan3vkfvi13bs10jjtf) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-0us6pbdgivltn0tyxc8nnjvvfyz1n204b88qtjax12r4wemesr-92lmwi0ak73vzxolamfmcoudm 192.168.0.93:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
#注:这就是添加节点的方式(要保存初始化后token,因为在节点加入时要使用token作为通讯的密钥)
相关命令: docker info #注:查看集群的相关信息
docker node ls #注:查看集群中的机器
#步骤2.3:添加节点主机到Swarm集群
#注:在其他主机运行这条命令
[root@node43 ~]# docker swarm join --token SWMTKN-1-0us6pbdgivltn0tyxc8nnjvvfyz1n204b88qtjax12r4wemesr-92lmwi0ak73vzxolamfmcoudm 192.168.0.93:2377
[root@node109 ~]# docker swarm join --token SWMTKN-1-0us6pbdgivltn0tyxc8nnjvvfyz1n204b88qtjax12r4wemesr-92lmwi0ak73vzxolamfmcoudm 192.168.0.93:2377
#注:docker node ls 查看集群中的机器及状态,里面有3台机器,且都为Ready
[root@manager93 ~]# docker node ls #注:查看有哪些节点
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
tnwimewan3vkfvi13bs10jjtf * manager93 Ready Active Leader 20.10.3
o04bfkh5l9vwzskz60bopd8g6 node43 Ready Active 20.10.3
s8n006w4k9016we79naoo1syq node109 Ready Active 20.10.3
#步骤3:在Swarm中部署服务(nginx为例)
#步骤3.1:创建网络在部署服务
# 创建网络
#注:创建网络,网络类型为 overlay
[root@manager93 ~]# docker network create -d overlay nginx_net
[root@manager93 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
0y2kher36e02 nginx_net overlay swarm
# 创建服务(manager-node节点)
[root@manager93 ~]# nginx -s stop #注:80端口不能被占用
#注释:
--replicas 2 #注:创建副本的数量,即创建2个镜像
--network nginx_net #注:使用overlay网络 nginx_net
[root@manager93 ~]# docker service create --replicas 2 --network nginx_net --name tanglf_nginx -p 80:80 nginx
#注:创建了一个具有2个副本(--replicas 2 )的nginx服务,使用镜像nginx
相关命令:
docker service ls 查看正在运行服务的列表
docker service inspect --pretty my_nginx 查询Swarm中服务的信息
-pretty 使命令输出格式化为可读的格式
#步骤3.2:
#命令:查询到哪个节点正在运行该服务
如下该容器被调度到manager-node节点上启动了,然后访问http://192.168.0.93即可访问这个容器应用(如果调度到其他节点,访问也是如此)
[root@manager93 ~]# docker service ps tanglf_nginx
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
o071s71f30vh tanglf_nginx.1 nginx:latest node109 Running Running 19 seconds ago
soyuiu58yd98 tanglf_nginx.2 nginx:latest node43 Running Running 20 seconds ago
#注:服务停止后,背后起的容器会自动删除 (docker service rm tang_nginx)
#步骤3.3:在Swarm中动态扩展服务(scale)
#注:docker service scale 将服务中容器的副本数扩展到4个
[root@manager93 ~]# docker service scale tanglf_nginx=4
如果一个节点宕机了(即该节点就会从swarm集群中被踢出),则Docker应该会将在该节点运行的容器,调度到其他节点,以满足指定数量的副本保持运行状态
结论:即在swarm cluster集群中启动的容器,在worker node节点上删除或停用后,该容器会自动转移到其他的worker node节点上
访问
http://192.168.0.163:80 --> 出现nginx界面
#步骤3.5:Swarm 动态缩容服务(scale)
swarm还可以缩容,同样是使用scale命令
[root@manager93 ~]# docker service scale tanglf_nginx=1
步骤4:Swarm中使用Volume(挂在目录,mount命令)
略 #_labelTop
步骤5:多服务Swarm集群部署 --> 多服务的编排
docker 三剑客中有个compose 这个就是对单机进行统一编排的,它的实现是通过docker-compose.yml的文件,这里就可以结合compose和swarm进行多服务的编排
1 .编写docker-compose.yml文件 vim docker-compose.yml
2 .通过这个yml文件部署服务 docker stack deploy -c docker-compose.yml deploy_deamon
#注:deploy 部署
略 #_labelTop
默认情况下,service discovery为每个swarm服务分配一个虚拟IP地址(vip)和DNS名称,使得在同一个网络中容器之间可以使用服务名称为互相连接
swarm自动生成一个vip
#步骤:在Swarm集群中创建overlay网络
[root@manager93 ~]# docker network create --driver overlay --opt encrypted --subnet 10.10.19.0/24 ngx_net
–opt encrypted 默认情况下swarm中的节点通信是加密的。在不同节点的容器之间,可选的–opt encrypted参数能在它们的vxlan流量启用附加的加密层。
--subnet 命令行参数指定overlay网络使用的子网网段。当不指定一个子网时,swarm管理器自动选择一个子网并分配给网络。
#步骤:将服务连接到overlay网络
[root@manager93 ~]# docker service create --replicas 5 --network ngx_net --name my-test -p 8099:80 nginx
[root@manager93 ~]# docker service ps my-test #注:查看哪些节点有处于running状态的任务
[root@manager93 ~]# docker network inspect ngx_net #注:查询某个节点上关于my-network的详细信息
"Containers": {
……
"IPv4Address": "10.10.19.10/24",
……
"IPv4Address": "10.10.19.7/24",
……
……
[root@node43 ~]# docker network inspect ngx_net #注:查询某个节点上关于my-network的详细信息
"Containers": {
……
"Name": "my-test.4.tbdyw0tkqvqj7gvjype95whqo",
……
"IPv4Address": "10.10.19.9/24",
……
#步骤:可以通过查询服务来获得服务的虚拟IP地址
[root@manager93 ~]# docker service inspect --format='{{json .Endpoint.VirtualIPs}}' my-test
[{"NetworkID":"myzf7pyq3jyz4ty4oo6ytx20j","Addr":"10.0.0.12/24"},{"NetworkID":"083h07kxryt7cbj8u3fi21m1m","Addr":"10.10.19.5/24"}]
#注:10.10.19.5其实就是swarm集群内部的vip
#注:docker内部实现,但是外面的人仍然访问不过来,所以前面要加一个负载均衡器
滚动升级
docker service update 命令,也可用于直接 升级 镜像等
滚动升级:
6个容器
如何把6个旧的容器升级到新的镜像的6个容器
答:关闭一个旧的,马上启动一个新的,慢慢完成
[root@manager93 ~]# docker network ls #注:查看有哪些网络
NETWORK ID NAME DRIVER SCOPE
083h07kxryt7 ngx_net overlay swarm
#注:启动服务,nginx低版本镜像
[root@manager93 ~]# docker service create --replicas 4 --network ngx_net --name jiaoguodong -p 80:80 nginx:1.19.6
[root@manager93 ~]# docker service ps jiaoguodong #注:看服务运行在哪些宿主机上
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
jtjr5jldr3o4 jiaoguodong.1 nginx:1.19.6 manager93 Running Running about a minute ago
ce1vsmnytmlj jiaoguodong.2 nginx:1.19.6 node43 Running Running about a minute ago
3mmz5747xali jiaoguodong.3 nginx:1.19.6 node109 Running Running 42 seconds ago
tg63cd7zvubk jiaoguodong.4 nginx:1.19.6 manager93 Running Running about a minute ago
灰度:旧的东西升级到新的东西,慢慢进行的过程 --> 过度的过程
#步骤:滚动升级
[root@manager93 ~]# docker service update --image nginx:1.19.7 jiaoguodong
[root@manager93 ~]# docker service update --image nginx:latest jiaoguodong
基于docker swarm的web集群项目
在node节点服务器上退出swarm集群
[root@node2 ~]# docker swarm leave #注:node节点离开swarm集群
[root@node3 ~]# docker swarm leave
在manager节点服务器上删除worker节点
[root@manager1 ~]# docker node rm node2 #注:manager节点上 删除worker节点
[root@manager1 ~]# docker node rm node3
manager节点服务器自己退出swarm集群
[root@manager93 ~]# docker swarm leave -f #注:-f 强制离开
loadbalancer ens33 192.168.0.199
ens37 192.168.51.254
nfs ens33 192.168.50.10
docker_manager ens33 192.168.31.1
docker_worker1 ens33 192.168.31.2
docker_worker2 ens33 192.168.31.3
#步骤:负载均衡器 配置NAT策略
SNAT另外一种写法
--> 让内网能够上网
MASQUERADE 伪装,从哪个口出去的,就伪装成哪个ip 数据出去的时候;原ip伪装成数据出去的ip
[root@LB ~]# vim iptables_snat.sh #注:开启路由功能和SNAT功能
#!/bin/bash
echo 1 >/proc/sys/net/ipv4/ip_forward
iptables -F
iptables -F -t nat
iptables -t nat -A POSTROUTING -s 192.168.55.0/24 -o ens33 -j SNAT --to-source 192.168.0.199
#iptables -t nat -A POSTROUTING -s 192.168.55.0/24 -o ens33 -j MASQUERADE
[root@LB ~]# bashiptables_snat.sh
[root@LB ~]# service firewalld stop
[root@LB ~]# systemctl disable firewalld
#步骤:安装nfs相关的软件
[root@nfs-server ~]# yum install nfs-utils -y #注:utility 工具 utils
#步骤:启动nfs服务
[root@nfs-server ~]# service nfs-server start #注:开启nfs服务
[root@nfs-server ~]# systemctl enable nfs-server #注:设置nfs开机启动
[root@nfs-server web]# setenforce 0
[root@nfs-server web]# vim /etc/selinux/config
SELINUX=disabled
[root@nfs-server ~]# vim /etc/exports #注:nfs默认的配置文件
/web 192.168.55.0/24(rw,all_squash,sync)
[root@nfs-server ~]# mkdir /web
[root@nfs-server ~]# chmod 777 /web #注:本身文件系统权限,本地给权限
[root@nfs-server web]# exportfs -rv #注:重新刷新配置文件,使生效
exporting 192.168.55.0/24:/web
#注:在其他的客户机上操作
--> 其他的机器上挂载过来
[root@manager1 ~]# yum install nfs-utils -y
[root@manager1 ~]# mkdir /web/
[root@manager1 ~]# cd /web/
[root@manager1 web]# mount 192.168.55.10:/web /web #注:源文件 目的地
[root@manager1 web]# df -Th
文件系统 类型 容量 已用 可用 已用% 挂载点
192.168.31.166:/web nfs4 17G 5.7G 12G 34% /web
[root@node2 ~]# yum install nfs-utils -y
[root@node2 ~]# mkdir /web
[root@node2 ~]# mount 192.168.55.10:/web /web
[root@node3 ~]# yum install nfs-utils -y
[root@node3 ~]# mkdir /web
[root@node3 ~]# mount 192.168.55.10:/web /web
让客户机开机的时候自动挂载nfs共享的文件夹
[root@manager1 web]# echo "mount 192.168.55.10:/web /web" >>/etc/rc.local
[root@manager1 ~]# vim /etc/hosts
192.168.50.1 manager1
192.168.50.2 node2
192.168.50.3 node3
[root@manager1 ~]# scp /etc/hosts 192.168.55.2:/etc/hosts
[root@manager1 ~]# scp /etc/hosts 192.168.55.3:/etc/hosts
[root@manager1 ~]# docker swarm init --advertise-addr 192.168.55.1 #注:创建swarm集群
docker swarm join --token SWMTKN-1-41v9tlen5yff4znrm0o7hsbjwwxxaippo31oz2a2uhlc9y28cq-dc26xfaw0irh5jq6o5tvnp742 192.168.55.1:2377
#注:其他worker节点加入swarm集群
[root@node2 ~]# docker swarm join --token SWMTKN-1-41v9tlen5yff4znrm0o7hsbjwwxxaippo31oz2a2uhlc9y28cq-dc26xfaw0irh5jq6o5tvnp742 192.168.55.1:2377
[root@node3 ~]# docker swarm join --token SWMTKN-1-41v9tlen5yff4znrm0o7hsbjwwxxaippo31oz2a2uhlc9y28cq-dc26xfaw0irh5jq6o5tvnp742 192.168.55.1:2377
解决方法1
创建卷,路径指向/web
创建卷 --> 容器挂载卷
#步骤:创建卷 (node2节点 或其他节点)
docker volume create --driver local \
--opt type=nfs \
--opt o=addr=192.168.55.10,rw \
--opt device=:/web \
volume-nfs
[root@node2 ~]# docker volume create --driver local \
> --opt type=nfs \
> --opt o=addr=192.168.55.10,rw \
> --opt device=:/web \
> volume-nfs
volume-nfs
#注:o=addr=192.168.55.10,rw 写NFS服务器的ip地址
--opt device=:/web 写NFS挂载的文件
#注:执行后,相关命令docker volume ls;docker volume inspect volume-nfs
#步骤:起容器 挂载卷
docker run -dp 7791:80 --name zhanghy2 -v volume-nfs:/web nginx
docker run -dp 7792:80 --name zhanghy3 -v volume-nfs:/usr/share/nginx/html nginx
#注:/usr/share/nginx/html 是容器内部文件,挂载到nfs服务器上的 /web上
[root@node2 ~]# docker run -dp 7791:80 --name zhanghy2 -v volume-nfs:/web nginx
[root@node2 ~]# docker exec -it zhanghy2 /bin/bash
root@42def0ea7a9c:/# cd /web #注:挂载起来了,容器内部自动生成/web文件
root@42def0ea7a9c:/web#
[root@node2 ~]# docker run -dp 7792:80 --name zhanghy3 -v volume-nfs:/usr/share/nginx/html nginx
[root@node2 ~]# curl 192.168.55.2:7792
chenpeng index
[root@node2 ~]# docker service rm nfs-service
[root@node2 ~]# docker service rm nfs-service-2
解决方法2:
swarm批量起容器 (精华部分)
#步骤:在manager1节点上 swarm 批量起容器
[root@manager1 ~]# docker service create -d \
> --name nfs-service \
> --mount 'type=volume,source=nfsvolume,target=/usr/share/nginx/html,volume-driver=local,volume-opt=type=nfs,volume-opt=device=:/web,"volume-opt=o=addr=192.168.55.10,rw,nfsvers=4,async"' \
> --replicas 5 \
> -p 7798:80 \
> nginx:latest
[root@manager1 ~]# docker service ls #注:服务起来了
ID NAME MODE REPLICAS IMAGE PORTS
3063cyhkh7cf nfs-service replicated 5/5 nginx:latest *:7798->80/tcp
[root@manager1 ~]# docker volume ls #注:结论:卷会自己创建
DRIVER VOLUME NAME
local nfsvolume
#步骤:Swarm节点里敲
[root@manager1 ~]# curl 192.168.55.1:7798
chenpeng index
[root@manager1 ~]# curl 192.168.55.2:7798
chenpeng index
[root@manager1 ~]# curl 192.168.55.3:7798
chenpeng index
#注:即可以访问 容器内部,swarm批量起容器成功
负载均衡器
# nginx负载均衡器里的配置
[root@loadbalancer ~]# vim /usr/local/nginx/conf/nginx.conf
upstream mydownload {
server 192.168.55.1:7798 weight=1;
server 192.168.55.2:7798 weight=1;
server 192.168.55.3:7798 weight=1;
}
server {
listen 80;
server_name www.sc.cn;
location / {
proxy_pass http://mydownload;
}
[root@loadbalancer ~]# nginx -s reload
windows修改hosts文件
C:\Windows\System32\drivers\etc
192.168.0.199 www.sc.cn
相关命令
docker network ls
docker network inspect ingress 查看容器内部的ip地址
docker service inspect nfs-services-2 查看到VIP的地址
docker ps
docker container inspect 接ip 查看容器的ip地址
[root@manager1 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
lsca11ngtxk3 ingress overlay swarm
[root@manager1 ~]# docker network inspect ingress #注:查看容器内部的ip地址
"Containers": {……
"Options": {……
"IP": "192.168.55.1"
{
"IP": "192.168.55.3"
{
"IP": "192.168.55.2"
}
[root@manager1 ~]# docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
3063cyhkh7cf nfs-service replicated 5/5 nginx:latest *:7798->80/tcp
#注:查看到VIP的地址
[root@manager1 ~]# docker service inspect --format='{{json .Endpoint.VirtualIPs}}' nfs-service
[{"NetworkID":"lsca11ngtxk3553pi4d9775px","Addr":"10.0.0.5/24"}]
10.0.0.5就是swarm集群内部的vip
[root@manager1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
71d37f1490e4 nginx:latest "/docker-entrypoint.…" 42 minutes ago Up 42 minutes 80/tcp nfs-service.4.8j0bjfmqvqchq4tdldjpbtphc
[root@manager1 ~]# docker container inspect 71d37f1490e4 #注:查看容器的ip地址
"IPAddress": "10.0.0.9",
数据卷
数据卷:volume
--> 存放数据的地方 --> 目的:就是让容器里的数据可以永久的保存,同时能够和其他的容器分享
容器的数据和本机的数据保存的问题
作用:实现容器和宿主机之间共享数据的
卷是共享属性数据的 --> 存储数据的问题
容器对应着运行的一个进程 --> 一个进程对应一个容器 --> 内存
数据持久化 --> 数据的保存问题 --> 容器停止后,数据永久保存的问题
docker里的相关的进程
docker-proxy 这个进程是专门负责端口映射 (监听端口的)
dockerd docker server的进程
containerd 整个容器的管理进程
containerd-shim-runc-v2 具体某个容器对应的进程
演示数据卷的使用
https://docs.docker.com/storage/volumes/
[root@docker ~]# mkdir /web
[root@docker ~]# cd /web/
[root@docker web]# ls
[root@docker web]# cat index.html
welcome to sanchuang!
#示例:-v 挂载
[root@docker web]# docker run -d --name liuyong -v /web:/usr/share/nginx/html -p 7790:80 nginx
[root@docker web]# curl 192.168.1.13:7790
welcome to sanchuang!
数据卷操作2个案例
nginx --> 网站内容
mysql --> 备份还原数据
示例:nginx 网站内容 挂载
[root@docker web]# echo "chenpeng index" >index.html
[root@docker web]# pwd
/web
[root@docker web]# docker run -d --name chenpeng -p 6655:80 -v /web:/usr/share/nginx/html nginx
[root@docker web]# curl 192.168.1.13:6655
chenpeng index
示例:使用卷的案例 (推荐)
https://docs.docker.com/storage/volumes/
卷默认存放的路径 /var/lib/docker/volumes/
[root@docker web]# docker volume create sc-vol #注:创建卷
sc-vol
[root@docker web]# docker volume ls #注:显示有哪些卷
DRIVER VOLUME NAME
local sc-vol
[root@docker web]# cd /var/lib/docker/volumes/ #注:存放卷的目录
[root@docker volumes]# docker volume inspect sc-vol #注:查看卷的详细信息
"Mountpoint": "/var/lib/docker/volumes/sc-vol/_data",
"Name": "sc-vol",
[root@docker _data]# docker run -d --name tanglf -p 6654:80 --mount source=sc-vol,target=/usr/share/nginx/html nginx
[root@docker _data]# pwd
/var/lib/docker/volumes/sc-vol/_data #注:存放卷的目录
[root@docker _data]# echo "tanglf nginx" >index.html
[root@docker _data]# curl 192.168.1.13:6654
tanglf nginx
示例:删除卷
[root@docker ~]# docker volume ls
DRIVER VOLUME NAME
local sc-vol
[root@docker ~]# docker volume rm sc-vol #注:删除卷 需要先停止docker容器
1 .创建一个卷 sc-vol-2
2 .创建一个nginx容器 使用这个卷
3 .修改卷对应的目录里的index.html页面的内容,刷新查看下效果
[root@docker ~]# docker volume create sc-vol-2
sc-vol-2
[root@docker ~]# docker run -d --name sc_nginx-2 -p 81:80 --mount source=sc-vol-2,target=/usr/share/nginx/html nginx
[root@docker ~]# echo "sc-vol-2 nginx" >/var/lib/docker/volumes/sc-vol-2/_data/index.html
[root@docker ~]# curl 192.168.1.13:81
sc-vol-2 nginx
示例:数据卷
[root@docker ~]# docker volume create sc-dahai #注:创建卷
sc-dahai
[root@docker ~]# docker volume ls
DRIVER VOLUME NAME
local sc-dahai
[root@docker ~]# docker volume inspect sc-dahai #注:查看卷的详细信息
[
"Mountpoint": "/var/lib/docker/volumes/sc-dahai/_data", #注:存放卷的地址
"Name": "sc-dahai",
……
]
网络类型
docker的网络类型
https://www.jianshu.com/p/22a7032bb7bd
[root@docker ~]# docker network ls #注:查看本机docker里的网络类型
NETWORK ID NAME DRIVER SCOPE
3398313e1f51 bridge bridge local
f169861e2cc9 host host local
d350fc9b48f1 none null local
bridge模式(默认为该模式)
当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中
host模式
如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口
container模式
这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等
--> k8s里的pod会使用
pod:理解为一个小组,最基本的单元在k8s里。一个pod里可以有很多容器
none模式
使用none模式,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等
这种网络模式下容器只有lo回环网络,没有其他网卡。none模式可以在容器创建时通过--network=none来指定。这种类型的网络没有办法联网,封闭的网络能很好的保证容器的安全性
以上4种模式,只是考虑宿主机和容器之间的通信 --> 在同一台机器里
第5种:overlay
实现跨主机的docker容器之间的通信
http://dockone.io/article/2717
总结
卷是共享属性数据的 --> 存储数据的问题
网络类型是在网络上传输数据的 --> 传输数据的问题
bridge --> 默认
host
none
container
上面4种是在一台宿主机里的网络通信问题
overlay
在不同的宿主机上的不同的容器之间的网络通信问题