K8S学习之dokcer篇(一)
一. namespace、cgroup在容器中的作用
### 1.、Namespace
namespace 为容器运行提供了相互隔离的运行空间,实现进程之间的相互隔离,通过namespace可以使容器相互之间不受干扰。
namespace可以划分下列6种:uts、ipc、pid、mount、network、user 。
UTS:允许每个container拥有独立的hostname(主机名)和domainname(域名),使其在网络上可以被视作一个独立的节点而非Host上的一个进程。
IPC:contaner中进程交互还是采用linux常见的进程间交互方法,包括常见的信号量,消息队列和共享内存。container的进程间交互实际上还是host上具有相同pid中的进程交互。
PID:不同用户的进程就是通过pid namesapce隔离开的,且不同namespace中可以有相同pid。所有的LXC(linux containers)进程在docker中的父进程为docker进程,每个LXC进程具有不同的namespace。
NET:不同用户的进程就是通过pidnamespace隔离开的,且不同namespace中可以有相同pid。所有的LXC进程在docker中的父进程为docker进程,每个lxc进程具有不同的namespace。
MNT:文件系统的挂载点。
USRE:每个container可以有不同的user和groupid,也就是说可以在container内部用container内部的用户执行程序而非Host上的用户。
二、cgroup
cgroup技术实现了对容器使用资源的限制, 避免单个或多个容器占用资源较大,甚至耗尽资源的情况
cgroup的作用:
(1)实现资源限制:通过cgroup可以控制某个进程消耗的资源,比如CPU,内存,IO等等;
(2)实现负载均衡:cgroup可以将多个容器归类到同一个组,在某个特定资源上, 根据均衡的原则,让每个容器都能够得到合理的分配;
(3)实现容器隔离:cgoup可以将多个容器归类到同一个组,每个容器对另一个容器都不可见,从而达到容器之间的完全隔离。
三、编排工具及依赖技术总结
当多个容器在多个主机运行的时候,单独管理容器是相当复杂而且很容易出错。而且也无法实现某一台主机宕机后,容器自动迁移到其他主机,从而实现高可用的目的,也无法实现动态伸缩的功能,因此需要有一种工具可以实现统一管理、动态伸缩、故障自愈、批量执行等功能,这就是容器编排引擎
容器编排通常包括容器管理、调度、集群定义和服务发现等功能
常用的编排工具
Docker compose:Docker 官方的单机容器编排工具
Docker swarm:Docker 官方的容器编排引擎
Kubernetes:google领导开发的容器编排引擎
四、docker容器依赖的技术
1. 容器网络
docker 服务自带的网络 docker network 仅支持管理单机的容器网络,当多主机运行的时候需要使用第三方开源网络,例如: calico、 flannel、cilium 等
2. 服务发现
容器的动态扩容特性决定了容器IP会随之变化,因此需要有一种机制开源自动识別并将用户请求动态转发到新创建的容器上, kubernetes 自带服务发现功能,需要结合 coredns (早期为 kube-dns)服务解析内部域名
3. 容器监控
可以通过原生命令 docker ps|top|stats 查看容器运行状态,另外也可以使用 Prometheus、heapster 等第三方监控工具监控容器的运行状态
4. 数据管理
容器的动态迁移会导致其在不同的 host 之间迁移,因此需要保证与容器相关的数据也能随之迁移或随时访问,可以使用逻辑卷存储挂载等方式解决
5. 日志收集
docker 服务自带日志查看工具 docker logs,但是容器内部的日志需要通过 ELK 等专门的日志收集分析和展示工具处理
五、基于dockerfile制作一个nginx镜像
1. 创建dockerfile 文件
root@master001:~# mkdir project root@master001:~# cd project && touch dockerfile
root@master001:~/project# cat dockerfile FROM centos:7.6.1810 ADD nginx-1.18.0.tar.gz /root RUN rm -rf /etc/yum.repos.d/* COPY base.repo /etc/yum.repos.d/ RUN yum clean all && yum install make gcc gcc-c++ zlib-devel pcre-devel -y RUN cd /root/nginx-1.18.0 && ./configure && make && make install CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
3. 生成镜像并运行nginx 镜像
root@master001:~/project# docker build -t nginx:v1 .
Successfully built 291dfaf2c1b6
Successfully tagged nginx:v1
root@master001:~/project#
root@master001:~/project#
root@master001:~/project#
root@master001:~/project#
root@master001:~/project# docker images ##查看本地镜像,可以看到nginx:v1镜像已经生成
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v1 291dfaf2c1b6 29 seconds ago 366MB
goharbor/harbor-exporter v2.3.2 37f41f861e77 18 months ago 81.1MB
goharbor/chartmuseum-photon v2.3.2 ad5cd42a4977 18 months ago 179MB
goharbor/redis-photon v2.3.2 812c6f5c260b 18 months ago 155MB
goharbor/trivy-adapter-photon v2.3.2 3f07adb2e138 18 months ago 130MB
goharbor/notary-server-photon v2.3.2 49aadd974d6d 18 months ago 110MB
goharbor/notary-signer-photon v2.3.2 6051589deaf9 18 months ago 108MB
goharbor/harbor-registryctl v2.3.2 0e551984a22c 18 months ago 133MB
root@master001:~/project# docker run -d -p 1234:80 nginx:v1 ##后台运行容器,并将宿主机的1234端口映射给容器的80端口
e284f6ab49dcb073f21aeca7c3e5240a958d3c7eb3d69b17e38bd938c871ed5b
root@master001:~/project# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e284f6ab49dc nginx:v1 "/usr/local/nginx/sb…" 5 seconds ago Up 4 seconds 0.0.0.0:1234->80/tcp goofy_diffie ##可以看到容器已经运行起来了
65c8db9fd7d3 goharbor/harbor-jobservice:v2.3.2 "/harbor/entrypoint.…" 4 weeks ago Up 4 weeks (healthy) harbor-jobservice
8670d06e5a15 goharbor/nginx-photon:v2.3.2 "nginx -g 'daemon of…" 4 weeks ago Up 4 weeks (healthy) 0.0.0.0:80->8080/tcp nginx
fb8016222f08 goharbor/harbor-core:v2.3.2 "/harbor/entrypoint.…" 4 weeks ago Up 4 weeks (healthy) harbor-core
aa7ae87d2bf5 goharbor/redis-photon:v2.3.2 "redis-server /etc/r…" 4 weeks ago Up 4 weeks (healthy) redis
ab6cd8e6aff5 goharbor/registry-photon:v2.3.2 "/home/harbor/entryp…" 4 weeks ago Up 4 weeks (healthy) registry
ed09211013cc goharbor/harbor-db:v2.3.2 "/docker-entrypoint.…" 4 weeks ago Up 4 weeks (healthy) harbor-db
e2cb3610c5bc goharbor/harbor-registryctl:v2.3.2 "/home/harbor/start.…" 4 weeks ago Up 4 weeks (healthy) registryctl
fa9e90cc07e8 goharbor/harbor-portal:v2.3.2 "nginx -g 'daemon of…" 4 weeks ago Up 4 weeks (healthy) harbor-portal
fd4029c1124d goharbor/harbor-log:v2.3.2 "/bin/sh -c /usr/loc…" 4 weeks ago Up 4 weeks (healthy) 127.0.0.1:1514->10514/tcp harbor-log
root@master001:~/project# ss -utpanl |grep -i 1234 ##查看端口监听状态, 1234 端口已被监听
tcp LISTEN 0 4096 *:1234 *:* users:(("docker-proxy",pid=3702843,fd=4))
root@master001:~/project# iptables -L -t nat ##查看iptables中的端口妆发规则,可以发现宿主机的1234端口转发给了容器的80端口
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DOCKER all -- anywhere anywhere ADDRTYPE match dst-type LOCAL
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
DOCKER all -- anywhere !localhost/8 ADDRTYPE match dst-type LOCAL
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
MASQUERADE all -- 172.17.0.0/16 anywhere
MASQUERADE all -- 172.18.0.0/16 anywhere
MASQUERADE tcp -- 172.18.0.2 172.18.0.2 tcp dpt:10514
MASQUERADE tcp -- 172.18.0.10 172.18.0.10 tcp dpt:http-alt
MASQUERADE tcp -- 172.17.0.2 172.17.0.2 tcp dpt:http
Chain DOCKER (2 references)
target prot opt source destination
RETURN all -- anywhere anywhere
RETURN all -- anywhere anywhere
DNAT tcp -- anywhere localhost tcp dpt:1514 to:172.18.0.2:10514
DNAT tcp -- anywhere anywhere tcp dpt:http to:172.18.0.10:8080
DNAT tcp -- anywhere anywhere tcp dpt:1234 to:172.17.0.2:80
六、镜像构建总结
1:FROMFROM : Dockerfile中第一条指令必须是FROM指令,表示从哪个基础镜像开始构建镜像
2:MAINTAINER
MAINTAINER : 镜像维护者个人信息,维护者的姓名和邮箱
3:RUN
RUN : 构建镜像时需要执行的命令,有两种命令执行方式
dockerfile每一条命令为一层,多条命令最好用最少的RUN命令执行,镜像的层数高了造成镜像的臃肿,不仅仅增加了构件部署的时间,还容易出错
4:ADD
ADD :将本地文件添加到构建的镜像中,tar类型文件会自动解压
5:COPY
COPY: 将本地文件复制至构建的镜像中
6.CMD
CMD : 指定镜像启动为容器后默认执行的命令,每个 Dockerfile 只能有一条 CMD 命令;如果指定了多条命令,只有最后一条会被执行,如果用户启动容器时候指定了运行的命令,则会覆盖掉 CMD 指定的命令
7:ENTRYPOINT
ENTRYPOINT : 类似于 CMD 指令,但其不会被创建容器时指定的命令覆盖,如果创建容器时指定了命令那么这些命令会被当作参数送给 ENTRYPOINT 指令指定的程序;CMD 和ENTRYPOINT 同在时 CMD 的内容会被当作参数传递给 ENTRYPOINT 指定的命令。
8:ENV
ENV :设置环境变量。此环境变量为镜像启动为容器之后容器中的环境变量
9:EXPOSE
EXPOSE :指定镜像启动为容器后开放的端口
10:WORKDIR
WORKDIR :工作目录,类似于cd命令
11:USER
USER :指定运行容器时的用户名或 UID,后续的 RUN 也会使用指定用户。使用USER指定用户时,可以使用用户名、UID或GID,或是两者的组合。当服务不需要管理员权限时,可以通过该命令指定运行用户。并且可以在之前创建所需要的用户
11:LABEL
LABEL指令用于让用户为镜像指定各种元数据(键值对的格式)
12:VOLUME
VOLUME指令用于在镜像中创建一个挂载点目录。Volume有两种类型:绑定挂载卷和docker管理的卷。在Dockerfile中只支持Docker管理的卷,也就是说只能指定容器内的路径,不能指定宿主机的路径。