云原生训练营模块三 Docker核心技术
Posted 果子哥丶
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了云原生训练营模块三 Docker核心技术相关的知识,希望对你有一定的参考价值。
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 配置
以上是关于云原生训练营模块三 Docker核心技术的主要内容,如果未能解决你的问题,请参考以下文章
云原生训练营模块四 Kubernetes 架构原则和对象设计