因为要异步部署项目,而缺少工作环境,这时候我就想到了docker的一键部署。

本文来初步认识一下docker。

为什么要使用docker

1.快速构建
2.运行
3.分享

架构与容器化

docker架构分为三个,分别是Client、Host、Registry
client可以控制host进行docker操作,host就是下载了docker的主机,registry是docker的应用商店,可以通过它下载mysql、redis等环境,而这些称之为镜像。
而在镜像被下载好之后,通过docker进行运行这些镜像,这些镜像以容器进行启动,也就是docker的进程。

容器是什么

在传统部署时,应用与应用公用同一个操作系统,可能出现操作冲突。
之后出现了虚拟化部署,在计算机中引入多个虚拟机,在每个虚拟机上部署不同的环境。但是每个虚拟机都会引入操作系统,这样会使得主机太过臃肿。
所以就出现了容器化部署,不像传统部署会出现的冲突问题,也避免了虚拟化的臃肿问题。
所以容器就是轻量级的vm,她共享操作系统内核,拥有自己的文件系统、cpu、内存、进程空间等。并且相互隔离。

安装

我使用的是centos系统,通过执行以下命令来进行docker的安装。

# 移除旧版本docker
sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

# 配置docker yum源。
sudo yum install -y yum-utils
sudo yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo


# 安装 最新 docker
sudo yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# 启动& 开机启动docker; enable + start 二合一
systemctl enable docker --now

# 配置加速
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
    "registry-mirrors": [
        "https://mirror.ccs.tencentyun.com",
        "https://docker.m.daocloud.io"
    ]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

docker常用命令

#查看运行中的容器
docker ps
#查看所有容器
docker ps -a
#搜索镜像
docker search nginx
#下载镜像
docker pull nginx
#下载指定版本镜像
docker pull nginx:1.26.0
#查看所有镜像
docker images
#删除指定id的镜像
docker rmi e784f4560448


#运行一个新容器
docker run nginx
#停止容器
docker stop keen_blackwell
#启动容器
docker start 592
#重启容器
docker restart 592
#查看容器资源占用情况
docker stats 592
#查看容器日志
docker logs 592
#删除指定容器
docker rm 592
#强制删除指定容器
docker rm -f 592
# 后台启动容器
docker run -d --name mynginx nginx
# 后台启动并暴露端口
docker run -d --name mynginx -p 80:80 nginx
# 进入容器内部
docker exec -it mynginx /bin/bash

# 提交容器变化打成一个新的镜像
docker commit -m "update index.html" mynginx mynginx:v1.0
# 保存镜像为指定文件
docker save -o mynginx.tar mynginx:v1.0
# 删除多个镜像
docker rmi bde7d154a67f 94543a6c1aef e784f4560448
# 加载镜像
docker load -i mynginx.tar 


# 登录 docker hub
docker login
# 重新给镜像打标签
docker tag mynginx:v1.0 leifengyang/mynginx:v1.0
# 推送镜像
docker push leifengyang/mynginx:v1.0

镜像操作

1.检索docker search XXX来判断镜像是否存在于registry中
2.如果不存在通过 docker pull XXX:version 进行下载
3. 通过docker images来查看镜像列表
4. docker rmi XXX:version来删除镜像
在这里插入图片描述

容器操作

1.docker run XXX:version #运行镜像,并且创建容器 如果不存在进行下载
2.docker ps 【-a】 #查看运行容器   -a 查看所有容器
3.docker rm XXX #删除容器
4.docker stats XXX 查看容器状态
5.docker restart XXX 重新启动容器
6.docker start XXX 启动容器

在我们使用nginx进行操作时,我们发现并不管用,那是因为每个容器都拥有他们自己的文件系统,容器所启动的80端口,并不是主机的80端口,所以我们需要端口映射。

docker run -d --name cmc-nginx -p 80:80 nginx:1.20.2

上面这句话的意思就是后台启动镜像,并将容器名字设置为cmc-nginx,当用户访问主机80端口,映射为容器端口80。
对于这两个端口,容器端口是可以重复的,每个容器是隔离的,但是主机端口不能重复。使用一次主机80端口后,就没有办法再去映射其他容器的端口了。

保存镜像

如果我们想要让其他人来使用我们的容器,我们可以将容器打包成tar包,通过执行以下命令。

docker commit -m "message" container image  #将容器提交成镜像
docker save -o "my-nginx.tar" image  #将镜像打包成名字为my-nginx的tar包
docker load my-nginx.tar 运行该tar包,并运行为容器

将镜像发送到hub

我们可以将镜像打包到docker hub上,供其他人下载使用。
通过执行以下命令

docker tag source_image:tag target_image:tag  #设置发送镜像的新名字 一般为username/image_name:tag
docker push image:tag  #发送image到hub上

存储

将文件存储进容器文件系统的方法

目录挂载

在运行镜像时 加入 -v options

docker run -d --name "container" -d 80:80 -v /usr/share/nginx/html /app/nghtml 
#将/usr/share/nginx/html 映射到/app/nghtml上

卷映射

如何我们还是用目录挂载的方法来进行配置文件的映射的话,那他在初始化的时候会报错,因为在目录创建时,里面内容是空的,我们需要再去放入配置文件。这个时候就需要使用卷映射了。

卷映射会把本身文件夹的内容全部生成到卷目录中。

docker run -d --name "container" -d 80:80 -v /usr/share/nginx/html /app/nghtml -v ngconfig:/ect/nginx  image
#将/usr/share/nginx/html

-v ngconfig:/ect/nginx通过这个方法,就可以实现卷目录的映射,而卷的内容全部保存到了 /var/lib/docker/volumes目录下,查看这个可以看到docker下的所有卷目录。
在这里插入图片描述

也可以使用方法docker volume ls查看
在这里插入图片描述

自定义网络

docker0会为每个容器分配默认的ip地址,也就是容器的局域网ip,我们可以通过命令来查看ip地址

docker inspect container

想要让不同的容器可以相互访问,每次都要查看ip地址,未免太麻烦。这时候就需要使用自定义网络,通过自定义网络,我们可以实现http://container:port的方式来进行获取内容了,那如何自定义呢?

通过以下命令创建网络,名字为mynet

docker network create mynet

docker network ls #查看所有的网络

默认的docker0是图上的第一个
在这里插入图片描述
然后在我们创建镜像的时候,就可以进行网络的设置了,使用 –network加上自定义网络的名字来进行这个容器的网络设置。

#
docker run -d -p port:port --network mynet -v image

这样,当我们容器去访问其他容器的时候,可以直接通过 名字加端口的方式来进行访问了!

docker exec -it app2 bash
curl http://app1:80

利用docker实现redis主从模式

使用的是bitnami封装的redis内容,可以更轻松的通过命令行施加环境配置。

docker run  -d -p 6380:6379 
-v /app/rd2:/bitnami/redis/data
 -e REDIS_REPLICATION_MODE=slave 
 -e REDIS_PASSWORD=123456 
 --network mynet --name redis02 
 -e REDIS_MASTER_PASSWORD=123456 
 -e REDIS_MASTER_HOST=redis01 
 -e REDIS_MASTER_PORT_NUMBER=6379
  bitnami/redis

-e就是施加命令的方法,具体环境配置查看bitnami下的configuration。

将两个redis都运行并且加入到同一个网络中。
就可以进行访问了。

compose

上面的内容都是单个容器操作,但我们项目中,都是多个容器进行操作的,那我们如何同时多个容器进行实施呢?那就需要使用docker为我们提供的compose了。

compose提供我们yaml配置文件,在配置文件中我们规定容器操作以及配置,然后通过docker命令统一上线或者下线。
在这里插入图片描述

docker compose -f filename up -d #上线
docker compose -f filename down #下线

命令

下面展示了运行wordpress的多个容器同时执行的操作命令文件。

name: myblog
services:
  #mysql启动
  mysql:
    container_name: wordpress-mysql
    image: mysql:8.0
    ports:
      - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: 1212
      MYSQL_DATABASE: wordpress
    volumes:
      - mysql-data:/var/lib/mysql
      - /app/mysql/config:/etc/mysql/conf.d
    restart: always
    networks:
      - blog

  wordpress:
    container_name: wordpress-blog
    image: wordpress
    ports:
      - "8080:80"
    environment:
      WORDPRESS_DB_HOST: mysql
      WORDPRESS_DB_USER: root
      WORDPRESS_DB_PASSWORD: 1212
      WORDPRESS_DB_NAME: wordpress
    volumes:
      - wordpress:/var/www/html
    restart: always
    networks:
      - blog
    #依赖什么镜像启动
    depends_on:
      - mysql

volumes:
  mysql-data:
  wordpress:

networks:
  blog:

使用docker的compose命令运行这个文件,docker就可以执行多任务了。

需要注意,当你修改compose.yaml内容并且重新运行的时候,docker会判断你修改了哪些部分,你没有修改哪些部分,修改的那个容器重新启动,没有修改就不动。
而当你关闭的时候,docker并不会将你的volume也删掉,这是为了保护数据不会丢失。

Dockerfile

自定义镜像,可以供别人下载使用,通过命令组成,创建一个dockerfile无后缀文件。
下面是常见命令
在这里插入图片描述

如果要编写一个运行jar包的dockerfile,内容可以是这样

FROM openjdk: 17  #指定镜像基础环境

LABEL author=CMC
COPY app.jar /app.jar #复制同路径jar包到镜像中

EXPOSE 8080 #暴露端口

ENTRYPOINT ["java","-jar","/app.jar"] #固定命令通过java执行jar包

然后通过命令build将dockerfile命令执行打包成image

docker build -f dockerfile -t myjavaapp:v1.0 . #后面的.意思是当前目录

这样就可以在image ls中看到了

docker镜像分层机制

对于docker来说,同样的镜像内容,生成不同的容器,不可能是每次都要重新加载文件内容,而是同用,这样可以大量节省磁盘空间,而下载镜像内容也是,每个镜像里所包含的layers下的sha256文本,代表的是不同的下载内容,这些内容被下载下来后,下次如果还有其他镜像包含这些sha256,就会直接拿来使用,而不是重新下载。
在这里插入图片描述

自此就是基本的docker使用了~

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐