Docker学习笔记

Docker

Docker和虚拟机技术的不同:

  • 传统虚拟机,虚拟出以系列硬件,运行一个完整的操作系统,然后在这个系统上安装和运行软件
  • 容器内应用直接运行在宿主机的内部,容器是没有自己的内核的,也没有虚拟我们的硬件,所以就轻便了
  • 每个容器间相互隔离,每个容器内都有一个属于自己的文件系统,互不影响

Docker的基本组成

image-20210617231142691

镜像:

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

容器:

Docker利用容器技术,独立运行一个或者一个组应用,通过镜像来创建的

可以启动,停止,删除,基本命令!

目前就可以把这个容器理解为就是一个简易的linux系统

仓库:

存放镜像的地方!

仓库分为公有仓库和私有仓库

Docker Hub(默认是国外的)

阿里云…都有容器服务器(配置镜像加速)

安装Docker

卸载旧的版本

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

安装

#需要的安装包
sudo yum install -y yum-utils
#设置镜像的仓库(国外)
 sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo #默认国外
 sudo yum-config-manager \
    --add-repo \
	https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo#阿里云镜像
#更新yum软件包索引
sudo yum makecache fast
#安装docker引擎,docker-ce 社区 ee 企业版
sudo yum install docker-ce docker-ce-cli containerd.io

启动docker

sudo systemctl start docker

使用docker version命令检测是否安装成功

image-20210712150236574

测试

#测试
docker run hello-world

image-20210712150541329

#查看一下下载的这个hello-world镜像
[root@localhost ~]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
hello-world   latest    d1165f221234   4 months ago   13.3kB

阿里云镜像加速

image-20210712151708961

配置

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

HelloWorld流程

image-20210712152223262

底层原理

Docker是怎么工作的?

Docker是一个Client-Server结构的系统,Docker的守护进程运行在主机上,通过Socket从客户端访问!

DockerServer接受到Docker-client的指令,就会执行这个命令!

image-20210712152820181

Docker为什么比VM快?

  1. Docker有着比虚拟机更少的抽象层

  2. Docker利用的是宿主机的内核,vm需要的是Guest OS

    image-20210712163511684

所以,新建一个容器的时候,docker不需要像虚拟机一样重新加载一个操作系统内核,避免引导,虚拟机是加载Guest OS,分钟级别的,而docker是利用宿主机的操作系统,省略了这个复杂的过程,秒级!

image-20210712164015883

Docker常用命令

帮助命令

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

镜像命令

docker images查看所有本地主机上的镜像

[root@localhost /]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
hello-world   latest    d1165f221234   4 months ago   13.3kB
#Repository 镜像的仓库源
#TAG        镜像的标签
#IMAGE ID   镜像的id
#CREATED    镜像创建时间
#SIZE       镜像的大小
#可选项:
-a,--all    #列出所有镜像
-q,--quiet  #只显示镜像的ID

docker search搜索镜像

image-20210712195649186

#可选项,通过搜藏来过滤
--filter=stars=3000 搜索出来的镜像就是STARS大于3000的

image-20210712195824571

下载镜像 docker pull

#下载镜像 docker pull 镜像名[:tag(可以加版本)]
[root@localhost /]# docker pull mysql
Using default tag: latest  #如果不写tag,默认是latest
latest: Pulling from library/mysql
b4d181a07f80: Pull complete #分层下载,docker image核心,联合文件系统
a462b60610f5: Pull complete 
578fafb77ab8: Pull complete 
524046006037: Pull complete 
d0cbe54c8855: Pull complete 
aa18e05cc46d: Pull complete 
32ca814c833f: Pull complete 
9ecc8abdb7f5: Pull complete 
ad042b682e0f: Pull complete 
71d327c6bb78: Pull complete 
165d1d10a3fa: Pull complete 
2f40c47d0626: Pull complete 
Digest: sha256:52b8406e4c32b8cf0557f1b74517e14c5393aff5cf0384eff62d9e81f4985d4b #签名
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest #真实地址

#下面两个等价:
docker pull mysql
docker pull docker.io/library/mysql:latest
##############################################
[root@localhost /]# docker pull mysql:5.7 #我们指定版本下载
5.7: Pulling from library/mysql
b4d181a07f80: Already exists              #联合文件系统的好处,重复的不会再下载一次
a462b60610f5: Already exists 
578fafb77ab8: Already exists  
524046006037: Already exists 
d0cbe54c8855: Already exists 
aa18e05cc46d: Already exists 
32ca814c833f: Already exists 
52645b4af634: Pull complete 
bca6a5b14385: Pull complete 
309f36297c75: Pull complete 
7d75cacde0f8: Pull complete 
Digest: sha256:1a2f9cd257e75cc80e9118b303d1648366bc2049101449bf2c8d82b022ea86b7
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7

image-20210712200735495

镜像删除

docker rmi -f Image ID/Repository #删一个

docker rmi -f Image ID/Repository Image ID/Repository Image ID/Repository #删多个

docker rmi -f $(docker images -aq) #删除全部容器

image-20210712200948219

容器命令

我们有了镜像才可以创建容器,linux,下载一个centos镜像来测试学习

docker pull centos

新建容器并启动

docker run [可选参数] image
#参数说明
--name="Name"  #容器名,用于区分容器
-d             #以后台方式运行,jar,nohup等
-it            #使用交互方式运行,进入容器查看内容
-p             #指定容器的端口 -p 8080:8080
   -p ip:主机端口:容器端口
   -p 主机端口:容器端口(常用)
   -p 容器端口
   容器端口
-P             #随机指定端口
#测试 启动并进入容器(通过镜像启动的容器)
[root@localhost /]# docker run -it centos /bin/bash
[root@bf73aa19db64 /]# ls #查看容器内的centos,但是里面也有很多不完善的内容
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@bf73aa19db64 /]# exit #退出
exit
[root@localhost /]# ls

image-20210712202239122

列出所有的运行的容器

#docker ps 命令                #列出当前正在运行的容器
                 -a           #列出当前正在运行的容器,顺便带出历史运行过的容器
                 -n = ?       #列出最近创建的容器,个数为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
bf73aa19db64   centos        "/bin/bash"   5 minutes ago   Exited (0) About a minute ago             angry_mendel
22f0d25c93ce   hello-world   "/hello"      5 hours ago     Exited (0) 5 hours ago                    happy_spence
600a632e59c3   hello-world   "/hello"      5 hours ago     Exited (0) 5 hours ago                    modest_rosalind
a1941ccd47ce   hello-world   "/hello"      5 hours ago     Exited (0) 5 hours ago                    determined_dijkstra
df2e4bb09c4f   hello-world   "/hello"      5 hours ago     Exited (0) 5 hours ago                    charming_kirch
cc4e5786f55e   hello-world   "/hello"      5 hours ago     Exited (0) 5 hours ago                    lucid_shaw
1257dd56ef94   hello-world   "/hello"      5 hours ago     Exited (0) 5 hours ago                    goofy_lamarr
40b3abea9f99   hello-world   "/hello"      2 months ago    Exited (0) 2 months ago                   pensive_brahmagupta

image-20210712202926674

退出容器

[root@bf73aa19db64 /]# exit #退出
exit
[root@localhost /]# ls

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

#进入容器:docker attach 容器ID
#               docker exec -it 容器ID /bin/bash 

image-20210712203156350

删除容器

docker rm 容器id              #删除一个指定的容器,不能强制删除,强制加上-f
docker rm -f(强制删除) $(docker ps -aq)#删除所有容器
docker ps -a -q|xargs docker rm       #删除所有容器

启动和停止容器

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

常用其他命令

后台启动容器

#docker run -d 镜像名!
[root@localhost ~]# docker ps -d centos
#docker ps-->发现centos停止了
#常见的坑,docker是容器使用后台运行,就必须就有一个前台进程,docker发现没有应用,就会自动停止
#nginx,容器启动后,发现自己没有提供服务,就会立刻停止,就是没有程序了

查看日志

#docker logs -f -t --tail n条 容器ID
--tf              #显示日志 f:follow动态显示 t:时间戳
--tail number     #显示数量
docker logs -tf --tail 10  5be3fa4037ab
#shell脚本
"whlie true;do echo myren;sleep 1;done"

查看容器中进程信息

#docker top 容器id号
[root@localhost ~]# docker top 9793d0141682
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                2251                2231                0                   10:15               pts/0               00:00:00            /bin/bash

查看镜像的源数据

#docker inspect 容器id号
[
    {
        "Id": "9793d01416827b71a36fa874eec275bc143c646e05ca169c6d8c6942943e82d9",
        "Created": "2021-07-16T02:15:43.904596549Z",
        "Path": "/bin/bash",
        "Args": [],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 2251,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2021-07-16T02:15:45.27440824Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
        "Image": "sha256:300e315adb2f96afe5f0b2780b87f28ae95231fe3bdd1e16b9ba606307728f55",
        "ResolvConfPath": "/var/lib/docker/containers/9793d01416827b71a36fa874eec275bc143c646e05ca169c6d8c6942943e82d9/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/9793d01416827b71a36fa874eec275bc143c646e05ca169c6d8c6942943e82d9/hostname",
        "HostsPath": "/var/lib/docker/containers/9793d01416827b71a36fa874eec275bc143c646e05ca169c6d8c6942943e82d9/hosts",
        "LogPath": "/var/lib/docker/containers/9793d01416827b71a36fa874eec275bc143c646e05ca169c6d8c6942943e82d9/9793d01416827b71a36fa874eec275bc143c646e05ca169c6d8c6942943e82d9-json.log",
        "Name": "/elegant_fermat",
        "RestartCount": 0,
        "Driver": "overlay2",
        "Platform": "linux",
        "MountLabel": "",
        "ProcessLabel": "",
        "AppArmorProfile": "",
        "ExecIDs": null,
        "HostConfig": {
            "Binds": null,
            "ContainerIDFile": "",
            "LogConfig": {
                "Type": "json-file",
                "Config": {}
            },
            "NetworkMode": "default",
            "PortBindings": {},
            "RestartPolicy": {
                "Name": "no",
                "MaximumRetryCount": 0
            },
            "AutoRemove": false,
            "VolumeDriver": "",
            "VolumesFrom": null,
            "CapAdd": null,
            "CapDrop": null,
            "CgroupnsMode": "host",
            "Dns": [],
            "DnsOptions": [],
            "DnsSearch": [],
            "ExtraHosts": null,
            "GroupAdd": null,
            "IpcMode": "private",
            "Cgroup": "",
            "Links": null,
            "OomScoreAdj": 0,
            "PidMode": "",
            "Privileged": false,
            "PublishAllPorts": false,
            "ReadonlyRootfs": false,
            "SecurityOpt": null,
            "UTSMode": "",
            "UsernsMode": "",
            "ShmSize": 67108864,
            "Runtime": "runc",
            "ConsoleSize": [
                0,
                0
            ],
            "Isolation": "",
            "CpuShares": 0,
            "Memory": 0,
            "NanoCpus": 0,
            "CgroupParent": "",
            "BlkioWeight": 0,
            "BlkioWeightDevice": [],
            "BlkioDeviceReadBps": null,
            "BlkioDeviceWriteBps": null,
            "BlkioDeviceReadIOps": null,
            "BlkioDeviceWriteIOps": null,
            "CpuPeriod": 0,
            "CpuQuota": 0,
            "CpuRealtimePeriod": 0,
            "CpuRealtimeRuntime": 0,
            "CpusetCpus": "",
            "CpusetMems": "",
            "Devices": [],
            "DeviceCgroupRules": null,
            "DeviceRequests": null,
            "KernelMemory": 0,
            "KernelMemoryTCP": 0,
            "MemoryReservation": 0,
            "MemorySwap": 0,
            "MemorySwappiness": null,
            "OomKillDisable": false,
            "PidsLimit": null,
            "Ulimits": null,
            "CpuCount": 0,
            "CpuPercent": 0,
            "IOMaximumIOps": 0,
            "IOMaximumBandwidth": 0,
            "MaskedPaths": [
                "/proc/asound",
                "/proc/acpi",
                "/proc/kcore",
                "/proc/keys",
                "/proc/latency_stats",
                "/proc/timer_list",
                "/proc/timer_stats",
                "/proc/sched_debug",
                "/proc/scsi",
                "/sys/firmware"
            ],
            "ReadonlyPaths": [
                "/proc/bus",
                "/proc/fs",
                "/proc/irq",
                "/proc/sys",
                "/proc/sysrq-trigger"
            ]
        },
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/66fac7b2997d07c11f72f8d9f89fc6394d7fe5ccb108efc83c5f1d3d0d580499-init/diff:/var/lib/docker/overlay2/d17b9013db6393be067e3fbd76d2f260657cdf98ef89717b1326dc03f955171a/diff",
                "MergedDir": "/var/lib/docker/overlay2/66fac7b2997d07c11f72f8d9f89fc6394d7fe5ccb108efc83c5f1d3d0d580499/merged",
                "UpperDir": "/var/lib/docker/overlay2/66fac7b2997d07c11f72f8d9f89fc6394d7fe5ccb108efc83c5f1d3d0d580499/diff",
                "WorkDir": "/var/lib/docker/overlay2/66fac7b2997d07c11f72f8d9f89fc6394d7fe5ccb108efc83c5f1d3d0d580499/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [],
        "Config": {
            "Hostname": "9793d0141682",
            "Domainname": "",
            "User": "",
            "AttachStdin": true,
            "AttachStdout": true,
            "AttachStderr": true,
            "Tty": true,
            "OpenStdin": true,
            "StdinOnce": true,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "/bin/bash"
            ],
            "Image": "300e315adb2f",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {
                "org.label-schema.build-date": "20201204",
                "org.label-schema.license": "GPLv2",
                "org.label-schema.name": "CentOS Base Image",
                "org.label-schema.schema-version": "1.0",
                "org.label-schema.vendor": "CentOS"
            }
        },
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "00fb7c24f450bc127ee443dcdabb3bb40b62d8ea33de2efd15727522270bd60d",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {},
            "SandboxKey": "/var/run/docker/netns/00fb7c24f450",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "804e6b3883b0ebf794b406da5398133d0e383d75263a172c3ad26ea3d787cf73",
            "Gateway": "172.17.0.1",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "172.17.0.2",
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
            "MacAddress": "02:42:ac:11:00:02",
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "4d095635101501a52f2b5745f1fd4f0dc0a03faffbe2ff49ac131a820b2b221f",
                    "EndpointID": "804e6b3883b0ebf794b406da5398133d0e383d75263a172c3ad26ea3d787cf73",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.2",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:02",
                    "DriverOpts": null
                }
            }
        }
    }
]

进入当前正在运行的容器

#进入后天运行的容器
# docker exec -it 容器id bashShell(/bin/bash)
# docker attach 容器id 进入容器正在执行的终端,不会启动新的进程

从容器内copy文件到主机上

#docker cp 容器id:容器内路径  目的主机路径
[root@localhost home]# docker attach 53ac4f6e0fd9
[root@53ac4f6e0fd9 /]# cd /home
[root@53ac4f6e0fd9 home]# ls
[root@53ac4f6e0fd9 home]# touch myren.java
[root@53ac4f6e0fd9 home]# exit
exit
[root@localhost home]# docker cp 53ac4f6e0fd9:/home/myren.java   /home
[root@localhost home]# ls
myren  myren.java  mysql80-community-release-el7-3.noarch.rpm  test1
[root@localhost home]# 

image-20210716105523787

作业练习

Docker安装Nginx

#1. docker search nginx
#2. docker pull nginx
[root@localhost home]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
nginx        latest    4cdc5dd7eaad   9 days ago     133MB
mysql        latest    5c62e459e087   3 weeks ago    556MB
centos       latest    300e315adb2f   7 months ago   209MB
#3. 运行测试
[root@localhost home]# docker run -d --name nginx01 -p 3344:80 nginx
#3344是本机端口,80为容器内端口
c6b898c6e4b0cc7adb24c253c551c26992f9ca4d2ee977ef743d165c0c8ac4ae
[root@localhost home]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                                   NAMES
c6b898c6e4b0   nginx     "/docker-entrypoint.…"   5 seconds ago   Up 3 seconds   0.0.0.0:3344->80/tcp, :::3344->80/tcp   nginx01

[root@localhost home]# curl localhost:3344
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

#进入docker 容器

[root@localhost home]# docker exec -it nginx01 /bin/bash
root@c6b898c6e4b0:/# whereis nginx
nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
root@c6b898c6e4b0:/etc# cd nginx
root@c6b898c6e4b0:/etc/nginx# ls
conf.d	fastcgi_params	mime.types  modules  nginx.conf  scgi_params  uwsgi_params
root@c6b898c6e4b0:/etc/nginx# 

端口暴露image-20210716205852355

问题:若每次改动Nginx配置文件,都要进入容器,不方便,我们可以在容器外部提供一个映射路径,达到在容器修改文件名,容器内部就可以自动修改 -v 数据卷

docker装一个tomcat

#官方
docker run -it --rm tomcat:9.0
#我们之前的启动都是后台,停止容器后,容器还是可以查到  docker run -it --rm 一般用于测试,用完就删除,ps -a都看不见,但镜像还在
#进入容器
[root@localhost home]# docker run -d -p 3355:8080 --name tomcat01 tomcat:9.0
4e97855e1ae2eda0ce6b4a4737ee20914e31fbbac103e24b52666b0069acf239
[root@localhost home]# docker exec -it tomcat01 /bin/bash
root@4e97855e1ae2:/usr/local/tomcat# ll
bash: ll: command not found
#问题:1.linux 命令少了   2. 没有webapps
#原因:阿里云镜像的原因,默认是最小的镜像,所有不必要的都剔除

思考:我们以后要部署项目,如果每次进入容器会非常麻烦?我们能否在外部提供一个映射路径,webapps,我们在外部放置项目,然后自动同步到内部

作业:部署es+kibana

#es 暴露的端口很多  十分耗测内存  es的数据一般需要放置到安全目录进行挂载
#启动命令:
#--net somenetwork ? 网络设置
#启动
docker run -d --name elasticsearch (--net somenetwork) -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:tag
#启动后 linux就很卡  docker stats 查看cpu状态

image-20210717145913373

#测试一下,成功了
[root@localhost ~]# curl localhost:9200
{
  "name" : "8483d214b5ab",
  "cluster_name" : "docker-cluster",
  "cluster_uuid" : "FiMw0EThSuyHUkGHVU5hhg",
  "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 (--net somenetwork) -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:tag

[root@localhost ~]# docker run -d --name elasticsearch01 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.6.2
78ce75bb968bcb800b595ef2724a5eaa9fbcd59f7d26e44d27e1ad366efb59b4
[root@localhost ~]# docker ps
CONTAINER ID   IMAGE                 COMMAND                  CREATED          STATUS          PORTS                                                                                  NAMES
78ce75bb968b   elasticsearch:7.6.2   "/usr/local/bin/dock…"   18 seconds ago   Up 17 seconds   0.0.0.0:9200->9200/tcp, :::9200->9200/tcp, 0.0.0.0:9300->9300/tcp, :::9300->9300/tcp   elasticsearch01

[root@localhost ~]# docker stats
CONTAINER ID   NAME              CPU %     MEM USAGE / LIMIT   MEM %     NET I/O     BLOCK I/O        PIDS
78ce75bb968b   elasticsearch01   0.81%     369MiB / 972.3MiB   37.95%    656B / 0B   513MB / 1.67MB   42

#测试
[root@localhost ~]# curl localhost:9200
{
  "name" : "78ce75bb968b",
  "cluster_name" : "docker-cluster",
  "cluster_uuid" : "tBlMiNZRTfi0YgVJBWLf8Q",
  "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"
}

image-20210717151209196

可视化管理

portainer(先使用这个) 是Docker图形化界面工具,提供一个后台面板供我们操作

docker run -d -p 8088:9000 \
--restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
#访问测试 外网,8088
192.168.159.128:8088

Rancher(CI/CD再用)

Docker镜像讲解

镜像是什么

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

如何得到镜像:

  • 从远程仓库下载
  • 朋友copy
  • 自己制作一个dockerfile

镜像加载原理

image-20210717155534288

image-20210717160159284

分层理解

image-20210717170900035

Commit镜像

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

实战测试

#启动一个默认tomcat
#默认tomcat 没有webapps应用 镜像的原因,官方的镜像默认webapps下是没有的文件的
#需要自己拷贝进去基本的文件
#将我们操作过的容器通过commit提交为一个镜像,我们以后就使用修改过的镜像即可,这是我们自己的一个修改的镜像

容器数据卷

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

如果数据都在容器中,那我们容器删除,数据也会丢失!

所以我们需要数据可以持久化

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

就是卷技术,目录的挂载,将容器内的目录,挂载到Linux上

image-20210718165407089

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

使用数据卷

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

docker run -it -v 主机目录:容器内目录 -p 
[root@localhost home]# docker run -it -v /home/test:/home centos /bin/bash
#测试
[root@localhost home]# docker inspect

image-20210718171109550

#双向绑定
[root@f5645fa61fa9 home]# touch test.java
[root@f5645fa61fa9 home]# ls
test.java
[root@localhost test]# ls
test.java
[root@localhost test]# vim test.java
[root@localhost test]# ls
test.java
[root@f5645fa61fa9 home]# ls
test.java
[root@f5645fa61fa9 home]# cat test.java 
hello,linux update

实战:安装Mysql

思考:Mysql的数据持久化问题

#获取镜像
docker pull mysql:5.7
#安装的时候不要忘了设置密码
官方:docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
-d:后台
-v:目录绑定
-e:额外
-p:端口
--name:别名
[root@localhost test]# 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

#启动成功后,我们可以在本地使用sqlyog/Navicat测试一下
#sqlyog-连接到服务器的3310,这个时候就可以连接了

image-20210718174627180

将此容器删除后,数据依然可以存在!于是就实现了持久化

具名和匿名挂载

#匿名挂载
-v 容器内路径
-P 随机映射端口
docker run -d -P --name nginx01 -v /etc/nginx nginx

#查看所有的volume的情况
[root@localhost data]# docker volume ls
DRIVER    VOLUME NAME
local     38b845929dd3fa27202a669e6c1264df1c8ba9236d31172059acace237244b66
#这里发现是匿名挂载,我们在-v只写了容器内路径,没写主机路径

#具名挂载
docker run -d -P --name nginx02 -v Name:/xxx nginx
[root@localhost home]# docker run -d -P --name nginx02 -v myren-nginx:/etc/nginx nginx
e5e541bef7e2a9513dd579c3d2d7cd59c17a6df500f1b7f5887498e53f38f555
[root@localhost home]# docker volume ls
DRIVER    VOLUME NAME
local     38b845929dd3fa27202a669e6c1264df1c8ba9236d31172059acace237244b66
local     myren-nginx

image-20210718202320697

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

image-20210718202602209

我们通过具名挂载,可以方便的找到我们的一个卷,大多情况下可以方便的查找到我们的卷

image-20210718202834336

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

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

拓展:

#特殊: 通过 -v 容器内路径:ro rw改变读写权限
ro readonlt   只读
rw readwrite  可读可写
#一旦设定了一个权限,容器对我们挂载出来的内容就有限定了
docker run -d -P --name nginx02 -v myren-nginx:/etc/nginx:ro nginx
docker run -d -P --name nginx02 -v myren-nginx:/etc/nginx:rw nginx

#ro 这个路径只能通过宿主机来操作,容器内部是无法操作的

DockerFile

DockerFile是用来构建docker镜像的构建文件,是一个命令脚本!

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

image-20210803175159206

image-20210803175231543

image-20210803175331796

#创建一个dockerfile文件,可以随机,建议DockerFile
#文件中的内容:指令(大写) 参数
FORM centos

VOLUME ["/volume01","/volume02"]

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

启动自己的容器

image-20210803180528686

这里其实是一个匿名挂载

image-20210803181448491

查看一下挂载的路径

image-20210803181519541

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

这种方式很常用,因为我们通常会构建自己的镜像!

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

数据卷容器

–volumes-from

可以实现多个mysql共享数据!

image-20210803182231701

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

image-20210803182537469

image-20210803182741096

此时,有两个正在运行的容器

image-20210803182909114

进入docker01,在volume01下创建docker01文件

image-20210803183036383

我们进入docker02,发现在volume01下也有docker01文件

image-20210803183328927

此时我们再次新创建个容器,依然也有docker01文件

image-20210803183451113

测试,可以删除docker01,查看一下docker02是否还有这个文件

结果:仍然存在

image-20210803183801849

多个mysql实现数据共享

[root@localhost test]# 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
[root@localhost test]# docker run -d -p 3310:3306 --volumes-from mysql01 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 mysql:5.7

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

结论:

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

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

DockerFile

dockerfile是用来构建docker镜像的文件!

构建步骤:

  1. 编写一个dockerfile文件
  2. docker build构建成为一个镜像
  3. docker run 运行镜像
  4. docker push发布镜像(DockerHub,阿里云镜像仓库)

image-20210803194649846

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

DockerFile的构建过程

基础知识:

  1. 每个保留关键字(指令)都是必须是大写字母
  2. 执行从上到下顺序执行
  3. #表示注释
  4. 每一个指令都会创建提交一个新的镜像层,并提交!

image-20210803195157936

dockerfile是面向开发的,以后发布项目,做镜像,就需要编写dockerfile文件,这个文件十分简单!

Docker镜像逐渐成为企业交付的标准,必须要掌握!

步骤:

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

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

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

DockerFile指令

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

image-20210803202613257

实战测试

创建一个自己的centos

# 1 编写Dockerfile的文件
[root@localhost dockerfile]# vim mydockerfile.centos
[root@localhost dockerfile]# cat mydockerfile.centos 
FROM centos
MAINTAINER myren<250225923@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]
docker build -f mydockerfile.centos -t mycentos:0.1 .
# 3 测试运行

image-20210803204512159

工作目录默认是根目录

我们增加之后的镜像

docker history查看是怎么构建起来的

image-20210803204757483

实战:Tomcat镜像

  1. 准备镜像文件
  2. 编写dockerfile文件,官方命名Dockerfile,build会自动寻找这个文件,就不需要-f指定了!
  3. build即可使用

Docker网络

理解Docker0

清空所有环境

测试 ip addr

image-20210808151405251

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

image-20210808151548224

#[root@localhost ~]# docker run -it --name tomcat01 tomcat
#查看容器的内部网络地址 ip addr,发现容器启动的时候会得到一个eth@if11 ip地址,是docker分配的
[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
10: eth0@if11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
#思考,linux能不能ping同容器内部!
#可以ping通

image-20210808153000096

原理

  1. 我们每启动一个docker容器,docker就会给docker容器分配一个ip,只要我们安装了docker,就会有一个网卡,是自带的,为docker0,是桥接模式,使用的技术是evth-pair技术!
  2. 再次测试ip addr,发现多了网卡11

image-20210808153432042

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

image-20210808154514584

image-20210808155041900

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

–link

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

image-20210808182742827

直接会失败

image-20210808182922693

我们使用–link就可以ping通

BUG:反向不一定能ping通

docker network ls 和 docker network inspect networkId查看信息

image-20210808183348895

探究:inspectimage-20210808183444900

–link就是在hosts配置中加了一个172.18.0.3 tomcat02 ~

image-20210808185248201

现在已经不建议使用了,现在是自定义网络,不适用docker0.

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

自定义网络

查看所有docker网络

image-20210808185809611

网络模式

bridge:桥接模式 docker(默认,自己创建的也使用bridge模式)

none:不配置网络

host:和宿主机(此时为linux)共享网络

container:容器网络联通!(用的少!局限很大)

测试

#我们直接启动的命令 --net bridge ,而这个就是我们的docker0
[root@localhost ~]# docker run -d -P --name tomcat01 --net bridge tomcat
WARNING: IPv4 forwarding is disabled. Networking will not work.
99e81cf5ddd13dba2c46af984a9df29568c610182590aac8b16ebb110a99fe4f
#docker0特点,默认,域名不能访问,--link可以打通连接!
#我们可以自定义一个网络!

image-20210808190223666

#--driver bridge
#--subnet 192.168.0.0/16
#--gateway 192.168.0.1
[root@localhost ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
d3f9beb1672c3ba021061da8402b7e608992368419c83a1ce90d50aa72c235e3
[root@localhost ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
9f7aa5ac704c   bridge    bridge    local
111b5bf69390   host      host      local
d3f9beb1672c   mynet     bridge    local
92329b71e5f0   none      null      local

image-20210808190815374

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

[root@localhost ~]# docker run -d -P --name tomcat02-mynet --net mynet tomcat
WARNING: IPv4 forwarding is disabled. Networking will not work.
01c33569bbd146acdeacd6f4cc30b8ff3cfe621a73ef94b1300c093e65bb2eb0
[root@localhost ~]# docker ps
CONTAINER ID   IMAGE     COMMAND             CREATED          STATUS          PORTS                                         NAMES
01c33569bbd1   tomcat    "catalina.sh run"   5 seconds ago    Up 3 seconds    0.0.0.0:49155->8080/tcp, :::49155->8080/tcp   tomcat02-mynet
99e81cf5ddd1   tomcat    "catalina.sh run"   10 minutes ago   Up 10 minutes   0.0.0.0:49154->8080/tcp, :::49154->8080/tcp   tomcat01
[root@localhost ~]# docker run -d -P --name tomcat03-mynet --net mynet tomcat
WARNING: IPv4 forwarding is disabled. Networking will not work.
035c7ee2060ab18964800ad149225209edf5d579ca3c4ddcbca3a628d4cc7709
[root@localhost ~]# docker exec -it tomcat02-mynet ping tomcat03-mynet
PING tomcat03-mynet (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat03-mynet.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.068 ms
64 bytes from tomcat03-mynet.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.045 ms
64 bytes from tomcat03-mynet.mynet (192.168.0.3): icmp_seq=3 ttl=64 time=0.042 ms
64 bytes from tomcat03-mynet.mynet (192.168.0.3): icmp_seq=4 ttl=64 time=0.045 ms
#我们发现可以通过名称直接ping通

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

好处:

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

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

image-20210808191635870

网络连通

image-20210808203548908

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值