• 容器编排学习(一)容器技术


    一  容器

    1  Linux 容器的起源

    容器的起源可以追溯到1979年 UNIX 系统中提供的chroot命令,容器的最初的设计目标是为了隔离计算机中的各类资源以便降低软件开发、测试阶段的风险,或者充当蜜罐,吸引黑客的攻击,以便监视黑客的行为。最初的容器是以chroot为代表的文件隔离技术,但这并不完美,如主机名、网络、系统进程、用户等都无法隔离

    2 名称空间和控制组

    为了实现完美的隔离机制,2002年 Linux引入了一种由内核直接提供的全局资源封装的全新隔离机制(名称空间)用来解决隔离的问题,至2009年,Linux内核已经支持了UTSPC、PID、NETWORK、MOUNT等多个名称空间。

    Linux解决资源配额的方案是控制组 (Cgroups),它与名称空间一样直接由内核提供功能,用于隔离或者说分配并限制某个进程组能够使用的资源量,包括占用 CPU 时间、内存大小、磁盘 1/0 速度,等等

    3  容器的诞生

    当文件系统、访问、资源都可以被隔离后,容器已经有它降生所需的全部条件,Linux内核开始提供Cgroups的同一时间就马上发布了名为 LXC的系统级虚拟化功能

    LXC 带着令人瞩目的光环登场,可惜的是,LXC 在设定自己的发展目标时,被前辈们的影响所局限住。LXC 眼中的容器是一种封装系统的轻量级虚拟机。这种局限的思想也决定了LXC不可能形成今天的容器生态的,所以,接下来舞台的聚光灯终于落到了 Docker 身上。

    二 docker

    1  概述

    2013年3月,一个名为 Docker 的项目宣布开源

    当时的人们并没有意识到这款软件将要带来怎样的技术变革

    它的出现促使“容器”从一个阳春白雪的只流传于极客口中的技术词汇,逐渐走向整个IT舞台的中央短短数年时间,就已成为开发、测试、部署等各个环节都难以或缺的基础支撑。是什么样的魔力让 Docker 可以从一问世就惊艳世间

    2  理念

    促使 Docker的一问世就惊艳世间的,不是什么黑科技式的秘密武器,而是其符合历史潮流的创意与设计理念,还有充分开放的生态环境。

    早期的容器技术是一种封装系统的轻量级虚拟化,Docker眼中“容器技术”是一种以应用为核心,对程序文件、运行时环境、软件依赖包都可以封装打包、部署的技术手段

    Docker 的容器中没有系统

    2014年,Docker开源了自己用 Golang开发的 Libcontainer

    2015年,在Docker的主导和倡议下,多家公司联合制定“开放容器交互标准”(0CI),这是一个关于容器格式和运行时的规范文件,其中包含:

    • 运行时标准(RUNTIME-SPEC)
    • 容器镜像标准(IMAGE-SPEC)
    • 镜像分发标准(DISTRIBUTION-SPEC)

    3  三大概念

    容器:容器是一个运行在隔离环境中的程序

    镜像:镜像是只读的模板,包含了创建容器所需的所有文件和配置信息

    仓库:仓库是用来存储、分发、管理镜像的地方

    三  安装部署

    1  配置Yum仓库

    把 docker 软件包添加到跳板机的自定义 yum 仓库中

    [root@docker ~]# yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
    主机名IP地址最低配置
    docker-0001192.168.1.312CPU,4G内存
    docker-0002192.168.1.322CPU,4G内存

    2  系统管理命令

    命令说明
    docker version查看服务器与客户端版本
    docker info查看 docker 服务配置信息

    3  安装部署

    1. # 开启路由转发
    2. [root@docker ~]# echo 'net.ipv4.ip_forward = 1' >>/etc/sysctl.conf
    3. [root@docker ~]# sysctl -p
    4. [root@docker ~]# dnf install -y docker-ce
    5. [root@docker ~]# systemctl enable --now docker
    6. # 查看服务器与客户端版本
    7. [root@docker ~]# docker version
    8. Client: Docker Engine - Community
    9. Version: 20.10.10
    10. ... ...
    11. Server: Docker Engine - Community
    12. Engine:
    13. Version: 20.10.10

    4  添加镜像加速

    1. [root@docker ~]# vim /etc/docker/daemon.json
    2. {
    3. "registry-mirrors": ["这里配置镜像仓库加速器地址"],
    4. "insecure-registries":[]
    5. }
    6. [root@docker ~]# systemctl restart docker
    7. # 查看 docker 服务配置信息
    8. [root@docker ~]# docker info
    9. ... ...
    10. Insecure Registries:
    11. 127.0.0.0/8
    12. Registry Mirrors:
    13. https://镜像仓库加速器/
    14. Live Restore Enabled: false

    四  镜像

    1  概述

    • 镜像是创建容器的核心
    • 镜像使用CoW技术
    • 镜像采用分层设计
    • 镜像始终都是只读的

    如何创建容器?

    首先使用 Cow 为镜像创建一个读写层,容器在读写层运行

    这种方式可以让一个镜像创建无数个容器

    2  获取镜像

    镜像可以从官方镜像仓库下载,也可以自己制作

    官方镜像仓库:https://hub.docker.com

    从官方下载较慢,可以使用国内的镜像站加速

    添加配置文件: /etc/docker/daemon.json
    {

            "reqistry-mirrors":["这里配置镜像加速器地址”]

            "insecure-registries":[ ]

    }

    1. [root@docker ~]# vim /etc/docker/daemon.json
    2. {
    3. "registry-mirrors": ["这里配置镜像仓库加速器地址"],
    4. "insecure-registries":[]
    5. }
    6. [root@docker ~]# systemctl restart docker
    7. # 查看 docker 服务配置信息
    8. [root@docker ~]# docker info
    9. ... ...
    10. Insecure Registries:
    11. 127.0.0.0/8
    12. Registry Mirrors:
    13. https://镜像仓库加速器/
    14. Live Restore Enabled: false

    3  镜像管理命令

    镜像管理命令说明备注
    docker images查看本机镜像
    docker pull 镜像名称:标签下载镜像
    docker save 镜像名称:标签 -o 备份文件名称备份镜像为tar包备份文件是 tar 格式
    docker load -i 备份文件名称导入备份的镜像文件备份文件 tar 或 tar.xx 格式
    docker history 镜像名称:标签查看镜像的制作历史

    镜像管理案例

    pull、images、history

    1. # 下载 busybox:latest 镜像
    2. [root@docker ~]# docker pull busybox:latest
    3. # 查看本机镜像
    4. [root@docker ~]# docker images
    5. REPOSITORY TAG IMAGE ID CREATED SIZE
    6. busybox latest 66ba00ad3de8 5 weeks ago 4.87MB
    7. # 查看镜像的制作历史
    8. [root@docker ~]# docker history busybox:latest
    9. IMAGE CREATED CREATED BY SIZE
    10. b539af69bc01 9 days ago /bin/sh -c #(nop) CMD ["sh"] 0B
    11. <missing> 9 days ago /bin/sh -c #(nop) ADD file:069460fea0454.86MB

    指定镜像的方法

    • 每一个镜像都对应唯一的镜像 id
    • 镜像名称 + 标签 = 唯一
    • 每一个镜像都有标签,默认标签 latest我们在调用镜像的时候,如果没有指定标签也是 latest

    镜像的备份与恢复

    save、load

    1. # 备份 rockylinux:8.5 镜像为 tar 包
    2. [root@docker ~]# docker save busybox:latest -o busybox.tar
    3. # 使用备份文件恢复镜像
    4. [root@docker ~]# docker load -i myos.tar.xz
    5. Loaded image: rockylinux:8.5
    6. Loaded image: myos:8.5
    7. Loaded image: myos:php-fpm
    8. Loaded image: myos:nginx
    9. Loaded image: myos:httpd
    10. Loaded image: myos:latest
    11. # 查看本机镜像
    12. [root@docker ~]# docker images
    13. REPOSITORY TAG IMAGE ID CREATED SIZE
    14. myos php-fpm 7124977c0b21 12 days ago 275MB
    15. myos latest 1de38c85c2d1 3 weeks ago 4.67MB
    16. myos nginx 5e45400d8e76 3 weeks ago 274MB
    17. myos httpd 9245e660f88f 3 weeks ago 299MB
    18. myos 8.5 621bfd7f9b46 3 weeks ago 249MB
    19. busybox latest 66ba00ad3de8 5 weeks ago 4.87MB
    20. rockylinux 8.5 210996f98b85 14 months ago 205MB
    1. [root@docker-0001 ~]# docker load -i myos.tar.xz
    2. [root@docker-0001 ~]# docker save rockylinux:8.5 -o rockylinux.tar
    3. [root@docker-0001 ~]# scp rockylinux.tar 192.168.1.32:/root/
    4. #-------------------------------------------------------------------#
    5. [root@docker-0001 ~]# docker load -i rockylinux.tar
    6. [root@docker-0001 ~]# docker history rockylinux:8.5

     

    五  容器管理

    1  容器管理命令

    容器管理命令说明
    docker run -it(d) 镜像名称:标签创建容器
    docker ps查看容器的信息
    docker inspect 镜像名称|容器名称查询(容器/镜像)的详细信息
    docker [start|stop|restart] 容器id启动、停止、重启容器
    docker exec -it 容器ID 启动命令在容器内执行命令
    docker cp 路径1 路径2拷贝文件:路径格式(本机路径、容器ID/路径)

    2  容器管理案例

    run

    查看 run 的参数

    • docker help run
    • man docker-run

    docker run 常用参数

    • 参数 -i 交互式
    • 参数 -t 分配终端
    • 参数 -d 后台运行
    • 参数 --name 容器名字
    • 参数 --rm 容器结束后自动删除
    • 转入后台快捷键 (ctrl-p + ctrl-g)
    1. # 创建一个容器
    2. [root@docker ~]# docker run -it myos:8.5
    3. [root@3aa1df05b795 /]# hostname
    4. 3aa1df05b795
    5. [root@3aa1df05b795 /]# ps -ef
    6. UID PID PPID C STIME TTY TIME CMD
    7. root 1 0 0 15:13 pts/0 00:00:00 /bin/bash
    8. root 19 1 0 15:13 pts/0 00:00:00 ps -ef
    9. [root@3aa1df05b795 /]# ifconfig eth0
    10. eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
    11. inet 172.17.0.2 netmask 255.255.0.0 broadcast 172.17.255.255
    12. ether 02:42:ac:11:00:02 txqueuelen 0 (Ethernet)
    13. RX packets 0 bytes 0 (0.0 B)
    14. RX errors 0 dropped 0 overruns 0 frame 0
    15. TX packets 0 bytes 0 (0.0 B)
    16. TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
    17. [root@3aa1df05b795 /]# exit
    18. # 创建后台容器
    19. [root@docker ~]# docker run -itd myos:httpd
    20. 6d6884244a995791f8171efa3ce81be1e9e51bedf25c3a5a67bac8bb7bc019b0
    21. # 创建名为web1的后台容器
    22. [root@docker ~]# docker run -itd --name web1 myos:httpd
    23. 14b669a75a95e9ba590c37137abc9d828d2c769d46f69c35fb0e8cc98cc544c4

    ps

    docker ps 常用参数

    • -a 显示所有容器
    • -p 只显示ID
    1. # 查询容器状态
    2. [root@docker ~]# docker ps
    3. CONTAINER ID IMAGE ... ... STATUS PORTS NAMES
    4. 14b669a75a95 myos:httpd ... ... Up 25 minutes 80/tcp web1
    5. 6d6884244a99 myos:httpd ... ... Up 25 minutes 80/tcp hawking
    6. [root@docker ~]# docker ps -a
    7. CONTAINER ID IMAGE ... ... STATUS PORTS NAMES
    8. 14b669a75a95 myos:httpd ... ... Up 25 minutes 80/tcp web1
    9. 6d6884244a99 myos:httpd ... ... Up 25 minutes 80/tcp hawking
    10. 47ded92f442f myos:8.5 ... ... Exited (0) yonath
    11. [root@docker ~]# docker ps -aq
    12. 14b669a75a95
    13. 6d6884244a99
    14. 47ded92f442f

    start、stop、restart

    1. [root@docker ~]# docker ps -a
    2. CONTAINER ID IMAGE ... ... STATUS PORTS NAMES
    3. 14b669a75a95 myos:httpd ... ... Up 25 minutes 80/tcp web1
    4. 6d6884244a99 myos:httpd ... ... Up 25 minutes 80/tcp hawking
    5. 47ded92f442f myos:8.5 ... ... Exited (0) yonath
    6. # 停止容器
    7. [root@docker ~]# docker stop web1 6d6884244a99
    8. web1
    9. 6d6884244a99
    10. [root@docker ~]# docker ps -a
    11. CONTAINER ID IMAGE ... ... STATUS PORTS NAMES
    12. 14b669a75a95 myos:httpd ... ... Exited (0) web1
    13. 6d6884244a99 myos:httpd ... ... Exited (0) hawking
    14. 47ded92f442f myos:8.5 ... ... Exited (0) yonath
    15. # 启动容器
    16. [root@docker ~]# docker start web1
    17. web1
    18. [root@docker ~]# docker ps -a
    19. CONTAINER ID IMAGE ... ... STATUS PORTS NAMES
    20. 14b669a75a95 myos:httpd ... ... Up 6 seconds 80/tcp web1
    21. 6d6884244a99 myos:httpd ... ... Exited (0) hawking
    22. 47ded92f442f myos:8.5 ... ... Exited (0) yonath
    23. # 重启容器
    24. [root@docker ~]# docker restart 6d6884244a99
    25. 6d6884244a99
    26. [root@docker ~]# docker ps -a
    27. CONTAINER ID IMAGE ... ... STATUS PORTS NAMES
    28. 14b669a75a95 myos:httpd ... ... Up 18 seconds 80/tcp web1
    29. 6d6884244a99 myos:httpd ... ... Up 3 seconds 80/tcp hawking
    30. 47ded92f442f myos:8.5 ... ... Exited (0) yonath

    inspect

    1. # 查询镜像的详细信息
    2. [root@docker ~]# docker inspect myos:httpd
    3. { ......
    4. "Cmd": [
    5. "httpd",
    6. "-DFOREGROUND"
    7. ],
    8. ......
    9. }
    10. # 查询容器的详细信息
    11. [root@docker ~]# docker inspect 6d6884244a99 web1
    12. [
    13. { ... ...
    14. "Gateway": "172.17.0.1",
    15. "GlobalIPv6Address": "",
    16. "GlobalIPv6PrefixLen": 0,
    17. "IPAddress": "172.17.0.3",
    18. "IPPrefixLen": 16,
    19. ... ...

    exec、cp

    拷贝文件

    • 上传:docker cp 本机文件路径 容器id:容器内路径
    • 下载:docker cp 容器id:容器内路径 本机文件路径
    1. # 在容器内执行非交互命令
    2. [root@docker ~]# docker exec -it web1 /bin/ls
    3. index.html info.php
    4. # 在容器内执行交互命令
    5. [root@docker ~]# docker exec -it web1 /bin/bash
    6. [root@487e19bb4ca3 ~]# exit
    7. # 从容器内拷贝文件出来
    8. [root@docker ~]# docker cp web1:/etc/httpd/conf/httpd.conf ./
    9. [root@docker ~]# sed -ri "s,(Listen )80,\18080," httpd.conf
    10. # 把文件拷贝到容器内
    11. [root@docker ~]# docker cp httpd.conf web1:/etc/httpd/conf/
    12. # 重启容器
    13. [root@docker ~]# docker restart web1
    14. # 查询容器详细信息
    15. [root@docker ~]# docker inspect web1
    16. {
    17. "Networks": {
    18. "bridge": {
    19. "IPAddress": "172.17.0.2",
    20. ......
    21. }
    22. [root@docker ~]# curl http://172.17.0.2:8080/
    23. Welcome to The Apache.

    3  其他管理命令

    管理命令说明
    docker rm 容器ID删除容器
    docker logs 容器ID查看容器日志
    docker tag 镜像ID:标签 镜像名称:新的标签创建新的镜像名称和标签
    docker rmi 镜像名称:标签删除镜像(必须先删除该镜像启动的所有容器)

    管理命令案例

    rm、logs

    1. # 删除容器
    2. [root@docker ~]# docker rm 47ded92f442f
    3. # 强制删除容器
    4. [root@docker ~]# docker rm -f web1
    5. # 删除所有容器
    6. [root@docker ~]# docker rm -f $(docker ps -aq)
    7. # 创建容器
    8. [root@docker ~]# docker run -itd --name web myos:nginx
    9. # 访问容器
    10. [root@docker ~]# docker inspect web |grep IPAddress
    11. [root@docker ~]# curl http://172.17.0.2/info.php
    12. # 查看容器日志
    13. [root@docker ~]# docker logs web
    14. 2023/01/17 15:51:49 [error] 6#0: *1 open() "/usr/local/nginx/html/info.php" failed (2: No such file or directory), client: 172.17.0.1, server: localhost, request: "GET /info.php HTTP/1.1", host: "172.17.0.2"

    rmi、tag

    1. # 删除一个镜像
    2. [root@docker ~]# docker rmi busybox:latest
    3. Untagged: busybox:latest
    4. # 已经创建容器的镜像无法删除
    5. [root@docker ~]# docker rmi -f myos:nginx
    6. Untagged: myos:nginx
    7. [root@docker ~]# docker images
    8. REPOSITORY TAG IMAGE ID CREATED SIZE
    9. myos php-fpm 7124977c0b21 12 days ago 275MB
    10. myos latest 1de38c85c2d1 3 weeks ago 4.67MB
    11. <none> <none> 5e45400d8e76 3 weeks ago 274MB
    12. myos httpd 9245e660f88f 3 weeks ago 299MB
    13. myos 8.5 621bfd7f9b46 3 weeks ago 249MB
    14. rockylinux 8.5 210996f98b85 14 months ago 205MB
    15. # 给镜像设置一个新的名称标签
    16. [root@docker ~]# docker tag 5e45400d8e76 myos:nginx
    17. [root@docker ~]# docker images
    18. REPOSITORY TAG IMAGE ID CREATED SIZE
    19. myos php-fpm 7124977c0b21 12 days ago 275MB
    20. myos latest 1de38c85c2d1 3 weeks ago 4.67MB
    21. myos nginx 5e45400d8e76 3 weeks ago 274MB
    22. myos httpd 9245e660f88f 3 weeks ago 299MB
    23. myos 8.5 621bfd7f9b46 3 weeks ago 249MB
    24. rockylinux 8.5 210996f98b85 14 months ago 205MB

    六  自定义镜像

    • 镜像采用分层设计
    • 创建读写层
    • 修改配置
    • 重新打包

    简单镜像制作

    1. # 使用基础镜像创建一个容器
    2. [root@docker ~]# docker run -itd --name linux rockylinux:8.5
    3. # 删除容器内的Yum配置文件
    4. [root@docker ~]# docker exec -it linux rm -rf /etc/yum.repos.d
    5. # 拷贝宿主机的Yum配置文件到容器内
    6. [root@docker ~]# docker cp /etc/yum.repos.d linux:/etc/
    7. # 在容器内安装工具软件包
    8. [root@docker ~]# docker exec -it linux dnf install -y net-tools vim-enhanced tree bash-completion iproute procps-ng psmisc
    9. # 清理缓存文件
    10. [root@docker ~]# docker exec -it linux dnf clean all
    11. # 停止容器
    12. [root@docker ~]# docker stop linux
    13. # 把容器制作成镜像
    14. [root@docker ~]# docker commit linux mylinux:latest
    15. sha256:7a4449e20f4c59d1f6c4db838b4724cbf63c8f4195513c5f17d053c7752891d5
    16. # 查看新制作的镜像
    17. [root@docker ~]# docker images
    18. REPOSITORY TAG IMAGE ID CREATED SIZE
    19. mylinux latest b64da40467ae 3 seconds ago 249MB
    20. rockylinux 8.5 210996f98b85 13 months ago 205MB
    21. # 删除制作镜像的容器
    22. [root@docker ~]# docker rm -f linux
    23. linux

    七  容器部署应用

    在容器中安装部署 apache 服务

    如何在容器内启动服务?

    • 由于容器内没有 systemd,参考服务文件手工执行启动程序
    • 服务文件路径 /usr/lib/systemd/system/httpd.service
    • 查看服务文件,设置环境变量执行服务启动程序
    • 如果没有 service文件,参考官方手册配置、启动服务

    1  安装部署 apache 服务

    1. # 删除所有容器
    2. [root@docker ~]# docker rm -f $(docker ps -aq)
    3. # 创建一个名为 myweb 的容器
    4. [root@docker ~]# docker run -it --rm --name myweb mylinux:latest
    5. #-----------------------------------------------------------
    6. # 在容器内安装部署 apache
    7. [root@a7f9d0c3e3e2 /]# dnf install -y httpd
    8. [root@a7f9d0c3e3e2 /]# echo "Hello World ." >/var/www/html/index.html
    9. [root@a7f9d0c3e3e2 /]# cat /usr/lib/systemd/system/httpd.service
    10. [root@a7f9d0c3e3e2 /]# export LANG=C
    11. [root@a7f9d0c3e3e2 /]# /usr/sbin/httpd -DFOREGROUND
    12. # 在另一个终端完成访问验证

    2  为 apache 添加解析 php 文件支持

    1. # ctrl + c 终止 httpd 服务运行
    2. [root@a7f9d0c3e3e2 /]# dnf install -y php
    3. [root@a7f9d0c3e3e2 /]# vim /etc/httpd/conf.modules.d/00-mpm.conf
    4. 11: LoadModule mpm_prefork_module ... ... # 去掉注释
    5. 17: # LoadModule mpm_event_module ... ... # 注释配置
    6. [root@a7f9d0c3e3e2 /]# /usr/sbin/httpd -DFOREGROUND
    7. # 服务不要关闭,在其他终端完成测试

    3  验证配置

    1. # 在另一个终端拷贝 public/info.php 到 docker 主机
    2. [root@docker ~]# docker cp info.php myweb:/var/www/html/
    3. [root@docker ~]# curl http://172.17.0.2/info.php
    4. <pre>
    5. Array
    6. (
    7. [REMOTE_ADDR] => 172.17.0.1
    8. [REQUEST_METHOD] => GET
    9. [HTTP_USER_AGENT] => curl/7.61.1
    10. [REQUEST_URI] => /info.php
    11. )
    12. php_host: 616e75df56ae
    13. 1229

    八  容器服务原理

    1  什么是上帝进程?

    简单的说就是系统创建之初产生的第一个进程

    2  特点

    • 没有父进程,PID = 1
    • 是所有程序的根进程
    • 上帝进程死亡系统实例也就关闭了

    3  容器有没有上帝进程?

    容器的启动进程就是上帝进程

    如果容器的启动进程关闭等同于容器关闭

    4  前台服务 VS后台服务?

    前台服务是占有控制终端的进程,可以在终端与用户交互式的访问与操作,一旦终端关闭,这个进程也随之消失。

    后台进程也叫守护进程,不受终端控制,它不需要交互;后台进程的本质是向系统托管进程服务

  • 相关阅读:
    Node的Web编程
    2015架构案例(五十一)
    Python 教程之控制流(11)无限迭代器
    拖尾渲染器-Unity拖尾渲染器的使用
    《手写Mybatis》第5章:数据源的解析、创建和使用
    APP自动化测试-8.移动端混合应用自动化测试
    模板进阶和反向迭代器
    CSS布局 | flex布局
    物料凭证过账时有用的BAdI和User exit
    git仓库版本管理基础知识
  • 原文地址:https://blog.csdn.net/2301_79227925/article/details/132772849