## 1、docker概念
### docker的组成
```bash
build(构建镜像)--------Registry(将镜像上传到仓库)-------container(创建容器)
docker host(docker的宿主机):可以是一台物理服务器也可以是一台虚拟机
docker server (docker的服务端):用来运行docker容器的
docker client (docker 客户端):通过使用docker命令或其他工具来调用docker API
docker Registry(镜像仓库):用来存储镜像的
docker images(docker 镜像):相当于实例模板,前期构建好后期直接拿来使用
docker container (docker 容器) :从镜像生成一个或一组对外提供服务的容器(意外之意一个容器可以部署一个服务或多个服务供客户访问)
docker和虚拟机的对比
docker对比虚拟机的优点:
1、资源利用率更高:一台物理机或者一台虚拟机可以运行数百上千台容器,但是一般只能运行数十个虚拟机
2、开销更小:docker容器不需要启动单独的虚拟机占用硬件资源(意外之意:docker可以和宿主机一起使用硬件资源),但是虚拟机需要单独再启动个虚拟机然后使用重新启动的虚拟机资源
3、启动的速度更快:可以在数秒内完成启动,但是虚拟机重新启动速度较慢,还有启动失败的风险
4、安全性、隔离性:docker资源隔离性没有虚拟机好,安全性也不如虚拟机
2、Linux Namespace技术
思考:
1、怎么确保同一宿主机上的每个容器有不同的文件系统且容器之间不会相互影响
2、一个docker主进程内的各个容器都是其子进程,那么都一个进程下的不同类型的子进程可以通信相互访问吗?
3、每个容器的Ip和端口怎么分配?
4、容器的主机名可以一样吗?
5、每个容器要不要有root用户?如何解决不同容器存在相同用户的问题?
namespace是Linux的底层概念,在内核层实现的,即有一些不同类型的命名空间被部署在核内,各个docker容器运行在同一个docker主进程并且共用同一个宿主机系统内核,各docker容器运行在宿主机的用户空间,每个容器都要有类似于虚拟机一样的相互隔离的运行空间,但是容器技术是在一个进程内实现运行指定服务的运行环境,并且还可以保护宿主机内核不受其他进程的干扰和影响,如文件系统空间、网络空间、进程空间等
隔离类型 | 功能 |
MNT Namespace | 提供磁盘挂载点和文件系统的隔离能力 |
IPC Namespace | 提供进程间通信的隔离能力 |
UTS Namespace | 提供主机名隔离能力 |
PID Namespace | 提供进程隔离能力 |
Net Namespace | 提供网络隔离能力 |
User Namespace | 提供用户隔离能力 |
1、MNT Namespace:
概念:
每个容器都要有独立的根文件系统有独立的用户空间,以实现在容器里面启动服务并且使用容器的运行环境,即一个宿主机是ubuntu的服务器,可以在里面启动一个centos运行环境的容器并且在容器里面启动一个Nginx服务,此Nginx运行
时使用的运行环境就是centos系统目录的运行环境,但是在容器里面是不能访问宿主机的资源,宿主机是使用了chroot技术把容器锁定到一个指定的运行目录里面并作为容器的根运行环境
如图:
2、IPC Namespace
概念:
容器内的进程间通信,允许容器内的不同进程的访问
3、UTS Namespace
概念:
和其上的其他容器。UTS namespace(UNIXTimesharing System包含了运行内核的名称、版本、底层体系结构类型等信息)用于系统标识,其中包含了hostname 和域名domainname ,它使得一个容器拥有属于自己hostname标识,这个主机名标识独立于宿主机系统和其上的其他容器。
4、PID Namespace
##### 概念:
```bash
Linux系统中,有一个PID为1的进程(init/systemd)是其他所有进程的父进程,那么在每个容器内也要有一个父进程来管理其下属的子进程,那么多个容器的进程通PIDnamespace进程隔离(比如PID编号重复、器内的主进程生成与回收子进程等)
5、Net Namespace
概念:
每一个容器都类似于虚拟机一样有自己的网卡、监听端口、TCP/IP协议栈等,Docker使用networknamespace启动一个vethX接口,这样你的容器将拥有它自己的桥接ip地址,通常是docker0,而docker0实质就是Linux的虚拟网桥,网桥是在OSI七层模型的数据链路层的网络设备,通过mac地址对网络进行划分,并且在不同网络直接传递数据
6、User Namespace
概念:
各个容器内可能会出现重名的用户和用户组名称,或重复的用户UID或者GID,那么怎么隔离各个容器内的用户空间呢?User Namespace允许在各个宿主机的各个容器空间内创建相同的用户名以及相同的用户UID和GID,只是会把用户的作用范围限制在每个容器内,即A容器和B容器可以有相同的用户名称和ID的账户,但是此用户的有效范围仅是当前容器内,不能访问另外一个容器内的文件系统,即相互隔离、互补影响、永不相见
3、docker资源限制
在一个容器内,如果不对其做资源限制,则宿主机会允许其占有无限大的内存空间,有时会因为代码bug程序会一直申请内存,直到把宿主机内存占完,为了避免此类情况,宿主机对容器进行资源限制,如CPU、内存等资源限制,Linux Cgroups它最主要的作用就是限制一个进程能够使用的资源上限和对进程进行优先级设置,以及将进程挂起和恢复等操作。
4、容器的常用命令
docker search images_name #搜索镜像
docker save images_name > images_name.tar = docker save nginx -o nginx.tar #导出镜像
docker load < images_name.tar = docker load -i nginx.tar #导入镜像
docker images #查看镜像
docker ps #查看正在运行的容器
docker ps -a #查看所有的容器(包括已经停止的)
docker rm #删除容器
docker rmi #删除镜像
docker pull image_name #下载镜像
docker tag nginx:1.8.1 nginx:v1 #给镜像打标签
docker inspect container_name #查看容器的详细信息
docker logs container_name #查看容器的日志信息
docker top container_name #查看容器的各项指标
docker stop contain_name #停止正在运行的容器
docker start container #开启容器
docker login 仓库地址 #登录镜像仓库
docker cp CONTAINER:SRC_PATH DEST_PATH #把容器的文件拷备到宿主机
docker cp SRC_PATH CONTAINER:DEST_PATH #把宿主机的文件拷备到容器
docker push Registry #上传镜像文件到仓库
docker build -t #构建镜像
[centos@root]#docker info
Client:
Debug Mode: false
Server:
Containers: 3 #当前主机运行的容器总数
Running: 1 #正在运行的容器个数
Paused: 0 #暂停容器的个数
Stopped: 2 #停止容器的个数
Images: 1 #当前服务器的镜像数
Server Version: 19.03.15 #docker服务的版本
Storage Driver: overlay2 #正在使用的存储引擎
Backing Filesystem: xfs #服务器的磁盘文件系统
Supports d_type: true #是否存储分层(只有支持时docker的引擎才能是overlay2)
Native Overlay Diff: true #是否支持差异数据存储
Logging Driver: json-file #日志的类型
Cgroup Driver: cgroupfs #cgroup(资源限制)的类型
Plugins:
Volume: local #卷的挂载路径
Network: bridge host ipvlan macvlan null overlay #通信的模式
Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog #日志的类型
Swarm: inactive #是否支持swarm
Runtimes: runc #已安装的容器运行时
Default Runtime: runc #默认使用的容器运行时
Init Binary: docker-init #初始化容器的守护进程,即pid为1的进程
containerd version: ea765aba0d05254012b0b9e595e995c09186427f
runc version: dc9208a3303feef5b3839f4323d9beb36df0a9dd
init version: fec3683
Security Options:
seccomp
Profile: default
Kernel Version: 3.10.0-1160.el7.x86_64 #宿主机的内核版本
Operating System: CentOS Linux 7 (Core) #宿主机的操作版本
OSType: linux #宿主机操作系统类型
Architecture: x86_64 #宿主机架构
CPUs: 1 #宿主机CPU数量
Total Memory: 972.3MiB #宿主机内存
Name: docker-server1 #宿主机主机名
ID: OVIP:3E2F:5QK5:SB67:JZXU:LOXL:2HQE:47UW:YDSH:AZEO:Q6FN:AIDZ #宿主机ID
Docker Root Dir: /var/lib/docker #宿主机数据的保存目录
Debug Mode: false
Registry: https://index.docker.io/v1/ #镜像仓库
Labels: #其他标签
Experimental: false #是否是测试版
Insecure Registries: #非安全的镜像仓库
127.0.0.0/8
Registry Mirrors: #镜像加速器
https://uxlgig3a.mirror.aliyuncs.com/
Live Restore Enabled: false
Product License: Community Engine
5、dockerfile
FROM centos:7.2009.3 #指定父镜像,除了注释外FROM位于dockerfile的第一行
ADD #把宿主机的文件、目录、压缩等资源传递到镜像里面去,并且会自动解压tar.gz格式的压缩包
LABEL "key" = "value" #设置镜像的属性标签
COPY #把宿主机的文件、目录、压缩等资源传递到镜像里面去但是不会自动解压任何压缩包
ENV #设置环境变量
USER #指定运行操作的用户
RUN #执行shell命令,但是一定以非交互式的方式执行
VOLUME #挂载卷
EXPOSE #把容器的某些端口映射给宿主机
###注意点#######
CMD和ENDPOINT的区别
1、CMD的概念
CMD ["executable","param1","param2"] (exec form, this is the preferred form) #推荐的可执行程序方式
CMD ["param1","param2"] (as default parameters to ENTRYPOINT) #作为ENTRYPOINT默认参数
CMD command param1 param2 (shell form) #基于shell命令的
#CMD有以上三种方式定义镜像启动为一个容器时候所执行的默认命令或脚本
2、ENDPOINT
ENTRYPOINT #也可以用于定义容器在启动时候默认执行的命令或者脚本,如果是和CMD命令混合使用的时候,会将CMD的命令当做参数传递给ENTRYPOINT后面的脚本,可以在脚本中对参数做判断并相应的容器初始化操作
例如:打nginx服务的dockerfile文件
# Nginx image
FROM ubuntu:20.04
LABEL "maintainer"= "wengshiqiang" "2923035330@qq.com"
COPY sources.list /etc/apt/sources.list
RUN apt update && apt install -y iproute2 ntpdate tcpdump telnet traceroute nfs-kernel-server nfs-common lrzsz tree openssl libssl-
dev libpcre3 libpcre3-dev zlib1g-dev ntpdate tcpdump telnet traceroute gcc openssh-server iotop unzip zip make vim && mkdir
/data/nginx -p
ADD nginx-1.20.2.tar.gz /usr/local/src
RUN cd /usr/local/src/nginx-1.20.2 && ./configure --prefix=/apps/nginx && make && make install && ln -sv /apps/nginx/sbin/nginx
/usr/bin && rm -rf /usr/local/src/nginx-1.20.2 && rm -rf /usr/local/src/nginx-1.20.2.tar.gz
#ADD nginx.conf /apps/nginx/conf/nginx.conf
#ADD static.tar.gz /data/nginx/html
RUN ln -sv /dev/stdout /apps/nginx/logs/access.log
RUN ln -sv /dev/stderr /apps/nginx/logs/error.log
RUN groupadd -g 2022 nginx && useradd -g nginx -s /usr/sbin/nologin -u 2022 nginx && chown -R nginx.nginx /apps/nginx
/data/nginx
EXPOSE 80 443
CMD ["/apps/nginx/sbin/nginx","-g","daemon off;"
6、docker的通信
1、docker和宿主机间可以通信吗?
2、docker和docker间可以通信吗?
3、docker和客户间可以通信吗?