当前位置:   article > 正文

Docker操作篇_docker exec -u

docker exec -u

Docker操作篇

本笔记以个人思维为导向讲述docker的操作,以实验用到什么聊什么为叙述指导,不包含太多关于原理性内容,并且自身为运维,故整篇文章还是偏重于运维角度的,距通用文档水平相去尚远,更算不得一篇原理性笔记,只是操作。综上这篇笔记还是比较合适对容器已经有一定概念的运维同学来一起学习使用。

并且本笔记不包含docker compose与docker swarm的内容,推荐在掌握了docker基础后使用kubernetes,故此不再过多的涉及docker的编排方面。

本文实验环境:

​ 基于 Centos7.9(通篇以linux为基本讲述,mac os及windows不涉及)

​ docker版本:docker-ce-20.10.7

​ 每节点 2核心2G内存40G磁盘

节点概况:

IP主机名角色
192.168.1.101node01docker测试
192.168.1.102node02docker测试
192.168.1.110harborharbor

修改记录:

版本修改时间备注
v.002021.6systemctl529_Yu

注:

​ 一定请看好每条命令前的主机名,本笔记以主机名区分不同主机操作

一、容器的概念及简史

容器,顾名思义,即为承载其他“物体”的器具,如生活中的锅碗瓢盆,他们都是物理世界中真实可触碰的载具,我们这里提到的容器,是软件层级的逻辑容器。

关于容器技术的发展,最早被认为是容器的技术,出现在1979年,Unix版本7在开发过程中引入Chroot Jail以及Chroot系统调用。Chroot jail被用于“Change Root”,它被认为是最早的容器化技术之一。(相信应该有不少人在单用户模式下使用过chroot /sysroot)

后来在21世纪初期出现了众多的容器相关的技术,比如Linux-Vserver,比如Cgroups LXC等等

而我们今天讨论的docker,第一个开源版本出现于2013年,但现今为止,类似docker的这种容器引擎,存在有众多的发行版本,截止目前,docker仍然是容器引擎的主流

docker公司原本叫做dotCloud,做PaaS项目,然而经营并不好,13年他们开源了docker,竟突然获得巨大成功,所以公司也就改名叫做docker Inc了,docker公司的CTO Solomon Hykes,是docker的灵魂人物,也正是他提出了现在注明的:“Build Once,Run Anywhere”,一次构建,到处运行。

探讨一个问题,我们已经有了相当成熟的Iaas虚拟化架构,为何又需要paas,我个人认为主要还是来源于效率的需求,传统虚拟化总是无法绕过“客户机操作系统”,即便是一个经过了精心裁剪的系统,其也无法摆脱一个独立的客户机系统内核及基本运行环境等的资源占用,而容器技术一大区别就是其不再需要额外的虚拟化出一套完整的系统,其内核直接共用宿主机系统,只需要封装一个基本的软件所需运行环境和项目代码即可了,这就使其足够的轻量化,减轻了一些资源的浪费,并且因为一个一个简洁的镜像和运行时,docker变得要比传统软件部署一定方面上更易于管理,再加上容器一旦配合上一些编排技术,那么其快速的扩缩容能力和通用部署能力也非传统虚拟化可比。当然了,目前来看,任何技术都并非完美的,虚拟化亦有其自身目前难以被替代的优势,比如其真正的资源隔离,对物理机的资源集群整合等。而且其实目前大部分的容器集群,真正的利用环境亦是运行在虚拟机之上的,真正具备物理机直接运行容器的企业,还是相对较大型的体量,总体较少,所以容器目前对于中小企业来看,仍然是前瞻意义大于实际意义的。

容器的优势和劣势在哪里?简单来说,容器的主要劣势还是存在于隔离性上面,优势就较多了,比如资源消耗小,启动速度快,跨平台能力强,扩展快,对微服务支持好,对自动化架构配合好等

二、Docker的实现

1、docker的实现技术

1.1 虚拟结构的不同

常见的传统虚拟化:

​ 以下是一个 2 型虚拟化的基本结构图:

在这里插入图片描述

传统的虚拟化通常有两种,1型虚拟化(如xen esxi)或者2型虚拟化(kvm workstation),不论是1型还是2型,都无法离开“Guest OS”,这也就会带来一定的资源额外消耗,

容器的虚拟化

容器也是一种虚拟化技术,只是它并非是“平台虚拟化”,而是“操作系统虚拟化”,也就是说,其虚拟的内容已经不再是传统虚拟化的硬件资源,而是应用运行环境

​ 以下是容器的基本结构图:

在这里插入图片描述

可以看到,容器是直接运行在宿主机系统之上的,不再需要一个额外的操作系统来作为应用运行环境,故这种形式,也可以将一个容器看作是一个“进程”

1.2 容器用哪些内核技术实现

既然容器直接跑在宿主机中,那么资源的隔离和限制怎么来实现,到目前,解决方案已经直接集成在了系统内核中

docker通过系统内核中的 namespace实现资源隔离,通过cGroups实现资源限制,那么一个容器需要隔离出哪些基本资源?

namespace资源隔离

资源隔离内容集成于哪个内核版本
Mount(文件系统,挂载点…)2.4.19
Pid (进程ID)2.6.24
IPC (信号量,消息队列,共享内存…)2.6.19
Net (网络设备,网络协议栈,端口…)2.6.29
UTS (主机名,域名…)2.6.19
User(操作进程的用户及用户组)3.8

namespace隔离的系统调用参数及基本解释

mount CLONE_NEWNS 每个容器的文件系统是独立的

pid CLONE_NEWPID 每个容器内部有独立的进程树

IPC CLONE_NEWIPC 每个容器依旧使用linux内核中进程交互的方法,实现进程间通信

Net CLONE_NEWNET 每个容器之间的网络默认隔离

UTS CLONE_NEWUTS 每个namesapce有自己独立的主机名或者域名

User CLONE_NEWUSER 每个容器都有独立的root,独立的用户

cGroups

cgroups(Control Groups) 是 linux内核提供的一种机制,这种机制可以根据需求把一系列系统任务及其子任务整合(或分隔)到按资源划分等级的不同组内,从而为系统资源管理提供一个统一的框架。简单说,cgroups可以限制、记录任务组所使用的物理资源。本质上来说,cgroups 是内核附加在程序上的一系列钩子(hook),通过程序运行时对资源的调度触发相应的钩子以达到资源追踪和限制的目的。

实现 cgroups 的主要目的是为不同用户层面的资源管理提供一个统一化的接口。从单个任务的资源控制到操作系统层面的虚拟化,cgroups 提供了四大功能:
资源限制:cgroups 可以对任务是要的资源总额进行限制,比如设定任务运行时使用的内存上限,一旦超出就发OOM。
优先级分配:通过分配的 CPU 时间片数量和磁盘 IO 带宽,实际上就等同于控制了任务运行的优先级。
资源统计:cgoups 可以统计系统的资源使用量,比如 CPU 使用时长、内存用量等。这个功能非常适合当前云端产品按使用量计费的方式。

任务控制:cgroups 可以对任务执行挂起、恢复等操作。

2、Docker的实现语言

docker引擎是基于Google公司的Go语言来编写实现,Golang号称21世纪C语言,当前非常热门,目前来看,Go语言的前景也确实够好。

Go(又称Golang)是Google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的编程语言。

docker部署时,可以直接安装二进制软件包,如果想要源码编译,也就需要一个Go的编译环境。

三、安装Docker

关于系统环境的基本初始化就不再赘述了,仍然是关掉防火墙,Selinux这一套

另外可能唯一和之前不同的是,需要开一下路由转发

# echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
# sysctl -p

  • 1
  • 2
  • 3

我们安装的docker,是docker-ce(社区版),企业版是docker-ee

1、配置Yum源

因为这里使用的是Centos(Rpm包管理),故需要配置的是yum源

首先配置基础源,可以是系统默认的,也可以自己手动新增国内源,然后配置docker源

# 配置清华源
[root@node01 yum.repos.d]# pwd
/etc/yum.repos.d
# 注意,国内源中缺少一些包,不要删除掉系统自带的repo文件,只新增即可
[root@node01 yum.repos.d]# vim tuna.os.repo
[tuna_centos]
name=tuna.centos.os.yum
baseurl=https://mirrors.tuna.tsinghua.edu.cn/centos/7.9.2009/os/x86_64/
enabled=1
gpgcheck=0


# epel源
[root@node01 yum.repos.d]# vim tuna.epel.repo
[tuna.epel]
name=tuna.epel
baseurl=https://mirrors.tuna.tsinghua.edu.cn/epel/7/x86_64/
enabled=1
gpgcheck=0



# 配置docker源
[root@node01 yum.repos.d]# vim tuna.docker.repo
[docker-ce-stable]
name=Docker CE Stable - $basearch
baseurl=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/$releasever/$basearch/stable
enabled=1
gpgcheck=1
gpgkey=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/gpg
或者
[root@node01 yum.repos.d]# wget https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/docker-ce.repo
[root@node01 yum.repos.d]# sed -i 's+download.docker.com+mirrors.tuna.tsinghua.edu.cn/docker-ce+' /etc/yum.repos.d/docker-ce.repo

# 缓存
[root@node01 yum.repos.d]# yum clean all
[root@node01 yum.repos.d]# yum makecache

# 查看最新的docekr版本
[root@node01 yum.repos.d]# yum list docker-ce
已加载插件:fastestmirror
Loading mirror speeds from cached hostfile
可安装的软件包
docker-ce.x86_64                      3:20.10.7-3.el7                      docker-ce-stable

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

列出源中所有软件包版本可以执行

[root@node01 yum.repos.d]# yum list docker-ce --show-duplicates

2、更新系统软件包

也可以只更新kernel相关包

[root@node01 yum.repos.d]# yum update

  • 1
  • 2

3、安装docker

[root@node01 ~]# yum -y install docker-ce

[root@node01 ~]# docker -v
Docker version 20.10.7, build f0df350

  • 1
  • 2
  • 3
  • 4
  • 5

4、配置并启动docker

# 启动并设置开机自启
[root@node01 ~]# systemctl start docker
[root@node01 ~]# systemctl enable docker

  • 1
  • 2
  • 3
  • 4
# 配置docker
[root@node01 ~]# vim /etc/docker/daemon.json
{
        "data-root": "/docker",
        "bip": "172.1.1.1/16",
        "storage-driver": "overlay2"
}


[root@node01 ~]# systemctl daemon-reload

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

daemon.json配置项简析:

首先需要一个 {},然后每行配置的间隔需要使用 , 号,最后一行可以不加 ,号

“exec-root”:“/docker” exec-root配置的是docker工作目录

“registry-mirrors”: [“https://xxxxxxxxxxxxxx.mirror.aliyuncs.com”] registry-mirrors是配置的镜像加速,如果有多个,可以[“1”,‘’2“]继续写

“insecure-registries”: [“域名/IP:port”] insecure-registries配置的是私有非ssl镜像仓库地址,如果有多个,可以[“1”,“2”]继续写

“storage-driver”: “overlay2” storage-driver存储驱动程序

\“bip”: “172.1.1.1/16” bip docker网络

“live-restore”: true live-restore传递一个SIGHUP信号给daemon进程来重载配置

docker-daemon.json各配置详解
{
 “api-cors-header”:"", ——————在引擎API中设置CORS标头
 “authorization-plugins”:[], ——————要加载的授权插件
 “bridge”:"", ————将容器附加到网桥
 “cgroup-parent”:"", ——————为所有容器设置父cgroup
 “cluster-store”:"", ——————分布式存储后端的URL
 “cluster-store-opts”:{}, ————————设置集群存储选项(默认map [])
 “cluster-advertise”:"", ————————要通告的地址或接口名称
 “debug”: true, ————————启用调试模式,启用后,可以看到很多的启动信息。默认false
 “default-gateway”:"", ——————容器默认网关IPv4地址
 “default-gateway-v6”:"", ——————容器默认网关IPv6地址
 “default-runtime”:“runc”, ————————容器的默认OCI运行时(默认为“ runc”)
 “default-ulimits”:{}, ——————容器的默认ulimit(默认[])
 “dns”: [“192.168.1.1”], ——————设定容器DNS的地址,在容器的 /etc/resolv.conf文件中可查看。
 “dns-opts”: [], ————————容器 /etc/resolv.conf 文件,其他设置
 “dns-search”: [], ————————设定容器的搜索域,当设定搜索域为 .example.com 时,在搜索一个名为 host 的 主机时,DNS不仅搜索host,还会搜
 索host.example.com 。 注意:如果不设置, Docker 会默认用主机上的 /etc/resolv.conf 来配置容器。
 “exec-opts”: [], ————————运行时执行选项
 “exec-root”:"", ————————执行状态文件的根目录(默认为’/var/run/docker‘)
 “fixed-cidr”:"", ————————固定IP的IPv4子网
 “fixed-cidr-v6”:"", ————————固定IP的IPv6子网
 “data-root”:"/var/lib/docker", ————-Docker运行时使用的根路径,默认/var/lib/docker
 “group”: “”, ——————UNIX套接字的组(默认为“docker”)
 “hosts”: [], ——————设置容器hosts
 “icc”: false, ——————启用容器间通信(默认为true)
 “ip”:“0.0.0.0”, ————————绑定容器端口时的默认IP(默认0.0.0.0)
 “iptables”: false, ———————启用iptables规则添加(默认为true)
 “ipv6”: false, ——————启用IPv6网络
 “ip-forward”: false, ————————默认true, 启用 net.ipv4.ip_forward ,进入容器后使用 sysctl -a | grepnet.ipv4.ip_forward 查看
 “ip-masq”:false, ——————启用IP伪装(默认为true)
 “labels”:[“nodeName=node-121”], ————————docker主机的标签,很实用的功能,例如定义:–label nodeName=host-121
 “live-restore”: true, ——————在容器仍在运行时启用docker的实时还原
 “log-driver”:"", ——————容器日志的默认驱动程序(默认为“ json-file”)
 “log-level”:"", ——————设置日志记录级别(“调试”,“信息”,“警告”,“错误”,“致命”)(默认为“信息”)
 “max-concurrent-downloads”:3, ——————设置每个请求的最大并发下载量(默认为3)
 “max-concurrent-uploads”:5, ——————设置每次推送的最大同时上传数(默认为5)
 “mtu”: 0, ——————设置容器网络MTU
 “oom-score-adjust”:-500, ——————设置守护程序的oom_score_adj(默认值为-500)
 “pidfile”: “”, ——————Docker守护进程的PID文件
 “raw-logs”: false, ——————全时间戳机制
 “selinux-enabled”: false, ——————默认 false,启用selinux支持
 “storage-driver”:"", ——————要使用的存储驱动程序
 “swarm-default-advertise-addr”:"", ——————设置默认地址或群集广告地址的接口
 “tls”: true, ————————默认 false, 启动TLS认证开关
 “tlscacert”: “”, ——————默认 ~/.docker/ca.pem,通过CA认证过的的certificate文件路径
 “tlscert”: “”, ————————默认 ~/.docker/cert.pem ,TLS的certificate文件路径
 “tlskey”: “”, ————————默认~/.docker/key.pem,TLS的key文件路径
 “tlsverify”: true, ————————默认false,使用TLS并做后台进程与客户端通讯的验证
 “userland-proxy”:false, ——————使用userland代理进行环回流量(默认为true)
 “userns-remap”:"", ————————用户名称空间的用户/组设置
 “bip”:“192.168.88.0/22”, ——————————指定网桥IP
 “registry-mirrors”: [“https://192.498.89.232:89”], ————————设置镜像加速
 “insecure-registries”: [“120.123.122.123:12312”], ———————设置私有仓库地址可以设为http
 “storage-opts”: [
 “overlay2.override_kernel_check=true”,
 “overlay2.size=15G”
 ], ————————存储驱动程序选项
 “log-opts”: {
 “max-file”: “3”,
 “max-size”: “10m”,
 }, ————————容器默认日志驱动程序选项
 “iptables”: false ————————启用iptables规则添加(默认为true)
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65

5、docker基本信息查看

# 执行docker info 可以查看基本的docker信息
[root@node01 docker]# docker info
Client:
 Context:    default
 Debug Mode: false
 Plugins:
  app: Docker App (Docker Inc., v0.9.1-beta3)
  buildx: Build with BuildKit (Docker Inc., v0.5.1-docker)
  scan: Docker Scan (Docker Inc., v0.8.0)

Server:
 Containers: 0
  Running: 0
  Paused: 0
  Stopped: 0
 Images: 0
 Server Version: 20.10.7      
 Storage Driver: overlay2     
  Backing Filesystem: xfs
  Supports d_type: true
  Native Overlay Diff: true
  userxattr: false
 Logging Driver: json-file
 Cgroup Driver: cgroupfs
 Cgroup Version: 1
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
 Swarm: inactive
 Runtimes: io.containerd.runc.v2 io.containerd.runtime.v1.linux runc
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: d71fcd7d8303cbf684402823e425e9dd2e99285d
 runc version: b9ee9c6314599f1b4a7f497e1f1f856fe433d3b7
 init version: de40ad0
 Security Options:
  seccomp
   Profile: default
 Kernel Version: 3.10.0-1160.11.1.el7.x86_64
 Operating System: CentOS Linux 7 (Core)
 OSType: linux
 Architecture: x86_64
 CPUs: 2
 Total Memory: 1.933GiB
 Name: node01
 ID: WIDC:DX4D:7IW7:H5OR:EK4Y:F4YX:ABUI:IKE7:DVIN:K5W3:KE76:6YAO
 Docker Root Dir: /docker
 Debug Mode: false
 Registry: https://index.docker.io/v1/
 Labels:
 Experimental: false
 Insecure Registries:
  127.0.0.0/8
 Registry Mirrors:
  https://xxxxxx.mirror.aliyuncs.com/
 Live Restore Enabled: false

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58

如果执行 docker info时,发现了以下两条警告

WARNING: bridge-nf-call-iptables is disabled
WARNING: bridge-nf-call-ip6tables is disabled

这意味着你的防火墙没有关闭,如果不想关,就增加下配置,以要求iptables不对bridge的数据进行处理

# vim /etc/sysctl.conf
# 追加
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1

# sysctl -p
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

6、docker镜像加速

提前做一下docker镜像加速的配置,因为后面运行docker需要先拉取docker镜像,但是docker hub是在国外的,对我们而言,很慢,所以先配置下加速

这里以阿里云镜像加速为例,首先记得注册好阿里云账号

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

配置下加速地址

[root@node01 ~]# vim /etc/docker/daemon.json
{
		### 追加以下一行
        "registry-mirrors": ["https://xxxxxxxxxxxx.mirror.aliyuncs.com"]
}

[root@node01 ~]# systemctl daemon-reload
[root@node01 ~]# systemctl restart docker

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

四、Docker的使用

docker对镜像或者容器的操作,使用ID或者名称均可

1、docker 镜像

docker镜像,就是打包好的应用以及应用环境(代码,运行时,库,环境变量,配置文件等)

1.1 查看本地镜像

# docker images 查看镜像列表
[root@node01 ~]# docker images
REPOSITORY   TAG       IMAGE ID   CREATED   SIZE

  • 1
  • 2
  • 3
  • 4

1.2 搜索镜像

搜索镜像可以在命令行搜索,也可以去比如docker hub等镜像仓库搜索

[root@node01 ~]# docker search centos
NAME                               DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
centos                             The official build of CentOS.                   6594      [OK]
ansible/centos7-ansible            Ansible on Centos7                              134                  [OK]
consol/centos-xfce-vnc             Centos container with "headless" VNC session…   129                  [OK]
jdeathe/centos-ssh                 OpenSSH / Supervisor / EPEL/IUS/SCL Repos - …   118                  [OK]
......

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

docker 官方镜像仓库:https://registry.hub.docker.com/

在这里插入图片描述

1.3 拉取镜像

拉取镜像时,如果不指定版本,那么拉取的就是 latest 最新版本,指定版本 # docker pull centos:TAG

[root@node01 ~]# docker pull centos
Using default tag: latest
latest: Pulling from library/centos
7a0437f04f83: Downloading  39.37MB/75.18MB

[root@node01 ~]# docker pull centos:7.9.2009
7.9.2009: Pulling from library/centos
2d473b07cdd5: Downloading  22.57MB/76.1MB


# 查看下本地镜像
[root@node01 ~]# docker images
REPOSITORY   TAG        IMAGE ID       CREATED        SIZE
centos       latest     300e315adb2f   6 months ago   209MB
centos       7.9.2009   8652b9f0cb4c   7 months ago   204MB

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

1.4 删除镜像

[root@node01 ~]# docker images
REPOSITORY   TAG        IMAGE ID       CREATED        SIZE
centos       latest     300e315adb2f   6 months ago   209MB
centos       7.9.2009   8652b9f0cb4c   7 months ago   204MB


[root@node01 ~]# docker rmi centos:latest
Untagged: centos:latest
Untagged: centos@sha256:5528e8b1b1719d34604c87e11dcd1c0a20bedf46e83b5632cdeac91b8c04efc1
Deleted: sha256:300e315adb2f96afe5f0b2780b87f28ae95231fe3bdd1e16b9ba606307728f55
Deleted: sha256:2653d992f4ef2bfd27f94db643815aa567240c37732cae1405ad1c1309ee9859


[root@node01 ~]# docker images
REPOSITORY   TAG        IMAGE ID       CREATED        SIZE
centos       7.9.2009   8652b9f0cb4c   7 months ago   204MB

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

1.5 导入导出镜像

# 导出
[root@node01 ~]# docker save centos:7.9.2009 -o /tmp/centos.7.9.2009
[root@node01 ~]# du -sh /tmp/centos.7.9.2009
202M    /tmp/centos.7.9.2009


# 导入
先删除本地的centos:7.9.2009镜像
[root@node01 ~]# docker rmi centos:7.9.2009
Untagged: centos:7.9.2009
Untagged: centos@sha256:0f4ec88e21daf75124b8a9e5ca03c37a5e937e0e108a255d890492430789b60e
Deleted: sha256:8652b9f0cb4c0599575e5a003f5906876e10c1ceb2ab9fe1786712dac14a50cf
Deleted: sha256:174f5685490326fc0a1c0f5570b8663732189b327007e47ff13d2ca59673db02
[root@node01 ~]# docker load < /tmp/centos.7.9.2009
174f56854903: Loading layer  211.7MB/211.7MB
Loaded image: centos:7.9.2009
[root@node01 ~]# docker images
REPOSITORY   TAG        IMAGE ID       CREATED        SIZE
centos       7.9.2009   8652b9f0cb4c   7 months ago   204MB

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

如果导入镜像后,查看时,发现镜像名为 ,这种可以使用 docker tag 来命名

# docker tag [镜像ID] 镜像名:TAG
  • 1

2、docker容器 (运行时)

也就是在运行的容器,运行起来的镜像;其与镜像的区别:镜像是静态的定义,容器是镜像运行时的实体

关于容器生命周期

  • 执行docker run时,检查本地是否有该名称的镜像,如果没有,从仓库检索并拉取
  • 使用本地镜像启动容器
  • 分配一个文件系统,并在只读的镜像层上挂载一个可写层(容器层)
  • 从宿主机配置的网桥接口中桥接一个虚拟接口到容器
  • 从地址池中分配IP给容器
  • 执行CMD指令
  • 执行完毕后容器生命结束,容器停止

2.1 运行容器

docker run [选项 参数] 镜像 CMD

# 当本地没有你要运行的镜像时,会自动拉取

[root@node01 ~]# docker pull centos:latest

[root@node01 ~]# docker run centos

  • 1
  • 2
  • 3
  • 4

2.2 查看运行的容器

# 查看运行中的容器
[root@node01 ~]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
刚运行的容器并没有存在,这是因为我们运行时没有指定CMD运行内容,有些镜像比如这种系统镜像,是需要手动指定运行内容的

# 查看所有的容器(包含未运行的)
[root@node01 ~]# docker ps -a
CONTAINER ID   IMAGE     COMMAND       CREATED          STATUS                      PORTS     NAMES
36a3d9354ba4   centos    "/bin/bash"   37 seconds ago   Exited (0) 36 seconds ago             confident_visvesvaraya


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

2.3 运行时添加选项

常用选项

-d: 后台运行容器,并返回容器ID;

-i: 以交互模式运行容器,通常与 -t 同时使用;

-P: 随机端口映射,容器内部端口随机映射到主机的端口

-p: 指定端口映射,格式为:主机(宿主)端口:容器端口

-t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用;

–name=“容器名”: 为容器指定一个名称;

**-m **:设置容器使用内存最大值;

–net=“bridge”: 指定容器的网络连接类型,支持 bridge/host/none/container: 四种类型;

–expose=[]: 开放一个端口或一组端口;

–volume , -v: 绑定一个卷

-e: 传递环境变量 环境变量key:环境变量value

# 运行bash程序
[root@node01 ~]# docker run -itd centos:latest /bin/bash
3b1157fa7e1b34b1c288de81da35cd8e310ff14ec4ea8d16d64cb4d60da96c09

[root@node01 ~]# docker ps
CONTAINER ID   IMAGE           COMMAND       CREATED         STATUS        PORTS     NAMES
3b1157fa7e1b   centos:latest   "/bin/bash"   2 seconds ago   Up 1 second             sharp_shaw

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

2.4 查看容器运行输出(日志)

[root@node01 ~]# docker run -itd --name="centos_v1" centos:latest /bin/bash -c "while true;do echo hello docker;sleep 10;done"
efcd72ea15a7e1ca8c17245d0ed41c7e331d646a488e3c8ef5a3d8fd7490dc3c

[root@node01 ~]# docker logs centos_v1
hello docker
hello docker

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

2.5 操作容器

[root@node01 ~]# docker exec -it centos_v1 /bin/bash
[root@efcd72ea15a7 /]# ps
   PID TTY          TIME CMD
    22 pts/1    00:00:00 bash
    36 pts/1    00:00:00 ps

# 退出时执行 exit
[root@efcd72ea15a7 /]# exit
exit

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

2.6 查看容器相关信息

[root@node01 ~]# docker inspect centos_v1
[
    {
        "Id": "efcd72ea15a7e1ca8c17245d0ed41c7e331d646a488e3c8ef5a3d8fd7490dc3c",
        "Created": "2021-06-13T09:51:13.330140921Z",
        "Path": "/bin/bash",
        "Args": [
            "-c",
            "while true;do echo hello docker;sleep 10;done"
        ],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 26148,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2021-06-13T09:51:14.040711318Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
        "Image": "sha256:300e315adb2f96afe5f0b2780b87f28ae95231fe3bdd1e16b9ba606307728f55",
        "ResolvConfPath": "/docker/containers/efcd72ea15a7e1ca8c17245d0ed41c7e331d646a488e3c8ef5a3d8fd7490dc3c/resolv.conf",
        "HostnamePath": "/docker/containers/efcd72ea15a7e1ca8c17245d0ed41c7e331d646a488e3c8ef5a3d8fd7490dc3c/hostname",
        "HostsPath": "/docker/containers/efcd72ea15a7e1ca8c17245d0ed41c7e331d646a488e3c8ef5a3d8fd7490dc3c/hosts",
        "LogPath": "/docker/containers/efcd72ea15a7e1ca8c17245d0ed41c7e331d646a488e3c8ef5a3d8fd7490dc3c/efcd72ea15a7e1ca8c17245d0ed41c7e331d646a488e3c8ef5a3d8fd7490dc3c-json.log",
        "Name": "/centos_v1",
        "RestartCount": 0,
        "Driver": "overlay2",
        "Platform": "linux",
        "MountLabel": "",
        "ProcessLabel": "",
        "AppArmorProfile": "",
        "ExecIDs": null,
        "HostConfig": {
            "Binds": null,
            "ContainerIDFile": "",
            "LogConfig": {
                "Type": "json-file",
                "Config": {}
            },
            "NetworkMode": "default",
            "PortBindings": {},
            "RestartPolicy": {
                "Name": "no",
                "MaximumRetryCount": 0
            },
            "AutoRemove": false,
            "VolumeDriver": "",
            "VolumesFrom": null,
            "CapAdd": null,
            "CapDrop": null,
            "CgroupnsMode": "host",
            "Dns": [],
            "DnsOptions": [],
            "DnsSearch": [],
            "ExtraHosts": null,
            "GroupAdd": null,
            "IpcMode": "private",
            "Cgroup": "",
            "Links": null,
            "OomScoreAdj": 0,
            "PidMode": "",
            "Privileged": false,
            "PublishAllPorts": false,
            "ReadonlyRootfs": false,
            "SecurityOpt": null,
            "UTSMode": "",
            "UsernsMode": "",
            "ShmSize": 67108864,
            "Runtime": "runc",
            "ConsoleSize": [
                0,
                0
            ],
            "Isolation": "",
            "CpuShares": 0,
            "Memory": 0,
            "NanoCpus": 0,
            "CgroupParent": "",
            "BlkioWeight": 0,
            "BlkioWeightDevice": [],
            "BlkioDeviceReadBps": null,
            "BlkioDeviceWriteBps": null,
            "BlkioDeviceReadIOps": null,
            "BlkioDeviceWriteIOps": null,
            "CpuPeriod": 0,
            "CpuQuota": 0,
            "CpuRealtimePeriod": 0,
            "CpuRealtimeRuntime": 0,
            "CpusetCpus": "",
            "CpusetMems": "",
            "Devices": [],
            "DeviceCgroupRules": null,
            "DeviceRequests": null,
            "KernelMemory": 0,
            "KernelMemoryTCP": 0,
            "MemoryReservation": 0,
            "MemorySwap": 0,
            "MemorySwappiness": null,
            "OomKillDisable": false,
            "PidsLimit": null,
            "Ulimits": null,
            "CpuCount": 0,
            "CpuPercent": 0,
            "IOMaximumIOps": 0,
            "IOMaximumBandwidth": 0,
            "MaskedPaths": [
                "/proc/asound",
                "/proc/acpi",
                "/proc/kcore",
                "/proc/keys",
                "/proc/latency_stats",
                "/proc/timer_list",
                "/proc/timer_stats",
                "/proc/sched_debug",
                "/proc/scsi",
                "/sys/firmware"
            ],
            "ReadonlyPaths": [
                "/proc/bus",
                "/proc/fs",
                "/proc/irq",
                "/proc/sys",
                "/proc/sysrq-trigger"
            ]
        },
        "GraphDriver": {
            "Data": {
                "LowerDir": "/docker/overlay2/119adbf51607bfc6fdfc8f30081b9263dc961d09400f1695527eb6b728b2209b-init/diff:/docker/overlay2/2386f591a659192e7d79caae80c3eb520db3d1120fbcd7970d9d6eb8fab10507/diff",
                "MergedDir": "/docker/overlay2/119adbf51607bfc6fdfc8f30081b9263dc961d09400f1695527eb6b728b2209b/merged",
                "UpperDir": "/docker/overlay2/119adbf51607bfc6fdfc8f30081b9263dc961d09400f1695527eb6b728b2209b/diff",
                "WorkDir": "/docker/overlay2/119adbf51607bfc6fdfc8f30081b9263dc961d09400f1695527eb6b728b2209b/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [],
        "Config": {
            "Hostname": "efcd72ea15a7",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "Tty": true,
            "OpenStdin": true,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "/bin/bash",
                "-c",
                "while true;do echo hello docker;sleep 10;done"
            ],
            "Image": "centos:latest",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {
                "org.label-schema.build-date": "20201204",
                "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": "0f3c7ccaebc706fb06f611ce07ce5c9a68c9ace1784a03af672f28bd3cc611d1",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {},
            "SandboxKey": "/var/run/docker/netns/0f3c7ccaebc7",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "ee962448e879bc5b001e3d77c04d0fa05c94aa6c9120e8e42b0705fab44c898f",
            "Gateway": "172.1.1.1",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "172.1.0.2",
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
            "MacAddress": "02:42:ac:01:00:02",
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "659b6c5dab2c8a0fd5058534fc195828865fc12d6e0388d47bf2a12118890998",
                    "EndpointID": "ee962448e879bc5b001e3d77c04d0fa05c94aa6c9120e8e42b0705fab44c898f",
                    "Gateway": "172.1.1.1",
                    "IPAddress": "172.1.0.2",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:01:00:02",
                    "DriverOpts": null
                }
            }
        }
    }
]

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209

2.7 提交容器为新镜像

假设我们运行了一个容器,并完成了修改,想要将其保存为一个镜像,在没有聊到dockerfile前,可以使用commit来实现

[root@node01 ~]# docker ps
CONTAINER ID   IMAGE           COMMAND                  CREATED          STATUS          PORTS     NAMES
efcd72ea15a7   centos:latest   "/bin/bash -c 'while…"   6 minutes ago    Up 6 minutes              centos_v1
3b1157fa7e1b   centos:latest   "/bin/bash"              10 minutes ago   Up 10 minutes             sharp_shaw

[root@node01 ~]# docker commit efcd72ea15a7 centos_while:v1
sha256:d11182ec9f08c11e57151f5005e6200432faf9da5563114fd9a6b7c7c0859af8

[root@node01 ~]# docker images
REPOSITORY     TAG        IMAGE ID       CREATED         SIZE
centos_while   v1         d11182ec9f08   5 seconds ago   209MB

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

2.8 停止容器

[root@node01 ~]# docker ps
CONTAINER ID   IMAGE           COMMAND                  CREATED          STATUS          PORTS     NAMES
efcd72ea15a7   centos:latest   "/bin/bash -c 'while…"   9 minutes ago    Up 9 minutes              centos_v1
3b1157fa7e1b   centos:latest   "/bin/bash"              13 minutes ago   Up 13 minutes             sharp_shaw

[root@node01 ~]# docker stop efcd72ea15a7
efcd72ea15a7

[root@node01 ~]# docker ps
CONTAINER ID   IMAGE           COMMAND       CREATED          STATUS          PORTS     NAMES
3b1157fa7e1b   centos:latest   "/bin/bash"   13 minutes ago   Up 13 minutes             sharp_shaw

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

2.9 启动容器

[root@node01 ~]# docker start efcd72ea15a7
efcd72ea15a7

[root@node01 ~]# docker ps
CONTAINER ID   IMAGE           COMMAND                  CREATED          STATUS          PORTS     NAMES
efcd72ea15a7   centos:latest   "/bin/bash -c 'while…"   10 minutes ago   Up 22 seconds             centos_v1
3b1157fa7e1b   centos:latest   "/bin/bash"              14 minutes ago   Up 14 minutes             sharp_shaw

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

2.10 删除容器

先停后删

[root@node01 ~]# docker ps
CONTAINER ID   IMAGE           COMMAND                  CREATED          STATUS          PORTS     NAMES
efcd72ea15a7   centos:latest   "/bin/bash -c 'while…"   10 minutes ago   Up 22 seconds             centos_v1
3b1157fa7e1b   centos:latest   "/bin/bash"              14 minutes ago   Up 14 minutes             sharp_shaw

[root@node01 ~]# docker stop efcd
efcd

[root@node01 ~]# docker rm efcd
efcd

[root@node01 ~]# docker ps
CONTAINER ID   IMAGE           COMMAND       CREATED          STATUS          PORTS     NAMES
3b1157fa7e1b   centos:latest   "/bin/bash"   15 minutes ago   Up 15 minutes             sharp_shaw

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

2.11 更新运行参数

如果容器已经运行起来,不便于重新运行一个新容器的情况下更新参数,可以使用docker update,但不是每一个参数都可以更新

# 查看下哪些参数可以被更新
[root@node01 ~]# docker update --help

Usage:  docker update [OPTIONS] CONTAINER [CONTAINER...]

Update configuration of one or more containers

Options:
      --blkio-weight uint16        Block IO (relative weight), between 10 and 1000,
                                   or 0 to disable (default 0)
      --cpu-period int             Limit CPU CFS (Completely Fair Scheduler) period
      --cpu-quota int              Limit CPU CFS (Completely Fair Scheduler) quota
      --cpu-rt-period int          Limit the CPU real-time period in microseconds
      --cpu-rt-runtime int         Limit the CPU real-time runtime in microseconds
  -c, --cpu-shares int             CPU shares (relative weight)
      --cpus decimal               Number of CPUs
      --cpuset-cpus string         CPUs in which to allow execution (0-3, 0,1)
      --cpuset-mems string         MEMs in which to allow execution (0-3, 0,1)
      --kernel-memory bytes        Kernel memory limit
  -m, --memory bytes               Memory limit
      --memory-reservation bytes   Memory soft limit
      --memory-swap bytes          Swap limit equal to memory plus swap: '-1' to
                                   enable unlimited swap
      --pids-limit int             Tune container pids limit (set -1 for unlimited)
      --restart string             Restart policy to apply when a container exits

# 简单的解释
--blkio-weight	阻塞IO (相对权重),介于10到1000之间,0表示禁用(默认禁止)
--cpu-period	限制CPU CFS(完全公平的调度程序)期限
--cpu-quota	限制CPU CFS(完全公平的调度程序)配额
--cpu-rt-period	API 1.25+,将CPU实时时间限制为微秒
--cpu-rt-runtime	API 1.25+,将CPU实时运行时间限制为微秒
--cpu-shares, -c	CPU份额(相对权重)
--cpus	API 1.29+,CPU数量
--cpuset-cpus	允许执行的CPU(0-3,0,1)
--cpuset-mem	允许执行的MEM(0-3,0,1)
--kernel-memory	内核内存限制
--memory-swap	交换限制等于内存加交换,“-1”以启用无限交换
--memory-reservatio	内存软限制
--memory, -m	内存限制
--pids-limit	API 1.40+,调节容器pids限制(-1表示无限制)
--restart	容器退出时重新启动策略以应用

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
# 更新下容器使其内存最高为 256M
[root@node01 ~]# docker ps
CONTAINER ID   IMAGE           COMMAND       CREATED       STATUS       PORTS     NAMES
3b1157fa7e1b   centos:latest   "/bin/bash"   2 hours ago   Up 2 hours             sharp_shaw

[root@node01 ~]# docker update -m 256M --memory-swap -1 3b11     # --momory-swap -1是因为docker 默认没有启用memory-swap交换内存,直接设置了内存问题会出问题,也就是说宿主 swap 支持使用多少则容器即可使用多少,将memory-swap 设置值为 -1,表示容器程序使用内存受限,而 swap 空间使用不受限制

[root@node01 ~]# docker inspect 3b11|grep -Ei "\"memory\""
            "Memory": 268435456,   # 已经生效

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

3、docker 镜像仓库

存放镜像文件的仓库,我们这里不演示公共仓库,如果想要使用公共仓库,直接打开公共仓库的页面,都会有配置提示,我们本文只演示本地仓库

docker使用Registry(注册中心)来保存镜像,常见的registry有公有私有两种,私有最常见的封装方案是 harbor

综上,这里先显示 harbor镜像仓库的搭建(作为私有仓库),然后再来演示仓库的登入登出等

harbor仓库直接运行于docker中,采用docker-compose部署,故部署也是极为简单

harbor的组件:

1、Proxy:反向代理工具

2、Registry:负责存储docker镜像,处理上传/下载命令。对用户进行访问控制,它指向一个token服务,强制用户的每次docker pull/push请求都要携带一个合法的token,registry会通过公钥对token进行解密验证。

3、Core service:Harbor的核心功能:

  • UI:图形界面
  • Webhook:及时获取registry上image状态变化情况,在registry上配置 webhook,把状态变化传递给UI模块。
  • Token服务:复杂根据用户权限给每个docker push/p/ull命令签发token。Docker客户端向registry服务发起的请求,如果不包含token,会被重定向到这里,获得token后再重新向registry进行请求。

4、Database:提供数据库服务,存储用户权限,审计日志,docker image分组信息等数据

5、Log collector:为了帮助监控harbor运行,复责收集其他组件的log,供日后进行分析

3.1 下载Harbor

harbor主机采用 192.168.1.110来安装,关于基础环境初始化及yum源此处不再演示,参照上文即可

浏览器访问:https://github.com/goharbor/harbor/releases 进行下载

# 创建一些目录,用于后续使用
[root@harbor ~]# mkdir /data/app -p
[root@harbor ~]# mkdir /data/docker
[root@harbor ~]# mkdir /data/harbor


# 安装一下docker
[root@harbor ~]# yum -y install docker-ce

# 配置docker
[root@harbor ~]# mkdir /etc/docker
[root@harbor ~]# vim /etc/docker/daemon.json
{
        "data-root": "/data/docker",
        "bip": "172.1.1.1/16",
        "storage-driver": "overlay2",
        "registry-mirrors": ["https://xxxxxxxxxxxxxxxx.mirror.aliyuncs.com"]
}

[root@harbor ~]# systemctl start docker
[root@harbor ~]# systemctl enable docker


# 下载harbor
[root@harbor /]# cd /data/app/
[root@harbor app]# wget https://github.com/goharbor/harbor/releases/download/v2.2.2/harbor-offline-installer-v2.2.2.tgz

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

3.2 安装docker-compose

harbor使用docker-compose部署,关于docker-compose的使用,后面再聊,现在先来安装下(可以直接下载,也可以使用 # pip install docker-compose -i http://mirrors.aliyun.com/pypi/simple/
–trusted-host mirrors.aliyun.com)

docker-compose下载地址:https://github.com/docker/compose/releases/

# 下载
[root@node01 app]# wget https://github.com/docker/compose/releases/download/1.29.2/docker-compose-Linux-x86_64

# 给予执行权限 
[root@harbor app]# cp docker-compose-Linux-x86_64 /usr/bin/docker-compose
[root@harbor app]# chmod 744 /usr/bin/docker-compose

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

3.3 安装harbor

[root@harbor app]# tar xf harbor-offline-installer-v2.2.2.tgz
[root@harbor app]# cd harbor
harbor/                              harbor-offline-installer-v2.2.2.tgz
[root@harbor app]# cd harbor
[root@harbor harbor]# ls
common.sh  harbor.v2.2.2.tar.gz  harbor.yml.tmpl  install.sh  LICENSE  prepare

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
# 修改配置文件
[root@harbor harbor]# cp -a harbor.yml.tmpl harbor.yml
[root@harbor harbor]# vim harbor.yml
hostname: harbor.local.top      # 本地IP或者域名,这里使用域名,但我们没有DNS,故此等下做下hosts解析
harbor_admin_password: 123456   # harbor管理员密码
database:
  password: 123456              # 数据库密码
data_volume: /data/harbor       # 存储目录
# 注释掉https
# https related config
#https:
#  # https port for harbor, default is 443
#  port: 443
#  # The path of cert and key files for nginx
#  certificate: /your/certificate/path
#  private_key: /your/private/key/path

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
# 做一下hosts解析,所有节点都要做,包括node1 node2
[root@harbor harbor]# echo "192.168.1.101    node01" >> /etc/hosts
[root@harbor harbor]# echo "192.168.1.102    node02" >> /etc/hosts
[root@harbor harbor]# echo "192.168.1.110    harbor" >> /etc/hosts
[root@harbor harbor]# echo "192.168.1.110    harbor.local.top" >> /etc/hosts

# 安装
[root@harbor harbor]# ./install.sh
[Step 0]: checking if docker is installed ...
Note: docker version: 20.10.7                  # 成功读取docker版本
[Step 1]: checking docker-compose is installed ...
Note: docker-compose version: 1.29.2           # 成功读取docker-compose版本
......
[Step 5]: starting Harbor ...
Creating network "harbor_harbor" with the default driver
Creating harbor-log ... done
Creating registry      ... done
Creating harbor-portal ... done
Creating harbor-db     ... done
Creating registryctl   ... done
Creating redis         ... done
Creating harbor-core   ... done
Creating nginx             ... done
Creating harbor-jobservice ... done
✔ ----Harbor has been installed and started successfully.----


# 查看启动了哪些容器
[root@harbor harbor]# docker-compose ps           # 注意docker-compose命令,只能于docker-compose项目目录下执行
      Name                    Command                State                 Ports
-------------------------------------------------------------------------------------------
harbor-core         /harbor/entrypoint.sh         Up (healthy)
harbor-db           /docker-entrypoint.sh         Up (healthy)
harbor-jobservice   /harbor/entrypoint.sh         Up (healthy)
harbor-log          /bin/sh -c /usr/local/bin/    Up (healthy)   127.0.0.1:1514->10514/tcp
                    ...
harbor-portal       nginx -g daemon off;          Up (healthy)
nginx               nginx -g daemon off;          Up (healthy)   0.0.0.0:80->8080/tcp,:::80
                                                                 ->8080/tcp
redis               redis-server                  Up (healthy)
                    /etc/redis.conf
registry            /home/harbor/entrypoint.sh    Up (healthy)
registryctl         /home/harbor/start.sh         Up (healthy)


[root@harbor harbor]# docker ps
CONTAINER ID   IMAGE                                COMMAND                  CREATED              STATUS                        PORTS                                   NAMES
be460fb4cb9b   goharbor/harbor-jobservice:v2.2.2    "/harbor/entrypoint.…"   About a minute ago   Up About a minute (healthy)                                           harbor-jobservice
9de4a1ca6be0   goharbor/nginx-photon:v2.2.2         "nginx -g 'daemon of…"   About a minute ago   Up About a minute (healthy)   0.0.0.0:80->8080/tcp, :::80->8080/tcp   nginx
91ce9201ea03   goharbor/harbor-core:v2.2.2          "/harbor/entrypoint.…"   2 minutes ago        Up About a minute (healthy)                                           harbor-core
abe2e68cee15   goharbor/redis-photon:v2.2.2         "redis-server /etc/r…"   2 minutes ago        Up 2 minutes (healthy)                                                redis
96fdb49b29d9   goharbor/harbor-registryctl:v2.2.2   "/home/harbor/start.…"   2 minutes ago        Up About a minute (healthy)                                           registryctl
d978e8fc6d75   goharbor/harbor-portal:v2.2.2        "nginx -g 'daemon of…"   2 minutes ago        Up 2 minutes (healthy)                                                harbor-portal
55c2bbadcc3e   goharbor/registry-photon:v2.2.2      "/home/harbor/entryp…"   2 minutes ago        Up 2 minutes (healthy)                                                registry
0bb8c40cea5c   goharbor/harbor-db:v2.2.2            "/docker-entrypoint.…"   2 minutes ago        Up 2 minutes (healthy)                                                harbor-db
fd34d2af91e8   goharbor/harbor-log:v2.2.2           "/bin/sh -c /usr/loc…"   2 minutes ago        Up 2 minutes (healthy)        127.0.0.1:1514->10514/tcp 

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57

3.4 harbor基本使用

因为都是图形化的,所以不多赘述,只说下怎么创建仓库

harbor的访问,使用浏览器输入harbor节点的IP:port或者域名即可

在这里插入图片描述

创建一个私有仓库(私有项目)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.5 登录私有仓库并推送镜像

# node1节点先确认做一下hosts解析
[root@node01 ~]# echo "192.168.1.101    node01" >> /etc/hosts
[root@node01 ~]# echo "192.168.1.102    node02" >> /etc/hosts
[root@node01 ~]# echo "192.168.1.110    harbor" >> /etc/hosts
[root@node01 ~]# echo "192.168.1.110    harbor.local.top" >> /etc/hosts

# 登录私有仓库
因为我们这里没有使用https进行通信,所以还需要给docker配置下http不安全通信
[root@node01 ~]# vim /etc/docker/daemon.json
{
			# 追加
        "insecure-registries": ["harbor.local.top"]
}

[root@node01 ~]# systemctl daemon-reload
[root@node01 ~]# systemctl restart docker


# 登录私有仓库
[root@node01 ~]# docker login harbor.local.top
Username: admin
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See  # 这句警告是说你的密码会不安全的存储在/root/.docker/config.json中。配置凭据助手可以去掉这个警告
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded


# 推送镜像到私有仓库
在推送前,需要先给本地的镜像打标签,以符合harbor中的项目路径
[root@node01 ~]# docker images
REPOSITORY     TAG        IMAGE ID       CREATED        SIZE
centos_while   v1         d11182ec9f08   3 hours ago    209MB
......

[root@node01 ~]# docker tag centos_while:v1 harbor.local.top/images/centos_while:v1

推送
[root@node01 ~]# docker push harbor.local.top/images/centos_while:v1
The push refers to repository [harbor.local.top/images/centos_while]
6ecc5281cd8d: Pushed
2653d992f4ef: Pushing  85.67MB/209.3MB

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

在这里插入图片描述

3.6 登出仓库

[root@node01 ~]# docker logout harbor.local.top
Removing login credentials for harbor.local.top

  • 1
  • 2
  • 3

4、运行一个应用容器

接下来我们来实际运行一个应用容器

以nginx为例

4.1 规划好应用容器的配置

运行容器前,除非是不重要的测试环境,否则一定要考虑好该容器的 端口 存储 等等信息后再运行

如果是官方镜像,那么这个容器有哪些参数可以被配置,都会写的很清晰,比如前往dockerhub网站,阅读容器的文档

此处,我以nginx容器为例

打开 https://registry.hub.docker.com/_/nginx

在这里插入图片描述

如上,可以看到官方会给出很多运行参数的示例

此处规划的参数如下:
-p 8001:80           # -p 映射端口,8001为宿主机端口,80为容器内端口
-v /data/docker/nginx/html:/usr/share/nginx/html   # -v 挂载卷,/data/docker/nginx/html是宿主机目录,/usr/share/nginx/html是容器内目录,这个挂载用于实现html目录的挂载
--name 8001   # 设置容器名
-v /data/docker/nginx/nginx.conf:/etc/nginx/nginx.conf:ro   # -v不仅可以挂载目录,也可以挂载单个文件,这里就是挂载的配置文件,ro是只读,默认是rw
--restart=always     # 重启策略为任何状态自动重启

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

既然做好了规划,那么下面就把规划的内容准备好

# 创建挂载卷的宿主机目录
[root@node01 ~]# mkdir /data/docker/nginx/html -p
# 准备html目录下的index.html测试文件
[root@node01 ~]# echo "nginx docker test" >> /data/docker/nginx/html/index.html
# 准备要被挂载进去的nginx.conf配置文件
[root@node01 ~]# vim /data/docker/nginx/nginx.conf
user  nginx;
worker_processes  auto;
error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;
events {
    worker_connections  1024;
}
http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  /var/log/nginx/access.log  main;
    sendfile        on;
    #tcp_nopush     on;
    keepalive_timeout  65;
    gzip  on;
    include /etc/nginx/conf.d/*.conf;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

4.2 运行nginx容器

# 拉取镜像
[root@node01 ~]# docker pull nginx

# 运行
[root@node01 ~]# docker run -d --name="nginx_8001" -v /data/docker/nginx/html:/usr/share/nginx/html -v /data/docker/nginx/nginx.conf:/etc/nginx/nginx.conf -p 8001:80 --restart=always nginx:latest
c410430dc13d7d27a2ed7b41ee8f40ddedac54a2afe0d753d044d6718836643a

# 查看启动后的状态
[root@node01 ~]# docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS          PORTS                                   NAMES
c410430dc13d   nginx:latest   "/docker-entrypoint.…"   19 seconds ago   Up 18 seconds   0.0.0.0:8001->80/tcp, :::8001->80/tcp   nginx_8001

# 查看宿主机端口
[root@node01 ~]# ss -naltp|grep 8001
LISTEN     0      128          *:8001                     *:*                   users:(("docker-proxy",pid=93384,fd=4))
LISTEN     0      128       [::]:8001                  [::]:*                   users:(("docker-proxy",pid=93389,fd=4))

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

测试访问

[root@harbor harbor]# curl node01:8001
nginx docker test

  • 1
  • 2
  • 3

测试自动重启策略

[root@node01 ~]# systemctl restart docker
[root@node01 ~]# docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED         STATUS        PORTS                                   NAMES
c410430dc13d   nginx:latest   "/docker-entrypoint.…"   2 minutes ago   Up 1 second   0.0.0.0:8001->80/tcp, :::8001->80/tcp   nginx_8001

  • 1
  • 2
  • 3
  • 4
  • 5

4.4 容器的数据卷

这里简单介绍下数据卷的挂载

在上面我们采用-V参数,挂载了数据存储目录到容器内,实际上这就是数据卷,数据卷主要解决的是数据持久化到宿主机且宿主机与容器间数据同步

挂载数据卷做持久化在绝大多数时候都是是必要的,毕竟容器可以被随意删除,一旦容器崩溃或者被删除掉,数据就丢失了。

另外多提一句,一般情况下,不建议在容器里运行有状态服务,比如mysql redis等,主要也是数据丢失的风险

5、docker的网络模式

docker本地共有四种网络模型,分别为 bridge,host,none,container

# 查看docker 网络
[root@node01 ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
95ab2996b951   bridge    bridge    local
ff9ddd83a44a   host      host      local
3ab59d75c16c   none      null      local

# 查看容器使用的网络模式
[root@node01 ~]# docker inspect c410

# 创建一个网络
	# 以创建一个新的briage网络 bridge_test1 为例
[root@node01 ~]# docker network create -d bridge --subnet "10.1.1.1/24" --gateway="10.1.1.254" briage_test1
2bdd140c3dfb69e0942d93a8416628d4c0cdd77b1e2437ff446e1b658aaaf0bb

[root@node01 ~]# docker network ls
NETWORK ID     NAME           DRIVER    SCOPE
2bdd140c3dfb   briage_test1   bridge    local    新创建的网络
95ab2996b951   bridge         bridge    local
ff9ddd83a44a   host           host      local
3ab59d75c16c   none           null      local

# 删除一个网络
[root@node01 ~]# docker network rm briage_test1
briage_test1
[root@node01 ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
95ab2996b951   bridge    bridge    local
ff9ddd83a44a   host      host      local
3ab59d75c16c   none      null      local

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

5.1 Bridge桥接网络

默认情况下,docker即使用bridge桥接网络,这个桥接和我们日常理解的桥接不同,它更像是我们在虚拟机中使用的NAT网络。

当宿主机存在多块网卡时,可以通过brctl命令将指定的物理网卡桥接到docker0上

当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。

[root@node01 ~]# ifconfig docker0
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.1.1.1  netmask 255.255.0.0  broadcast 172.1.255.255
        inet6 fe80::42:4aff:fece:f9d1  prefixlen 64  scopeid 0x20<link>
        ether 02:42:4a:ce:f9:d1  txqueuelen 0  (Ethernet)
        RX packets 12  bytes 1100 (1.0 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 17  bytes 1267 (1.2 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0


[root@node01 ~]# route -n | grep docker0
172.1.0.0       0.0.0.0         255.255.0.0     U     0      0        0 docker0

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

从docker0子网中分配一个IP给容器使用,并设置docker的IP地址为容器的默认网关,在主机上创建一对虚拟网卡veth pair设备,docker将veth pair设备的一端放在容器中,并以eth0命名,一端放在宿主机中,以vethxxx命名,并且将这个网络加入到docker0网桥中,可以通过 # brctl show 命令查看(没有brctl安装下 # yum install bridge-utils -y)

# 起个容器
[root@node01 ~]# docker run -itd --name="centos_test1" centos:7.9.2009 /bin/bash
55124e99e88f2da9f61a927eb301ef43e043eb9eb862579d894ce8903a31e2e8
[root@node01 ~]# docker ps
CONTAINER ID   IMAGE             COMMAND                  CREATED         STATUS         PORTS                                   NAMES
55124e99e88f   centos:7.9.2009   "/bin/bash"              6 seconds ago   Up 6 seconds                                           centos_test1


# 查看容器内网卡名
[root@node01 ~]# docker exec -it 5512 /bin/bash
[root@55124e99e88f /]# yum -y install net-tools
[root@55124e99e88f /]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.1.0.2  netmask 255.255.0.0  broadcast 172.1.255.255
        ether 02:42:ac:01:00:02  txqueuelen 0  (Ethernet)
        RX packets 3877  bytes 16524721 (15.7 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 3223  bytes 178107 (173.9 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
......


# 查看宿主机内网卡名
[root@node01 ~]# ip a
17: veth48645da@if16: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
    link/ether 0a:45:b9:c9:ea:2c brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::845:b9ff:fec9:ea2c/64 scope link
       valid_lft forever preferred_lft forever
......



# 网桥控制器查看
[root@node01 ~]# brctl show
bridge name     bridge id               STP enabled     interfaces
docker0         8000.02424acef9d1       no              veth48645da

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

bridge模式是docker的默认网络模式,不写–net参数,就是bridge模式。使用docker run -p时,docker实际是在iptables做了DNAT规则,实现端口转发功能。可以使用 # iptables -t nat -vnL查看。

5.2 Host宿主机共享网络

如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。

使用host模式的容器可以直接使用宿主机的IP地址与外界通信,容器内部的服务端口也可以使用宿主机的端口,不需要进行NAT,host最大的优势就是网络性能比较好,但是docker host上已经使用的端口就不能再用了,网络的隔离性不好。

启动容器时使用host网络

–net=host 参数

以nginx镜像为例,nginx镜像默认使用80端口,我们来验证下

# 查看下宿主机80端口没有冲突
[root@node01 ~]# ss -naltp|grep 80

# 使用 --net=host 来指定使用host网络模式
[root@node01 ~]# docker run -d --net=host --name="nginx_host_test1" nginx:latest
b908023b773f1a5163cc8cf91864c3684f546e937159396fdaa0e9a81d39b29b
[root@node01 ~]# docker ps
CONTAINER ID   IMAGE             COMMAND                  CREATED          STATUS          PORTS                                   NAMES
b908023b773f   nginx:latest      "/docker-entrypoint.…"   5 seconds ago    Up 4 seconds                                            nginx_host_test1

# 再来查看下宿主机中的端口
[root@node01 ~]# ss -naltp|grep 80
LISTEN     0      128          *:80                       *:*                   users:(("nginx",pid=107305,fd=7),("nginx",pid=107304,fd=7),("nginx",pid=107262,fd=7))
LISTEN     0      128       [::]:80                    [::]:*                   users:(("nginx",pid=107305,fd=8),("nginx",pid=107304,fd=8),("nginx",pid=107262,fd=8))
可以看到,80端口直接出现在了宿主机中


# 直接访问下
[root@node01 ~]# curl localhost:80
<!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>
......

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

5.3 None无外部网络

用none模式,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等。

这种网络模式下容器只有lo回环网络,没有其他网卡。none模式可以在容器创建时通过–network=none来指定。这种类型的网络没有办法联网,封闭的网络能很好的保证容器的安全性。

通过 --net=none参数指定

# 运行时指定--net=none
[root@node01 ~]# docker run -itd --net=none --name="centos7.9_none_test1" centos:7.9.2009 /bin/bash
e81b1e6ca20d9d3469dcfe4876e7828099167ba5731a7fcb60c5d0b0d686293a
[root@node01 ~]# docker ps
CONTAINER ID   IMAGE             COMMAND                  CREATED          STATUS          PORTS                                   NAMES
e81b1e6ca20d   centos:7.9.2009   "/bin/bash"              4 seconds ago    Up 2 seconds                                            centos7.9_none_test1


# 查看下网络设备
[root@node01 ~]# docker exec -it e81b /bin/bash
[root@e81b1e6ca20d /]# cat /proc/net/dev
Inter-|   Receive                                                |  Transmit
 face |bytes    packets errs drop fifo frame compressed multicast|bytes    packets errs drop fifo colls carrier compressed
    lo:       0       0    0    0    0     0          0         0        0       0    0    0    0     0       0          0
可以看到,只有一个lo网络

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

5.4 container容器共享(依附)网络

这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo 网卡设备通信。

–net=container:被依附的容器名

# 先启动一个新的容器,命名为 centos_container_test1
[root@node01 ~]# docker run -itd --name  centos_container_test1 centos:7.9.2009 /bin/bash
49595449fb50b82625af2c08745e2597853af450a98973b477020bf442f61c9c


# 在启动一个容器,启动时指定网络为container并依附到 centos_container_test1
[root@node01 ~]# docker run -itd --name centos_container_test2 --net=container:centos_container_test1 centos:7.9.2009 /bin/bash
ca27254e32512c5c5ec095f590d5c627c91ff08a3c8a00e4bf0628479ba549c9

# 查看网络是否相同
[root@node01 ~]# docker exec -it centos_container_test1 /bin/bash
[root@49595449fb50 /]# yum -y install net-tools
[root@49595449fb50 /]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.1.0.3  netmask 255.255.0.0  broadcast 172.1.255.255
        ether 02:42:ac:01:00:03  txqueuelen 0  (Ethernet)
        RX packets 4075  bytes 16535781 (15.7 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 3213  bytes 177825 (173.6 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
......
[root@node01 ~]# docker exec -it centos_container_test2 /bin/bash
[root@49595449fb50 /]# yum -y install net-tools
[root@49595449fb50 /]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.1.0.3  netmask 255.255.0.0  broadcast 172.1.255.255
        ether 02:42:ac:01:00:03  txqueuelen 0  (Ethernet)
        RX packets 6926  bytes 33005634 (31.4 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 5632  bytes 312908 (305.5 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
......

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

附:批量停止及删除容器

前面实验开启了非常多的容器,怎么一次全停止并删除

# 停
[root@node01 ~]# docker stop $(docker ps -q)
ca27254e3251
49595449fb50
e81b1e6ca20d
b908023b773f
55124e99e88f
c410430dc13d


# 删
[root@node01 ~]# docker rm $(docker ps -aq)
ca27254e3251
49595449fb50
e81b1e6ca20d
b908023b773f
55124e99e88f
c410430dc13d
3b1157fa7e1b
36a3d9354ba4
[root@node01 ~]# docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

五、DockerFile 构建镜像

构建镜像除了前面提到的docker commit,还有dockerfile。实际真正使用的也是dockerfile

Dockerfile把构建镜像的步骤都写出来,然后按顺序执行实现自动构建镜像,就像ansible的playbook类似,也类似于使用pom去构建maven项目…

dockerfile的组成模块

关键字模块
FROM基础镜像信息
MAINTAINER维护者信息
RUN COPY ADD USER WORKDIR VOLUME EXPOSE…容器操作
CMD ENTRYPOINT启动操作

1、dockerfile关键字(指令)

1.1 FROM

指定以哪个镜像为基础镜像

# 比如以centos为基础镜像
FROM centos:7.9.2009

  • 1
  • 2
  • 3

1.2 MAINTAINER

指定镜像维护者信息

# 比如指定维护者及邮件
MAINTAINER "systemctl529_yu" "systemctlxxxxxx@163.com" 

  • 1
  • 2
  • 3

1.3 RUN

用于在构建镜像中执行命令,比如安装一些软件、配置一些基础环境,可使用\来换行或者用 && 连续执行,尽量减少多行RUN*(一个RUN一层)*

# 两种语法:
1. shell格式
RUN yum -y install nginx && echo "test web" >> /usr/share/nginx/html/index.html
RUN echo "hello docker" \
	/usr/share/nginx/html/index.html


2. exec格式
RUN ["命令", "参数1", "参数2"]
RUN ["yum","-y","install","nginx"]

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

1.4 COPY

将主机的文件复制到镜像内,如果目的位置不存在,Docker会自动创建所有需要的目录结构,但是它只是单纯的复制,并不会去做文件提取和解压工作。

需要复制的目录一定要放在Dockerfile文件的同级目录下

# 拷贝配置文件到容器中
COPY nginx.conf /etc/nginx

  • 1
  • 2
  • 3

1.5 ADD

将主机的文件复制到镜像中,跟COPY一样,限制条件和使用方式都一样,也是需要在dockerfile的同级目录中。

ADD会对压缩文件(tar, gzip, bzip2, etc)做提取和解压操作

# 拷贝html.tar到容器中
ADD HTML.tar /usr/share/nginx/html

  • 1
  • 2
  • 3

1.6 EXPOSE

暴露镜像的端口供主机做映射,启动镜像时,使用-P参数来将镜像端口与宿主机的随机端口做映射。(可指定多个)

docker run时,还需 -p 参数指定内外端口

EXPOSE 指令是声明运行时容器提供服务端口,这只是一个声明,在运行时并不会因为这个声明应用就会开启这个端口的服务。在 Dockerfile 中写入这样的声明有两个好处,一个是帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射;另一个用处则是在运行时使用随机端口映射时,也就是 docker run -P时,会自动随机映射 EXPOSE 的端口

EXPOSE 80 81 82 ...

  • 1
  • 2

1.7 ENV

ENV指令用于指定一个环境变量

当使用生成的镜像运行容器时,使用 ENV 设置的环境变量将持久存在于容器内,如果仅仅要在构建过程中使用变量,可以 RUN MY_NAME=“systemctl529_yu”,或者用ARG MY_NAME="systemctl529_yu"

# ENV <key> <value> 或者 ENV <key>=<value>
ENV JAVA_HOME /usr/local/openjdk/bin
ENV MY_NAME="systemctl529_yu" MY_JOB="OPS"

  • 1
  • 2
  • 3
  • 4

1.8 WORKDIR

在构建镜像时,指定镜像的工作目录,之后的命令都是基于此工作目录,如果不存在,则会创建目录

WORKDIR /usr/share/nginx/html
RUN echo 'hello docker' > text.txt   # 这样就会在容器的/usr/share/nginx/html/text.txt文件写入 “hello docker”

  • 1
  • 2
  • 3

1.9 ONBUILD

为他人做嫁衣,做基础镜像使用

ONBUILD 是一个特殊的指令,它后面跟的是其它指令,比如 RUN, COPY 等,而这些指令,在当前镜像构建时并不会被执行。只有当以当前镜像为基础镜像,去构建下一级镜像的时候才会被执行。

Dockerfile 中的其它指令都是为了定制当前镜像而准备的,唯有 ONBUILD 是为了帮助别人定制自己而准备的。比如我们需要一个java镜像跑jar包,每次都创建一个jre环境太麻烦,所以就可以先创建个基础镜像,然后每次放不同jar进去做新的镜像

语法格式为 :ONBUILD <其它指令>

# 创建基础镜像image1
FROM openjdk
RUN mkdir /APP
ONBUILD COPY xxxxx.jar /APP 
WORKDIR /APP
CMD java -jar xxxxx.jar

# 基于基础镜像1创建镜像image2
FROM image1       # 似的,没看错,就这一行,其会调用image1中的ONBUILD

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

1.10 USER

指定该镜像以哪个用户去执行(比如以hadoop用户执行hadoop)

如果设置了容器以XXXXX用户去运行,那么RUN,CMD和ENTRYPOINT都会以这个用户去运行
镜像构建完成后,通过docker run运行容器时,可以通过-u参数来覆盖所指定的用户

USER XXXX

  • 1
  • 2

1.11 VOLUME

用来向基于镜像创建的容器添加卷。比如你可以将mongodb镜像中存储数据的data文件指定为宿主机的某个文件。(容器内部建议不要存储任何数据),如果只指定挂载点,docker宿主机映射的目录会自动生成。

# VOLUME 宿主机目录 容器内目录
或者
# VOLUME 容器目录

VOLUME /data/nginx/html /usr/share/nginx/html

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

1.12 CMD

容器启动时需要执行的命令

CMD不同于RUN,CMD用于指定在容器启动时所要执行的命令,而RUN用于指定镜像构建时所要执行的命令

每个Dockerfile只能有一条CMD命令。如果指定了多条命令,只有最后一条会被执行,同时CMD可以被docker run 时指定的运行命令覆盖

# 两种语法
1. exec写法
CMD ["命令","参数1","参数2"]

CMD ["/bin/bash"]

2. shell写法
CMD 命令 参数1 参数2

CMD /bin/bash

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

1.13 ENTRYPOINT

用法和功能与CMD一致

ENTRYPOINT指定的命令不会被docker run覆盖,但会把docker run后的命令当做 ENTRYPOINT指定命令的参数,如果dockerfile中同时有CMD和ENTRYPOINT,那么CMD也会被ENTRYPOINT当做执行命令的参数

# 两种语法
1. exec写法
ENTRYPOINT ["命令","参数1","参数2"]

ENTRYPOINT ["/bin/bash"]

2. shell写法
ENTRYPOINT 命令 参数1 参数2

ENTRYPOINT /bin/bash

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

2 实际写几个

build创建镜像时,需要在命令后写一个 . 这个 . 代表当前目录上下文(当前目录及当前目录下的子目录)

2.1 写个nginx的先
[root@node01 ~]# mkdir /data/dockerfile -p
[root@node01 ~]# cd /data/docker
[root@node01 docker]# mkdir nginx_dockerfile
[root@node01 docker]# cd nginx_dockerfile/
[root@node01 nginx_dockerfile]#


# 以centos为基础镜像,写一个nginx的容器
[root@node01 nginx_dockerfile]# vim nginx_dockerfile
FROM centos:latest
MAINTAINER "systemctl529_yu" "xxxxxxx.163.com"
RUN yum -y install nginx
COPY index.html /usr/share/nginx/html
COPY nginx.conf /etc/nginx
EXPOSE 80
CMD nginx -g "daemon off;"



# 准备好dockerfile中定义的文件
[root@node01 nginx_dockerfile]# echo "dockerfile_nginx_test1" >> index.html
[root@node01 nginx_dockerfile]# vim nginx.conf
user  nginx;
worker_processes  auto;
error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;
events {
    worker_connections  1024;
}
http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  /var/log/nginx/access.log  main;
    sendfile        on;
    #tcp_nopush     on;
    keepalive_timeout  65;
    gzip  on;
    include /etc/nginx/conf.d/*.conf;
    server {
        listen       80 default_server;
        server_name  _;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
        }

        error_page 404 /404.html;
        location = /404.html {
        }

        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
        }
    }

}


# build构建镜像
[root@node01 nginx_dockerfile]# docker build -f nginx_dockerfile -t nginx_dockerfile:test1 .
Sending build context to Docker daemon  4.608kB
Step 1/7 : FROM centos:latest
 ---> 300e315adb2f
Step 2/7 : MAINTAINER "systemctl529_yu" "xxxxxxx.163.com"
 ---> Running in 00ba4060520f
Removing intermediate container 00ba4060520f
 ---> 1b3338ca9f72
Step 3/7 : RUN yum -y install nginx
......
Step 4/7 : COPY index.html /usr/share/nginx/html
 ---> 97379c724a8d
Step 5/7 : COPY nginx.conf /etc/nginx
 ---> 23b118c3271d
Step 6/7 : EXPOSE 80
 ---> Running in 4b14485d0bcd
Removing intermediate container 4b14485d0bcd
 ---> f88b7595fefa
Step 7/7 : CMD nginx -g "daemon off;"
 ---> Running in 1df3be4f8e69
Removing intermediate container 1df3be4f8e69
 ---> 3a7c2ca9c867
Successfully built 3a7c2ca9c867
Successfully tagged nginx_dockerfile:test1


[root@node01 nginx_dockerfile]# docker images | grep nginx_dockerfile
nginx_dockerfile   test1      3a7c2ca9c867   About a minute ago   313MB


# 运行个容器试试
[root@node01 nginx_dockerfile]# docker run -d --name="nginx_dockerfile_test1_8001" -p 8001:80 nginx_dockerfile:test1
9c483dccd5e657006d46b60dc04422eb138b8050552b2358c1889a345392a477

[root@node01 nginx_dockerfile]# curl localhost:8001
dockerfile_nginx_test1

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102

2.2 写个tomcat的

[root@node01 docker]# mkdir /data/docker/tomcat_dockerfile
[root@node01 docker]# cd /data/docker/tomcat_dockerfile/

[root@node01 tomcat_dockerfile]# vim tomcat_dockerfile
# 这里没有war包演示,所以就用tomcat默认页面了,实际使用,可以使用 RUN rm -rf /usr/local/tomcat/webapps/*删除掉自带的项目,然后CPOY进WAR包
FROM adoptopenjdk/openjdk8:ubi
MAINTAINER "systemctl529_yu" "xxxxxxx.163.com"
ADD apache-tomcat-9.0.14.tar.gz /usr/local
EXPOSE 8080
CMD /usr/local/apache-tomcat-9.0.14/bin/catalina.sh run


# 下载好tomcat到当前目录
[root@node01 tomcat_dockerfile]# ls
apache-tomcat-9.0.14.tar.gz  tomcat_dockerfile


# build构建
[root@node01 tomcat_dockerfile]# docker build -f tomcat_dockerfile -t tomcat_dockerfile:test1 .

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

至于jar包的,更简单,比如

FROM adoptopenjdk/openjdk8:ubi
RUN mkdir /opt/app
COPY xxxxxxx.jar /opt/app
CMD ["java", "-jar", "/opt/app/xxxxxxx.jar"]

  • 1
  • 2
  • 3
  • 4
  • 5
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/73978
推荐阅读
相关标签
  

闽ICP备14008679号