Docker个人笔记

Docker概述

Dicker为什么会出现

一款产品:开发- -上线 - -两套环境!应用环境,应用配置

开发 — 运维。问题,对于运维来说考验很大

开发即运维!

环境配置是十分麻烦的,每个机器要部署环境(集群Redis,ES,Hadoop)费时费力

发布一个项目 jar(Redis,mysql,jdk,ES),项目能不能带上环境安装

之前在服务器配置一个应用环境,配置很麻烦,不能够跨平台

传统:jar+运维来做

现在:开发,打包,部署,上线,一套流程做完

java - jar - 打包项目带上环境(镜像) - Docker仓库:商店 - 下载我们发布的镜像 - 直接运行即可

Docker给以上问题提出了解决方案

Docker的思想来自于集装箱

JRE - 多个应用(端口冲突)- 原来都是交叉的

隔离:Docker核心思想,打包装箱,每个箱子是互相隔离的

Docker通过隔离机制,将服务器应用到极致

本质:所有技术都是因为出现了一些问题,我们需要去解决,才去学习。

Docker历史

容器化技术,命名就是docker

Docker刚刚诞生的时候没有引起行业的注意

开源

开放源代码,2013年开源

越来越多的人发现了docker的优点

2014年,Docker1.0发布!

Docker为什么这么火?十分的轻巧!

在容器技术出来之前都是使用的VM(虚拟机技术)

虚拟机:在windows中装一个虚拟机软件,通过VMware可以虚拟出来一台或多台电脑,笨重

虚拟机也是属于虚拟化技术

Docker的容器技术也是属于一种虚拟化技术

VM:linux centos镜像 原生镜像(一个电脑) 隔离,开启多个虚拟机
Docker:隔离,镜像机制(最核心的环境 + jdk + mysql)十分小巧,运行镜像就可以了,秒级启动

到现在,所有开发人员都必须要会docker

聊聊docker

Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 LinuxWindows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。

基于GO语言开发的

官网:https://www.docker.com/

文档:https://docs.docker.com/ Docker的文档是超级详细的

DockerHub(仓库地址):https://hub.docker.com/

Docker能干嘛

之前的虚拟机技术:

虚拟机技术缺点:

  1. 占用资源十分多
  2. 冗余步骤多
  3. 启动慢

image-20201016092511252

容器化技术:

容器化技术不是一个完整的操作系统

比较docker和虚拟机的不同

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

DevOps(开发,运维)

  1. 更快速的交付和部署,传统:一堆帮助文档,安装程序 Docker:打包镜像,发布测试,一键运行
  2. 更便捷的升级和扩缩容,使用了Docker之后,我们部署应用就和搭积木一样
  3. 更简单的系统运维:在容器化之后,开发测试环境高度一致
  4. 更高效的计算资源利用,Docker是内核级别的虚拟化,可以在一个物理机上运行很多的容器实例,服务器性能被压榨到极致

Docker安装

Docker的基本组成

查看源图像

镜像(image)

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

容器(container)

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

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

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

仓库(repository)

仓库就是存放镜像的地方!

仓库分为共有仓库和私有仓库!

Docker Hub(默认国外的)

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

安装Docker

环境准备

  1. 需要一点点的linux基础
  2. CentOS 7
  3. 使用xshell连接远程服务器进行操作

环境查看

# 系统内核是4.18
[root@ecs-029-docker ~]# uname -r
4.18.0-80.7.2.el7.aarch64
# 系统版本
[root@ecs-029-docker ~]# cat /etc/os-release 
NAME="CentOS Linux"
VERSION="7 (AltArch)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (AltArch)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"

CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"

安装(centos)

帮助文档:

# 1.卸载旧的版本 Uninstall old versions
sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine
                  
# 2.下载需要的安装包 SET UP THE REPOSITORY
$ sudo yum install -y yum-utils

# 3.设置镜像的仓库
sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo # 默认为国外的
    
sudo yum-config-manager \
    --add-repo \
    http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # 国内镜像,推荐使用阿里云
    
# 更新软件包索引

# 4.安装docker相关的内容 docker-ce 社区 ee 企业版
sudo yum install docker-ce docker-ce-cli containerd.io

# 5.启动docker
sudo systemctl start docker

# 6.使用docker verson查看是否安装成功
docker version

image-20201016174912663

# 7.通过运行hello-world 映像来验证是否正确安装了Docker Engine 。
sudo docker run hello-world

image-20201016175152891

# 8.查看下载的hello-world镜像
^H^H^H^H^H[root@ecs-029-docker ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-world         latest              a29f45ccde2a        9 months ago        9.14kB

了解:卸载docker

# 1.卸载Docker Engine,CLI和Containerd软件包:
sudo yum remove docker-ce docker-ce-cli containerd.io

# 2.主机上的映像,容器,卷或自定义配置文件不会自动删除。要删除所有图像,容器和卷:
sudo rm -rf /var/lib/docker

# /var/lib/docker docker的默认工作路径

阿里云镜像加速

  1. 登录阿里云找到容器服务

  2. 找到镜像加速地址 https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors

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

回顾hello-world流程

image-20201016181805182

底层原理

Docker是怎么工作的?

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

DockerServer接收到Docker Client指令,就会执行这个命令

image-20201016182510227

1. Docker为什么比虚拟机快

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

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

img

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

image-20201016183636114

Docker命令

帮助命令

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

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

镜像命令

docker images

[root@ecs-029-docker docker]# docker images
REPOSITORY           TAG                 IMAGE ID               CREATED             SIZE
hello-world         latest              a29f45ccde2a        9 months ago        9.14kB
# 解释
REPOSITORY 镜像的仓库源
TAG		   镜像的标签
IMAGE ID   镜像的ID
CREATED	   镜像的创建时间
SIZE	   镜像的大小
# 可选项
Options:
  -a, --all             Show all images (default hides intermediate images)列出所有的镜像
      --digests         Show digests

  -q, --quiet           Only show numeric IDs 只显示镜像的ID

docker search 搜索镜像

[root@ecs-029-docker docker]# docker search mysql
NAME                              DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
mysql                             MySQL is a widely used, open-source relation…   10053               [OK]     

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


docker pull 下载镜像

# docker pull 镜像名字[:tag]
[root@ecs-029-docker docker]# docker pull mysql
Using default tag: latest # 如果不写 tag,默认就是 latest
latest: Pulling from library/mysql
bb79b6b2107f: Pull complete  # 分层下载,docker image核心 联合文件系统
49e22f6fb9f7: Pull complete 
842b1255668c: Pull complete 
9f48d1f43000: Pull complete 
c693f0615bce: Pull complete 
8a621b9dbed2: Pull complete 
0807d32aef13: Pull complete 
9eb4355ba450: Pull complete 
6879faad3b6c: Pull complete 
164ef92f3887: Pull complete 
6e4a6e666228: Pull complete 
d45dea7731ad: Pull complete 
Digest: sha256:86b7c83e24c824163927db1016d5ab153a9a04358951be8b236171286e3289a4 # 签名
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest # 真实地址

docker pull mysql
docker pull docker.io/library/mysql:latest # 两者等价

# 指定版本下载
[root@ecs-029-docker-x86 ~]# docker pull mysql:5.7
5.7: Pulling from library/mysql
bb79b6b2107f: Already exists 
49e22f6fb9f7: Already exists 
842b1255668c: Already exists 
9f48d1f43000: Already exists 
c693f0615bce: Already exists 
8a621b9dbed2: Already exists 
0807d32aef13: Already exists 
6d2fc69dfa35: Pull complete 
56153548dd2c: Pull complete 
3bb6ba940303: Pull complete 
3e1888da91a7: Pull complete 
Digest: sha256:b3dc8d10307ab7b9ca1a7981b1601a67e176408be618fc4216d137be37dae10b
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7

docker rmi 删除镜像

docker rmi -f 42cdba9f1b08[镜像ID] # 删除一个镜像
docker rmi -f $(docker images -aq) # 删除所有镜像
docker rmi -f [镜像ID] [镜像ID]...   # 删除多个镜像

容器命令

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

docker pull centos  

新建容器并启动

docker run [可选参数] image

# 参数说明
--name="Name" # 容器名字,用来区分容器
-d			  # 后台方式运行,nohup
-it			  # 使用交互模式,进入容器,查看内容
-p 			  # 指定容器端口,-p 8080:8080
	-p ip:主机端口:容器端口
	-p 主机端口:容器端口(常用)
	-p 容器端口
	容器端口
-P			  # 随机指定端口

# 测试,启动并进入容器
docker run -it centos /bin/bash

[root@6fe35d7a3bb3 /]# ls # 查看容器内的centos,基础版本,很多命令都是不完善的
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

# 退出容器
[root@6fe35d7a3bb3 /]# exit
exit

列出所有的运行的容器

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


退出容器

exit  # 容器直接停止并退出
ctrl + P + Q #容器不停止退出

删除容器

docker rm 容器id				  # 删除指定的容器,不能删除正在运行的容器,如果要强制删除,rm -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@ecs-029-docker-x86 /]# docker run -d centos

# 问题:docker ps的时候发现centos停止了

# 常见的坑:docker 容器使用后台运行,就必须要有一个前台进程,docker发现没有应用,就会自动停止
# nginx,容器启动后发现自己没有提供服务,就会立刻停止,没有程序了

查看日志命令

# 查看日志
docker logs -f -t --tail 容器,没有日志

# 自己编写一段脚本
[root@ecs-029-docker-x86 /]# docker run -d centos /bin/sh -c "while true;do echo yangjian;sleep 1;done"

[root@ecs-029-docker-x86 /]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
e70c82f6b9c6        centos              "/bin/sh -c 'while t…"   3 seconds ago       Up 2 seconds                            lucid_kirch
# 显示日志
docker logs 
-f 	   # 字符串显示
-t 	   # 带上时间戳
--tail # 要显示的日志数
docker logs -f -t e70c82f6b9c6  # 显示所有日志
docker logs -f -t --tail e70c82f6b9c6 # 显示指定行数的日志

查看容器中的进程信息

# top命令 docker top 容器ID
[root@ecs-029-docker-x86 /]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
e70c82f6b9c6        centos              "/bin/sh -c 'while t…"   6 minutes ago       Up 6 minutes                            lucid_kirch
[root@ecs-029-docker-x86 /]# docker top e70c82f6b9c6
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                24592               24575               0                   09:27               ?                   00:00:00            /bin/sh -c while true;do echo yangjian;sleep 1;done
root                25110               24592               0                   09:34               ?                   00:00:00            /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1

查看镜像的元数据

# 命令:
docker inspect 容器ID

[root@ecs-029-docker-x86 /]# docker inspect e70c82f6b9c6
[
    {
        "Id": "e70c82f6b9c6ab319750c7458f8b17dc271e924ebbb977a7db317ae59e273bbc",
        "Created": "2020-10-18T01:27:46.446357531Z",
        "Path": "/bin/sh",
        "Args": [
            "-c",
            "while true;do echo yangjian;sleep 1;done"
        ],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 24592,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2020-10-18T01:27:46.688127544Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
        "Image": "sha256:0d120b6ccaa8c5e149176798b3501d4dd1885f961922497cd0abef155c869566",
        "ResolvConfPath": "/var/lib/docker/containers/e70c82f6b9c6ab319750c7458f8b17dc271e924ebbb977a7db317ae59e273bbc/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/e70c82f6b9c6ab319750c7458f8b17dc271e924ebbb977a7db317ae59e273bbc/hostname",
        "HostsPath": "/var/lib/docker/containers/e70c82f6b9c6ab319750c7458f8b17dc271e924ebbb977a7db317ae59e273bbc/hosts",
        "LogPath": "/var/lib/docker/containers/e70c82f6b9c6ab319750c7458f8b17dc271e924ebbb977a7db317ae59e273bbc/e70c82f6b9c6ab319750c7458f8b17dc271e924ebbb977a7db317ae59e273bbc-json.log",
        "Name": "/lucid_kirch",
        "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,
            "Capabilities": null,
            "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/11d292a78b3e087c19e72300cee3a27fd0316b92b17834d5f1f8d1d203bb95d8-init/diff:/var/lib/docker/overlay2/bbcc41cb4e6f32dc0745346446acff77d9bc91caa488d77a563d1fa2e09da7ef/diff",
                "MergedDir": "/var/lib/docker/overlay2/11d292a78b3e087c19e72300cee3a27fd0316b92b17834d5f1f8d1d203bb95d8/merged",
                "UpperDir": "/var/lib/docker/overlay2/11d292a78b3e087c19e72300cee3a27fd0316b92b17834d5f1f8d1d203bb95d8/diff",
                "WorkDir": "/var/lib/docker/overlay2/11d292a78b3e087c19e72300cee3a27fd0316b92b17834d5f1f8d1d203bb95d8/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [],
        "Config": {
            "Hostname": "e70c82f6b9c6",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "/bin/sh",
                "-c",
                "while true;do echo yangjian;sleep 1;done"
            ],
            "Image": "centos",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {
                "org.label-schema.build-date": "20200809",
                "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": "a72a2825ffec96b0c200ec2989b23b643e25b9d439bcfc124cb3f4504c16881a",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {},
            "SandboxKey": "/var/run/docker/netns/a72a2825ffec",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "eca2863d687cc6b9c0935d2497907ff712905354c6895d17e78b73b869c89e43",
            "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": "8f377385b3ccdda29ce0eb54359fe80cb7c41775c90d5dbac1188aa30755e573",
                    "EndpointID": "eca2863d687cc6b9c0935d2497907ff712905354c6895d17e78b73b869c89e43",
                    "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
[root@ecs-029-docker-x86 /]# docker exec -it e70c82f6b9c6 /bin/bash
[root@e70c82f6b9c6 /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@e70c82f6b9c6 /]# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 01:27 ?        00:00:00 /bin/sh -c while true;do echo yangjian;sleep 1;done
root       963     0  0 01:43 pts/0    00:00:00 /bin/bash
root       988     1  0 01:43 ?        00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1
root       989   963  0 01:43 pts/0    00:00:00 ps -efD bashShell
[root@ecs-029-docker-x86 /]# docker exec -it e70c82f6b9c6 /bin/bash
[root@e70c82f6b9c6 /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@e70c82f6b9c6 /]# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 01:27 ?        00:00:00 /bin/sh -c while true;do echo yangjian;sleep 1;done
root       963     0  0 01:43 pts/0    00:00:00 /bin/bash
root       988     1  0 01:43 ?        00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1
root       989   963  0 01:43 pts/0    00:00:00 ps -ef

# 方式2
docker attach 容器ID  # 正在执行当前的代码

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

从容器内拷贝到主机上

docker cp 容器ID:容器内路径 目的地的主机路径

# 测试

# 进入docker容器内部
[root@ecs-029-docker-x86 home]# docker attach 0e1093ef735b
[root@0e1093ef735b /]# ls 
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@0e1093ef735b /]# cd home/
# 在容器内新建一个文件
[root@0e1093ef735b home]# touch test.java
[root@0e1093ef735b home]# exit
exit
[root@ecs-029-docker-x86 home]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
[root@ecs-029-docker-x86 home]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
0e1093ef735b        centos              "/bin/bash"         2 minutes ago       Exited (0) 6 seconds ago                       xenodochial_aryabhata
# 将文件拷贝出来到主机上
[root@ecs-029-docker-x86 home]# docker cp 0e1093ef735b:/home/test.java /home
[root@ecs-029-docker-x86 home]# ls
test.java  yangjian.java

# 拷贝是一个手动过程,未来我们使用 -v卷的技术,可以实现,自动同步

作业练习

Docker安装Nginx

# 1.搜索镜像 建议去docker hub上搜索
docker search nginx

# 2.下载镜像
docker pull nginx

# 3.启动
-d 后台运行
--name 给容器命名
-p 宿主机:容器内部端口
docker run -d --name nginx01 -p 3344:80 nginx

# 4.运行测试
curl localhost:3344

[root@ecs-029-docker-x86 home]# curl localhost:3344

# 5.进入容器
[root@ecs-029-docker-x86 home]# docker exec -it nginx01 /bin/bash
root@e3182cda5aa9:/# whereis nginx
nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
root@e3182cda5aa9:/# cd /etc/nginx/
root@e3182cda5aa9:/etc/nginx# ls
conf.d	fastcgi_params	koi-utf  koi-win  mime.types  modules  nginx.conf  scgi_params	uwsgi_params  win-utf


思考问题:我们每次改动nginx配置文件都十分麻烦,我们要是在容器外部提供一个映射路径,在外部达到容器外部部署我们的项目:
数据卷技术

端口暴露的概念

image-20201018104516210

Docker安装Tomcat

# 官方的使用
docker run -it --rm tomcat:9.0

# 我们之前的启动都是后台,停止了容器之后,容器还是可以查到   docker run -it --rm tomcat:9.0 一般用来测试,用完即删除

# 下载再启动
docker pull tomcat

# 运行
docker run -d -p 3355:8080 --name tomcat01 tomcat

# 测试访问无问题
# 进入容器
docker exec -it tomcat01 /bin/bash

# 发现问题 1.命令少了 2.没有webapps 。 阿里云镜像的原因,默认是最少的镜像,所有不必要的都剔除了
# 保证最小可运行环境

思考问题:我们以后要部署项目,如果每次都要进入容器十分麻烦,提供一个映射路径,webapps,我们在外部放置项目,自动同步到内部就好了

部署ES+kibana

# es 暴露的端口很多
# es 十分的耗费内存
# es 的数据一般需要防止在安全目录!挂载
# --next somenetwork ? 网络配置

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

# 启动了linux很卡 docker status

# es是十分消耗内存的

# 查看docker stats

# 测试es是否成功
curl localhost:9200
# 赶紧关闭,增加内存的限制

增加内存限制

修改配置文件

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

可视化

portainer(先用这个)

什么是portainer?

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

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

访问测试:外网8088端口

  • 选择本地local

image-20201018232517182

  • 访问

Rancher(CI/CD)

Docker镜像

镜像是什么

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

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

如何得到镜像

  • 从远程仓库下载
  • 朋友拷贝
  • 自己制作一个镜像DockerFile

Docker镜像加载原理

UnionFS(联合文件系统)

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

Docker镜像加载原理

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

bootfs(boot file system)系统启动需要引导加载,所有镜像公用

rootfs(root file system),包含linux的文件系统,容器就是一个小的虚拟机

虚拟机是分钟级别,容器是秒级

分层理解

image-20201019083958105

commit镜像

docker commit # 提交容器成为一个新的副本

# 命令和git类似
docker commit -m "提交的描述信息" -a="作者" 目标镜像名:[tag]

实战测试

# 启动一个默认的tomcat
docker run -it -p 8080:8080 tomcat
# 发现默认的tomcat没有webapps应用,官方镜像原因 -r 递归

# 自己拷贝进去基本文件
cp -r webapps.dist/* webapps

# 自己commit一个自己的镜像
docker commit -a="yangjian" -m="add webapps app" 492bc17078cd tomcat02:1.0

# 我们以后就使用我们修改过的镜像即可

image-20201019085346176

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

容器数据卷

什么是容器数据卷

docker的理念

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

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

MySQL,容器删了数据也就丢了,删库跑路 需求:Mysql的数据可以存储在本地

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

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

image-20201019095324308

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

使用数据卷

方式1:直接使用命令来挂载 -v,双向绑定,同步

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

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

# 启动起来之后可以使用
docker inspect 容器ID 查看挂载点详细信息

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

image-20201019215708464

实战:安装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 端口映射  -P 随机映射端口
-v 数据卷挂载
-e 环境配置
--name 别名  容器名字
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

# 启动成功之后使用navicat连接一下
# navicat连接到服务器的3310端口和容器内的3306映射,这个时候就可以连接上了

# 再本地创建一个数据库,查看映射是否正确

# 我们将容器删除后,发现我们的数据依然没有丢失,这就实现了数据持久化功能
docker rm -f mysql01

具名挂载和匿名挂载

匿名挂载

-v 容器内路径
# 1.运行挂载
docker run -d -P --name nginx01 -v /etc/nginx nginx

# 2.查看所有卷的情况
docker volume ls

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

image-20201020091000187

具名挂载

# 1.运行具名挂载
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
 
# 2.通过-v 卷名:容器内路径

# 3.查看
[root@ecs-029-docker-x86 ~]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
b4e4b4cbe3937648790f7a1ac4bf73e77dce9a88aafc58419521d489a02fbfec
[root@ecs-029-docker-x86 ~]# docker volume ls
DRIVER              VOLUME NAME
local               56cf2f19bda457ac9a8793045f5977e65e2355b098d70eba67c8d421b571a107
local               f8ef4f970d32fc08b2be7cde90b0462ec01719e4c83f5aace5f342a7325bf2bd
local               juming-nginx

# 4.查看对应路径
[root@ecs-029-docker-x86 ~]# docker volume inspect juming-nginx
[
    {
        "CreatedAt": "2020-10-20T09:13:27+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/xxx

我们通过具名挂载可以方便的找到卷,大多数情况下使用的具名挂载,不建议使用匿名挂载

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

拓展:

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


# 一旦设定了容器权限,容器对挂载出来的内容就有限定了
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:只能从外部改变,通过宿主机来改变,容器内部是无法操作的
# rw:为默认

初识DockerFile

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

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

# 1.编写DockerFile,严格区分大小写,名字可以随意,建议为dockerfile
FROM centos

VOLUME ["volume01","volume02"]  # 匿名挂载

CMD echo "--------end --------"

CMD /bin/bash

# 这里的每个命令就是镜像的一层

# 2.build
docker build -f dockerfile1 -t yangjian/centos .

image-20201020093726917

启动一下自己生成的容器

image-20201020094119581

这个卷和外部一定有一个同步的目录

image-20201020094833390

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

image-20201020095007123

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

数据卷容器

多个mysql同步数据

image-20201020100128396

# 启动三个容器,通过我们刚才自己写的镜像启动
docker run -it --name docker02 --volumes-from docker01 yangjian/centos

image-20201020122249875

image-20201020122447507

image-20201020123043978

# 测试:可以删除docker01,查看一下docker02和docker03

# 测试依旧可以访问,备份机制,双向拷贝

image-20201020123724158

多个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 3311:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql:5.7

结论:容器之间配置信息的传递,数据卷容器的声明周期一直持续到没有容器使用为止,去中心化

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

DockerFile

DockerFile介绍

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

构建步骤:

  1. 编写一个DockerFile文件
  2. docker build 构建成为一个镜像
  3. docker run 运行镜像
  4. docker push 发布镜像(Docker Hub , 阿里云镜像仓库)
  5. 查看一下官方是怎么做的image-20201020133608869
  6. image-20201020133644632

很多官方的镜像都是基础包,很多功能没有,我们需要自己搭建自己的镜像

官方既然可以制作镜像,我们也可以

DockerFile构建过程

基础知识:

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

image-20201020134704598

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

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

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

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

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

Docker网络原理

Idea整合Docker

Docker Compose

Docker Swarm

CI/CD jenkins

posted @ 2020-12-14 11:09  void-white  阅读(150)  评论(0)    收藏  举报