1.是什么
2.能干嘛
3.去哪下
4.怎么玩
5.helloword
是什么
解决版本配置问题
将代码和环境打包成镜像
别迷糊玺子,你就理解为docker相当于一个轻量化VM,只保留了必要的虚拟内核,没有模拟虚拟磁盘之类的硬件
Go语言
开源的应用容器引擎
Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。
容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。
Docker 从 17.03 版本之后分为 CE(Community Edition: 社区版) 和 EE(Enterprise Edition: 企业版),我们用社区版就可以了。
优点
1、快速,一致地交付您的应用程序
2、响应式部署和扩展
3、在同一硬件上运行更多工作负载
架构
- 镜像(Image):Docker 镜像(Image),就相当于是一个 root 文件系统。比如官方镜像 ubuntu:16.04 就包含了完整的一套 Ubuntu16.04 最小系统的 root 文件系统。
- 容器(Container):镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
- 仓库(Repository):仓库可看成一个代码控制中心,用来保存镜像。
Docker 使用客户端-服务器 (C/S) 架构模式,使用远程API来管理和创建Docker容器。
Docker 容器通过 Docker 镜像来创建。
ESC服务器
部署doctor必须要Linux内核
查看自己的CentOS版本
cat /etc/redhat-release
uname -r
内核版本 硬件架构 主机名称 操作系统类型
docker直接使用实际物理机的硬件资源,不需要想虚拟机一样加载一个操作系统内核
容器iD NAMEs
cat /proc/version
yum -y install gcc
yum -y install gcc-c++
在新机子上安装第一次需要先设置仓库
sudo yum install -y yum-utils
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
查看当前系统版本
查看到 Docker 客户端的所有命令选项
docker
查看帮助
命令 --help
卸载
systemctl stop docker
yum remove docker-ce docker-ce-cli containerd.io
rm -rf/var/lib/docker
rm -rf /var/lib/containerd
yum install docker-ce docker-ce-cli contained.io
docker version
ps -ef|grep docker
容器使用
获取镜像
如果本地没有,用
docker pull ubuntu
启动容器
使用ubuntu镜像启动一个容器,参数为 以命令行模式 以命令行模式
docker run -it ubuntu /bin/bash
-i: 交互式操作。
-t: 终端。
ubuntu: ubuntu 镜像。
/bin/bash:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是 /bin/bash
退出
exit
查看所有容器
docker ps -a
启动
docker start ID 或者 NAMES
后台运行
docker run -itd --name ubuntu-test ubuntu /bin/bash
-d 参数默认不会进入容器,想要进入容器需要使用指令 docker exec
--name 指定的容器的名字
停止容器
docker stop <容器ID>
重启
docker restart <容器ID>
进入容器
docker attach <容器ID> 退出容器后,停止容器
docker exec -it <容器ID> /bin/bash 退出容器后,不停止容器
导出容器
docker export 1e560fca3906 > ubuntu.tar 后面是目录(需要该目录存在)
导入容器快照
删除
docker rm -f 1e560fca3906
清理掉所有处于终止状态的容器
docker container prune
帮助启动类命令
systemctl status docker
systemctl restart docker
systemctl stop docker
systemctl start docker
开启启动
systemctl enable docker
查看docker概要信息
docker info
docker总体帮助命令
docker --help
docker命令帮助命令
docker 具体命令 --help
镜像命令
查询本地的所有镜像
docker images
REPOSITORY 表示镜像的仓库源
TAG 镜像的标签版本号
IMAGE ID 镜像ID
CREATED 镜像创建时间
SIZE 镜像大小
-a 列出本地所有的镜像(含历史版本)
-q 只显示镜像ID
docker images -a
docker images -q
查看远程库是否有相关镜像
docker search 某个镜像名字
NAME 镜像名字
DESCRIPTION 镜像说明
STARS 点赞数量
OFFICIAL 是否是官方的
AUTOMATED 是否是自动构建的
docker search --limit (25) 镜像名字
下载镜像
docker pull 某个镜像名字[:TAG]
默认下载最新的
查看镜像/容器/数据卷所占的空间
doker system df
删除镜像
docker rmi 某个镜像名字ID
docker -f rmi 镜像ID1 镜像ID2
docker rmi -f $(docker images -qa)
虚悬镜像 dangling image
仓库名,标签都是<none>
容器命令
新建+启动容器
docker run[OPTIONS]IMAGE[COMMAND][ARG...]
OPTIONS说明
--name=容器新名称
-d 后台运行容器并返回容器ID,也即 启动守护式容器(后台启动)
启动交互式容器(前台有伪终端,等待交互)
-i 以交互模式运行终端
-t 为容器重新分配一个伪输入终端
-P 随机分配端口映射
-p 指定端口映射
e.g. 希望有个shell
docker run -it ubuntu /bin/bash
只加载Linux内核,没有vim,如果使用需要安装
exit 退出
列出所有正在运行的容器实列
docker ps[OPTIONS]
如果没有指定名称 则随机分配一个
-a 列出所有的容器和历史上运行过的容器
-l 显示最近创建的容器
-n 3 显示最近创建的3个容器
-q 静默模式 只显示容器编号
退出容器
exit run 进去容器,exit退出,容器停止
ctrl+p+q run进去容器,ctrl+p+q退出,容器不停止
启动已停止的容器
docker start 容器ID或者容器名
重启
docker restart 容器ID或者容器名
停止
docker stop 容器ID或者容器名
强制停止
docker kill 容器ID或者容器名
删除已经停止的容器
docker rm 删容器
docker rmi 删镜像
docker rm 容器ID或者容器名
一次性删除多个
docker rm -f ${docker ps -a -q}
docker ps -a -q | xargs docker rm
注意:
dokcer run
dokcer ps
启动守护式容器 docker run -d
docker run -d ubuntu
缺少前台进行,自杀
docker run -d redis:6.0.8
docker ps
查看容器日志
docker logs 容器ID
linex
top
查看容器内运行的进程
docker top 容器ID
查看容器内部细节
docker inspect 容器ID
进入正在运行的容器并以命令行交互
docker exec -it 容器ID /bin/bash
在容器中打开新的终端,可以启动新的进程,用exit退出,不会导致容器的停止
docker attach 容器ID
直接进入容器启动命令的终端,不会启动新的进程,用exit退出会导致容器停止
Ctrl + p + q 后台运行容器,但是当你在使用 run 是重新创建一个新的容器,而 exec 是进入之前创建的容器
从容器内拷贝文件到主机上
docker cp 容器ID:容器内的路径 主机路径
将容器内的镜像导出tar
docker export 容器ID > 名字.tar
将tar导入容器
cat 名字.tar | docker import - 镜像用户/镜像名:镜像版本号
镜像
分层的镜像
UnionFS(联合文件系统)
commit
docker commit -m="提交的描述信息" -a="作者" 容器ID 要创建的目标镜像名:[标签名]
原镜像删除不影响新的镜像
生成镜像一共有两种
Dockerfile commit
下载仓库镜像
docker pull registry
docker images
创建仓库容器
docker run -d -p 5000:5000 -v /zzyyuse/myregistry/:/tmp/registry --privileged=true registry
-p hostPort:contalnerPort
-p 81:80 -p 443:443 指定多个
-p hostPort:containPort:udp 指定协议 -p 8080:80:tcp
-p ip::containerPort 随机分配端口 -p 10.0.0.00::80
-p ip:hostPort:containerPort 配置监听地址 -p 10.0.0.100:8080:80
默认情况下,仓库被创建在容器的/var/lib/registry目录下,建议自行用容器卷映射,方便宿主机联调
启动registry,centos会分配它一个端口,并映射到自己的电脑上的端口,因为运行这个镜像是一个后台进程,会有他自己的目录结构,所以为了方便使用目录,要把自己的目录挂载到centos的零时目录下
查询当前本地仓库中的镜像
curl-XGET http://ip:port/v2/_catalog
端口后面的路径是 docker 官方规定的镜像仓库的路径,详情见官网文档
将要添加到仓库的镜像改成符合规范的tag
docker tag 镜像:版本 ip:port/镜像:版本
修改配置文件的使其支持http
取消docker 默认不允许http方式推送镜像
(如修改后,不生效,重启docker)
cat /etc/docker/daemon.json
添加
"insecure-registries":["ip:port"]
将镜像推送到私服
docker images
docker push 镜像名:版本
检查私服库上的镜像
(需要打开防火墙的5000端口)
curl -XGET http://ip:port/v2/_catalog
docker pull ip:port/镜像名:版本
容器数据卷
-v 就是添加自定义的容器卷
宿主机的路径:容器内的路径
--privileged=true 放开权限
实现了宿主机和容器内的路径的信息互联
宿主机容器之间映射添加容器卷
docker run -it --privileged=true -v /宿主机的绝对路径:/容器内的目录 镜像名
重启已关闭的容器
docker ps -a
docker start 容器ID
重新进入
docker exec -it 容器ID /bin/bash
docker inspect : 获取容器/镜像的元数据。
可以用 docker inspect 容器ID
来看容器的容器卷
[root@VM-24-12-centos ~]# docker inspect f7
[
{
"Id": "f71707a5a9dd8f09da1e0e6941b10912376088515a2c4df535119ccceb794847",
"Created": "2022-11-23T04:48:10.949098771Z",
"Path": "bash",
"Args": [],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 5553,
"ExitCode": 0,
"Error": "",
"StartedAt": "2022-11-23T04:54:20.925807082Z",
"FinishedAt": "2022-11-23T04:52:31.34076589Z"
},
"Image": "sha256:a8780b506fa4eeb1d0779a3c92c8d5d3e6a656c758135f62826768da458b5235",
"ResolvConfPath": "/var/lib/docker/containers/f71707a5a9dd8f09da1e0e6941b10912376088515a2c4df535119ccceb794847/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/f71707a5a9dd8f09da1e0e6941b10912376088515a2c4df535119ccceb794847/hostname",
"HostsPath": "/var/lib/docker/containers/f71707a5a9dd8f09da1e0e6941b10912376088515a2c4df535119ccceb794847/hosts",
"LogPath": "/var/lib/docker/containers/f71707a5a9dd8f09da1e0e6941b10912376088515a2c4df535119ccceb794847/f71707a5a9dd8f09da1e0e6941b10912376088515a2c4df535119ccceb794847-json.log",
"Name": "/u2",
"RestartCount": 0,
"Driver": "overlay2",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": {
"Binds": [
"/tmp/host_data:/tmp/docker_data"
],
"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": true,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": [
"label=disable"
],
"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": null,
"ReadonlyPaths": null
},
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/0263bd664d02a95e53913b6ce105986dce2e13cc0e41c10dd4fe7208ea350474-init/diff:/var/lib/docker/overlay2/adfb71a8c8207e844ea4403939f0d588af5975d7dc44c8d72d5a2bf933643ba9/diff",
"MergedDir": "/var/lib/docker/overlay2/0263bd664d02a95e53913b6ce105986dce2e13cc0e41c10dd4fe7208ea350474/merged",
"UpperDir": "/var/lib/docker/overlay2/0263bd664d02a95e53913b6ce105986dce2e13cc0e41c10dd4fe7208ea350474/diff",
"WorkDir": "/var/lib/docker/overlay2/0263bd664d02a95e53913b6ce105986dce2e13cc0e41c10dd4fe7208ea350474/work"
},
"Name": "overlay2"
},
"Mounts": [
{
"Type": "bind",
"Source": "/tmp/host_data",
"Destination": "/tmp/docker_data",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
"Config": {
"Hostname": "f71707a5a9dd",
"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": [
"bash"
],
"Image": "ubuntu",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "b06e9b8df63040206e8e60b671d2b46acfe57b53309ac4dc4d67c242be865894",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {},
"SandboxKey": "/var/run/docker/netns/b06e9b8df630",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "84432eb2e9fe8fb5c33a02f783e14921b0e07fbf0bdea529fe15241816d7c3fa",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.3",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:03",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "76b278b26a695a24e299af0baac3ec53c986b866cb306d59e0e665bb94207b60",
"EndpointID": "84432eb2e9fe8fb5c33a02f783e14921b0e07fbf0bdea529fe15241816d7c3fa",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.3",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:03",
"DriverOpts": null
}
}
}
}
]
"Mounts": [
{
"Type": "bind",
"Source": "/tmp/host_data",
"Destination": "/tmp/docker_data",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
sorce 挂载宿主机的目录
destination 容器内的目录
容器和宿主机内可以数据共享,即使容器被关闭,在主机内添加数据,重启服务后,也在容器会有添加的数据
即使删除容器,宿主机下面的目录中的数据也会存在。
修改容器卷的读写权限
docker run -it --privileged=true -v 主机路径:容器路径:ro 镜像名
ro only read 限制容器只能读取宿主机的数据,不能写入数据
继承容器卷
docker run -it --privileged=true --volumes-from 父类 --name u2 镜像名
安装
docker search tomcat
docker pull tomcat
docker images tomcat
docker run -d -p 8070:8080 tomcat
如果想要访问tomcat WebUI, 应该要在webapp文件夹下面
如果tomcat notfoung404
防火墙,端口号
如果是Apache Tomcat/10.1.2
docker exec -it 容器ID /bin/bash
cd webapps/
ll
cd ..
rm -rf webapps
mv webapps.dist webapps
免修改版
docker pull billygoo/tomcat8-jdk8
docker run -d -p 8070:8080 --name mytomcat8 billygoo/tomcat8-jdk8
mysql安装
docker search mysql
docker pull mysql:8.0.22
docker images mysql:8.0.22
docker run --name=mysql8 -p 13306:3306 -e MYSQL_ROOT_PASSWORD=abc123 -d mysql:8.0.22
docker ps
docker exec -it 容器ID /bin/bash
root没有远程权限
mysql8运行:ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '密码';
SHOW VARIABLES LIKE 'character%';
需要设置容器数据卷来解决,每次在docker 生成mysql容器的 mysql的字符集问题
同时需要容器数据卷来备份容器中MySQL的数据
docker run -d -p 13306:3306 --privileged=true \
-v /zzyyuse/mysql/log:/var/log/mysql \
-v /zzyyuse/mysql/data:/var/lib/mysql \
-v /zzyyuse/mysql/conf:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=abc123 \
--name mysql8 \
mysql:8.0.22
容器里没有的一些工具(如vim),在宿主机上有,所以如果要修改容器卷的数据一般在宿主机里修改
cd /zzyyuse/mysql/conf
ll
vim my.cnf
[client]
default_character_set=utf8
[mysql]
collation_server = utf8_general_ci
character_set_server = utf8
cat my.cnf
dokcer ps
dokcer restart mysql8
docekr exec -it mysql /bin/bash
mysql -uroot -p 密码
SHOW VARIABLES LIKE 'character%';
要在容器内查看字符集,navicat会自动修改一下字符集