*Docker

Docker为什么会出现?

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

开发 —- 运维 问题:我在我的电脑上可以运行!版本更新,导致服务不可用!对于运维来说,考验就十分大?

开发即运维

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

那么项目能不能带上环境一起安装呢

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

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

Docker的历史

2010年,几个搞IT的年轻人,就在美国成立了一家公司 dotCloud做一些pass的云计算服务!

我们将自己的技术(容器化技术)命名 就是docker!

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

开源

开发源代码

2013年,Docker开源

Docker越来越多的人发现了Docker的优点,Docker每个月都会更新一个版本

2014年四月,Docker1.0发布

Docker为什么这么火呢,因为它相对于一个虚拟机来说,它非常轻。

  • 在容器技术出来之前,我们都是使用的虚拟机技术。
    • 虚拟机:创建一个操作系统非常的笨重 内存占用大
    • Docker: 内存占用下 启动快 只需要运行一个软件即可

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

聊聊Docker

Docker是基于Go语言开发的·!开源项目!

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

文档: https://docs.docker.com/

Docker能干嘛

  • 之前的虚拟机技术
    • 1、 资源占用十分多
    • 冗余步骤多
    • 启动很慢

image-20231206090521553

  • 容器化技术

image-20231206090703349

比较Docker和虚拟机技术的不同:

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

Docker安装

Docker的基本组成

15

镜像 (Image):

docker镜像就好比是一个模板,开源通过这个模板来创建容器服务,romcat镜像—run—tomcat01容器(提供服务器),通过这个镜像可以创建多个容器。

容器(container):

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

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

目前可以把容器给i理解为就是一个简易的Linux系统

仓库 (repository):

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

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

Docker Hub (默认是国外的)

阿里云..都有容器服务

安装Docker (网络源)

环境查看

# 系统内核要是3.0以上的
[root@k8s ~]# uname -r
5.14.0-162.6.1.el9_1.0.1.x86_64
# 系统版本
[root@k8s ~]# cat /etc/os-release
NAME="Rocky Linux"
VERSION="9.1 (Blue Onyx)"
ID="rocky"
ID_LIKE="rhel centos fedora"
VERSION_ID="9.1"
PLATFORM_ID="platform:el9"
PRETTY_NAME="Rocky Linux 9.1 (Blue Onyx)"
ANSI_COLOR="0;32"
LOGO="fedora-logo-icon"
777CPE_NAME="cpe:/o:rocky:rocky:9::baseos"
HOME_URL="https://rockylinux.org/"
BUG_REPORT_URL="https://bugs.rockylinux.org/"
ROCKY_SUPPORT_PRODUCT="Rocky-Linux-9"
ROCKY_SUPPORT_PRODUCT_VERSION="9.1"
REDHAT_SUPPORT_PRODUCT="Rocky Linux"
REDHAT_SUPPORT_PRODUCT_VERSION="9.1"

安装

1、 卸载Docker的旧版本

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

2、 安装基本环境

yum install -y yum-utils

3、设置镜像的仓库

yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

4、更新yum源并安装docker-ce

yum update --allowerasing --nobest
yum makecache
sudo yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin -y

5、启动docker

[root@k8s ~]# systemctl start docker

6、 查看docker version 查看是否安装成功

[root@k8s ~]# docker version
Client: Docker Engine - Community
Version: 24.0.7
API version: 1.43
Go version: go1.20.10
Git co- Thu Oct 26 09:09:13 2023
OS/Arch: linux/amd64
Context: default

Server: Docker Engine - Community
Engine:
Version: 24.0.7
API version: 1.43 (minimum version 1.12)
Go version: go1.20.10
Git commit: 311b9ff
Built: Thu Oct 26 09:07:45 2023
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.6.25
GitCommit: d8f198a4ed8892c764191ef7b3b06d8a2eeb5c7f
runc:
Version: 1.1.10
GitCommit: v1.1.10-0-g18a0cb0
docker-init:
Version: 0.19.0
GitCommit: de40ad0

7、 运行hello world

[root@k8s ~]# docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
719385e32844: Pull complete
Digest: sha256:c79d06dfdfd3d3eb04cafd0dc2bacab0992ebc243e083cabe208bac4dd7759e0
Status: Downloaded newer image for hello-world:latest

Hello from Docker! //看到这句话表明安装成功
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/

For more examples and ideas, visit:
https://docs.docker.com/get-started/

8、 查看hello-world镜像

[root@k8s ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest 9c7a54a9a43c 7 months ago 13.3kB

了解:卸载docker

# 1、卸载依赖
yum remove install docker-ce docker-ce-cli containerd.io docker-compose-plugin -y

# 2、 删除资源
rm -rf /var/lib/docker

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

配置阿里云加速

1、 执行命令、查看是否在dockrr.service文件中配置过镜像地址

systemctl cat docker | grep '\-\-registry\-mirror'

2、 在/etc/docker/daemon.json中写入如下内容 (如果文件不存在请新建该文件)

{
"registry-mirrors": [
"https://hub-mirror.c.163.com",
"https://mirror.baidubce.com"
]
}

一定要确保文件符合jssn规范,否则Docker将不能启动

3、重启docker服务

sudo systemctl daemon-reload
sudo systemctl restart docker

回顾HelloWorld流程

run的运行流程图

image-20231206100712580

底层原理

Docker是什么工作的?

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

image-20231206101604313

Docker为什么比VM快?

  • Docker有着比虚拟机更少的抽象层
  • Docker利用的是宿主机的内核,VM需要是Guest OS。

image-20231206101735199

所以说,新建一个容器的时候,docker不需要像虚拟机一样重新加载一个操作系统内核,避免引导。虚拟机时加载Guest OS,分钟级别的,而Docker时利用宿主机的操作系统。

Docker的常用命令

帮助命令

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

帮助文档地址:https://docker-practice.github.io/zh-cn/

镜像命令

  • docker images 查看镜像
[root@k8s ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest 9c7a54a9a43c 7 months ago 13.3kB

# 解释
REPOSITORY 镜像的仓库源
TAG 镜像的标签
Image ID 镜像的id
Create 镜像的创建时间
SIZE 镜像的大小

# 可选项
Options:
-a, --all # 显示镜像的详细信息
-q, --quiet # 只显示镜像id
  • docker search 搜索镜像
[root@k8s ~]# docker search nginx
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
nginx Official build of Nginx. 19320 [OK]
unit Official build of NGINX Unit: Universal Web … 19 [OK]
nginxinc/nginx-unprivileged Unprivileged NGINX Dockerfiles 136

# 可选项,通过搜藏来过来吧
--filter=STARS=3000 ## 搜索出的镜像收藏大于3000的
  • docker pull 下载镜像
# 下载镜像 docker pull 镜像名[:tag]
[root@k8s ~]# docker pull nginx
Using default tag: latest # 如果不写tag,默认就是latest
latest: Pulling from library/nginx
1f7ce2fa46ab: Pull complete # 分层下载 docker images的核心 联合文件系统
9b16c94bb686: Pull complete
9a59d19f9c5b: Pull complete
9ea27b074f71: Pull complete
c6edf33e2524: Pull complete
84b1ff10387b: Pull complete
517357831967: Pull complete
Digest: sha256:10d1f5b58f74683ad34eb29287e07dab1e90f10af243f151bb50aa5dbb4d62ee # 签名
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest # 真实地址

# 等价于它
docker pull nginx
docker pull docker.io/library/nginx:latest

# 指定版本下载

  • docker rm 删除镜像
[root@k8s ~]# docker rmi -f nginx:latest 
Untagged: nginx:latest

# 删除所有镜像
[root@k8s ~]# docker rmi -f $(docker images -qa)
Untagged: hello-world:latest
Untagged: hello-world@sha256:c79d06dfdfd3d3eb04cafd0dc2bacab0992ebc243e083cabe208bac4dd7759e0
Deleted: sha256:9c7a54a9a43cca047013b82af109fe963fde787f63f9e016fdc3384500c2823d

[root@k8s ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE


容器命令

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

docker pull centos

新建容器并启动

docker run [可选参数] image

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

# 启动并进入容器
[root@k8s ~]# docker run -it centos /bin/bash
[root@83711eb4d20a /]#

# 查看容器内的centos
[root@83711eb4d20a /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var

# 退回主机
[root@83711eb4d20a /]# exit
exit
[root@k8s ~]#

列出运行中的容器

# docker ps 命令
-a # 列出当前正在运行的容器+带出历史运行过的容器
-n=? #显示最近创建的容器
-q # 只显示容器的编号
[root@k8s ~]# docker ps -a -n=1
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
83711eb4d20a centos "/bin/bash" 4 minutes ago Exited (0) 2 minutes ago awesome_lederberg

[root@k8s ~]# docker ps -aq
83711eb4d20a
e36750cdcde1
  • 退出容器
exit  # 停止容器并退出
ctrl Q P # 退出并不停止

# 运行容器并执行退出并不停止指令
[root@k8s ~]# docker run -it centos /bin/bash
[root@69296df22e03 /]# [root@k8s ~]#

# 查看当前运行的容器
[root@k8s ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
69296df22e03 centos "/bin/bash" 12 seconds ago Up 11 seconds cool_bouman
  • 删除容器
docker rm 容器id   # 删除指定容器,不能删除正在运行的容器 如果要强制删除 rm -f
docker rm -f $(docker ps -aq) # 删除所有容器
  • 启动和停止容器的操作
docker start 容器id    # 启动容器
docker restart 容器id # 重启容器
docker stop 容器id # 停止当前正在运行的容器
docker kill 容器id # 强制停止当前容器

常用其它命令

后台启动容器

[root@k8s ~]# docker run -d centos    //后台启动容器
c75899a445cd92b117337f1bb80c4606dcef87f0dbdda1c76149301b5dcb4725

[root@k8s ~]# docker ps -a //查看容器
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c75899a445cd centos "/bin/bash" 2 minutes ago Exited (0) 2 minutes ago elegant_edison cool_bouman

# 问题 docker ps,发现centos 停止了

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

利用死循环让容器有事可做

# 创建容器 并在其中编写一个shell脚本
[root@k8s ~]# docker run -d centos /bin/sh -c "while true;do echo kuangshen;sleep 1;done"
bf139241a91b97b33d8fbefdec9b7c337500dafc5d270e40407b516f7b66ab0c

# 查看容器状态
[root@k8s ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bf139241a91b centos "/bin/sh -c 'while t…" 17 seconds ago Up 16 seconds modest_kilby

# 查看容器日志
[root@k8s ~]# docker logs -t -f --tail 10 bf139241a91b
2023-12-06T03:40:39.057567655Z kuangshen
2023-12-06T03:40:40.059862129Z kuangshen
2023-12-06T03:40:41.062034487Z kuangshen
2023-12-06T03:40:42.064470085Z kuangshen
2023-12-06T03:40:43.066782894Z kuangshen

查看日志

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

# 自己编写一段shell脚本
"whlie ture;do echo toto;sleep 2;done"
# 显示日志
-tf # 显示日志
--tail number # 要显示的日志条数
[root@k8s ~]# docker logs -f -t --tail 10 7a173bcad9ba 查看容器日志
2023-12-06T03:31:50.560503837Z /bin/sh: whlie ture;do echo toto;sleep 2;done: No such file or directory

查看容器中的进程信息 ps

[root@k8s ~]# docker top bf139241a91b
UID PID PPID C STIME TTY TIME CMD
root 10569 10532 0 22:38 ? 00:00:00 /bin/sh -c while true;do echo kuangshen;sleep 1;done
root 11713 10569 0 22:48 ? 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1

查看镜像源数据

[root@k8s ~]# docker inspect bf139241a91b
[
{
"Id": "bf139241a91b97b33d8fbefdec9b7c337500dafc5d270e40407b516f7b66ab0c",
"Created": "2023-12-06T03:38:56.618698931Z",
"Path": "/bin/sh",
"Args": [
"-c",
"while true;do echo kuangshen;sleep 1;done"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 10569,
"ExitCode": 0,
"Error": "",
"StartedAt": "2023-12-06T03:38:56.841697401Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6",
"ResolvConfPath": "/var/lib/docker/containers/bf139241a91b97b33d8fbefdec9b7c337500dafc5d270e40407b516f7b66ab0c/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/bf139241a91b97b33d8fbefdec9b7c337500dafc5d270e40407b516f7b66ab0c/hostname",
"HostsPath": "/var/lib/docker/containers/bf139241a91b97b33d8fbefdec9b7c337500dafc5d270e40407b516f7b66ab0c/hosts",
"LogPath": "/var/lib/docker/containers/bf139241a91b97b33d8fbefdec9b7c337500dafc5d270e40407b516f7b66ab0c/bf139241a91b97b33d8fbefdec9b7c337500dafc5d270e40407b516f7b66ab0c-json.log",
"Name": "/modest_kilby",
"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,
"ConsoleSize": [
46,
153
],
"CapAdd": null,
"CapDrop": null,
"CgroupnsMode": "private",
"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",
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": [],
"BlkioDeviceReadBps": [],
"BlkioDeviceWriteBps": [],
"BlkioDeviceReadIOps": [],
"BlkioDeviceWriteIOps": [],
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": [],
"DeviceCgroupRules": null,
"DeviceRequests": null,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": null,
"OomKillDisable": null,
"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",
"/sys/devices/virtual/powercap"
],
"ReadonlyPaths": [
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
},
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/1f2d513a668a223e0ca04353b567a1fd88c1ff384472805d82e7aca0ab1aa7e0-init/diff:/var/lib/docker/overlay2/3d9e04ce7377c934935b44d560ac38c7fabad822afe5277a0aebcc4dc18a7f1f/diff",
"MergedDir": "/var/lib/docker/overlay2/1f2d513a668a223e0ca04353b567a1fd88c1ff384472805d82e7aca0ab1aa7e0/merged",
"UpperDir": "/var/lib/docker/overlay2/1f2d513a668a223e0ca04353b567a1fd88c1ff384472805d82e7aca0ab1aa7e0/diff",
"WorkDir": "/var/lib/docker/overlay2/1f2d513a668a223e0ca04353b567a1fd88c1ff384472805d82e7aca0ab1aa7e0/work"
},
"Name": "overlay2"
},
"Mounts": [],
"Config": {
"Hostname": "bf139241a91b",
"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 kuangshen;sleep 1;done"
],
"Image": "centos",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {
"org.label-schema.build-date": "20210915",
"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": "aed70a42c2b8aeace833daa6eb8eb1957d96b3f6d9e8ae08be93ca8ce982429c",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {},
"SandboxKey": "/var/run/docker/netns/aed70a42c2b8",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "01577e66ee97687e028f2e0760a5c62369a33ad1cfce03cac440f8464df67387",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.4",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:04",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "26c6fbe3fe76e6e36a1833f32b0d5216a17c1fd70f9a6efd037114bba1cd56c8",
"EndpointID": "01577e66ee97687e028f2e0760a5c62369a33ad1cfce03cac440f8464df67387",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.4",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:04",
"DriverOpts": null
}
}
}
}
]

进入当前正在运行的容器

# 我们通常容器都是使用后台方式运行的,需要进入容器,修改一些配置

# 命令
docker exec -it 容器id bashshell

# 使用exec进入容器
[root@k8s ~]# docker exec -it bf139241a91b bash
[root@bf139241a91b /]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 03:38 ? 00:00:00 /bin/sh -c while true;do echo kuangshen;sleep 1;done
root 1275 0 0 04:00 pts/0 00:00:00 bash
root 1309 1 0 04:00 ? 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1
root 1310 1275 0 04:00 pts/0 00:00:00 ps -ef

# 方式二

docker attach 容器id

[root@k8s ~]# docker attach bf139241a91b
kuangshen
kuangshen

# docker exec # 进入容器后开启一个新的终端
# docker attch # 进入容器正在执行的终端,不会启动新的进程

从容器内拷贝文件到容器外

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

[root@k8s home]# docker cp b25a87d930f8:/home/test.java /home
Successfully copied 1.54kB to /home
[root@k8s home]# ls
ayaka kuangshen.java test.java toto


exec会进入容器并开启一个新bash终端,exit时不会导致容器stop,attach退出时会导致容器stop

小结

attach    Attach to a running container  #当前shell下attach连接指定运行镜像
build Build an image from a Dockerfile #通过Dockerfile定制镜像
commit Create a new image from a container's changes #提交当前容器为新的镜像
cp Copy files/folders from a container to a HOSTDIR or to STDOUT #从容器中拷贝指定文件或者目录到宿主机中
create Create a new container #创建一个新的容器,同run 但不启动容器
diff Inspect changes on a container's filesystem #查看docker容器变化
events Get real time events from the server#从docker服务获取容器实时事件
exec Run a command in a running container#在已存在的容器上运行命令
export Export a container's filesystem as a tar archive #导出容器的内容流作为一个tar归档文件(对应import)
history Show the history of an image #展示一个镜像形成历史
rename Rename a container #重命名容器
restart Restart a running container #重启运行的容器
rm Remove one or more containers #移除一个或者多个容器
rmi Remove one or more images #移除一个或多个镜像(无容器使用该镜像才可以删除,否则需要删除相关容器才可以继续或者-f强制删除)
run Run a command in a new container #创建一个新的容器并运行一个命令
save Save an image(s) to a tar archive#保存一个镜像为一个tar包(对应load)
search Search the Docker Hub for images #在dockerhub中搜索镜像
start Start one or more stopped containers#启动容器
stats Display a live stream of container(s) resource usage statistics #统计容器使用资源
stop Stop a running container #停止容器
tag Tag an image into a repository #给源中镜像打标签
top Display the running processes of a container #查看容器中运行的进程信息
unpause Unpause all processes within a container #取消暂停容器
version Show the Docker version information#查看容器版本号
wait Block until a container stops, then print its exit code #截取容器停止时的退出状态值
images List images #列出系统当前镜像
import Import the contents from a tarball to create a filesystem image #从tar包中的内容创建一个新的文件系统映像(对应export)
info Display system-wide information #显示系统相关信息
inspect Return low-level information on a container or image #查看容器详细信息
kill Kill a running container #kill指定docker容器
load Load an image from a tar archive or STDIN #从一个tar包中加载一个镜像(对应save)
login Register or log in to a Docker registry#注册或者登陆一个docker源服务器
logout Log out from a Docker registry #从当前Docker registry退出
logs Fetch the logs of a container #输出当前容器日志信息
pause Pause all processes within a container#暂停容器
port List port mappings or a specific mapping for the CONTAINER #查看映射端口对应的容器内部源端口
ps List containers #列出容器列表
pull Pull an image or a repository from a registry #从docker镜像源服务器拉取指定镜像或者库镜像
push Push an image or a repository to a registry #推送指定镜像或者库镜像至docker源服务器

Docker安装Nginx

# 搜索镜像 下载镜像
# 下载镜像 pull
# 运行模式

1、下载nginx镜像
docker pull nginx

2、查看镜像
[root@k8s ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest a6bd71f48f68 2 weeks ago 187MB
hello-world latest 9c7a54a9a43c 7 months ago 13.3kB
centos latest 5d0da3dc9764 2 years ago 231MB

3、创建容器
docker run -d --name web1 -p 8001:80 nginx

# -d 后台运行容器
# --name 给容器命名
# -p 宿主机端口:容器内部端口
4、查看容器列表
[root@k8s ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
354382b1bdb4 nginx "/docker-entrypoint.…" 2 minutes ago Up 2 minutes 0.0.0.0:8001->80/tcp, :::8001->80/tcp web1
5、访问本机的8001端口
[root@k8s ~]# curl 192.168.123.101:8001
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
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>

思考问题:我们每次改动nginx配置文件,都需要进入容器内部?十分的麻烦,我要是可以再容器外部提供一个映射的路径,在容器修改文件,容器内部就可以自动修改?

-v 数据卷

docker安装tomcat

一、下载tomcat

docker pull tomcat

二、检查镜像

[root@k8s ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat latest e76527586e57 3 days ago 454MB

三、启动运行tomcat

[root@k8s ~]# docker run -d -p 8002:8080 --name tomcat01 tomcat
ce4f651b97a28c829ca4a055fdc44fb389d21ffa8520bb2060c05031771a0403

四、测试访问tomcat

[root@k8s ~]# curl localhost:8002
<!doctype html><html lang="en"><head><title>HTTP Status 404 – Not Found</title><style type="text/css">body {font-family:Tahoma,Arial,sans-serif;} h1, h2, h3, b {color:white;background-color:#525D76;} h1 {font-size:22px;} h2 {font-size:16px;} h3 {font-size:14px;} p {font-size:12px;} a {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTP Status 404 – Not Found</h1><hr class="line" /><p><b>Type</b> Status Report</p><p><b>Description</b> The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.</p><hr class="line" /><h3>Apache Tomcat/10.1.16</h3></body></html>[

image-20231206145030002

发生404报错 说明缺少配置

五、进入tomcat容器

[root@k8s ~]# docker exec -it tomcat01 bash

root@ce4f651b97a2:/usr/local/tomcat# cd webapps
root@ce4f651b97a2:/usr/local/tomcat/webapps# ls

# 发现问题 Linux命令少了 没有webapps。
原因:
tomcat默认是最小的镜像 把所有没必要的配置文件都删除
保证最小可运行的环境

# 进入webapps.dist
root@ce4f651b97a2:/usr/local/tomcat/webapps/webapps.dist# ls
docs examples host-manager manager ROOT

发现:
webapps.dist目录下存在的所有目录都是webapps的 我们将该目录的所有配置文件复制到webapps里卖弄

# 复制文件
root@ce4f651b97a2:/usr/local/tomcat# cp -a webapps.dist/* webapps/

# 保存并退出容器 再次进行访问

保存并退出容器 再次进行访问

image-20231206145754654

网页就已经有内容了

思考问题:当每次部署服务时,每次都要进入容器是否十分麻烦?我要是可以在容器外部提供一个映射路径,webapps。我们在外部放置项目,就自动同步到内部就好了!

部署es+kibana

# es 暴露的端口很多
# es 十分的耗内存
# es 的数据一般需要放置到安全目录!挂载

启动elasticsearch

docker run -d --name elasticsearch2 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" --memory="4g" -e "ES_JAVA_OPTS=-Xms1024m -Xmx2048m" --ulimit nofile=1024   elasticsearch

docker stats查看cpu状态

docker stats

CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
f8fac70c779b elasticsearch2 0.17% 1.226GiB / 4GiB 30.64% 3.18kB / 771B 63.2MB / 2.14MB 66

访问测试9200端口

[root@k8s ~]# curl localhost:9200
{
"name" : "yJ3yRFr",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "kdlRE7FlQHGQji1MK8CNcQ",
"version" : {
"number" : "5.6.12",
"build_hash" : "cfe3d9f",
"build_date" : "2018-09-10T20:12:43.732Z",
"build_snapshot" : false,
"lucene_version" : "6.6.1"
},
"tagline" : "You Know, for Search"
}
[root@k8s ~]#

可视化

  • 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的图形化界面管理工具,提供一个后台面板供我们操作

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

二、访问本地主机的8088端口

  • 进入后的面板

image-20231206163019399

可视化面板我们平时不会使用,大家测试玩玩即可

Docker镜像讲解

镜像是什么

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

所用应用打包到docker镜像

如何得到镜像:

  • 远程仓库下载
  • 朋友拷给你
  • 自己制作一个镜像dockerfile

Docker镜像加载原理

UnionFS (联合文件系统)

UnionFS(联合文件系统):Union文件系统是一种分层、轻量级并且高性能的文件系统、它支持对文件系统的修改作为一次提交来一层层的叠加、同时可以将不同目录挂载同一个虚拟文件系统下。Union文件系统时Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。

特性:一次他哦那个是加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终文件系统会包含所有底层的文件和目录。

Docker镜像加载原理

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

bootfs主要包含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等。

image-20231206194149946

平时我们安装进虚拟机的Centos都是好几个G,为什么Docker这里才200M?

image-20231206195003842

对于一个精简的OS,rootfs可以很小,只需要包含最基本的命令,工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供rootfs就可以了。由此可见对于不同的linux发行版,bootfs最基本时一直的,rootfs会有差别,因此不同的发行版可以公用bootfs。

分层理解

分层的镜像

我们可以去下载一个镜像,注意观察下载的日志输出,可以看到时一层一层的在下载!

image-20231206200629998

理解:

所有的Docker镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层上面,创建新的镜像层。

举一个简单的例子,假如基于Ubuntu Linux创建一个新的镜像,这就是新镜像的第一层,如果在该镜像中添加Python包,就会在基础镜像层之上创建第二个镜像层,如果继续添加一个安全补丁,就会创建第三个镜像层。

该镜像当前已经包含3个镜像层,如下图所示:

image-20231207082519068

在添加额外的镜像层的同时,镜像始终保持时当前所有镜像的组合,下图中,每个镜像层包含3个文件,而镜像包含了来自两个镜像层的6个文件。

image-20231207082641558

上图中的镜像跟之前略有区别,便于展示文件。

下图中展示了一个稍微复杂的三层镜像,在外部看来整个镜像只有6个文件,这是因为最上层中的文件7时文件5的一个更新的版本。image-20231207082752378

这种情况下,上层镜像层中的文件覆盖了顶层镜像层中的文件,这样使得文件的更新版本作为一个新镜像层添加到镜像当中。

Docker通过存储引擎(新版本采用快照机制)的方式来实现镜像层的堆栈,并保证多镜像层对外展示统一的文件系统。

Linux上可用的村塾引擎由AUFS,Overlay2.故名思意,每种存储引擎都基于Linux中对应的文件一同或者块这杯技术。

Docker在Windows上仅支持windowsfilter一种存储引擎,该殷勤基于NTFS文件系统之上实现了分层

特点

Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部。

这一层就是我们常说的容器层,容器之下的都叫镜像层。

特点

Docker镜像都是只读的,当容器启动时 (run),一个新的可写层被加载到镜像的顶部!

这一层就是我们所说的容器层,容器之下的都叫镜像层(pull)

image-20231206201714143

如何提交一个自己的镜像

commit镜像

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

# 命令和git原理类似
docker commit -m=“提交的描述信息” -a=“作者” 容器id 目标镜像名,[Tag]

实战测试

一、启动一个默认的tomcat

# 发现这个默认的tomcat 是没有webapps应用的 镜像的原因 官方的镜像默认webapps下面是没有文件的!

# 我自己拷贝进去了的基本的文件
root@814727eb2952:/usr/local/tomcat# cp -r webapps.dist/* webapps
root@814727eb2952:/usr/local/tomcat# ls webapps
docs examples host-manager manager ROOT

# 查看容器列表
[root@k8s ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
814727eb2952 tomcat "catalina.sh run" 4 minutes ago Up 4 minutes 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp lucid_meninsky

# commit修改好的tomcat容器为tomcat02:1.0镜像
[root@k8s ~]# docker commit -a="ayaka" -m="add webapps app" 814727eb2952 tomcat02:1.0
sha256:60e11d6e91c0a5a5bd66de73240e84f644b453be6e97b378f0aba5f63d0aaa9e

# 查看镜像库
[root@k8s ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat02 1.0 60e11d6e91c0 4 seconds ago 458MB
tomcat latest e76527586e57 4 days ago 454MB
httpd latest a6ca7b52a415 2 weeks ago 168MB
nginx latest a6bd71f48f68 2 weeks ago 187MB

image-20231206202718157

容器数据卷

什么是容器数据卷

docker的理念回顾

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

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

使用数据卷

  • 方式一:使用命令进行挂载
docker run -it -v 主机目录,容器目录

# 使用docker inspcet查看容器的具体信息
docker inspect 容器id

image-20231207084700871

宿主机内创建的文件 容器内部也能看到

效果:

容器内部:

image-20231207084937247

宿主机:

image-20231207085027544

部署MySQL

获取镜像

[root@k8s home]# docker pull mysql:5.7

启动服务

[root@k8s home]# 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 

-d 后台运行
-v 卷挂载
-p 端口映射
-e 环境配置
--name 容器名字

# 启动成功之后,在本地使用sqlyog来测试一下
# sqlyog-连接到服务器的3310---3310和容器内的3306端口的映射,整个时候我们就可以脸上了

# 在本地测试创建一个数据库 查看一下映射的路径
[root@k8s home]# ls /home/mysql/data/
auto.cnf client-cert.pem ibdata1 ibtmp1 performance_schema server-cert.pem toto
ca-key.pem client-key.pem ib_logfile0 mysql private_key.pem server-key.pem
ca.pem ib_buffer_pool ib_logfile1 mysql.sock public_key.pem sys

具名挂载和匿名挂载

# 匿名挂载
-v 容器内的路径
docker run -d -P --name nginx1 -v /etc/nginx nginx
# 查看所有volume的情况
[root@k8s home]# docker volume ls
DRIVER VOLUME NAME
local 0f7af9b1708ed85f3c19f990ccf2ac4fb11e609ca79ae6cd03fd8b2940725a2d
local 1e3f80d7bef22963854d2fcb6b47cd1810a40b60beefb468a2183264ee20f5a0

# 上面这种就是匿名挂载

# 使用具名挂载
[root@k8s home]# docker run -d -P --name NginxB -v juming-nginx:/etc/nginx nginx
da62fa064716e96fe552c91bc8a3eb5e30f686b43c02b3edbf76b5f640758c3f

# 再次查看卷列表
[root@k8s home]# docker volume ls
DRIVER VOLUME NAME
local f531c23ff1b3320bc3467a899119ef3c868d4830a1ac345b27f9f0ddda7f3ffe
local juming-nginx

对应的路径

[root@k8s home]# docker volume inspect juming-nginx
[
{
"CreatedAt": "2023-12-06T20:30:22-05:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data",
"Name": "juming-nginx",
"Options": null,
"Scope": "local"
}
]

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

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

区分具名、匿名挂载

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

image-20231207093818468

初识dockerfile

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

#  创建一个dockerfile文件,名字可用随机,建议使用Dockerfile
# 文件中的内容
[root@k8s docker-test]# cat dockerfile1
FROM centos

VOLUME ["volume01","volume02"]

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

image-20231207094909141

使用构建的镜像创建容器

[root@k8s docker-test]# docker run -it bcb7b9d02259  bash

# bcb7b9d02259为我们镜像的id
REPOSITORY TAG IMAGE ID CREATED SIZE
mycentos 1.0 bcb7b9d02259 2 years ago 231MB

image-20231207095153112

测试目录同步

进入到volume2中 创建文件并保存

[root@k8s docker-test]# docker exec -it 65b097a207f6 bash
[root@65b097a207f6 /]# cd volume02
[root@65b097a207f6 volume02]# mkdir toto
[root@65b097a207f6 volume02]# touch index.txt
[root@65b097a207f6 volume02]# read escape sequence
# 按住ctrl+p+q退出并继续运行容器

查看容器信息 (查看宿主机默认的挂载目录)

[root@k8s _data]# docker inspect 65b097a207f6

"Mounts": [
{
"Type": "volume",
"Name": "2ad3dd80f2261dee63ddd333ccfe0057a890ded085d58e2c050fd141d40dafe2",
"Source": "/var/lib/docker/volumes/2ad3dd80f2261dee63ddd333ccfe0057a890ded085d58e2c050fd141d40dafe2/_data",
"Destination": "volume02",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
},
#
查询到默认挂载的目录:/var/lib/docker/volumes/2ad3dd80f2261dee63ddd333ccfe0057a890ded085d58e2c050fd141d40dafe2/_data

进入默认挂载目录并查看目录内容

[root@k8s docker-test]# cd /var/lib/docker/volumes/2ad3dd80f2261dee63ddd333ccfe0057a890ded085d58e2c050fd141d40dafe2/_data

[root@k8s _data]# ls
index.txt toto
# 同步成功

数据卷容器

多个mysql同步数据 容器间的数据共享

image-20231207100626194

# 启动三个容器 通过我们自己写的镜像启动
  • docker01

image-20231207101041024

  • docker02

image-20231207101342245

  • docker03 同步

image-20231207102147050

  • docker01 同步

image-20231207102227008

  • docker02 同步

image-20231207102257809

同步成功 这样我们就实现了容器间的数据共享

当我们在docker1上创建了文件时 宿主机、docker02、3都能接收到这个文件 说明了我们实现了容器间的数据共享~

docker02、03时绑定的docker01 但是docker01容器被kill掉时 docker02、03的数据依旧不会消失 ~

因为他们三个都绑定到了宿主机上 只要宿主机上的文件还存在 那么volumes01、02目录的内容就不会消失~

实现多个mysql数据共享

一、创建两个mysql容器 mysqlB绑定到mysqlA上

[root@k8s ~]# docker run -d -p 3311:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysqlA mysql:5.7

[root@k8s ~]# docker run -d -p 3312:3306 --volumes-from mysqlA -e MYSQL_ROOT_PASSWORD=123456 --name mysqlB mysql:5.7c2c2bf254ad7c1e5b6ea56886cbe959fbe5ae07d5262d651d3509129cedad31a

二、在MysqlA上创建数据库mariadb 并查看宿主机上的挂载目录

image-20231207104032725

三、在MysqlB上创建数据库postgresql并在宿主机上查看目录

image-20231207104302194

这样就实现了多个mysql的数据共享


Dockerfile

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

构建步骤:

1、编写一个dockerfile文件

2、docker build构建成一个镜像

3、docker run 运行镜像

4、 docker push 发布镜像

Docker构建过程

基础知识:

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

2、执行从上到下的顺序

3、 # 表示注释

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

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

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

Dockerfile:构建文件,定义了一切的步骤

DockerImages:通过dockerfile构建生成的一个镜像

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

Dockerfile的指令

FROM          # 基础镜像,一切从这里开始构建
MAINTAINER # 维护者信息
RUN # 镜像构建运行的命令
ADD # 增加文件
workdir # 镜像的工作目录
VOLUME # 镜像挂载目录
EXPOSE # 申明端口
CMD # 指定启动容器时运行的命令
ENTRYPOINT # 指定这个容器启动的时候要运行的命令,可用追加命令
COPY # 类似ADD命令,将我们文件拷贝到镜像中

nMzQji

创建一个自己的centos

[root@k8s centos]# cat Dockerfile 
FROM centos:7
MAINTAINER ayaka<2187988995@qq.com>

ENV MYPATH /usr/local
WORKDIR $MYPATH

RUN yum install -y vim
RUN yum -y install net-tools

EXPOSE 80

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

通过文件构建镜像

[root@k8s centos]# docker build -f Dockerfile -t centos-yum:1.0 .

[root@k8s centos]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos-yum 1.0 b7e760e76050 2 hours ago 687MB

测试运行

[root@k8s centos]# docker run -it --name centos01 centos-yum:1.0
/usr/local
----end----
[root@075633642f19 local]#
[root@075633642f19 local]# ls
bin etc games include lib lib64 libexec sbin share src

测试vim和ifconfig命令

[root@075633642f19 local]# ifconfig 
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.3 netmask 255.255.0.0 broadcast 172.17.255.255
ether 02:42:ac:11:00:03 txqueuelen 0 (Ethernet)
RX packets 17 bytes 2144 (2.0 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1000 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

[root@075633642f19 local]#

查看镜像构建过程

Docker history

[root@k8s centos]# docker history centos-yum:1.0 
IMAGE CREATED CREATED BY SIZE COMMENT
b7e760e76050 2 hours ago CMD ["/bin/bash" "-c" "echo $MYPATH && echo … 0B buildkit.dockerfile.v0
<missing> 2 hours ago EXPOSE map[80/tcp:{}] 0B buildkit.dockerfile.v0
<missing> 2 hours ago RUN /bin/sh -c yum -y install net-tools # bu… 198MB buildkit.dockerfile.v0
<missing> 2 hours ago RUN /bin/sh -c yum install -y vim # buildkit 285MB buildkit.dockerfile.v0
<missing> 3 hours ago WORKDIR /usr/local 0B buildkit.dockerfile.v0
<missing> 3 hours ago ENV MYPATH=/usr/local 0B buildkit.dockerfile.v0
<missing> 3 hours ago MAINTAINER ayaka<2187988995@qq.com> 0B buildkit.dockerfile.v0
<missing> 2 years ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
<missing> 2 years ago /bin/sh -c #(nop) LABEL org.label-schema.sc… 0B
<missing> 2 years ago /bin/sh -c #(nop) ADD file:b3ebbe8bd304723d4… 204MB

CMD

Dockerfile中的CMD的运用技巧

# 创建一个Dockerfile 并在其中添加CMD参数命令 指定进入容器时 运行ls -a命令
[root@k8s centos]# vim dockerfile-cmd-test
# 构建镜像
[root@k8s centos]# docker build -f dockerfile-cmd-test -t cmdtest:1.0 .
# 启动容器
[root@k8s centos]# docker run -it cmdtest:1.0
. .. .dockerenv bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var

Dockerfile内容
[root@k8s centos]# cat dockerfile-cmd-test
FROM centos
CMD ["ls","-a"]

ENTRYPORT

Dockerfile中ENTRYPOINT的运用技巧

创建容器
[root@k8s centos]# docker run -it entrypoint:1
. .. .dockerenv bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var

构建镜像
[root@k8s centos]# docker build -f dockerfile-cmd-entrypoint -t entrypoint:1 .

Dockerfile中的内容
FROM centos
ENTRYPOINT ["ls","-a"]

# 我们的追加命令,时可以直接评价在ENTRYPOINT追加
[root@k8s centos]# docker run entrypoint:1 -l
total 4
drwxr-xr-x 1 root root 6 Dec 7 06:41 .
drwxr-xr-x 1 root root 6 Dec 7 06:41 ..
-rwxr-xr-x 1 root root 0 Dec 7 06:41 .dockerenv
lrwxrwxrwx. 1 root root 7 Nov 3 2020 bin -> usr/bin
drwxr-xr-x 5 root root 340 Dec 7 06:41 dev
drwxr-xr-x 1 root root 66 Dec 7 06:41 etc
drwxr-xr-x. 2 root root 6 Nov 3 2020 home
lrwxrwxrwx. 1 root root 7 Nov 3 2020 lib -> usr/lib
lrwxrwxrwx. 1 root root 9 Nov 3 2020 lib64 -> usr/lib64
drwx------. 2 root root 6 Sep 15 2021 lost+found
drwxr-xr-x. 2 root root 6 Nov 3 2020 media
drwxr-xr-x. 2 root root 6 Nov 3 2020 mnt
drwxr-xr-x. 2 root root 6 Nov 3 2020 opt
dr-xr-xr-x 429 root root 0 Dec 7 06:41 proc
dr-xr-x---. 2 root root 162 Sep 15 2021 root
drwxr-xr-x. 11 root root 163 Sep 15 2021 run
lrwxrwxrwx. 1 root root 8 Nov 3 2020 sbin -> usr/sbin
drwxr-xr-x. 2 root root 6 Nov 3 2020 srv
dr-xr-xr-x 13 root root 0 Dec 7 06:41 sys
drwxrwxrwt. 7 root root 171 Sep 15 2021 tmp
drwxr-xr-x. 12 root root 144 Sep 15 2021 usr
drwxr-xr-x. 20 root root 4096 Sep 15 2021 var

构建httpd镜像

一、创建文件夹并编辑Dockerfile文件

FROM rockylinux:9.1
MAINTAINER ayaka

COPY yum.repo /usr/local
COPY httpd.conf /usr/local

RUN rm -rf /etc/yum.repos.d/* && \
cp /usr/local/yum.repo /etc/yum.repos.d/ && \
yum makecache && \
yum install -y httpd* && \
echo "hello world" > /var/www/html/index.html && \
mv -f /usr/local/httpd.conf /etc/httpd/conf/

CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]
# 构建镜像
[root@k8s tomcat]# docker build -t centos-web:1.0 .

查看镜像列表

root@k8s tomcat]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos-web 1.0 6e46f461db6c 14 minutes ago 278MB

创建容器

[root@k8s tomcat]# docker run -itd --name webA -p 8001:80 centos-web:1.0 
55b24aaec93d01e68cbfb286d854d9758348c9fcf4aeb4496c195f714bd793ca

访问8001端口

[root@k8s tomcat]# curl localhost:8001
hello world

Rocky容器内启动Apche Httpd服务

利用镜像创建容器

[root@k8s ~]# docker run -it --name web1 -p 1234:80 --privileged=true --restart=always rockylinux:9.1 bash
828e1c7387b2c692e82f9d96402779325e824bf34505b94869ae742a9681a576

配置好yum源

[root@daa98bede414 /]# cat /etc/yum.repos.d/yum.repo 
[Install-Media]
name=RockyLinux9.1
baseurl=http://192.168.123.101/cdrom/AppStream
gpgcheck=0
enabled=1
[Install-BaseOS]
name=RockyLinux9.1
baseurl=http://192.168.123.101/cdrom/BaseOS
gpgcheck=0
enabled=1

# 更新本地源缓存
[root@daa98bede414 /]# yum makecache
RockyLinux9.1 4.0 MB/s | 4.1 kB 00:00
RockyLinux9.1 3.6 MB/s | 3.6 kB 00:00
Metadata cache created.

下载软件包并进行配置

# 下载软件包和vim工具
[root@daa98bede414 /]# yum install -y httpd* vim
# 编辑主页内容
[root@daa98bede414 /]# echo "Hello World" > /var/www/html/index.html
# 进入配置文件配置虚拟主机
[root@k8s ~]# tail -10 /etc/httpd/conf/httpd.conf
IncludeOptional conf.d/*.conf
<Virtualhost *:80>
ServerName localhost
DocumentRoot "/var/www/html"
<Directory "/var/www/html">
Require all granted
</Directory>
</VirtualHost>

重启httpd

[root@daa98bede414 /]# /usr/sbin/httpd 

退出到宿主机并访问1234端口

[root@k8s ~]# curl localhost:1234
Hello World