Docker安装(linux)

安装docker

# 卸载干净
$ sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

# 安装包
yum install -y yum-utils
# 设置镜像仓库
yum-config-manager \
    --add-repo \
    http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 更新yum软件包索引
yum makecache fast
# 安装docker相关的包
yum install docker-ce docker-ce-cli containerd.io

# 启动docker
systemctl start docker
# 运行docker容器
docker run hello-world

Docker卸载(linux)

1、卸载依赖
yum remove docker-ce docker-ce-cli containerd.io
2、删除资源
rm -rf /var/lib/docker

配置Docker加速

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
    "registry-mirrors":["https://阿里云节点"]
   
}

修改Docker默认镜像储存位置

暂停docker

wsl --shutdown

导出原有镜像

wsl --export docker-desktop "D:\Docker\wsl\data\docker-desktop.tar"
wsl --export docker-desktop-data "D:\Docker\wsl\data\docker-desktop-data.tar"

取消原有镜像

wsl --unregister docker-desktop
wsl --unregister docker-desktop-data

导入镜像

wsl --import docker-desktop D:\Docker\wsl\distro D:\Docker\wsl\data\docker-desktop.tar --version 2
wsl --import docker-desktop-data D:\Docker\wsl\data D:\Docker\wsl\data\docker-desktop-data.tar --version 2

Docker常用命令

docker version          # 显示docker的版本
docker info             # 显示docker系统级信息,包括镜像和容器的数量
docker 命令 --help       # 帮助命令

帮助文档(中文)

镜像命令

docker images           # 查看镜像
-a                      # 显示所有的镜像
-q                      # 只显示容器的id

docker search           # 搜索镜像
--fileter=STARS=3000    # 搜索出来的镜像就是stars大于3000的

docker pull             # 下载镜像
docker pull mysql:5.7

删除镜像

docker rmi -f images id
docker rmi -f $(docker images -aq)       # 删除所有的images

运行容器命令

docker run [可选参数] image
参数说明
--name=“name” # 容器命令
-d            # 后台运行
-it           # 使用交互方式运行,进入容器查看内容
-p            # 指定容器的端口 -p 80:80
        -p ip:主机端口:容器端口
        -p 主机端口容器端口(常用)
        -p 容器端口
        
-P(大写)  # 随机指定端口
docker run -itd -p 80:80 [imgaes]

列出所有的运行容器

docker ps
-a      # 显示所有的容器+历史运行的容器
-n=# 列出最近创建的容器
-q      # 只显示容器的编号

退出容器

exit        # 退出并通知容器
Ctrl+p+q    # 容器不停止退出

删除容器

docker rmi -f 镜像id                # 删除指定镜像
docker rmi -f 镜像id 镜像id 镜像id   # 删除多个镜像 
docker rmi -f $(docker images aq)   # 删除全部镜像

docker rm -f 容器id                 # 删除指定容器
docker rm -f 容器 容器 镜像id        # 删除多个容器 
docker rm -f $(docker ps -aq)       # 删除全部容器
docker ps -a -q|xargs docker rm     # 删除全部容器

启动和停止容器的操作

docker start
docker restart
docker stop
docker kill 

常用其他命令

后台启动容器
docker run -d 镜像
问题 docker ps 发现容器停止
docker容器使用后台运行,就必须有应该前台进程,docker发现没有应用就会停止

查看日志

docker log -f -t --tail 容器,没有日志

查看容器的信息

docker inspect 容器
# 将本地的镜像导出
docker save -o 导出的路径 镜像id

# 加载本地的镜像文件
docker load -i 镜像文件

# 修改镜像文件
docker tag 镜像id 新镜像名称:版本

# 保存当前容器的状态
docker commit  [CONTAINER ID] demo:v1.3

进入当前正在运行的容器

方法1
docker exec -it 容器id /bin/bash
方法2
docker attach  容器id 
区别:
exec命令,进入容器后开启一个新的终端,可以操作(常用)
attach命令,进入容器正在执行的终端,不会启动新的进程

从容器拷贝文件到主机上

docker cp 容器:容器内的路径 主机的路径
同理的主机到容器

部署es+kubana

# 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是否成功
# 访问 http://127.0.0.1:9200
{
  "name" : "1043572a13e5",
  "cluster_name" : "docker-cluster",
  "cluster_uuid" : "X5qHk_JRRhK9HPKWfaMvYg",
  "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"
}
# 增加内存的限制,修改配置文件 -e 环境配置修改
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.6.2

作业:使用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(CI/CD再用)

什么是portainer?

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

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

Docker镜像讲解

镜像是什么

镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含
运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。

所有应用,直接打包docker镜像,就可以直接跑起来!

  • 从远程仓库下载

  • 朋友拷贝给你

  • 自己制作镜像Dockerfile

Docker镜像加载原理

UnionFS(联合文件系统)

我们下载的时候看到的一层层就是这个

UnionFS(联合文件系统):Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,
它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系
统下(unite several directories into a single virtual filesystem)。Union 文件系统是 Docker 镜像的基
础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件
系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录

Docker镜像加载原理

docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。
bootfs(boot file system)主要包含bootloader和kernel, bootloader主要是引导加载kernel, Linux刚启
动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs。这一层与我们典型的Linux/Unix系统是
一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已
由bootfs转交给内核,此时系统也会卸载bootfs。

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

如何提交一个自己的镜像

commit镜像

docker commit 提交容器成为一个新容器

docker commit -m="提交描述信息" -a="作者" 容器id 目标镜像名:[tag]

实战测试

# 1、启动一个默认的tomcat

# 2、发现这个tomcat没有webapps应用,官方镜像webapps没有文件!

# 3、自己拷贝进去基本的文件
# 4、将我们操作过的容器通过commit提交为一个镜像,我们以后就是用我们修改过的镜像

image-20211006180546891

学习方式说明:理解概念,但是一定要实践

如果你想要保存当前容器的状态,就可以通过commit来提交,获得一个镜像
相当于快照

到这里才是入门!!!学习不需要坚持,学习是爱好!!!

容器数据卷

什么是容器数据卷

docker的理念和回顾

将应用和环境打包成一个镜像!

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

MySQL,容器删除,删库跑路!==需求:MySQL数据可以储存在本地==!

容器之间可以有一个共享的技术!Docker容器中产生的数据,同步到本地!

这就是卷技术!目录的挂载,将我们的容器内的目录,挂在到Linux什么!

image-20211006195711247

总结一句话:容器的持久化和同步操作!容器间也是可以数据共享的!

使用数据卷

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

docker run -it -v 主机目录:容器目录
# 测试
docker run -it -v D:/dockertest/tomcat:/home tomcat /bin/bash

这里可以看到成功挂载了

挂载成功

测试同步

image-20211006201602762

再来测试!

1、停止容器

2、宿主机上修改文件

3、启动容器

4、容器内的数据依旧是同步的!

image-20211006202110667

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

实战:安装MySQL

思考: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 环境配置
--name 容器名字
docker run -d -p 3310:3306 -v D:/dockertest/mysql/conf:/etc/mysql/conf.d -v D:/dockertest/mysqldata:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7

启动成功

假设我们将容器删除

image-20211006204840217

发现我们挂载到本地的数据卷依旧没有丢失,这就实现了容器数据的持久性功能

具名和匿名挂载

# 匿名挂载(直接写容器捏路径,不去写主机内路径,可以自动生成主机路径)
-v 容器内路径
docker run -d -P --name nginx01 -v /etc/nginx nginx

# 查看volume情况
PS C:\Users\Wans> docker volume ls
DRIVER    VOLUME NAME
local     2de53d078ecf017bc509e723f27f6b561f665c0cccf7946d62882e89493ce68a

# 这里发现,这种没有名字就是匿名挂载,我们在-v只写了容器内的路径,没写容器外的路径


# 具名挂载
PS C:\Users\Wans> docker run -d -P --name nginx02 -v jvming:/etc/nginx nginx
4e3ecbe8f7ab5c25b2a00cb882f0c744bb5c849070c7a7772fb304e7a1a4df2c
PS C:\Users\Wans> docker volume ls
DRIVER    VOLUME NAME
local     jvming
PS C:\Users\Wans>
# 通过-v 卷名:容器内路径
# 查看一下这个卷

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

我们通过具名挂载可以方便的找到我们的一个卷,大多数情况在使用的具名挂载

# 如何确定是具名挂载还是匿名挂载,还是指定路径挂载!
-v 容器内路径	#匿名挂载
-v 卷名:容器内路径	#具名挂载
-v /宿主机路径:容器内路径	# 指定路径挂载!

拓展

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

# 一旦这个设置了容器权限,容器对我们挂载出来的内容就有限了
docker run -d -P --name nginx02 -v jvming:/etc/nginx:ro nginx
docker run -d -P --name nginx02 -v jvming:/etc/nginx:rw nginx

# ro只要看到ro说明这个路径只能通过宿主机来操作,容器内部无法操作

初始Dockerfile

Dockerfile就是用来构建dockers镜像的构建文件!命令脚本、先体验一下!

# 创建Dockerfile文件,名字可以随意,建议dockerfile
FROM centos
VOLUME ["volume01","volume02"]
CMD echo "----end----"
CMD /bin/bash

image-20211006221917614

# 启动自己写的容器

image-20211006222316149

这个卷和外部一定是同步的

测试一下刚才的文件是否同步出去了!

这种方式我们未来使用的十分多,因为我们通常会构建自己的镜像!

假设构建镜像时候没有挂载卷,要手动镜像挂载-v卷名:容器内路径!

数据卷容器

多个mysql同步数据!

image-20211006223333496

# 启动3个容器,通过我们刚才自己的写镜像启动

image-20211006224547475

image-20211006224352364

# 测试,删除docker01,查看docker02和docker03依旧可以访问volume

image-20211006225002861

多个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 --volome-from mysql01 mysql:5.7

# 这时候可以实现两个容器数据同步

结论:

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

但是一旦你持久化到本地这个时候,本地的数据不会删除

Dockerfile

Dockerfile介绍

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

构建步骤:

1、编写dockerfile文件

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

3、docker run 运行镜像

4、docker push 发布镜像(dockerhub、阿里云镜像仓库)

image-20211007061934942

image-20211007062001424

很多官方镜像都是基础包好的功能没有,我们提出会搭建自己的镜像

Dockerfile构建过程

基础知识

1、每个保留关键字(指令)都是必须是大写字母

2、执行是从上到下顺序执行

3、# 表示注释

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

image-20211007062549193

步骤:开发、部署、运维、缺一不可

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

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

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

Dockerfile的指令

FROM		# 基础镜像,一切从这里开始构建
MAINTAINER	# 镜像构建者信息:姓名+邮箱
RUN			# 镜像构建的时候要运行的命令
ADD			# 步骤:tomecat镜像,这个tomcat压缩包!添加内容
WORKDIR		# 镜像的工作目录
VOLUME		# 挂载的目录
EXPOST		# 保留端口配置
CMD			# 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT	# 指定这个容器启动的时候要运行的命令
ONBUILD		# 当构建一个被继承Dockerfile这个时候就会运行ONBUILD的指令,出发指令
COPY		# 类似ADD,将我们文件拷贝到镜像中
ENV			# 构建的时候设置环境变量 -e

image-20211007064730968

实战测试

Docker hub 中99%都是从FROM scratch,然后配置需要的软件和配置来进行的构建

创建自己的centos镜像

# 1、编写Dockerfiel文件

# FROM centos
# VOLUME ["volume01","volume02"]
# CMD echo "----end----"
# CMD /bin/bash
FROM centos
MAINTAINER Wans<wa.ns@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 -f <dockerfile文件路径> -t 镜像名:[tag]

# 3、测试运行,添加了vim和ifconfig

image-20211007074651332

我们可以看看镜像的历史记录,就可以永久它是怎么做的

image-20211007075255351

CMD和ENTRYPOINT区别

# 编写dokcerfile文件
FROM centos
CMD ["ls","-a"]

# 构建镜像
PS D:\dockertest> docker build -f Dockerfile -t cmdtest:0.1 .
[+] Building 22.3s (5/5) FINISHED
 => [internal] load build definition from Dockerfile                                                                              2.5s
 => => transferring dockerfile: 381B                                                                                              0.0s
 => [internal] load .dockerignore                                                                                                 3.8s
 => => transferring context: 2B                                                                                                   0.0s
 => [internal] load metadata for docker.io/library/centos:latest                                                                 16.4s
 => CACHED [1/1] FROM docker.io/library/centos@sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177            0.0s
 => exporting to image                                                                                                            0.7s
 => => exporting layers                                                                                                           0.0s
 => => writing image sha256:7d202bdf002be182b794b7f2b4c90c4fe3560c3ac4f8cebc27f1c8a94ab10a9a                                      0.3s
 => => naming to docker.io/library/cmdtest:0.1                                                                                    0.4s

Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them

# run运行,发现ls -a命令生效
PS D:\dockertest> docker run cmdtest:0.1
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
# 无法追加-l命令
PS D:\dockertest> docker run cmdtest:0.1 -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.
#cmd的情况下 -l 替换 CMD ["ls","-a"]命令,-l不是命令所以报错!
# 使用ENTRYPOINT 则可以在run后面加-l

Dockerfile中很多命令都十分相似,我们需要了解他们的区别。

实战:Tomcat镜像

1、准备镜像文件tomcat压缩包,jdk的压缩包

image-20211007115140033

2、 编写dockerfile文件,

官方命名Dockerfile,build会自动寻找这个文件,就不需要-f指定了

# vim Dockerfile
FROM centos
MAINTAINER Wans<wa.ns@qq.com>

# 把宿主机当前上下文的read.txt拷贝到容器/usr/local/路径下
COPY Readme.md /usr/local/Readme.md

# 把java与tomcat添加到容器中
ADD jdk-8u11-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.54.tar.gz /usr/local/

# 安装vim编辑器
RUN yum -y install vim

# 设置工作访问时候的WORKDIR路径,登录落脚点
ENV MYPATH /usr/local
WORKDIR $MYPATH

# 配置java与tomcat环境变量
ENV JAVA_HOME /usr/local/jdk-8u11-linux-x64
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 /url/local/apache-tomcat-9.0.54/bin/logs/catalina.out

3、构建镜像

docker build -t wanstomcat .

4、启动镜像

docker run -d -p 9090:8080 --name wanstomcat -v D:/dockertest/tomcat/test:/usr/local/apache-tomcat-9.0.54/webapps/test -v  D:/dockertest/tomcat/logs/:/url/local/apache-tomcat-9.0.54/logs wanstomcat

5、 访问测试

image-20211008062543095

6、发布项目(由于做了卷挂载,我们直接本地编写项目就可以发布了)

Dockers网络

理解Docker0

# 问题Docker怎么处理容器网络访问的?

image-20211008204301074

# docker run -d -P --name tomcat01 tomcat


# 查看容器的内部网络地址 ip addr 因为我下载的tomcat 没有ip addr 命令
# 所以我就使用了ls -la测试了一下

docker exec -it tomcat01 ls -la

PS C:\Users\Wans> docker exec -it 7c2708f0dd7a ls -la
total 176
drwxr-xr-x 1 root root  4096 Oct  6 19:10 .
drwxr-xr-x 1 root root  4096 Sep 29 11:13 ..
-rw-r--r-- 1 root root 18994 Sep 28 13:34 BUILDING.txt
-rw-r--r-- 1 root root  6210 Sep 28 13:34 CONTRIBUTING.md
-rw-r--r-- 1 root root 60269 Sep 28 13:34 LICENSE
-rw-r--r-- 1 root root  2333 Sep 28 13:34 NOTICE
-rw-r--r-- 1 root root  3372 Sep 28 13:34 README.md
-rw-r--r-- 1 root root  6905 Sep 28 13:34 RELEASE-NOTES
-rw-r--r-- 1 root root 16517 Sep 28 13:34 RUNNING.txt
drwxr-xr-x 2 root root  4096 Oct  6 19:10 bin
drwxr-xr-x 1 root root  4096 Oct  8 13:05 conf
drwxr-xr-x 2 root root  4096 Oct  6 19:10 lib
drwxrwxrwx 1 root root  4096 Oct  8 13:05 logs
drwxr-xr-x 2 root root  4096 Oct  6 19:10 native-jni-lib
drwxrwxrwx 2 root root  4096 Oct  6 19:10 temp
drwxr-xr-x 2 root root  4096 Oct  6 19:10 webapps
drwxr-xr-x 7 root root  4096 Sep 28 13:34 webapps.dist
drwxrwxrwx 2 root root  4096 Sep 28 13:34 work
PS C:\Users\Wans>
# linux 可以 ping 通 docker 容器内部

原理

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

# evth-pair 就是一对的虚拟设备接口,他们都是成对出现的,一段连着协议,一段彼此相连
# evth-pair充当桥梁,连接各种虚拟网络设备的
# openStac,docker容器之间的连接,ovs的连接,都是evth-pair技术

2、tomcat01和tomcat02直接可以ping通

image-20211008223737900

结论:tomcat01和tomcat02是共用一个路由器,docker0

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

小结

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

image-20211008224414385

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

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

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

# 不能ping通
# PS D:\Users\Wans\Desktop> docker exec -it tomcat02 ping tomcat01

# 通过 --link可以解决名字ping
docker run -d -P --name tomcat03 --link tomcat02 tomcat

# 反向不可以ping通
docker exec -it tomcat02 ping tomcat03

image-20211008230158994

# 这里看到--link将tomcat02的地址写在hosts中

现在已经不推荐–linkl

自定义网络!!不适合docker0!

docker0问题:不支持容器名连接访问

自定义网络

查看所有的docker网络

image-20211008230613841

网络模式

bridge:桥接模式(莫仍,自己创建也使用桥接模式)

host:主机模式(和宿主机共享网络)

none:不配网络

container:容器网络连通(用的少,局限大)

测试

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

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

# 查看创建网卡的命令
PS D:\Users\Wans\Desktop> docker network create --help

Usage:  docker network create [OPTIONS] NETWORK

Create a network

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
PS D:\Users\Wans\Desktop>

# 成功创建网卡
PS D:\Users\Wans\Desktop> docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
108130a48496e1f9e2b864cc3fb324dbdd4ccc1822985307773789b7c8ae6e3e
PS D:\Users\Wans\Desktop> docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
e02c3a9814c2   bridge    bridge    local
ac450d1a3661   host      host      local
108130a48496   mynet     bridge    local
1e32ceb0b028   none      null      local
PS D:\Users\Wans\Desktop>

image-20211010212207280

网络连通

image-20211010212416674

image-20211010212444973

# 测试打通 tomcat -mynet

# 连通之后就是将tomcat01放到了mynet网络下
# 一个容器两个ip地址 ! 
# 相当于阿里云服务,内网ip和公网ip

image-20211010212709223

结论:假设要跨网络操作别人,就需要docker network connet连通

实战:Redis集群

image-20211010213235048

shell脚本!

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

# 通过脚本创建六个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

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; \

# 启动6个容器
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

image-20211010220516620

# 进入redis
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: 008bae73c70dc85404d37bd5a2e50803d63c01db 172.38.0.11:6379
   slots:[0-5460] (5461 slots) master
M: 08a33c605873c8dc30fd0b883310e09647c22ef8 172.38.0.12:6379
   slots:[5461-10922] (5462 slots) master
M: 08da98ed12ca231a64fb18b168df106bcdbc1132 172.38.0.13:6379
   slots:[10923-16383] (5461 slots) master
S: 6c466d74c7e2b505c1732280fea7f13177467e2d 172.38.0.14:6379
   replicates 08da98ed12ca231a64fb18b168df106bcdbc1132
S: e24369c4771b8948325dd5ce2eb4bd99dab415d9 172.38.0.15:6379
   replicates 008bae73c70dc85404d37bd5a2e50803d63c01db
S: 32fc9e78674f24cefcc070052f1de39fbf54e4f2 172.38.0.16:6379
   replicates 08a33c605873c8dc30fd0b883310e09647c22ef8
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: 008bae73c70dc85404d37bd5a2e50803d63c01db 172.38.0.11:6379
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: 08a33c605873c8dc30fd0b883310e09647c22ef8 172.38.0.12:6379
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: 32fc9e78674f24cefcc070052f1de39fbf54e4f2 172.38.0.16:6379
   slots: (0 slots) slave
   replicates 08a33c605873c8dc30fd0b883310e09647c22ef8
S: 6c466d74c7e2b505c1732280fea7f13177467e2d 172.38.0.14:6379
   slots: (0 slots) slave
   replicates 08da98ed12ca231a64fb18b168df106bcdbc1132
S: e24369c4771b8948325dd5ce2eb4bd99dab415d9 172.38.0.15:6379
   slots: (0 slots) slave
   replicates 008bae73c70dc85404d37bd5a2e50803d63c01db
M: 08da98ed12ca231a64fb18b168df106bcdbc1132 172.38.0.13:6379
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

Docker搭建redis集群完成

image-20211010221506757

我们使用了docker之后,所有的技术都会简单

SpringBoot微服务打包Docker镜像

1、使用 IDEA 构建一个 SpringBoot 项目

2、编写一个helloController

@RestController
public class HelloController {
	@GetMapping("/hello")
	public String hello(){
		return "hello,kuangshen";
	}
}

3、启动测试下,端口修改下,避免8080冲突!本地访问没问题就可以!

4、打jar包

image-20211010223916639

有了 jar 包,我们就可以作镜像了! 记得测试一下jar包可以使用吗!

打包镜像

1、在项目下编写 Dockerfile 文件,将打包好的jar包拷贝到Dockerfile同级目录

FROM java:8
# 服务器只有dockerfile和jar在同级目录
COPY *.jar /app.jar
CMD ["--server.port=8080"]
# 指定容器内要暴露的端口
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app.jar"]

2、将Dockerfile 和 项目的 jar 包上传到linux服务器上,构建运行

[root@kuangshen idea]# pwd
/home/idea
[root@kuangshen idea]# ll
total 17228
-rw-r--r-- 1 root root 17634294 May 14 12:33 demo-0.0.1-SNAPSHOT.jar
-rw-r--r-- 1 root root 207 May 14 12:32 Dockerfile
# 构建镜像
docker build -t idea-ks .
# 查看镜像
docker images
# 运行
docker run -d -P --name idea-ks idea-ks
[root@kuangshen ~]# docker ps
CONTAINER ID IMAGE PORTS NAMES
2366c960ba99 idea-ks 0.0.0.0:32779->8080/tcp idea-ks1
# 测试访问
[root@kuangshen ~]# curl localhost:32779
[root@kuangshen ~]# curl localhost:32779/hello

Docker Compose

安装Docker-compose

1、下载安装

sudo 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.29.2/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
# 添加执行权限
sudo chmod +x /usr/local/bin/docker-compose

2、体验

博客WordPress

1、下载,安装数据库、配置、、

compse应用—》一键启动

1、下载项目(docker-compose.yam)

2、如果需要文件,dockerfile

3、文件准备齐全一键启动

创建docker-compose.yml

将下面脚本写入

然后执行docker-compose up

version: "3.9"
    
services:
  db:
    image: mysql:5.7
    volumes:
      - db_data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: somewordpress
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress
    
  wordpress:
    depends_on:
      - db
    image: wordpress:latest
    volumes:
      - wordpress_data:/var/www/html
    ports:
      - "8000:80"
    restart: always
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WORDPRESS_DB_NAME: wordpress
volumes:
  db_data: {}
  wordpress_data: {}

前台启动

docker -d

docker-compose up -d