一,docker介绍使用
1.Docker 安装 windos安装
1 2 直接官网下载就可以了 https://download.docker.com/win/stable/Docker%20Desktop%20Installer.exe
Docker支持以下的CentOS版本: CentOS 7 (64-bit) CentOS 6.5 (64-bit) 或更高的版本 前提条件 目前,CentOS 仅发行版本中的内核支持 Docker。 Docker 运行在 CentOS 7 上,要求系统为64位、系统内核版本为 3.10 以上。 Docker 运行在 CentOS-6.5 或更高的版本的 CentOS 上,要求系统为64位、系统内核版本为 2.6.32-431 或者更高版本。
1.使用 yum 安装(CentOS 7下) Docker 要求 CentOS 系统的内核版本高于 3.10 ,查看本页面的前提条件来验证你的CentOS 版本是否支持 Docker 。 通过 uname -r 命令查看你当前的内核版本
1 [root@server1 ~]# uname -r
从 2017 年 3 月开始 docker 在原来的基础上分为两个分支版本: Docker CE 和 Docker EE。 Docker CE 即社区免费版,Docker EE 即企业版,强调安全,但需付费使用。 本文介绍 Docker CE 的安装使用。
docker的官方文档安装
1 https://docs.docker.com/engine/install/centos/
移除旧的版本:
1 2 3 4 5 6 7 8 9 10 sudo yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-selinux \ docker-engine-selinux \ docker-engine
安装一些必要的系统依赖工具 :
1 yum install -y yum-utils device-mapper-persistent-data lvm2
添加软件源信息
1 2 3 4 5 6 7 8 9 阿里云的软件源: yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 官方的下载源: sudo yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo
更新 yum 缓存
列出Docker软件版本信息
1 yum list docker-ce --showduplicates | sort -r
安装 Docker-ce
1 2 3 yum -y install docker-ce //默认安装最新版本 yum -y install docker-ce-3:18.09.7-3.el7 //安装指定版本
支持端口转发
1 2 echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf sysctl -p
重新加载systemctl配置
1 2 3 如果修改了systemctl edit docker.service 这个文件,就要执行这步操作 systemctl daemon-reload
启动 Docker 后台服务
1 2 3 systemctl start docker systemctl status docker systemctl enable docker
1.1docker疑难杂症:docker命令Tab无法自动补全 1.安装bash-complete
1 yum install -y bash-completion
2.刷新文件
1 2 source /usr/share/bash-completion/completions/docker source /usr/share/bash-completion/bash_completion
查看版本信息
1 2 docker version docker info
测试Docker安装
通过运行hello-world Docker映像来测试安装是否正常:
1 $ docker run hello-world
2.使用脚本安装 Docker 1、使用 sudo 或 root 权限登录 Centos。
2、确保 yum 包更新到最新
3、执行 Docker 安装脚本。
1 2 3 curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh
执行这个脚本会添加 docker.repo 源并安装 Docker
4、启动 Docker 进程。
1 2 3 systemctl start docker systemctl status docker systemctl enable docker
5、查看版本信息
1 2 docker version docker info
3,删除卸载Docker CE 执行以下命令来删除 Docker CE:
1 2 sudo yum remove docker-ce docker-ce-cli containerd.io -y sudo rm -rf /var/lib/docker
2.Docker的使用 1.docker常用命令 1.镜像仓库 1 2 3 4 5 6 7 8 1.搜索镜像 docker search centos 2. 从镜像参数中拉取指定镜像 docker pull centos docker官方镜像库 https://hub.docker.com/
2.镜像相关命令 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 1.列出本地镜像 docker images docker images -a docker image ls 2.删除镜像 docker rmi 镜像名 docker rmi -f 镜像名 //强制删除镜像 3.查到指定镜像的创建历史 docker history 镜像名 4.将指定镜像保存为tar归档文件 -o 输出指定文件 docker save -o hello.tar hello-world //hello-world为镜像名。 hello.tar为指定输出的文件 5.由tar文档生成镜像 docker import -m "有本地保存的tar文件生成" ./hello.tar hello-world 参数说明: -m 为创建的镜像设置描述信息,可以通过docker history -H 查看。 ./hello.tar 为tar文件的路径, hello-world 为镜像名字 6.使用dockerfile创建镜像 docker build [可选选项] 文件路径 . 当前目录 docker build -t look/centos7.3 . 参数说明: -t :指定要创建的目标镜像名 . :Dockerfile 文件所在目录,可以指定Dockerfile 的绝对路径 7. 创建某个镜像的副本 docker tag src_image[:tag] tar_image[:tag] docker tag centos:latest localhost:5000/centos #把本地的centos镜像复制一份,命名为localhost:5000/centos
3.容器操作常见命令 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 1.docker ps 列出容器 docker ps -a -a 只显示正在运行的 2.docker inspect 7019f9fdf8ab 查看容器或镜像的元数据 3.docker top 容器名 查看指定容器中运行的进程 4.docker exec -it 容器名 /bin/bash //进入容器 5.docker logs -f 容器名 #查看容器的实时日志 6.docker cp // 容器与主机之间的文件复制 从容器中复制到主机 docker cp testtomcat:/usr/local/tomcat/webapps/test/js/test.js /opt 从主机复制到容器中 docker cp /opt/test.js testtomcat:/usr/local/tomcat/webapps/test/js 选项: -a 复制所有的gid/uid信息 -L Always follow symbol link in SRC_PATH 始终遵循原路径的符号信息 7.docker difff CONTAINER // 查看容器中被修改过的文件或目录 8.启动停止重启容器 docker stop hello-world docker start hello-world docker restart hello-world docker kill hello-world #杀死一个容器 9.查看所有容器id docker ps -aq 10.删除所有容器 docker rm $(docker ps -aq) 11.查看所有没有运行的容器id docker ps -f "status=exited" -q 12. 删除所有没有运行的容器 docker rm $(docker ps -f "status=exited" -q)
4.运行容器 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 运行容器 docker run --name 容器名 -d -p 3306:3306 mysql docker 启动容器 docker run image_name docker run -d -p 80:80 nginx:latest run(创建并运行一个容器) -d 放在后台 -p 端口映射 :docker的容器端口 -P 随机分配端口 -v 源地址(宿主机):目标地址(容器) docker run -it --name centos6 centos:6.9 /bin/bash -it 分配交互式的终端 --name 指定容器的名字 /bin/sh覆盖容器的初始命令
2,构建Dockerfile 编写一个go程序hello.go
1 2 3 4 5 6 7 8 package main import "fmt" func main(){ fmt.Println("hello world") }
创建一个文件Dockerfile命名
1 2 3 4 5 6 7 8 9 #从头开始 FROM scratch #加到根目录 ADD hello / #运行hello CMD ["/hello"]
开始构建
1 docker build -t gohallo/hello .
把go程序跑起来
1 docker run gohello/hello
下载一个centos镜像并跑起来
1 2 3 4 5 6 7 8 docker run centos docker run -it --name centosl -d centos 拷贝hello文件到容器 docker cp hello centosl:/usr/local/ 进入容器 docker exec -it centosl /bin/bash
2.1Dockerfile 详解 1.FROM
1 2 3 4 文件的开始 FROM scratch #从头开始制作一个最简单的 FROM centos #使用centos 为系统,本地若没有则拉取 FROM centos:7.0 #指定系统+ 版本号
2.LABEL
1 2 3 LABEL:相当于注释,或者说明信息。 LABEL version="1.0" LABEL author="luke"
3.RUN
1 2 3 4 5 RUN :相当于执行命令,每执行一条RUN,就会多一层 RUN yum -y update && yum install -y lrzsz \ net-tools \相当于连接线,如果一行写不完就可以这样做。
4.WORKDIR
1 2 3 4 5 WORKDIR 进入或创建目录 WORKDIR /root 进入/root目录 WORKDIR /test 自动创建目录 WORKDIR demo RUN pwd # /test/demo 会打印这个路径
5.ADD and COPY
1 2 3 4 5 6 ADD and COPY 将本地文件添加到镜像里 ADD 可以解压文件 ADD hello / 将主机当前的hello文件 添加到 容器的/根目录下 ADD XXX.tar.gz / 添加到根目录,并解压文件 COPY hello / 直接复制一份到/目录下
6.ENV
1 2 3 4 5 6 7 8 功能为设置环境变量 ENV MYSQL_VERSION 5.6 #设置常量 RUN yum install -y mysql-server="$(MYSQL_VERSION)" 等于下载mysql 5.6版本的 或者 设置了后,后续的 RUN 命令都可以使用,container 启动后,可以通过 docker inspect 查看这 个环境变量,也可以通过在 docker run --env key=value 时设置或修改环境变量。 假如你安装了 JAVA 程序,需要设置 JAVA_HOME,那么可以在 Dockerfile 中这样写: ENV JAVA_HOME /usr/local/jdkxxxx/
7.EXPOSE
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 EXPOSE 用于指定容器在运行时监听的端口: EXPOSE <port> [<port>...] EXPOSE 并不会让容器的端口访问到主机。要使其可访问,需要在 docker run 运行容器时通过-p 来发布这些端口,或通过-P 参数来发布 EXPOSE 导出的所有端口。 映射一个端口 EXPOSE port1 # 相应的运行容器使用的命令 docker run -p port1 image # 映射多个端口 EXPOSE port1 port2 port3 # 相应的运行容器使用的命令 docker run -p port1 -p port2 -p port3 image # 还可以指定需要映射到宿主机器上的某个端口号 docker run -p host_port1:port1 -p host_port2:port2 -p host_port3:port3 image 端口映射是 docker 比较重要的一个功能,原因在于我们每次运行容器的时候容器的 IP 地址不能 指定而是在桥接网卡的地址范围内随机生成的。 宿主机器的 IP 地址是固定的,我们可以将容器的端口的映射到宿主机器上的一个端口,免去每次 访问容器中的某个服务时都要查看容器的 IP 的地址。 对于一个运行的容器,可以使用 docker port 加上容器中需要映射的端口和容器的 ID 来查看该 端口号在宿主机器上的映射端口
8.CMD and ENTRYPOINT
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #shell格式 RUN yum install -y lrzsz CMD echo "hello docker " ENTRYPONINT echo "hello docker" #exec 格式 RUN ["yum","-y","install","lrzsz"] CMD ["/bin/echo","hello Docker"] ENTRYPONINT ["/bin/bash","-c","echo hello Docker"] CMD 和ENTRYPOINT的区别 CMD 若docker指定了其他命令,CMD 会被忽略 若定义了多个CMD,只会执行最后一个
9.VOLUME
1 VOLUME ["/var/www/html","/data/mysql/data"]
3,搭建私有镜像仓库 1.直接执行一条命令搭建
1 2 3 4 5 6 官网地址: https://hub.docker.com/_/registry docker run -d -p 5000:5000 --restart always --name registry registry:2 或者 docker run -d -p 5000:5000 --restart always --name registry -v /opt/reqistry:/var/lib/registry registry:2 /var/lib/registry是容器存放镜像的目录
2.构建自己的镜像
1 2 3 4 docker build -t 192.168.224.11:5000/centos2 . 或者复制一份本地的镜像 docker tag centos:latest localhost:5000/centos
3.上传到自己搭建的镜像仓库
1 2 3 4 5 6 7 8 9 10 11 12 docker push 192.168.224.11:5000/centos2 The push refers to repository [192.168.224.11:5000/centos2] Get https://192.168.224.11:5000/v2/: http: server gave HTTP response to HTTPS client 如果报错: echo '{ "insecure-registries":["192.168.224.11:5000"] }' > /etc/docker/daemon.json 重启docker docker push localhost:5000/centos 去仓库看看。 http://192.168.224.11:5000/v2/_catalog
4.在本地删除构建的镜像
1 2 3 docker rmi 192.168.224.11:5000/centos2:latest docker rmi localhost:5000/centos:latest
5.然后在去搭建的私有创库去下载镜像
1 2 3 4 docker pull 192.168.224.11:5000/centos2 docker pull localhost:5000/centos 也是很快就下载下来了
6.本地仓库加安全认证
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1.生成密码: yum install -y httpd-tools mkdir /opt/registry-auth/ -p htpasswd -Bbn luke 123 > /opt/registry-auth/htpasswd 多用户就追加 htpasswd -Bbn luke1 123 >> /opt/registry-auth/htpasswd 2.重新启动带有秘钥功能的registry容器 docker run -d -p 5000:5000 --restart always --name registry -v /opt/registry-auth/:/auth/ -v /opt/reqistry:/var/lib/registry -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" registry:2 3.push镜像,需要进行login docker login 192.168.224.11:5000 docker push 192.168.224.11:5000/centos2 上传成功 docker logout 192.168.224.11:5000 退出登录
7.docker-habor实现图形化镜像仓库
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 1.安装docker-compose yum install -y docker-compose 2.下载harbor离线安装包并解压 wget https://storage.googleapis.com/harbor-releases/release-1.7.0/harbor-offline-installer-v1.7.1.tgz #解压harbor安装包: tar xvf harbor-offline-installer-v1.7.1.tgz 3.修改harbor.cfg配置文件 3.1 修改如下参数 vim harbor/harbor.cfg hostname = 192.168.224.11 barbor_admin_password = luke123 执行install.sh 3.2.修改docker配置文件 vim /etc/docker/daemon.json #增加如下参数 ["192.168.224.11"] "live-restore":true 3.3重启docker systemctl restart docker 4.测试harbor仓库 4.1 建立harbor项目 通过web访问harbor仓库 http://192.168.224.11/ 输入用户名和密码: 默认用户admin 密码:luke123 #修改harbor.cfg时设置的密码 4.2建立项目,命名luke 设置公有 4.3 给镜像打标签 docker tag centos:latest 192.168.224.11/luke/centos_habor:v1 4.4 登录仓库 [root@instance-x0nj9foj harbor]# docker login 192.168.224.11 Username: admin Password: luke123 Login Succeeded 4.5 上传镜像文件 docker push 192.168.224.11/luke/centos_habor:v1 4.6 web登录镜像仓库进行确认
4.Docker的网络 1.网络的分类 单机
1 2 3 4 5 Bridge Network 桥接网络 Host Network 公用主机网络和宿主机一个网络 None Network 本地网络,自己和自己玩
多机
1 2 Overlay Network 做集群的时候用。
2.Linux 网络命名空间namespace 命名空间是docker底层重要的概念
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 列出网络名 ip netns list 增加一个网络名 ip netns add test1 删除一个网络 ip netns delete test1 查看新建的网络的状态 刚开始是DOWN ip netns exec test1 ip a 设置test1网络的状态,现在变成了UNKNOWN ip netns exec test1 ip link set dev lo up 命名空间至少需要两个以上才能连接起来 在添加一个 ip netns add test2 添加veth peer veth 对 ip link add veth-test1 type veth peer name veth-test2 查看veth对 ip link 把veth-test1 加入到 test1网络 ip link set veth-test1 netns test1 查看test1的link状态. ip netns exec test1 ip link 把veth-test2加入到test2网络 ip link set veth-test2 netns test2 给test1网络添加ip ip netns exec test1 ip addr add 172.17.0.2/24 dev veth-test1 给test2网络添加ip ip netns exec test2 ip addr add 172.17.0.3/24 dev veth-test2 在查看状态test1命名空间的 ip netns exec test1 ip link 启动test1,指定veth对 ip netns exec test1 ip link set dev veth-test1 up 启动test2,指定veth对 ip netns exec test2 ip link set dev veth-test2 up 查看test1网络的IP ip netns exec test1 ip a test1网络去ping test2的ip ip netns exec test1 ping 172.17.0.3 test2网络去ping test1的ip ip netns exec test2 ping 172.17.0.2
3.Bridge 详解 进行多容器通信
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 查看支持的网络 docker network ls 查看网络id的数据信息 docker network inspect 6343c0e76790 查看registry容器的网络信息 docker exec registry ip a eth0@if26 用ip a命令查看 26: vetha30904a@if25: 这个if25和if26就是veth对 yum install -y bridge-utils 下载这个工具 brctl show 查看桥接网络和容器的veth对 brctl show bridge name bridge id STP enabled interfaces docker0 8000.02423025af29 no veth33d7deb vetha30904a
4.容器通信 有时写代码时,并不知道要请求的IP地址
1. –link <name or id>:alias 其中,name和id是源容器的name和id,alias是源容器在link下的别名。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1.启动一个容器命名为mycentos2 docker run -it --name mycentos2 --restart=always -d centos 2.再启动一个容器mycentos3 --link 链接到mycentos2 docker run -it --name mycentos3 --restart=always --link mycentos2 -d centos 这时候进去mycentos3里面,docker exec -it mycentos3 /bin/bash 就可以直接ping mycentos2 可以直接ping通了。不用输入ip地址,但是进去mycentos2里面不能通过容器名ping通mycentos3这个容器,只能ip才可以ping 3.在启动一个容器,进行多个容器链接。 docker run -it --name mycentos4 --restart=always --link mycentos2:centos2 --link mycentos3:centos3 -d centos 进入容器 docker exec -it mycentos4 /bin/bash ping mycentos2 或者ping centos2 ping mycentos3 或者ping centos3 都可以ping通
2.创建网络(推荐) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 docker network ls 创建网络 docker network create -d bridge my-bridge -d 后面第一个bridge是网络的连接方式,第二个my-bridge是自己起的网络的名字 如何创建镜像同时连上主容器的某个网络上? 在镜像创建时指定network 的name ,可以通过docker network ls查看到所有的网络,如下面实例 docker run -it --name test1 --restart=always --network my-bridge -d centos 如何查看是否连上了呢? docker network inspect+ 网络的名字 my-bridge 如何手动将网络和容器连接呢? docker network connect my-bridage mycentos4 docker network connect my-bridge mycentos3 docker network connect my-bridge mycentos2 这时候进去test1 就可以ping mycentos4了。同时mycentos4里面也可以通过ping test1来ping通 docker exec -it test1 /bin/bash 这时他们几个容器都可以互相ping通 通过将test2和test3同时连上自己的创建的网络(注意是自己创建的网络,不是系统自己默认的网络),这样双方都可以通过名字互ping上
5.端口映射 实现外界访问
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1. -p 8080:80 把容器的80端口映射到主机的8080端口 docker run -it --name web --restart=always -p 8080:80 --network my-bridge -d nginx 这时候访问主机的8080端口就可以访问内部的80端口了。 http://192.168.224.11:8080/ 2. -p ip:8081:80 把容器的80端口映射到主机指定的ip端口 docker run -it --name nginx2 --restart=always -p 192.168.224.11:8081:80 --network my-bridge -d nginx 这样就只能通过指定ip:端口才可以访问了, 3.随机端口映射(32768-60999) -p 80 把容器的80端口映射到主机的随机端口 docker run -it --name web2 --restart=always -p 80 --network my-bridge -d nginx 4. udp端口映射 把容器的udp端口映射到主机端口 -p 82:53/udp 5. 多个端口映射 -p 8080:80 -p 33060:3306 -p 2222:22
6.网络的none和host none 应用场景:安全性要求极高,存储绝密数据等
1 2 3 4 指定网络模式为none docker run -it --name none1 --restart=always --network none -d centos 这里面只有127.0.0.1这个ip ,只能ping通自己,其他都不能ping通
host网络
1 2 3 docker run -it --name host1 --restart=always --network host -d centos 网络和宿主机一样。
7.多容器部署和应用 flask 做web服务,redis做自增
8.多机器多容器通信 1.利用etcd实现多机的ip管理 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 etcd 思路: 下载etcd wget https://github.com/coreos/etcd/releases/download/v3.0.12/etcd-v3.0.12-linux-amd64.tar.gz etcd启动命令(node01) 注意修改ip nohup ./etcd --name docker-node1 --initial-advertise-peer-urls http://192.168.224.11:2380 \ --listen-peer-urls http://192.168.224.11:2380 \ --listen-client-urls http://192.168.224.11:2379,http://127.0.0.1:2379 \ --advertise-client-urls http://192.168.224.11:2379 \ --initial-cluster-token etcd-cluster \ --initial-cluster docker-node1=http://192.168.224.11:2380,docker-node2=http://192.168.224.12:2380 \ --initial-cluster-state new& etcd启动命令(node02) 注意修改ip nohup ./etcd --name docker-node2 --initial-advertise-peer-urls http://192.168.224.12:2380 \ --listen-peer-urls http://192.168.224.12:2380 \ --listen-client-urls http://192.168.224.12:2379,http://127.0.0.1:2379 \ --advertise-client-urls http://192.168.224.12:2379 \ --initial-cluster-token etcd-cluster \ --initial-cluster docker-node1=http://192.168.224.11:2380,docker-node2=http://192.168.224.12:2380 \ --initial-cluster-state new& 参数说明: ● –data-dir 指定节点的数据存储目录,若不指定,则默认是当前目录。这些数据包括节点ID,集群ID,集群初始化配置,Snapshot文件,若未指 定–wal-dir,还会存储WAL文件 ● –wal-dir 指定节点的was文件存储目录,若指定了该参数,wal文件会和其他数据文件分开存储 ● –name 节点名称 ● –initial-advertise-peer-urls 告知集群其他节点的URL,tcp2380端口用于集群通信 ● –listen-peer-urls 监听URL,用于与其他节点通讯 ● –advertise-client-urls 告知客户端的URL, 也就是服务的URL,tcp2379端口用于监听客户端请求 ● –initial-cluster-token 集群的ID ● –initial-cluster 集群中所有节点 ● –initial-cluster-state 集群状态,new为新创建集群,existing为已存在的集群 查看端口有没有正常起来 netstat -putnel 查看集群状态 ./etcdctl cluster-health docker启动命令(node01) 先停止下docker /usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock --cluster-store=etcd://192.168.224.11:2379 --cluster-advertise=192.168.224.11:2375& docker启动命令(node02) 先停止下docker /usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock --cluster-store=etcd://192.168.224.12:2379 --cluster-advertise=192.168.224.12:2375& 测试下集群网络 在node01节点创建overlay网络,名为demo docker network create -d overlay demo 这时候去node2节点看docker network ls 查看是否也有demo这个网络,有就说明可以了 开始在node01运行容器 docker run -it --name test1 --restart=always --net demo -d centos 在node02运行一台,容器名不要和node01的重复 docker run -it --name test2 --restart=always --net demo -d centos 这时候进去容器。两台机器上的容器都可以互相ping通了 docker exec -it test1 /bin/bash ping test2
2.利用consul服务管理 方法一
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 1.启动 consul服务,实现网络的统一配置管理 docker run --name consul -p 8500:8500 -h consul -d progrium/consul -server -bootstrap consul: kv类型的存储数据库(key:value) docker01和docker02服务器上: vim /etc/docker/daemon.json { "live-restore":true , "host":["tcp://0.0.0.0:2376","unix:///var/run/docker.sock"], "cluster-store":"consul://192.168.224.11:8500", "cluster-advertise":"ens33:2376" } cluster-store:配置的Consul的leader地址,单体直接写,其它软件注意协议 cluster-advertise: 指定监听的网卡和端口,也可以指定接收订阅消息的IP:PORT systemctl daemon-reload systemctl restart docker 2. 创建overlay网络 docker network create -d overlay --subnet 172.16.0.0/24 --gateway 172.16.0.254 over_1 docker network ls 会发现两台服务器上都多了一个网络over_1 3. 启动容器测试 docker run -it --name luke01 -h luke1 --network over_1 -d centos docker run -it --name luke02 -h luke2 --network over_1 -d centos 进入容器测试 docker container exec -it luke01 /bin/bash ping luke02 可以ping通 他们都可以互相ping通 每个容器有两块网卡,eth0实现容器间的通讯,eth1实现容器访问外网 容器默认路由是走eth1。docker会创建一个bridge网络“docker_gwbridge”,为所有连接到overlay网络的容器提供访问外网的能力 :
方法二
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 1.网卡名ens33 vim /etc/docker/daemon.json { "live-restore":true , "cluster-store":"consul://192.168.224.11:8500", "cluster-advertise":"ens33:2376" } 接着执行命令,重启docker服务,另一台服务器操作方式相同,注意网卡名称 sudo systemctl daemon-reload && sudo systemctl restart docker 2.在11上启动consul docker run --name consul -p 8500:8500 -h consul -d consul:1.5.2 3.创建Docker overlay共享网络 $ docker network create -d overlay my_overlay 访问192.168.224.11:8500 key/value 会出现相关节点信息 4. 启动容器测试 docker run -it --name luke01 -h luke1 --network my_overlay -d centos docker run -it --name luke02 -h luke2 --network my_overlay -d centos 进入容器测试 docker container exec -it luke01 /bin/bash ping luke02 可以ping通 他们都可以互相ping通 每个容器有两块网卡,eth0实现容器间的通讯,eth1实现容器访问外网 容器默认路由是走eth1。docker会创建一个bridge网络“docker_gwbridge”,为所有连接到overlay网络的容器提供访问外网的能力 :
5.docker容器数据持久化本地挂载 1.数据持久化引入
1 2 官方mysql数据存储文档 https://hub.docker.com/_/mysql
在主机系统上的适当卷上创建数据目录,例如/my/own/datadir
。
mysql
像这样启动容器:
1 docker run --name some-mysql -v /my/own/datadir:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql
该-v /my/own/datadir:/var/lib/mysql
命令的一部分/my/own/datadir
从底层主机系统/var/lib/mysql
在容器内部安装目录,默认情况下,MySQL将在该目录中写入其数据文件。
2.数据卷容器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1.宿主机模拟数据目录 mkdir -p /opt/volume/a mkdir -p /opt/volume/b touch /opt/volume/a/a.txt touch /opt/volume/b/b.txt 2.启动数据卷容器 docker container run -it --restart=always --name nginx_volumes -v /opt/volume/a:/opt/a -v /opt/volume/b:/opt/b -d centos 3.使用数据卷容器 docker run -d -p 8085:80 --volumes-from nginx_volumes --restart=always --name nginx_5 nginx docker run -d -p 8086:80 --volumes-from nginx_volumes --restart=always --name nginx_6 nginx 这样有多个目录需要挂载就可以使用这种方式。 作用: 在集中管理集群中。大批量的容器都需要挂载相同的多个数据卷时,可以采用数据卷容器进行统一管理。
6,volume卷管理 docker volume 可以理解成一个container中的磁盘,既可以跟随container的生命周期(在Dockerfile 中定义使用VOLUME关键字),也可以单独创建,永久存储,直到用docker volume rm 命令删除。
1.查看volume
2.创建volume
1 2 3 4 5 6 7 8 9 docker volume create [options] 卷名 options选项有两个参数 -d 指定存储设备,默认是local -o 直接卷的存储路径 默认是 map[] 示例1: docker volume create -d local-persist -o mountpoint=/data/nginx --name=nginxroot 示例2: 参数默认 docker volume create vo_logs 这时候卷的存放路径是/var/lib/docker/volumes/vo_logs/_data
3.查看volume的详细信息
1 docker volume inspect vo_logs
4.删除卷
1 2 3 4 5 6 7 docker volume rm -f vo_logs -f 表示强制删除 docker volume prune [options] 删除未被任何容器使用的本地卷 --filter 提供过滤值 -f , --force 不提示确认信息,直接删除
5.卷的使用
1 2 3 4 5 6 7 docker run -t --name mysql --restart=always -p 3306:3306 -v myvoluem:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=mypassword -d mysql 这时候容器里的/var/lib/mysql的数据就存在myvoluem这个数据卷里了, 第二种是本地挂载 绑定宿主目录的概念很容易理解,就是将宿主目录绑定到容器中的某个目录位置。这样容器可以直接访问宿主目录的文件。其形式是 docker run --name some-mysql -v /my/own/datadir:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql
挂载nginx
1 2 3 4 5 6 7 8 9 1.创建nginx家目录存储卷 docker volume create -d local-persist -o mountpoint=/data/nginx --name=nginxroot 2.创建nginx配置目录存储卷 docker volume create -d local-persist -o mountpoint=/data/nginxconf --name=nginxconf 3.启动容器并挂载卷 docker run -it --name nginx1 --restart=always -p 8080:80 -v nginxroot:/usr/share/nginx/html -v nginxconf:/etc/nginx -d nginx 4.这时候修改配置文件就可以直接在物理机修改就可以了
6.卷和挂载目录有什么区别?
卷 (Docker Volume) 是受控存储,是由 Docker 引擎进行管理维护的。因此使用卷,你可以不必处理 uid、SELinux 等各种权限问题,Docker 引擎在建立卷时会自动添加安全规则,以及根据挂载点调整权限。并且可以统一列表、添加、删除。另外,除了本地卷外,还支持网络卷、分布式卷。
而挂载目录那就没人管了,属于用户自行维护。你就必须手动处理所有权限问题。特别是在 CentOS 上,很多人碰到 Permission Denied,就是因为没有使用卷,而是挂载目录,而且还对 SELinux 安全权限一无所知导致。
3,docker-compose 多容器部署 1.安装 1 2 3 4 5 6 7 方法一: curl -L https://github.com/docker/compose/releases/download/1.26.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose 或者: curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose
查看版本信息
1 # docker-compose --version
但是此方法会经常因为网络的原因而无法安装
方法二:
1、安装python-pip
1 2 3 yum -y install epel-release yum -y install python-pip
2、安装docker-compose
1 pip install docker-compose
待安装完成后,执行查询版本的命令,
2.docker-compose用法 官方文档
1 https://docs.docker.com/compose/
常用选项:
–verbose:输出更多的调试信息
–version:查看compose的版本
-f –file FILE:使用特定的compose模板文件,默认为docker-compose.yml。
-p –project-name NAME 指定项目名称,默认使用目录名称。
常用命令:
down: 停止并删除容器、网络、镜像和卷
build:构建或重建服务
ps:查看已经启动的服务状态
kill:停止某个服务、杀掉容器
logs:可以查看某个服务的log、显示容器的输出内容
port:打印绑定的public port(开放端口)
pull:拉取服务镜像
up:启动yml定义的所有服务
stop:停止yml中定义的所有服务
start:启动被停止的yml中的所有服务
kill:强行停止yml中定义的所有服务
rm:删除yml中定义的所有服务
restart:重启yml中定义的所有服务
scale:设置服务的容器数目
run:运行一个一次性命令
docker-compose up -d nginx 构建建启动nignx容器 在后台运行
docker-compose exec nginx bash 登录到nginx容器中
docker-compose down 删除所有容器,镜像
docker-compose ps 显示所有容器
docker-compose restart nginx 重新启动nginx容器
docker-compose run –no-deps –rm php-fpm php -v 在php-fpm中不启动关联容器,并容器执行php -v 执行完成后删除容器
docker-compose build nginx 构建镜像 。
docker-compose build –no-cache nginx 不带缓存的构建。
docker-compose logs nginx 查看nginx的日志
docker-compose logs -f nginx 查看nginx的实时日志
3.YAML简介 Yaml简介.YAML是一种标记语言,可读性很强。类似于XML数据描述语言,语法比XML简单的多。YAML数据结构通过缩进来表示,连续的项目通过减号来表示,键值对用冒号分割,数组用括号括起来, hash用花括号括起来。
YAML文件格式注意事项:
在缩排中空白字符的数目并不是非常重要,只要相同阶层的元素左侧对齐就可以了(不过不能使用TAB字符);
通常开头缩进2个空格;字符的后面缩进1个空格,比如冒号、逗号、横杆;
支持#注释;
允许在文件中加入选择性的空行,以增加可读性;
可以看到一份标准配置文件应该包含 version、services、networks、volumes 四大部分,其中最关键的就是 services 和 networks 两个部分,下面先来看 services 的书写规则。
示例: 创建4台centos容器。在同一个网络,有挂载。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 version: '3' services: centos: image: centos restart: always hostname: centos container_name: centos ports: - 80:80 networks: - nginx centos1: image: centos restart: always hostname: centos1 container_name: centos1 networks: - nginx command: - yum install -y epel-release && yum install -y nginx volumes: - nginx:/usr/share/nginx/html - nginx:/etc/nginx centos2: image: centos restart: always hostname: centos2 container_name: centos2 networks: - nginx centos3: image: centos restart: always hostname: centos3 container_name: centos3 networks: - nginx networks: nginx: driver: bridge volumes: nginx: driver: local-persist driver_opts: mountpoint: /data/nginx
4.docker-compose中YAML常用的字段:
字段
描述
version: ‘3’
表示当前yaml文件版本
build dockerfile context
指定dockerfile文件名构建镜像上下文路径
services
相当于容器服务
image
指定镜像
restart
重启策略,默认no,always|on-failurel|unless-stopped
hostname
容器主机名
command
执行命令,覆盖默认命令
container_name
指定容器名称,由于容器名称是唯一的,如果指定自定义名称,则无法scale
ports
暴漏端口,与-p相同,但端口不能低于60
environment
添加环境变量
networks
加入网络,引用顶级networks下条目
extra_hosts
添加主机名的标签,就是往/etc/hosts文件中添加一些记录,与Docker client的–add-host类似:
volumes
挂载宿主机路径或命名卷在顶级volumes定义卷名称
deploy
指定部署和运行服务相关配置,只能在Swarm模式使用
depends_on
这个标签解决了容器的依赖、启动先后的问题。
1 2 3 4 5 6 7 Docker容器的重启策略如下: restart no,默认策略,在容器退出时不重启容器 on-failure,在容器非正常退出时(退出状态非0),才会重启容器 on-failure:3,在容器非正常退出时重启容器,最多重启3次 always,在容器退出时总是重启容器 unless-stopped,在容器退出时总是重启容器,但是不考虑在Docker守护进程启动时就已经停止了的容器
关于networks
1 2 3 4 5 6 networks: - my-bridge #此容器用的my-bridge网络 networks: my-bridge: #创建的网络名称 driver: bridge #网络模式为桥接
关于volumes
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 使用卷: volumes: - data01:/var/lib/mysql 创建卷: volumes: data01: driver: local-persist driver_opts: mountpoint: /data/a data10: driver: local-persist driver_opts: mountpoint: /data/b data01为卷的名字。 /data/a为卷的物理路径。
示列 docker-compose -f docker-compose.yml up 启动
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 version: '3' services: zoo1: image: zookeeper restart: unless-stopped hostname: zoo1 ports: - "2181:2181" - "2881:2888" - "3881:3888" container_name: zookeeper networks: zoo_net: ipv4_address: 172.18.0.2 extra_hosts: - "zoo1:172.18.0.2" - "zoo2:172.18.0.3" - "zoo3:172.18.0.4" volumes: - "/root/kafka/zoo1data:/data" - "/root/kafka/zoo1data_log:/datalog" environment: ZOO_MY_ID: 1 ZOO_SERVERS: server.1=zoo1:2881:3881;2181 server.2=zoo2:2882:3882;2181 server.3=zoo3:2883:3883;2181 zoo2: image: zookeeper restart: unless-stopped hostname: zoo2 container_name: zookeeper2 networks: zoo_net: ipv4_address: 172.18.0.3 extra_hosts: - "zoo1:172.18.0.2" - "zoo2:172.18.0.3" - "zoo3:172.18.0.4" ports: - "2182:2181" - "2882:2888" - "3882:3888" volumes: - "/root/kafka/zoo2data:/data" - "/root/kafka/zoo2data_log:/datalog" environment: ZOO_MY_ID: 2 ZOO_SERVERS: server.1=zoo1:2881:3881;2181 server.2=zoo2:2882:3882;2181 server.3=zoo3:2883:3883;2181 zoo3: image: zookeeper restart: unless-stopped hostname: zoo3 container_name: zookeeper3 networks: zoo_net: ipv4_address: 172.18.0.4 extra_hosts: - "zoo1:172.18.0.2" - "zoo2:172.18.0.3" - "zoo3:172.18.0.4" ports: - "2183:2181" - "2883:2888" - "3883:3888" volumes: - "/root/kafka/zoo3data:/data" - "/root/kafka/zoo3data_log:/datalog" environment: ZOO_MY_ID: 3 ZOO_SERVERS: server.1=zoo1:2881:3881;2181 server.2=zoo2:2882:3882;2181 server.3=zoo3:2883:3883;2181 kafka1: image: wurstmeister/kafka ports: - "9092:9092" extra_hosts: - "zoo1:172.18.0.2" - "zoo2:172.18.0.3" - "zoo3:172.18.0.4" networks: - zoo_net restart: always environment: KAFKA_ADVERTISED_HOST_NAME: 192.161.87.218 ## 修改:宿主机IP KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://192.161.87.218:9092 ## 修改:宿主机IP KAFKA_ZOOKEEPER_CONNECT: "zoo1:2181" KAFKA_ADVERTISED_PORT: 9092 KAFKA_BROKER_ID: 1 KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 3 volumes: - "/root/kafka/kafka1-data:/kafka" depends_on: - zoo1 container_name: kafka1 kafka2: image: wurstmeister/kafka networks: - zoo_net restart: always ports: - "9093:9092" extra_hosts: - "zoo1:172.18.0.2" - "zoo2:172.18.0.3" - "zoo3:172.18.0.4" volumes: - "/root/kafka/kafka2-data:/kafka" environment: KAFKA_ADVERTISED_HOST_NAME: 192.161.87.218 ## 修改:宿主机IP KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://192.161.87.218:9093 ## 修改:宿主机IP KAFKA_ZOOKEEPER_CONNECT: "zoo1:2181" KAFKA_ADVERTISED_PORT: 9093 KAFKA_BROKER_ID: 2 KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 3 depends_on: - zoo1 container_name: kafka2 kafka3: image: wurstmeister/kafka ports: - "9094:9092" restart: always extra_hosts: - "zoo1:172.18.0.2" - "zoo2:172.18.0.3" - "zoo3:172.18.0.4" volumes: - "/root/kafka/kafka3-data:/kafka" networks: - zoo_net environment: KAFKA_ADVERTISED_HOST_NAME: 192.161.87.218 ## 修改:宿主机IP KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://192.161.87.218:9094 ## 修改:宿主机IP KAFKA_ZOOKEEPER_CONNECT: "zoo1:2181" KAFKA_ADVERTISED_PORT: 9094 KAFKA_BROKER_ID: 3 KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 3 depends_on: - zoo1 container_name: kafka3 kafka4: image: wurstmeister/kafka ports: - "9095:9092" restart: always extra_hosts: - "zoo1:172.18.0.2" - "zoo2:172.18.0.3" - "zoo3:172.18.0.4" volumes: - "/root/kafka/kafka4-data:/kafka" networks: - zoo_net environment: KAFKA_ADVERTISED_HOST_NAME: 192.161.87.218 ## 修改:宿主机IP KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://192.161.87.218:9095 ## 修改:宿主机IP KAFKA_ZOOKEEPER_CONNECT: "zoo1:2181" KAFKA_ADVERTISED_PORT: 9095 KAFKA_BROKER_ID: 4 KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 3 depends_on: - zoo1 container_name: kafka4 kafka-manager: image: sheepkiller/kafka-manager ## 镜像:开源的web管理kafka集群的界面 networks: - zoo_net environment: ZK_HOSTS: 192.161.87.218 ## 修改:宿主机IP ports: - "9000:9000" ## 暴露端口 depends_on: - kafka3 networks: zoo_net: ipam: config: - subnet: 172.18.0.0/16