【狂神说docker笔记】 入门篇(手敲的 网络篇请移步视频)

Docker概述

Docker为什么出现?

一款产品∶

开发–上线两套环境!应用环境,应用配置!
开发—运维。问题︰我在我的电脑上可以运行!版本更新,导致服务不可用!对于运维来说,考验就十分大?环境配置是十分的麻烦,每一个机器都要部署环境(集群Redis、ES、Hadoop…)”!费时费力。
发布一个项目( jar + ( Redis MySQL jdk ES ) ),项目能不能都带上环境安装打包!
之前在服务器配置一个应用的环境(Redis MySQL jdk ES Hadoop),配置超麻烦了,不能够跨平台。Windows,最后发布到Linux !

传统:开发jar,运维来做!

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

java – apk --发布(应用商店)—张三使用apk —安装即可用!

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

Docker的思想就来自于集装箱!
JRE–多个应用(端口冲突) —原来都是交叉的!
隔离:Docker核心思想!打包装箱!每个箱子是互相隔离的。水果生化武器
Docker通过隔离机制,可以将服务器利用到极致!

Docker能干啥

之前的虚拟机技术

img

虚拟机技术的缺点:

1.资源占用太多

2.冗余步骤太多

3.启动很慢

现在的容器化技术

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

img

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

①传统虚拟机,虚拟出一条硬件,运行一个完整的操作系统,然后在这个系统上安装和运行软件

②容器内的应用直接运行在宿主机的内容,容器是没有自己的内核的,也没有虚拟我们的硬件,所以就轻便了

③每个容器间是互相隔离,每个容器内都有一个属于自己的文件系统,互不影响。

应用更快速的交付和部署

传统: 一堆帮助文档,安装程序

Docker: 打包镜像发步测试,一键运行

更便捷的升级和扩缩

容使用了Docker之后,我们部署应用就和搭积木一样!

项目打包为一个镜像,扩展服务器A!服务器B

更简单的系统运维

在容器化之后,我们的开发,测试环境都是高度一致的。更高效的计算资源利用:

Docker是内核级别的虚拟化,可以再一个物理机上可以运行很多的容器实例!服务器的性能可以被压榨到极致。

Docker的名词概念

img

镜像:(image):

docker镜像如同一个模板,可以通过这个模板创建容器服务。

容器:(container)

docker利用容器技术,独立运行一个或一组应用,通过对象创建的

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

目前可将容器理解成一个简易的linux系统

仓库:(repository)

仓库是存放镜像的地方

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

安装docker

#需要的安装包
yum install -y yum-utils
#设置镜像仓库
yum-config-manager \     --add-repo \    http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
#安装docker核心
yum install docker-ce docker-ce-cli containerd.io
#启动docker
systemctl start docker
#运行helloworld
docker run hello-world
#查看hello-world镜像
docker images

img

卸载docker

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

#2、制除资源
rm -rf /var /lib/docker #docker的工作目录

回顾helloworld的流程

img

运行流程图

img

Docker的运行原理

img

Docker为什么比VM快

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

2.docker利用的宿主机的内核,vm是guestOs

img

所以说新建一个容器,docker不需要像虚拟机一样重新加载一个操作系统的内核,虚拟机要加载guestOs,docker利用宿主机的核心省略了这个过程

Docker的常用命令

帮助命令

docker version      #显示docker版本
docker info					#显示docker的信息
docker 命令 --help  #显示docker的帮助文档

镜像命令

docker images

[root@iZwz923fx7de74e5pc1tgoZ ~]	#docker images
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
hello-world   latest    d1165f221234   5 months ago   13.3kB

REPOSITORY:镜像的仓库源
TAG:镜像的标签
IMAGE ID:镜像的id
CREATED:镜像创建时间
SIZE:镜像大小
#可选项

Options:
  -a, --all             列出所有镜像
  -q, --quiet           只显示镜像的id

docker search

[root@iZwz923fx7de74e5pc1tgoZ ~]# docker search mysql
NAME                              DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
mysql                             MySQL is a widely used, open-source relation…   11225     [OK]       
mariadb                           MariaDB Server is a high performing open sou…   4265      [OK]       

#可选项,通过搜索过滤
--filter=STARS=3000   搜索3000以上star的源

docker pull

#下载镜像
[root@iZwz923fx7de74e5pc1tgoZ ~]# docker pull mysql
Using default tag: latest     # 如果不写tag,默认就是latest(最近的)
latest: Pulling from library/mysql
33847f680f63: Pull complete   # 分层下载 docker images的核心  联合文件系统
5cb67864e624: Pull complete 
1a2b594783f5: Pull complete 
b30e406dd925: Pull complete 
48901e306e4c: Pull complete 
603d2b7147fd: Pull complete 
802aa684c1c4: Pull complete 
715d3c143a06: Pull complete 
6978e1b7a511: Pull complete 
f0d78b0ac1be: Pull complete 
35a94d251ed1: Pull complete 
36f75719b1a9: Pull complete  
Digest: sha256:8b928a5117cf5c2238c7a09cd28c2e801ac98f91c3f8203a8938ae51f14700fd #签名
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest #真实地址

# 指定版本下载
docker pull mysql:5.7

img

红框中是刚刚安装latest版本中相同的依赖,docker对其做了处理,让我们不需要重复的下载相同的依赖。

docker rmi

#删除镜像

[root@iZwz923fx7de74e5pc1tgoZ ~]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
mysql         5.7       8cf625070931   2 weeks ago    448MB
mysql         latest    c60d96bd2b77   2 weeks ago    514MB
hello-world   latest    d1165f221234   5 months ago   13.3kB
[root@iZwz923fx7de74e5pc1tgoZ ~]# docker rmi -f c60d96bd2b77 #删除id为c60d96bd2b77的镜像
Untagged: mysql:latest
Untagged: mysql@sha256:8b928a5117cf5c2238c7a09cd28c2e801ac98f91c3f8203a8938ae51f14700fd
Deleted: sha256:c60d96bd2b771a8e3cae776e02e55ae914a6641139d963defeb3c93388f61707
Deleted: sha256:5c8c91273faab368a6d659156f2569fa9f40b0e0139222fdf9eef073df4b3797
Deleted: sha256:33d8196a776f42a16f10395b66f10f91443b1fb194bca2a9b8dfb0deff5babb8
Deleted: sha256:3ec63323025213e3cabf17ac7933506dc5520ec49226a9764418f77ea60d35c8
Deleted: sha256:1f129b005b51b049ac84ed0775b82096d480b7d9308a9a137697f37346562266
Deleted: sha256:80ed209bd0434faa1ce31fbaab8508124dddf8f6502c5736ee4b8e46697a8477
[root@iZwz923fx7de74e5pc1tgoZ ~]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
mysql         5.7       8cf625070931   2 weeks ago    448MB
hello-world   latest    d1165f221234   5 months ago   13.3kB

#递归删除命令
docker rmi -f $(docker images -aq)

容器命令

有了镜像我们才能创建容器,下载一个centos来学习

docker pull centos

新建容器并启动

docker run [可选参数] image

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



[root@iZwz923fx7de74e5pc1tgoZ ~]# docker run -it centos
[root@d11af9403852 /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@d11af9403852 /]# exit
exit 			#退出命令

列出所有运行中的容器

#docker ps命令
			#列出当前正在运行的容器
-a		#列出当前正在运行的容器+带出历史运行过的容器
-n=?	#显示最近创建的容器
-q		#只显示id
[root@iZwz923fx7de74e5pc1tgoZ ~]# docker ps    #查看运行中的容器
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
[root@iZwz923fx7de74e5pc1tgoZ ~]# docker ps -a #查看历史运行中的容器 + 当前正在运行的容器
CONTAINER ID   IMAGE         COMMAND       CREATED             STATUS                          PORTS     NAMES
d11af9403852   centos        "/bin/bash"   2 minutes ago       Exited (0) About a minute ago             vigilant_ardinghelli
9ca3796f40aa   hello-world   "/hello"      About an hour ago   Exited (0) About an hour ago              beautiful_hermann

退出容器

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

删除容器

docker rm 容器id
docker rm -f $(docker ps -aq) 删除所有容器

启动或者停止容器

docker start 容器id #启动容器
docker restart 容器id #重启容器
docker stop 容器id #停止当前正在运行的容器
docker kil 容器id #强制停止当前容器

docker run 和 docker start的区别是前者是第一次启动创建容器并且运行,后者是运行现有的容器

其他的命令

后台启动容器
#后台启动容器
docker run -d centos

#常见的坑: docker容器使用后台运行,就必须要有要一个前台进程,docker发现没有应用,就会自动停止
#nginx,容器启动后,发现自己没有提供服务,就会立刻停止,就是没有程序了
查看日志
docker logs	
#显示日志
-tf  			#显示日志
--tail number#要显示日志条数
[root@kuangshen / ]# docker logs -tf --tai1 10 dce7b86171bf
查看容器中的进程信息
docker top 容器id	

[root@iZwz923fx7de74e5pc1tgoZ ~]# docker top 427d8b6a1e42
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                22129               22110               0                   09:29               pts/0               00:00:00            /bin/bash
查看容器的元数据
[root@iZwz923fx7de74e5pc1tgoZ ~]# docker inspect 8cf625070931
[
    {
        "Id": "sha256:8cf6250709314f2fcd2669e8643f5d3bdebfe715bddb63990c8c96e5d261d6fc",
        "RepoTags": [
            "mysql:5.7"
        ],
        "RepoDigests": [
            "mysql@sha256:be70d18aedc37927293e7947c8de41ae6490ecd4c79df1db40d1b5b5af7d9596"
        ],
        "Parent": "",
        "Comment": "",
        "Created": "2021-07-22T09:46:58.633532241Z",
        "Container": "55c80e6cae67918a0f23a3e89d1fb67567180c0fa14be584f72a634f26018bd3",
        "ContainerConfig": {
            "Hostname": "55c80e6cae67",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "3306/tcp": {},
                "33060/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "GOSU_VERSION=1.12",
                "MYSQL_MAJOR=5.7",
                "MYSQL_VERSION=5.7.35-1debian10"
            ],
            "Cmd": [
                "/bin/sh",
                "-c",
                "#(nop) ",
                "CMD [\"mysqld\"]"
            ],
            "Image": "sha256:db75bc17dd0f7a6fc62da7c4ad423276262ac089d6baf875af2f099f3a384718",
            "Volumes": {
                "/var/lib/mysql": {}
            },
            "WorkingDir": "",
            "Entrypoint": [
                "docker-entrypoint.sh"
            ],
            "OnBuild": null,
            "Labels": {}
        },
        "DockerVersion": "20.10.7",
        "Author": "",
        "Config": {
            "Hostname": "",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "3306/tcp": {},
                "33060/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "GOSU_VERSION=1.12",
                "MYSQL_MAJOR=5.7",
                "MYSQL_VERSION=5.7.35-1debian10"
            ],
            "Cmd": [
                "mysqld"
            ],
            "Image": "sha256:db75bc17dd0f7a6fc62da7c4ad423276262ac089d6baf875af2f099f3a384718",
            "Volumes": {
                "/var/lib/mysql": {}
            },
            "WorkingDir": "",
            "Entrypoint": [
                "docker-entrypoint.sh"
            ],
            "OnBuild": null,
            "Labels": null
        },
        "Architecture": "amd64",
        "Os": "linux",
        "Size": 448231635,
        "VirtualSize": 448231635,
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/7b9260c0abd246be572d1f30e255e57a7e6ad3260f83252582f3698421b9b602/diff:/var/lib/docker/overlay2/44994b9bd6bd8355976f8f92c390f72444dc68e9334e59d697654e5022209aca/diff:/var/lib/docker/overlay2/410f7ca5510958929b5f732d6c48ea463eabd8b5266bcfc232fe4fb21758e1fd/diff:/var/lib/docker/overlay2/90b2ec06c320fd23651efc43a461011b18409affa354633099d31ece4145ac42/diff:/var/lib/docker/overlay2/566b76bb20e5891177b195007896d2015a341c9b63e896ababdc766e1186a5a4/diff:/var/lib/docker/overlay2/fd0648d2a59f4f3adabcd23297143c36edb91930fc759c6cae1c2ddae06c4174/diff:/var/lib/docker/overlay2/fb30191819232b24e68f35bf7af053678216b4efbb2a457e74da2b4212b04de4/diff:/var/lib/docker/overlay2/ae976dd3c5747768aa5eb22525cb81801254201eac88cdb337628bbb99ec49f3/diff:/var/lib/docker/overlay2/044119402a0929300900b5df1fce539572e303e8f052a01eb478b100cd74d89b/diff:/var/lib/docker/overlay2/8d0c84ccceee3e657b91cd3272d4095ab1a7861e4e09bce9dbc61025d39b8326/diff",
                "MergedDir": "/var/lib/docker/overlay2/bdd29e2762d98a38a48aa4bfebf6e63b7690206937202dc9072cc3e7280fa058/merged",
                "UpperDir": "/var/lib/docker/overlay2/bdd29e2762d98a38a48aa4bfebf6e63b7690206937202dc9072cc3e7280fa058/diff",
                "WorkDir": "/var/lib/docker/overlay2/bdd29e2762d98a38a48aa4bfebf6e63b7690206937202dc9072cc3e7280fa058/work"
            },
            "Name": "overlay2"
        },
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:814bff7343242acfd20a2c841e041dd57c50f0cf844d4abd2329f78b992197f4",
                "sha256:7075fc380548c52cc2a5c67d0ad62ca2d6b4e1a8d3648f803c5c3ce1f184e27e",
                "sha256:147b6eb160c4df8032ec4929c0c8381f63745bee5d0d1c648ca6b4618211b619",
                "sha256:b4419c864ffe6a264ba82bec875b19ee2fa08dbe1f92070901affb5ca1d4c8e9",
                "sha256:719288c1485f6918cc94c98ec325374de8fbe0f254c8c810bd49c4dfd9097ed2",
                "sha256:418c960a3eca900d4b4b1669d8f5c1fe5dd99f65d97e7243630f31b81f492805",
                "sha256:104ecd74e4e4c89524a3b93f8f97ef8f8574aaa52f9d9163f6a94aabe2f3fa1f",
                "sha256:5952cb12b9ed756f79fe1ed2b6c0bafb246e737cc0aa9f787771f4ef4f616b26",
                "sha256:7fa793435ff13e4dd013df0e54f68bbe110210af023359473e0bb7cfb85519c8",
                "sha256:8cb73d42958e5e83119036193e5e2f3c2564b76f06c02019d20c3dc9f923eb72",
                "sha256:9885efd52d6f8f5da69beef0cdea85066553fd2434c9dbfa1f13c7274188eeb6"
            ]
        },
        "Metadata": {
            "LastTagTime": "0001-01-01T00:00:00Z"
        }
    }
]
进入容器
#方式一
docker exec -it 容器id baseshell
[root@iZwz923fx7de74e5pc1tgoZ ~]# docker exec -it 427d8b6a1e42 /bin/bash
[root@427d8b6a1e42 /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@427d8b6a1e42 /]# ps -ef      
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 01:29 pts/0    00:00:00 /bin/bash
root        16     0  0 01:34 pts/1    00:00:00 /bin/bash
root        31    16  0 01:34 pts/1    00:00:00 ps -ef

#方式二
docker attach 容器id

attach和exec的区别
exec会进入当前容器并开启一个新的终端
attach就会直接进入当前终端不会重新开启
从容器内拷贝
docker cp 容器id:容器内路径  目的的主机路径

[root@iZwz923fx7de74e5pc1tgoZ ~]# docker cp 427d8b6a1e42:/home/test.java /
[root@iZwz923fx7de74e5pc1tgoZ /]# ls
bin  boot  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  test.java  tmp  usr  var

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

实战:docker 安装nginx

#1、搜索镜像search建议大家去docker搜索,可以看到帮助文档
#2、下载镜像pull
#3、运行测试

[root@iZwz923fx7de74e5pc1tgoZ ~]# docker pull nginx

-d:后台运行
--name:给容器命名
-p:宿主机端口:容器内部端口

[root@iZwz923fx7de74e5pc1tgoZ ~]# docker run -d --name nginx1 -p 3344:80 nginx
65c03bbac600695bb8c496dd85585ad10088265196e82865d31ad12409e277e1
[root@iZwz923fx7de74e5pc1tgoZ ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                  NAMES
65c03bbac600   nginx     "/docker-entrypoint.…"   4 seconds ago   Up 3 seconds   0.0.0.0:3344->80/tcp   nginx1
[root@iZwz923fx7de74e5pc1tgoZ ~]# curl localhost:3344
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

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

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

端口暴露

img

当我们启动容器后,便可以用进入容器的命令,对该容器运行的nginx的配置文件进行修改,但是我们每次要修改nginx的配置文件都得进入容器吗?可不可以自动同步? -v

实战:docker安装tomcat

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

#我们之前的启动都是后台,停止了容器后,容器还是能够查到

--rm代表用完即删除

安装完tomcat后,会跑tomcat的日志,ctrl+c停止后执行查看容器命令

[root@iZwz923fx7de74e5pc1tgoZ ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                  NAMES
65c03bbac600   nginx     "/docker-entrypoint.…"   18 minutes ago   Up 18 minutes   0.0.0.0:3344->80/tcp   nginx1
发现找不到tomcat,说明已经被删除了

#先下载在启动
docker pull tomcat
  
[root@iZwz923fx7de74e5pc1tgoZ ~]# docker run -d --name tomcat01 -p 3345:8080 tomcat
ca7f06dda761579b2dcca71e986bbbe8ffa6556f31320f35203478a07f52b61e
root@ca7f06dda761:/usr/local/tomcat# ls
BUILDING.txt  CONTRIBUTING.md  LICENSE	NOTICE	README.md  RELEASE-NOTES  RUNNING.txt  bin  conf  lib  logs  native-jni-lib  temp  webapps  webapps.dist 
root@ca7f06dda761:/usr/local/tomcat# ll
bash: ll: command not found

#发现问题1、linux命令少了 2、没有webapps 阿里云镜像的原因。
#默认用最小的镜像,将其他不需要的剔除

实战:部署es+kibana

#es暴露的端口很多
#es耗内存
#es的数据需要放在安全目录

--net somenetwork?网络配置

#启动了linux就卡住了docker stats查看cpu的状态
# es是十分耗内存的,1.xG ,1核2G

[root@iZwz923fx7de74e5pc1tgoZ ~]# curl localhost:9200
{
  "name" : "3fb90b526277",
  "cluster_name" : "docker-cluster",
  "cluster_uuid" : "fmzwfnluTgGfN45duhYzUg",
  "version" : {
    "number" : "7.6.2",
    "build_flavor" : "default",
    "build_type" : "docker",
    "build_hash" : "ef48eb35cf30adf4db14086e8aabd07ef6fb113f",
    "build_date" : "2020-03-26T06:34:37.794943Z",
    "build_snapshot" : false,
    "lucene_version" : "8.4.0",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}

可视化

portainer

#端口访问9000
docker run -d -p 8000:8000 -p 9000:9000 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce

Docker镜像讲解

Dock镜像是什么

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

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

如何得到镜像︰

·从远程仓库下载

·朋友拷贝给你

· 自己制作一个镜像DockerFile

Docker镜像加载原理

UnionFS(联合文件系统)

UnionFS (联合文件系统):Union文件系统(UnionFS )是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtualfilesystem)。Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。特性︰一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录

Docker镜像加载原理

docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。bootfs(boot file system)主要包含bootloader和kernel, bootloader主要是引导加载kernel, Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。

roots (root file system),在bootfs之上。包含的就是典型Linux系统中的/dev, /proc, /bin, /etc等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu , Centos等等。

img

分层理解

分层的镜像

我们去下载一个镜像的时候,观察日志,发现是一层一层在下载

img

思考:为什么Docker镜像要采用这种分层的结构呢?

最大的好处,我觉得莫过于是资源共享了!比如有多个镜像都从相同的Base镜像构建而来,那么宿主机只需在磁盘上保留一份base镜像,同时内存中也只需要加载一份base镜像,这样就可以为所有的容器服务了,而且镜像的每一层都可以被共享。

查看镜像分层的方式可以通过docker image inspect命令!

理解:

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

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

该镜像当前已经包含3个镜像层,如下图所示(这只是一个用于演示的很简单的例子)。

img

在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点非常重要。下图中举了一个简单的例子,每个镜像层包含3个文件,而镜像包含了来自两个镜像层的6个文件。

img

上图中的镜像层跟之前图中的略有区别,主要目的是便于展示文件。下图中展示了一个稍微复杂的三层镜像,在外部看来整个镜像只有6个文件,这是因为最上层中的文件7是文件5的一个更新版本。

img

这种情况下,上层镜像层中的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个新镜像层添加到镜像当Docker通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系统.

Linux上可用的存储引擎有AUFS、Overlay2、Device Mapper、Btrfs以及zFS。顾名思义,每种存储引擎都基于Linux中对应的文件系统或者块设备技术,并且每种存储引擎都有其独有的性能特点。

Docker在Windows上仅支持windowsfilter一种存储引擎,该引擎基于NTFS文件系统之上实现了分层和CoW[1].

下图展示了与系统显示相同的三层镜像。所有镜像层堆叠并合并,对外提供统一的视图。

img

特点

Docker镜像都是只读的,当容器启动后,一个新的可写层被加载到镜像的顶部!这一层通常被我们叫做容器层,容器之下就是镜像层

img

如何提交自己的镜像

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

docker commit -m="提交的信息" 	-a="作者" 容器id  目标镜像名字:Tag

实战:

#启动一个默认的tomcat
#发现这个默认的tomcat是没有webapps应用,镜像的原因,官方的镜像默认 webapps下面是没有文件的!
#我自己拷贝进去了基本的文件

[root@iZwz923fx7de74e5pc1tgoZ ~]# docker commit -a="penghaomin" -m="add webapps" 5c454d00dded tomcat1:1.0
sha256:11a27901896e58c041885df62d029693c2c607b09375004ea2bdf72e22f69d3d
[root@iZwz923fx7de74e5pc1tgoZ ~]# docker images
REPOSITORY               TAG       IMAGE ID       CREATED          SIZE
tomcat1                  1.0       11a27901896e   10 seconds ago   673MB
tomcat                   9.0       710ec5c56683   3 hours ago      668MB
tomcat                   latest    710ec5c56683   3 hours ago      668MB
portainer/portainer-ce   latest    dfac2df13044   8 days ago       210MB
redis                    latest    aa4d65e670d6   2 weeks ago      105MB
nginx                    latest    08b152afcfae   2 weeks ago      133MB
mysql                    5.7       8cf625070931   2 weeks ago      448MB
hello-world              latest    d1165f221234   5 months ago     13.3kB
centos                   latest    300e315adb2f   8 months ago     209MB
elasticsearch            7.6.2     f29a1ee41030   16 months ago    791MB

容器数据卷

什么是容器数据卷

docker的理念回顾

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

数据?如果数据都在容器中,那么我们容器删除,数据就会丢失 !需求∶数据可以持久化

MySQL,容器删了,删库跑路 需求:Mysql数据存在本地

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

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

使用容器数据卷

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

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

img

反向操作

img

实战:mysql数据同步

docker run --name mysql4 -e MYSQL_ROOT_PASSWORD=123456  -v /home/mysql/conf:/etc/my.cnf  -v /home/mysql/data:/var/lib/mysql -p 3310:3306 -d mysql:5.7

具名挂载和匿名挂载

#匿名挂载
docker run -d --name nginx -v 容器内路径

#查看所有卷的情况
[root@iZwz923fx7de74e5pc1tgoZ mysql]# docker volume ls
DRIVER    VOLUME NAME
local     6b2209c890e1b3631efc68e19019d749e0dd7ad922e71afc7b8f4094c84c0bbb
local     7b720be37f88f110d50c0fe85764661280d807123c0d2cc751899561c7880325
local     678e293904a49a8e7f1feae876ac86a7f0891a141e70a637656c0e0e015e43e0
local     58255b78e82441600bb8cf7a325f22e500d61a41eb01ae9ee27ab8359609e591
local     c5964c817d4afed84e04ec27d2d2ff63fe837b27d87b875e9681413561b94674
local     e5ae42beca5cb33c96a2e6f665a21416ca2167e0be6bcbe5e1769d4477200c6e
local     f611d08defde2257ab7ef01b8dd1c613a2efb9cde63c912881f447caaa5ed1b8
local     fde187080f79f2c74b229f8c29867fa41e455887616936e772e0879defffab4b
local     portainer_data

#听过-v 卷名:容器路径 来为数据卷命名

#查看卷的详情
[root@iZwz923fx7de74e5pc1tgoZ mysql]# docker volume inspect 6b2209c890e1b3631efc68e19019d749e0dd7ad922e71afc7b8f4094c84c0bbb
[
    {
        "CreatedAt": "2021-08-07T17:12:48+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/6b2209c890e1b3631efc68e19019d749e0dd7ad922e71afc7b8f4094c84c0bbb/_data",
        "Name": "6b2209c890e1b3631efc68e19019d749e0dd7ad922e71afc7b8f4094c84c0bbb",
        "Options": null,
        "Scope": "local"
    }
]

所有的卷没有指定目录的话,都是在/var/lib/docker/volumes /卷名字/ _data存储的

#如何确定是具名挂载还是匿名挂载呢
-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 说明这个路径只可以通过宿主机操作,无法在容器内操作

初识DockerFile

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

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

方式二: 
vim dockerfile


FROM centos

VOLUME ["volume01","volume02"]

CMD echo "end"

CMD /bin/bash



[root@iZwz923fx7de74e5pc1tgoZ volume]# docker build -f /home/volume/dockerfile -t phm/centos:7.0 .
注意最后有个点

Sending build context to Docker daemon  2.048kB
Step 1/4 : FROM centos
 ---> 300e315adb2f
Step 2/4 : VOLUME ["volume01","volume02"]
 ---> Running in 736834fbd9a4
Removing intermediate container 736834fbd9a4
 ---> b9f5c2a242fc
Step 3/4 : CMD echo "end"
 ---> Running in a9c2d94b224d
Removing intermediate container a9c2d94b224d
 ---> d5d4f294337d
Step 4/4 : CMD /bin/bash
 ---> Running in f8627be75051
Removing intermediate container f8627be75051
 ---> e6895c6fc05e
Successfully built e6895c6fc05e
Successfully tagged phm/centos:7.0

成功构建镜像

img

我们进入容器中,ls发现了好玩的东西,在/下生成了我们自动挂载的数据卷目录

img

这些卷肯定和外部有目录是连接的。

进入该数据卷目录,新建一个文件,因为我们知道,内部容器中做出的改变,外部容器是同步的,我们就可以通过这个来找到目录,还是匿名挂载

img

数据卷容器

#先启动三个容器
[root@iZwz923fx7de74e5pc1tgoZ /]# docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS          PORTS                               NAMES
341bc81f4311   e6895c6fc05e   "/bin/bash"              11 seconds ago   Up 10 seconds                                       phm3
690301013bed   e6895c6fc05e   "/bin/bash"              18 seconds ago   Up 18 seconds                                       phm2
841dbdd78779   e6895c6fc05e   "/bin/bash"              40 seconds ago   Up 39 seconds                                       phm1
9eb416d9fb1b   mysql:5.7      "docker-entrypoint.s…"   52 minutes ago   Up 52 minutes   33060/tcp, 0.0.0.0:3310->3306/tcp   mysql4

[root@iZwz923fx7de74e5pc1tgoZ /]# docker run  -it --name=phm2 --volumes-from phm1  e6895c6fc05e /bin/bash

利用–volumes-from将phm1和phm2同步

img

可以看到在phm2中touch了一个a.txt,在phm1的volume01中也出现了

[root@kuangshen home]# docker run -d -p 3310:3306 -v/etc/mysq1/conf.d -v /var/1ib/mysq1 -eYsQL_ROOT_PASSWORD=123456--name mysq101 mysq1:5.7
[root@kuangshen home]# docker run -d -p 3310:3306 -e MYSQL_R00T_PASSWORD=123456 --name mysq102 --olumes-form mysq101 mysq1:5.7


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

结论∶容器之间配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止。但是一旦你持久化到了本地,这个时候,本地的数据是不会删除的!

DockerFile

dockerfile是用来构建dokcer镜像的文件!命令参数脚本!构建步骤:

1、编写一个dockerfile 文件

2、docker build构建成为一个镜像

3、docker run运行镜像

4、docker push 发布镜像(DockerHub、阿里云镜像仓库!)

很多官方镜像都是基础包,很多功能没有,我们通常会自己搭建自己的镜像!官方既然可以制作镜像,那我们也可以!

DockerFile的创建过程

基础知识

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

2、指令从上到下执行

3、#表示注释

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

img

dockerfile是面向开发的,我们以后要发布项目,作镜像,就要编写dockerfile文件,这个文件特别简单

Docker镜像已经逐渐成为了企业交接的标准

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

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

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

DockerFile的指令说明

img

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

实战构建自己的centos

Docker Hub中99%镜像都是从这个基础镜像过来的FROM scratch,然后配置需要的软件和配置来进行的构建

创建一个目录,然后创建dockerFile文件

FROM centos
MAINTAINER phm<892552140@qq.com>
ENV MYPATH /usr/local
WORKDIR $MYPATH   #设置工作目录
RUN yum -y install vim 
RUN yum -y install net-tools
EXPOSE 80
CMD echo $MYPATH
CMD "echo " ----end-
CMD /bin/bashl

通过build命令构建

docker build -f dockerfile -t mycentos:1 .

CMD和ENTRYPOINT的区别

#编写dockerfile 文件
[root@kuangshen dockerfile]# vim dockerfile-cmd-testFROM centos
CMD ["ls ", "-a"]
#构件镜像
[root@kuangshen dockerfile]# docker build -f dockerfile-cmd-test -t cmdtest .
#run运行,发现我们的-a命令生效

[root@kuangshen dockerfile]# docker run dd8e4401d72f -l
docker: Error. response from daemon: OCI runtime create failed: container_linux. g0:349: starting
container process caused "exec: \"-1\": executab7e file not found in $PATH": unknown.

#cmd的情况下 -l替换成了CMD["ls","-a"]命令,但是没有单个-l的命令,所以会报错,下列就不报错
[root@kuangshen dockerfile]# docker run dd8e4401d72f ls -al

但是我们如果用ENTRYPOINT就不会报错,因为ENTRYPOINT是可以追加的

Docker制作tomcat镜像

1、准备tomcat镜像的压缩包,jdk的压缩包

img

2、dockerfile文件,官方命名Dockerfile,这样就不需要-f绑定了

FRoM centos
MAINTAINET kuangshen<24736743@qq.com:COPY readme.txt /usr/local/readme.txt
ADD	jdk-8u11-linux-x64.tar.gz /usr/local/ADD apache-tomcat-9.0.22.tar.gz /usr/local/RUN yum -y install vim
ENV MYPATH /usr/localwORKDIR $MYPATH
ENV JAVA_HOME /usr/local/jdk1.8.0_11
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jarENV CATALINA_HOME/usr/local/apache-tomcat-9.0.22
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.22
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
EXPOSE 8080
CND/usr/local/apache-tomcat-9.0.22/bin/startup.sh && tail -F /url/local/apache-tomcat-9.0.22/bin/logs/catalina.out

3、构建镜像

#docker build -t diytomcat .

4、启动镜像

5、访问测试

6、发布项目(由于做了卷挂载,我们直接在本地编写项目就可以发布了! )

发布至dockerhub

DockerHub

1、首先得注册一个账号

2、在服务器上登录账号

[root@iZwz923fx7de74e5pc1tgoZ ~]# docker login --help

Usage:  docker login [OPTIONS] [SERVER]

Log in to a Docker registry.
If no server is specified, the default is defined by the daemon.

Options:
  -p, --password string   Password
      --password-stdin    Take the password from stdin
  -u, --username string   Username

我的docker账号:wohenlaijin

3、登陆完毕就可以提交镜像了

docker push  作者/项目:标签

找不到可以

docker tag id kuangshen/tomcat: 1.0

阿里云容器

1、登录阿里云

2、找到容器镜像服务

3、创建命名空间

4、创建镜像仓库

img

后边基本一致

小结

img

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值