芝法酱躺平攻略(19)——docker简单入门

一、docker的介绍

1.1 docker是干什么的

当你构建一个软件系统时,通常会涉及到多个组件和依赖,包括操作系统、库文件、配置文件等等。这些组件和依赖可能与你的系统在不同的环境中(例如不同的操作系统、软件版本等等)具有不同的行为,这可能会导致许多问题,例如兼容性问题、环境配置问题等等。

Docker是一个流行的容器化技术,它允许你将软件系统及其所有依赖项打包到一个称为“容器”的独立单元中,以便可以在不同的环境中轻松移植和部署。容器是一个独立的运行时环境,可以与操作系统和硬件隔离,从而可以在任何地方运行。Docker通过简化软件的部署、管理和扩展,使得构建和运行应用程序更加容易。

1.2 为什么docker对资源的消耗远远低于虚拟机

Docker之所以比传统的虚拟机消耗更少的资源,是因为Docker使用的是容器化技术,而不是虚拟化技术。在传统的虚拟机中,每个虚拟机都需要一个完整的操作系统和硬件模拟器,因此每个虚拟机都需要消耗大量的资源。相比之下,Docker容器是在主机操作系统的基础上创建的,因此不需要运行多个操作系统或硬件模拟器。

具体来说,以下是Docker相对于虚拟机能够降低资源消耗的一些原因:

  1. 轻量级:Docker容器比虚拟机轻量级得多,因为它们共享主机的内核和操作系统,而不是每个容器都运行完整的操作系统。
  2. 快速启动:Docker容器启动速度很快,通常只需要几秒钟。相比之下,虚拟机需要较长时间才能启动。
  3. 少量的硬件资源:Docker容器只需要运行所需的程序和依赖项,因此它们不需要像虚拟机那样占用大量的硬件资源。
  4. 更好的资源利用率:Docker容器可以更好地利用主机的CPU和内存资源,因为它们共享主机的内核和操作系统。

总之,Docker采用的是轻量级的容器化技术,这种技术可以帮助减少资源的消耗,使得应用程序更加轻松地在不同的环境中部署和运行。

1.3 docker层的概念

Docker使用了一种称为Union文件系统的技术,可以将多个文件系统层组合在一起,从而形成一个完整的文件系统。这些文件系统层就是Docker层的概念。

每个Docker镜像都由多个只读文件系统层构成,其中最底层是一个基础镜像(例如Ubuntu、Alpine等),每个上层文件系统层则包含了对底层文件系统层的修改。当你启动一个Docker容器时,Docker引擎会使用这些文件系统层来创建一个新的容器实例,容器中的文件系统就是这些层的组合结果。

以下是Docker层的一些特点和优点:

  1. 轻量级:由于每个文件系统层都是只读的,因此Docker镜像非常轻量级。当你创建一个新的容器实例时,Docker会创建一个新的读写层,该层是基于之前的只读层进行修改的,因此不会占用额外的磁盘空间。
  2. 高效性:Docker层使用了Copy-on-Write(COW)技术,这意味着当你在容器中修改文件时,Docker实际上并不会直接修改底层文件系统层,而是会在新的读写层中创建一个新的文件或修改一个现有的文件。这种技术可以帮助提高性能和效率。
  3. 可维护性: 由于每个文件系统层都是只读的,因此Docker镜像非常易于维护和更新。当你需要更新一个镜像时,你只需要修改相应的文件系统层,而不需要重新构建整个镜像。

上面的内容是我chatgpt回答的,简单来说,docker的每一个层,就像git的一个版本记录,记录的当前层针对之前堆叠层的增删改查操作。并且不同层可以做大量复用,这样就大大降低了磁盘空间的消耗。

二、ubuntu下的docker安装

安装相关的官网

#1 Uninstall old versions
sudo apt-get remove docker docker-engine docker.io containerd runc
#2. Update the apt package index and install packages to allow apt to use a repository over HTTPS:
sudo apt-get update
sudo apt-get install \
    ca-certificates \
    curl \
    gnupg \
    lsb-release
sudo apt-get remove docker docker-engine docker.io containerd runc
#3. Add Docker’s official GPG key:
 sudo mkdir -m 0755 -p /etc/apt/keyrings
 curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
#4. Use the following command to set up the repository
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
#5. Install Docker Engine
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
#6. 开启docker,测试helloworld
sudo service docker start

三、docker-cli基本命令介绍

docker 的命令,可以去官网查看

3.1 docker image系列

Docker镜像是一个只读的模板,它包含了用于创建Docker容器的所有文件和配置信息。镜像可以用于创建多个Docker容器实例,这些实例都是基于同一个镜像创建的,因此它们具有相同的环境和配置。

3.1.1 搜索镜像

可以去docker-hub上搜索自己想要的镜像,以及其对应的tag
以redis为例,官网页面如此
在这里插入图片描述
我们尝试一下:

sudo docker pull redis:7-alpine

3.1.2 docker image ls

可以使用ls命令,查看当前有哪些镜像

sudo docker image ls

REPOSITORY    TAG        IMAGE ID       CREATED         SIZE
python        latest     a41622906035   41 hours ago    925MB
redis         7-alpine   aeeb92ae6202   2 weeks ago     29.9MB
nginx         latest     3f8a00f137a0   2 weeks ago     142MB
hello-world   latest     feb5d9fea6a5   17 months ago   13.3kB

我们来解释一下各列的含义

列名释义
REPOSITORY镜像的名字
TAG镜像的标签,可以简单理解为版本
IMAGE ID镜像的Id,可以在生成容器时使用id,更精确的创建。也可以在删除时精确匹配
CREATED创建时间
SIZE镜像大小

3.1.3 docker image rm

删除镜像

sudo docker image rm -f feb5d9fea6a5

3.2 docker container

Docker容器则是基于镜像创建的一个可运行的实例,它是一个隔离的环境,其中包含了应用程序运行所需要的所有文件、配置和依赖项。容器可以被启动、停止、删除、暂停等操作,并且可以与宿主机和其他容器进行通信。

3.2.1 创建容器 docker container create

该命令用于基于镜像创建容器

sudo docker container create -p 3340:80 --name "my-nginx" 3f8a00f137a0
a032812b4f6f69355ec3e7b8cb25b39e9ab32ff567c6351797a20a302b44f6bb
sudo docker container ls --all
CONTAINER ID   IMAGE          COMMAND                  CREATED             STATUS                         PORTS     NAMES
a032812b4f6f   3f8a00f137a0   "/docker-entrypoint.…"   5 minutes ago       Created                                  my-nginx

解释下参数,-p表示端口映射,把镜像的80端口映射到主机的3340端口。–name是起别名。
该套命令还有很多参数,道友们可在官网细细参悟。

3.2.2 查看容器 docker container start

sudo docker container start a032812b4f6f

我们访问localhost:3340 就可以访问nginx了

3.2.3 查看容器 在运行的容器

sudo docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED       STATUS       PORTS                                   NAMES
a032812b4f6f   3f8a00f137a0   "/docker-entrypoint.…"   7 hours ago   Up 6 hours   0.0.0.0:3340->80/tcp, :::3340->80/tcp   my-nginx

如果想停止该容器

sudo docker container stop a032812b4f6f

3.3 容器交互

为方便测试,我们创建一个redis的容器

sudo docker container create -p 6378:6379 --name "my-redis" aeeb92ae6202
sudo docker container ls --all
CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS                   PORTS     NAMES
53e77ee390ae   aeeb92ae6202   "docker-entrypoint.s…"   16 seconds ago   Created                            my-redis
a032812b4f6f   3f8a00f137a0   "/docker-entrypoint.…"   9 hours ago      Exited (0) 2 hours ago             my-nginx
#启动容器
sudo docker container start 53e77ee390ae
#进入容器
sudo docker exec -it 53e77ee390ae sh

我们进入redis后,可以看到redis的容器并没有提供redis的配置,难绷。

3.4 容器卷

3.4.1 容器卷简介

容器卷volumes功能,可以把容器中的文件、文件夹映射到宿主机中。这样做有2个好处:

  • 方便修改配置
    可以把一些配置文件,资源文件映射到宿主机,这样在宿主机中修改,即可在容器中生效。
  • 方便数据持久化
    通常,我们会把数据库的存储文件和log文件映射出去,这样在移除容器时,不会导致数据丢失
  • 方便迁移
    这个很好理解,把配置和数据映射出来,在更换容器时,就很容易迁移了

我们以redis为例,实验下这个功能

3.4.2 配置docker下的redis

#创建映射文件夹
mkdir ~/DOCUMENTS/docker/redis
cd ~/DOCUMENTS/docker/redis
mkdir data
wget https://raw.githubusercontent.com/redis/redis/7.0/redis.conf 

注意,wsl中wget https链接可能会被拒绝,可以在windows中下载这个配置
为了测试,我们修改下配置

logfile "/data/redis-log.log" #log文件存放位置
dir "/data/redis" #指定dump.rdb路径
dbfilename dump.rdb
requirepass 密码

3.4.3 容器命令

sudo docker container create \
-p 6378:6379 \
--name "my-redis" \
-v /home/hataksumo/DOCUMENTS/docker/redis/data:/data \
-v /home/hataksumo/DOCUMENTS/docker/redis/config/redis.conf:/etc/redis/redis.conf \
aeeb92ae6202 \
redis-server /etc/redis/redis.conf
1bf50d4b5b06ba3858279436ec1c5d0eba2795157acbe74b0547e9801d6ab4a5
sudo docker container ls --all
CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS                    PORTS     NAMES
1bf50d4b5b06   aeeb92ae6202   "docker-entrypoint.s…"   15 seconds ago   Created                             my-redis
a032812b4f6f   3f8a00f137a0   "/docker-entrypoint.…"   19 hours ago     Exited (0) 12 hours ago             my-nginx
sudo docker container start 1bf50d4b5b06
sudo docker container ls --all
CONTAINER ID   IMAGE          COMMAND                  CREATED              STATUS                    PORTS                                       NAMES
1bf50d4b5b06   aeeb92ae6202   "docker-entrypoint.s…"   About a minute ago   Up 49 seconds             0.0.0.0:6378->6379/tcp, :::6378->6379/tcp   my-redis
a032812b4f6f   3f8a00f137a0   "/docker-entrypoint.…"   19 hours ago         Exited (0) 12 hours ago                                               my-nginx
sudo netstat -tulpn | grep :6378
tcp        0      0 0.0.0.0:6378            0.0.0.0:*               LISTEN      2878/docker-proxy
tcp6       0      0 :::6378                 :::*                    LISTEN      2885/docker-proxy
redis-cli -p 6378

可以看到,连接成功,并且在用户目录也映射出相应的文件

hataksumo@֯��:~/DOCUMENTS/docker/redis/data$ ls
dump.rdb  redis.log

注意:这里有一个坑。如果把redis的配置文件的port改为6378,端口映射写成-p 6378:6378时,可能是不生效的。
我们进入redis的docker-file文件可以看到,docker-file命令有一个开放端口的命令,EXPOSE 6379。也可以在docker container create命令中,加入–expose 6378

3.5 网络

对于网络的探究,我们使用nginx为例子。使用最常用的桥接做展示。我们打算配置4个nginx服务器,一个名为gate,另外3个分别为s1,s2,s3。在gate的反向代理中,我们通过配置另外3个nginx的逻辑名来做,而不写具体的ip和端口。这样可以使配置更加通用。

3.5.1 准备配置文件和修改html

首先,我们准备文件夹
建4个文件夹,分别表示gate服务器,和对应的3个微服务
在这里插入图片描述
在每个文件夹内,建这几个文件夹

mkdir res res/html config

运行docker容器创建命令,创建4个nginx容器
把nginx中对应的配置文件和默认的html拷到对应的地方
把s1,s2,s3的indix.html的主体改一下

<h1>Welcome to nginx! s{x}-nginx</h1>
<p><em>This is s{x}-nginx</em></p>

把nginx容器的配置拷贝出来

cd ~/DOCUMENTS/docker/nginx/gate/config
sudo docker cp my-nginx:/etc/nginx/conf.d/default.conf default.conf
sudo chmod o+w  default.conf
cd ~/DOCUMENTS/docker/nginx/s1/config
sudo docker cp my-nginx:/etc/nginx/conf.d/default.conf default.conf
cd ~/DOCUMENTS/docker/nginx/s2/config
sudo docker cp my-nginx:/etc/nginx/conf.d/default.conf default.conf
cd ~/DOCUMENTS/docker/nginx/s3/config
sudo docker cp my-nginx:/etc/nginx/conf.d/default.conf default.conf

3.5.2 配置gate的config

打开~/DOCUMENTS/docker/nginx/gate/config/default.conf

upstream s_work{
    server s1  weight=1;
    server s2  weight=1;
    server s3  weight=1;
}


server {
    listen       80;
    listen  [::]:80;
    server_name  localhost;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    location /worker {
        proxy_pass http://s_work/;
    }

    location /worker/s1 {
        proxy_pass http://s1/;
    }

    location /worker/s2 {
        proxy_pass http://s2/;
    }

    location /worker/s3 {
        proxy_pass http://s3/;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

3.5.3 创建网桥

sudo docker network create --driver bridge nginx
e157926e9c8d764b26128343394af8c998297cec67fb6b52009cc2440a5352d1

3.5.4 创建容器

sudo docker container create \
-p 8000:80 \
--name "gate-nginx" \
-v /home/hataksumo/DOCUMENTS/docker/nginx/gate/res:/usr/share/nginx \
-v /home/hataksumo/DOCUMENTS/docker/nginx/gate/config:/etc/nginx/conf.d \
3f8a00f137a0
c22857441a1a06282412991a16d7df215091a3171b23a844244808ef42afca29
sudo docker container create \
-p 8001:80 \
--name "s1-nginx" \
-v /home/hataksumo/DOCUMENTS/docker/nginx/s1/res:/usr/share/nginx \
-v /home/hataksumo/DOCUMENTS/docker/nginx/s1/config:/etc/nginx/conf.d \
3f8a00f137a0
eff608b0a6057e58af3f447fa0c188310fdc9a76b06228925f54eb2327d17389
sudo docker container create \
-p 8002:80 \
--name "s2-nginx" \
-v /home/hataksumo/DOCUMENTS/docker/nginx/s2/res:/usr/share/nginx \
-v /home/hataksumo/DOCUMENTS/docker/nginx/s2/config:/etc/nginx/conf.d \
3f8a00f137a0
5369f6d5dedc321f94bbf3a981d5e6cc7ea03bd389c2039ae2e62ac8e8654840
sudo docker container create \
-p 8003:80 \
--name "s3-nginx" \
-v /home/hataksumo/DOCUMENTS/docker/nginx/s3/res:/usr/share/nginx \
-v /home/hataksumo/DOCUMENTS/docker/nginx/s3/config:/etc/nginx/conf.d \
3f8a00f137a0
5c12c20296d7d96d1e29fa66d03be02557f807f283c16f45769d04338cb48a3a

3.5.5 把容器加入网络

sudo docker network connect --alias gate nginx gate-nginx
sudo docker network connect --alias s1 nginx s1-nginx
sudo docker network connect --alias s2 nginx s2-nginx
sudo docker network connect --alias s3 nginx s3-nginx

3.5.6 启动各容器与测试

sudo docker container start c22857441a1a eff608b0a605 5369f6d5dedc 5c12c20296d7

在浏览器上访问http://localhost:8000/worker,可以看到负载均衡的效果
在这里插入图片描述

3.6 环境变量

有的容器可以通过设置环境变量来做配置,使用-e或–env。这种方式在Java编写的镜像中很常用。在这里暂时不赘述,等遇到后再展示。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值