0%

docker安装

什么是docker

  • 这篇文章对docker进行了比较详细的介绍,我抄录一些笔记

  • Docker是容器技术的一种实现,也是操作系统层面的一种虚拟化,与虚拟机通过一套硬件再安装操作系统完全不同。

image-20220317105407328

  • Docker 和虚拟机并不一样,Docker是在操作系统进程层面的隔离,而虚拟机是在物理资源层面的隔离,两者完全不同,另外,我们也可以通过下面的一个比较,了解两者的根本性差异。

image-20220317105131805

Docker的版本

  • Docker分为社区版(CE)和企业版(EE)两个版本,社区版本可以免费使用,而企业版则需要付费使用,对于我们个人开发者或小企业来说,一般是使用社区版的。

  • Docker CE有三个更新频道,分别为stabletestnightlystable是稳定版本,test是测试后的预发布版本,而nightly则是开发中准备在下一个版本正式发布的版本,我们可以根据自己的需求下载安装。

开始安装

  • 我自己购买的是某云的服务器,系统是centos7 64如下,docker官方说至少3.8以上,建议3.10以上
1
2
3
[root@VM-24-13-centos ~]# uname -a
Linux VM-24-13-centos 3.10.0-1160.11.1.el7.x86_64 #1 SMP Fri Dec 18 16:34:56 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

  • 更新yum包,需要时间可能会比较久,慢慢等就行了,生产环境慎重操作
1
yum update
  • 修改yun-config的python版本为2
1
2
3
vi /usr/bin/yum-config-manager

#!/usr/bin/python2 -tt
  • 设置yum的源
1
2
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

  • 安装docker
1
sudo yum install docker-ce
  • 启动docker服务,后台运行
1
sudo systemctl start docker
  • 更换国内源
1
2
3
4
5
6
7
8
9
vi /etc/docker/daemon.json

{
"registry-mirrors": [
"https://registry.docker-cn.com",
"http://hub-mirror.c.163.com",
"https://docker.mirrors.ustc.edu.cn"
]
}
  • 重启
1
2
sudo systemctl daemon-reload
sudo systemctl restart docker
  • 查看是否设置成功
1
2
3
4
5
6
7
8
9
10
11
12
docker info

Labels:
Experimental: false
Insecure Registries:
127.0.0.0/8
Registry Mirrors:
https://registry.docker-cn.com/
http://hub-mirror.c.163.com/
https://docker.mirrors.ustc.edu.cn/
Live Restore Enabled: false

  • 查看版本信息
1
2
3
4
5
6
7
8
9
10
11
[root@VM-24-13-centos ~]# docker version
Client: Docker Engine - Community
Version: 20.10.13
API version: 1.41
Go version: go1.16.15
Git commit: a224086
Built: Thu Mar 10 14:09:51 2022
OS/Arch: linux/amd64
Context: default
Experimental: true

  • 卸载
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
sudo yum remove docker \

docker-client \

docker-client-latest \

docker-common \

docker-latest \

docker-latest-logrotate \

docker-logrotate \

docker-selinux \

docker-engine-selinux \

docker-engine


sudo rm -rf /var/lib/docke

三大组件

镜像(Image)容器(Container)仓库(Repository)是我们常说的Docker的三大组件,来自对此文章的抄录

镜像

简单地理解,Docker镜像就是一个Linux的文件系统(Root FileSystem),这个文件系统里面包含可以运行在Linux内核的程序以及相应的数据。

谈到这里,我们可能需要先补充一点与Linux操作系统相关的知识:

一般而言, Linux分为两个部分:Linux内核(Linux Kernel)用户空间,而真正的Linux操作系统,是指Linux内核,我们常用的Ubuntu,Centos等操作系统其实是不同厂商在Linux内核基础上添加自己的软件与工具集(tools)形成的发布版本(Linux Distribution)。

因此,我们也可以把镜像看成是上面所说的用户空间,当Docker通过镜像创建一个容器时,就是将镜像定义好的用户空间作为独立隔离的进程运行在宿主机的Linux内核之上。

搜索镜像

1
2
3
4
[root@VM-24-13-centos ~]# docker search hello-word
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
chenlicn163/hello-word hello-word 0
...........

拉取镜像

  • 拉取镜像可以使用docker image pull,其格式如下:
1
docker image pull [OPTIONS] NAME[:TAG|@DIGEST]
  • 要拉取镜像,需要指定Docker Registry的URL和端口号,默认是Docker Hub,另外还需要指定仓库名和标签,仓库名和标签唯一确定一个镜像,而标签是可能省略,如果省略,则默认使用latest作为标签名,而仓库名则由作者名和软件名组成。

  • 比如下面就算拉取hello-word的镜像,整个命令的意思就是:在Docker Hub中拉取最新(last)版本的镜像文件

1
2
3
4
5
6
7
[root@VM-24-13-centos ~]# docker pull hello-world
Using default tag: latest
latest: Pulling from library/hello-world
2db29710123e: Pull complete
Digest: sha256:4c5f3db4f8a54eb1e017c385f683a2de6e06f75be442dc32698c9bbe6c861edd
Status: Downloaded newer image for hello-world:latest
docker.io/library/hello-world:latest
  • 查看镜像 docker imagesdocker image ls
1
2
3
[root@VM-24-13-centos ~]# docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest feb5d9fea6a5 5 months ago 13.3kB

导出和导入镜像

  • 如果想与别人共享某个镜像,除了从镜像服务仓库中pull镜像和把镜像push到仓库上去之外,其实我们还可以将本地构建好的镜像直接导出并保存为文件发送给别人,如下:
1
docker image save -o /tmp/test_image.tar.gz hello-world:latest
  • 查看导出的镜像
1
2
[root@VM-24-13-centos ~]# ll /tmp/ | grep image
-rw------- 1 root root 24064 Mar 17 15:11 test_image.tar.gz
  • 而当你拿到别人导出的镜像文件,你可以使用docker load命令把镜像加载到本地的Docker镜像列表中,如下:
1
docker load < /tmp/test_image.tar.gz

删除本地镜像

  • 常用格式如下:
1
docker rmi  [option]  IMAGE1,IMAGE2,...IMAGEn
  • 可以使用镜像的长id、镜像短id、镜像摘要以及镜像名称来删除镜像,如下删除刚刚拉取的hello-word镜像
1
2
3
4
5
6
[root@VM-24-13-centos ~]# docker rmi feb5d9fea6a5
Untagged: hello-world:latest
Untagged: hello-world@sha256:4c5f3db4f8a54eb1e017c385f683a2de6e06f75be442dc32698c9bbe6c861edd
Deleted: sha256:feb5d9fea6a5e9606aa995e879d862b825965ba48de054caab5ef356dc6b3412
Deleted: sha256:e07ee1baac5fae6a26f30cabfe54a36d3402f96afda318fe0a96cec4ca393359

  • 当然我们想要清除本地全部镜像时,可以使用下面的命令,不过一般不建议使用
1
$ docker rmi $(docker images -qa)
  • 另外,一般如果镜像已经被使用来创建容器,使用上面的命令删除会报下面的错误,告诉我们该镜像已经被使用,不允许删除。对于已经被用于创建容器的镜像,删除方法有两种,一种是先把容器删除,再删除镜像,另一种则只需要在删除镜像的命令中跟一个-f参数便可,如:
1
$ docker rim -f f7302

构建镜像

面的例子都是直接使用官方提供的镜像,其实,除了从官方仓库或其他镜像仓库拉取别人构建好的镜像外,我们也可以构建自己的镜像,本次跳过

容器(Container)

  • 容器与镜像的关系,就如同面向编程中对象与类之间的关系。因为容器是通过镜像来创建的,所以必须先有镜像才能创建容器,而生成的容器是一个独立于宿主机的隔离进程,并且有属于容器自己的网络和命名空间。

  • 镜像是只读的,但容器却是可读可写的

启动容器

有两种,分别为docker rundocker start

docker run
  • 使用docker run命令通过镜像创建一个全新的容器
    • 如果镜像(hello-world)本地不存在,会提前去下载,然后再次运行
    • 运行后会退出,通过docker ps 查看不到,要加个-adocker ps -a
1
docker run hello-world
  • 如容器是一种提供服务的守护进程,那么通常需要开放端口供外部访问,则容器会一直处于运行状态,如
1
2
docker run -p 81:80 nginx
# -p 81:80 将容器内部端口80映射到端口81
  • 可以为容器指定一个名称,如:
1
2
$ docker run -p 80:80 --name mynginx nginx
# --name 后面的myngin就是自定义的容器名字
  • 也可以进入到容器中,直接与容器进行交互
1
2
3
4
$ docker run -it centos /bin/bash
# -i 表示允许你对容器内的标准输入 (STDIN) 进行交互。
# -t 在新容器内指定一个伪终端或终端
# /bin/bash表示运行容器后要执行的命令
docker start

另外一种则是使用docker start命令重新启动已经停止运行的容器

1
2
# container_id表示容器的id
$ docker start container_id

进入容器

  • Docker容器运行起来以后,要想进入容器内部可以先通过docker ps命令查看,当前运行的容器信息

  • 再通过 docker exec -it ec3d30bff042 命令,其中ec3d30bff042为容器ID docker exec -it ec3d30bff042 /bin/bash

重启

而对于正在运行的容器,也可以通过docker restart命令重新启动,如

1
$ docker restart container_id

查看容器

  • 查看在运行的容器
1
docker ps
  • 查看所有容器包括在运行中的和停止的容器
1
docker ps -a
  • 比如运行hellword,为什么输入 docker ps 不显示出来呢?输入docker ps -a 就显示出来?这里说明一下,这个 hellwordrun一下子它就结束程序了你还想它后台运行啥?如果你还是让它运行,那倒是也可以,写一个死循环就可以咯!

  • 有时候,我们只想查到容器的id,可以用下面的命令:

1
docker ps -aq

停止容器

  • 对于已经不需要的容器,可以使用docker stop命令停止其运行,如:
1
$ docker stop container_id1,container_id2...
  • 批量停止容器,如:
1
$ docker stop $(docker ps -qa)

删除容器

  • 指定容器id进行删除
1
2
# container_id表示容器id,通过docker ps可以看到容器id
$ docker rm container_id
  • 当我们需要批量删除所有容器,可以用下面的命令:
1
2
3
# 删除所有容器
docker rm $(docker ps -a -q)

  • 删除所有退出的容器,这样执行后,刚刚执行的helloword容器用docker ps -a就查不到了
1
docker container prune

导出容器为镜像

1
$ docker export -o ./image.tar.gz f4f184f5ffb9
  • 将容器导出后,我们可以另外一台有安装Docker的电脑中将文件包导入成为镜像,如:
1
$ docker import image.tar.gz

仓库

仓库(Repository)是集中存储镜像的地方,这里有个概念要区分一下,那就是仓库与仓库服务器(Registry)是两回事,像我们上面说的Docker Hub,就是Docker官方提供的一个仓库服务器,不过其实有时候我们不太需要太过区分这两个概念。

公共仓库

  • 公共仓库一般是指Docker Hub,前面我们已经多次介绍如何从Docker Hub获取镜像,除了获取镜像外,我们也可以将自己构建的镜像存放到Docker Hub,这样,别人也可以使用我们构建的镜像。

  • 不过要将镜像上传到Docker Hub,必须先在Docker的官方网站上注册一个账号,注册好了之后,可以在本地使用命令登录到Dokcer Hub了,过程如下:

    1
    $ docker login

在输入账号密码登录到Docker Hub之后,便可以使用docker push命令把镜像推送到Docker Hub

1
$ docker push test:1.0

私有仓库

  • 有时候自己部门内部有一些镜像要共享时,如果直接导出镜像拿给别人又比较麻烦,使用像Docker Hub这样的公共仓库又不是很方便,这时候我们可以自己搭建属于自己的私有仓库服务,用于存储和分布我们的镜像。

  • Docker官方提供了registry这个镜像,可以用于搭建私有仓库服务,我们把镜像拉到本地之后,用下面命令创建该镜像的容器便可以搭建一个仓库服务,如下:

1
$ docker run -d -p 5000:5000 --restart=always --name registry registry
  • 假设我们把一台IP为192.168.0.100的服务器作为仓库服务,并运行上面的语句,那么我们可以下面的语句重新构建上面的镜像,如:
1
$ docker build -t "192.168.0.100/hello-go:1.0" .
  • 然后使用下面的语句推送到自己的私有仓库服务器:
1
$ docker push 192.168.0.100/hello-word:1.0

Docker的组成与架构

  • 在安装好并启动了Docker之后,我们可以使用在命令行中使用docker命令操作docker,比如我们使用如下命令打印docker的版本信息。

image-20220317165337772

  • 从上面的图中,我们看到打出了两个部分的信息:ClientServer

  • 这是因为Docker跟大部分服务端软件一样(如MySQL),都是使用C/S的架构模型,也就是通过客户端调用服务器,只是我们现在刚好服务端和客户端都在同一台机器上而已。

  • 因此,我们可以使用下面的图来表示Docker的架构,DOCKER_HOSTDocker server,而Clinet便是我们在命令中使用docker命令。

    image-20220317165825026