前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >云原生之路 | 3.实践Docker容器环境部署及初体验

云原生之路 | 3.实践Docker容器环境部署及初体验

作者头像
全栈工程师修炼指南
发布2024-03-13 15:54:21
1300
发布2024-03-13 15:54:21
举报
前言简述

2022年,原本是准备和同事一起完成出一本Kubernetes在企业落地实践的书的,但是由于老婆怀孕以及后来娃娃的出生需要照顾,从而错过了发版时间(工期赶不赢),后来一想是有点后悔,浪费了这一次宝贵机会,但是也无可奈何,出书对主题大纲、书籍目录、代码贴图、文章内容以及来源等格式都有严格的限制,所以说就是想赶上时间也是没办法的,不过在之前我已经完成了‍几章,如今生活一切都步入了正规,作者不想所以写和总结的文章吃灰,遂一一分享出来给大家一起学习,并且后续作者也会继续更新云原生在企业落地实践等相关文章,在【云原生落地实用指南】付费专栏之中持续更新,希望大家多多支持,关注转发!

温馨提示:作者最近开通的知识星球,全栈系列从门到实践教程将会逐步同步到星球内,加入星球将获得作者在安全、运维、开发中的所有学习实践笔记,和问题答疑以及远程技术支持,希望大家多多支持!

2.2 容器Docker安装使用体验

上一小节我们准备Ubuntu 、Linux 、WindowsServer 等操作系统的基础环境,本节我们分别简单尝试在准备的环境中安装配置Dokcer和以及Docker容器初始体验,让我们准备好一起揭开Docker 、Containerd容器神秘的面纱吧。

官方文档参考地址: https://docs.docker.com/engine/install/

2.2.1 Windows Server中安装运行Docker Desktop

最初Docker没有支持在Windows 平台上运行,但因为当时大多数程序开发者针对于对Linux不熟悉,而又想使用Docker来快速部署运行测试某些应用的来说是非常有必要的。然Docker 并不想抛弃Windows用户的容器市场,所以Docker官方逐渐提供了Docker Tool box 来在Window7系统中安装使用Docker,但是配置比较繁琐并且对硬件有要求,其中最重要的就是需要支持虚拟化。随后Docker官方又为Windows 用户提供了Docker Desktop可视化软件,以便Windows 用户可以在可视化的界面进行操作管理Docker。

Docker Desktop是一个适用于 MacOS 和 Windows 机器的应用程序,用于构建和共享容器化应用程序。我们可以利用可视化界面,便在几分钟内快速构建您的第一个容器化应用程序,不过值得注意的是在企业生产环境中通常不建议采用Windows Server部署的Docker来运行开发的应用程序,但是可以进行开发时的应用测试以及搭建Kubernetes集群控制器完全是OK的,所以本节将会讲解Docker Desktop在Windows下的安装配置以及常规使用。

安装环境说明

  • l操作系统: Windows Server 2019(注: 如是个人PC必须是Windows 10 64位操作系统 )
  • l处理器与内存: 4C / 8G
  • lDocker Desktop版本: 4.1.1

安装步骤流程

1.安装 Docker Desktop 也是非常的简单,访问Docker官网 https://www.docker.com/get-started ,点击Docker Desktop Download for Windows 进行下载安装程序,安装文件大约500MB左右有,建议采用专用下载工具进行下载,可以加快下载速度。

2.下载完毕后双击运行Docker Desktop Installer.exe ,此时它将在线下载相关依赖包,我们勾选启用Windows Hyper 组件支持并将在桌面创建应用链接图标,如下图2-20所示,之后点击OK。

图 2 - 20 Docker Desktop 配置选项

3.然后等待直到出现 Installation Succeeded后点击Close and Restart 表示安装完成,当点击后它可能将会重启操作系统,请注意保存工作空间。

4.系统重启后我们点击桌面Docker Desktop的快捷方式运行Docker,此处勾选接受条款以及点击接受按钮,然后它将会启动Docker Engine 服务,如下图2-21所示。

图 2 - 21 同意Docker Desktop 用户协议

5.此时进入主界面将会启动Docker Engine Service,当成功启动该服务后会显示 Get started with Docker in a few easy steps! 的页面,如下图2-22所示,我们直接点击 Skip Tutorial 来跳过新手教程。

图 2 - 22 Docker Engine Service 成功启动

6.然后我们将会进入到Docker Desktop主界面,可以从图2-23中看到提示没有容器运行,我们可以尝试使用下面的Docker命令复制并粘贴到PowerShell终端进行创建一个容器。

代码语言:javascript
复制
docker run -d -p 80:80 docker/getting-started

图 2 - 23 Docker Desktop主界面

6.采用getting-started 镜像创建容器后的结果,如下图2-24所示

图 2 - 24 getting-started 镜像容器容器创建结果

8.Docker Desktop还为我们提供了直接管理容器应用、镜像管理和存储卷控制台,以及最新开发测试环境模块,使得用户可以非常方便的进行容器生命周期操作和管理,如下图2-25所示。

图 2 - 25 Docker Desktop 容器管理界面

9.我们点击Container/Apps 选项卡后便可以看见我们创建的容器,点击容器我们便可以看见如下图所示界面,它给用户提供了容器运行日志查看、容器配置检查、容器资源占用情况等以及进行容器的内部shell终端,并且可直接点击图标进行容器的停止、重启、删除操作,

图 2 - 26 容器状态查看及生命周期管理

上面是我们在Windows Server 2019操作系统中安装使用Docker Desktop的一个简单流程,从中可以看到使用Docker Desktop可以非常便捷的进行创建和管理容器,减少开发者的使用难度,便于新手小白快速入门,但是对于企业生产环境来说,其扩展性和高可用性远远达不到我们的要求,其仅仅适合于个人开发者和简单入门使用。

由于在Windows Server上使用容器非本书的重点,如果有感兴趣的朋友可以自行扩展了解,至此在Windows Server 中安装Docker Desktop运行容器初体验完毕。

2.2.2 Linux(CentOS) 中安装运行Containerd与Docker

上一小节讲述了在Windows 是可视化桌面安装和使用Docker,而在实际企业的之中大多是采用Linux操作系统作为应用运行的基础环境,其中CentOS 发行版操作系统在国内企业中的占用率相对比红帽的Redhat操作系统更受中小型企业的喜爱毕竟可以免费使用谁不爱。所以本节我们将带领读者朋友们快速在CentOS7中安装Docker和Containerd.io

安装环境说明

l操作系统: Ubuntu Focal 20.04 (主机地址: 10.10.107.241)

l处理器与内存: 4C / 8G

lDocker CE版本: 19.03.15

lContainerd.io 版本: 1.4.11

lDocker-compose 版本: 1.25.0

安装部署流程

1.使用2.1章节中初始化和安全加固过的CentOS7基础环境,首先我们卸载机器上docker或者docker-engine旧版本以及相关的依赖项,执行如下命令。

代码语言:javascript
复制
yum remove -y docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine

2.在新主机上首次安装 Docker Engine 之前,您需要 设置 Docker 稳定的存储库

代码语言:javascript
复制
# 方式1.命令设置官方源
sudo yum install -y yum-utils
sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
# 方式2.手动设置官方源
# sudo tee /etc/yum.repos.d/docker.repo <<-'EOF'
# [dockerrepo]
# name=Docker Repository
# baseurl=https://yum.dockerproject.org/repo/main/centos/$releasever/
# enabled=1
# gpgcheck=1
# gpgkey=https://yum.dockerproject.org/gpg
# EOF

3.在CentOS7中安装最新或者特定版本的Docker、Containerd.io 和Docker-compose执行如下命令,得到如图2-27结果所示。

代码语言:javascript
复制
# 方式1.安装最新版本的 Docker Engine 和 Containerd
# sudo yum install docker-ce docker-ce-cli containerd.io docker-compose  
# 方式2.安装特定版本的 Docker Engine,请在列出可用版本中选择并安装,
# 即 包名(docker-ce) 加上版本字符串(第二列) 从第一个冒号 ( :),直到第一个连字符,由 一个连字符 ( -)。例如 docker-ce-18.09.1.
yum list docker-ce --showduplicates | sort -r
# docker-ce.x86_64            3:19.03.15-3.el7                    docker-ce-stable  
# docker-ce.x86_64            3:19.03.14-3.el7                    docker-ce-stable
# 此处我们依然安装的19.03.15版本的Docker 引擎以及客户端。
sudo yum install -y docker-ce-19.03.15 docker-ce-cli-19.03.15 containerd.io docker-compose

图 2 - 27 yum仓库中可用Docker 版本查看你

Docker CE有三种更新通道是稳定通道、测试通道和夜间通道,如果想更新docker-ce可以执行yum -y upgrade docker-ce 命令即可。

4.安装成功后执行如下Shell命令验证Docker安装以及依赖相关安装环境。

代码语言:javascript
复制
$ docker info | egrep "Version|Driver|mirror"
Server Version: 19.03.15
Storage Driver: overlay2
Logging Driver: json-file
Cgroup Driver: systemd
Kernel Version: 3.10.0-1160.45.1.el7.x86_64
https://xlx9erfu.mirror.aliyuncs.com/
$ ctr --version
ctr containerd.io 1.4.11
$ docker-compose --version
docker-compose version 1.18.0, build 8dd22a9

5.将当前普通用户加入docker用户组,然后退出会话重新登陆,使得非root用户也可以执行docker相关命令。

代码语言:javascript
复制
sudo gpasswd -a weiyigeek docker

6.在/etc/docker/daemon.json配置文件中进行配置Docker加速拉取镜像源仓库以及存储驱动设置为overlay2。

代码语言:javascript
复制
mkdir -vp /etc/docker/
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"data-root":"/var/lib/docker/",
"registry-mirrors": ["https://xlx9erfu.mirror.aliyuncs.com"],
"exec-opts": ["native.cgroupdriver=systemd"],
"storage-driver": "overlay2",
"log-driver": "json-file",
"log-level": "warn",
"log-opts": {
"max-size": "100m",
"max-file": "10"
},
"live-restore": true,
"dns": ["223.5.5.5","223.6.6.6"]
}
EOF

上述配置文件主要参数含义如下所述:

代码语言:javascript
复制
data-root : 指定Docker容器存储根路径。
registry-mirrors : 指定镜像仓库镜像源,通常为了加速拉取镜像。
exec-opts : 指定docker engine服务启动的额外参数。
storage-driver : 指定后端存储驱动,现在最常用的是overlay2 。
log-driver: 指定日志驱动,例如上面配置文件中将日志格式化为 JSON,这是 Docker 默认的日志驱动程序。
log-level : 日志记录级别
log-opts : 日志记录选项,我们可以设置每个日志文件最大字节数以及日志文件个数。
live-restore: 保证 docker daemon重启时容器不重启(需要设置 docker.server 只杀死docker进程,而不是cgroup中的所有进程)
dns: 指定容器中缺省的域名解析服务器。

7.注意修改daemon.json后需重载守护进程,执行如下命令设置Docker服务开机自启并重新启动docker引擎服务。

代码语言:javascript
复制
sudo systemctl daemon-reload
sudo systemctl enable docker
sudo systemctl restart docker

8.最后运行systemctl status docker 和 docker info 命令来查看Docker运行情况,如出现如下图2-28所示则表示已启动Docker应用程序容器引擎。

图 2 - 28 Docker 引擎服务状态和服务端信息查询

至此在CentOS7系统中安装Docker完毕,后续将简单体验Docker容器技术和Container为运维工作带来的便利性。

Docker容器初体验(Hello World)

1.首先通过执行以下命令拉取查看下载到本地hello-world镜像。

代码语言:javascript
复制
# 拉取hello-world 镜像
$ docker pull hello-world
Using default tag: latest
latest: Pulling from library/hello-world
Digest: sha256:cc15c5b292d8525effc0f89cb299f1804f3a725c8d05e158653a563f15e4f685
Status: Image is up to date for hello-world:latest
docker.io/library/hello-world:latest
# 查看系统已拉取的镜像
$ docker images
REPOSITORY TAG      IMAGE ID            CREATED             SIZE
hello-world latest     feb5d9fea6a5        2 months ago        13.3kB

2.然后我们执行docker run命令来创建容器并运行镜像中的应用。

代码语言:javascript
复制
$ docker run hello-world

上述命令运行后正确输出结果将会如下图2-29所示。

图 2 - 29 hello-world 镜像运行结果

3.当docker运行镜像并创建容器后,可以通过docker ps 命令来查看当前主机中已创建的容器,如果想删除一个已停止的容器可以通过docker rm命令来显示,运行结果如下图2-30所示。

代码语言:javascript
复制
$ docker ps -a
$ docker rm vigilant_lovelace # 指定要删除容器名称或者容器ID即可

图 2 - 30 删除一个停止的容器

4.如果想删除一个镜像可以采用docker rmi命令只需指定镜像名称即可,例如docker rmi hello-world ,更深入的使用将会在下一章进行讲解。

containerd初体验(Hello Container)

Containerd 作为dockerd 的下一层,我们也可以通过它直接来管理容器的生命周期,相比较于docker直接操作流程较复杂,实际环境中并不会单独使用它,下述实践只是为了读者大致了解Containerd 可以做那些事,或者说是那些工作。

1.在使用Containerd前我们需对 /etc/containerd/config.toml文件进行初始化基础配置,执行如下命令:

代码语言:javascript
复制
# (1) 初始化Containerd基础配置
$ sudo mkdir -vp /etc/containerd
# Containerd默认配置生成
$ containerd config default | sudo tee /etc/containerd/config.toml
# 替换默认的 sandbox_image = "k8s.gcr.io/pause:3.2" 镜像,因为网络的原因导致无法直接访问,我们可以替换为阿里云镜像源。
$ sudo sed -ir 's#sandbox_image = \S\w+.*$#sandbox_image = "registry.cn-hangzhou.aliyuncs.com/google-containers/pause-amd64:3.0"#g' /etc/containerd/config.toml
$ sudo sed -ir "s#https://registry-1.docker.io#https://xlx9erfu.mirror.aliyuncs.com#g"  /etc/containerd/config.toml

2.修改containerd配置后我们重载systemd 守护进程并重新运行containerd单元服务。

代码语言:javascript
复制
$ sudo systemctl daemon-reload

$ sudo systemctl restart containerd 

3.重启containerd服务后我们通过如下命令进行查看其服务运行状态和containerd Client与Server端的版本信息

代码语言:javascript
复制
$ sudo systemctl status containerd.service

$ ctr version

上述命令执行结果如下图2-31所示。

图 2 - 31 containerd.service 服务状态以及ctr工具版本查看

5.当containerd.service成功运行后,此处我们通过containerd提供的客户端工具,运行以下ctr命令拉取busybox:latest镜像并运行验证其安装环境,运行结果如下图2- 32所示。

代码语言:javascript
复制
# 首先我们将 busybox:latest 镜像拉取到默认的名称空间中。
ctr image pull docker.io/library/busybox:latest
# 分别查看拉取的镜像
ctr image ls

图 2 - 32 ctr拉取busybox镜像和镜像查看

注意的是由于Containerd也有namespaces的概念,对于上层编排系统的支持,主要区分了3个命名空间分别是k8s.io、moby和default。如需查看或操作不同的名称空间请在ctr 命令中加上 -n参数。

6.利用下载的镜像创建一个容器后台运行busybox,创建过后可以通过下述命令查看运行的容器以及task信息。

代码语言:javascript
复制
# 后台运行busybox容器
$ ctr run -d docker.io/library/busybox:latest busybox
# 查看运行的容器以及task信息
$ ctr container ls 
$ ctr task ls

图 2 - 33 ctr 创建容器以及task任务信息获取

7.通过ps ajxf命令和利用Task PID 值我们可以查看该容器在宿主机上相关进程

代码语言:javascript
复制
ps ajxf|grep "containerd-shim-runc\|9992"|grep -v grep
1  9969  9969  6587 ?           -1 Sl       0   0:00 /usr/bin/containerd-shim-runc-v2 -namespace default -id busybox -address /run/containerd/containerd.sock
9969  9992  9992  9992 ?           -1 Ss       0   0:00  \_ sh

8.当busybox 容器运行后我们可以进入到容器内部执行简单的Shell命令,以及在测试完毕后可以删除运行的容器及其镜像。

代码语言:javascript
复制
# (1) 我们进入正在运行busybox容器的Shell终端界面。
ctr tasks exec --exec-id $RANDOM -t busybox sh
/ # uname -a
/ # ip addr
/ # echo "Hello Container!"
# (2) 停止正在运行的busybox 容器,发送SIGKILL信号量杀死该容器
ctr task kill -s SIGKILL busybox  
# (3) 使用如下命令可以看到容器已经处于停止状态
ctr task ls
TASK PID     STATUS
busybox 9992    STOPPED
# (4) 然后删除创建的Task、snapshots 以及容器等
ctr task rm busybox && ctr snapshots rm busybox && ctr container rm busybox
# (5) 移除下载的镜像
ctr images rm docker.io/library/busybox:latest
docker.io/library/busybox:latest

运行结果如图2-34所示:

图 2 - 34 进入ctr创建的busybox容器内部终端执行shell命令

至此在 CentOS7上安装使用Docker 和Containerd 初体验完成。

2.2.3 Linux(Ubuntu) 中安装运行Containerd与Docker

上一节,我们说到在企业的生产环境中常常采用Linux服务器来安装部署各类应用或服务,因为其节约资源并且容器性能和安全性都比Windows 好,所以大多数运维人员基本都是选择 Linux 来搭建相关的应用服务。

于此同时又有一个新的问题摆放在我们面前,到底应该如何选择Liunx发行版来安装部署容器环境。国内企业中普遍使用的Linux发行版的有Ubuntu、CentOS以及Redhat (红帽)的等操作系统,PS: CentOS 已被 Redhat 收购了,值得注意得是在CentOS官网提示CentOS7的生命周期是在2024-06-30结束、CentOS8的生命周期是在2021-12-31结束,可以看到CentOS即将退出江湖,但这个事情准确一些说,应该是CentOS不再按照以前的方式,从RHEL的版本中去掉Redhat商标之类的东西,重新编译打包在社区发行出来,发行版本免费且没有RHEL的商业License;CentOS将主要专注在CentOS Stream这个分支上,也就是基于比RHEL稳定版本更新的软件包,去掉Redhat商标之类的东西,重新编译打包在社区发行出来,发行版本免费且没有RHEL的商业License。所以大致来说,CentOS不再是一个去掉了支持的免费的RHEL,而是变成了一个类似于RHEL的稳定版的小白鼠一样的社区beta版本,也就是CentOS Stream

所以考虑到后续企业的维护成本和社区支持,作者我毅然决然将采用Ubuntu发行版操作系统作为日常开发和运维的主要系统,为此本书从此到本书完结,将一直采用Ubuntu发行版操作系统作为实践基础环境。

好,我们回归正题,本小节采用Ubuntu 20.04 操作系统进行Containerd 与Docker的安装运行出体验,下面记录操作流程步骤以及注意事项。

安装环境说明

l操作系统: Ubuntu Focal 20.04 (主机地址: 10.10.107.242)

l处理器与内存: 4C / 8G

lDocker版本: 19.03.15 (此处没有选择最新的20.x版本考虑到19.03.15版本的稳定性)

lContainerd.io 版本: 1.4.11

lDocker-compose 版本: 1.25.0

Docker 在Ubuntu上安装部署流程官方参考: https://docs.docker.com/engine/install/ubuntu/

Docker Community Edition (CE) 对于希望开始使用Docker并尝试基于容器的应用程序的开发人员和小型团队来说非常理想。

安装部署流程

1.执行下述Shell命令脚本安装对应的版本的Docker、Containerd.io 和Docker-compose ,但是首先我们需要卸载系统中旧版本和更新apt包索引以及添加Docker官方GPG密钥,当然此处操作系统是全新安装所以不存在Docker 容器相关软件。

代码语言:javascript
复制
# 卸载旧版本
sudo apt-get remove docker docker-engine docker.io containerd runc
# 更新apt包索引并安装包以允许apt在HTTPS上使用存储库
sudo apt-get update
sudo apt-get install -y \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common
# 添加Docker官方GPG密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# 通过搜索指纹的最后8个字符进行密钥验证
sudo apt-key fingerprint 0EBFCD88

2.设置稳定的Docker软件存储库,它可以让我们拉取Docker官方提供的最新的docker相关工具。

代码语言:javascript
复制
sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"

3.执行 apt install docker命令默认是安装Docker Engine最新版本,为了后续实践环境,此处我们指定安装 19.03.15 版本的Docker Engine 和 Docker-ce-cli。

代码语言:javascript
复制
# 如您需要安装其它特定版本的Docker引擎,请在repo中列出可用的版本
apt-cache madison docker-ce
# docker-ce | 5:20.10.6~3-0~ubuntu-focal| https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
# docker-ce | 5:19.03.15~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu xenial/stable amd64 Packages
# 使用第二列中的版本字符串安装特定的版本,例如:5:18.09.1~3-0~ubuntu-xenial。
# $sudo apt-get install docker-ce=<VERSION_STRING> docker-ce-cli=<VERSION_STRING> containerd.io
# 安装19.03.15 版本的Docker Engine 和 Docker-ce-cli。
sudo apt-get update && sudo apt-get install -y docker-ce=5:19.03.15~3-0~ubuntu-focal docker-ce-cli=5:19.03.15~3-0~ubuntu-focal containerd.io docker-compose

4.将指定的普通用户加入docker用户组,然后退出会话重新登陆,使得普通用户也可以操作使用docker相关命令。

代码语言:javascript
复制
sudo gpasswd -a ${USER} docker
sudo gpasswd -a weiyigeek docker

5.在/etc/docker/daemon.json配置文件中进行配置Docker加速拉取镜像源仓库以及存储驱动设置为overlay2(在上一章节已经解析下述关键参数的意义,此处不在累述)

代码语言:javascript
复制
mkdir -vp /etc/docker/
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"data-root":"/var/lib/docker/",
"registry-mirrors": ["https://xlx9erfu.mirror.aliyuncs.com"],
"exec-opts": ["native.cgroupdriver=systemd"],
"storage-driver": "overlay2",
"log-driver": "json-file",
"log-level": "warn",
"log-opts": {
"max-size": "100m",
"max-file": "10"
},
"live-restore": true,
"dns": ["223.5.5.5","223.6.6.6"]
}
EOF

6.同样当修改daemon.json文件后需重载systemd守护进程,执行如下命令设置Docker服务开机自启并重新启动docker引擎服务。

代码语言:javascript
复制
sudo systemctl daemon-reload
sudo systemctl enable docker
sudo systemctl restart docker

7.重启完毕后,利用如下命令查看Docker应用程序容器引擎服务状态和Docker应用程序相关信息

代码语言:javascript
复制
# $ systemctl status docker
● docker.service - Docker Application Container Engine
...
Main PID: 6065 (dockerd)
Tasks: 10
Memory: 36.6M
CGroup: /system.slice/docker.service    # Docker 引擎底层是通过调用containerd 来创建容器。
└─6065 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
Nov 07 11:22:56 ubuntu2004 systemd[1]: Starting Docker Application Container Engine...
Nov 07 11:22:57 ubuntu2004 systemd[1]: Started Docker Application Container Engine.  # 表示已成功启动
$ docker info
Client:
Debug Mode: false      # 客户端是否开启Debug模式
Server:
Containers: 0
Running: 0
Paused: 0
Stopped: 0
Images: 0
Server Version: 19.03.15    # 服务端版本
Storage Driver: overlay2    # 存储驱动
Backing Filesystem: extfs  # 后端文件系统类型
Supports d_type: true
Native Overlay Diff: true
Logging Driver: json-file
Cgroup Driver: systemd    # Cgroup 资源控制驱动
Plugins:                   # 插件包括 存储卷、网络、日志 等方面
Volume: local
Network: bridge host ipvlan macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
Swarm: inactive
Runtimes: runc             # 运行时为 runC,它是在前面提到的Libcontainer的基础上进化而来的。
Default Runtime: runc      # 默认运行时
Init Binary: docker-init
containerd version: 5b46e404f6b9f661a205e28d59c982d3634148f8
runc version: v1.0.2-0-g52b36a2
init version: fec3683
Security Options:           # 安全选项
apparmor
seccomp
Profile: default
Kernel Version: 5.4.0-90-generic   # 以下是操作系统相关信息,包括系统架构内核
Operating System: Ubuntu 20.04.3 LTS
OSType: linux
Architecture: x86_64
CPUs: 2
Total Memory: 3.844GiB
Name: ubuntu2004
ID: ZTPB:K6VQ:5I4R:56BY:KGKM:WVOD:QWV7:LBQJ:NNRE:E5U4:XGPE:24WV
Docker Root Dir: /var/lib/docker      # Docker 家目录
Debug Mode: false
Registry: https://index.docker.io/v1/   # 默认镜像仓库拉取地址
Labels:
Experimental: false
Insecure Registries:                    # 私有的
127.0.0.0/8
Registry Mirrors:   
https://xlx9erfu.mirror.aliyuncs.com/   # Docker 国内镜像源仓库
Live Restore Enabled: true              #保证Docker引擎重启时正在的容器不重启

8.查看Docker 应用程序以及相关软件工具的版本。

代码语言:javascript
复制
# 查看 docker 版本
$ docker --version
Docker version 19.03.15, build 99e3ed8919
# 查看containerd.io 版本
$ ctr --version
ctr containerd.io 1.4.11
# 查看 docker-compose 版本
$ docker-compose --version
docker-compose version 1.25.0, build unknown

Docker容器初体验(Hello World)

实践目的: 通过在Ubuntu 20.04操作系统上利用docker拉取并运行hello-world镜像验证 Docker Engine是否已正确安装,然后拉取busybox工具箱镜像,创建busybox容器并进入其容器内部Shell终端中。

1.首先拉取hello-world镜像,执行以下命令从我们的镜像源仓库中拉取它,运行结果如图2-35所示:

代码语言:javascript
复制
# 拉取hello-world到本地
$ docker pull hello-world
# 查看指定的本地镜像
$ docker images
# 运行指定镜像创建名为hello-world 的容器
# --name 指定创建的容器名称
$ docker run --name hello-world hello-world 
# 查看当前主机运行或停止的容器 (此时它将会生成一个随机名称的容器)
$ docker ps -a
# 删除已停止的hello-world 容器
$ docker rm hello-world

图 2 - 35 在Ubuntu中拉取并运行hello-world镜像

2.我们拉取一个Linux命令和工具的软件 BusyBox的镜像 (提供最基础的Linux工具运行环境),然后通过docker run 来运行和创建busybox 容器,执行结果如下图2-36所示。

代码语言:javascript
复制
# 同样拉取busybox镜像
$ docker pull busybox:latest
# 运行busybox镜像生成容器,并进入到容器的shell终端中,便可以像在Liunx中执行命令了。
# --name 指定容器名称
# --rm 容器停止即删除
# -it 进入容器交互模式
$ docker run --name busybox  --rm -it busybox sh
/ # id
/ # ip addr
/ # echo “Hello World! Docker”
# 退出容器后查看busybox容器是已经删除。
$ docker ps -a

图 2 - 36 BusyBox容器创建及其容器内部终端命令执行

containerd初体验(Hello Container)

Containerd 作为dockerd 的下一层,我们也可以通过它直接来管理容器的生命周期,相比较于docker直接操作流程较复杂,实际环境中并不会单独使用它,下述实践只是为了读者大致了解Containerd 可以做那些事,或者说是那些工作。

1.前面说过除了使用Docker来拉取运行镜像,还可以直接采用containerd 来直接拉取和运行镜像,但是在使用前需要简单的初始化配置。

代码语言:javascript
复制
# 初始化Containerd基础配置
$ sudo mkdir -vp /etc/containerd
# Containerd默认配置生成
$ containerd config default | sudo tee /etc/containerd/config.toml
# 替换默认的 sandbox_image = "k8s.gcr.io/pause:3.2" 镜像,因为网络的原因导致无法直接访问,我们可以替换为阿里云镜像源。
$ sudo sed -ir 's#sandbox_image = \S\w+.*$#sandbox_image = "registry.cn-hangzhou.aliyuncs.com/google-containers/pause-amd64:3.0"#g' /etc/containerd/config.toml
$ sudo sed -ir "s#https://registry-1.docker.io#https://xlx9erfu.mirror.aliyuncs.com#g"  /etc/containerd/config.toml

上面命令操作结果如下图2-37所示。

图 2 - 37 Containerd使用前的初始化配置关键点

2.修改containerd配置后我们重载systemd 守护进程并重新运行containerd单元服务。

代码语言:javascript
复制
$ sudo systemctl daemon-reload
$ sudo systemctl restart containerd

3.重启containerd服务后我们通过如下命令进行查看containerd.service服务运行状态和containerd Client与Server端的版本信息。

代码语言:javascript
复制
$ sudo systemctl status containerd.service

$ ctr version

4.当containerd.service成功运行后,我们再使用 containerd 提供的ctr客户端工具,拉取hello-world:latest镜像运行验证其安装环境。

代码语言:javascript
复制
# (1) 首先我们将hello-world:latest 镜像拉取到默认的名称空间中。
ctr image pull docker.io/library/hello-world:latest
# (2) 分别查看拉取的镜像
ctr image ls && ctr -n k8s.io image ls
# (3) 运行hello-world:latest 镜像
ctr run docker.io/library/hello-world:latest hello-world
# (4) 查看容器以及快照信息
ctr container ls && ctr snapshots ls
# (5) 移除containerd中已停止的容器、快照和镜像
ctr snapshots rm hello-world && ctr container rm hello-world
ctr images rm docker.io/library/hello-world:latest

使用ctr运行hello-world:latest 镜像结果如下图2-38所示

图 2 - 38 使用Containerd 创建与运行hello-world容器结果

至此在 Ubuntu20.04 上安装使用Docker 和Containerd 初体验完成。

新手问答

1. 如何选择在生产环境中虚拟化的产品?

那我们如何选择使用那种虚拟化平台?

针对于个人用户而言可以选择VMware Workstation Pro 、VMware Workstation Player、Virtual Box等虚拟化平台安装在个人PC或者工作站中,针对于企业用户可以选择VMware vSphere 、Hyper-V、KVM等虚拟化平台安装在企业服务器或者超融合服务器中。

2. 如何选择运行的操作系统与之对应的Docker和Kubernetes版本?

问题01.现有企业中使用最广泛的两个服务器发行版系统有CentOS 、Ubuntu、Debian、Redhat等,其中行业老大CentOS社区宣布 CentOS 8将于2021年底停止维护,未来将不会提供稳定的系统,意味着CentOS退出江湖的最后时刻已经来到,而此时我想大多企业也不想使用一个没有更新支持、不稳定的操作系统吧,所以会找一个替代品不言而喻Ubuntu不失为一个好的选择,因为其更新及时、资料丰富、社区支持,运维成本更低。好在我们当下大多应用都部署在容器中,对于底层的宿主机操作系统依赖并不强,所以我们只需要在新的发行版的操作系统上安装对应的Docker或者Kubernetes 环境即可。

问题02.我们可以通过从Kubernetes 官网查询到不同的版本对应建议的Docker版本,在Kubernetes 社区宣布1.20.x版本后,将containerd 作为默认的运行时,从而替换掉docker运行时,并且在1.23.x版本时全面弃用Docker,所以为了其稳定性如果想使用Docker作为运行时,则建议Kubernetes版本采用1.20.x以下的1.19.x版本,而Docker版本建议采用19.03.15 即可。

综合演练

下面来到我们综合演练章节,此处我们准备了两个小例子供大家了解Docker容器到底为运维开发带来了那些便利,以及对比使用docker工具与containerd 的ctr工具之间的部署差异,由于各Linux 发行版中使用Docker来创建管理容器操作流程大致上是相同的,因此为了学习实践环境的统一化,后续将使用Ubuntu发行版的操作系统进行作为我们实验环境。

好,废话不多说,下面就让我们一起开始愉快的学习吧。

1. 使用Docker运行Nginx 镜像快速搭建Web服务器

实践流程:

步骤01.首先我们可以访问Docker的官方镜像网站(https://hub.docker.com/_/nginx)查找可用的Nginx镜像版本,该页面上包含该镜像使用说明,它可以帮助我们快速了解并使用该镜像,对于我们新手来说帮助是不言而喻。

# 从docker官方镜像仓库中拉取nginx:latest 到本地

代码语言:javascript
复制
~$ docker pull nginx
.......
Digest: sha256:644a70516a26004c97d0d85c7fe1d0c3a67ea8ab7ddf4aff193d9f301670cf36
Status: Downloaded newer image for nginx:latest

如Dokcer Hub中搜索Nginx官方镜像如下图2-39所示

图 2 - 39 在Dokcer Hub中搜索Nginx官方镜像结果

扩展知识:什么是nginx?

Nginx(发音为“engine-x”)是用于 HTTP、HTTPS、SMTP、POP3 和 IMAP 协议的开源反向代理服务器,以及负载均衡器、HTTP 缓存和 Web 服务器(原始服务器)。nginx 项目一开始就非常注重高并发、高性能和低内存使用。

步骤02.然后准备一个静态的HTML页面,此处我拉取我的个人主页项目到本地。

代码语言:javascript
复制
# 从Github中拉取测试用的静态html5页面
~$ git clone --depth=1 https://github.com/WeiyiGeek/WeiyiGeek.git
Cloning into 'WeiyiGeek'...
remote: Enumerating objects: 15, done.
remote: Counting objects: 100% (15/15), done.
remote: Compressing objects: 100% (14/14), done.
remote: Total 15 (delta 0), reused 11 (delta 0), pack-reused 0
Unpacking objects: 100% (15/15), 10.17 MiB | 28.00 KiB/s, done.
# 查看拉取个人主页的项目
~$ ls WeiyiGeek/
CNAME favicon.ico  index.html  README.md  res  telegram-worker.js  wechat.html
# 此处防止nginx 容器运行时报项目中的文件资源 Permission denied 的问题。
~$ sudo chmod 755 -R WeiyiGeek

步骤03.在Nginx镜像与Blog项目都下载到本地后,我们可参照镜像的使用说明,利用如下docker命令进行快速搭建一个属于我们自己Web站点了,此时我们可以从浏览器中访问 (http://10.10.107.242:8080/index.html) 来验证nginx是否可以正常显示个人主页。

代码语言:javascript
复制
# 使用nginx镜像创建并后台运行一个名称myblog 的容器,映射我们项目文件到容器中/usr/share/nginx/html目录下,对外服务的端口为8080,运行后将会返回容器ID。
~$ docker run -d --name myblog -v /home/weiyigeek/WeiyiGeek:/usr/share/nginx/html -p 8080:80 nginx
507666f93a706a7af54602362341a85e7d3216f53720ab68bbd4de1f1a2db17c
# 查看容器的运行状态
~$ docker ps
CONTAINER ID IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
507666f93a70 nginx               "/docker-entrypoint.…"   22 seconds ago      Up 21 seconds       0.0.0.0:8080->80/tcp   myblog
# 查看容器运行的日志,采用-f选项可以持续更新,--tail 选项表示只显示尾部的多少行的数据
~$ docker logs -f --tail 30 myblog
# 查看本机的网卡地址用于后续访问Web服务器时。
~$ hostname -I
10.10.107.242 172.17.0.1

访问创建的Web容器结果如下图2-40所示

图 2 - 40 使用浏览器访问Nginx容器搭建的HTML5首页

代码语言:javascript
复制
上述docker run -d --name myblog -v /home/weiyigeek/WeiyiGeek:/usr/share/nginx/html -p 8080:80 nginx 命令参数解析如下:
-d : 后台运行容器。
--name : 指定创建的容器名称。
-v : 映射本地目录到容器内部指定目录。
-p : 绑定本地端口到容器应用服务端口。

步骤04.如果想停止或者删除我们创建的myblog 容器也是非常简单,执行如下docker命令即可。

代码语言:javascript
复制
# 停止正在运行的myblog容器
~$ docker stop myblog
myblog
# 显示包括运行或者停止状态的全部容器,此处我们采用grep 命令进行过滤只显示带有myblog关键字的行。
~$ docker ps -a | grep “myblog”
# 删除已停止的myblog容器
~$ docker rm myblog
Myblog
# 此处再看myblog您会发现它已不再其中,这表示您已经将其删除了。
~$ docker ps -a
# 最后我们还可以将下载的nginx镜像从本地进行删除。
~$ docker rmi nginx:latest

上述命令运行结果如下图2-41所示:

图 2 - 41 myblog 容器和nginx镜像操作结果

通过上述操作是否可以让您感受到Docker搭建部署应用的速度之快,它大大节约了我们运维人员的时间成本,不必配置复杂的基础环境,同时也可以让我们从开发测试到上线环境保持一致,避免测试环境与生产环境不一致导致应用无法启动或者报错等相关问题。

2.使用Containerd 运行Nginx镜像快速搭建Web服务器

我们使用Containerd 直接来创建和管理容器相对于开箱即用的Docker来说流程较为复杂,所以此处只是做一个简单演示使用,在实践工作中我们一般都不会单独使用Containerd 来构建运行容器,都是通过Dockerd和kubernetes CRI 插件来对接Containerd 完成runC 容器的生命周期操作。

在前面我们我们使用containerd创建了容器,但是你进入busybox容器中会发现里面只有一张lo网卡而且无法连接到外部网络之中,所以为了本节实践操作的完成,我们需要借助于CNI(Container Network Interface) 它是一个云计算基础项目来实现Containerd容器具有网络功能,项目官方地址为https://www.cni.dev/。

lCNI 网络插件(Plugins) : https://github.com/containernetworking/plugins (当前版本 v0.9.1)

lCNI 容器网络接口-Linux容器网络 : https://github.com/containernetworking/cni (当前版本 v1.0.1)

实践流程:

步骤01.从Github上官方仓库拉取下载CNI插件的及容器CNI网络接口二进制文件到本地,并分别解压到/usr/local/cni-plugins 和 /usr/local/ 目录中。

代码语言:javascript
复制
# 从containernetworking/plugins 的release页面下载最新版本并解压到/usr/local/cni-plugins目录中
$ wget https://github.com/containernetworking/plugins/releases/download/v0.9.1/cni-plugins-linux-amd64-v0.9.1.tgz
$ mkdir -vp /usr/local/cni-plugins
$ tar xvf cni-plugins-linux-amd64-v0.9.1.tgz -C /usr/local/cni-plugins
# 从containernetworking/cni的release页面下载最新版本并解压到/usr/local/cni-{version}:
$ wget wget https://github.com/containernetworking/cni/archive/refs/tags/v1.0.1.tar.gz
$ tar -zxvf v1.0.1.tar.gz -C /usr/local/
$ ls -d /usr/local/cni-*
/usr/local/cni-1.0.1 /usr/local/cni-plugins

步骤02.初始化创建和使用CNI网络插件,首先创建一个 netconf 文件来描述网络,更多使用请参考Github上containernetworking/cni项目主页。

代码语言:javascript
复制
# 使用bridge插件创建一个网卡依赖于一下面的配置文件。
$ mkdir -p /etc/cni/net.d
$ cat >/etc/cni/net.d/10-mynet.conf <<EOF
{
"cniVersion": "0.2.0",
"name": "mynet",
"type": "bridge",
"bridge": "cni0",
"isGateway": true,
"ipMasq": true,
"ipam": {
"type": "host-local",
"subnet": "10.22.0.0/16",
"routes": [
{ "dst": "0.0.0.0/0" }
]
}
}
EOF
cat >/etc/cni/net.d/99-loopback.conf <<EOF
{
"cniVersion": "0.2.0",
"name": "lo",
"type": "loopback"
}
EOF

步骤03.利用CNI网络插件进行激活cni0网卡,非常注意priv-net-run.sh 脚本依赖于 jq可执行命令,如果没有安装的可执行以下命令进行安装, 安装后将会发现主机上多个一个名为cni0的虚拟网卡。

代码语言:javascript
复制
# priv-net-run.sh 会进行处理 json字符串解析,而解析则需要依赖jq命令,执行下述命令安装,如已安装则可以跳过。
apt install jq -y
# 激活cni0网卡
$ cd /usr/local/cni-1.0.1/scripts/
$ CNI_PATH=/usr/local/cni-plugins ./priv-net-run.sh echo "Hello World! CNI Plugins."
Hello World! CNI Plugins.
# 查看cni0网卡
$ ip addr show cni0

执行上述命令结果如下图所示:

图 2 - 42 激活并查看cni0网卡结果

步骤04. 在containerd容器网络配置好后便可以拉取nginx镜像了,此处为了能加速拉取镜像采用了阿里云的容器仓库镜像源。

代码语言:javascript
复制
$ ctr image pull docker.io/library/nginx:latest
$ ctr image ls -q

步骤05. 使用ctr工具创建一个nginx容器,此处仍采用实践1的H5代码示例,运行下述命令会映射blog目录中的项目到Nginx容器 /usr/share/nginx/html 工作目录并后台运行,命令执行结果如下图2-43所示

代码语言:javascript
复制
$ ctr run -d --mount \
type=bind,src=/home/weiyigeek/WeiyiGeek,dst=/usr/share/nginx/html,options=rbind:ro \
docker.io/library/nginx:latest myblog
# 查看创建的容器
$ ctr container ls
# 查看task任务
$ ctr tasks ls

图 2 - 43 myblog容器创建与容器task pid查看

步骤06.配置containerd创建的容器拥有被外部网络通信访问和具备各容器互通的能力,具体操作如下所示。

代码语言:javascript
复制
# 首次创建的 myblog 容器默认是不能够进行网络通信的,例如下命令执行无任何容器地址返回。xi
$ ctr tasks exec -t --exec-id $RANDOM myblog hostname -I
# 进入myblog 容器内部shell终端
$ ctr tasks exec -t --exec-id $RANDOM myblog bash
# task PID进程号查看
$ ctr task ls
$ ctr task ls|grep myblog|awk '{print $2}'
# 获得容器的PID值,然后为容器添加网络
$ pid=$(ctr task ls|grep myblog|awk '{print $2}')
$ netnspath=/proc/$pid/ns/net
$ CNI_PATH=/usr/local/cni-plugins /usr/local/cni-1.0.1/scripts/exec-plugins.sh add $pid $netnspath
# 此时 myblog 容器将可以获取到绑定的IP地址并进行网络通信
$ ctr tasks exec -t --exec-id $RANDOM myblog hostname -I

上述命令执行后结果如下图所示:

图 2 - 44 配置myblog容器的网络访问互联

步骤07.此时便已经可在本地终端通过curl命令访问到我们部署的nginx,但是这还达不到我们的要求,我们可以通过转发的形式来通过外部访问该容器提供的web服务。

代码语言:javascript
复制
# 通过本地终端访问nginx 容器提供的web服务
$ curl -I 10.22.0.3
HTTP/1.1 200 OK
Server: nginx/1.21.4
Date: Tue, 14 Dec 2021 09:29:55 GMT
Content-Type: text/html
Content-Length: 17303
Last-Modified: Tue, 14 Dec 2021 09:01:50 GMT
Connection: keep-alive
ETag: "61b85d7e-4397"
Accept-Ranges: bytes
# 开启ssh转发只需要将AllowTcpForwarding 设置为yes
$ vim /etc/ssh/sshd_config
AllowTcpForwarding yes  
# 重启sshd服务
$ systemctl restart sshd
# 将容器10.22.0.3:80绑定到本机10.10.107.242:8888,以供其它外部客户端访问,注意普通用户需要输入root登陆
$ ssh -p 20211 -N -v -L 10.10.107.242:8888:10.22.0.3:80 root@10.10.107.242

然后使用浏览器通过 http://10.10.107.242:8888 地址访问 myblog 容器提供的web服务,如下图所示。

图 2 - 45 myblog 容器提供的web服务

步骤08.测试完毕后,我们可以将创建的容器中的进程进行Kill并将容器进行删除,最后移除nginx:latest镜像。

代码语言:javascript
复制
# 移除容器的网络互联
$ pid=$(ctr task ls|grep myblog|awk '{print $2}')
$ netnspath=/proc/$pid/ns/net
$ CNI_PATH=/usr/local/cni-plugins /usr/local/cni-0.8.1/scripts/exec-plugins.sh del $pid $netnspath
# kill 并删除task
$ ctr task kill myblog && ctr task rm myblog
# 删除名为myblog的snapshots
ctr snapshots rm myblog
# 删除名为myblog的container
ctr container rm myblog
# 删除nginx:latest 的镜像
ctr images rm docker.io/library/nginx:latest

至此完成了Containerd 中创建并访问nginx 容器生命周期的管理实践。

亲,文章就要看完了,不关注一下【全栈工程师修炼指南】吗?

本章小结

本章主要讲解了四个部分内容,首先介绍了一些常用的虚拟化软件应用场景,以及VMware Workstation Pro安装配置,然后是分别安装了Ubuntu、CentOS、Windows Server 等系统的相关环境,并对其系统进行了安全加固和优化处理,其次是分别在上述三个发行版系统中进行实践安装配置Docker 和 Containerd 以及快速简单的使用,最后使用了两个综合案例,分别在 Docker 和Contained 中拉取Nginx镜像并创建运行容器,提供了一个演示界面,可以让读者尝试使用容器来部署我们的Web应用,感受到容器部署给开发运维带来的好处。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2024-03-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 全栈工程师修炼指南 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 2.2 容器Docker安装使用体验
    • 2.2.1 Windows Server中安装运行Docker Desktop
      • 2.2.2 Linux(CentOS) 中安装运行Containerd与Docker
        • 2.2.3 Linux(Ubuntu) 中安装运行Containerd与Docker
        • 新手问答
          • 1. 如何选择在生产环境中虚拟化的产品?
            • 2. 如何选择运行的操作系统与之对应的Docker和Kubernetes版本?
            • 综合演练
              • 1. 使用Docker运行Nginx 镜像快速搭建Web服务器
                • 2.使用Containerd 运行Nginx镜像快速搭建Web服务器
                相关产品与服务
                容器服务
                腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档