云原生训练营模块三docker核心技术(代码片段)

果子哥丶 果子哥丶     2022-12-11     445

关键词:

Docker核心技术

1、系统架构


微服务改造:
分离微服务的方法建议:
• 审视并发现可以分离的业务逻辑业务逻辑
• 寻找天生隔离的代码模块,可以借助于静态代码分析工具
• 不同并发规模,不同内存需求的模块都可以分离出不同的微服务,此方法可提高资源利用率,节省成本
一些常用的可微服务化的组件:
• 用户和账户管理
• 授权和会话管理
• 系统配置
• 通知和通讯服务
• 照片,多媒体,元数据等

微服务间通讯
点对点

API网关
服务发现、调用、鉴权

2、Docker

Docker概念

  • 基于 Linux 内核的 Cgroup,Namespace,以及 Union FS 等技术,对进程进行封装隔离,属于操作系统层面的虚拟化技术,由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。
  • 最初实现是基于 LXC,从 0.7 以后开始去除 LXC,转而使用自行开发的 Libcontainer,从 1.11 开始,则进一步演进为使用 runC 和 Containerd。
  • Docker 在容器的基础上,进行了进一步的封装,从文件系统、网络互联到进程隔离等等,极大的简化了容器的创建和维护,使得 Docker 技术比虚拟机技术更为轻便、快捷。

Docker好处:

  • 更高效地利用系统资源
  • 更快速的启动时间
  • 一致的运行环境
  • 持续交付和部署
  • 更轻松地迁移
  • 更轻松地维护和扩展

安装Docker

在 ubuntu 上安装 Docker 运行时,参考 https://docs.docker.com/engine/install/ubuntu/
$ sudo apt-get update
$ sudo apt-get install \\
apt-transport-https \\
ca-certificates \\
curl \\
gnupg-agent \\
software-properties-common
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo add-apt-repository \\
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \\
$(lsb_release -cs) \\
stable"
$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io

容器操作

启动:docker run
-it 交互
-d 后台运行
-p 端口映射
-v 磁盘挂载

启动已终止容器:docker start

停止容器:docker stop

查看容器进程:docker ps

查看容器细节:docker inspect <containerid>

进入容器:docker exec -it xxx bash

Docker attach
通过 nsenter
PID=$(docker inspect --format " .State.Pid " <container>)
$ nsenter --target $PID --mount --uts --ipc --net --pid

查询docker内容器的pid:docker inspect xxx | grep -i pid


#进入当前容器后开启一个新的终端,可以在里面操作。(常用)
docker exec 
#进入容器正在执行某个命令的终端,不能在里面操作
docker attach

拷贝文件至容器内:
docker cp file1 <containerid>:/file-to-path

将 Dockerfile 打包成镜像

docker build -t cncamp/httpserver:$tag .
docker push cncamp/httpserver:v1.0

运行容器
docker run -d cncamp/httpserver:v1.0

六大子系统


关于namespace的常用操作

查看当前系统的 namespace:
lsns –t <type>

查看某进程的 namespace:
ls -la /proc/<pid>/ns/

进入某 namespace 运行命令:
nsenter -t <pid> -n ip addr
1、在新 network namespace 执行 sleep 指令:
unshare -fn sleep 60

2、查看进程信息
ps -ef|grep sleep
root       32882    4935  0 10:00 pts/0    00:00:00 unshare -fn sleep 60
root       32883   32882  0 10:00 pts/0    00:00:00 sleep 60

3、查看网络 Namespace
lsns -t net
4026532508 net       2 32882 root unassigned                                unshare

4、进入改进程所在 Namespace 查看网络配置,与主机不一致
nsenter -t 32882 -n ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

Cgroups

  • Cgroups (Control Groups)是 Linux 下用于对一个或一组进程进行资源控制和监控的机制;
  • 可以对诸如 CPU 使用时间、内存、磁盘 I/O 等进程所需的资源进行限制;
  • 不同资源的具体管理工作由相应的 Cgroup 子系统(Subsystem)来实现 ;
  • 针对不同类型的资源限制,只要将限制策略在不同的的子系统上进行关联即可 ;
  • Cgroups 在不同的系统资源管理子系统中以层级树(Hierarchy)的方式来组织管理:每个 Cgroup 都可以
    包含其他的子 Cgroup,因此子 Cgroup 能使用的资源除了受本 Cgroup 配置的资源参数限制,还受到父
    Cgroup 设置的资源限制 。


文件系统

Union FS

  • 将不同目录挂载到同一个虚拟文件系统下 (unite several directories into a single virtual filesystem)的文件系统

Linux

  • 在启动后,首先将 rootfs 设置为 readonly, 进行一系列检查, 然后将其切换为 “readwrite”供用户使用。

Docker 启动

  • 初始化时也是将 rootfs 以 readonly 方式加载并检查,然而接下来利用 union mount 的方式将一个readwrite 文件系统挂载在 readonly 的 rootfs 之上;
  • 并且允许再次将下层的 FS(file system) 设定为 readonly 并且向上叠加。
  • 这样一组 readonly 和一个 writeable 的结构构成一个 container 的运行时态, 每一个 FS 被称作一个 FS层

容器存储驱动

以OverlayFS为例
OverlayFS 也是一种与 AUFS 类似的联合文件系统,同样属于文件级的存储驱动,包含了最初的 Overlay 和更新更稳定的 overlay2。

Overlay 只有两层:upper 层和 lower 层,Lower 层代表镜像层,upper 层代表容器可写层。

网络模型

Null(–net=None)

  • 把容器放入独立的网络空间但不做任何网络配置;
  • 用户需要通过运行 docker network 命令来完成网络配置。

Host

  • 使用主机网络名空间,复用主机网络。

Container

  • 重用其他容器的网络。

Bridge(–net=bridge)

  • 使用 Linux 网桥和 iptables 提供容器互联,Docker 在每台主机上创建一个名叫 docker0的网桥,通过 veth pair 来连接该主机的每一个 EndPoint。

Remote(work with remote drivers)

  • Underlay:使用现有底层网络,为每一个容器配置可路由的网络IP
  • Overlay:通过网络封包实现,跨主机网络,是一个内置的基于 VXLAN 的网络驱动。


这一个过程是docker的驱动做的,在容器启动进行端口映射的时候,会写入到iptables-save -t nat

测试自主搭建network
https://github.com/cncamp/101/blob/master/module3/setup-network.md

1、Create network ns
mkdir -p /var/run/netns
find -L /var/run/netns -type l -delete

2、Start nginx docker with non network mode
docker run --network=none  -d nginx
Check corresponding pid
docker ps|grep nginx
docker inspect <containerid>|grep -i pid
"Pid": 876884,
"PidMode": "",
"PidsLimit": null,

3、Check network config for the container
nsenter -t 876884 -n ip a

4、Link network namespace
export pid=876884
ln -s /proc/$pid/ns/net /var/run/netns/$pid
ip netns list

5、Check docker bridge on the host
brctl show
ip a
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:35:40:d3:8b brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:35ff:fe40:d38b/64 scope link
       valid_lft forever preferred_lft forever

6、Create veth pair
ip link add A type veth peer name B

7、Config A
brctl addif docker0 A
ip link set A up

8、Config B
SETIP=172.17.0.10
SETMASK=16
GATEWAY=172.17.0.1
ip link set B netns $pid
ip netns exec $pid ip link set dev B name eth0
ip netns exec $pid ip link set eth0 up
ip netns exec $pid ip addr add $SETIP/$SETMASK dev eth0
ip netns exec $pid ip route add default via $GATEWAY

9、Check connectivity
curl 172.17.0.10

VXLAN

Overlay network sample — Flannel

  • 同一主机内的 Pod 可以使用网
    桥进行通信。
  • 不同主机上的 Pod 将通过
    flanneld 将其流量封装在 UDP
    数据包中。


理解构建上下文(Build Context)

  • 当运行 docker build 命令时,当前工作目录被称为构建上下文。
  • docker build 默认查找当前目录的 Dockerfile 作为构建输入,也可以通过 -f 指定 Dockerfile。
  • docker build -f ./Dockerfile
  • 当 docker build 运行时,首先会把构建上下文传输给 docker daemon,把没用的文件包含在构建上下文时,会导致传输时间长,构建需要的资源多,构建出的镜像大等问题。
  • 试着到一个包含文件很多的目录运行下面的命令,会感受到差异;
    • docker build -f $GOPATH/src/github.com/cncamp/golang/httpserver/Dockerfile;
    • docker build $GOPATH/src/github.com/cncamp/golang/httpserver/;
  • 可以通过.dockerignore文件从编译上下文排除某些文件。
  • 因此需要确保构建上下文清晰,比如创建一个专门的目录放置 Dockerfile,并在目录中运行 docker build。

Build Cache

构建容器镜像时,Docker 依次读取 Dockerfile 中的指令,并按顺序依次执行构建指令。

Docker 读取指令后,会先判断缓存中是否有可用的已存镜像,只有已存镜像不存在时才会重新构建。

  • 通常 Docker 简单判断 Dockerfile 中的指令与镜像。
  • 针对 ADD 和 COPY 指令,Docker 判断该镜像层每一个文件的内容并生成一个 checksum,与现存镜像比较时,Docker 比较的是二者的 checksum。
  • 其他指令,比如 RUN apt-get -y update,Docker 简单比较与现存镜像中的指令字串是否一致。
  • 当某一层 cache 失效以后,所有层级的 cache 均一并失效,后续指令都重新构建镜像。

Dockerfile常用指令







Docker镜像管理

docker save/load
docker tag
docker push/pull

docker tag 命令可以为容器镜像添加标签
docker tag 0e5574283393 hub.docker.com/cncamp/httpserver:v1.0
hub.docker.com: 镜像仓库地址,如果不填,则默认为 hub.docker.com
cncamp: repositry
httpserver:镜像名
v1.0:tag,常用来记录版本信息


创建私有镜像仓库
docker run -d -p 5000:5000 registry

课后练习

  • 编写 Dockerfile 将练习 2.2 编写的 httpserver 容器化
    FROM ubuntu
    ENV MY_SERVICE_PORT=80
    ENV MY_SERVICE_PORT1=80
    ENV MY_SERVICE_PORT2=80
    ENV MY_SERVICE_PORT3=80
    LABEL multi.label1="value1" multi.label2="value2" other="value3"
    ADD bin/amd64/httpserver /httpserver
    EXPOSE 80
    ENTRYPOINT /httpserver
    
  • 通过 nsenter 进入容器查看 IP 配置

云原生训练营模块一1.1go语言特性(代码片段)

Go语言特性如何学习云原生技术?构建高可用微服务架构统一思想Go语言Go语言特点Go语言编译环境控制结构数据结构如何学习云原生技术?代码驱动掌握Go语言编程能力从点到面学习容器技术cgroup,namespace网络协议栈... 查看详情

云原生训练营模块四kubernetes架构原则和对象设计(代码片段)

Kubernetes架构原则和对象设计K8s安装K8s概念K8s架构控制器的工作流程了解KubectlKubernetes生态系统常用Kubernetes对象及其分组核心技术概念和API对象TypeMeta核心对象概览课后练习K8s安装CentOS7利用Kubeadm快速部署Kubernetes集群K8s概念Kubernete... 查看详情

云原生生态圈:docker核心技术全面总结(代码片段)

...专栏将从基础开始,循序渐进,由浅入深讲解云原生相关知识,希望大家都能够从中有所收获,也请大家多多支持。专栏地址:云原生专栏如果文章知识点有错误的地方,请指正!大家一起学习,一起进... 查看详情

云原生|docker-一文了解docker(代码片段)

...推动了虚拟化、容器化技术的产生和发展,以及现在的云原生时代的到来,都极大提高了其资源利用率。DockerDocker本身不是容器,它只是一个应用容器引擎,这么解释可能有些抽象,大家理解下面内容。三大核心镜像(Image)容器... 查看详情

云原生|docker-一文了解docker(代码片段)

...推动了虚拟化、容器化技术的产生和发展,以及现在的云原生时代的到来,都极大提高了其资源利用率。DockerDocker本身不是容器,它只是一个应用容器引擎,这么解释可能有些抽象,大家理解下面内容。三大核心镜像(Image)容器... 查看详情

云原生训练营模块八kubernetes生命周期管理和服务发现(代码片段)

生命周期管理和服务发现1、深入理解Pod的生命周期管理Pod的生命周期pod创建的时候,经历了哪些过程?initCPod状态计算细节如何确保Pod的高可用基于Taint的Evictions健康探针前置后置Post-start&Pre-stop钩子容器应用可能面临... 查看详情

云原生训练营模块八kubernetes生命周期管理和服务发现(代码片段)

生命周期管理和服务发现1、深入理解Pod的生命周期管理Pod的生命周期pod创建的时候,经历了哪些过程?initCPod状态计算细节如何确保Pod的高可用基于Taint的Evictions健康探针前置后置Post-start&Pre-stop钩子容器应用可能面临... 查看详情

云原生训练营模块二go语言进阶(代码片段)

这里写目录标题函数Main函数init函数传递变长参数内置函数回调函数闭包接口反射机制常用语法错误处理deferPanic和recover多线程channel-多线程通信通道缓冲遍历通道缓冲区关闭通道Select定时器Timer上下文Context如何停止一个子协程线... 查看详情

猿创征文|云原生领域之容器日常使用工具推荐(代码片段)

猿创征文|云原生领域之容器日常使用工具推荐一、云原生介绍1.云原生定义2.容器技术简介3.云原生相关工具导航二、Docker1.Docker介绍①Docker简介②Docker特点③Docker的三个基本概念④Docker的架构图2.Docker的优势3.Docker的使用效果①... 查看详情

云原生训练营模块六kubernetes控制平面组件:apiserver(代码片段)

APIServer0、APIServer概念1、认证基于webhook的认证服务集成构建符合Kubernetes规范的认证服务1、开发认证服务2、配置apiserver2、鉴权Role与ClusterRole账户/组的管理3、准入准入控制准入控制插件4、限流计数器固定窗口算法漏斗算法... 查看详情

云原生训练营模块五kubernetes控制平面组件:etcd(代码片段)

etcd----------Part1----------etcd概述etcd功能与场景服务注册与发现,消息发布与订阅Etcd的安装etcd工具练习Raft协议❤etcd基于Raft的一致性选举方法日志复制安全性失效处理wal日志----------Part2----------etcdv3存储,Watch以及过期机制... 查看详情

云原生训练营模块五kubernetes控制平面组件:etcd(代码片段)

etcd----------Part1----------etcd概述etcd功能与场景服务注册与发现,消息发布与订阅Etcd的安装etcd工具练习Raft协议❤etcd基于Raft的一致性选举方法日志复制安全性失效处理wal日志----------Part2----------etcdv3存储,Watch以及过期机制... 查看详情

云原生核心技术之——kubernetes(代码片段)

...发人员、运维人员的噩梦。前面的篇章已经总体介绍了云原生技术体系,体系中的‘微服务’、‘容器’技术,今天给大家介绍的便是云原生技术体系中的‘容器编排引擎——Kubernetes’。回顾:::hljs-center图云原生核心技术:::微服... 查看详情

docker手把手教程公有云&核心技术(代码片段)

...;简称ACR)是面向容器镜像、HelmChart等符合OCI标准的云原生制品安全托管及高效分发平台。ACR支持全球同步加速、大规模/大镜像分发加速、多代码源构建加速等全链路提效,与容器服务ACK无缝集成,帮助企业降低交付... 查看详情

云原生训练营模块六kubernetes控制平面组件:apiserver(代码片段)

APIServer0、APIServer概念1、认证基于webhook的认证服务集成构建符合Kubernetes规范的认证服务1、开发认证服务2、配置apiserver2、鉴权Role与ClusterRole账户/组的管理3、准入准入控制准入控制插件4、限流计数器固定窗口算法漏斗算法... 查看详情

云原生一文带你搞懂docker容器的核心基石cgroups(代码片段)

目录大家好,本文是对Docker容器的核心基石Cgroups的详细讲解,讲解了Cgroups的相关概念、Cgroups的构成与作用、如何查看和使用Cgroups等,对大家后续理解容器有很大的帮助~1、为什么要了解Cgroups2、Cgroups简介3、什么是Cg... 查看详情

『云原生·docker』docker-compose容器编排(代码片段)

...主要分为以下六大部分,正在更新中,尽请期待!『云原生·生之门』『云原生·前置知识』『云原生·Docker』『云原生·Kubernetes』『云原生·KubeSphere』『云原生·DevOps』🚩点击关注本专栏提示:已经更新的或正在更新的... 查看详情

云原生•docker用故事给老板讲docker核心原理成功装逼(代码片段)

用故事给老板讲Docker核心原理成功装逼Docker是什么?「Docker使用Google公司推出的Go语言进行开发实现,基于操作系统内核中Cgroup(资源控制)、Namespace(资源隔离)与OverlayFS(数据存储)等技术,实现了基于操作系统层面的虚... 查看详情