首页 > 其他分享 >docker基础

docker基础

时间:2022-11-22 13:22:08浏览次数:64  
标签:容器 -- 基础 redis 镜像 docker root

推荐教程:https://www.bilibili.com/video/BV1og4y1q7M4?spm_id_from=333.999.0.0&vd_source=642a988fd50073c667fec7829ca79103
Docker技术入门与实战-第3版.pdf

dokecr为什么会出现?

一款产品:开发--上线 开发环境 应用环境 应用配置
开发........运维 。 问题 :我在我的电脑上可以运行!版本更新,导致服务不可用!对于运维人员的考核压力大。
环境的配置十分麻烦,每一个机器都要环境配置(集群Reds、ES、Hadoop),费时费力。

发布一个项目(jar +(Reds、Mysql、jdk、ES)),实现项目环境的安装打包.。实现环境的跨平台,简化配置

传统方式:

  • 传统 开发jar 运维来做
  • 开发打包上线 一套流程

java --apk --发布(应用商店) ----用户使用应用 ------安装即可使用
java ---jar(环境) ---打包项目带线上环境 --(Docker仓库 、应用商店) ----下载即可使用

Docker给以上问题的,提出了相关的解决方案

image.png
Docker的思想来源于集装箱
JRE ...多个应用(端口冲突) --原来是交叉的
:::tips
隔离: docker核心思想;打包装箱;每个箱子都是相互隔离的
dokcer通过隔离技术,将服务器利用到极致
:::

Docker的历史

2010年 几个搞it的年轻人,就在美国成立了一家公司dotcloud,做一些pass的云计算服务,LXC相关的技术,将容器化进行了统一的简化命名docker
dokcer 刚刚诞生的时候,没有引起行业的注意,dotcloud的活不下去,进行源代码的开放

2013年,docker开源,越来越多人发现docker的优点,docker每个月都会更新一个版本。

2014年4月9日,docker 1.0 发布 ,解决了通过软件虚拟化一台或多台设备臃肿、笨重的问题,
docker容器技术也属于虚拟技术

linux centos系统镜像(一个电脑) 隔离,需要多个虚拟机,几个G,几分钟
docker,隔离,镜像(最核心的镜像),十分小巧,运行镜像就可以了,秒级启动

docker基于GO语言开发,开源项目
官网:https://www.docker.com/
image.png
官方文档网址:https://docs.docker.com/
docker仓库:https://www.docker.com/products/docker-hub/

docker能干嘛

传统虚拟机技术
image.png
虚拟机技术缺点:

  1. 资源占用多
  2. 冗余过多
  3. 启动慢

容器化技术
image.png
比较docker和虚拟机的不同

  • 传统的虚拟机,虚拟出一个硬件,然后在系统上运行软件
  • 容器内的应用直接运行在宿主机上的内容,也没有虚拟化硬件,所以轻便了
  • 每个容器之间是相互隔离的,每个容器内都有自己的文件系统,互不影响

devops(开发、运维)

更快速的交付和部署,
传统:堆帮助文档、安装程序
docker:打包镜像发布测试、一键运行

更快捷的升级和扩容
使用了 docker之后,应用部署和搭积木一样,项目打包为一个镜像、扩展服务器A 服务器B

更简单的系统运维
在容器化之后,开发和测试环境都是高度一致的

更高效的计算机资源利用
docker是内核的虚拟化,可以在一个物理机上运行多个实例,服务器的性能发挥到机制

docker的安装

docker的组成

image.png
镜像:(image)
docker 的镜像就好比是一个模板,可以通过模板来创建容器的服务,
tomcat镜像--->run--->tomcat01容器(提供服务器),通过这个镜像可创建多个容器(最终服务运行或者项目运行就是容器中的)

容器:(container)
docker利用容器技术,独立运行一个或者多个应用,通过镜像来创建的。
启动、停止、删除、基本命令
目前可以把这个容器理解为一个简易的linux系统
仓库:(rpositroy)
仓库就是来存放镜像的地方
仓库分为共有仓库和私有仓库
Docker--hub
阿里云......都有容器服务(配置镜像加速)

Docker的安装

系统内核的查看

[root@localhost ~]# uname -r
4.18.0-147.el8.x86_64
#系统内核为3.0或者以上
[root@localhost ~]# cat /etc/os-release
NAME="Red Hat Enterprise Linux"
VERSION="8.1 (Ootpa)"
ID="rhel"
ID_LIKE="fedora"
VERSION_ID="8.1"
PLATFORM_ID="platform:el8"
PRETTY_NAME="Red Hat Enterprise Linux 8.1 (Ootpa)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:redhat:enterprise_linux:8.1:GA"
HOME_URL="https://www.redhat.com/"
BUG_REPORT_URL="https://bugzilla.redhat.com/"

REDHAT_BUGZILLA_PRODUCT="Red Hat Enterprise Linux 8"
REDHAT_BUGZILLA_PRODUCT_VERSION=8.1
REDHAT_SUPPORT_PRODUCT="Red Hat Enterprise Linux"
REDHAT_SUPPORT_PRODUCT_VERSION="8.1"

安装
帮助文档:https://docs.docker.com/engine/install/centos/
1.卸载旧版本

sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

2.设置存储库

 sudo yum install -y yum-utils
 
 sudo 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

3.安装docker引擎

sudo yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin

4.启动docker

 sudo systemctl start docker
  1. 测试
docker version

docker run hello-world

6.查看镜像

docker images

7.卸载docker

1.卸载依赖
yum remove docker-ce docker-ce-cli containerd.io docker-compose-plugin
2.卸载资源
sudo rm -rf /var/lib/docker
 sudo rm -rf /var/lib/containerd
 #/var/lib/docker   默认工作路径

阿里云加速

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://xxxxxx.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

回顾hello wrold

image.png

image.png

底层原理

docker是怎么工作的
docker 是一个client -server结构的系统,docker的守护进程运行在主机上, 通过socket客户端访问。
docker -server 接收到 docker -client的指令,进行执行
image.png
docker为什么比vm快
1.docker有着比虚拟机少的抽象层
2.docker利用的是主机的内核,vm是centos
image.png
所以在新建一个容器的时候,docker不需要和虚拟机一样加载一个操作系统的内核,避免引导,虚拟机加载centos分钟级别,而docker是利用主机的内核,为秒级别。
image.png

docker的常用命令

帮助命令

docker version #显示docker的版本信息
docker info#显示docker的系统的详细信息
docker  命令   ---help  #帮助命令

帮助文档的地址:https://docs.docker.com/reference/

镜像命令

docker images 查看镜像

[root@localhost ~]# docker images
REPOSITORY    TAG            IMAGE ID       CREATED        SIZE
alpine        xiaowangc1.0   b5226f57471e   3 weeks ago    249MB
alpine        latest         e66264b98777   8 weeks ago    5.53MB
hello-world   latest         feb5d9fea6a5   9 months ago   13.3kB
#解释
REPOSITORY   仓库名称  
TAG   仓库标签
IMAGE ID   仓库ID
CREATED    镜像的创建的时间
SIZE      镜像的大小

#可选项
-a, --all              #列出所有镜像 
 -q, --quiet           #只显示ID


docker search搜索命令

[root@localhost ~]# docker search mysql
NAME                DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
mysql        MySQL is a widely used, open-source relation…   12887     [OK]
mariadb     MariaDB Server is a high performing open sou…   4942      [OK]

# --filter 筛选条件
   --filter =STARS=3000 #筛选出stars值在3000以上的
   

dokcer pull 下载镜像

#下载 镜像  docker pull 镜像名称 [:tag]
[root@localhost ~]# docker pull mysql
Using default tag: latest    #如果不写tag,默认为latset
latest: Pulling from library/mysql
72a69066d2fe: Pull complete  #分层下载
93619dbc5b36: Pull complete
99da31dd6142: Pull complete
626033c43d70: Pull complete
37d5d7efb64e: Pull complete
ac563158d721: Pull complete
d2ba16033dad: Pull complete
688ba7d5c01a: Pull complete
00e060b6d11d: Pull complete
1c04857f594f: Pull complete
4d7cfa90e6ea: Pull complete
e0431212d27d: Pull complete
Digest: sha256:e9027fe4d91c0153429607251656806cc784e914937271037f7738bd5b8e7709#签名
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest  #真实地址
[root@localhost ~]# docker pull mysql:5.7  #指定mysql 5.7版本下载

5.7: Pulling from library/mysql
72a69066d2fe: Already exists
93619dbc5b36: Already exists
99da31dd6142: Already exists
626033c43d70: Already exists
37d5d7efb64e: Already exists
ac563158d721: Already exists
d2ba16033dad: Already exists
0ceb82207cd7: Pull complete
37f2405cae96: Pull complete
e2482e017e53: Pull complete
70deed891d42: Pull complete
Digest: sha256:f2ad209efe9c67104167fc609cca6973c8422939491c9345270175a300419f94
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7

image.png
docker rmi 删除镜像

[root@localhost ~]# docker rmi -f  镜像ID    目标指定镜像
[root@localhost ~]# docker rmi -f  镜像 ID   容器ID     删除多个镜像
[root@localhost ~]# docker rmi -f  $(docker images -aq)    删除所有

容器命令

下载一个linux镜像进行学习

docker pull  centos

新建容器并启动

docker run [可选参数]  images
#参数说明
--name="name" 容器的名字    区分容器
-d     在后台运行
-it       交互方式运行
-P(大写)  指定容器的端口   -p:8080
     -p  ip:主机端口:容器端口
     -p 主机端口:容器端口(常用的)
     -p  容器端口
    容器端口
 -p   随机指定端口
#测试    #启动并进入容器
[root@localhost ~]# docker run -it centos /bin/bash   
[root@3ab4dbba43a0 /]# ls  #查看内部的centos    很多命令不完善
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@3ab4dbba43a0 /]# exit     #退出容器

列出所有运行的容器

#docker ps命令
-a     列出历史运行过的容器
-n= ?  显示最近创建的容器
-q    只显示容器编号


[root@localhost ~]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
[root@localhost ~]# docker ps -a
CONTAINER ID   IMAGE         COMMAND       CREATED             STATUS                         PORTS     NAMES
3ab4dbba43a0   centos        "/bin/bash"   3 minutes ago       Exited (0) 59 seconds ago                intelligent_euclid
9484d4fa30c5   hello-world   "/hello"      About an hour ago   Exited (0) About an hour ago             strange_cori

退出容器

exit   直接退出
ctrl +p +q #容器不停止退出

删除容器

docker  rm  容器id    #删除指定容器,删除正在运行的容器需要带-f
docker rm -f $(docker ps -aq)   删除所有容器
docker ps -a|xargs docker rm   #删除所有的 容器

启动和停止容器的操作

docker start   容器id  #启动容器
docker restart  容器id #重启容器
docker stop  容器id     #停止容器
docker  kill   容器id    #强制停止容器

常用的其他命令

后台启动容器

#docker run  d  镜像名称

[root@localhost ~]# docker run -d centos

#问题   ps    发现 centos 停止了

#容器使用后台运行,必须要有一个前台执行程序,docker发现没有可用程序
就会进行停止。

查看日志命令

docker logs -f  -t -tail   容器没有日志
#编写一个脚本
[root@localhost ~]# docker run -d centos /bin/sh -c "while true;do echo yutoujun;sleep 1;done

#[root@localhost ~]# docker ps
CONTAINER ID   IMAGE     COMMAND
43bddbf6340d   centos
#显示日志  
-tf
--tail  number  指定条数
[root@localhost ~]# docker logs -tf --tail 10 43bddbf6340d

查看进程信息

#命令:docker top  容器id
[root@localhost ~]# docker top  43bddbf6340d
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                4439                4421                0                   18:07               ?                   00:00:00            /bin/sh -c while true;do echo yutoujun;sleep 1;done
root                4761                4439                0                   18:12               ?                   00:00:00            /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1
 docker inspect  容器id
[root@localhost ~]# docker inspect 43bddbf6340d
[
    {
        "Id": "43bddbf6340dc19fe749d94cd0737c9443da83b140dce6e436340015bda30114",
        "Created": "2022-07-19T10:08:00.411361034Z",
        "Path": "/bin/sh",
        "Args": [
            "-c",
            "while true;do echo yutoujun;sleep 1;done"
        ],
     ...........................

当前正在运行的容器

#容器通常都是以后台的方式运行,需要进入容器,修改一些配置
docker exec -it 容器id bashshell
#测试
[root@localhost ~]# docker exec -it 43bddbf6340d bash
[root@43bddbf6340d /]# ps -ef
UID         PID   PPID  C STIME TTY          TIME CMD
root          1      0  0 10:07 ?        00:00:00 /bin/sh -c while true;do echo yutoujun;sleep 1;done
root       2471      0  1 10:49 pts/0    00:00:00 bash
root       2491      1  0 10:49 ?        00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1
root       2492   2471  0 10:49 pts/0    00:00:00 ps -ef

#方式2
docker attach 容器id 
#测试
[root@localhost ~]docker attach  43bddbf6340d
正在执行代码.....

#docker exec #开启一个新的终端,可以在里边进行操作
#docker attach    #进入正在执行的终端,不会开启新的进程

从容器拷贝文件到主机上

docker cp 容器id:容器内路径  主机路径
#查看当前主机目录
[root@localhost home]# ls
yutoujun.txt
[root@localhost home]# docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED          STATUS          PORTS     NAMES
bf93c08ffbfd   centos    "/bin/bash"   22 seconds ago   Up 21 seconds             laughing_mestorf
#进入容器内部
[root@localhost home]# docker attach bf93c08ffbfd
[root@bf93c08ffbfd /]# cd /home
[root@bf93c08ffbfd home]# ls
#新建一个文件
[root@bf93c08ffbfd home]# touch test.txt
[root@bf93c08ffbfd home]# exit
exit
#退出进行文件拷贝
[root@localhost home]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
[root@localhost home]# docker cp bf93c08ffbfd:/home/test.txt  /home
[root@localhost home]# ls
test.txt  yutoujun.txt
#拷贝是手动过程,后边会使用卷的技术进行自动同步

小结

docker.png

attach    Attach to a running container  #当前shell下attach连接指定运行镜像
build     Build an image from a Dockerfile  #通过Dockerfile定制镜像
commit    Create a new image from a container's changes  #提交当前容器为新的镜像
cp    Copy files/folders from a container to a HOSTDIR or to STDOUT  #从容器中拷贝指定文件或者目录到宿主机中
create    Create a new container  #创建一个新的容器,同run 但不启动容器
diff    Inspect changes on a container's filesystem  #查看docker容器变化
events    Get real time events from the server#从docker服务获取容器实时事件
exec    Run a command in a running container#在已存在的容器上运行命令
export    Export a container's filesystem as a tar archive  #导出容器的内容流作为一个tar归档文件(对应import)
history    Show the history of an image  #展示一个镜像形成历史
images    List images  #列出系统当前镜像
import    Import the contents from a tarball to create a filesystem image  #从tar包中的内容创建一个新的文件系统映像(对应export)
info    Display system-wide information  #显示系统相关信息
inspect    Return low-level information on a container or image  #查看容器详细信息
kill    Kill a running container  #kill指定docker容器
load    Load an image from a tar archive or STDIN  #从一个tar包中加载一个镜像(对应save)
login    Register or log in to a Docker registry#注册或者登陆一个docker源服务器
logout    Log out from a Docker registry  #从当前Docker registry退出
logs    Fetch the logs of a container  #输出当前容器日志信息
pause    Pause all processes within a container#暂停容器
port    List port mappings or a specific mapping for the CONTAINER  #查看映射端口对应的容器内部源端口
ps    List containers  #列出容器列表
pull    Pull an image or a repository from a registry  #从docker镜像源服务器拉取指定镜像或者库镜像
push    Push an image or a repository to a registry  #推送指定镜像或者库镜像至docker源服务器
rename    Rename a container  #重命名容器
restart    Restart a running container  #重启运行的容器
rm    Remove one or more containers  #移除一个或者多个容器
rmi    Remove one or more images  #移除一个或多个镜像(无容器使用该镜像才可以删除,否则需要删除相关容器才可以继续或者-f强制删除)
run    Run a command in a new container  #创建一个新的容器并运行一个命令
save    Save an image(s) to a tar archive#保存一个镜像为一个tar包(对应load)
search    Search the Docker Hub for images  #在docker
hub中搜索镜像
start    Start one or more stopped containers#启动容器
stats    Display a live stream of container(s) resource usage statistics  #统计容器使用资源
stop    Stop a running container  #停止容器
tag         Tag an image into a repository  #给源中镜像打标签
top       Display the running processes of a container #查看容器中运行的进程信息
unpause    Unpause all processes within a container  #取消暂停容器
version    Show the Docker version information#查看容器版本号
wait         Block until a container stops, then print its exit code  #截取容器停止时的退出状态值

练习

nginx

[root@localhost home]# docker search  nginx
[root@localhost home]# docker pull nginx
[root@localhost home]# docker images
REPOSITORY    TAG            IMAGE ID       CREATED         SIZE
alpine        xiaowangc1.0   b5226f57471e   3 weeks ago     249MB
nginx         latest         605c77e624dd   6 months ago    141MB
hello-world   latest         feb5d9fea6a5   9 months ago    13.3kB
centos        latest         5d0da3dc9764   10 months ago   231MB
#-d 后台运行  --name起名字  -p端口设置
[root@localhost home]# docker run -d --name nginx11 -p 3344:80 nginx
c71d3d33d66061c5872fac4d1024a23177511324995d2258fe30987888909923
#查看运行状态
[root@localhost home]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                                   NAMES
c71d3d33d660   nginx     "/docker-entrypoint.…"   3 minutes ago   Up 3 minutes   0.0.0.0:3344->80/tcp, :::3344->80/tcp   nginx11

#进入容器
[root@localhost home]# docker exec -it nginx11 /bin/bash
root@c71d3d33d660:/# whereis nginx
nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
root@c71d3d33d660:/#

端口暴露的概念
image.png

部署tomcat

在docker hub 查看tomcat的版本
https://hub.docker.com/search?q=tomcat

#官方的使用
docker run -it --rm tomcat:9.0
#之前的启动都是后台,停止了容器之后还可以查到
#官方的使用,用完就会删除d
docker run -it --rm
#下载启动
[root@localhost ~]# docker pull tomcat:9.0
#启动测试
[root@localhost ~]# docker run -d -p 3355:8080  --name tomcat01 tomcat
8e7329b4c2769101de8302ddb4a470bf1288aa9ad378b4f86b189aa987f0ab2b
#测试访问没问题

#进入容器
[root@localhost ~]# docker run -it tomcat /bin/bash
root@2bc3bb1e618f:/usr/local/tomcat#

#发现问题  1.linux命令少了   2.没有webapps  原因:镜像原因,默认最小化
很多功能被阉割了,保证最小化运行

:::tips
思考问题:我们以后都要部署项目,如果每次都要进入容器是不是会很麻烦?要是能在容器外部提供一个映射路径,webapps,在外部部署项目,就自动同步就好了??
:::

部署 ES+Kibana

#ES暴露的端口很多
#ES很占用内存
#ES需要放置在安全目录  挂载  

#--name elasticsearch   网络配置

#启动elasticsearch 
 docker run -d --name elasticsearch  -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2
 #启动了,发现整个虚拟机卡顿   docker stats 查看cpu的状态
 #关闭ES 进行内存的限制     
 #通过-e进行内存大小的限制  -e ES_JAVA_OPTS="-Xms64m _Xms512m"
 docker run -d --name elasticsearch02  -p 9200:9200 -p 9300:9300 -e  "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m _Xms512m" elasticsearch:7.6.2 
 

image.png
Kibana的原理:

image.png

可视化

#portainer(先用这个)

docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portain
#Rancher(CI/CD再用)

什么是portainer
docker的一个图形化界面管理工具,提供一个后台进行操作

docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portain
docker volume create portainer_data
docker run -d -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer
cd /usr/libexec/docker/
sudo ln -s docker-runc-current docker-runc

使用http//:ip地址:端口测试

http://192.168.130:9000

进行用户的创建
image.png
选择仓库(建议选择本地的)
image.png
进入之后的面板
image.png
可以清楚的看到本地的容器的一些信息
image.png

可视化面板很少使用

Docker镜像详解

什么是镜像

镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需要的所有内容,包括代码,运行时(一个程序在运行或者在被执行的依赖)、库,环境变量和配置文件。
所有应用,直接打包docker,可以直接运行

Docker镜像加载原理

Docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统是UnionFS联合文件系统。
Docker的镜像实际由一层一层的文件系统组成:

  • bootfs(boot file system)主要包含bootloader和kernel。bootloader主要是引导加载kernel,完成后整个内核就都在内存中了。此时内存的使用权已由bootfs转交给内核,系统卸载bootfs。可以被不同的Linux发行版公用。
  • rootfs(root file system),包含典型Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。rootfs就是各种不同操作系统发行版(Ubuntu,Centos等)。因为底层直接用Host的kernel,rootfs只包含最基本的命令,工具和程序就可以了。
  • 分层理解
    所有的Docker镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层之上,创建新的容器层。
    容器在启动时会在镜像最外层上建立一层可读写的容器层(R/W),而镜像层是只读的(R/O)。

rootfs (root file system),在bootfs之上。包含的就是典型Linux系统中的/dev,/proc, /bin, /etc等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。Rootfs(根文件系统),在引导之上。包含的就是典型linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。Rootfs就是各种不同的操作系统发行版,比如Ubuntu,CentOS等等。
image.png

平时我们安装进虚拟机的CentOS都是好几个G,为什么Docker这里才200M ?
image.png

对于一个精简的oS, rootfs 可以很小,只需要包含最基本的命令,工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供rootfs就可以了。由此可见对于不同的linux发行版, bootfs基本是一致的, rootfs会有差别,因此不同的发行版可以公用bootfs。

分层理解

我们去下载一个镜像,注意下载日志,可以发现是分层进行下载的
image.png

思考∶为什么Docker镜像要采用这种分层的结构呢?

最大的好处,我觉得莫过于是资源共享了!比如有多个镜像都从相同的Base镜像构建而来,那么宿主机只需在磁盘上保留一份base镜像,同时内存中也只需要加载一份base镜像,这样就可以为所有的容器服务了,而且镜像的每一层都可以被共享。

查看镜像分层的方式可以通过docker image inspect命令!

[root@localhost ~]# docker image inspect redis:latest
[
    {
        "Id": "sha256:7614ae9453d1d87e740a2056257a6de7135c84037c367e1fffa92ae922784631",
        "RepoTags": [
            "redis:latest"
        ],
        "RepoDigests": [
            "redis@sha256:db485f2e245b5b3329fdc7eff4eb00f913e09d8feb9ca720788059fdc2ed8339"
        ],
        "Parent": "",
        "Comment": "",
        "Created": "2021-12-21T12:42:49.755107412Z",
        "Container": "13d25f53410417c5220c8dfe8bd49f06abdbcd69faa62a9b877de02464bb04a3",
        "ContainerConfig": {
            "Hostname": "13d25f534104",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "6379/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "GOSU_VERSION=1.12",
                "REDIS_VERSION=6.2.6",
                "REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-6.2.6.tar.gz",
                "REDIS_DOWNLOAD_SHA=5b2b8b7a50111ef395bf1c1d5be11e6e167ac018125055daa8b5c2317ae131ab"
            ],
            "Cmd": [
                "/bin/sh",
                "-c",
                "#(nop) ",
                "CMD [\"redis-server\"]"
            ],
            "Image": "sha256:e093f59d716c95cfce82c676f099b960cc700432ab531388fcedf79932fc81ec",
            "Volumes": {
                "/data": {}
            },
            "WorkingDir": "/data",
            "Entrypoint": [
                "docker-entrypoint.sh"
            ],
            "OnBuild": null,
            "Labels": {}
        },
        "DockerVersion": "20.10.7",
        "Author": "",
        "Config": {
            "Hostname": "",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "6379/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "GOSU_VERSION=1.12",
                "REDIS_VERSION=6.2.6",
                "REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-6.2.6.tar.gz",
                "REDIS_DOWNLOAD_SHA=5b2b8b7a50111ef395bf1c1d5be11e6e167ac018125055daa8b5c2317ae131ab"
            ],
            "Cmd": [
                "redis-server"
            ],
            "Image": "sha256:e093f59d716c95cfce82c676f099b960cc700432ab531388fcedf79932fc81ec",
            "Volumes": {
                "/data": {}
            },
            "WorkingDir": "/data",
            "Entrypoint": [
                "docker-entrypoint.sh"
            ],
            "OnBuild": null,
            "Labels": null
        },
        "Architecture": "amd64",
        "Os": "linux",
        "Size": 112691373,
        "VirtualSize": 112691373,
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/e9108002980c92a086707dd3fdaf92585a359803f62463eec03d44d552432e9e/diff:/var/lib/docker/overlay2/ee41879c2adad89d8e0847e4186d01a39dbaa48c3f71fcd725ca55278ee84c14/diff:/var/lib/docker/overlay2/d48921882961deb5ec301f7877e5a529f094475c25a044240f35957b013e2b9b/diff:/var/lib/docker/overlay2/b699114ebaf4efdba2086f24f289bbd2223f6159811f6d2ddf00f0184030883e/diff:/var/lib/docker/overlay2/3186fbc839e6e7d6ecc565b3378d22494f1ec8ee9454f8335a82883dbf21e450/diff",
                "MergedDir": "/var/lib/docker/overlay2/67146a76f119a87a206599fb753914929ecfd2093f19fa08d8893fbf7c0ee298/merged",
                "UpperDir": "/var/lib/docker/overlay2/67146a76f119a87a206599fb753914929ecfd2093f19fa08d8893fbf7c0ee298/diff",
                "WorkDir": "/var/lib/docker/overlay2/67146a76f119a87a206599fb753914929ecfd2093f19fa08d8893fbf7c0ee298/work"
            },
            "Name": "overlay2"
        },
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:2edcec3590a4ec7f40cf0743c15d78fb39d8326bc029073b41ef9727da6c851f",
                "sha256:9b24afeb7c2f21e50a686ead025823cd2c6e9730c013ca77ad5f115c079b57cb",
                "sha256:4b8e2801e0f956a4220c32e2c8b0a590e6f9bd2420ec65453685246b82766ea1",
                "sha256:529cdb636f61e95ab91a62a51526a84fd7314d6aab0d414040796150b4522372",
                "sha256:9975392591f2777d6bf4d9919ad1b2c9afa12f9a9b4d260f45025ec3cc9b18ed",
                "sha256:8e5669d8329116b8444b9bbb1663dda568ede12d3dbcce950199b582f6e94952"
            ]
        },
        "Metadata": {
            "LastTagTime": "0001-01-01T00:00:00Z"
        }
    }
]

image.png
所有的Docker镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层之上,创建新的镜像层。
举一个简单的例子,假如基于Ubuntu Linux 16.04创建一个新的镜像,这就是新镜像的第一层;如果在该镜像中添加Python包,就会在基础镜像层之上创建第二个镜像层;如果继续添加一个安全补丁,就会创建第三个镜像层。
该镜像当前已经包含3个镜像层,如下图所示(这只是一个用于演示的很简单的例子)。、
image.png
在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点非常重要。下图中举了一个简单的例子,每个镜像层包含3个文件,而镜像包含了来自两个镜像层的6个文件。
image.png

上图中的镜像层跟之前图中的略有区别,主要目的是便于展示文件。
下图中展示了一个稍微复杂的三层镜像,在外部看来整个镜像只有6个文件,这是因为最上层中的文件7是文件5的一个更新版本。
image.png
image.png

这种情况下,上层镜像层中的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个新镜像层添加到镜像当中。Docker通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系统。

Linux上可用的存储引擎有AUFS、Overlay2、Device Mapper、Btrfs以及ZFS。顾名思义,每种存储引擎都基于Linux中对应的文件系统或者块设备技术,并且每种存储引擎都有其独有的性能特点。

Docker在Windows上仅支持windowsfilter一种存储引擎,该引擎基于NTFS文件系统之上实现了分层和CoW[1].下图展示了与系统显示相同的三层镜像。所有镜像层堆叠并合并,对外提供统一的视图。
image.png

特点:
Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部!
这一层就是我们通常说的容器层,容器之下的都叫镜像层!

image.png

commit镜像

docker commit 提交镜像成为一个新的副本
#原理与git相似
docker commit -m ="提交的一些信息"  -a="作者" 容器id  镜像名:[tag]

实战测试:

#启动一个默认的tomcat
#发现这个默认的tomcat是没有webapps应用,镜像的原因,官方的镜像默认 webapps下面是没有文件的!
#拷贝进去了基本的文件
#1.复制文件   
[root@localhost ~]#  docker exec -it   c488a6848f7d   /bin/bash
root@c488a6848f7d:/usr/local/tomcat# cd webapps
root@c488a6848f7d:/usr/local/tomcat/webapps#  ls
root@c488a6848f7d:/usr/local/tomcat/webapps# cd ../
root@c488a6848f7d:/usr/local/tomcat# cp -r webapps.dist/* webapps
root@c488a6848f7d:/usr/local/tomcat# cd webapps
root@c488a6848f7d:/usr/local/tomcat/webapps# ls
ROOT  docs  examples  host-manager  manager
#2.查看运行状态
[root@localhost ~]# docker ps
CONTAINER ID   IMAGE          COMMAND             CREATED       STATUS       PORTS                                       NAMES
c488a6848f7d   fb5657adc892   "catalina.sh run"   3 hours ago   Up 3 hours   0.0.0.0:8080->8080/tcp, :::8080->8080/tcp   tender_zhukovsky
#3.进行镜像提交
[root@localhost ~]# docker commit -a=““"utoujun" -m="add webapps app"   c488a6848f7d  tomcat02:1.0
sha256:855f0e3d5375642f9a80d3b59e903c7e14984490372a41ae46750192996fa616
#4、将我们操作过的容器通过commit提交为一个镜像!
我们以后就使用我们修改过的镜像即可,
这就是我们自己的一个修改的镜像

image.png

如果你想要保存当前容器的状态,就可以通过commit来提交,获得一个镜像,就好比我们以前学习VM时候,快照!

容器数据卷

什么是容器数据卷

docker的理念回顾
将应用和环境打包成一个镜像! 需求:数据可以持久化
MySQL,容器删了,删库跑路!- 需求:MySQL数据可以存储在本地!

容器之间可以有一个数据共享的技术。Docker容器中产生的数据,同步到本地。
这就是卷技术。目录的挂载,将我们容器内的目录,挂载到Linux上面

image.png
总结:容器的持久化和同步操作。容器间也是可以数据共享的

使用数据卷

方式一:直接使用命令来挂载 -v

[root@localhost ~]# docker run -it -v 主机目录:容器目录
[root@localhost ~]# docker run -it -v /home/ceshi:/home centos /bin/bash
#启动起来之后可以使用 docker inspect 容器ID  查看容器的详细新

image.png

测试效果

image.png

再来测试
1、停止容器
2、宿主机上修改文件
3、启动容器
4、容器内的数据依旧是同步的!
image.png

好处: 我们以后修改只需要在本地修改即可,容器内会自动同步

安装mysql

[root@localhost home]# docker search  mysql
[root@localhost home]# docker pull mysql:5.7
#运行容器进行挂载
#安装mysql需要进行密码配置,这是需要注意的点
#官方测试: docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
#启动Mysql [root@localhost home]# docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name=mysql01  mysql:5.7
#-d 后台运行 -p端口映射 -v 挂载   -e环境配置    容器名字 启动
#启动成功之后,我们在本地使用sqlyog来接测试一下
# sq1yog-连接到服务器的3310 --- 3310 和容器内的 3306映射,这个时候我们就可以连接上了!
#在本地测试创建一个数据库,查看一下我们映射的路径是否ok

image.png

假设我们把容器删除
image.png
发现本地数据没有丢失,实现了容器数据持久化

匿名挂载和具名挂载

匿名挂载

-v容器内路径
docker run -d -P --name nginx01 -v / etc/nginx nginx

查看所有的卷的情况

[root@localhost ~]# docker volume ls
DRIVER VOLUME NAME
local 3f3af1f6e15bcf1c7141fff7e7968bf2200b7c23af1eb91b3e496b8007d25cd1
local 813c8a39807f8b136e118f27f4277625bfa269bdf6c2937d3aceaaf9f511223d
local b6929a0d2b57f1d040c2c59d39312e7f9e0fc4208247e1bd8453547cbf806d61
这里发现,这种就是匿名挂载,因为只写了容器内的路径,没有写容器外的路径
[root@localhost ~]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
eed558ff67e39babd3ed11e2427d9c54ab1f7cea76881ac8fe7248b9064a6a86
[root@localhost ~]# docker volume ls
DRIVER VOLUME NAME
local 3f3af1f6e15bcf1c7141fff7e7968bf2200b7c23af1eb91b3e496b8007d25cd1
local 813c8a39807f8b136e118f27f4277625bfa269bdf6c2937d3aceaaf9f511223d
local b6929a0d2b57f1d040c2c59d39312e7f9e0fc4208247e1bd8453547cbf806d61
local juming-nginx
local portainer_data

通过-v卷名:容器内路径

查看一下这个卷

:::
image.png
所有的docker容器内的卷,没有指定目录的情况下都是在/var/lib/docker/voTumes / xxxx/_dat
我们通过具名挂载可以方便的找到我们的一个卷,大多数情况在使用的具名挂载
:::tips

如何确定是具名挂载还是匿名挂载,还是指定路径挂载!

-v容器内路径 #匿名挂载
-v卷名:容器内路径#具名挂载
-v/宿主机路径::容器内路径#指定路径挂载
:::

#通过-v容器内路径:rorw改变读写权限
roreadonly #只读
rwreadwrite #可读可写
#一旦这个了设置了容器权限,容器对我们挂载出来的内容就有限定了!
[root@localhost _data]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:ro nginx
[root@localhost _data]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:rw nginx
# ro只要看到ro就说明这个路径只能通过宿主机来操作,容器内部是无法操作

初识dockerFile

Dockerfile就是用来构建docker镜像的构建文件。 命令脚本
通过这个脚本可以生成镜像,镜像是一层一层的,脚本一个个的命令,每个命令都是一层

#创建一个docker文件,名字可以随意,建议dockerfile
#文件内容 指令(大写) 参数
FROM centos

VOLUME ["volume01","volume02"]

CMD echo ".....end...."
CMD /bin/bash
#这里的每个命令就是镜像的一层

image.png
:::tips
启动容器
:::
image.png
这个卷在外部一定有一个同步的目录
image.png
查看一下卷挂载的路径
image.png
测试一下刚才的文件是否同步出去了
image.png
这种方式我们未来使用的十分多,因为我们通常会构建自己的镜像
假设构建镜像时候没有挂载卷,要手动镜像挂载-v卷名:容器内路径

数据卷容器

image.png
:::tips

启动三个容器

:::
image.png
image.png
image.png
image.png

会发现使用了--volumes-from的容器之间的数据是同步的

在删除了centos01之后查看centos02和centos03,会发现同步的文件还存在

image.png

DockerFile

dockerfile介绍

dockerfile是用来构建dokcer镜像的文件!命令参数脚本
构建步骤︰
1、编写一个dockerfile 文件
2、docker build构建成为一个镜像
3、docker run运行镜像
4、docker push发布镜像(DockerHub、阿里云镜像仓库)
查看一下官方是怎么做的

image.png
image.png
很多官方的镜像都是基础包,很多功能没有。
我们也可以制作自己的镜像

dockerfile构建过程

基础知识:
1、每个保留关键字(指令)都是必须是大写字母
2、执行从上到下顺序执行
3、#表示注释
4、每一个指令都会创建提交一个新的镜像层,并提交
image.png
dockerfile是面向开发的,我们以后要发布项目,做镜像,就需要编写dockerfile文件,这个文件十分简单!Docker镜像逐渐成为企业交付的标准,必须要掌握

步骤∶开发,部署,运维。。。缺一不可

DockerFile :构建文件,定义了一切的步骤,源代码

Dockerlmages:通过DockerFile构建生成的镜像,最终发布和运行的产品!Docker容器︰容器就是镜像运行起来提供服务器

DokcerFile指令

:::tips
FROM #基础镜镜像,一切从这里开始构建
MAINTAINER #镜像是谁写的,姓名+邮箱
RUN #镜像构建的时候需要运行的命令
ADD #步骤: tomcat镜像,这个tomcat压缩包!添加内容
WORKDIR #挂载的目录
EXPOSE #保留端配置
CMD #指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT #指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD #当构建一个被继承 DockerFile这个时侯就会运行ONBUILD 的指令。触发指令。
COPY #类似ADD ,将我们文件拷贝到镜像中
ENV #构建的时候设置环境变量
:::
image.png

实战测试

可以发现,很多镜像都是从from开始的,都是从基础镜像开始的,然后来配置我们需要的软件和配置
image.png
:::tips
创建一个自己的centos
:::

#1编写配置文件
FROM centos:7
MAINTAINER  yutoujun<[email protected]>


ENV MYPATH /usr/local
WORKDIR $MYPATH

RUN  yum install -y vim
RUN yum install -y  net-tools

EXPOSE 80

CMD echo $MYPATH
CMD echo ".....end...."
CMD  /bin/bash
#2 通过文件构建文件
#命令docker bui1d -f dockerfile文件路径-t镜像名:[tag]
Successfully built 6e78e5c7c250
Successfully tagged mycentos:01
对比原生的版本,我们制作的镜像进行了相关的升级,也支持了相关的命令执行

我们可以列出本地镜像的变更的历史
image.png
我们拿到一个镜像之后,可以明白它是怎么做的。

CMD 和ENTRYPOINT的区别

:::tips
CMD #指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT #指定这个容器启动的时候要运行的命令,可以追加命令
:::
测试CMD

[root@localhost dockerfile]# vi mydockerfile-cmd-test
FROM centos
CMD ["ls"," -a"]
 docker build -f mydockerfile-cmd-test -t cmd-test .
[root@localhost dockerfile]# dokcer run  a8a778fc9487
#想追加一个命令-1   ls -al
报错docker run dd8e4401d72f -1
docker: Error response from daemon: 0CI runtime create failed: container_1inux.go:349: startingcontainer process caused "exec: \"-7\ ": executable file not found in SPATH": unknown.
# cmd的清理下-7 替换了CMD ["1s ", "-a"]命令,-1不是命令所以报错!

测试 ENTRYPOINT

[root@localhost dockerfile]#  vi mydockerfile-entrpoint
 FROM centos
ENTRYPOINT ["ls","-a"]
[root@localhost dockerfile]# docker build -f  mydockerfile-entrpoint -t entrypoint-test .
Successfully built 8a28a4d37717
Successfully tagged entrypoint-test:latest
[root@localhost dockerfile]# docker run 8a28a4d37717 -l
total 0
drwxr-xr-x.   1 root root   6 Jul 25 15:07 .
drwxr-xr-x.   1 root root   6 Jul 25 15:07 ..
-rwxr-xr-x.   1 root root   0 Jul 25 15:07 .dockerenv
lrwxrwxrwx.   1 root root   7 Nov  3  2020 bin -> usr/bin
drwxr-xr-x.   5 root root 340 Jul 25 15:07 dev
drwxr-xr-x.   1 root root  66 Jul 25 15:07 etc
drwxr-xr-x.   2 root root   6 Nov  3  2020 home
lrwxrwxrwx.   1 root root   7 Nov  3  2020 lib -> usr/lib
lrwxrwxrwx.   1 root root   9 Nov  3  2020 lib64 -> usr/lib64
drwx------.   2 root root   6 Sep 15  2021 lost+found
drwxr-xr-x.   2 root root   6 Nov  3  2020 media
drwxr-xr-x.   2 root root   6 Nov  3  2020 mnt
drwxr-xr-x.   2 root root   6 Nov  3  2020 opt
dr-xr-xr-x. 150 root root   0 Jul 25 15:07 proc
dr-xr-x---.   2 root root 162 Sep 15  2021 root
drwxr-xr-x.  11 root root 163 Sep 15  2021 run
lrwxrwxrwx.   1 root root   8 Nov  3  2020 sbin -> usr/sbin
drwxr-xr-x.   2 root root   6 Nov  3  2020 srv
dr-xr-xr-x.  13 root root   0 Jul 25 14:08 sys
drwxrwxrwt.   7 root root 171 Sep 15  2021 tmp
drwxr-xr-x.  12 root root 144 Sep 15  2021 usr
drwxr-xr-x.  20 root root 262 Sep 15  2021 var

发布自己的镜像

docker hub

:::tips
1.注册账号:https://hub.docker.com/
2.注册登录之后选择个人账户
3.进行镜像的提交
:::
image.png
:::tips
通过终端登录
[root@localhost dockerfile]# docker login --help
Options:
-p, --password string Password
--password-stdin Take the password from stdin
-u, --username string Username
:::
:::tips

登录成功

[root@localhost dockerfile]# docker login -u yutoujun
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded
:::
:::tips
登录成功之后就是docker push了
[root@localhost dockerfile]# docker push yutoujun/centos:1.0
The push refers to repository [docker.io/yutoujun/centos]
74ddd0ec08fa: Preparing
[上传成功
:::
:::tips
[root@localhost dockerfile]# docker push yutoujun/centos
Using default tag: latest
The push refers to repository [docker.io/yutoujun/centos]
tag does not exist: yutoujun/centos:latest

这种报错使用docker tag 添加一个版本号就可以上传了

docker tag 7809df8649ea yutoujun/centos:1.0
:::

发布镜像到阿里云

docker使用阿里云镜像仓库
1:阿里云docker仓库 https://dev.aliyun.com/search.html
2:进去注册帐号后,点击自己的管理中心。
3:在管理中心点击加速器,右边面板会有你的加速地址,右边面板下面有详细设置步骤。
以下代码用于检测你有没有开启加速器

 ps -ef | grep
root 17825 1 0 16:50 ? 00:00:11 /usr/bin/dockerd --registry-mirror=https://no1pfk8z.mirror.aliyuncs.com --registry-mirror=https://no1pfk8z.mirror.aliyuncs.com --registry-mirror=https://n42ocvxt.mirror.aliyuncs.com --raw-logs

有如上的信息输出代表你已经成功了

4:使用commit构建镜像,执行命令

docker pull centos:latest
docker run -it -p 80 --name willian centos /bin/bash

在bash安装所需要的运行的环境

 docker commit -a 'ss' willian willian/java8

将镜像提交到本地仓库

docker images

这时可以看到你自己的镜像

 docker login --username=willian19960118 registry.cn-hangzhou.aliyuncs.com
1
2

给阿里云仓库打tag

 docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/willianevils/zhangweilun:[镜像版本号]
1
2
 docker push registry.cn-hangzhou.aliyuncs.com/willianevils/zhangweilun:[、

小结

image.png

docker网络

docker0网络详解

:::tips
清空环境
docker rm -f $(docker images -aq)
:::
image.png
会发现有三个网络
:::tips

docker是如何处理容器网络的?

:::

ps -a  
docker ps -a | grep Exited
docker ps -a | grep Exited | awk '{print $1}'
docker ps -a | grep Exited | awk '{print $1}' | xargs docker rm -f

[root@localhost ~]# dokcer run -d -P --name tomcat01 tomcat
#查看容器内网络  ip addr 会发现容器启动会得到一个eth0@if7的ip地址(容器分配)
[root@localhost ~]# docker exec -it tomcat01 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
6: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

:::tips

思考,能不能ping通容器内部

[root@localhost ~]# ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.228 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.075 ms

说明linux可以ping通容器的内部

:::

原理:
1.我们每启动一个docker容器,就会给docker容器分配一个ip,每安装一个docker就有一个网卡(通过桥接技术),,使用的技术是evth-pair技术
再次测试ip addrimage.png
2.再启动一个容器测试,发现又多了一个网卡
image.png
我们发现容器带来的网卡都是一对的,
evth-pair 就是一对的虚拟设备接口,他们都是成对出现的,一段连着协议,一段彼此相连#正因为有这个特性,evth-pair充当一个桥梁,连接各种虚拟网络设备的
openstac,Docker容器之间的连接,oVs的连接,都是使用evth-pair 技术

3.测试tomcat01和tomcat02能不能ping通
[root@localhost ~]# docker exec -it tomcat02 ping 172.18.0.2
结论:容器和容器之间是可以互相ping通的!
image.png
结论: tomcat01和tomcat02是公用的一个路由器,docker0。
所有的容器不指定网络的情况下,都是docker0路由的,docker会给我们的容器分配一个默认的可用IP

:::tips

容器内部没有ip addr 或者其他命令需要进入容器进行安装

更新apt依赖

apt update

安装ipaddr apt install -y iproute2

安装ifconfig apt install -y net-tools

安装ping apt install -y iputils-ping

:::

小结Docker使用的是Linux的桥接,宿主机中是一个Dokcer容器的网桥 docker0.

image.png
Docker 中的所有的网络接口都是虚拟的。虚拟的转发效率高
只要删除容器,对应网桥就没了
image.png

(–link现在已经不推荐使用,了解即可)

在微服务部署的场景下,注册中心是使用服务名来唯一识别微服务的,而我们上线部署的时候微服务对应的IP地址可能会改动,所以我们需要使用容器名来配置容器间的网络连接。使用–link可以完成这个功能。

ping如果是报错的OCI的,记得先进容器内部执行,之所以会报错是因为这里的tomcat没有ping这个命令,需要先安装 apt update && apt install -y net-tools

[rootekuangshen / ]#docker exec -it tomcat02
ping tomcat01ping : tomcat01 : Name or service not knovmn

#知何可以解决呢? --link
[root@localhost ~]# docker exec -it tomcat03 ping tomcat02
PING tomcat02 (172.17.0.3) 56(84) bytes of data.
64 bytes from tomcat02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.088 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.058 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=3 ttl=64 time=0.058 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=4 ttl=64 time=0.056 ms
^C
--- tomcat02 ping statistics ---
#反向能不能呢? 很明显 不能
[root@localhost ~]# docker exec -it tomcat02 ping tomcat03
ping: tomcat03: No address associated with hostname

:::tips
docker network命令
connect Connect a container to a network
create Create a network
disconnect Disconnect a container from a network
inspect Display detailed information on one or more networks
ls List networks
prune Remove all unused networks
rm Remove one or more networks
:::
:::success
探究inspect
image.png

:::
其实这个tomcat03就是在本地配置了tomcat02的配置?

#查看hosts配置,在这里原理发现

[root@localhost ~]# docker exec -it tomcat02 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.3      23c44c7e1500

本质探究:--link就是我们在hosts配置中增加了一个172.18.0.3 tomcat02 312857784cd4我们现在玩Docker 已经不建议使用--link了
自定义网络,不适用docker0

自定义网络

因为docker0,默认情况下不能通过容器名进行访问。需要通过–link进行设置连接。这样的操作比较麻烦,更推荐的方式是自定义网络,容器都使用该自定义网络,就可以实现通过容器名来互相访问了。

查看所有网络

image.png

网络模式
bridge:桥接docker (默认,自己床架也使用bridge模式)
none:不配置网络
host :和宿主机共享网络
container :容器网络连通!(用的少!局限很大)

测试

#我们直接启动的命令--net bridge,--net bridge 是默认参数,不写也会自动带上的
而这个就是我们的dockero
docker run -d -p --name tomcato1 tomcat
docker run -d -p --name tomcato1 --net bridga tomcat
docker0特点。默认,域名不能访问,--Tink可以打通连接
#我们可以自定义一个网络
--driver bridge
--subnet 192.168.0.0/16
--gateway 192.168.0.1
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet

网络构建完成
image.png


[root@localhosts ~]# docker network inspect mynet
[
    {
        "Name": "mynet",
        "Id": "bd09d0023cc17bb06679eea4a70707f3d0deef462e49a883e849b38ce4bc059a",
        "Created": "2022-04-27T09:11:51.194880776+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.0.0/16",
                    "Gateway": "192.168.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]

# 下面启动两个容器,指定使用该自定义网络mynet,测试处于自定义网络下的容器,是否可以直接通过容器名进行网络访问。
[root@localhosts ~]# docker run -d -P --name tomcat-net-01 --net mynet tomcat
5742920d6a3cafe5d88bca0ef66d2b56d475c887984bd7948e114cc57b915720
[root@VM-20-17-centos ~]# docker run -d -P --name tomcat-net-02 --net mynet tomcat
d50e701c062d2d041728a0422d2c47b9ec6c80aea8b920ee32d2bb9674eca624


[root@localhost ~]# docker network inspect mynet
"Containers": {
            "5742920d6a3cafe5d88bca0ef66d2b56d475c887984bd7948e114cc57b915720": {
                "Name": "tomcat-net-01",
                "EndpointID": "690a2421dcef5530238b37487ed2c879db8a8f776388bf3e0444a8914576ca57",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            },
            "d50e701c062d2d041728a0422d2c47b9ec6c80aea8b920ee32d2bb9674eca624": {
                "Name": "tomcat-net-02",
                "EndpointID": "e36caa80fefa8d1a700ed37cad51047db542e5057297435f558161921335d230",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
            }
        },
 # 进入01,安装ping命令       
[root@localhost ~]# docker exec -it tomcat-net-01/bin/bash
root@5742920d6a3c:/usr/local/tomcat# apt-get update
root@5742920d6a3c:/usr/local/tomcat# apt install iputils-ping
# 进入02,安装ping命令
[root@localhost ~]# docker exec -it tomcat-net-02 /bin/bash
root@d50e701c062d:/usr/local/tomcat# apt-get update
root@d50e701c062d:/usr/local/tomcat# apt install iputils-ping


[root@localhost ~]# docker exec -it tomcat-net-01 ping 192.168.0.3

# 直接通过名字ping通
[root@localhost ~]# docker exec -it tomcat-net-01 ping tomcat-net-02
PING tomcat-net-02 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.057 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.062 ms
^C
--- tomcat-net-02 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.057/0.059/0.062/0.002 ms


# 反过来通过02 ping 01,一样能通
[root@localhost ~]# docker exec -it tomcat-net-02 ping tomcat-net-01
PING tomcat-net-01 (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.058 ms
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.057 ms
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=3 ttl=64 time=0.063 ms
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=4 ttl=64 time=0.063 ms
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=5 ttl=64 time=0.078 ms
^C
--- tomcat-net-01 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4000ms
rtt min/avg/max/mdev = 0.057/0.063/0.078/0.007 ms


:::success
docker netwrok create 参数
Options:
--attachable Enable manual container attachment
--aux-address map Auxiliary IPv4 or IPv6 addresses used by Network driver (default map[])
--config-from string The network from which to copy the configuration
--config-only Create a configuration only network
-d, --driver string Driver to manage the Network (default "bridge")
--gateway strings IPv4 or IPv6 Gateway for the master subnet
--ingress Create swarm routing-mesh network
--internal Restrict external access to the network
--ip-range strings Allocate container ip from a sub-range
--ipam-driver string IP Address Management Driver (default "default")
--ipam-opt map Set IPAM driver specific options (default map[])
--ipv6 Enable IPv6 networking
--label list Set metadata on a network
-o, --opt map Set driver specific options (default map[])
--scope string Control the network's scope
--subnet strings Subnet in CIDR format that represents a network segment
:::

网络连通

image.png
image.png

#测试打通 tomcat01 connect
 docker network connect mynet tomcat01
#打通之后发现,会把该容器的地址添加到该网络中
#一个容器,两个地址

image.png

#01连通ok
[root@localhost ~]# docker exec -it tomcat01 ping tomcat-net-01
PING tomcat-net-01 (192.168.0.2)56(84) bytes of data.
64 bytes from tomcat-net-O1.mynet (192.168.0.2): icmp_seq=1 ttlm64 timem0.072 ms
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=2 ttlm64 timem0.070 ms
#02是依旧打不通的
[root@localhost ~]# docker exec -it tomcat02 ping tomcat-net-01
ping: tomcat-net-01: Name or service not known

:::success
结论︰假设要跨网络操作别人,就需要使用docker network connect连通
:::

实战:部署Redis集群

image.png

docker network create redis --subnet 172.38.0.0/16
for port in $(seq 1 6); \
do \
mkdir -p /mydata/redis/node-${port}/conf
touch /mydata/redis/node-${port}/conf/redis.conf
cat << EOF >/mydata/redis/node-${port}/conf/redis.conf
port 6379
bind 0.0.0.0
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 172.38.0.1${port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF
done

#第1个Redis容器
docker run -p 6371:6379 -p 16371:16379 --name redis-1 \
    -v /mydata/redis/node-1/data:/data \
    -v /mydata/redis/node-1/conf/redis.conf:/etc/redis/redis.conf \
    -d --net redis --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
#第2个Redis容器
docker run -p 6372:6379 -p 16372:16379 --name redis-2 \
    -v /mydata/redis/node-2/data:/data \
    -v /mydata/redis/node-2/conf/redis.conf:/etc/redis/redis.conf \
    -d --net redis --ip 172.38.0.12 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
#第3个Redis容器
docker run -p 6373:6379 -p 16373:16379 --name redis-3 \
    -v /mydata/redis/node-3/data:/data \
    -v /mydata/redis/node-3/conf/redis.conf:/etc/redis/redis.conf \
    -d --net redis --ip 172.38.0.13 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
#第4个Redis容器
docker run -p 6374:6379 -p 16374:16379 --name redis-4 \
    -v /mydata/redis/node-4/data:/data \
    -v /mydata/redis/node-4/conf/redis.conf:/etc/redis/redis.conf \
    -d --net redis --ip 172.38.0.14 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
#第5个Redis容器
docker run -p 6375:6379 -p 16375:16379 --name redis-5 \
    -v /mydata/redis/node-5/data:/data \
    -v /mydata/redis/node-5/conf/redis.conf:/etc/redis/redis.conf \
    -d --net redis --ip 172.38.0.15 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
#第6个Redis容器
docker run -p 6376:6379 -p 16376:16379 --name redis-6 \
    -v /mydata/redis/node-6/data:/data \
    -v /mydata/redis/node-6/conf/redis.conf:/etc/redis/redis.conf \
    -d --net redis --ip 172.38.0.16 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
docker run -p 637S{port}:6379 -p 1637S{port}:16379 --name redis-Siport}\-
v /mydata/redis/node-Siport]/data : / data \
-v/mydata/redis/node-S{port]/conf/redis.conf :/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.1S(port} redis :5.0.9-alpine3.11 redis-server /etc/redis/redis.conf;
[root@localhost mydata]# docker ps
CONTAINER ID   IMAGE                    COMMAND                  CREATED          STATUS          PORTS                                                                                      NAMES
65f2d4a0bee3   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   6 seconds ago    Up 5 seconds    0.0.0.0:6373->6379/tcp, :::6373->6379/tcp, 0.0.0.0:16373->16379/tcp, :::16373->16379/tcp   redis-3
7723616e75ab   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   22 minutes ago   Up 22 minutes   0.0.0.0:6376->6379/tcp, :::6376->6379/tcp, 0.0.0.0:16376->16379/tcp, :::16376->16379/tcp   redis-6
a230f670810a   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   22 minutes ago   Up 22 minutes   0.0.0.0:6375->6379/tcp, :::6375->6379/tcp, 0.0.0.0:16375->16379/tcp, :::16375->16379/tcp   redis-5
05db3437fc9b   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   22 minutes ago   Up 22 minutes   0.0.0.0:6374->6379/tcp, :::6374->6379/tcp, 0.0.0.0:16374->16379/tcp, :::16374->16379/tcp   redis-4
b725d91f31b9   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   23 minutes ago   Up 23 minutes   0.0.0.0:6372->6379/tcp, :::6372->6379/tcp, 0.0.0.0:16372->16379/tcp, :::16372->16379/tcp   redis-2
66b4857a103c   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   23 minutes ago   Up 23 minutes   0.0.0.0:6371->6379/tcp, :::6371->6379/tcp, 0.0.0.0:16371->16379/tcp, :::16371->16379/tcp   redis-1
#进入其中一个容器
docker exec -it redis-1 /bin/sh
#进行集群的配置
/data # redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1

>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 172.38.0.15:6379 to 172.38.0.11:6379
Adding replica 172.38.0.16:6379 to 172.38.0.12:6379
Adding replica 172.38.0.14:6379 to 172.38.0.13:6379
M: 0c4d6d85ae339e2cd1ea83fb9970040ddabbb05e 172.38.0.11:6379
   slots:[0-5460] (5461 slots) master
M: a2d073ba19af2dad5d44c55cf9da144ab33977e4 172.38.0.12:6379
   slots:[5461-10922] (5462 slots) master
M: c8de23ecf2760f3373fda9ad7294225742e23078 172.38.0.13:6379
   slots:[10923-16383] (5461 slots) master
S: 7d905318e026fbf999cc51b1895540d07d4fe138 172.38.0.14:6379
   replicates c8de23ecf2760f3373fda9ad7294225742e23078
S: 0a6f3d91e9d8790c44378ef6f20ade4cd0e55a6b 172.38.0.15:6379
   replicates 0c4d6d85ae339e2cd1ea83fb9970040ddabbb05e
S: 677503d6390c2d7cc1d0096cb3b83b1515d92f84 172.38.0.16:6379
   replicates a2d073ba19af2dad5d44c55cf9da144ab33977e4
Can I set the above configuration? (type 'yes' to accept):#输入yes确定
#创建成功
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
# redis-cli -c
# cluster info
# cluster nodes
/data # redis-cli -c
127.0.0.1:6379> cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_ping_sent:203
cluster_stats_messages_pong_sent:206
cluster_stats_messages_sent:409
cluster_stats_messages_ping_received:201
cluster_stats_messages_pong_received:203
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:409
127.0.0.1:6379> cluster nodes
1fe798431adf6929e7c4c42dfe68a06cf2afc8fc 172.38.0.12:6379@16379 master - 0 1651026759598 2 connected 5461-10922   # 主机
8772dc6ea9377834bd6478dc705abe6fa3a655f1 172.38.0.14:6379@16379 slave # 从机 24b2f2cf14ad8edc16b336ec539ca38c615f030a 0 1651026759000 4 connected  
002d5169ffa41b51d434a53a62388e039fabb3ad 172.38.0.16:6379@16379 slave # 从机 1fe798431adf6929e7c4c42dfe68a06cf2afc8fc 0 1651026758095 6 connected  
5859376a31233072e1761c82a43a55d4a4508740 172.38.0.11:6379@16379 myself,master - 0 1651026758000 1 connected 0-5460  # 主机
5edeb5a195a1ae0f0e9b54018312e4f129c5bdab 172.38.0.15:6379@16379 slave   # 从机 5859376a31233072e1761c82a43a55d4a4508740 0 1651026760099 5 connected
24b2f2cf14ad8edc16b336ec539ca38c615f030a 172.38.0.13:6379@16379 master - 0 1651026759097 3 connected 10923-16383   # 主机


/data # redis-cli -c
127.0.0.1:6379> set test02 ceshi
-> Redirected to slot [14163] located at 172.38.0.13:6379
OK

[root@VM-20-17-centos ~]# docker stop redis-3
redis-3
#要重进集群,因为当前连的是172.38.0.13的,而正好在刚刚被我们停掉了,所以要重新进入集群,然后再次查看
/data # redis-cli -c
127.0.0.1:6379> get test02
-> Redirected to slot [14163] located at 172.38.0.14:6379
"ceshi"

标签:容器,--,基础,redis,镜像,docker,root
From: https://www.cnblogs.com/yutoujun/p/16914833.html

相关文章

  • React 学习笔记之一 - ES6 基础
    1.1let及const1.1.1let命令用var声明变量有变量提升的情况。1console.log(a);2vara=1; 如果没有第二行的声明,那么会看到“aisnotdefined......
  • docker 常见操作
    1.开启mysqldockerrun--rm-itd-p3306:3306--restart=on-failure:3--namemysql-eMYSQL_ROOT_PASSWORD=123mysql:latestdockerexec-it<容器id>shmysql-uroo......
  • Java基础
    Java基础环境准备安装JDK配置环境变量安装开发工具(IDEA)IDEAIDE(集成开发环境,是用于提供程序开发环境的应用程序)IDEA,开发Java代码WebStorm,开发前端代码......
  • Docker Compose 部署 Jenkins
    Jenkins介绍Jenkins是一个开源软件项目,是基于Java开发的一种持续集成工具Jenkins应用广泛,大多数互联网公司都采用Jenkins配合GitLab、Docker、K8s作为实现DevOps的核心......
  • day05_狂神说java基础_流程控制
    d05Java流程控制(p33-p44)1.用户交互Scanner之前的基本语法中没有涉及到程序和人的交互,java.util.Scanner是Java5提供的工具类,可以通过Scanner类获取用户的输入。......
  • 机器学习基础(4)—— 模型选择之评估方法
    参考:西瓜书第二章李航《统计学习方法(第二版)》第一章现实任务中,往往有多种学习方法可供选择,对于同一个方法,使用不同的参数配置,也可以产生不同的模型。选择哪个模型(算法)、......
  • typescript 基础数据类型
    typescript入门介绍开始阶段推荐使用线上[Playground]https://www.typescriptlang.org/play基础数据类型布尔值letisDone:boolean=falselethasDone:boolean......
  • Typescript ----基础类型
    typescript入门介绍开始阶段推荐使用线上[Playground]https://www.typescriptlang.org/play基础数据类型布尔值letisDone:boolean=falselethasDone:boolean......
  • MAUI新生1.7-XAML语法基础:UI平台差异OnPlatform&OnIdiom
    MAUI支持跨平台和多设备,可以针对不同平台(Android、iOS、WinUI、MacCatalyst、Tizen),或不同设备(Phone、Tablet、Desktop、TV、Watch),定制不同的UI,应用根据运行环境,自动适应。......
  • docker启动错误
    很久没有启动docker了,想使用dockerps-a命令查看之前自己安装的容器,出现了报错CannotconnecttotheDockerdaemonatunix:///var/run/docker.sock.Isthedockerda......