工作之后一直有买书的习惯,正所谓何以解忧,唯有买书。
刚上班那会儿,把买书当成投资了,每个月工资不高但都会抽出一部分用来买书。自以为每读一本书,自己就会变得厉害一点点,长此以往岂不是会变得越来越厉害。可是想象中的事并没有发生,因为买书容易,读书难。特别是前段时间病倒了,人生进入倒记时,长期规划突然崩塌,读书变成不再要紧的事。
最近整理堆在墙角吃灰的书籍,翻了翻,大部分都是为了某一目的应急买回来的。比如前年为了考Oracle OCP把市面上的Oracle书籍能买的都买了一堆回来,还用工作中会用到的C#相关、Tomcat相关、Apache相关以及早期买的编程类的、网络类、算法类、编程思想、操作系统底层等。琢磨着,反正一时半会死不掉,生活还要继续,书也要接着读,读到好书就整理出来和大家分享。
书作为一种价值浓缩的产品简直太超值了,作者写一本书短的要好几个月,长的要好几年。然后再精简、校对、反复打磨,最后出版送到诸位手中,只用花区区不到100块钱,再加上货币通胀、贬值、路边的早餐价格都翻倍了,书从定价那一刻起就落后通货膨胀,越是早期的书现在来看越是便宜。能用这么低的代价换取作者近一年的付出,对于每位买书人来说,你都应该感觉赚到了。这个世界资源是有限的,唯有思想没有你的我的之分,把书读到你的脑子里了,这就是你的,你不接受书中的观点,说明你能分辨是非,甄别好坏,更高级。
我们回到主题,今天和大家一起了解下容器,这玩意从2013年出现,到现在快10年,部分与我们合作的厂商已经在生产环境用了起来,比如本士的企业“蚂蚁云服”。书我早买了,之前走马观花地读过,再在重新捡起来,配合实际操作,和大家一起学习一下。
先看看WiKi上的解释:
DevOps(Development和Operations的组合词)是一种重视“软件开发人员(Dev)”和“IT运维技术人员(Ops)”之间沟通合作的文化、运动或惯例。透过自动化“软件交付”和“架构变更”的流程,来使得构建、测试、发布软件能够更加地快捷、频繁和可靠。
Docker是基于 Linux 的 cgroup、namespaces 特性来构建的运行容器。
Kubernetes(常简称为K8s)是用于自动部署、扩展和管理“容器化(containerized)应用程序”的开源系统。该系统由Google设计并捐赠给Cloud Native Computing Foundation(今属Linux基金会)来使用。它旨在提供“跨主机集群的自动部署、扩展以及运行应用程序容器的平台”。它支持一系列容器工具,包括Docker等。
简单地说
DevOps是一种运动,Docker是容器(进程运行环境),K8s是容器管理工具,用于编排和大规模部署。Docker与K8s是砖头与房子的关系,DevOps更关注如何让房子自动盖起来。
要理解这一切,要先从容器开始。一个容器就类似Android上的一个App,它所有的运行时都是自包含的。多个容器间也可以相互关联相互配合,比如一个容器提供前端web服务,另一个容器提供后端数据库服务。当多个容器一起配合提供一个业务时就需要对容器进行编排,先启动什么,后启动什么,如何关联,比如 docker compose 就是干这个用的。如果再从单机(Node, or minion)扩大到集群,一组组的业务(Pod) 能够做到自动扩容或收缩(repication service),这就要由更复杂的K8s来支持了。

我们从最简单的单一容器例子来看,docker到底能做什么。
Ubuntu 安装 Docker
sudo apt-get install updatesudo apt-get install docker.io
安装完后,检查一下关于docker的包
(base) root@it:~# dpkg -l | grep dockerii docker 1.5-1 amd64 System tray for KDE3/GNOME2 docklet applicationsii docker.io 18.09.2-0ubuntu1~16.04.1 amd64 Linux container runtime
老的Linux发行版需要配置 docker 命令自动补全,新版本已自带补全。
(base) root@it:~# apt-get install bash-completion(base) root@it:~# source usr/share/bash-completion/completions/docker
当输入docker 接两下空格,已经支持命令补全了
(base) root@it:~# dockerattach container events history info login node ps restart save stack swarm trust volumebuild cp exec image inspect logout pause pull rm search start system unpause waitcommit create export images kill logs plugin push rmi secret stats tag updateconfig diff help import load network port rename run service stop top version
启动 docker 服务
(base) root@it:~# systemctl start docker(base) root@it:~#(base) root@it:~# systemctl status docker● docker.service - Docker Application Container EngineLoaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)Active: active (running) since 日 2021-10-03 14:12:14 CST; 6s agoDocs: https://docs.docker.comMain PID: 37729 (dockerd)Tasks: 53Memory: 153.1MCPU: 880msCGroup: /system.slice/docker.service├─37729 usr/bin/dockerd -H fd://└─37753 docker-containerd --config var/run/docker/containerd/containerd.toml --log-level info10月 03 14:12:13 it dockerd[37729]: time="2021-10-03T14:12:13.953813014+08:00" level=warning msg="Your kernel does not support swap memory limit"10月 03 14:12:13 it dockerd[37729]: time="2021-10-03T14:12:13.953923067+08:00" level=warning msg="Your kernel does not support cgroup rt period"10月 03 14:12:13 it dockerd[37729]: time="2021-10-03T14:12:13.953946293+08:00" level=warning msg="Your kernel does not support cgroup rt runtime"10月 03 14:12:13 it dockerd[37729]: time="2021-10-03T14:12:13.954760741+08:00" level=info msg="Loading containers: start."10月 03 14:12:14 it dockerd[37729]: time="2021-10-03T14:12:14.264023190+08:00" level=info msg="Default bridge (docker0) is assigned with an IP address 172.17.10月 03 14:12:14 it dockerd[37729]: time="2021-10-03T14:12:14.331274075+08:00" level=info msg="Loading containers: done."10月 03 14:12:14 it dockerd[37729]: time="2021-10-03T14:12:14.629513781+08:00" level=info msg="Docker daemon" commit=6247962 graphdriver(s)=overlay2 version=110月 03 14:12:14 it dockerd[37729]: time="2021-10-03T14:12:14.650676625+08:00" level=info msg="Daemon has completed initialization"10月 03 14:12:14 it dockerd[37729]: time="2021-10-03T14:12:14.712151999+08:00" level=info msg="API listen on var/run/docker.sock"10月 03 14:12:14 it systemd[1]: Started Docker Application Container Engine.
Docker 是基于go语言开发的,早期的服务端和客户端共用一个二进制文件。启动服务端时使用 -d 加其它选项执行,让它成为守护进程。现在已经分离成dockerd和docker,我们平时主要使用客户端docker命令,服务端使用systemctl启动。
可以使用ps查看服务端进程的命令行
(base) root@it:~# ps -eaf| grep docker | grep -v greproot 37729 1 0 14:12 ? 00:00:01 usr/bin/dockerd -H fd://root 37753 37729 0 14:12 ? 00:00:00 docker-containerd --config var/run/docker/containerd/containerd.toml --log-level info
也可以通过systemctl查看服务状态,从status状态信息中也可以看到docker服务端进程信息。
docker 安装完后,测试一下是否可用
(base) root@it:~# docker run --rm -ti ubuntu:latest bin/bashUnable to find image 'ubuntu:latest' locallylatest: Pulling from library/ubuntuf3ef4ff62e0d: Pull completeDigest: sha256:44ab2c3b26363823dcb965498ab06abf74a1e6af20a732902250743df0d4172dStatus: Downloaded newer image for ubuntu:latestroot@ebf55d716c97:/#
测试使用的是使用最新版Ubuntu镜像,这里的镜像image是指docker的镜像不是ISO安装镜像。docker镜像是打包好的容器。使用ubuntu的docker镜像就像使用虚拟机一样,容器执行后会创建了一个只有七十多兆的Ubuntu环境。这个环境甚至可以装软件:
root@ebf55d716c97:/home# apt-get install lsb-releaseThe following additional packages will be installed:distro-info-data file libexpat1 libmagic-mgc libmagic1 libmpdec2 libpython3-stdlib libpython3.8-minimal libpython3.8-stdlib libreadline8 libsqlite3-0libssl1.1 mime-support python3 python3-minimal python3.8 python3.8-minimal readline-common xz-utilsroot@ebf55d716c97:/home#root@ebf55d716c97:/home# lsb_release -aNo LSB modules are available.Distributor ID: UbuntuDescription: Ubuntu 20.04.3 LTSRelease: 20.04Codename: focal
有了docker基本上就不再需要在裸金属上安装各种发行版本了,几乎对于各种版本的软件都可以做到开箱即用,并且还是最轻量化的配置。
docker run --rm -ti ubuntu:latest bin/bash
命令行解释
--rm 退出容器时删除这个容器
-t 分配伪终端tty
-i 交互会话
--dns=8.8.4.4 配置dns
--mac-address="aa:11:aa:22:aa:33" 配置MAC地址
-v mnt:/data 将宿主机文件系统/mnt目录挂载到容器/data目录
--read-only=true 使容器的根目录只读
-p 8080:8080 宿主机与容器的端口映射
--restart=on-failure:3 尝试重启,3次失败则放弃(on 不重启, always 一 直重启, on-failure:#)
-d Run container in background and print container ID
所有命令行中,要数 run 的命令行最长了,run基本上把应用的初始化环境都传给了容器里的应用,如果再复杂一点用要用配置文件了。命令行长到最后就会演化成配置文件,配置文件复杂到最后就会诞生一门新的语言,复杂的配置文件的解析实际就是编译原理,也就是语言编译器干的事。
查看docker运行状态
(base) root@it:~# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESb533e551529c 075b46fe5d29 "/bin/sh -c 'apt-get…" 2 minutes ago Up 2 minutes reverent_feynmanebf55d716c97 ubuntu:latest "/bin/bash" 2 hours ago Up 2 hours hopeful_elbakyan
常用docker命令
docker stop <容器ID> 停止容器 (发送 SGTERM信号)
docker start <容器ID> 启动容器
docker kill <容器ID> 杀掉容器(类似 kill 命令,支持任何信号)
docker pause <容器ID> 暂停容器
docker unpause <容器ID> 恢复运行
docker rm <容器ID> 删容器
docker images 列出image
docker rmi <image id> 删image
使用 docker ps -a 可以查看所有的容器,包含未运行的容器。
docker 所有需要占存储空间的部分都存在/var/lib/docker目录
(base) root@it:~# docker imagesREPOSITORY TAG IMAGE ID CREATED SIZE<none> <none> 3757b2ac0a82 5 hours ago 921MBubuntu latest 597ce1600cf4 2 days ago 72.8MBnode 11.11.0 9ff38e3a6d9d 2 years ago 904MBjaspeen/oracle-11g latest 0c8711fe4f0f 6 years ago 281MB(base) root@it:~# du -sh var/lib/docker/1.6G var/lib/docker/(base) root@it:~# docker rmi 3757b2ac0a82Deleted: sha256:3757b2ac0a825096be27894feca658d88a2df59901fe7df827745655b3d08ba7Deleted: sha256:a0dd5c2595a17faf3f458dc616ad18a21d3787c48401ece2d4929d8d6a30295aDeleted: sha256:075b46fe5d29608bcf316d6043ebb3a090d3f76a2e184d0a4c90b4c7918b78c4Deleted: sha256:eb538dac43df4ae40dee55ddfd6b77fc30e81ff0aa1d1156f3f221b03fbc49f1Deleted: sha256:aaf649273f848e7761a649a6e4c4b8407a2104c6b42026a65780543b9abcf18fDeleted: sha256:0741a9ea9fb9cc9963f3a948a80a4d652ad302f05e2b8ebe3162f3e1ab7b40f8Deleted: sha256:9700fef77c183770ec8b7281dc2ba1b8681d25c923ab2cbbf919b1a185863423(base) root@it:~# docker rmi 0c8711fe4f0fUntagged: jaspeen/oracle-11g:latestDeleted: sha256:0c8711fe4f0f52e9feb12eb96cdaf29345f609bcc0107df27f6faf7df0163e02Deleted: sha256:1cb21e703b720cd7d832ddd033041e53feee79d08d93cc02805d7fffc670747eDeleted: sha256:7bb3e530fe08d9d23a60ba5de39989cf33af14367e86d1b2813139f749134c4dDeleted: sha256:0ffdd075541bfe29ef70f92ecf2a0ec931e649e798a0dce849fbf3e6af0c9ac5Deleted: sha256:837c058a7f0375340930e5733349455af71dc02a1d71161f530931efa52f4187Deleted: sha256:b80eb81e63135876399d500d3f92f1ac6b2de6c6fd001fff3c9a2e89df4ea18bDeleted: sha256:6119e2a62ddda05a8a16965e4d07a6431a965c191eac1d33fd8bc82f744f265fDeleted: sha256:6e2e13b04294c9b2d52a3d7b3e0358640077b618b9ae0761ae003894dab89851Deleted: sha256:8b3a4acf1707a66ffa42a92836ba529b636cc4c6ad31ce18533a3daf0932974dDeleted: sha256:3b30f458c60f169e59e5c7b73cb2225bdc831f62d917e29c45780627d62f0b0bDeleted: sha256:c11139db960f045c479c1df10cccbdf30b047e738cccf155e64a778705fbe59eDeleted: sha256:9c91ea33cf06bb3fc5cf109e02d3c7ddd51319278cdb71e09327632d63bef80bDeleted: sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef(base) root@it:~# docker rmi 9ff38e3a6d9dUntagged: node:11.11.0Untagged: node@sha256:065610e9b9567dfecf10f45677f4d372a864a74a67a7b2089f5f513606e28edeDeleted: sha256:9ff38e3a6d9dfacaf53a31c7b28cf39aebedcdc0173f883d23caee921397051eDeleted: sha256:fa7e0dc979024e1ddf23f3f6eea66b1f22581056c0112528fcfad69e614b6c01Deleted: sha256:977ead571ee54b40f5b9d0de754ef0f82b3da9dfa5fc0ce555cdf02d1ab117e7Deleted: sha256:bc2623320ddb3fc116213259d4b53d1342b7351cd4dda8c9c8c618fb55700a39Deleted: sha256:1e150f8e5d1906a97dfe10a8928651f8a1cea1cfc9471585faf69b8f1a97a147Deleted: sha256:127e85e4eeabb41591238fbfba3a84feb80dbc2c2455bd29dd0dc76591e8fb59Deleted: sha256:e5885c49fd01d365bac1ee35d39fbe6e2f85f74f787b3e384addee5f41b6815eDeleted: sha256:5fd83feb03ebf717e192822a2e9684009856a9a9900fa561f28de4ac8b463c86Deleted: sha256:5bb0785f2eee7f27e4c6d9ac3e7f05838e243d22feb827b55d70762f1eb4781a(base) root@it:~# du -sh var/lib/docker293M var/lib/docker
删完之后,占用的空间降下来了。
掌握了基本的命令之后,到哪儿去找image?
可以到 docker hub上去找自己想要的image,在每个image介绍里都有一个pull 地址

将命令拷贝下来执行即可获取相应的image

下面尝试运行刚下载下来的容器
(base) root@it:~# docker imagesREPOSITORY TAG IMAGE ID CREATED SIZEubuntu latest 597ce1600cf4 2 days ago 72.8MBstore/docker/getting-started vscode 5af07ebb9a73 15 months ago 27.2MB(base) root@it:~# docker run -d -t -p 8001:80 5af07ebb9a73a16b6ded4194e396387bd02b5d8c5b66d359de45038147d35c46aaf40f492021(base) root@it:~# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESa16b6ded4194 5af07ebb9a73 "/docker-entrypoint.…" 3 minutes ago Up 3 minutes 0.0.0.0:8001->80/tcp dreamy_kapitsa
在浏览器上查看运行效果:

“getting-started” 容器已经运行起来了。
参考书籍:





