前置知识点
企业IT数字化转型的“三阶段两转变“
什么是云原生
- 云原生基金会(CNCF) 对云原生的定义是 (V1.0)
- 云原生技术有利于各组织在公有云、私有云和混合云等新型动态环境中,构建和运行可弹性扩展的应用云原生的代表技术包括容器、服务网格、微服务、不可变基础设施和声明式API。
- 这些技术能够构建容错性好、易于管理和便于观察的松耦合系统。结合可靠的自动化手段,云原生技术使工程师能够轻松地对系统作出频繁和可预测的重大变更。
云原生基金会(CNCF)全称是: Cloud Native Computing Foundation,由Google、华为等多家企业联合创建于2015年7月21日。华为云是云原生基金会(CNCF)的亚洲唯一创始会员,国内唯一白金会员。
云原生2.0
企业新生能力基于云原生构建,使其生于云:应用、数据和AI的全生命周期云上完成,使其长于云:同时既有能力通过立而不破的方式继承下来,并与新生能力有机协同。
华为云云原生2.0架构全景
什么是容器技术?
- 容器技术起源于Linux,是一种内核虚拟化技术,提供轻量级的虚拟化,以便隔离进程和资源。尽管容器技术已经出现很久,却是随着Docker的出现而变得广为人知。
- Docker诞生于2013年,设计思想来源于集装箱,将软件的交付向集装箱运输一样标准化,同时各个“集装箱”中的软件独立运行,互不影响:一经推出便迅速获得了业界的热捧,统一了纷乱的云计算PaaS的技术,垄断了容器市场:2015年由Docker主导的容器技术标准组织OCI成立,确立了业界公认的容器引擎技术的标准。
Docker的技术优势
- 统一的交付标准可以屏蔽环境差异,使能DevOps
- 更小的资源消耗,提高资源利用率,匹配微服务架构
- 极速的弹性伸缩、故障恢复解放运维生产力
关键技术介绍
Docker的几项关键技术
- Namespace: 将内核的全局资源进行封装,使得每个Namespace都有一份独立的资源。因此不同进程在各自namespace内对同一种资源的使用不会相互干扰。
- Cgroup:限制一个进程组对系统资源的使用上限,包括CPU、内存、Block /0等,实现容器运行的资源隔离,避免容器间资源抢占和冲突。
- Union Filesystem:一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来叠加,是容器镜像的基础。
Docker容器主要概念:
- 镜像:Docker镜像里包含了已打包的应用程序及其所依赖的环境
- 镜像仓库:用于存放Docker镜像的仓库
- 容器: 容器是从镜像创建的运行实例,可以被启动、停止和删除。一个0容器镜像可以构建多个容器
Kata Containers介绍
- Kata-container通过轻量型虚拟机技术构建一个安全的容器运行时,表现像容器一样,但通硬件虚拟化技术提供强隔离作为第二层的安全防护。
- Kata Containers runtime(kata-runtime)通过QEMU/KVM技术创建了一种轻量型的虚拟机,兼容OCI runtimespecification 标准,支持Kubernetes Container Runtime lnterface(CR))接口,可替换CRI shim runtime (runc)通过k8s来创建pod或容器
特点
- 安全:独立的内核,提供网络、I/O.内存的隔离。
- 兼容性:支持OCI容器标准,k8s的CRI接口。
- 性能:兼容虚拟机的安全和容器的轻量特点。
- 简单:使用标准的接口。
Docker容器介绍及操作
Docker是一个轻量级虚拟化解决方案
安装
需要选择安装的 Docker 版本。当前有两个版本可供选择:社区版(Community Edition,CE)和企业版(Enterprise Edition,EE)。
Docker CE 是免费的,并且是接下来示例中将要使用的版本。
Docker EE 包含 Docker CE 中的全部功能,还包括了商业支持以及与其他 Docker 产品的集成,比如 Docker 可信镜像库和通用控制面板。
Docker 需要安装在64位的平台,并且内核版本不低于3.10。使用命令
uname -r
查看内核版本;yum update
更新内核版本。
1 配置Docker的yum源
[root@localhost ~]# cd /etc/yum.repos.d/
[root@localhost yum.repos.d]# yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
已加载插件:fastestmirror, langpacks
adding repo from: http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
grabbing file http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo to /etc/yum.repos.d/docker-ce.repo
repo saved to /etc/yum.repos.d/docker-ce.repo
[root@localhost yum.repos.d]# ls
CentOS-Base.repo CentOS-Debuginfo.repo CentOS-Media.repo CentOS-Vault.repo
CentOS-CR.repo CentOS-fasttrack.repo CentOS-Sources.repo docker-ce.repo
2 查看 Docker 版本列表
[root@localhost ~]# yum list docker-ce --showduplicates | sort -r
3 安装 Docker 指定版本
[root@localhost ~]# yum -y install docker-ce
4 启动并查看 IP 地址
[root@localhost ~]# systemctl start docker
[root@localhost ~]# systemctl enable docker
注意这里的虚拟网桥docker0
,如果打开多个容器,每个容器都会有自己的IP地址。Docker会为每个容器分配一个唯一的IP地址,并将其添加到一个虚拟网桥(如docker0)中。这些IP地址通常是在私有IP地址范围内,如172.17.x.x。
这些IP地址是动态分配的,由Docker自动管理。
[root@localhost ~]# ifconfig
br0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.27.145 netmask 255.255.255.0 broadcast 192.168.27.255
inet6 fe80::20c:29ff:fe8b:d38c prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:8b:d3:8c txqueuelen 1000 (Ethernet)
RX packets 69723 bytes 116051066 (110.6 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 47820 bytes 2783981 (2.6 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
ether 02:42:9c:5b:fd:df txqueuelen 0 (Ethernet)
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
5 配置阿里云镜像加速
镜像加速,其实就是将镜像的下载地址指向国内
编辑文件/etc/docker/daemon.json
,没有就新建
[root@localhost ~]# vim /etc/docker/daemon.json
[root@localhost ~]# cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://registry.docker-cn.com","http://hub-mirror.c.163.com"]
}
重启没有报错,即修改成功
[root@localhost ~]# systemctl restart docker
Docker 使用
1 镜像搜索
docker search 镜像名
[root@localhost ~]# docker search centos7
2 下拉镜像
从 Docker 镜像仓库(这里是 daocloud.io)中拉取一个名为 centos 的镜像,版本为 7。Docker 镜像是一个轻量级的独立软件包,包含了运行一个特定应用或操作系统的所有文件和依赖。使用 docker pull 命令可以将镜像下载到本地的 Docker 主机上,以供后续使用。
daocloud.io 的地址在:https://hub.daocloud.io/repos/bf207788-d7de-4044-bdeb-521a998f748b
daocloud.io/centos:7 是镜像的完整名称,daocloud.io 是镜像仓库的地址,centos 是镜像的名称,7 是镜像的版本号。
[root@localhost ~]# docker pull daocloud.io/centos:7
7: Pulling from centos
75f829a71a1c: Pull complete
Digest: sha256:fe2347002c630d5d61bf2f28f21246ad1c21cc6fd343e70b4cf1e5102f8711a9
Status: Downloaded newer image for daocloud.io/centos:7
daocloud.io/centos:7
3 查询本地镜像
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
daocloud.io/centos 7 7e6257c9f8d8 2 years ago 203MB
4 创建容器,默认未运行
[root@localhost ~]# docker create -it daocloud.io/centos:7 /bin/bash
acb2597bde1a8f6d8992bb789b14b655e2722374a006c2f67cf8bccfa09dec94
-it daocloud.io/centos:7
-i 让容器的输入保持打开
-t 让Docker分配一个伪终端
5 查看容器
查询运行的容器
[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
acb2597bde1a daocloud.io/centos:7 "/bin/bash" About a minute ago Created sharp_cannon
6 运行容器
docker start CONTAINER ID / ID 前几位数 / NAMES
[root@localhost ~]# docker start acb2597bde1a
acb2597bde1a
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
acb2597bde1a daocloud.io/centos:7 "/bin/bash" 3 minutes ago Up 22 seconds sharp_cannon
7 进入容器
docker exec :在运行的容器中执行命令
在容器 sharp_cannon 中开启一个交互模式的终端
[root@localhost ~]# docker exec -it sharp_cannon /bin/bash
[root@acb2597bde1a /]# ls
anaconda-post.log bin dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
注意这里的 IP 地址,172.17.0.2
[root@acb2597bde1a /]# yum -y install net-tools
[root@acb2597bde1a /]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.2 netmask 255.255.0.0 broadcast 172.17.255.255
ether 02:42:ac:11:00:02 txqueuelen 0 (Ethernet)
RX packets 15012 bytes 30480322 (29.0 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 10404 bytes 565093 (551.8 KiB)
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
测试下载 apache ,然后访问它
[root@acb2597bde1a /]# yum -y install httpd
[root@acb2597bde1a conf]# apachectl
8 退出容器
[root@acb2597bde1a conf]# exit
exit
注意,这里我已经退出容器,但查询状态仍然在运行状态。这是因为在进入容器时使用命令docker exec -it sharp_cannon /bin/bash
,进入后相当于有两个终端在容器中,退出后容器中任然有程序在运行,所以容器任然存在。
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
acb2597bde1a daocloud.io/centos:7 "/bin/bash" 15 minutes ago Up 12 minutes sharp_cannon
重新附着到该容器的会话上
docker attach 容器ID/容器名
进入容器
[root@localhost ~]# docker attach acb2
[root@acb2597bde1a /]# netstat -anpt | grep 80
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 113/httpd
退出后查看状态,容器已经退出
[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
acb2597bde1a daocloud.io/centos:7 "/bin/bash" 17 minutes ago Exited (0) 13 seconds ago sharp_cannon
说明:容器必须要有运行的程序,否则不能够存活
9 创建、启动、进入
docker run -it --name nginx01 镜像ID /bin/bash
创建 mycentos01 的容器,并启动进入容器
[root@localhost ~]# docker run -it --name mycentos01 daocloud.io/centos:7 /bin/bash
查看 IP 地址,之前的 IP 地址为172.17.0.2
,现在 DOCKER 自动分配的 IP 为172.17.0.3
[root@6be47176ab34 /]# yum -y install net-tools
[root@6be47176ab34 /]# 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 8 bytes 656 (656.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
同样下载 apache 查看网页
[root@6be47176ab34 /]# yum -y install httpd
[root@6be47176ab34 /]# apachectl
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.3. Set the 'ServerName' directive globally to suppress this message
[root@6be47176ab34 /]# netstat -anpt | grep 80
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 33/httpd
[root@6be47176ab34 /]# echo "test 11111111" >> /var/www/html/index.html
10 停止、删除容器
停止容器
docker stop
查看正在运行的容器
docker ps -q
停止全部容器
docker stop `docker ps -q`
删除已经停止的容器
docker rm 容器名/ID
删除正在运行的容器
docker rm -f 容器名/ID
批量删除
docker rm $(docker ps -aq)
删除镜像
docker rmi 镜像名
11 总结常用的docker命令
docker ps:列出运行中的容器
docker ps -a :列出所有的容器
docker stop 容器id:停止容器
docker kill 容器id:强制停止容器
docker start 容器id:启动已停止的容器
docker inspect 容器id:查看容器的所有信息
docker container logs 容器id:查看容器日志
docker top 容器id:查看容器里的进程
docker exec -it 容器id /bin/bash:进入容器
exit:退出容器
docker rm 容器id:删除已停止的容器
docker rm -f 容器id:删除正在运行的容器
案例:使用 nginx
[root@localhost ~]# docker pull daocloud.io/nginx
Using default tag: latest
latest: Pulling from nginx
6f28985ad184: Pull complete
29f7ebf60efd: Pull complete
879a7c160ac6: Pull complete
de58cd48a671: Pull complete
be704f37b5f4: Pull complete
158aac73782c: Pull complete
Digest: sha256:48d56bae87c65ca642b0a1d13c3dc97c4430994991e5531ff123f77cdf975fae
Status: Downloaded newer image for daocloud.io/nginx:latest
daocloud.io/nginx:latest
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
daocloud.io/nginx latest 6084105296a9 2 years ago 133MB
daocloud.io/centos 7 7e6257c9f8d8 2 years ago 203MB
[root@localhost ~]# docker run -it --name nginx01 daocloud.io/nginx
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
只是一个程序,没有操作系统,但是有 IP 地址等,这里相当于前台启动
注意这个 IP,之前我关掉了 mycentos01 容器,nginx01 启动后自动分配了03的 IP
如果你想要有交互式的操作,可以使用以下命令:
docker run -it --name nginx01 daocloud.io/nginx /bin/bash
Docker 的数据及网络
Docker 数据卷
Docker 数据卷是用于在 Docker 容器和主机之间共享数据的一种机制。它允许你在容器中持久化存储数据,并且在容器重启或迁移时保持数据的一致性。
数据卷是一个供容器使用的目录,位于容器中;
可以在容器之间挂载;也可以将宿主机中的目录挂载到数据卷上,实现数据的迁移;对数据的操作立即可见。
1 数据卷基本操作
可以使用docker volume create
命令来创建一个数据卷
[root@localhost ~]# docker volume create my-vol
my-vol
使用命令docker volume ls
查看所有的数据卷
[root@localhost ~]# docker volume ls
DRIVER VOLUME NAME
local my-vol
使用命令docker volume inspect
查看指定数据卷详细信息
[root@localhost ~]# docker volume inspect my-vol
[
{
"CreatedAt": "2023-07-22T16:34:37+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/my-vol/_data",
"Name": "my-vol",
"Options": null,
"Scope": "local"
}
]
挂载数据卷:在运行容器时,使用 -v 或 --mount 选项将数据卷挂载到容器中
[root@localhost ~]# docker run -v my_vol:/usr/share/nginx/html daocloud.io/centos:7
删除数据卷
[root@localhost ~]# docker volume rm my-vol
my-vol
2 数据卷进阶+示例
①使用 centos7
使用 run 命令创建容器,并将/testdata
目录挂载到容器的/data
目录中
docker run -it --name centos7-1 -v /testdata:/data 7e6 /bin/bash
容器创建完成后,/data
目录不存在内容
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
daocloud.io/nginx latest 6084105296a9 2 years ago 133MB
daocloud.io/centos 7 7e6257c9f8d8 2 years ago 203MB
[root@localhost ~]# docker run -it --name centos7-1 -v /testdata:/data 7e6 /bin/bash
[root@380b02ea26c7 /]# cd /data
[root@380b02ea26c7 data]# ls
退出容器到/testdata
目录中创建文件
[root@localhost ~]# cd /testdata/
[root@localhost testdata]# echo "test123412341234" >> index.html
[root@localhost testdata]# ls
index.html
进入到容器中可以看到刚才创建的文件已经在容器中生成
[root@380b02ea26c7 data]# ls
index.html
[root@380b02ea26c7 data]# cat index.html
test123412341234
②使用 nginx
同样的道理,将/mynginx
目录挂载到容器中
docker run -it --name nginx-1 -d -v /mynginx:/usr/share/nginx/html daocloud.io/nginx
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
daocloud.io/nginx latest 6084105296a9 2 years ago 133MB
daocloud.io/centos 7 7e6257c9f8d8 2 years ago 203MB
[root@localhost ~]# docker run -it --name nginx-1 -d -v /mynginx:/usr/share/nginx/html daocloud.io/nginx
904ad4aa7e8f143edb312e7a6c8c5d093324aa6b8c4124dc36394dd69174b35b
[root@localhost ~]#
[root@localhost ~]# cd /mynginx/
[root@localhost mynginx]# ls
[root@localhost mynginx]# vim test.html
[root@localhost mynginx]# cat test.html
sdfasdfasdf
③理解数据卷容器
容器中有数据卷,那么它就是数据卷容器,Docker数据卷是用于在Docker容器和主机之间共享数据的一种机制
通过数据卷挂载之后,无论创建多少个容器,使用--volume-from
命令,只需要修改真机中/mynginx
目录就可以修改每个容器中/usr/share/nginx/html
目录了
使用命令创建容器
docker run -it --volumes-from nginx-1 --name nginx-2 daocloud.io/nginx /bin/bash
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
daocloud.io/nginx latest 6084105296a9 2 years ago 133MB
daocloud.io/centos 7 7e6257c9f8d8 2 years ago 203MB
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
904ad4aa7e8f daocloud.io/nginx "/docker-entrypoint.…" 44 minutes ago Up 44 minutes 80/tcp nginx-1
380b02ea26c7 7e6 "/bin/bash" 3 hours ago Up 3 hours centos7-1
[root@localhost ~]# docker run -it --volumes-from nginx-1 --name nginx-2 daocloud.io/nginx /bin/bash
root@bbbaad600f1c:/# cd /usr/share/nginx/html/
root@bbbaad600f1c:/usr/share/nginx/html# ls
test.html
root@bbbaad600f1c:/usr/share/nginx/html# cat test.html
sdfasdfasdf
root@bbbaad600f1c:/usr/share/nginx/html#
在容器 nginx-2 中可以看到之前创建的内容 test.html
Docker 网络
1 端口映射
通过端口映射使外网通过访问宿主机的端口访问容器中的服务,其底层仍然是 iptables 的 SNAT 和 DNAT
使用 -P 可以实现随机端口映射,范围 49000~49900
docker run -d -P nginx-4:centos7
使用 -p 指定端口的映射
docker run -d -it --name nginx-3 -p 8081:80 daocloud.io/nginx
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
904ad4aa7e8f daocloud.io/nginx "/docker-entrypoint.…" About an hour ago Up About an hour 80/tcp nginx-1
380b02ea26c7 7e6 "/bin/bash" 3 hours ago Up 3 hours centos7-1
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
daocloud.io/nginx latest 6084105296a9 2 years ago 133MB
daocloud.io/centos 7 7e6257c9f8d8 2 years ago 203MB
[root@localhost ~]# docker run -d -it --name nginx-3 -p 8081:80 daocloud.io/nginx
897dc848d366a60e2a8bcd33f9ee95e796d6e47dffbb5ed07d05b85fb3c69d59
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
897dc848d366 daocloud.io/nginx "/docker-entrypoint.…" 13 minutes ago Up 13 minutes 0.0.0.0:8081->80/tcp, :::8081->80/tcp nginx-3
904ad4aa7e8f daocloud.io/nginx "/docker-entrypoint.…" About an hour ago Up About an hour 80/tcp nginx-1
380b02ea26c7 7e6 "/bin/bash" 3 hours ago Up 3 hours centos7-1
2 容器互联与操作
容器互联是通过容器的名称在容器间建立一条专门的网络通信隧道实现互联
docker run 建立容器 A ,使用 --name 指定容器名称
docker run -d -P --name web1 apache6:centos7
docker run 建立容器 B,使用 --name 指定名称,–link 容器名称:连接别名,以实现容器互联
docker run -d -P -name web2 -link web1:web1 apache6:centos7
Docker镜像管理
1 镜像基础操作
搜寻
docker search 关键字
获取
docker pull 仓库名称:标签
查看
docker 仓库名称:标签
导出/存出
docker save -o nginx.tar daocloud.io/nginx
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
myhttpd 03 f8e304bb6087 47 minutes ago 986MB
daocloud.io/nginx latest 6084105296a9 2 years ago 133MB
daocloud.io/centos 7 7e6257c9f8d8 2 years ago 203MB
[root@localhost ~]# docker save -o nginx.tar daocloud.io/nginx
[root@localhost ~]# ll
总用量 220504
-rw-------. 1 root root 137351168 7月 24 15:06 nginx.tar
导入/载入
docker load < nginx.tar
或
docker --input nginx.tar
[root@localhost ~]# docker load < nginx.tar
Loaded image: daocloud.io/nginx:latest
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
myhttpd 03 f8e304bb6087 49 minutes ago 986MB
daocloud.io/nginx latest 6084105296a9 2 years ago 133MB
daocloud.io/centos 7 7e6257c9f8d8 2 years ago 203MB
新增名称
docker tag 名称:标签 新名称:新标签
[root@localhost ~]# docker tag myhttpd:03 myhttpd:01
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
myhttpd 01 f8e304bb6087 50 minutes ago 986MB
myhttpd 03 f8e304bb6087 50 minutes ago 986MB
daocloud.io/nginx latest 6084105296a9 2 years ago 133MB
daocloud.io/centos 7 7e6257c9f8d8 2 years ago 203MB
上传
docker push daocloud.io/nginx
docker push zhangsan/centos:7
2 镜像的创建方法
- Docker镜像
- 应用发布的标准格式
- 支撑一个Docker容器的运行
- Docker镜像的创建方法
- 基于已有镜像创建
- 基于本地模板创建
- 基于Dockerfile创建
①基于已有镜像创建
将容器里面运行的程序及运行环境打包生成新的镜像
docker commit [选项] 容器ID/名称 仓库名称:[标签]
-m 说明信息
-a 作者信息
-p 生成过程中停止容器的运行
创建一个容器,并在容器中安装 apache
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
daocloud.io/centos 7 7e6257c9f8d8 2 years ago 203MB
[root@localhost ~]# docker run -it --name mycentos01 daocloud.io/centos:7 /bin/bash
[root@6cb659967c6d /]# yum -y install httpd
···
[root@6cb659967c6d /]# vi /var/www/html/index.html
my test web
[root@6cb659967c6d /]# exit
基于容器创建镜像
[root@localhost ~]# docker commit -m "my centos httpd" -a "lisa" -p mycentos01 mydocker:web01
sha256:bdbfad1bebabacac6e2de5f9677878706e21564d70d3ead9557b15bb252c0be9
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mydocker web01 bdbfad1bebab 5 seconds ago 449MB
daocloud.io/centos 7 7e6257c9f8d8 2 years ago 203MB
测试:基于刚才创建的镜像创建一个容器
[root@localhost ~]# docker run -it --name my-1 bdbfad1bebab /bin/bash
[root@72cfc51045c9 /]# apachectl
②基于本地模板创建
从OPENVZ开源项目下载模板,导入操作系统模板文件生成镜像
wget http://download.openvz.org/template/precreated/debian-7.0-x86-minimal.tar.gz
debian-7.0-x86-minimal.tar.gz
导入成功后可查看本地镜像信息
docker images | grep new
③基于 Dockerfile 创建
-
Docker镜像的分层
- Dockerfile中的每个指令都会创建一个新的镜像层
- 镜像层将被缓存和复用
- 当Dockerfile的指令修改了,复制的文件变化了,或者构建镜像时指定的变量不同了对应的镜像层缓存就会失效
- 某一层的镜像缓存失效之后,它之后的镜像层缓存都会失效
- 镜像层是不可变的,如果在某一层中添加一个文件,然后在下一层中删除它,则镜像中依然会包含该文件
-
Dockerfile操作指令
Dockfile是一种被Docker程序解释的脚本,Dockerfile由一条一条的指令组成,每条指令对应Linux下面的一条命令- FROM 镜像:指定新的镜像所基于的镜像
- MAINTAINER 名字:说明新镜像的维护人
- RUN 命令:在所基于的镜像上执行命令,并提交到新的镜像中
- CMD [ “要运行的程序”,“参数1”,“参数2”]:指定启动容器时要运行命令或者脚本;只能有一条CMD命令
- ENTRYPOINT 指令的目的也是为容器指定默认执行的任务
差异1:CMD指令指定的容器启动时命令可以被docker run指定的命令覆盖,而ENTRYPOINT指令指定的命令不能被覆盖,而是将docker run指定的参数当做ENTRYPOINT指定命令的参数。
差异2:CMD指令可以为ENTRYPOINT指令设置默认参数,而且可以被docker run指定的参数覆盖; - EXPOSE 端口号:指定新镜像加载到Docker时要开启的端口
- ENV 环境变量 环境变量值:设置一个环境变量值,会被后边的RUN使用
- ADD 源文件/目录 目标文件/目录:将源文件复制到目标文件,源文件要与Dockerfile在同一文 件目录中,目标文件存在则不覆盖
- COPY源文件/目录 目标文件/目录:将本地主机上的文件/目录复制到目标地点,源文件要与Dockerfile在同一文件目录中,目标文件存在则覆盖
- VOLUME [ “目录” ] :在容器中创建一个挂载点用
- USER 用户名/uid:指定运行容器时的用户
- WORKDIR 路径:为后续的RUN、CMD、ENTRYPOINT指定工作目录
- ONBUILD 命令:指定所生成的镜像作为一个基础镜像时所要运行的命令
案例:创建自定义 httpd 镜像
创建工作目录
[root@localhost ~]# mkdir apache
[root@localhost ~]# cd apache/
创建并编写 Dockerfile 文件
[root@localhost apache]# vim Dockerfile
# 基于的基础镜像
FROM daocloud.io/centos:7
# 维护该镜像的用户信息
MAINTAINER lisa
# 镜像操作指令安装 apache 软件包
RUN yum -y install httpd
# 开放 80 端口
EXPOSE 80
# 复制网站首页文件
ADD index.html /var/www/html/index.html
# 将执行脚本复制到镜像中
ADD run.sh /run.sh
RUN chmod 775 /run.sh
# 启动容器时执行脚本
CMD ["/run.sh"]
编写执行脚本内容
-D FOREGROUND 该进程将在前台运行而不是从shell中分离
-D FOREGROUND
选项确实意味着Apache不会fork,但这并不意味着它附加到你的shell!-D FOREGROUND选项确实意味着Apache不会fork,但这并不意味着它附加到你的shell!
Docker的设计理念是在容器里面不运行后台服务,容器本身就是宿主机上的一个独立的主进程,也可以间接的理解为就是容器里运行服务的应用进程。一个容器的生命周期是围绕这个主进程存在的,所以正确的使用容器方法是将里面的服务运行在前台。
再说到systemd,这个套件已经成为主流Linux发行版(比如CentOS7、Ubuntu14+)默认的服务管理,取代了传统的SystemV风格服务管理。systemd维护系统服务程序,它需要特权去会访问Linux内核。而容器并不是一个完整的操作系统,只有一个文件系统,而且默认启动只是普通用户这样的权限访问Linux内核,也就是没有特权,所以自然就用不了
[root@localhost apache]# vim run.sh
#!/bin/bash
/usr/sbin/apachectl -D FOREGROUND
/bin/bash
创建测试页面
[root@localhost apache]# echo "my test web" > index.html
[root@localhost apache]# ls
Dockerfile index.html run.sh
使用 Dockerfile 生成镜像
编写完 Dockerfile 以及相关内容后,可以通过 docker build 命令来创建镜像
命令格式:docker build [选项] 路径
-t 指定镜像的标签信息
[root@localhost apache]# docker build -t myhttpd-1 .
[+] Building 55.4s (10/10) FINISHED docker:default
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 300B 0.0s
=> [internal] load metadata for daocloud.io/centos:7 0.0s
=> CACHED [1/5] FROM daocloud.io/centos:7 0.0s
=> [internal] load build context 0.0s
=> => transferring context: 176B 0.0s
=> [2/5] RUN yum -y install httpd 52.3s
=> [3/5] ADD index.html /var/www/html/index.html 0.1s
=> [4/5] ADD run.sh /run.sh 0.1s
=> [5/5] RUN chmod 775 /run.sh 0.6s
=> exporting to image 2.1s
=> => exporting layers 2.1s
=> => writing image sha256:0b779fd6a23428691bbea65b20e83019cb84f8f658c039e6347a93572cd3b9f2 0.0s
=> => naming to docker.io/library/myhttpd-1 0.0s
使用新的镜像运行容器
使用 -p 选项实现从本地端口43980映射到容器中80端口
[root@localhost apache]# docker run -d -p 43980:80 myhttpd-1
d2f9d723f987634f6da200a4322b4cd16d91ed5dd9c27e9aae577460d196139a
[root@localhost apache]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d2f9d723f987 myhttpd-1 "/run.sh" 40 seconds ago Up 39 seconds 0.0.0.0:43980->80/tcp, :::43980->80/tcp magical_dirac
构建 Docker 镜像实战
构建 Tomcat 镜像
1 创建工作目录
[root@localhost ~]# mkdir tomcat
[root@localhost ~]# cd tomcat/
2 创建 Dockerfile 文件
[root@localhost tomcat]# vim Dockerfile
FROM daocloud.io/centos:7
MAINTAINER LISA
RUN yum -y install net-tools
COPY jdk-8u91-linux-x64.tar.gz /root
WORKDIR /root
RUN tar -zxf jdk-8u91-linux-x64.tar.gz
RUN mv jdk1.8.0_91 /usr/local/java
ENV JAVA_HOME=/usr/local/java
ENV CLASSPATH=$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar
ENV PATH=$JAVA_HOME/bin:$PATH
COPY apache-tomcat-8.5.55.tar.gz /root
RUN tar -zxf apache-tomcat-8.5.55.tar.gz
RUN mv apache-tomcat-8.5.55 /usr/local/tomcat
EXPOSE 8080
COPY run.sh /run.sh
RUN chmod 755 /run.sh
CMD ["/run.sh"]
[root@localhost tomcat]# vim run.sh
#!/bin/bash
/usr/local/tomcat/bin/startup.sh
/bin/bash
3 生成镜像
[root@localhost tomcat]# docker build -t tomcat:01 .
[+] Building 56.1s (16/16) FINISHED docker:default
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 934B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for daocloud.io/centos:7 0.0s
=> CACHED [ 1/11] FROM daocloud.io/centos:7 0.0s
=> [internal] load build context 0.0s
=> => transferring context: 303B 0.0s
=> [ 2/11] RUN yum -y install net-tools 22.8s
=> [ 3/11] COPY jdk-8u91-linux-x64.tar.gz /root 5.6s
=> [ 4/11] WORKDIR /root 0.1s
=> [ 5/11] RUN tar -zxf jdk-8u91-linux-x64.tar.gz 11.9s
=> [ 6/11] RUN mv jdk1.8.0_91 /usr/local/java 5.6s
=> [ 7/11] COPY apache-tomcat-8.5.55.tar.gz /root 0.1s
=> [ 8/11] RUN tar -zxf apache-tomcat-8.5.55.tar.gz 1.2s
=> [ 9/11] RUN mv apache-tomcat-8.5.55 /usr/local/tomcat 1.4s
=> [10/11] COPY run.sh /run.sh 0.1s
=> [11/11] RUN chmod 755 /run.sh 0.5s
=> exporting to image 6.7s
=> => exporting layers 6.7s
=> => writing image sha256:096112d5a9fad6522580b53d15cf5ba835c00db062381df41ee63aa0afeff206 0.0s
=> => naming to docker.io/library/tomcat:01 0.0s
4 运行容器并验证
[root@localhost tomcat]# docker run -dit --name mytomcat-1 -p 80:8080 tomcat:01
bf0c77294ac5948e000551c8c2b0058132521ed8559d867a762205b02c6d47e1
[root@localhost tomcat]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bf0c77294ac5 tomcat:01 "/run.sh" 6 seconds ago Up 5 seconds 0.0.0.0:80->8080/tcp, :::80->8080/tcp mytomcat-1
构建 Nginx 镜像
1 下载基础镜像
创建 nginx 镜像的基础镜像:centos 镜像
[root@localhost ~]# docker pull daocloud.io/centos:7
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
daocloud.io/centos 7 7e6257c9f8d8 2 years ago 203MB
2 建立工作目录
[root@localhost ~]# mkdir nginx
[root@localhost ~]# cd nginx/
这里上传源码包
[root@localhost nginx]# ls
nginx-1.12.0.tar.gz
3 编写 Dockerfile 文件
[root@localhost nginx]# vim Dockerfile
FROM daocloud.io/centos:7
MAINTAINER my test nginx
RUN yum -y install proc-devel net-tools gcc zlib zlib-devel make openssl-devel
COPY nginx-1.12.0.tar.gz /root
WORKDIR /root
RUN tar zxf nginx-1.12.0.tar.gz
WORKDIR nginx-1.12.0
RUN ./configure --prefix=/usr/local/nginx
RUN make
RUN make install
EXPOSE 80
EXPOSE 443
RUN echo "daemon off;" >> /usr/local/nginx/conf/nginx.conf
WORKDIR /root/nginx
COPY run.sh /run.sh
RUN chmod 755 /run.sh
CMD ["/run.sh"]
4 编写执行脚本内容
[root@localhost nginx]# vim run.sh
#!/bin/bash
/usr/local/nginx/sbin/nginx
/bin/bash
5 生成镜像
[root@localhost nginx]# docker build -t nginx:01 .
[root@localhost nginx]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx 01 75aabfe6fcd5 2 minutes ago 521MB
daocloud.io/centos 7 7e6257c9f8d8 2 years ago 203MB
6 启动容器进行测试
[root@localhost nginx]# docker run -d -P nginx:01
b085b79e1a8f6f7b66317504f210890f71a0cdc443005fd861bbd9d2e6992f77
[root@localhost nginx]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b085b79e1a8f nginx:01 "/run.sh" 4 seconds ago Up 2 seconds 0.0.0.0:32769->80/tcp, :::32769->80/tcp, 0.0.0.0:32768->443/tcp, :::32768->443/tcp blissful_wright
构建 Mysql 镜像
1 创建工作目录
[root@localhost ~]# mkdir mysql
[root@localhost ~]# cd mysql/
2 创建 Dockerfile 文件
[root@localhost mysql]# vim Dockerfile
FROM daocloud.io/centos:7
MAINTAINER LISA
COPY cmake-2.8.6.tar.gz /root
WORKDIR /root
RUN yum -y install ncurses-devel gcc-c++ perl-Module-Install net-tools
RUN tar -zxf cmake-2.8.6.tar.gz -C /usr/local/
WORKDIR /usr/local/cmake-2.8.6/
RUN ./configure
RUN gmake && gmake install
COPY mysql-5.6.36.tar.gz /root
WORKDIR /root
RUN tar -zxf mysql-5.6.36.tar.gz -C /usr/local/
WORKDIR /usr/local/mysql-5.6.36/
RUN cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci -DWITH_EXTRA_CHARSETS=all -DSYSCONFDIR=/etc
RUN make && make install
RUN cp /usr/local/mysql-5.6.36/support-files/my-default.cnf /etc/my.cnf
RUN cp /usr/local/mysql-5.6.36/support-files/mysql.server /etc/rc.d/init.d/mysqld
RUN chmod +x /etc/rc.d/init.d/mysqld
ENV PATH=$PATH:/usr/local/mysql/bin
RUN groupadd mysql
RUN useradd -M -s /sbin/nologin mysql -g mysql
RUN chown -R mysql:mysql /usr/local/mysql
RUN /usr/local/mysql/scripts/mysql_install_db --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data --user=mysql
EXPOSE 3306
RUN /etc/rc.d/init.d/mysqld start && /usr/local/mysql/bin/mysqladmin -u root password 123456 && /usr/local/mysql/bin/mysql -uroot -p123456 -e "grant all privileges on *.* to 'root'@'%' identified by '123456';" && /usr/local/mysql/bin/mysql -uroot -p123456 -e "grant all privileges on *.* to 'root'@'localhost' identified by '123456';"
ENTRYPOINT ["mysqld_safe"]
[root@localhost mysql]# ls
cmake-2.8.6.tar.gz Dockerfile mysql-5.6.36.tar.gz run.sh
3 生成镜像
docker build -t mysql:01 .
4 运行容器并验证
使用镜像运行容器,并随机映射本地的端口到容器的 3306 端口
[root@localhost mysql]# docker run -d -P mysql:01
aeba4a7e7c13cb022783a3b2135def367cca6d0634662446179742bdc9f5bfc3
[root@localhost mysql]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
aeba4a7e7c13 mysql:01 "mysqld_safe" 3 seconds ago Up 2 seconds 0.0.0.0:32773->3306/tcp, :::32773->3306/tcp distracted_mendeleev
从本机登录 MySQL 数据库进行验证
[root@localhost ~]# yum -y install mysql
[root@localhost ~]# mysql -uroot -h 192.168.27.195 -P 32773 -p123456
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.6.36 Source distribution
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
+--------------------+
4 rows in set (0.00 sec)
构建 PHP 镜像
1 创建工作目录
[root@192 ~]# mkdir php
[root@192 ~]# cd php
2 创建 Dockerfile 文件
[root@192 php]# vim Dockerfile
FROM daocloud.io/centos:7
MAINTAINER LISA
RUN yum -y install gd \
libjpeg libjpeg-devel \
libpng libpng-devel \
freetype freetype-devel \
libxml2 libxml2-devel \
zlib zlib-devel \
curl curl-devel \
openssl openssl-devel \
gcc gcc-c++ make pcre-devel
RUN useradd -M -s /sbin/nologin nginx
COPY php-5.5.24.tar.gz /root
WORKDIR /root
RUN tar -zxf php-5.5.24.tar.gz
WORKDIR /root/php-5.5.24
RUN ./configure \
--prefix=/usr/local/php \
--with-mysql-sock=/tmp/mysql.sock \
--with-mysqli \
--with-zlib \
--with-curl \
--with-gd \
--with-jpeg-dir \
--with-png-dir \
--with-freetype-dir \
--with-openssl \
--enable-fpm \
--enable-mbstring \
--enable-xml \
--enable-session \
--enable-ftp \
--enable-pdo \
--enable-tokenizer \
--enable-zip && make && make install
RUN cp /root/php-5.5.24/php.ini-development /usr/local/php/php.ini && sed -i 's#mysqli.default_socket =#mysqli.default_socket = /tmp/mysql.sock#' /usr/local/php/php.ini && sed -i '939 s#;date.timezone =#date.timezone = Asia/Shanghai#' /usr/local/php/php.ini
RUN ln -s /usr/local/php/bin/* /usr/local/bin/
RUN ln -s /usr/local/php/sbin/* /usr/local/sbin/
RUN cp /usr/local/php/etc/php-fpm.conf.default /usr/local/php/etc/php-fpm.conf && sed -i '17 s/^;//' /usr/local/php/etc/php-fpm.conf
COPY zend-loader-php5.5-linux-x86_64_update1.tar.gz /root
WORKDIR /root
RUN tar -zxf zend-loader-php5.5-linux-x86_64_update1.tar.gz
WORKDIR /root/zend-loader-php5.5-linux-x86_64
RUN cp ZendGuardLoader.so /usr/local/php/lib/php/
RUN sed -i "2a zend_extension=/usr/local/php/lib/php/ZendGuardLoader.so" /usr/local/php/php.ini
RUN sed -i "2a zend_loader.enable=1" /usr/local/php/php.ini
WORKDIR /root
EXPOSE 9000
ENTRYPOINT [ "/usr/local/php/sbin/php-fpm", "-F" ]
3 生成镜像
[root@192 php]# ls
Dockerfile php-5.5.24.tar.gz zend-loader-php5.5-linux-x86_64_update1.tar.gz
[root@192 php]# docker build -t php:01 .
···
4 运行容器并验证
[root@192 ~]# docker run -d -P php:01
53053e1cff61b18ee73fea8e93620bb4bb07e43999ffc420ef2d82a020fe6ade
[root@192 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
53053e1cff61 php:01 "/usr/local/php/sbin…" 4 seconds ago Up 2 seconds 0.0.0.0:32771->9000/tcp, :::32771->9000/tcp loving_payne