四时宝库

程序员的知识宝库

Docker记录(docker记录了重启过容器的日志嘛)

知识点回顾

  • Docker命令
  • docker run/start/restart/kill/exec
  • docker inspect/top/logs
  • docker save/export/import
  • docker build/tag/push

Dockerfile写法

  • FROM
  • MAINTAINER
  • RUN
  • USER
  • VOLUME
  • WORKDIR
  • CMD 每个容器只能执行一条CMD命令,多个CMD命令时,只最后一条被执行
  • ENV
  • ADD/COPY
  • EXPOST
  • ENTRYPOINT 配置容器启动后执行的命令,并且不可被 docker run 提供的参数覆盖。

拆解docker/容器


容器镜像通过UnionFS(联合文件系统)将不同的目录挂载到同一个虚拟文件系统下 ,创建一个新的层叠加上去作为一个可读可写层,然后通过change root(chroot dir/)对根目录进行一个限制,在通过namespace命名空间对内核全局资源进行封装,达到资源隔离的目的。Cgroup技术对一组进程的cpu,内存,磁盘io,网络带宽等资源进行限制。

解压镜像

root@ubuntu:~# docker  pull  busybox
root@ubuntu:~# docker  image  save  busybox  -o  busybox.tar
root@ubuntu:~# mkdir  -p  /var/lib/fmeng/busybox
root@ubuntu:~# tar  -xf  busybox.tar  -C  /var/lib/fmeng/busybox/
tar  xf  layer.tar
chroot  /var/lib/fmeng/busybox/75fae911f860e3d9d6898b7af34a3b96374dcb33ee9d8b7a6230b74d4a1f30d4/  /bin/sh

OverlayFS文件系统

  • https://zh.wikipedia.org/zh-cn/OverlayFS
  • OverlayFS是一个面向Linux的文件系统服务,其实现一个面向其他文件系统的联合挂载。

Overlayfs的基本理念

  1. 只读底层和可写顶层叠加在一起,看起来像一个单一的文件系统。
  2. 在这种情况下,目录被叠加,文件从顶部看。
  3. 如果有冲突,对于文件,顶层将优先考虑,而对于目录,顶层将被合并。
  4. 如果你编辑一个只在底部的文件(只读),在顶部会有一个副本。

实验

为了进行overlayfs,你需要以下四个目录

  • work:工作目录,与上层文件系统相同,必须为空。
  • lower: 下一级的目录。 它是只读的,可以使用各种文件系统。
  • upper: 上层目录。它必须是可写的,并返回适当的d_type的readdir,所以不能使用NFS。
  • merged:overlayfs被挂载到的目录。

准备以下三个文件来测试

  • both:上面和下面都有的文件
  • only_upper: 只存在于顶部的文件
  • only_lower: 只存在于底部的文件
azureuser@build:~$ mkdir -p fmeng/{work,upper,lower,merged}
azureuser@build:~$ echo "upper" >> fmeng/upper/both
azureuser@build:~$ echo "upper" >> fmeng/upper/only_upper
azureuser@build:~$ echo "lower" >> fmeng/lower/both
azureuser@build:~$ echo "lower" >> fmeng/lower/only_lower
azureuser@build:~$ cd fmeng/
azureuser@build:~/fmeng$ sudo mount -t overlay overlay -o lowerdir=lower,upperdir=upper,workdir=work merged
azureuser@build:~/fmeng$
azureuser@build:~/fmeng$ df -h | grep overlay
overlay          29G  2.1G   27G   7% /home/azureuser/fmeng/merged
azureuser@build:~/fmeng$

ls看到这三个文件。
azureuser@build:~/fmeng/merged$ ls
both  only_lower  only_upper
azureuser@build:~/fmeng/merged$

实际上我们创建了四个文件,其中两个both,我们看看both是什么现在
azureuser@build:~/fmeng/merged$ cat bothupper
azureuser@build:~/fmeng/merged$

如果删除both,出现字符特殊文件
azureuser@build:~/fmeng/merged$ rm both
azureuser@build:~/fmeng/upper$ sudo ls -l
total 4
c--------- 2 root      root      0, 0 Jan 15 14:55 both
-rw-rw-r-- 1 azureuser azureuser    0 Jan 15 14:52 mytest
-rw-rw-r-- 1 azureuser azureuser    6 Jan 15 14:47 only_upper
azureuser@build:~/fmeng/upper$ 
root@build:~# brctl addbr fmengbr0
root@build:~# ip addr add 172.18.0.1/24 dev fmengbr0
root@build:~# ip link set dev fmengbr0 up
root@build:~#

ip link add dev veth0_1 type veth peer name veth1_1
ip link set dev veth0_1 up
ip link set veth0_1 master fmengbr0
ip netns add netns_test
ip link set veth1_1 netns netns_test
ip netns exec netns_test ip link set dev lo up
ip netns exec netns_test ip link set veth1_1 address 02:42:ac:11:00:01
ip netns exec netns_test ip addr add 172.18.0.2/24 dev veth1_1
ip netns exec netns_test ip link set dev veth1_1 up
ip netns exec netns_test ip route add default via 172.18.0.2

root@build:~# ifconfig fmengbr0
fmengbr0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.18.0.1  netmask 255.255.255.0  broadcast 0.0.0.0
        inet6 fe80::b88d:ebff:fe19:d95a  prefixlen 64  scopeid 0x20<link>
        ether ba:8d:eb:19:d9:5a  txqueuelen 1000  (Ethernet)
		...


root@build:~# cgcreate -g cpu,cpuacct,memory:/test
root@build:~# cgexec -g "cpu,cpuacct,memory:/test"  ip netns exec netns_test unshare -fmuip --mount-proc chroot "/var/lib/fmeng/image/busybox/75fae911f860e3d9d6898b7af34a3b96374dcb33ee9d8b7a6230b74d4a1f30d4" /bin/sh
/ # ls
VERSION    etc        layer.tar  root       var
bin        home       lib        tmp
dev        json       lib64      usr
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
		...
    
5: veth1_1@if6: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue qlen 1000
    link/ether 02:42:ac:11:00:01 brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.2/24 scope global veth1_1
...


镜像构建技巧

容器历史

  • chroot
  • Solaris Zone -> 很像一个VM
  • OpenVZ
  • LXC - Linux 容器(LXC)是第一个、最完整的 Linux 容器管理器的实现方案
  • Docker
  • Rocket - CoreOS
  • containerd 大一统 (OCI)

Dockerfile 语法

ADD和COPY区别

https://www.ctl.io/developers/blog/post/dockerfile-add-vs-copy/

ENTRYPOINT 和 CMD 区别

https://www.ctl.io/developers/blog/post/dockerfile-entrypoint-vs-cmd/
http://www.johnzaccone.io/entrypoint-vs-cmd-back-to-basics/
  • 至少得定义一个(ENTRYPOINT 或者CMD),以保证运行。否则容器跑不起来
  • 容器运行时只定义它们其中一个的话,CMD和ENTRYPOINT的效果是一样的。
  • 写法SHELL和exec,推荐exec
  • ENTRYPOINT和CMD都可以被 docker run -- entrypoint参数 override

如果你不想开发者修改镜像缺省的执行命令,例如ping, 那么用ENTRYPOINT。

以命令(ENTRYPOINT)+ 参数(CMD)的形式,提供用户修改参数的灵活性。

如果甚至希望提供修改镜像缺省命令的能力,那么只用CMD(没有ENTRYPOINT) 这样用户可以完全地自己定义我起镜像用什么命令,灵活性最高。

测试:

cat Dockerfile
FROM alpine
ENTRYPOINT ["ping"]
CMD ["www.google.com"]

docker run test www.yahoo.com
PING www.yahoo.com (98.139.183.24): 56 data bytes
64 bytes from 98.139.183.24: seq=0 ttl=37 time=0.590 ms

root@build:~# docker run -it test sh
ping: bad address 'sh'
root@build:~#


cat Dockerfile
FROM alpine
CMD ["ping", "www.google.com"]  
docker run -it test:0.2 sh
/ # ls
bin    dev    etc    home   lib    media  mnt    opt    proc   root   run    sbin   srv    sys    tmp    usr    var

/ #root@build:~# docker run test:0.2 www.baidu.com
docker: Error response from daemon: failed to create shim: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "www.baidu.com": executable file not found in $PATH: unknown.

OCI镜像

OCI镜像规范的目标是:允许开发者只要对容器打包和签名一次,就可以在所有的容器引擎上运行该容器。这意味着开发团队可以根据自己的需要选择构建工具和扩展语法。

OCI 主要有三个规范:运行时规范 runtime-spec ,镜像规范 image-spec 以及不常见的镜像仓库规范 distribution-spec

镜像规范:

├── annotations.md         # 注解规范
├── config.md              # image config 文件规范
├── considerations.md      # 注意事项
├── conversion.md          # 转换为 OCI 运行时
├── descriptor.md          # OCI Content Descriptors 内容描述
├── image-index.md         # manifest list 文件
├── image-layout.md        # 镜像的布局
├── implementations.md     # 使用 OCI 规范的项目
├── layer.md               # 镜像层 layer 规范
├── manifest.md            # manifest 规范
├── media-types.md         # 文件类型
├── README.md              # README 文档
├── spec.md                # OCI 镜像规范的概览

容器镜像仓库的选择

公有云

  • 官方 https://hub.docker.com
  • jfrog artifactory https://www.jfrog.com/confluence/display/JFROG/Docker+Registry
  • 各个云厂商的镜像仓库服务

私有云

  • harbor
  • jfrog
  • https://quay.io/

基础镜像的选择

  • 静态语言:越小越好
  • 动态语言:根据情况测试

https://aws.amazon.com/cn/blogs/china/choose-the-best-docker-image-for-your-python-application/

实战课程

https://time.geekbang.org/column/intro/100063801

runtime:

  • 容器运行时
  • kernel
  • kubernetes源码

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言
    友情链接