Docker详述-安装/使用/docker-compose/harbor私有库
目录
- Docker前言
- 在 CentOS 系统上安装 Docker
- Docker镜像
- Docker 容器
- Docker网络
- Dockerfile构建镜像
- Docker-compose容器编排工具
- Harbor私有仓库
Docker前言
1、Docker简介
传统运维可能会遇到的问题:
1、机器很多但是版本各异:使用自动化运维工具(Ansible)来避免不同型号,不同版本导致的服务器之间的命令的不同。但是自动化运维工具也伴随这这些问题:当系统不支持时,自动化运维工具无法解决;当大规模应用需要部署时,无法解决稳定运行的问题。
2、这时候就考虑到以下功能的实现:将编写好了的软件进行打包,如果需要运行的时候,直接运行安装包即可实现服务稳定运行。如果出现服务运行宕机等不稳定现象时,将自动重启直至服务稳定运行。实现这一功能的软件有两个,打包的软件叫作:Docker;实现自动化部署和运行的软件叫作:kubernetes。
3、打包的过程叫作虚拟化,虚拟化的发展史:
● 20世纪90年代的时候,Linux操作系统中为了解决多进程之间的相互隔离的问题,创建出了一个systemd的虚拟化
● 21世纪初,提出了操作系统软件虚拟化。
● 21世纪10年代初,Google的一个科学家发布了一篇关于软件虚拟化的论文。
● 2013年,有一个dotCloud公司,开发出了一款叫作Docker的虚拟化软件。
● 2014年,Google公司推出了一款容器管理软件:kubernetes
4、至此,容器化可以落地并且实现规模化。
# 在Docker中,有三个核心概念,分别是:镜像、容器以及仓库。
1.镜像:在Docker中,部署的所有的应用都必须打包成一个镜像。也就是说镜像就是我们将软件打包之后的安装包。
2.容器:容器是镜像运行之后的一个实例。实质上,容器就是一个进程。容器可以被创建、启动、停止、删除、暂停等。
3.仓库:仓库是用来存放镜像的地方。当我们构建好自己的镜像之后,需要存放在仓库中,当我们需要启动一个镜像时,可以在仓库中下载下来。
# Docker 是一个开源项目,诞生于 2013 年初,最初是 dotCloud 公司内部的一个业余项目。它基于 Google公司推出的 Go 语言实现。 项目后来加入了 Linux 基金会,遵从了 Apache 2.0 协议,项目代码在 GitHub 上进行维护。Docker 自开源后受到广泛的关注和讨论,以至于 dotCloud 公司后来都改名为 Docker Inc。Redhat已经在其 RHEL6.5 中集中支持 Docker;Google 也在其 PaaS 产品中广泛应用。Docker 项目的目标是实现轻量级的操作系统虚拟化解决方案。 Docker 的基础是 Linux 容器(LXC)等技术。在 LXC 的基础上 Docker进行了进一步的封装,让用户不需要去关心容器的管理,使得操作更为简便。用户操作 Docker 的容器就像操作一个快速轻量级的虚拟机一样简单。Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。
2、为什么要用Docker
2.1 Docker 容器虚拟化的好处
在云时代,开发者创建的应用必须要能很方便地在网络上传播,也就是说应用必须脱离底层物理硬件的限制;同时必须满足“任何时间任何地点”可获取可使用的特点。因此,开发者们需要一种新型的创建分布式应用程序的方式,快速分发部署,而这正是 Docker 所能够提供的最大优势。Docker 提供了一种更为聪明的方式,通过容器来打包应用、解耦应用和运行平台。这意味着迁移的时候,只需要在新的服务器上启动需要的容器就可以了,无论新旧服务器是否是同一类别的平台。这无疑帮助我们节约了大量的宝贵时间,并降低部署过程出现问题的风险。
2.2 Docker 在开发和运维中的优势
对于开发和运维人员来说,最梦寐以求的效果可能就是一次创建和配置,之后可以在任意地方、任意时间让应用正常运行,而 Docker 恰恰可以实现这一中级目标。具体来说,在开发和运维过程中,Docker 具有以下几个方面的优势:
1.更快的交付和部署:使用 Docker,开发人员可以使用镜像来快速构建一套标准的开发环境;开发完之后,测试和运维人员可以直接使用完全相同的环境来部署代码。只要是开发测试过的代码,就可以确保在生产环境无缝运行。Docker 可以快速创建和删除容器,实现快速迭代,节约开发、测试及部署的时间。
2.更高效的利用资源:运行 Docker 容器不需要额外的虚拟化管理程序的支持,Docker 是内核级的虚拟化,可以实现更高的性能,同时对资源的额外需求很低,与传统的虚拟机方式相比,Docker 的性能要提高 1 ~ 2 个数量级。
3.更轻松的迁移和扩展:Docker 容器几乎可以在任意的平台上运行,包括物理机、虚拟机、公有云、私有云、个人电脑等等,同时支持主流的操作系统发行版本。这种兼容性能让用户可以在不同的平台之间轻松的迁移应用。
4.更轻松的管理和更新:使用 Dockerfile,只需要小小的配置修改,就可以替代以往大量的更新工作。所有的修改都以增量的方式被分发和更新,从而实现自动化并且高效的容器管理。
2.3 Docker 与虚拟机的比较
Docker可以说是一个依赖于Linux虚拟化的容器软件。它是由dotClound公司使用Golang语言在2013年初开发的。后来加入了Linux基金会,遵循Apache 2.0协议同时将源代码开源至GitHub上。
# 容器中的数据无法永久保存,但是虚拟机中的数据可以永久保存。
在 CentOS 系统上安装 Docker
Docker 目前支持 CentOS 7 及以后版本。系统的要求跟 Ubuntu 情况类似,64 位操作系统,内核至少是 3.10
以上。
1.1 更换系统 yum 源
# 查看系统内核版本
[root@mysql01 ~]# uname -a
Linux mysql01 3.10.0-1160.el7.x86_64 #1 SMP Mon Oct 19 16:18:59 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
# 备份原来 yum 源
[root@mysql01 ~]# cp /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak
# 更换 yum 源
[root@mysql01 ~]# curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
# 刷新 yum 源缓存
[root@mysql01 ~]# yum makecache
1.2 更新系统
[root@mysql01 ~]# yum update -y --exclud=kernel*
1.3 安装所需的基础软件
[root@mysql01 ~]# yum install -y yum-utils device-mapper-persistent-data lvm
# 知识补充:
yum-utils:yum的管理工具包,安装yum-utils之后才能运行yum-config-manager命令。
device-mapper-persistent-data: Linux2.6 内核中支持逻辑卷管理的通用设备映射机制,它为实现用于存储资源管理的块设备驱动提供了一个高度模块化的内核架构。
lvm:逻辑盘卷管理(Logical Volume Manager)的简称,它是一种磁盘管理工具,最主要的功能就是可以随时在线调整分区的大小,解决了安装Linux系统时需要评估分区大小的烦恼。从linux内核2.6.9开始,device-mapper模块就已经包含在内,只需加载即可。
[root@mysql01 ~]# modprobe dm_mod && lsmod | grep dm_mod # 加载lvm并查看
dm_mod 124501 5 dm_log,dm_mirror
1.4 安装 yum 源
[root@mysql01 ~]# yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
Loaded plugins: fastestmirror
adding repo from: https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
grabbing file https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo to /etc/yum.repos.d/docker-ce.repo
repo saved to /etc/yum.repos.d/docker-ce.repo
1.5 更新并安装 Docker-CE
[root@mysql01 ~]# yum makecache fast
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: mirrors.aliyun.com
* extras: mirrors.aliyun.com
* updates: mirrors.aliyun.com
...
Metadata Cache Created
[root@mysql01 ~]# yum install docker-ce-19.03.12 -y
已加载插件:fastestmirror
Loading mirror speeds from cached hostfile
* base: mirrors.aliyun.com
* extras: mirrors.aliyun.com
* updates: mirrors.aliyun.com
...
Complete!
1.6 测试启动
[root@mysql01 ~]# systemctl start docker # 启动
[root@mysql01 ~]# systemctl status docker # 查看状态
Docker镜像
在Docker中,部署的所有的应用都必须打包成一个镜像。也就是说镜像就是我们将软件打包之后的安装包。
# docker镜像的来源,分别是:
1.官方的镜像仓库(https://hub.docker.com/),优势:
○ 官方的仓库比较小
○ 官方的仓库比较安全
○ 官方仓库的镜像免费,可以拿来自己修改
2.第三方镜像仓库(https://cr.console.aliyun.com/cn-shanghai/instances)
○ 服务商提供的仓库稳定,一般用来作为公司内部的镜像仓库
3.自建镜像仓库(https://goharbor.io/)
1.1 获取Docker镜像
语法格式:
docker pull [仓库URL]/[名称空间]/仓库名称:版本号
# 解释
默认的仓库:URL
默认的名称空间:library
默认的版本号:latest
# 案例:查询默认的仓库名称
[root@kubernetes ~]# docker info
Registry: https://index.docker.io/v1/
# 案例:在阿里云上下载docker镜像
[root@kubernetes ~]# docker pull registry.cn-hangzhou.aliyuncs.com/k8stes/kube-proxy:v1.18.8
1.2 查看本机下载的镜像
语法格式:docker images 或者 docker image ls
[root@mysql01 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest f2f70adc5d89 7 hours ago 142MB
registry.cn-hangzhou.aliyuncs.com/k8stes/kube-proxy v1.18.8 0fb7201f92d0 19 months ago 117MB
1.3 搜索镜像
语法格式:docker search [镜像名称]
[root@kubernetes ~]# docker search nginx
# 解释:
● NAME:镜像名称
● DESCRIPTION:简介
● STARS:收藏(点赞)的个数
● OFFICIAL:是否是官方构建的镜像
● AUTOMATED:是否是自构建的镜像
1.3.1 参数 --limit : 指定每次搜索显示的行数
[root@kubernetes ~]# docker search nginx --limit=2
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
nginx Official build of Nginx. 16478 [OK]
bitnami/nginx Bitnami nginx Docker Image 120 [OK]
1.3.2 参数:-f : 过滤
[root@kubernetes ~]# docker search nginx --limit=2 -f is-official=true
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
nginx Official build of Nginx. 16478 [OK]
1.3.3 参数--no-trunc:不截断输出
[root@kubernetes ~]# docker search nginx --no-trunc
1.4 为镜像添加tag
语法格式:docker tag [原名称] 新名称
[root@mysql01 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest f2f70adc5d89 7 hours ago 142MB
registry.cn-hangzhou.aliyuncs.com/k8stes/kube-proxy v1.18.8 0fb7201f92d0 19 months ago 117MB
[root@kubernetes ~]# docker tag 605c77e624dd registry.cn-hangzhou.aliyuncs.com/k8stes/nginx:latest
1.5 上传镜像到仓库
# 登录仓库
语法格式:docker login [仓库的URL]
默认登录的是官方仓库URL
[root@kubernetes ~]# docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: alvinos
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
# 上传至仓库
格式:docker push [镜像名称]
[root@kubernetes ~]# docker push registry.cn-hangzhou.aliyuncs.com/k8stes/nginx:latest
The push refers to repository [registry.cn-hangzhou.aliyuncs.com/k8stes/nginx]
d874fd2bc83b: Pushed
32ce5f6a5106: Pushed
f1db227348d0: Pushed
b8d6e692a25e: Pushed
e379e8aedd4d: Pushed
2edcec3590a4: Pushed
latest: digest: sha256:c4c20a2fa2aaa7ede3 size: 1570
1.6 查看镜像详情
# 查询镜像更多的详细信息。
语法格式:docker inspect [可选参数-f] 镜像ID
[root@kubernetes ~]# docker inspect 605c77e624dd
[root@kubernetes ~]# docker inspect -f '{{ .DockerVersion }}' 605c77e624dd
20.10.7
[root@kubernetes ~]# docker inspect -f '{{ .ContainerConfig.Hostname }}' 605c77e624dd
ca3e48389f71
1.7 镜像的历史
语法格式:docker history 镜像ID
[root@kubernetes ~]# docker history 605c77e624dd
1.8 删除和清理镜像
# 删除镜像
语法格式:docker rmi 镜像名称
# 注意:如果镜像有多个TAG,docker rmi删除的就是tag;如果没有了tag,才会删除docker镜像。
[root@kubernetes ~]# docker rmi test:v2
Untagged: test:v2
# 清理镜像
将当前电脑中,所有的未被使用过的镜像全部删除。
[root@kubernetes ~]# docker image prune -a
Docker 容器
容器是镜像运行之后的一个实例。实质上,容器就是一个进程。容器可以被创建、启动、停止、删除、暂停等。
1、创建容器
语法:docker run [参数] [镜像] [启动语法格式]
# 注意:容器内必须至少有一个进程运行在前台才能让容器保持运行,如果容器内没有进程运行在前台的话,容器就是空的,系统机制会直接回收资源。
# 案例:创建一个CentOS容器。
[root@kubernetes ~]# docker run centos bash
# 案例:启动一个nginx容器
[root@kubernetes ~]# docker run -d --name nginx-test -P -v /root/nginx-test:/usr/share/nginx/html -e Name=Nginx-test nginx
1.1 参数
参数 | 参数解析 | 案例 |
---|---|---|
-d | 以守护进程方式运行 | # 指定一个宿主主机的端口,来代理容器内部的端口。 [root@kubernetes ~]# docker run -d -p 30080:80 nginx |
-p | 指定映射端口 | |
-P | 随机映射端口 | # 随机分配一个宿主主机的端口,用来代理容器的端口 [root@kubernetes ~]# docker run -d -P nginx |
-v | 设置挂载文件到主机上 | Docker容器是无法永久保存数据的,一旦容器被删除,则里面的数据就会全部删掉。将docker容器内部的数据保存在宿主主机中。 [root@kubernetes ~]# docker run -d -P -v /root/teszt/:/usr/share/nginx/html/ nginx |
--rm | 当容器关闭时自动删除 | # 容器生命周期一旦结束,立即删除容器 [root@kubernetes ~]# docker run --rm -d centos sleep 11 |
--name | 为启动的容器设置名字; 将容器的名称解析至容器DNS上 | [root@kubernetes ~]# docker run -d --name test nginx |
-i | 保持标准输入打开 | [root@kubernetes teszt]# docker run -i -t centos bash |
-t | 分配一个伪终端 | [root@kubernetes teszt]# docker run -i -t centos bash |
-e | 设置容器中的环境变量 | [root@kubernetes teszt]# docker run -e Name=test-centos centos printenv |
-h | 指定容器内的主机名 | |
--network | 指定使用哪个网络 | |
--link | 链接到另一个容器 |
2、查看容器
查询操作系统中,运行过的容器。
语法格式:docker ps [可选参数-a] # -a : 查看所有的容器
[root@kubernetes ~]# docker ps
[root@kubernetes ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9b119a6b1032 centos "bash" 2 minutes ago Exited (0) 2 minutes ago angry_dhawan
# 解释
● CONTAINER ID : 容器ID
● IMAGE:镜像语法格式
● COMMAND:运行的语法格式
● CREATED:创建的时间
● STATUS:启动状态
○ UP:正常启动
○ DOWN:正常关闭
○ Exited:启动失败
● PORTS:启动的端口
● NAMES:容器的名称
3、查看docker容器的日志
语法格式:docker log 容器ID或容器名称
参数:
○ -f : 实时打印日志
[root@kubernetes ~]# docker logs 346ac4822d4c
[root@kubernetes ~]# docker logs 346ac4822d4c -f
4、开启/停止容器
语法格式:
● 开启:docker start 容器ID或容器名称
● 停止:docker stop 容器ID或容器名称
[root@kubernetes ~]# docker start exciting_meninsky
[root@kubernetes ~]# docker stop exciting_meninsky
5、 查看容器详细信息
语法格式:docker inspect 容器ID或容器名称
[root@kubernetes ~]# docker inspect jovial_cori
6、删除容器
将容器在宿主主机中删除
语法:docker rm 容器名称 [可选参数-f] # -f: 强制删除
[root@kubernetes ~]# docker rm -f exciting_meninsky
exciting_meninsky
7、保存容器和镜像
保存镜像有三种方式:保存容器为镜像、导出容器为镜像、导出镜像为镜像。
7.1 保存容器为镜像
# 保存容器为镜像:将正在运行的容器保存为镜像。
语法:docker commit [可选参数] 容器名称 镜像名称
参数:
-a : 指定作者
-c :修改的列表
-m :提交信息
-p :暂停容器
[root@kubernetes ~]# docker commit jovial_cori test:v1
sha256:e9a3491205940b0f390461086bffb7bf08da497b327ce0d67c0462cfc89f452f
[root@kubernetes ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
test v1 e9a349120594 5 seconds ago 141MB
7.2 导出容器为镜像
导出容器为镜像:将正在运行的容器,导出为一个镜像压缩包。
语法格式:
导出:docker export -o [容器包名] [容器名] # 或 docker export [容器名] > [容器包名]
导入:docker import [容器包名] [镜像名]
[root@kubernetes teszt]# docker export -o nginx.tar jovial_cori
[root@kubernetes teszt]# ll
总用量 140660
-rw------- 1 root root 144025600 3月 18 11:00 nginx.tar
[root@kubernetes teszt]# docker import -m '测试导出' ./nginx.tar test:v2
sha256:ac7290ff39286ffbc88a23b520d634851f017c71bad4ab53985f95bd1f73e750
[root@kubernetes teszt]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
test v2 ac7290ff3928 6 seconds ago 140MB
7.3 导出镜像
导出镜像:将宿主主机中的镜像导出为镜像压缩包。
语法格式:
导出镜像:docker save -o [镜像包名] [镜像名]
导入镜像:docker load -i
[root@kubernetes teszt]# docker save -o centos.tar centos:latest
[root@kubernetes teszt]# docker load -i centos.tar
Loaded image: centos:latest
[root@kubernetes teszt]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest 8becc16f3db7 4 months ago 204MB
8、进入容器
8.1 attach
attach 是最早 docker 官方推出的进入容器的命令了,它主要是建立一个进程管道,连接上容器中的PID为1的进程。
不过使用该命令有一个问题。当多个窗口同时使用该命令进入该容器时,所有的窗口都会同步显示。如果有一个窗口阻塞了,那么其他窗口也无法再进行操作,当所有窗口退出时,即所有的进程都结束的话,容器结束,会被系统回收。
[root@mysql01 ~]# docker attach clever_ride
8.2 exec
继attach 之后,exec 是官方推出的有一个新的进入容器的命令,这个命令相当于在容器中执行一个命令。主要是用来在宿主主机中执行容器内的命令,是目前企业最常用的方式。
[root@mysql01 ~]# docker exec -it clever_ride /bin/bash # /bin/bash是给个bash进程窗口可以执行命令
8.3 nsenter
需要配合 docker inspect 来使用,主要是是新建一个进程管道,并且在容器中新建一个bash进程。
[root@mysql01 ~]# nsenter --target $(docker inspect -f '{{ .State.Pid }}' vigorous_jackson ) --mount --uts --ipc --net --pid
9、容器复制文件
9.1 复制容器内文件到宿主主机
语法格式:docker cp 容器名称:文件路径 宿主主机路径
[root@mysql01 ~]# docker cp 437617cd0270:/root/test.txt /opt
[root@mysql01 opt]# ll /opt
9.2 复制宿主主机文件到容器内
语法格式:docker cp 宿主主机路径 容器名称:文件路径
[root@mysql01 opt]# docker cp /opt/test.txt 437617cd0270:/root/test1.txt
[root@mysql01 opt]# docker exec 437617cd0270 ls /root/
10、练习:要求使用容器部署Django
# 要求使用容器部署Django
1.安装依赖软件
[root@mysql01 opt]# yum install python3 libxml* gcc* pcre-devel openssl-devel python3-devel python-devel-y
2.安装Django:pip3
[root@mysql01 opt]# pip3 install django -i http://pypi.douban.com/simple --trusted-host=pypi.douban.com
3.创建项目生成代码:django-admin startproject / startapp
[root@mysql01 ~]# cd /opt/
[root@mysql01 opt]# django-admin startproject djangotest
[root@mysql01 opt]# cd /opt/djangotest/
[root@mysql01 djangotest]# django-admin startapp application
4.修改配置文件
[root@mysql01 djangotest]# vim /opt/djangotest/djangotest/settings.py
ALLOWED_HOSTS = ['*'] # 加入一个※号表示通用
DATABASES = {} # 把原来的内容清空
5.安装uwsgi
[root@mysql01 djangotest]# pip3 install uwsgi http://pypi.douban.com/simple --trusted-host=pypi.douban.com
7.修改ini配置文件
[root@mysql01 djangotest]# vim /opt/djangotest/myweb.ini
[uwsgi]
# 端口号
socket = :8080
# 指定项目的目录
chdir = /opt/djangotest
# wsgi文件路径
wsgi-file = djangotest/wsgi.py
# 模块wsgi路径
module = djangotest.wsgi
# 是否开启master进程
master = true
# 工作进程的最大数目
processes = 4
# 结束后是否清理文件
vacuum = true
8.启动uwsgi
[root@mysql01 djangotest]# uwsgi --ini myweb.ini
5.指定启动端口
[root@mysql01 djangotest]# python3 /opt/djangotest/manage.py runserver 0.0.0.0:8081
10.启动docker
[root@mysql01 ~]# systemctl enable --now docker
11.启动容器
[root@mysql01 ~]# docker run -dit -v /opt/djangotest/:/opt -p 8081:8081 python:3
12.进入容器
[root@mysql01 ~]# docker ps
[root@mysql01 ~]# docker exec -it eloquent_chaum bash
12.在容器内安装Django
root@6010a5a4b1b1:/# cd /opt
root@6010a5a4b1b1:/opt# pip3 install django==2.2.2 -i https://pypi.tuna.tsinghua.edu.cn/simple/
root@6010a5a4b1b1:/opt# python manage.py runserver 0.0.0.0:8081
13.浏览器访问
192.168.15.51:8081
Docker网络
Docker本身的技术依赖于Linux内核虚拟化,对Linux内核的特性有很强的依赖。要学习Docker网络首先要了解linux内核。
在Docker之中,存在多个容器使用同一个端口的情况,怎么解决?例如多个nginx都使用80端口,是怎么实现的呢?
1、Linux网络基础
为了支持网络协议的多实例,Linux在网络协议栈中引入了网络名称空间(Network Namespace),这些独立的协议栈被隔离到不同的命名空间中去,处于不同的命名空间中的网络协议栈完全隔离,彼此之间无法进行网络通信。
通这种对网络协议资源的隔离,就能够在一个宿主主机上虚拟出来多个不同的网络环境,Docker正是利用了这种网络名称空间的特性,实现了不同容器之间的网络隔离。
Linux的网络协议栈是十分复杂的,为了支持独立的协议栈,Linux把所有的全局变量都修改为网络协议栈的私有变量。最好的办法就是让这些全局变量成为一个 Net Namespace 变量的成员,然后为了协议栈的函数调用加入一个Namespace 参数。这就是 Linux 网络名称空间的核心。所以的网络设备都只能属于一个网络名称空间。当然,通常的物理网络设备只能关联到 root 这个命名空间中。虚拟网络设备则可以被创建并关联到一个给定的命名空间中,而且可以在这些名称空间之间移动。
1.2 实现Linux命名空间之间网络转发
1.2.1 创建一个命名空间
[root@kubernetes ~]# ip netns add test01
[root@kubernetes ~]# ip netns list
test01
1.2.2 Linux中不同命名空间之间网络互通的实现方式
在Linux操作系统中,实现不同网络名称空间之间网络互通的方式如下:
1.Veth设备对:建立一个Veth设备对时,会创建两个Veth设备网卡,将其中一个Veth设备网卡放到需要链接的网络名称空间内,即可实现两个名称空间之间的网络互通。
2. Iptables:通过Iptables进行网络转发,来实现网络互通。
3. 网桥:所有的网络全部走网桥,通过网桥进行网络转发。
设备 | 作用 |
---|---|
network namespace | 主要提供了关于网络资源的隔离,包括网络设备、IPv4 和 IPv6 协议栈、IP 路 由表、防火墙、/proc/net 目录、/sys/class/net 目录、端口(socket)等。 |
veth pair | 两个虚拟网卡组成的数据通道。在 Docker 中,用于连接 Docker 容器和 Linux Bridge。一端在容器中作为 eth0 网卡,另一端在 Linux Bridge 中作为网桥的 一个端口。 |
iptables | 主要为容器提供 NAT 以及容器网络安全。 |
linux Bridge | 功能相当于物理交换机,为连在其上的设备(容器)转发数据帧。如 docker0 网桥。 |
1.3 Veth设备对
为了解决不同网络名称空间之间的网络互通,我们可以使用Veth设备对来实现。由于要连接的两个网络命名空间,所以 Veth 设备是成对出现的,很像一对以太网卡,并且中间有一根直连的网线。既然是一对网卡,那么我们将其中一端称为另一端的peer。在 Veth 设备的一端发送数据时,它会将数据直接发送到另一端,并触发另一端的接收操作。
# 创建Veth设备对:生成了两个 veth 设备, 互为对方的 peer。
[root@kubernetes ~]# ip link add veth type veth peer name veth001
# 将veth设备对绑定到命名空间
[root@kubernetes ~]# ip link set veth001 netns test01
# 将 Veth 分配 IP:注意不能与现有IP网段一致
[root@kubernetes ~]# ip a
[root@kubernetes ~]# ip netns exec test01 ip addr add 172.18.0.111/20 dev veth001
[root@kubernetes ~]# ip addr add 172.18.0.112/20 dev veth
# 刷新宿主主机的veth设备 IP
[root@kubernetes ~]# ip link set dev veth down
[root@kubernetes ~]# ip link set dev veth up
# 刷新容器的veth设备 IP
[root@kubernetes ~]# ip netns exec test01 ip link set dev veth001 down
[root@kubernetes ~]# ip netns exec test01 ip link set dev veth001 up
# 测试连接:ping通即OK
[root@kubernetes ~]# ping 172.18.0.111
[root@kubernetes ~]# ping 172.18.0.112
1.4 Iptables
Iptables:基于系统安全框架,绕过网络名称空间实现网络互通。网络命名空间属于是用户级别,而Iptables属于是系统层级。
我们知道, Linux 络协议樵非常高效,同时比较复杂 如果我们希望在数据的处理过程中对关心的数据进行一些操作该怎么做呢? Linux 提供了一套机制来为用户实现自定义的数据包处理过程。
在 Linux 网络协议棋中有一组回调函数挂接点,通过这些挂接点挂接的钩子函数可以在 Linux 网络棋处理数据包的过程中对数据包进行 些操作,例如过滤、修改、丢弃等 整个挂接点技术叫作 Netfilter lptablesNetfilter 负责在内核中执行各种挂接的规则,运行在内核模式中:而 lptables 是在用户模式下运行的进程,负责协助维护内核中 Netfilter 的各种规则表 通过 者的配合来实现整个 Linux 网络协议战中灵活的数据包处理机制。
Iptables详情参考博客:https://www.cnblogs.com/90s-blog/p/15736429.html
2、Docker网络
Docker使用了Linux桥接的方式,在宿主主机上虚拟出来一个Docker容器网桥,Docker启动一个容器时,会根据网段分配给容器一个IP地址,称之为:Contabiner IP,同时Docker网桥是每个容器默认的网关,因为在同一个宿主主机内的容器都接入同一个网桥,这样容器之间就可以实现互联互通了。
2.1 Docker网桥
Linux 可以支持多个不同的网络,它们之间能够相互通信,就需要一个网桥。 网桥是二层的虚拟网络设备,它是把若干个网络接口“连接”起来,从而报文能够互相转发。网桥能够解析收发的报文,读取目标 MAC 地址的信息,和自己记录的 MAC 表结合,来决定报文的转发目标网口。
网桥设备 brO 绑定了 eth0、 eth1 。对于网络协议械的上层来说,只看得到 brO 。因为桥接是在数据链路层实现的 ,上层不需要关心桥接的细节,于是协议枝上层需要发送的报文被送到 brO ,网桥设备的处理代码判断报文该被转发到 ethO 还是 ethl ,或者两者皆转发。反过来,从 ethO 或从 ethl 接收到的报文被提交给网桥的处理代码,在这里会判断报文应该被转发、丢弃还是提交到协议枝上层。 而有时 ethl 也可能会作为报文的源地址或目的地址 直接参与报文的发送与接收,从而绕过网桥。
网桥相当于交换机,所有的网络之间要想互联互通,就必须跟网桥关联,然后由网桥进行网络转发。在Docker中,网桥一般有四种模式:分别是:HOST模式、Contaniner模式、None模式和Bridge模式。
# MAC 地址: 类似于身份证号码,用于标识唯一的一台计算机。以太网协议:规定了计算机必须有一块网卡,并且网卡上面需要有一串固定12位的16进制数字。前六位是产商编号,后六位是流水线号。上述的数字也称为计算机的mac地址。
2.2 Docker 网络模式
Docker 使用 Linux 桥接的方式,在宿主机虚拟一个 Docker 容器网桥(docker0),Docker 启动一个容器时会根据 Docker 网桥的网段分配给容器一个 IP 地址,称为 Container-IP,同时 Docker 网桥是每个容器的默认网关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的 Container-IP 直接通信。
Docker 网桥是宿主机虚拟出来的,并不是真实存在的网络设备,外部网络是无法寻址到的,这也意味着外部网络无法通过直接 Container-IP 访问到容器。如果容器希望外部访问能够访问到,可以通过映射容器端口到宿主主机(端口映射),即 docker run 创建容器时候通过 -p 或 -P 参数来启用,访问容器的时候就通过[宿主机 IP]:[容器端口]访问容器。
Docker网络模型 | 配置 | 说明 |
---|---|---|
host模式 | –-network=host | 容器和宿主机共享Network namespace |
containe模式 | --network=container:ID | 容器和另外一个容器共享 Network namespace。 kubernetes 中的 pod 就是多个容器共享一个 Network namespace。 |
none 模式 | --network=none | 容器有独立的 Network namespace,但并没有对其进行任何网 络设置,如分配 veth pair 和网桥连接,配置 IP 等。 |
bridge 模式 | --network=bridge | 当 Docker 进程启动时,会在主机上创建一个名为 docker0 的虚 拟网桥,此主机上启动的 Docker 容器会连接到这个虚拟网桥上。 虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器 就通过交换机连在了一个二层网络中。(默认为该模式) |
2.2.1 HOST 模式
如果启动容器的时候使用 host 模式,那么这个容器将不会获得一个独立的 Network Namespace,而是和主机共用一个 Network Namespace。容器将不会虚拟出自己的网卡,配置自己的 IP 等,而是使用宿主机的 IP和端口。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。
使用 host 模式的容器可以直接使用宿主机的 IP 地址与外界通信,容器内部的服务端口也可以使用宿主机的端口,不需要进行 NAT,host 最大的优势就是网络性能比较好,但是 docker host 上已经使用的端口就不能再用了,网络的隔离性不好。
[root@kubernetes ~]# docker run -d --network host nginx
[root@kubernetes ~]# docker ps
[root@kubernetes ~]# curl 127.0.0.1:80
2.2.2 Containe 模式
这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo 网卡设备通信。
[root@kubernetes ~]# docker run --name test -it centos bash
[root@kubernetes ~]# docker run -it --network "container:test" centos bash
[root@mysql01 djangotest]# docker exec eloquent_galileo ip a
[root@mysql01 djangotest]# docker exec test ip a
2.2.3 none 模式
使用 none 模式,Docker 容器拥有自己的 Network Namespace,但是,并不为 Docker 容器进行任何网络配置。也就是说,这个 Docker 容器没有网卡、IP、路由等信息。需要我们自己为 Docker 容器添加网卡、配置IP 等。
这种网络模式下容器只有 lo 回环网络,没有其他网卡。none 模式可以在容器创建时通过--network=none来指定。这种类型的网络没有办法联网,封闭的网络能很好的保证容器的安全性。一般这种模式只会用在机密或者绝密数据。
[root@kubernetes ~]# docker run -it --network none centos bash
2.2.4 bridge 模式
当 Docker 进程启动时,会在主机上创建一个名为 docker0 的虚拟网桥,此主机上启动的 Docker 容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。
从 docker0 子网中分配一个 IP 给容器使用,并设置 docker0 的 IP 地址为容器的默认网关。在主机上创建一对虚拟网卡 veth pair 设备,Docker 将 veth pair 设备的一端放在新创建的容器中,并命名为 eth0(容器的网卡),另一端放在主机中,以 vethxxx 这样类似的名字命名,并将这个网络设备加入到 docker0 网桥中。可以通过 brctl show 命令查看。
bridge 模式是 docker 的默认网络模式,不写--net 参数,就是 bridge 模式。使用 docker run -p 时,docker实际是在 iptables 做了 DNAT 规则,实现端口转发功能。可以使用 iptables -t nat
[root@kubernetes ~]# docker network create test
[root@kubernetes ~]# docker run -d --network test nginx
[root@kubernetes ~]# docker run -it --network test centos
2.3 Docker网络(network)
2.3.1 创建docker 网络
[root@kubernetes ~]# docker network create chenyang1
87d1a7fae878ebb1cd26dab85b81f126eccec18d8d8dcc160ab96c0afa5e6a51
2.3.2 查看网桥
[root@kubernetes ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
87d1a7fae878 chenyang1 bridge local
- NETWORK ID : 网桥的ID
- NAME :网桥的名称
- DRIVER :网桥的类型
- SCOPE :网桥的所在地
2.3.3 链接网桥
已经创建过的容器链接网桥。
[root@kubernetes ~]# docker network connect chenyang1 9bc930694812
2.3.4 断开链接网桥
[root@kubernetes ~]# docker network disconnect chenyang1 9bc930694812
2.3.5 删除网桥
[root@kubernetes ~]# docker network rm chenyang2
2.3.6 清理网桥
将所有未被使用到的网桥全部删除
[root@kubernetes ~]# docker network prune
3、练习:要求在docker中实现用nginx代理django
3.1 生成代码
# 安装:python3.6 python3-devel nginx
[root@mysql01 djangotest]# yum install python3.6 python3-devel nginx
# 安装django和uwsgi
[root@mysql01 djangotest]# pip3 install django==2.2.2 -i https://pypi.tuna.tsinghua.edu.cn/simple/
[root@mysql01 djangotest]# pip3 install uwsgi -i https://pypi.tuna.tsinghua.edu.cn/simple/
# 创建目录生成代码
[root@mysql01 djangotest]# cd /opt
[root@mysql01 djangotest]# mkdir linux
[root@mysql01 djangotest]# cd linux
[root@mysql01 djangotest]# django-admin startproject test
[root@mysql01 djangotest]# cd test
[root@mysql01 djangotest]# django-admin startapp application
# 修改配置文件settings.py和myweb.ini
[root@mysql01 djangotest]# vim /opt/djangotest/djangotest/settings.py
ALLOWED_HOSTS = ['*']
DATABASES = {}
[root@mysql01 djangotest]# vim /opt/djangotest/myweb.ini
[uwsgi]
# 端口号
socket = :8080
# 指定项目的目录
chdir = /opt/djangotest
# wsgi文件路径
wsgi-file = djangotest/wsgi.py
# 模块wsgi路径
module = djangotest.wsgi
# 是否开启master进程
master = true
# 工作进程的最大数目
processes = 4
# 结束后是否清理文件
vacuum = true
3.2 部署django
# 开启docker
[root@mysql01 djangotest]# systemctl enable --now docker
# 创建docker网络
[root@mysql01 djangotest]# docker network create chenyang3
# 创建容器
[root@mysql01 djangotest]# docker run -it -d --name djangotest -v /opt/djangotest/djangotest/:/opt --network chenyang3 python:3.6 bash
# 进入容器
[root@mysql01 djangotest]# docker exec -it djangotest bash
# 切换目录
root@883b7923c861:/# cd /opt/
# 安装django
root@883b7923c861:/opt# pip install django==2.2.2 -i https://pypi.tuna.tsinghua.edu.cn/simple/
# 启动
root@883b7923c861:/opt# python manage.py runserver 0.0.0.0:8080
3.3 部署Nginx
# 创建目录
[root@mysql01 djangotest]# mkdir /opt/djangotest/nginx
[root@mysql01 djangotest]# cd nginx/
# 编辑配置文件
[root@mysql01 nginx]# vim default.conf
server {
server_name _;
listen 80;
location / {
proxy_pass http://djangotest:8080;
}
}
[root@kubernetes nginx]# docker run -d -P --name nginx1 -v /root/django/nginx/:/etc/nginx/conf.d --network chenyang3 nginx
3.4 测试结果
# 查看随机端口号
[root@mysql01 nginx]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a7b070217d24 nginx "/docker-entrypoint.…" 6 seconds ago Up 4 seconds 0.0.0.0:49153->80/tcp, :::49153->80/tcp nginx01
94288f90aaab python:3.6 "bash" 4 minutes ago Up 4 minutes djangotest
# 浏览器访问:192.168.15.52:49153 出现django
Dockerfile构建镜像
Dockerfile主要用在Docker中,构建镜像。
Dockerfile是由一行一行指令组成的,支持以#开头的行为注释的行。
一般而言,Dockerfile主体内容分为两个部分:基础镜像信息(必须)、其他指令。
在构建镜像之前,必须基于Docker一个基础环境(基础镜像)。
构建镜像语法:Docker build -t 镜像名字:版本 镜像路径
1、FROM:指定基础环境
FROM指令必须是Dockerfile中的第一个指令,而且FROM指令有且只有一个,主要用来指定一个构建镜像的基础环境。
[root@kubernetes linux]# vim Dockerfile
FROM python:3.6
2、MAINTAINER:指定维护者信息
指定维护者信息。没有实际作用,主要是用来指定构建该镜像的作者信息。
[root@kubernetes linux]# cat Dockerfile
FROM python:3.6
MAINTAINER shanhe shanhe@123.com xxxxxxx
3、RUN:构建镜像时执行命令
构建镜像时执行命令。
[root@kubernetes linux]# cat Dockerfile
FROM python:3.6
MAINTAINER shanhe shanhe@123.com xxxxxxx
RUN pip install django==2.2.2 -i https://pypi.tuna.tsinghua.edu.cn/simple/
4、CMD:设置Docker镜像启动时默认执行的命令
设置Docker镜像启动时默认执行的命令。
[root@kubernetes linux]# cat Dockerfile
FROM python:3.6
MAINTAINER shanhe shanhe@123.com xxxxxxx
RUN pip install django==2.2.2 -i https://pypi.tuna.tsinghua.edu.cn/simple/
CMD python manage.py runserver 0.0.0.0:8080
5、ENTRYPOINT:设置Docker镜像启动命令
设置Docker镜像启动命令,如果设置了ENTRYPOINT,则CMD将会变成它的参数。
[root@kubernetes linux]# cat Dockerfile
FROM python:3.6
MAINTAINER shanhe shanhe@123.com xxxxxxx
RUN pip install django==2.2.2 -i https://pypi.tuna.tsinghua.edu.cn/simple/
ADD ./ /opt/
VOLUME /tmp
WORKDIR /opt
EXPOSE 8080
ENTRYPOINT ["python"]
CMD ["manage.py", "runserver", "0.0.0.0:8080"]
6、WORKDIR:指定Docker容器的工作目录
指定Docker容器的工作目录。也就是说docker容器启动时,默认执行命令的目录。
[root@kubernetes linux]# cat Dockerfile
FROM python:3.6
MAINTAINER shanhe shanhe@123.com xxxxxxx
RUN pip install django==2.2.2 -i https://pypi.tuna.tsinghua.edu.cn/simple/
WORKDIR /opt
CMD python manage.py runserver 0.0.0.0:8080
[root@kubernetes linux]# docker run -d -v /root/django/linux/:/opt -p 8081:8080 django:v3
7、EXPOSE:指定默认端口号
expost是Dockerfile中指定默认端口号。
[root@kubernetes linux]# cat Dockerfile
FROM python:3.6
MAINTAINER shanhe shanhe@123.com xxxxxxx
RUN pip install django==2.2.2 -i https://pypi.tuna.tsinghua.edu.cn/simple/
WORKDIR /opt
EXPOSE 8080 8081 8082 8083/udp
CMD python manage.py runserver 0.0.0.0:8080
8、ADD:将宿主主机中的内容或者互联网下载的内容放置于镜像中
将宿主主机中的内容或者互联网下载的内容放置于镜像中。支持自动解压tar类型的压缩包。
[root@kubernetes linux]# cat Dockerfile
FROM python:3.6
MAINTAINER shanhe shanhe@123.com xxxxxxx
RUN pip install django==2.2.2 -i https://pypi.tuna.tsinghua.edu.cn/simple/
ADD ./ /opt/
ADD http://106.13.81.75/Navicat15.exe /tmp/
WORKDIR /opt
EXPOSE 8080 8081 8082 8083/udp
CMD python manage.py runserver 0.0.0.0:8080
9、COPY:将宿主主机中的内容复制到镜像中
将宿主主机中的内容复制到镜像中。不支持互联网下载,也不支持自动解压。
[root@kubernetes linux]# cat Dockerfile
FROM python:3.6
MAINTAINER shanhe shanhe@123.com xxxxxxx
RUN pip install django==2.2.2 -i https://pypi.tuna.tsinghua.edu.cn/simple/
COPY etcd-v3.4.14-linux-amd64.tar.gz /tmp/
WORKDIR /opt
EXPOSE 8080
CMD python manage.py runserver 0.0.0.0:8080
10、VOLUME:指定容器需要挂载的目录
指定容器需要挂载的目录(注意:如果我们启动容器时,使用了-v参数则直接挂载,如果没有使用-v,则会使用volume指定默认的挂载)
[root@kubernetes linux]# cat Dockerfile
FROM python:3.6
MAINTAINER shanhe shanhe@123.com xxxxxxx
RUN pip install django==2.2.2 -i https://pypi.tuna.tsinghua.edu.cn/simple/
ADD ./ /opt/
VOLUME /tmp
WORKDIR /opt
EXPOSE 8080
CMD python manage.py runserver 0.0.0.0:8080
11、ENV:指定该镜像启动容器中的环境变量
指定该镜像启动容器中的环境变量。
[root@kubernetes linux]# cat Dockerfile
FROM python:3.6
MAINTAINER shanhe shanhe@123.com xxxxxxx
RUN pip install django==2.2.2 -i https://pypi.tuna.tsinghua.edu.cn/simple/
ADD ./ /opt/
VOLUME /tmp
ENV DJANGO_VERSION=123456
WORKDIR /opt
EXPOSE 8080
ENTRYPOINT ["python"]
CMD ["manage.py", "runserver", "0.0.0.0:8080"]
12、ARG:设置构建镜像临时参数
设置构建镜像临时参数。
[root@kubernetes django]# cat Dockerfile
FROM python:3.6
ARG package=django
RUN pip install $package
[root@kubernetes django]# docker build --build-arg=package=pymysql -t django:v17 .
13、ONBUILD:构建触发器
Docker构建触发器。主要是当该镜像作为基础镜像时触发。
[root@kubernetes django]# cat Dockerfile
FROM django:v19
ARG package=django
RUN pip install $package
ONBUILD RUN rm -rf /opt
14、案例:使用Nginx代理Django
14.1 宿主主机生成代码
# 安装依赖软件
[root@kubernetes ~]# yum install python3.6 python3-dev
# 安装django和uwsgi
[root@kubernetes ~]# pip3 install django==2.2.2 -i https://pypi.tuna.tsinghua.edu.cn/simple/
[root@kubernetes ~]# pip3 install uwsgi -i https://pypi.tuna.tsinghua.edu.cn/simple/
# 创建目录生成代码
[root@kubernetes ~]# mkdir -p /opt/linux
[root@kubernetes ~]# cd /opt/linux
[root@kubernetes linux]# django-admin startproject djangotest
[root@kubernetes linux]# cd djangotest
[root@kubernetes djangotest]# django-admin startapp application
# 修改配置
[root@kubernetes djangotest]# vim /opt/linux/djangotest/settings.py
ALLOWED_HOSTS = ['*']
DATABASES = {}
14.2 部署Django
# 1.创建Dockerfile文件
[root@kubernetes opt]# vim Dockerfile
FROM python:3.6
MAINTAINER shanhe shanhe@123.com xxxxxxx
RUN pip install uwsgi -i https://pypi.tuna.tsinghua.edu.cn/simple/
RUN pip install django==2.2.2 -i https://pypi.tuna.tsinghua.edu.cn/simple/
RUN mkdir /opt/linux
ADD ./linux /opt/linux/
EXPOSE 8000
WORKDIR /opt/linux
CMD uwsgi --ini myweb.ini
# 2.配置myweb.ini文件
[root@kubernetes opt]# vim /opt/linux/myweb.ini
[uwsgi]
# 端口号
socket = :8000
# 指定项目的目录
chdir = /opt/linux
# wsgi文件路径
wsgi-file = djangotest/wsgi.py
# 模块wsgi路径
module = djangotest.wsgi
# 是否开启master进程
master = true
# 工作进程的最大数目
processes = 4
# 结束后是否清理文件
vacuum = true
# 3.构建镜像到当前目录
[root@kubernetes opt]# docker build -t django:v1 .
# 4.启动镜像
[root@kubernetes opt]# docker run -d --name djangotest django:v1
14.3 部署Nginx
# 1.创建nginx目录
[root@kubernetes django]# mkdir -p /opt/linux/nginx
# 2.编辑配置文件
[root@kubernetes django]# cd /opt/linux/nginx
[root@kubernetes nginx]# vim /opt/linux/nginxdefault.conf
server {
listen 80;
server_name py.test.com;
location / {
include uwsgi_params;
uwsgi_pass djangotest:8000;
uwsgi_read_timeout 2;
uwsgi_param UWSGI_SCRIPT djangotest.wsgi;
uwsgi_param UWSGI_CHDIR /opt/linux;
index index.html index.htm;
client_max_body_size 35m;
}
}
# 3.创建Dockerfile
[root@kubernetes django]# vim Dockerfile
FROM nginx
ADD default.conf /etc/nginx/conf.d/
EXPOSE 80 443
CMD nginx -g 'daemon off;'
# 4.构建镜像到当前目录
[root@kubernetes django]# docker build -t nginx:v1 .
# 5.创建网桥
[root@kubernetes django]# docker network create bridge1
# 6.绑定容器
[root@kubernetes django]# docker network connect bridge1 djangotest1
# 7.创建容器
[root@kubernetes django]# docker run -d -p 8082:80 --name nginxtest1 --network bridge1 nginx:v1
14.4 测试结果
浏览器访问192.168.15.51:8082
Docker-compose容器编排工具
在K8S出现之前,市场上有很多个容器编排工具。docker-compose就是其中之一,但是docker-compose只支持单机容器编排。
docker-compose是Docker官方开源的又一个项目,主要负责对Docker容器集群进行快速编排。
在docker-compose中有两个重要的概念:
● service:一个应用的容器,实际上可以包含若干个运行相同镜像的容器。
● project:由一组相关联的应用容器组成的一个完整的业务单元。
由此,docker-compose恰好满足用户通过一个命令,启动整个业务单元中所有的容器的这样一个功能。
而且,docker-compose是通过Python编写的,是想上调用了Docker服务提供的API,来对容器进行管理。因此,只要所操作的平台支持Docker,就可以利用docker-compose来进行管理。
1、安装Docker-compose
安装docker-compose非常的简单,从GitHub上面直接下载下来给个执行权限就能用。
[root@mysql01 ~]# echo "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)"
https://github.com/docker/compose/releases/download/1.29.2/docker-compose-Linux-x86_64
[root@mysql01 ~]# sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-Linux-x86_64" -o /usr/local/bin/docker-compose
[root@mysql01 ~]# sudo chmod +x /usr/local/bin/docker-compose
[root@mysql01 ~]# dockre-compose # 查看有数据则安装完成
2、增加docker-compose的命令行补全
[root@mysql01 ~]# curl -L https://raw.githubusercontent.com/docker/compose/1.29.2/contrib/completion/bash/docker-compose > /etc/bash_completion.d/docker-compose
3、docker-compose的使用
docker-compose管理容器是通过配置清单的方式进行管理。配置清单的名称必须如下选择一个:
docker-compose.yml, docker-compose.yaml(推荐), compose.yml, compose.yaml。
3.1 image:指定镜像
[root@kubernetes ~]# mkdir harbor
[root@kubernetes ~]# cd harbor
[root@kubernetes harbor]# vim docker-compose.yaml
# 指定docker-compose配置清单的版本
version: "3"
services:
mydjango: # 自己具体应用
image: django:v24
[root@kubernetes harbor]# docker-compose up -d
3.2 build:构建镜像
根据指定路径的dockerfile构建镜像并启动。
# 指定docker-compose配置清单的版本
version: "3"
services:
mydjango:
build: ./
# 指定docker-compose配置清单的版本
version: "3"
services:
mydjango:
build:
context: ./
dockerfile: docker-file
3.3 command:指定容器启动的默认命令
# 指定docker-compose配置清单的版本
version: "3"
services:
mydjango:
build:
context: ./
dockerfile: docker-file
command: python manage.py runserver 0.0.0.0:80
3.4 container_name:指定容器名称
# 指定docker-compose配置清单的版本
version: "3"
services:
mydjango:
build:
context: ./
dockerfile: docker-file
command: python manage.py runserver 0.0.0.0:80
container_name: test
3.5 depens_on:解决容器启动顺序
# django + Nginx时,Nginx通常必须在Django容器之后启动。
version: "3"
services:
mydjango:
build:
context: ./
dockerfile: docker-file
command: python manage.py runserver 0.0.0.0:80
container_name: django
mynginx:
image: nginx:v3
depends_on:
- mydjango
3.6 ports:指定容器端口
version: "3"
services:
mydjango:
build:
context: ./
dockerfile: docker-file
container_name: django
mynginx:
image: nginx:v3
ports:
- "8090:80"
depends_on:
- mydjango
3.6 volumes:挂载目录
version: "3"
services:
mydjango:
build:
context: ./
dockerfile: docker-file
container_name: django
mynginx:
image: nginx:v3
ports:
- "8090:80"
volumes:
- /opt:/opt
depends_on:
- mydjango
4、docker-compose常用命令
关于docker-compose操作容器的命令。
4.1 up:创建容器并启动
[root@kubernetes django]# docker-compose up -d
4.2 down:停止容器
[root@kubernetes django]# docker-compose down
4.3 ps:容器列表
[root@kubernetes django]# docker-compose ps
Name Command State Ports
---------------------------------------------------------------------------------------------------------
django uwsgi --ini myweb.ini Up 8000/tcp
django_mynginx_1 /docker-entrypoint.sh /bin ... Up 443/tcp, 0.0.0.0:8090->80/tcp,:::8090->80/tcp
4.4 exec:进入容器
[root@kubernetes django]# docker-compose exec mynginx bash
4.5 restart:重启容器
[root@kubernetes django]# docker-compose restart
4.6 rm:删除容器
# 先停止后删除
[root@kubernetes django]# docker-compose stop mydjango
Stopping django ... done
[root@kubernetes django]# docker-compose rm -f mydjango
Going to remove django
Removing django ... done
4.7 top:查看容器内部的进程
[root@kubernetes django]# docker-compose top mynginx
5、docker的可视化平台
5.1 启动
# step1 加上域名解析
[root@kubernetes linux]# vim /etc/sysconfig/network-scripts/ifcfg-ens33
DNS1=114.114.114.114
DNS2=192.168.15.61
# step2 两种启动方法:
# 方法1:用命令行启动
[root@docker01 harbor]# docker run -d -p 8000:8000 -p 9443:9443 --name portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:2.11.1
# 方法2:用docker-compose.yaml启动
[root@docker01 harbor]# vim docker-compose.yaml
version: "3"
services:
portainer:
image: portainer/portainer-ce:2.11.1
volumes:
- /opt/portainer_data:/data
- /var/run/docker.sock:/var/run/docker.sock
container_name: portainer
ports:
- 8000:8000
- 9443:9443
# 启动
[root@kubernetes linux]# docker-compose up -d
5.2 查看
# 浏览器访问:https://192.168.15.61:9443
# 设置密码
# 进入docker可视化平台
Harbor私有仓库
Harbor是有VMware公司中国团队为企业用户设计的私有仓库开源项目,它包含了权限管理、审计、管理界面、自我注册等企业必须的功能。同时针对中国用户的特点,设计了镜像复制和中文支持等功能。提供了更好的性能和安全,提升用户使用私有仓库构建和运行环境的传输效率。
1、下载harbor
# 下载harbor安装包
wget https://github.com/goharbor/harbor/releases/download/v2.4.2/harbor-offline-installer-v2.4.2.tgz
# 解压
tar -xf harbor-offline-installer-v2.4.2.tgz
# 创建证书目录
mkdir /root/harbor/harbor/cert
cd /root/harbor/harbor/cert
2、安装
2.1 生成CA签名
openssl genrsa -out ca.key 4096
2.2 生成CA证书
注意修改 IP !!
openssl req -x509 -new -nodes -sha512 -days 3650 \
-subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=192.168.15.61" \
-key ca.key \
-out ca.crt
2.3 生成服务器证书
注意修改 IP !!
openssl genrsa -out 192.168.15.61.key 4096
# 注意:192.168.15.61为本机IP,注意修改!
2.4 生成证书签名
注意修改 IP !!
openssl req -sha512 -new \
-subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=192.168.15.61" \
-key 192.168.15.61.key \
-out 192.168.15.61.csr
# 注意:192.168.15.61为本机IP,注意修改!
2.5 生成x509 v3拓展文件
注意修改 IP !!
cat > v3.ext <<-EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = IP:192.168.15.61
EOF
2.6 通过v3.ext文件生成证书
注意修改 IP !!
openssl x509 -req -sha512 -days 3650 \
-extfile v3.ext \
-CA ca.crt -CAkey ca.key -CAcreateserial \
-in 192.168.15.61.csr \
-out 192.168.15.61.crt
2.7 将证书提供给Docker
# 创建目录
mkdir -p /data/cert/
openssl x509 -inform PEM -in 192.168.15.61.crt -out 192.168.15.61.cert
# 复制证书给docker
mkdir -pv /etc/docker/certs.d/192.168.15.61/
cp 192.168.15.61.cert /etc/docker/certs.d/192.168.15.61/
cp 192.168.15.61.key /etc/docker/certs.d/192.168.15.61/
cp ca.crt /etc/docker/certs.d/192.168.15.61/
2.8 修改Harbor的配置文件
cd /root/harbor/harbor
cp harbor.yml.tmpl harbor.yml
vim harbor.yml # 只需要修改下面三处,其他不修改
hostname: 192.168.15.61
certificate: /data/cert/192.168.15.61.crt
private_key: /data/cert/192.168.15.61.key
2.9 生成Harbor的配置文件
cp /root/harbor/harbor/cert/{192.168.15.61.crt,192.168.15.61.key} /data/cert/
bash /root/harbor/harbor/prepare
2.10 安装Harbor
bash /root/harbor/harbor/install.sh
2.11 浏览器访问
# 访问https://192.168.15.61
# 初始账号admin; 初始密码Harbor12345
3、测试Docker登录Harbor
3.1 docker登录
[root@kubernetes harbor]# docker login 192.168.15.61
Username: admin
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
3.2 浏览器登录harbor创建空间os
3.3 docker上传镜像
[root@kubernetes harbor]# docker tag 5d0da3dc9764 192.168.15.61/os/centos:8
[root@kubernetes harbor]# docker push 192.168.15.61/os/centos:8
The push refers to repository [106.13.81.75/os/centos]
74ddd0ec08fa: Pushed
8: digest: sha256:a1801b843b1bfaf77c501e7a6d3f709401a1e0c83863037fa3aab063a7fdb9dc size: 529