ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

docker入门

2022-07-15 22:03:40  阅读:149  来源: 互联网

标签:容器 00 run 入门 -- 镜像 docker


FROM

B站-遇见狂神说 https://www.bilibili.com/video/BV1og4y1q7M4?p=27&spm_id_from=pageDriver

docker安装

虚拟化的容器技术,轻巧,快速,方便

可以理解为:一种带环境的程序集合;

配置好的docker环境可以放到别的机器上,不用担心因为环境问题而无法运行。

在docker之前,都是用虚拟机技术,windows上安装Vmware,在Windows电脑上模拟出一台或多台电脑,十分笨重卡;

docker上运行的容器,例如centos,都是精简版的,所以小,其只包含了一些基本命令,根本的信息还是使用的主机的系统,所以启动的快;

官方文档:https://docs.docker.com/

安装docker

安装docker有不同类型 install on centos; install on Ubuntu等,具体安装什么环境看官方文档

本文档已Centos7为例

需要存在gcc环境

yum -y install gcc
yum -y install gcc-c++
1.安装docker需要先卸载旧的版本
# 直接运行,存在就卸载
yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine
2.安装一些需要的安装包(环境)
yum install -y yum-utils
3.设置镜像仓库
# 官方文档提供的是国外的镜像仓库,速度很慢,此处不建议用
# 不用这个 yum-config-manager \
# 不用这个    --add-repo \
# 不用这个    https://download.docker.com/linux/centos/docker-ce.repo
# 此处使用阿里云镜像仓库
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
4.安装最新版docker引擎
# 安装引擎前,更新软件包索引
yum makecache fast
# docker-ce 表示社区版(推荐)  ee 表示企业版
yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin
5.可以启动docker、测试docker了
# 一般没报错,就是启动成功了
systemctl start docker
docker version
# docker的运行命令都有run
# 运行hello-world 镜像,他会去远程拉去该镜像
docker run hello-world
6.查看一下镜像在否
# images 命令
docker images

卸载docker

# 卸载当前依赖
yum remove docker-ce docker-ce-cli containerd.io docker-compose-plugin
# 删除docker资源、一般都是这个默认工作路径
rm -rf /var/lib/docker
7.阿里云镜像加速

登陆阿里云-工作台-容器镜像服务-镜像工具-镜像加速器-centos

配置镜像加速器

针对Docker客户端版本大于 1.10.0 的用户
# 复制直接跑
您可以通过修改daemon配置文件/etc/docker/daemon.json来使用加速器

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://1907i166.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
8. docker run工作原理
运行yuge这个镜像
docker run yuge
1.查找本地是否存在这个镜像,如果存在,直接运行
不存在 那就去远程docker仓库获取(默认docker hub,自己有配置阿里云镜像或者别的什么镜像仓库)
2.远程仓库找到了,下载到本地运行
远程仓库没找到,直接报错

9.docker简单工作原理

服务器上运行docker程序,相当于在我们服务器上运行了个小的且隔离的服务器,与整个服务器隔离开互不影响。

因此我们web程序访问docker上的nginx、mysql等应用,需要进行建立连接:整个Linux系统与docker的连接.

10.docker为什么比虚拟机快

百度去

docker_portainer安装

# 拉去镜像
docker search portainer
docker pull portainer/portainer
# portainer_data这个挂载是我自己建的一个卷,后面那个什么.sock是单机启动必须指定docker.sock
docker run -d --name portainer --restart always -p 8092:9000 -v portainer_data:/data  -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer

docker常用命令

官方命令文档:https://docs.docker.com/engine/reference/commandline

1.帮助命令

# 版本
docker version
# 详细信息:服务器信息、镜像信息、运行状态信息
docker info
# 帮助命令
docker --help
docker images --help

2.镜像命令

# 显示全部镜像
docker images -a
# 显示镜像的id
docker images -q
docker images -aq 或者 -qa 都可以
# 搜索命令
docker search mysql
# 过滤搜索 --filter
# 过滤掉MySQL星标小于500的
docker search mysql --filter stars=500
# 镜像下载
docker pull
# 默认下载最新版本
docker pull mysql
# 指定版本下载,这个版本一定要在官方文档支持的
docker pull mysql:5.7
# 删除镜像 remove image + 指定容器id + id + id 多个删除
docker rmi id id id
# 全部删除镜像 $(这里面是镜像id列表)
docker rmi -f $(docker images -aq)

3.容器命令

有镜像才可以创建容器

# 启动容器 docker run 参数 image
# 参数说明
# --name="name" 容器名字
# -d  以后台方式运行
# -it 使用交互方式运行,进入容器查看内容 
# -P  大写的P,指定容器的端口,灰常重要 
#    -p ip:8080:8080 主机端口映射到容器端口(常用)
#    -p 8080:8080 主机端口映射到容器端口(常用)
#    -p 8080 容器端口
# -p  小写的p,随即指定端口

# 启动并进入容器 
docker run -it centos /bin/bash
[root@iZ2zec82iqaelrhwpp07m4Z ~]# docker run -it centos /bin/bash
[root@c09aff7abbd9 /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
启动并进入发现里面就是个小型的centos系统,very good
# 容器停止并退出 在容器内直接exit
exit
# 容器退出不停止  Ctrl + p + q
# 列出容器 ps
docker ps    列出正在运行的容器
docker ps -a 列出全部的容器
docker ps -n=5 最近5个容器
docker ps -aq 列出全部容器id
docker ps -n=2 -q
# 删除容器
docker rm 容器id,正在运行的容器没办法删除
docker rm -f 可以删除正在运行的容器
docker rm -f $(docker ps -aq)
# 启动、重启、停止正在运行的、强制停止
docker start 容器id
docker restart id
docker stop id
docker kill id

常用命令

# 后台启动
docker run  -d centos
# 坑 docker ps 发现没有在运行
# 因为:docker检测到我们启动的容器并没有对外提供什么服务,所以启动完了他就自动停止了,使用run -it 启动就不会出现此坑
# 查看日志命令(容器启动才有用) 
docker logs -f -t --tail 10 容器id
# 查看进程信息
docker top 容器id
# docker inspect 查看容器内部信息
docker inspect 容器id

# 进入当前正在运行的容器  
# -it 表示以交互模式运行
docker exec -it 容器id /bin/bash
docker attach 容器id
# exec 与 attach 区别
# exec: 进入容器后新开启一个终端,可以在里面进行操作(常用)
# attach: 直接进入正在执行的终端,不会启动新的进程

# docker cp 容器内-文件拷贝到主机
docker cp 容器id:容器内路径 主机路径
#  主机-文件拷贝到容器内 使用挂载

# 查看docker服务器信息
docker stats

# 查看镜像如何做的
docker history 镜像id
docker history --no-trunc 镜像id
# 给镜像打标签(重命名) + 版本号
docker tag 镜像id mytomcat/镜像名:1.0

# docker 保存tar包、导入tar包
docker save -o mytomcat.tar mytomcat   # 保存当前镜像到当前目录为mytomcat.tar	 
docker load -i mytomcat.tar   # 将当前目录的这个tar包导入进容器镜像中

测试拉取镜像、启动镜像nginx

# -p 暴露端口
# docke run -d --name nginx01 -p 3333:8080 nginx
# curl 3333 本机自测这个端口

提交镜像

# commit 提交容器+镜像 成为新的镜像 方便使用
# docker commit -m="描述" -a="xingyu" 容器id  要生成名字:标签
docker commit -m="nginx配置好的镜像" -a="yuge" 5091f3c823ca nginx01:1.0.1
[root@iZ2zec82iqaelrhwpp07m4Z /]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
nginx01      1.0.1     58e14049e3b5   4 seconds ago   141MB
nginx        latest    605c77e624dd   4 months ago    141MB
tomcat       latest    fb5657adc892   4 months ago    680MB

容器数据卷(数据持久化)

容器间数据共享技术:目录的挂载,讲容器内的目录挂载到主机上;

# 直接使用命令挂载 -v 主机目录:容器目录    -v 可以挂载多个
# 当容器启动成功后,挂载成功,主机目录就与容器目录的内容双向绑定,自动同步
# 只要容器建立,停止容器也不会影响  
docker run -d -v /home/ceshi:/home -v 目录:目录 -v 目录:目录 centos /bin/ 
docker run -it --name nginx03 -p 8094:80 -v /home/ceshi:/home nginx /bin/bash
# 删除、编辑主机目录信息,容器内目录信息也会删除、编辑;但是删除容器目录信息,主机的不会被删除

mysql 容器注意事项

  1. -e 命令 MySQL的初始密码

具名挂载、匿名挂载

匿名挂载:容器启动时只指定了容器内挂载(卷)的路径,未指定主机路径(卷);

具名挂载:容器启动时只制定了容器内的挂载路径,并且为卷赋名;

# 匿名挂载 只指定了容器内路径
docker run -d *** -v /etc/nginx nginx /bin/bash
# 查看卷(挂载)
docker volume ls 
# 通过卷id查看挂载目录
docker volume inspect 卷id
# 具名挂载 指定了卷的名称 方便查找 
# -v的冒号前面字符未加根目录'/',表示这个是名称,即具名
docker run -d *** -v juming:/etc/nginx nginx /bin/bash

挂载的三种方式

1. 匿名挂载
docker run *** -v /容器内路径 /bin/bash
2. 具名挂载
docker run *** -v 卷名:/容器内路径 
3. 正常挂载
docker run *** -v /主机路径:/容器路径

挂载时加上权限

# :ro 只读  :rw 可读可写    支持三种挂载方式
1.docker run -v /home:/home:ro /bin/bash 
#  表示只读,要想修改这个容器路径内的信息,只能修改宿主机的挂载路径信息
2. docker run -v name:/home:rw /bin/bash 
#  表示可读可写,容器路径内信息可以直接修改,无需通过宿主机挂载路径修改,不过常用的话还是改宿主机信息方便

Dockerfile(大写D小写f)

用来构建docker镜像的文件,命令脚本

docker的镜像是一层一层的,因此dockerfile文件命令也是一层一层的,每个命令是一层;

# 简单的构建一个dockerfile文件(没有后缀)
FROM centos
VOLUME ["volumn1","volumn2"]
CMD echo "----END----"
CMD /bin/bash
# 构建镜像命令
# -f 表示引用那个dockerfile;dockerfile文件名如果叫做dockerfile1等等,那一定要在构建时指定绝对路径
#    只有在叫Dockerfile时,并且在当前目录构建,才不需要指定绝对路径
# -t target的意思:新的镜像名称  可以加':1.0',表示tags为1.0版本
# . 最后的那个'.'不能忘记
docker build -f /home/dockerfile -t yugecentos . 
# 标准官方名字文件可以直接当前路径构建
docker build -t myimages .
# 构建完成启动下自己的镜像
docker run -d -it yugecentos /bin/bash
# 新启动的容器内就会有我们要的两个 挂载卷目录 volumn1,volumn2
# 查看容器的信息,找到"Mounts",就可以看到挂载的信息了
docker inspect 容器id

# 在配置镜像时,没有 VOLUMN ["volumn1"] 挂载镜像,那还是在启动阶段 -v命令手动挂载
docker run -d -v volumn1:/容器内路径 yugecentos 

数据卷容器

例:多个MySQL需要数据共享;

# -e 命令,设置环境,此处就是设置MySQL的初始密码
docker run -e MYSQL_ROOT_PASSWORD=123456
# 多个挂载放在一起:挂载再进行挂载,都是允许的,文件互相同步
# 实现多个容器信息同步:配置文件、数据等的共享,知道没有容器使用,数据卷才会结束,
 docker run -d --name nginx02 --volumes-from nginx01 nginx
 docker run -d --name nginx03 --volumes-from nginx01 nginx

数据卷总结

1.数据卷的声明周期:只有存在一个容器在使用,则一直存在。

2.多个容器进行数据共享时,删除任意一个并不会影响,但是全部删除了,拿数据就会消失;

因此,为了保证我们数据的安全,还是需要将其中一个容器挂载到主机服务器,这样就算容器全部删除,数据还会 保存。

dockerfile

构建docker镜像的文件:命令脚本的集合;

构建步骤:

1、编写dockerfile 文件

2、docker build 构建一个镜像

3、docker run 运行镜像

4、docker push 发布镜像(远程仓库)

dockerfile介绍

1、指令的关键字必须大写字母

2、执行顺序从上到下

3、每个指令都会创建提交一个新的镜像层,并提交

# FROM 基础镜像,字面意思:来源 
FROM
# MAINTAINER 作者 一半格式为 作者+邮箱
MAINTAINER
# RUN 运行时的命令
RUN
# ADD 添加的东西,比如想要在镜像里面添加的内容,比如tomcat安装包
ADD
# WORKDIR 镜像的工作目录
WORKDIR
# 卷,挂载主机的位置
VOLUME
# 对外指定的端口(暴露哪个端口)
EXPOSE
# 运行
RUN
# CMD 指定容器启动时要运行的命令
CMD
# ENTRYPOINT(追加命令) 同CMD 一样,指定需要运行的命令;
ENTRYPOINT
# ONBUILD 当继承一个 dockerfile时候,会触发
ONBUILD 
# COPY 复制,类似add命令,将文件拷贝到镜像中
COPY
# 环境,构建时设置环境变量 后面跟键值对的形式
ENV 


Dockerfile 构建tomcat

1、建立Dockerfile文件
# 基于centos镜像
FROM centos
# 作者
MAINTAINER yuge<738524794@qq.com>
# 将Dockerfile文件拷贝到镜像中
COPY Dockerfile /usr/local/Dockerfile
# 添加tomcat(需要jdk)和jdk,安装包和Dockerfile同一路径,自动解压到指定目录下
ADD  jdk-8u333-linux-x64.tar.gz  /usr/local/
ADD  apache-tomcat-8.5.79.tar.gz /usr/local/
# 添加个vim命令,因为centos的基础镜像包没有这个命令
# RUN yum -y install vim 因为centos版本问题这行命令会报错
# 配置工作默认镜像进来时候的目录,即配置环境
ENV MYPATH /usr/local
WORKDIR $MYPATH
# 配置java\tomcat的环境
ENV JAVA_HOME /usr/local/jdk1.8.0_333
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools/jar
ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.79
ENV CATALINA_BASH /usr/local/apache-tomcat-8.5.79
ENV PATH $PATH:$JAVA_HOME/lib:$CATALINA_HOME/lib:$CATALINA_HOME/bin
# 因为tomcat默认端口8080,那就把8080暴露出去
EXPOSE 8080
# 启动时,需要执行的命令 用and符号连接起来‘&&’
CMD /usr/local/apache-tomcat-8.5.79/bin/startup.sh && tail -F /usr/local/apache-tomcat-8.5.79/bin/logs/catalina.out

2、建镜像
# 官方名字因此不用指定Dockerfile
docker build -t mytomcat .
3、启动镜像
# 启动自己的镜像 映射端口 挂载目录
docker run -d --name yugetomcat -p 8090:8080 -v /home/volume/tomcat/project:/usr/localapache-tomcat-8.5.79/webapps/ -v /home/volume/tomcat/logs:/usr/localapache-tomcat-8.5.79/logs mytomcat:latest
4、检查下
docker exec -it id /bin/bash
# 使用 ls 命令发现当前路径就是我们再 Dockerfile中指定的WORKDIR
# 可以浏览器访问tomcat了

发布镜像到Dockerhub

# 肯定要注册自己的DockerHub账号的,然后直接在服务器上提交就好
# docker登录
docker login -u 你的名字 -p 你的密码
# 提交hub
docker push 我得镜像名:1.0

发布到阿里云镜像hub

# 发布
登录阿里云
创建命名空间
创建镜像仓库
然后访问看教程就好了

docker网络

容器没有ping命令的话,可以进入容器内部进行更新

apt-get update
apt install iputils-ping

docker0

[root@iZ2zec82iqaelrhwpp07m4Z project]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo      # 本机回环地址
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:16:3e:0a:00:f2 brd ff:ff:ff:ff:ff:ff
    inet 172.25.88.13/20 brd 172.25.95.255 scope global dynamic eth0
       valid_lft 311155183sec preferred_lft 311155183sec
       # 172.25.88.13 阿里云内网地址
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 02:42:a5:c9:fa:a2 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
       # 172.17.0.1  docker0地址,可以当成路由器地址,安装docker后就会生成一个
# 启动一个容器后,再看网络信息
[root@iZ2zec82iqaelrhwpp07m4Z project]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:16:3e:0a:00:f2 brd ff:ff:ff:ff:ff:ff
    inet 172.25.88.13/20 brd 172.25.95.255 scope global dynamic eth0
       valid_lft 311153432sec preferred_lft 311153432sec
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:a5:c9:fa:a2 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
       # 这个113 112 就是新启动的容器的一对网卡(容器的网卡是成对出现的)veth-pair技术:虚拟接口
113: veth754988b@if112: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether 32:93:98:ac:e6:f5 brd ff:ff:ff:ff:ff:ff link-netnsid 0

evth-pair 作为主机与容器的通信桥梁,连接各种虚拟设备

# 查看容器ip   networks
docker inspect tomcat01 
# 因为版本问题 下面这条命令可能无法执行
docker exec -it tomcat01 ping 容器ip

主机与容器之间可以ping通,容器容器之间也可以ping通(通过主机docker),安装docker后相当于安装了一个路由器,每启动一个容器,就会分配一个ip,所以都可以互通(veth-pair技术)。

# tomcat03 link 上 tomcat01
docker run -it --name tomcat03 --link tomcat01 /bin/bash
# 查看docker网络
docker netwokr ls
docekr inspect id
# 进入容器查看容器 网络绑定信息
# 上面我们用tomcat03 link了 tomcat01
docker exec -it tomcat03 cat /etc/hosts
docker exec -it tomcat03 /bin/bash
cat /etc/hosts
127.0.0.1       localhost   
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2      tomcat01 6e92e69b7491   # 这就是绑定的tomcat01
172.17.0.4      ef32788a846e   # 这个是docker分配给容器的虚拟ip
# 这时在容器里面ping tomcat01 就可以通了
root@ef32788a846e:/usr/local/tomcat# ping tomcat01
bash: ping: command not found    # 没有ping的命令,请自行百度处理

link本质:host映射,已经不建议使用了;使用自定义网络,不适用docker0,因为他不支持容器名访问。

自定义网络

使用桥接模式网络 bridge

docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
384a4e3961b5   bridge    bridge    local
a5bbb4302ec2   host      host      local
573ce6bbbe7a   none      null      local
# 我们正常的启动容器时,没有指定网络,其实是有默认使用docker0的(无法访问域名)
# 下面这俩相等
docker run -it tomcat01 tomcat /bin/bash
docker run -it tomcat01 --net bridge tomcat /bin/bash

创建网络

# 创建
docker network create --help
# --driver bridge   桥接网络
# --subnet 192.168.0.0/16  子网掩码、数量  下面可以绑定网络为 192.168.0.2 到 192.168.255.255 好多个
# --gateway 192.168.0.1 网关ip
# mynet 随便起的网络名称
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet

将tomcat发布在自己建立的网络中

# 指定网络,不适用默认网络
docker run -it -d --name tomcat01 --net mynet tomcat /bin/bash
docker run -it -d --name tomcat02 --net mynet tomcat /bin/bash
docker inspect mynet
docker exec -it tomcat01 ping tomcat02 是可以ping的通的
# 现在就不需要进行--link了,就可以容器之间相互ping了,只要在同一网络下
# 不在同一个网络下,ping 不通的
docker network create --driver bridge --subnet 192.167.0.0/16 --gateway 192.168.0.1 mynet2
docker run -it -d --name tomcat03 --net mynet2 tomcat /bin/bash
# 用mynet的容器去ping mynet2的容器 是ping不通的
docker exec -it tomcat01 ping tomcat03  不通

docker网络互通

不通网络间,我们通常把redis集群放在一个网络,mysql集群放在一个网络,分网络管理;

但是这样会导致redis无法访问mysql,因此需要进行网络打通 --connect

# 我现在有两个网络mynet、mynet2
# mynet上面有tomcat01 ,mynet2上面有tomcat03
# 网络打通
docker network connect mynet2 tomcat01  # 然后再用tomcat01 ping tomcat03  就可以了
# 将tomcat01放到了mynet2网络中了

网络打通后看看网络怎么变成什么了

docker inspect tomcat01
# docker inspect mynet2
# 展示
  "Networks": {
                "mynet": {  # 原tomcat01属于mynet网络的
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": [
                        "a537269d7dd8"
                    ],
                    "NetworkID": "a4275f1352244bb68b9e8d70ecc9f581a929b14bb4488c423229ac0e2eb02163",
                    "EndpointID": "43c2760be9aedb01603b6e4b69a0c4bc2586545754aa61008d8374cb887506ba",
                    "Gateway": "192.168.0.1",
                    "IPAddress": "192.168.0.2",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:c0:a8:00:02",
                    "DriverOpts": null
                },
                "mynet2": {    # 现在tomcat01 也存在mynet2中了
                    "IPAMConfig": {},
                    "Links": null,
                    "Aliases": [
                        "a537269d7dd8"
                    ],
                    "NetworkID": "733c3cd12346a201865c6dc3daf10b83e349e499364b695a7960b56f3f80b180",
                    "EndpointID": "474cb493b396b68f3409e1a48b8ee01b4ae99b856b038265c54bfc96317d880f",
                    "Gateway": "192.167.0.1",
                    "IPAddress": "192.167.0.3",  # 并且占用了mynet2中的一个ip 
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:c0:a7:00:03",
                    "DriverOpts": {}
                }

现在tomcat01存在了两个ip,mynet中一个,mynet2中一个;

一个容器多个ip;

针对容器与网络,多个容器需要挨个打通;

docker compose

管理多容器的工具,不需要每个容器都单独的构建启动。

根据配置文件进行批量容器编排。

1、需要一个Dockerfile文件

2、docker-compose.yml文件

3、启动、停止项目

安装compose

# 官网下载
 curl -SL https://github.com/docker/compose/releases/download/v2.6.0/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose
# 官网地址下载太慢,可以考虑百度下搜索别的

# 授权
chmod 777 docker-compose
# 测试,显示版本号就安装成功了
docker-compose version

官网简单实现测试

https://docs.docker.com/compose/gettingstarted/

1、创建目录
 mkdir composetest
2、创建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)
3、创建另一个名为的文件requirements.txt
flask
redis
4、创建Dockerfile
  • 从 Python 3.7 映像开始构建映像。
  • 将工作目录设置为/code.
  • 设置命令使用的环境变量flask
  • 安装 gcc 和其他依赖项
  • 复制requirements.txt并安装 Python 依赖项。
  • 向镜像添加元数据以描述容器正在侦听端口 5000
  • 将项目中的当前目录复制.到镜像中的workdir .
  • 将容器的默认命令设置为flask run.
# syntax=docker/dockerfile:1
FROM python:3.7-alpine
WORKDIR /code
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
EXPOSE 5000
COPY . .
CMD ["flask", "run"]
5、在 Compose 文件中定义服务、创建一个名为的文件docker-compose.yml

后缀名为 .yaml 更规范,优先级更高

version: "3.9"    # 声明版本
services:         # 服务
  web:            # 服务一
    build: .      # 这个'.'表示需要根据同目录下的Dockerfile文件自己构建镜像
    ports:
      - "8000:5000"   # 端口映射
  redis:          # 服务二
    image: "redis:alpine" # 从官方拿精简版镜像

这个 Compose 文件定义了两个服务:webredis.

该服务使用从当前目录中web构建的图像。Dockerfile然后它将容器和主机绑定到暴露的端口,8000. 此示例服务使用 Flask Web 服务器的默认端口,5000.

redis服务使用 从 Docker Hub 注册表中提取的公共Redis映像。

6、使用 Compose 构建并运行您的应用程序
# 通过compose启动,会生成自己的网络,可以瞧瞧 docker network ls
docker-compose up
7、测试
# 启动成功后测试下,调的通就行
curl localhost:8000
# 关闭服务
docker-compose stop
# 后台启动
docker-compose up -d
8、网络的高可用

docker network ls

 "Containers": {
            "72d014f5ad025c11ac8a4e4438457668cd56577b5987a927fcc1dba7ddc0e883": {
                "Name": "composetest-redis-1",
                "EndpointID": "2bb814aaf216f658d4a7bb221c9e79b6886031267ca0de7495383a50c27ebad7",
                "MacAddress": "02:42:ac:12:00:02",
                "IPv4Address": "172.18.0.2/16",
                "IPv6Address": ""
            },
            "fe544716c7e2cb00272cf75abeb4c56b5e4b28e023028347b3f41a1d6e2ffa0d": {
                "Name": "composetest-web-1",
                "EndpointID": "f3c7a815b50f493f15fbc9030ebbd5d1db7bbcdcbd88c4a4dba99dd3d04502a7",
                "MacAddress": "02:42:ac:12:00:03",
                "IPv4Address": "172.18.0.3/16",
                "IPv6Address": ""
            }
        },

通过compose启动的容器,全部在同一个网络下,因此各个容器间可以直接通过 域名:端口 进行访问,

比如访问redis, 就可以 'redis:6379' 即可

docker-compose 命令必须在docker-compose.yml 同级目录使用

优点:一个命令启动、停止配置文件内的所有容器;

docker-compose.yml编写规则核心

官方文档(太多了):https://docs.docker.com/compose/compose-file/

CSDN大佬:https://blog.csdn.net/huangjinjin520/article/details/124054043

# 主要三层
1.version:      # compose版本,与docker版本是向下兼容的,推荐使用最新的版本,当然docker也是最新版本优先
2.services:     # 应用服务信息,即镜像容器相关(第三层都是第二层指向过去的)
3.networks:     # 网络配置
  volumes:      # 挂载卷配置
  configs:      # 用来配置每个服务的方位config的权限
  secrets:      # 对每个数据授予对保密数据的访问权限
  ...
使用docker官方提供的wordpress博客简易测试

官方提供:https://docs.docker.com/samples/wordpress/

1、创建一个空文件夹

mkdir mywordpress

2、创建docker-compose.yaml文件

version: "3.9"   # 使用3.9版本compose
    
services:			# 服务应用
  db:                                     # 数据库
    image: mysql:5.7                      # 镜像版本
    volumes:   
      - db_data:/var/lib/mysql            # 挂载卷
    restart: always
    environment:                          # 环境设置
      MYSQL_ROOT_PASSWORD: somewordpress  # 设置root用户密码
      MYSQL_DATABASE: wordpress           # 数据库名称
      MYSQL_USER: wordpress				  # 数据库用户
      MYSQL_PASSWORD: wordpress           # 数据库密码
    
  wordpress:                              # 应用                     
    depends_on:                           # 依赖
      - db                                # 依赖db,启动本应用之前会先去启动db服务
    image: wordpress:latest               # 镜像
    volumes:
      - wordpress_data:/var/www/html      # 卷
    ports:
      - "8000:80"                         # 映射暴露端口
    restart: always
    environment:
      WORDPRESS_DB_HOST: db               # 指向域名:因为docker-compose启动的服务都在同一个网络下面
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WORDPRESS_DB_NAME: wordpress
volumes:
  db_data: {}
  wordpress_data: {}


3、后台启动

docker-compose up -d

4、over

总结

1、我们需要一个应用,此例中的app.py

2、需要一个Dockerfile 文件用打包应用、构建镜像

3、需要一个Docerk-compose.yml文件定义整个服务,环境

4、docker-compose up 启动项目

docker swarm

集群部署

搭建集群

1、一台服务器init,初始化一个集群主机;

2、这个集群主机提供 manager token、worker token;

3、其他manager、worker服务器通过token加入集群;

# 集群的几个服务器互相网络相同,同一个子节点下,(我试了下ping通了,但是docker集群无法搭建)
# 首先生成一个集群的主节点(定义集群的开始) - 本机的ip
docker swarm init --advertise-addr 172.17.***.***

[root@iZ7xva6bpev0ngkpysg7l1Z ~]# docker swarm init --advertise-addr 172.17.***.***
Swarm initialized: current node (h00kcv542j0rrtl44cdod976n) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join --token SWMTKN-1-0jeioqc0ll53saqzwf0a4pj8if1lwwqxecdi3vsrddnr2o5e9x-df8uusesyt9vnar6mck1v3jsj 172.17.***.***:2377    # 这一行是加入集群的命令

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

# 集群搭建好了,在主机上查看加入集群的命令
# 作为manager 主机 加入集群,在主机上输入命令
docker swarm join-token manager
   会得到这个,把这个拿到另一台服务器上输入  docker swarm join --token SWMTKN-1-1rz3ji6sge1ohdfu0pxcvurheh1ynsteq9s6qwsyu80wnj9tqz-5baejzdodessul4npylyw5b9t 172.27.**.*:2377
# 作为worker 从机 加入集群,在主机上输入命令
docker swarm join-token worker  # 步骤同上
# 查看集群情况,这条命令只能在manager机器上输入
docker node ls
[root@iZ7xva6bpev0nh2bbplvx6Z ~]# docker node ls
ID                            HOSTNAME                  STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
bbg6lw6nsvgnd9bsqu0865ufl *   iZ7xva6bpev0nh2bbplvx6Z   Ready     Active         Leader           20.10.17
3n2fvd3vjp0hpp4yelz4fpdlg     iZ7xva6bpev0nh2bbplvx7Z   Ready     Active                          20.10.17
hwedxd44se9ypj4no5betn4kv     iZ7xva6bpev0nh2bbplvx8Z   Ready     Active                          20.10.17
qk8d9xwj0qu8h6kmardsy3c0m     iZ7xva6bpev0nh2bbplvx9Z   Ready     Active         Reachable        20.10.17
# Leader 表示是集群的第一台机器,肯定是manager机器了
# Ranchable 表示是其他的manager机器
# 空白的就是 worker 从机了

双主双从不符合Raft协议。这里学习使用为了省钱。流量也挺贵的;

Raft协议

docker集群采用的Raft协议:一致性协议

保证大多数节点可以存活。如果只有两个节点,则挂了一个,另外一个无法通过选举上位,因此需要保证节点至少有三个。

# 尝试
# 关掉一个manager
systemctl stop docker
# 然后去另一个manager上查看会发现
[root@iZ7xva6bpev0nh2bbplvx6Z ~]# docker node ls
Error response from daemon: rpc error: code = DeadlineExceeded desc = context deadline exceeded
# 无法显示集群信息了,崩了,因为两个manager,挂了一个,另一个无法通过Raft协议选举
systemctl start docker 
docker node ls
ID                            HOSTNAME                  STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
bbg6lw6nsvgnd9bsqu0865ufl *   iZ7xva6bpev0nh2bbplvx6Z   Ready     Active         Reachable        20.10.17
3n2fvd3vjp0hpp4yelz4fpdlg     iZ7xva6bpev0nh2bbplvx7Z   Ready     Active                          20.10.17
hwedxd44se9ypj4no5betn4kv     iZ7xva6bpev0nh2bbplvx8Z   Ready     Active                          20.10.17
qk8d9xwj0qu8h6kmardsy3c0m     iZ7xva6bpev0nh2bbplvx9Z   Ready     Active         Leader           20.10.17
# docker重启后,自动加入集群,会发现,原来如果是Leader机器变成了Reachable机器了


# 不要在你关掉docker的manager机器上测试,他会找一会找不到,然后把你关掉的docker又启动回来了
# 从机worker 退出集群(从机退出不影响)
docker swarm leave
# 然后退出的这台机器已主机身份加入
# 再退出一台manager主机,就不会影响其他了,因为三台主机退出一个还剩两个,能进行选举
# 三主一从 good
[root@iZ7xva6bpev0nh2bbplvx7Z ~]# docker node ls
ID                            HOSTNAME                  STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
bbg6lw6nsvgnd9bsqu0865ufl     iZ7xva6bpev0nh2bbplvx6Z   Unknown   Active         Unreachable      20.10.17
3n2fvd3vjp0hpp4yelz4fpdlg     iZ7xva6bpev0nh2bbplvx7Z   Down      Active                          20.10.17
xil6ct9l4i86qhq1qqeomnrl5 *   iZ7xva6bpev0nh2bbplvx7Z   Unknown   Active         Leader           20.10.17
hwedxd44se9ypj4no5betn4kv     iZ7xva6bpev0nh2bbplvx8Z   Unknown   Active                          20.10.17
qk8d9xwj0qu8h6kmardsy3c0m     iZ7xva6bpev0nh2bbplvx9Z   Unknown   Active         Reachable        20.10.17

部署应用

# 启动一个nginx服务
docker service create -p 8008:80 --name mynginx nginx
# 很多类似service的命令只能在manager机器上使用
# 查看service服务全部
docker service ls
[root@iZ7xva6bpev0nh2bbplvx6Z ~]# docker service ls 
ID             NAME      MODE         REPLICAS   IMAGE          PORTS
3oit4v5r9wbd   mynginx   replicated   1/1        nginx:latest   *:8008->80/tcp
                                      只启动了一个服务
# 查看mynginx具体信息
docker service ps mynginx
[root@iZ7xva6bpev0nh2bbplvx6Z ~]# docker service ps mynginx
ID             NAME        IMAGE          NODE                      DESIRED STATE   CURRENT STATE           ERROR     PORTS
x3katk4qbk8g   mynginx.1   nginx:latest   iZ7xva6bpev0nh2bbplvx9Z   Running         Running 9 minutes ago        
                                          服务启动在这个机器上
                                          
# docker service 是集群命令,在每个manager机器上都能看到服务信息
# docker ps      是单机命令,只能在有启动服务的机器上才能看到服务信息

服务扩缩容

动态的将服务进行增加或减少

# 将我们的mynginx服务 创建10个
docker service update --replicas 10 mynginx
[root@iZ7xva6bpev0nh2bbplvx9Z ~]# docker service ls
ID             NAME      MODE         REPLICAS   IMAGE          PORTS
3oit4v5r9wbd   mynginx   replicated   10/10      nginx:latest   *:8008->80/tcp
                                      已启动了10个服务
# 查看发现均匀分布在集群的几个服务器上
docker ps
[root@iZ7xva6bpev0nh2bbplvx6Z ~]# docker service ps mynginx
ID             NAME         IMAGE          NODE                      DESIRED STATE   CURRENT STATE                ERROR     PORTS
x3katk4qbk8g   mynginx.1    nginx:latest   iZ7xva6bpev0nh2bbplvx9Z   Running         Running 17 minutes ago                 
twupl8i58obw   mynginx.2    nginx:latest   iZ7xva6bpev0nh2bbplvx6Z   Running         Running about a minute ago             
k1jf7m1gbvph   mynginx.3    nginx:latest   iZ7xva6bpev0nh2bbplvx8Z   Running         Running about a minute ago             
ybkedu9xqujl   mynginx.4    nginx:latest   iZ7xva6bpev0nh2bbplvx9Z   Running         Running 2 minutes ago                  
87ug7vpy1seb   mynginx.5    nginx:latest   iZ7xva6bpev0nh2bbplvx9Z   Running         Running 2 minutes ago                  
zxonfugqmdge   mynginx.6    nginx:latest   iZ7xva6bpev0nh2bbplvx7Z   Running         Running about a minute ago             
vfjfrhstd52t   mynginx.7    nginx:latest   iZ7xva6bpev0nh2bbplvx7Z   Running         Running about a minute ago             
87rlt010i0m4   mynginx.8    nginx:latest   iZ7xva6bpev0nh2bbplvx8Z   Running         Running about a minute ago             
gfmaeq6hqtoc   mynginx.9    nginx:latest   iZ7xva6bpev0nh2bbplvx6Z   Running         Running about a minute ago             
m174oisn2wj5   mynginx.10   nginx:latest   iZ7xva6bpev0nh2bbplvx7Z   Running         Running about a minute ago  

docker service scale 命令和 docker service update 是一样的

# docker service update --replicas 1 mynginx
docker service scale mynginx=1

集群命令只能在manager机器上执行,无法再worker机器上执行

docker run             # 单机命令
docker service create  # 集群命令
docker ps              # 单机命令
docker service ps      # 集群命令
# 移除删除
docker service rm mynginx

Docker Stack

Docker 适用于开发和测试。Docker Stack 则适用于大规模场景和生产环境。

在 Compose 文件中定义应用,然后通过 docker stack deploy 命令完成部署和管理。

Dokcer Secret

Docker Config

k8s

标签:容器,00,run,入门,--,镜像,docker
来源: https://www.cnblogs.com/xy20211005/p/16482876.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有