B站狂神说Docker笔记

docker

docker安装

#yum安装gcc相关环境
yum -y install gcc
yum -y install gcc-c++

#1.uninstall old version
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 \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

#4.更新yum软件包索引
yum makecache

#5.安装docker CE
yum install docker-ce docker-ce-cli containerd.io

#6.启动docker
systemctl start docker

#7.配置阿里云加速
mkdir -p /etc/docker

tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://a44vgxfx.mirror.aliyuncs.com"]
}
EOF

systemctl daemon-reload

systemctl restart docker

Docker的常用命令

常用

#启动docker
systemctl start docker

#卸载docker
systemctl stop docker 

yum -y remove docker-ce docker-ce-cli containerd.io

rm -rf /var/lib/docker

帮助命令

docker version

docker info  //显示docker的系统信息

docker 命令 --help

镜像命令

docker images   查看本机所有的镜像

docker search   搜索命令

docker pull  下载镜像

docker rmi -f 删除镜像

容器命令

有了镜像才可以创建容器

新建容器并启动

docker run [可选参数] image

#可选参数
--name="name"
-d                后台运行
-it               交互式运行
-p                指定容器的端口 -p 8080:8080
   -p ip:主机端口:容器端口
   -p 主机端口:容器端口
   -p 容器端口
   容器端口
-p                 随机指定端口

#测试,启动并进入容器
root@iZ2vc7zktoz7z9fn3qhptjZ ~]# docker run -it centos /bin/bash
[root@66b736657325 /]# 

列出所有运行中的容器

docker ps  查看运行中的容器
    #当前运行、
-a  #列出运行的容器+历史运行
[root@iZ2vc7zktoz7z9fn3qhptjZ ~]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
[root@iZ2vc7zktoz7z9fn3qhptjZ ~]# docker ps -a
CONTAINER ID   IMAGE         COMMAND       CREATED             STATUS                         PORTS     NAMES
66b736657325   centos        "/bin/bash"   5 minutes ago       Exited (0) 3 minutes ago                 bold_golick
bc74ee3218c7   hello-world   "/hello"      About an hour ago   Exited (0) About an hour ago             wonderful_kepler

退出容器

exit  #退出
Ctrl+P+Q  #容器不停止退出

删除容器

docker rm 容器id
docker rm -f $(docker pa -aq)   #删除所有

启动和停止容器

docker start 容器id
docker restart 容器id
docker stop id
docker kill id

其他常用命令

#查看日志
docker logs

#自己编写一段shell脚本
docker run -d centos /bin/sh -c "while true;do echo kuangshen;sleep 1;done"

[root@iZ2vc7zktoz7z9fn3qhptjZ ~]# docker ps

[root@iZ2vc7zktoz7z9fn3qhptjZ ~]# docker logs -tf --tail 10 ca62595a175a
#查看容器的进程信息
docker top 容器id

#查看容器的元信息
docker inspect id
#进入当前正在运行的容器
#我们的容器都是使用后台方式运行的,需要进入容器,修改一些配置
docker exec -it 容器id bashShell

#测试
[root@iZ2vc7zktoz7z9fn3qhptjZ ~]# docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED       STATUS       PORTS     NAMES
df33d9b19dfc   centos    "/bin/bash"   3 hours ago   Up 3 hours             intelligent_pasteur
[root@iZ2vc7zktoz7z9fn3qhptjZ ~]# docker exec -it df33d9b19dfc /bin/bash
[root@df33d9b19dfc /]# ps -ef
UID          PID    PPID  C STIME TTY          TIME CMD
root           1       0  0 10:10 pts/0    00:00:00 /bin/bash
root          15       0  0 12:50 pts/1    00:00:00 /bin/bash
root          29      15  0 12:51 pts/1    00:00:00 ps -ef

#方式二
docker attach 容器id


#docker exec   #进入容器后开启一个新的终端,可以在里面操作
#docker attach    #进入容器正在执行的终端
#从容器内拷贝文件到主机上
docker cp 容器id:

#测试
[root@iZ2vc7zktoz7z9fn3qhptjZ home]# docker attach 31ffda8491d6
[root@31ffda8491d6 /]# cd /home
[root@31ffda8491d6 home]# ls
[root@31ffda8491d6 home]# touch text.java
[root@31ffda8491d6 home]# ls
text.java
[root@31ffda8491d6 home]# exit
exit
[root@iZ2vc7zktoz7z9fn3qhptjZ home]# docker ps -a
CONTAINER ID   IMAGE         COMMAND                  CREATED              STATUS                      PORTS     NAMES
31ffda8491d6   centos        "/bin/bash"              About a minute ago   Exited (0) 10 seconds ago             sleepy_diffie

#将文件拷贝出到主机上
[root@iZ2vc7zktoz7z9fn3qhptjZ home]# docker cp 31ffda8491d6:/home/text.java /home
[root@iZ2vc7zktoz7z9fn3qhptjZ home]# ls
text.java  yang.java

作业

Docker安装Nginx

#1.搜索镜像 docker search
#2.下载镜像 docker pull
#3.运行测试

[root@iZ2vc7zktoz7z9fn3qhptjZ home]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
mysql         latest    ecac195d15af   16 hours ago   516MB
nginx         latest    87a94228f133   7 days ago     133MB
hello-world   latest    feb5d9fea6a5   3 weeks ago    13.3kB
centos        latest    5d0da3dc9764   4 weeks ago    231MB

#-d 后台运行
#--name   给容器命名
#-p   容器内部端口
[root@iZ2vc7zktoz7z9fn3qhptjZ home]# docker run -d --name nginx01 -p 3344:80 nginx
c2487d62a28c0577cf3dd7f1c3dd98967c32a2e81fcc45a6c4bf3502b5ee3924
[root@iZ2vc7zktoz7z9fn3qhptjZ home]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                                   NAMES
c2487d62a28c   nginx     "/docker-entrypoint.…"   4 seconds ago   Up 4 seconds   0.0.0.0:3344->80/tcp, :::3344->80/tcp   nginx01
[root@iZ2vc7zktoz7z9fn3qhptjZ home]# crul localhost:3344
-bash: crul: command not found
[root@iZ2vc7zktoz7z9fn3qhptjZ home]# curl localhost:3344

#进入容器


端口暴露的概念

在这里插入图片描述

数据卷

作业:安装Tomcat

#官方的使用
docker run -it --rm tomcat:9.0
#我们之前启动的是后台,停止了容器之后,容器还是可以查到  docker run -it --rm  这个命令用完即删

#下载
docker pull tomcat

#启动
docker run -d -p 3355:8080 --name tomcat01 tomcat

#进入容器
[root@iZ2vc7zktoz7z9fn3qhptjZ home]# docker exec -it tomcat01 /bin/bash
#进入容器后发现:1.Linux命令少了  2.没有webapps 阿里云镜像默认只保存最小的镜像,不必要的将会删除

思考问题:我们以后部署项目,每次都要进入容器非常麻烦

部署es+kiband

#es暴露的端口很多
#es十分耗费内存
#es的数据需要放到安全目录挂载
#--net somenetwork  

#启动elasticsearch
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2

#启动后Linux变得非常卡 docker stats 查看CPU的状态

#es是十分耗内存的
#测试es十分成功
#赶紧关闭,增加内存限制

docker run -d --name elasticsearch02 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.6.2

在这里插入图片描述

#测试
[root@iZ2vc7zktoz7z9fn3qhptjZ ~]# curl localhost:9200
{
  "name" : "df4d4ae3f99e",
  "cluster_name" : "docker-cluster",
  "cluster_uuid" : "YoDi8IlLRke18VxvJr2gLQ",
  "version" : {
    "number" : "7.6.2",
    "build_flavor" : "default",
    "build_type" : "docker",
    "build_hash" : "ef48eb35cf30adf4db14086e8aabd07ef6fb113f",
    "build_date" : "2020-03-26T06:34:37.794943Z",
    "build_snapshot" : false,
    "lucene_version" : "8.4.0",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}

作业:使用kibana连接es,网络如何才能连接过去

在这里插入图片描述

可视化

portainer

docker run -d -p 8088:9000 \
--restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer

Rancher

什么是portainer

docker图形化界面管理工具,提供一个后台面板供我们操作

访问测试

测试外网端口8088

在这里插入图片描述

如何提交自己的镜像

docker commit #提交容器称为一个新的副本
docker commit -m="描述信息" -a="作者" 容器id 目标镜像名:[tag]

实战测试

#启动一个默认的Tomcat
#发现这个默认的Tomcat是没有webapps应用,官方的原因
#自己通过命令拷贝进去了基本的文件
#将我们操作过得容器通过commit提交为一个镜像,我们以后就使用自己修改过得镜像

在这里插入图片描述

在这里插入图片描述

容器数据卷

什么是容器数据卷

docker理念回顾:将应用和环境打包成一个镜像!

数据?如果数据都在容器中,那么我们删除容器,数据就会丢失 需求:实现数据持久化

MySQL ,容器删了,就完了!!!! 需求:MySQL数据可以存储在本地

容器之间有一个数据共享技术,docker容器产生的数据,同步到本地

这就是卷技术,目录的挂载,将我们容器的目录挂载到Linux上面

在这里插入图片描述

容器的持久化和同步操作,容器间也是

使用数据卷

方式1:直接使用命名挂载 -v

docker run -it -v 主机目录:容器目录

#测试
docker run -it -v /home/ceshi:/home centos /bin/bash

在这里插入图片描述

在这里插入图片描述

实战:安装MySQL

#获取镜像
docker pull mysql:5.7

#运行容器,配置mysql的密码
docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag

#启动我们的mysql
-d    后台运行
-p    端口
-v    磁盘挂载
-e    环境设置

docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7

#在挂载的时候宿主机的目录必须不存在或者为空,否则容器会自动停止运行

#
docker run -p 3310:3306 --name mysql01 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7

#测试  使用Navicat连接

删除镜像后,数据库的数据并未删除

具名挂载和匿名挂载

#匿名挂载   不指定宿主机内的目录,随机分配挂载目录
docker run -d -P --name nginx01 -v /etc/nginx nginx

#查看所有volume的情况
docker volume ls
[root@iZ2vc7zktoz7z9fn3qhptjZ data]# docker volume ls
DRIVER    VOLUME NAME
local     8f25eadc6fc021cceec30d57f098c8b747c0c4259893daef94180fcad9e0d035
local     77191ab5590d6993214c197d35234b802b20b1dd0b3fc9ab89610614478e1cab
local     2561304f2d5452e681af143f6bf7f89a3ffd8d16b54b87fe4d7d56baa54666ef


#具名挂载
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx

#测试
[root@iZ2vc7zktoz7z9fn3qhptjZ data]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
47a6f0234961c0370c3c03517e556e74ac2a73569aeb82d5987c3935571d30c7
[root@iZ2vc7zktoz7z9fn3qhptjZ data]# docker volume ls
DRIVER    VOLUME NAME
local     8f25eadc6fc021cceec30d57f098c8b747c0c4259893daef94180fcad9e0d035
local     9e95356d6b94193e20b71ca27ba174e7f9dafb083d548cfb41304cba212e1e80
local     77191ab5590d6993214c197d35234b802b20b1dd0b3fc9ab89610614478e1cab
local     2561304f2d5452e681af143f6bf7f89a3ffd8d16b54b87fe4d7d56baa54666ef
local     juming-nginx


#查看挂载的具体地址
docker volume inspect juming-nginx
[root@iZ2vc7zktoz7z9fn3qhptjZ data]# docker volume inspect juming-nginx
[
    {
        "CreatedAt": "2021-10-21T20:17:55+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data",
        "Name": "juming-nginx",
        "Options": null,
        "Scope": "local"
    }
]


#所有docker容器内的卷,在没有指定目录的情况下都在/var/lib/docker/volumes/XXXX/_data

在这里插入图片描述

#所有docker容器内的卷,在没有指定目录的情况下都在/var/lib/docker/volumes/XXXX/_data

我们通过具名挂载可以方便的找到我们的卷,大多数时候使用

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

拓展

#通过 -v 容器内路径:ro rw  改变读写权限
ro  #只读
rw  #读写


docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:ro nginx
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:rw nginx
#ro只能通过宿主机操作,在容器内部是无法操作的

初识Dockerfile

Dockerfile就是用来构建docker镜像的构建文件命令脚本!

通过这个脚本可以生成镜像,镜像一层一层的,脚本就是一个个的命令,每个命令都是一层

#创建一个dockerfile文件

#文件中的内容命令大写
FROM centos

VOLUME ["volume01","volume02"]

CMD echo "----end----"
CMD /bin/bash

#
docker build -f /home/docker-test-volume/dockerfile1 -t kuangshen/centos:1.0 .

在这里插入图片描述

在这里插入图片描述

这个卷一定和外部的目录是挂载的

在这里插入图片描述

测试刚才的文件是否同步出去

数据卷容器

多个mysql同步数据

在这里插入图片描述

启动3个容器,通过我们自己构建的容器启动

在这里插入图片描述

在这里插入图片描述

#将docker02的数据挂载到docker01  删除docker01,docker02的数据还在,所以文件共享是拷贝的状态
docker run -it --name docker02 --volumes-from docker01 kuangshen/centos:1.0

多个mysql实现数据共享

#第一步
docker run -d -p 3310:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7

#第二步
docker run -d -p 3310:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql02 mysql:5.7

#实现两个容器数据共享

结论:容器之间配置信息的传递,容器数据卷的生命周期一直持续到没有容器使用为止

但是你一旦持久化到了本地,本地的数据是不会删除的

Dockerfile

dockerfile是用来构建docker镜像的文件!命令参数脚本!

构建步骤

1.编写一个dockerfile文件

2.docker build构建成为一个镜像

3.docker run 运行镜像

4.docker push 发布镜像(DockerHub,阿里云镜像仓库)

查看官方是怎么做的

在这里插入图片描述

很多官方镜像都是基础包,跟多功能没有,我们通常会搭建自己的环境

官方可以自己制作镜像,我们也可以

Dockerfile构建过程

基础知识

1.每个保留关键字或者指令都必须是大写指令

2.指令从上执行到下

3.#表示注释

4.每个指令都会创建并提交一个新的镜像层

在这里插入图片描述

dockerfile是面向开发的,我们以后要发布项目,做镜像,就需要编写dockerfile文件

步骤:开发,部署,运维

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

DockerImages:通过DockerFile构建生成的镜像,最终发布和运行的产品

Docker容器:容器就是镜像运行起来提供服务的

DockerFile的指令

在这里插入图片描述

#指令
FROM           #基础镜像 centos ubantu,一切从这里开始
MAINTAINER     #镜像是谁写的  姓名+邮箱
RUN            #镜像运行的时候需要运行的命令
ADD            #步骤:Tomcat镜像:Tomcat压缩包!
WORKDIR        #工作目录
VOLUME         #设置卷,挂载到哪个位置
EXPOSE         #指定对外的端口
CMD            #指定容器启动运行的要运行的命令,只有最后一个会生效
ENTRYPOINT     #容器启动是运行的命令,可以追加命令
ONBUILD        #当构建镜像被继承,这个时候会运行ONBUILD   的指令
COPY           #类似ADD,将文件拷贝到镜像中
ENV            #构建的时候设置环境变量


练习:写个自己的镜像

在这里插入图片描述

DockerHub中99%的镜像都是FROM scratch,然后配置需要的软件和配置

创建自己的centos

#1.编写dockerfile文件
[root@iZ2vc7zktoz7z9fn3qhptjZ dockerfile]# vim mydockerfile-centos
[root@iZ2vc7zktoz7z9fn3qhptjZ dockerfile]# cat mydockerfile-centos
FROM centos
MAINTAINER ybw<1554094535@qq.com>

ENV MYPATH /usr/local
WORKDIR $MYPATH
RUN yum -y install vim
RUN yum -y install net-tools

EXPOSE 80
CMD echo $MYPATH
CMD echo "---end----"
CMD /bin/bash

#2.通过docker build 构建

#3.测试运行

对比

之前的原生centos

在这里插入图片描述

增加我们自己的centos

在这里插入图片描述

我们可以本地查看变更历史

在这里插入图片描述

CMD和ENTRYPOINT的区别

CMD            #指定容器启动运行的要运行的命令,只有最后一个会生效
ENTRYPOINT     #容器启动是运行的命令,可以追加命令

测试CMD

#编写dockerfile文件
[root@iZ2vc7zktoz7z9fn3qhptjZ dockerfile]# vim dockerfile-cmd-test
FROM centos
CMD ["ls","-a"]
#构建镜像
[root@iZ2vc7zktoz7z9fn3qhptjZ dockerfile]# docker build -f dockerfile-cmd-test -t cmdtest .
#run运行
[root@iZ2vc7zktoz7z9fn3qhptjZ dockerfile]# docker run 0ab8341a6e84
.
..
.dockerenv
bin
dev
etc
home
lib

#要想追加一个命令-l,使得执行的命令变成 ls -al,会发现报错
[root@iZ2vc7zktoz7z9fn3qhptjZ dockerfile]# docker run 0ab8341a6e84 -l
docker: Error response from daemon: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "-l": executable file not found in $PATH: unknown.
ERRO[0000] error waiting for container: context canceled 

#正确的办法应该为
[root@iZ2vc7zktoz7z9fn3qhptjZ dockerfile]# docker run 0ab8341a6e84 ls -al
total 0
drwxr-xr-x   1 root root   6 Oct 21 15:32 .
drwxr-xr-x   1 root root   6 Oct 21 15:32 ..
-rwxr-xr-x   1 root root   0 Oct 21 15:32 .dockerenv
lrwxrwxrwx   1 root root   7 Nov  3  2020 bin -> usr/bin
drwxr-xr-x   5 root root 340 Oct 21 15:32 dev
drwxr-xr-x   1 root root  66 Oct 21 15:32 etc
drwxr-xr-x   2 root root   6 Nov  3  2020 home

测试ENTRYPOINT

[root@iZ2vc7zktoz7z9fn3qhptjZ dockerfile]# vim dockerfile-cmd-entrypoint
FROM centos
ENTRYPOINT ["ls","-a"]

#构建
[root@iZ2vc7zktoz7z9fn3qhptjZ dockerfile]# docker build -f dockerfile-cmd-entrypoint -t entrypoint-test .

Successfully built 7cf9e42fd793
Successfully tagged entrypoint-test:latest
#启动
[root@iZ2vc7zktoz7z9fn3qhptjZ dockerfile]# docker run 7cf9e42fd793
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found
#追加命令
[root@iZ2vc7zktoz7z9fn3qhptjZ dockerfile]# docker run 7cf9e42fd793 -l
total 0
drwxr-xr-x   1 root root   6 Oct 21 15:36 .
drwxr-xr-x   1 root root   6 Oct 21 15:36 ..
-rwxr-xr-x   1 root root   0 Oct 21 15:36 .dockerenv
lrwxrwxrwx   1 root root   7 Nov  3  2020 bin -> usr/bin
drwxr-xr-x   5 root root 340 Oct 21 15:36 dev
drwxr-xr-x   1 root root  66 Oct 21 15:36 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 14:17 lost+found

实战:Tomcat镜像

1.准备Tomcat压缩包,jdk的压缩包

在这里插入图片描述

2.编写dockerfile文件,官方命名Dockerfile,执行docker build时会自动寻找dockerfile文件不需要-f指定

FROM centos
MAINTAINER ybw<1554094535@qq.com>

COPY readme.txt /usr/local/readme.txt
ADD apache-tomcat-9.0.54.tar.gz /usr/local/
ADD jdk-8u311-linux-x64.tar.gz /usr/local/

RUN yum -y install vim

ENV MYPATH /usr/local
WORKDIR $MYPATH

ENV JAVA_HOME /usr/local/jdk1.8.0_311
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.54
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.54
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin

EXPOSE 8080
CMD /usr/local/apache-tomcat-9.0.54/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.54/bin/logs/catalina.out

3.构建镜像

docker build -t diytomcat .

4.运行

docker run -d -p 9090:8080 --name ybwtomcat -v /home/ybw/tomcat/test:/url/local/apache-tomcat-9.0.54/webapps/test -v /home/ybw/tomcat/tomcatlogs/:/url/local/apache-tomcat-9.0.54/logs diytomcat

5.启动镜像

6.访问测试

7.发布项目,做了卷挂载,直接在本地发布

  <?xml version="1.0" encoding="UTF-8"?>
  <web-app xmlns="http://java.sun.com/xml/ns/javaee"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                               http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
           version="2.5">

  </web-app>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>hello,杨博文</title>
</head>
<body>
Hello World!<br/>
<%
System.out.println("---ybw---");
%>
</body>
</html>

项目部署成功

在这里插入图片描述

我们以后的开发步骤,需要掌握DockerFile的编写

发布自己的镜像

DockerHub注册自己的账号

1、地址 hub.docker.com注册账号

2、在服务器上提交

#1.查看登录命令
[root@iZ2vc7zktoz7z9fn3qhptjZ tomcatlogs]# docker login --help

Usage:  docker login [OPTIONS] [SERVER]

Log in to a Docker registry.
If no server is specified, the default is defined by the daemon.

Options:
  -p, --password string   Password
      --password-stdin    Take the password from stdin
  -u, --username string   Username
#2.登录
[root@iZ2vc7zktoz7z9fn3qhptjZ tomcatlogs]# docker login -u timenever



#给镜像添加标签
docker tag diytomcat ybw/tomcat:1.0

#发布
docker pull

发布到阿里云镜像

1.登录阿里云

2.找到容器镜像服务

3.创建命名空间

在这里插入图片描述

4.创建容器镜像

在这里插入图片描述

5.游览仓库信息

在这里插入图片描述

小结

在这里插入图片描述

Docker 网络

理解docker0

1.清空所有环境

测试

在这里插入图片描述

三个网络

#docker如何处理网络访问

在这里插入图片描述

[root@iZ2vc7zktoz7z9fn3qhptjZ ~]# docker run -d -P --name tomcat01 tomcat

#查看容器内部网络地址  ip addr 发现容器启动时会有eth0@if77 这是docker分配的
#容器容器内部没有ip命令,进入容器执行 apt update && apt install -y iproute2
#  没有ipconfig   执行    apt install net-tools
#没有ping命令   执行   apt install iputils-ping
[root@iZ2vc7zktoz7z9fn3qhptjZ ~]# 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
76: eth0@if77: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0
       valid_lft forever preferred_lft forever

#思考  Linux能不能ping通容器内部
[root@iZ2vc7zktoz7z9fn3qhptjZ ~]# ping 172.18.0.2
PING 172.18.0.2 (172.18.0.2) 56(84) bytes of data.
64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.034 ms
64 bytes from 172.18.0.2: icmp_seq=2 ttl=64 time=0.035 ms
64 bytes from 172.18.0.2: icmp_seq=3 ttl=64 time=0.037 ms
64 bytes from 172.18.0.2: icmp_seq=4 ttl=64 time=0.033 ms

#说明Linux可以ping通容器内部

原理

1.我们每安装一个docker容器,docker就会docker容器分配一个ip,我们只要安装了docker,就会有一个网卡docker0桥接模式,使用的是evth-pair技术

#在此使用ip addr
#多了一个网卡77

在这里插入图片描述

2.再启动一个容器测试,发现又多了一对网卡

在这里插入图片描述

#我们发现这个容器的网卡,都是一对对的
#evth-pair  就是一对虚拟设备接口,他们是成对出现的,一段连着协议,一段彼此相连
#正因为有这个特性,evth-pair 充当一个桥梁,连接着各种虚拟设备
#OpenStack,Docker容器之间的连接,OVS的连接,都是使用evth-pair技术

3.我们来测试Tomcat01和Tomcat02能否ping通

[root@iZ2vc7zktoz7z9fn3qhptjZ ~]# docker exec -it tomcat02 ping 172.18.0.2
PING 172.18.0.2 (172.18.0.2) 56(84) bytes of data.
64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.061 ms
64 bytes from 172.18.0.2: icmp_seq=2 ttl=64 time=0.043 ms
64 bytes from 172.18.0.2: icmp_seq=3 ttl=64 time=0.046 ms


#发现容器和容器之间是可以ping通

在这里插入图片描述

tomcat01和tomcat02是公用的一个路由器

所有的容器不指定网络的情况下,都是docker0路由的,docker会给我们的容器默认分配ip

小结

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

在这里插入图片描述

Docker中所有的网络接口都是虚拟的,虚拟的转发效率高

只要删除容器,对应的一对网桥就没了

思考一个场景,编写一个微服务,database url=ip;项目不重启,数据库ip换掉了,我们希望可以处理这个问题,可以通过名字来进行访问容器

[root@iZ2vc7zktoz7z9fn3qhptjZ ~]# docker exec -it tomcat02 ping tomcat01
ping: tomcat01: Name or service not known

#如何解决这个问题
#1.用--link
[root@iZ2vc7zktoz7z9fn3qhptjZ ~]# docker run -d -P --name tomcat03 --link tomcat02 tomcat
#2.测试
[root@iZ2vc7zktoz7z9fn3qhptjZ ~]# docker exec -it tomcat03 ping tomcat02
PING tomcat02 (172.18.0.3) 56(84) bytes of data.
64 bytes from tomcat02 (172.18.0.3): icmp_seq=1 ttl=64 time=0.069 ms
64 bytes from tomcat02 (172.18.0.3): icmp_seq=2 ttl=64 time=0.047 ms
64 bytes from tomcat02 (172.18.0.3): icmp_seq=3 ttl=64 time=0.044 ms
#反向可以ping通吗

在这里插入图片描述

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

#查看hosts配置,在这里发现
[root@iZ2vc7zktoz7z9fn3qhptjZ ~]# docker exec -it tomcat03 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.18.0.3	tomcat02 0b46548f4648
172.18.0.4	300b08083fdb

本质:–link就是我们在host配置中增加了一个172.18.0.3 tomcat02 0b46548f4648

我们现在用docker已经不建议用–link

我们现在自定义网络

自定义网络

查看所有的docker网络

在这里插入图片描述

网络模式

bridge:桥接 docker(默认)

none: 不配置网络

host:和宿主机共享网络

container:容器网络连通(局限大)

测试

#我们直接启动的命令 --net bridge,而这个就是我们的docker0
docker run -d -P --name tomcat01 tomcat
docker run -d -P --name tomcat01 --net bridge tomcat

#docker0的特点  默认:域名不能访问 --link可以打通连接

#我们可以自定义一个网络


[root@iZ2vc7zktoz7z9fn3qhptjZ ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
39029c391c45291274fb21b1dece9b46664b2ad95987804b13fe10db98125039
[root@iZ2vc7zktoz7z9fn3qhptjZ ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
570b70de9ce6   bridge    bridge    local
76ade01f6e8e   host      host      local
39029c391c45   mynet     bridge    local
e846891d3b76   none      null      local

我们自己的网络就创建好了

在这里插入图片描述

#进入容器后解决apt update下载速度慢
root@6646172977e6:/usr/local/tomcat# cd /etc/apt
root@6646172977e6:/etc/apt# ls
apt.conf.d  auth.conf.d  preferences.d	sources.list  sources.list.d  trusted.gpg.d
root@6646172977e6:/etc/apt# echo "">sources.list
root@6646172977e6:/etc/apt# echo "deb http://ftp2.cn.debian.org/debian/ buster main">>sources.list
root@6646172977e6:/etc/apt# echo "deb http://ftp2.cn.debian.org/debian/debian-security buster/updates main">>sources.list
root@6646172977e6:/etc/apt# echo "deb http://ftp2.cn.debian.org/debian/debian buster-updates main">>sources.list

[root@iZ2vc7zktoz7z9fn3qhptjZ ~]# docker exec -it tomcat-net-01 ping 192.168.0.3
PING 192.168.0.3 (192.168.0.3) 56(84) bytes of data.
64 bytes from 192.168.0.3: icmp_seq=1 ttl=64 time=0.028 ms
64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.026 ms
64 bytes from 192.168.0.3: icmp_seq=3 ttl=64 time=0.027 ms
#发现ping容器名称可以ping通
[root@iZ2vc7zktoz7z9fn3qhptjZ ~]# docker exec -it tomcat-net-01 ping tomcat-net-02
PING tomcat-net-02 (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat-net-02.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.074 ms
64 bytes from tomcat-net-02.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.054 ms

我么自定义的网络docker都已经帮我们维护好了对应的关系

好处:

redis:不同的集群使用不同的网络,保证集群是安全和健康的

mysql:不同的集群使用不同的网络,保证集群是安全和健康的

网络连通

#尝试将tomcat01和tomcat-net-01连通
[root@iZ2vc7zktoz7z9fn3qhptjZ ~]# docker exec -it tomcat01 ping tomcat-net-01
ping: tomcat-net-01: Name or service not known
#失败

在这里插入图片描述

在这里插入图片描述

#测试  tomcat能否ping通tomcat-net-01
docker network connect mynet tomcat01
#连通之后就是将tomcat01放到了mynet网络下
#一个容器两个ip地址

在这里插入图片描述

[root@iZ2vc7zktoz7z9fn3qhptjZ ~]# docker exec -it tomcat01 ping tomcat-net-01
PING tomcat-net-01 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat-net-01.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.072 ms
64 bytes from tomcat-net-01.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.053 ms
64 bytes from tomcat-net-01.mynet (192.168.0.3): icmp_seq=3 ttl=64 time=0.055 ms
#tomcat01和tomcat-net-01连通

#tomcat02依旧是打不通的
[root@iZ2vc7zktoz7z9fn3qhptjZ ~]# docker exec -it tomcat02 ping tomcat-net-01
ping: tomcat-net-01: Name or service not known

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

实战:部署redis集群

在这里插入图片描述

#创建网卡
docker network create redis --subnet 172.38.0.0/16

#通过脚本创建6个Redis配置
redis集群
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

运行部分
for port in $(seq 1 6); \
do
docker run -p 637${port}:6379 -p 1637${port}:16379 --name redis-${port} \
-v /mydata/redis/node-${port}/data:/data \
-v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf; \
done


#创建集群
[root@iZ2vc7zktoz7z9fn3qhptjZ conf]# docker exec -it redis-1 /bin/sh
/data # ls
appendonly.aof  nodes.conf
/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: 3d08d4a1b1a69e6541f94748cf58f0e3d406c7f5 172.38.0.11:6379
   slots:[0-5460] (5461 slots) master
M: 4409cb51675fd8cfc259b083991d40225329747f 172.38.0.12:6379
   slots:[5461-10922] (5462 slots) master
M: f0bf7d6fce8e15091e4de77d2e3c0fc28db6c4d5 172.38.0.13:6379
   slots:[10923-16383] (5461 slots) master
S: eca5b549a77c15e0274f2472600bfbf05dc00b82 172.38.0.14:6379
   replicates f0bf7d6fce8e15091e4de77d2e3c0fc28db6c4d5
S: 92d808d95466384e4dc5f26d2b50f77f0207e887 172.38.0.15:6379
   replicates 3d08d4a1b1a69e6541f94748cf58f0e3d406c7f5
S: 6856d04ed4b0b2ef5257ff3f9638518089eb1133 172.38.0.16:6379
   replicates 4409cb51675fd8cfc259b083991d40225329747f
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
..
>>> Performing Cluster Check (using node 172.38.0.11:6379)
M: 3d08d4a1b1a69e6541f94748cf58f0e3d406c7f5 172.38.0.11:6379
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
S: 92d808d95466384e4dc5f26d2b50f77f0207e887 172.38.0.15:6379
   slots: (0 slots) slave
   replicates 3d08d4a1b1a69e6541f94748cf58f0e3d406c7f5
S: 6856d04ed4b0b2ef5257ff3f9638518089eb1133 172.38.0.16:6379
   slots: (0 slots) slave
   replicates 4409cb51675fd8cfc259b083991d40225329747f
M: f0bf7d6fce8e15091e4de77d2e3c0fc28db6c4d5 172.38.0.13:6379
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
M: 4409cb51675fd8cfc259b083991d40225329747f 172.38.0.12:6379
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: eca5b549a77c15e0274f2472600bfbf05dc00b82 172.38.0.14:6379
   slots: (0 slots) slave
   replicates f0bf7d6fce8e15091e4de77d2e3c0fc28db6c4d5
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

#测试
/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:186
cluster_stats_messages_pong_sent:199
cluster_stats_messages_sent:385
cluster_stats_messages_ping_received:194
cluster_stats_messages_pong_received:186
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:385
127.0.0.1:6379> cluster nodes
92d808d95466384e4dc5f26d2b50f77f0207e887 172.38.0.15:6379@16379 slave 3d08d4a1b1a69e6541f94748cf58f0e3d406c7f5 0 1635347376000 5 connected
6856d04ed4b0b2ef5257ff3f9638518089eb1133 172.38.0.16:6379@16379 slave 4409cb51675fd8cfc259b083991d40225329747f 0 1635347377502 6 connected
f0bf7d6fce8e15091e4de77d2e3c0fc28db6c4d5 172.38.0.13:6379@16379 master - 0 1635347376501 3 connected 10923-16383
4409cb51675fd8cfc259b083991d40225329747f 172.38.0.12:6379@16379 master - 0 1635347376501 2 connected 5461-10922
3d08d4a1b1a69e6541f94748cf58f0e3d406c7f5 172.38.0.11:6379@16379 myself,master - 0 1635347375000 1 connected 0-5460
eca5b549a77c15e0274f2472600bfbf05dc00b82 172.38.0.14:6379@16379 slave f0bf7d6fce8e15091e4de77d2e3c0fc28db6c4d5 0 1635347377002 4 connected
127.0.0.1:6379> set a b
-> Redirected to slot [15495] located at 172.38.0.13:6379
OK
172.38.0.13:6379> get a
Could not connect to Redis at 172.38.0.13:6379: Host is unreachable
(18.18s)
not connected> 
/data # redis-cli -c
127.0.0.1:6379> get a
-> Redirected to slot [15495] located at 172.38.0.14:6379
"b"
172.38.0.14:6379> cluster nodes
92d808d95466384e4dc5f26d2b50f77f0207e887 172.38.0.15:6379@16379 slave 3d08d4a1b1a69e6541f94748cf58f0e3d406c7f5 0 1635347593557 1 connected
f0bf7d6fce8e15091e4de77d2e3c0fc28db6c4d5 172.38.0.13:6379@16379 master,fail - 1635347462939 1635347462000 3 connected
3d08d4a1b1a69e6541f94748cf58f0e3d406c7f5 172.38.0.11:6379@16379 master - 0 1635347594560 1 connected 0-5460
6856d04ed4b0b2ef5257ff3f9638518089eb1133 172.38.0.16:6379@16379 slave 4409cb51675fd8cfc259b083991d40225329747f 0 1635347593958 6 connected
4409cb51675fd8cfc259b083991d40225329747f 172.38.0.12:6379@16379 master - 0 1635347593057 2 connected 5461-10922
eca5b549a77c15e0274f2472600bfbf05dc00b82 172.38.0.14:6379@16379 myself,master - 0 1635347594000 7 connected 10923-16383

SpringBoot微服务打包Docker镜像

1.构建springboot项目

2.打包应用

3.编写dockerfile

4.构建镜像

5.发布运行

Docker进阶

Docker Compose

Docker Compose轻松高效管理容器

官方介绍

定义运行多个容器

YAML file配置文件

Using Compose is basically a three-step process:

  1. Define your app’s environment with a Dockerfile so it can be reproduced anywhere.
  2. Define the services that make up your app in docker-compose.yml so they can be run together in an isolated environment.
  3. Run docker compose up and the Docker compose command starts and runs your entire app. You can alternatively run docker-compose up using the docker-compose binary.
version: "3.9"  # optional since v1.27.0
services:
  web:
    build: .
    ports:
      - "5000:5000"
    volumes:
      - .:/code
      - logvolume01:/var/log
    links:
      - redis
  redis:
    image: redis
volumes:
  logvolume01: {}

compose重要概念

  • 服务service,容器,应用(Redis,mysql)
  • 项目project 一组关联的容器

安装

1.下载

curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

#或者
curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.5/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose

2.授权

chmod +x /usr/local/bin/docker-compose
#查看是否安装成功
[root@ybw bin]# docker-compose version
docker-compose version 1.25.5, build 8a1c60f6
docker-py version: 4.1.0
CPython version: 3.7.5
OpenSSL version: OpenSSL 1.1.0l  10 Sep 2019

3.体验

[root@ybw bin]# docker-compose version
docker-compose version 1.25.5, build 8a1c60f6
docker-py version: 4.1.0
CPython version: 3.7.5
OpenSSL version: OpenSSL 1.1.0l  10 Sep 2019

1.应用app.py

2.Dockerfile 应用打包为镜像

3.Docker-compose.yaml(定义整个服务需要的环境 web redis)

4.启动docker-compose(docker-compose up)

流程

1.创建网络

2.执行docker-compose.yaml

3.启动服务

[root@ybw composetest]# docker-compose up
Starting composetest_web_1 ... 
Starting composetest_web_1 ... done

#步骤
1.创建项目文件夹
mkdir composetest
cd 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)
    
if __name__ == "__main__":
    app.run(host="0.0.0.0",debug=True)

#3创建requirements.txt
flask
redis

#4创建Dockerfile
FROM python:3.6-alpine
ADD . /code
WORKDIR /code
RUN pip install -r requirements.txt
CMD ["python", "app.py"]


#4创建docker-compose.yml文件
version: "3.8"
services:
  web:
    build: .
    ports:
      - "5000:5000"
    volumes:
      - .:/code      
  redis:
    image: "redis:alpine"
    
#5使用docker-compose up 启动

在这里插入图片描述

默认的服务名 :文件名_______服务名____num

网络规则

在这里插入图片描述

在这里插入图片描述

以前都是单个docker run 启动容器

docker-compose,通过编写yml文件,一次启动或停止多个容器

yaml规则

#docker-compose.yml
#3层
version:'3.8'
service:
  服务1:web
    #服务配置
    images
    build
  服务2:redis
    #服务配置
    
  服务3:
  
#第3层 其它配置
volumes:
network:

实战

docker-compose up --build #重新构建

Docker Swarm

1.生成主节点 docker swarm init

2.加入

十分简单:集群,可用!3个主节点

Raft协议

双主双从:假设一个节点挂了,其它节点是否可用

Raft协议:保证绝大多数节点存活才可用,只要>1,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值