29_linux笔记-docker


个人博客
https://blog.csdn.net/cPen_web


安装

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的容器

https://hub.docker.com/

[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-started
https://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 <1533431376@qq.com>"

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://www.cnblogs.com/chenqionghe/p/10494868.html

官网教程
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

https://www.cnblogs.com/xiao987334176/p/9930517.html

步骤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/

https://www.cnblogs.com/zhujingzhi/p/9792432.html

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命令)
略	https://www.cnblogs.com/zhujingzhi/p/9792432.html#_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 部署
略	https://www.cnblogs.com/zhujingzhi/p/9792432.html#_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内部实现,但是外面的人仍然访问不过来,所以前面要加一个负载均衡器

参考 https://www.cnblogs.com/zhujingzhi/p/9792432.html#_labelTop


滚动升级

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容器之间的通信

https://www.cnblogs.com/xiangsikai/p/9898174.html
http://dockone.io/article/2717

总结

	卷是共享属性数据的 --> 存储数据的问题
	网络类型是在网络上传输数据的 --> 传输数据的问题
		bridge --> 默认
		host
		none
		container
			上面4种是在一台宿主机里的网络通信问题
		overlay
			在不同的宿主机上的不同的容器之间的网络通信问题

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mycpen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值