Docker

Docker架构

镜像和容器

Docker中有几个重要的概念:
镜像(Image):Docker将应用程序及其所需的依赖、函数库、环境、配置等文件打包在一起,称为镜像。
容器(Container):镜像中的应用程序运行后形成的进程就是容器,只是Docker会给容器进程做隔离,对外不可见。
一切应用最终都是代码组成,都是硬盘中的一个个的字节形成的文件。只有运行时,才会加载到内存,形成进程
镜像,就是把一个应用在硬盘上的文件、及其运行环境、部分系统函数库文件一起打包形成的文件包。这个文件包是只读的。
容器呢,就是将这些文件中编写的程序、函数加载到内存中允许,形成进程,只不过要隔离起来。因此一个镜像可以启动多次,形成多个容器进程。
Docker_第1张图片
例如你下载了一个QQ,如果我们将QQ在磁盘上的运行文件及其运行的操作系统依赖打包,形成QQ镜像。然后你可以启动多次,双开、甚至三开QQ,跟多个妹子聊天。

首先安装CentOS7

Docker CE 支持 64 位版本 CentOS 7,并且要求内核版本不低于 3.10, CentOS 7 满足最低内核的要求

# 切换至root user
su root
password:benjamin

卸载(可选)

如果之前安装过旧版本的Docker,可以使用下面命令卸载:

yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-selinux \
                  docker-engine-selinux \
                  docker-engine \
                  docker-ce

安装docker

虚拟机联网,安装yum工具

yum install -y yum-utils \
           device-mapper-persistent-data \
           lvm2 --skip-broken

然后更新本地镜像源:

# 设置docker镜像源
yum-config-manager \
    --add-repo \
    https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
    
sed -i 's/download.docker.com/mirrors.aliyun.com\/docker-ce/g' /etc/yum.repos.d/docker-ce.repo

yum makecache fast

然后输入命令:docker-ce为社区免费版本。稍等片刻,docker即可安装成功。

yum install -y docker-ce

启动docker

Docker应用需要用到各种端口,逐一去修改防火墙设置。非常麻烦
启动docker前,一定要关闭防火墙后!

# 关闭
systemctl stop firewalld
# 禁止开机启动防火墙
systemctl disable firewalld
# 查看防火墙状态,看到Active: inactive (dead)说明防火墙已关闭
systemctl status firewalld

通过命令启动docker:

# 启动docker服务
systemctl start docker
# 停止docker服务
systemctl stop docker
# 重启docker服务
systemctl restart docker
# 查看docker服务状态
systemctl status docker
查看docker版本也可以判断docker是否启动
docker -v

配置镜像加速

docker官方镜像仓库网速较差,我们需要设置国内镜像服务:
参考阿里云的镜像加速文档:
https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors

配置CentOS镜像加速器

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://jw7jfdv7.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

镜像命令

拉取、查看镜像

1)首先去镜像仓库搜索nginx镜像,比如
https://hub.docker.com/
Docker_第2张图片
Docker_第3张图片

2)根据查看到的镜像名称,拉取自己需要的镜像,通过命令:docker pull nginx

docker pull nginx
Using default tag: latest默认拉取的是latest版本
docker pull redis
docker pull nacos/nacos-server

3)通过命令:docker images 查看拉取到的镜像

[root@192 benjamin]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
nginx        latest    605c77e624dd   9 months ago    141MB
redis        latest    7614ae9453d1   10 months ago   113MB
mysql        5.7.25    98455b9624a9   3 years ago     372MB

保存、删除、导入镜像

1)使用docker save导出镜像到磁盘

docker save -o [保存的目标文件名称] [镜像名称]
-o指output
docker save -o nginx.tar nginx:latest
docker save -o redis.tar redis:latest

删除本地的nginx镜像

docker rmi nginx:latest
docker rmi redis:latest

2)使用docker load加载镜像
将tar文件加载成镜像文件

docker load -i nginx.tar
-i指input
docker load -i redis.tar

容器操作

Docker_第4张图片
默认情况下,容器是隔离环境,我们直接访问宿主机的80端口,肯定访问不到容器中的nginx。
现在,将容器的80与宿主机的80关联起来,当我们访问宿主机的80端口时,就会被映射到容器的80,这样就能访问到nginx了:
Docker_第5张图片

容器保护三个状态:
- 运行:进程正常运行
- 暂停:进程暂停,CPU不再运行,并不释放内存
- 停止:进程终止,回收进程占用的内存、CPU等资源

其中:
# 创建并运行一个容器
- docker run:创建并运行一个容器,处于运行状态
	docker run --name containerName -p 80:80 -d nginx
	命令解读:
	docker run :创建并运行一个容器
	--name : 给容器起一个名字,比如叫做mn
	-p :将宿主机(linux)端口:容器(docker容器)端口映射
	-d:后台运行容器
	nginx:镜像名称,例如nginx
docker run --name mynginx -p 80:80 -d nginx
a060d91dc55c9c5247f06a84dd260e46f4e923f6cbed3360e9612f5e9e7f691a//生成的唯一id
docker run --name myredis -p 6379:6379 -d redis redis-server --appendonly yes
8c2d5417bb956b89014bd7a90f7b43e50b035f7fd87d8c459e56c9be54e94c82//生成的唯一id
docker run --name cloud-demo_nacos_1 -e MODE=standalone -p 8848:8848 -d nacos/nacos-server

# 查看容器访问log
- docker logs mynginx  //查看mynginx容器日志
- docker logs -f mynginx  //持续追踪日志
	--follow         Follow log output 和 tail -f一个道理

# 进入容器。进入我们刚刚创建的nginx容器
- docker exec -it mynginx bash
	命令解读:
	docker exec :进入容器内部,执行一个命令
	-it : 给当前进入的容器创建一个标准输入、输出终端,允许我们与容器交互
	mynginx :要进入的容器的名称
	bash:进入容器后执行的命令,bash是一个linux终端交互命令
docker exec -it myredis bash
docker exec -it myredis redis-cli 直接进入redis容器的redis client端

# 修改html文件
- cd /usr/share/nginx/html
# 修改index.html的内容。容器内没有vi命令,无法直接修改,可以使用sed来修改:
sed -i -e 's#Welcome to nginx#welcome Benjamin 张#g' -e 's###g' index.html

# 进入redis client端并操作redis
redis-cli
# 查看redis数据
keys * 
# 给redis添加一个数据
set num 666
# 获取数据
get num

# 退出容器/或者退出redis client端
exit

# 停止一个运行的容器
docker stop mynginx

# 让一个停止的容器再次运行
docker start mynginx

# 删除一个容器
docker rm mynginx:删除一个未运行容器
docker rm -f mynginx:删除一个运行容器,无视运行状态
	-f指--force

- docker pause:让一个运行的容器暂停
- docker unpause:让一个容器从暂停状态恢复运行
- docker start:让一个停止的容器再次运行

# 查看容器运行状态
- docker ps   //查看运行中容器
- docker ps -a   //查看所有容器包括未运行的,-a是指--all
	Process Status 的缩写。ps 命令用来列出系统中当前正在运行的那些进程

# 运行已有的容器
# 60e6416a5535为"docker ps -a"查看的redis image id
docker start 60e6416a5535

访问运行中的容器

http://192.168.98.129/80

Docker_第6张图片

查询html文件位置

进入nginx的HTML所在目录 /usr/share/nginx/html
Docker_第7张图片

Docker安装Rabbitmq

Docker安装Rabbitmq
RabbitMq的启动重启

数据卷(容器数据管理)

Docker_第8张图片
必须将数据与容器解耦,这就要用到数据卷了
**数据卷(volume)**是一个虚拟目录,指向宿主机文件系统中的某个目录。将容器与数据分离,解耦合,方便操作容器内数据,保证数据安全
Docker_第9张图片

数据卷操作命令

数据卷操作:
- docker volume create volumename:创建数据卷

- docker volume ls  查看所有数据卷
	DRIVER    VOLUME NAME
	local     758dfa139d6b1a383c7d8f6b41956e268db10a460323ea1ad3ef51eb30a096a3
	local     2049eb7f7dbbfd4b0c71bb008ba3178e03c70daaf5079706fd1af6bf9cdf52d4
	local     volumename
	
- docker volume inspect volumename:查看数据卷详细信息,包括关联的宿主机目录位置
	[
	    {
	        "CreatedAt": "2022-10-22T00:02:58-07:00",
	        "Driver": "local",
	        "Labels": {},
	        "Mountpoint": "/var/lib/docker/volumes/volumename/_data",
	        "Name": "volumename",
	        "Options": {},
	        "Scope": "local"
	    }
	]
	
- docker volume rm volumename:删除指定数据卷

- docker volume prune:删除所有未使用的数据卷

挂载数据卷

数据卷挂载与目录直接挂载的
数据卷挂载耦合度低,由docker来管理目录,但是目录较深,不好找
目录挂载耦合度高,需要我们自己管理目录,不过目录容易寻找查看

# 使用nginx镜像,创建容器,关联容器80与宿主80端口,绑定http数据卷与目标容器内路径
docker run --name mynginx -p 80:80 -v http:/usr/share/nginx/html -d nginx
如果容器运行时http数据卷不存在,会自动被创建出来
# 查看数据卷内容,查询数据卷挂载点,"Mountpoint": "/var/lib/docker/volumes/http/_data",
docker volume inspect http
# 打开挂载点目录
cd /var/lib/docker/volumes/http/_data
[root@192 _data]# ls
50x.html  index.html
# vi命令修改index.html内容就可以了

目录直接挂载

# 将tar文件加载成镜像文件
docker load -i mysql.tar

# 创建多级目录
mkdir -p mysql/data
mkdir -p mysql/conf

# 删除目录
rm -rf path

# 根据mysql:5.7.25镜像创建mysql容器,
	指定root账户密码为root,宿主机3306与容器3306端口映射,
	设置宿主机conf、data路径与容器conf、data路径,后台运行
docker run \
 --name mysql \
 -e MYSQL_ROOT_PASSWORD=root \
 -p 3306:3306 \
 --explicit_defaults_for_timestamp=true \
 -v /tmp/mysql/conf/hmy.cnf:/etc/mysql/conf.d/hmy.cnf \
 -v /tmp/mysql/data:/var/lib/mysql \
 -d \
 mysql:5.7.25
 
docker run --name mysql -e MYSQL_ROOT_PASSWORD=root -p 3306:3306  -v /tmp/mysql/conf/hmy.cnf:/etc/mysql/conf.d/hmy.cnf  -v /tmp/mysql/data:/var/lib/mysql -d mysql:5.7.25  --explicit_defaults_for_timestamp=true

连接linux端的mysql容器
Docker_第10张图片

自定义镜像

Dockerfile语法

构建自定义的镜像时,并不需要一个个文件去拷贝,打包。
我们只需要告诉Docker,我们的镜像的组成,需要哪些BaseImage、需要拷贝什么文件、需要安装什么依赖、启动脚本是什么,将来Docker会帮助我们构建镜像。
而描述上述信息的文件就是Dockerfile文件。
Dockerfile就是一个文本文件,其中包含一个个的指令(Instruction),用指令来说明要执行什么操作来构建镜像。每一个指令都会形成一层Layer。
Docker_第11张图片

基于Ubuntu构建Java项目

Dockerfile解析

# 指定基础镜像
FROM ubuntu:16.04
# 配置环境变量,JDK的安装目录
ENV JAVA_DIR=/usr/local

# 拷贝jdk和java项目的包
COPY ./jdk8.tar.gz $JAVA_DIR/
COPY ./docker-demo.jar /tmp/app.jar

# 安装JDK
RUN cd $JAVA_DIR \
 && tar -xf ./jdk8.tar.gz \
 && mv ./jdk1.8.0_144 ./java8

# 配置环境变量
ENV JAVA_HOME=$JAVA_DIR/java8
ENV PATH=$PATH:$JAVA_HOME/bin

# 暴露端口
EXPOSE 8090
# 入口,java项目的启动命令
ENTRYPOINT java -jar /tmp/app.jar

运行命令

docker-demo.jar  Dockerfile  jdk8.tar.gz
# 自定义构建镜像
docker build -t javaweb:1.0 .
.指Dockerfile目录
-t指-tar javaweb:1.0指jar:版本号

# 查看镜像
docker images 
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
javaweb      1.0       ee7a523f5644   20 minutes ago   722MB

# 运行容器
docker run --name web -p 8090:8090 -d javaweb:1.0

# 查看容器状态
docker ps -a

# 访问项目
http://192.168.98.129:8090/hello/count

基于java8-alpine构建Java项目

虽然我们可以基于Ubuntu基础镜像,添加任意自己需要的安装包,构建镜像,但是却比较麻烦。所以大多数情况下,我们都可以在一些安装了部分软件的基础镜像上做改造。基于java:8-alpine作为基础镜像。
Dockerfile解析

# 指定基础镜像
FROM java:8-alpine

# 拷贝java项目的包
COPY ./docker-demo.jar /tmp/app.jar

# 暴露端口
EXPOSE 8090
# 入口,java项目的启动命令
ENTRYPOINT java -jar /tmp/app.jar

运行命令

//docker-demo.jar  Dockerfile  jdk8.tar.gz
# 自定义构建镜像
docker build -t javaweb:1.0 .
.指Dockerfile目录
-t指-tar javaweb:1.0指jar:版本号

# 查看镜像
docker images 
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
javaweb      2.0        d554b4e7cb0c   9 seconds ago    171MB

# 查看容器状态
docker ps -a

# 创建并运行容器
docker run --name web2.0 -p 8091:8090 -d javaweb:2.0
docker run --name docker_redis  -p 6379:6379 -d redis

# 运行已有的容器
# 60e6416a5535为"docker ps -a"查看的redis image id
docker start 60e6416a5535

# 访问项目
http://192.168.98.129:8091/hello/count

DockerCompose

Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。帮助我们快速部署分布式应用,无需一个个微服务去构建镜像和部署。格式如下:

# 相当于把docker run命令用配置表示出来
version: "3.8"
 services:
  mysql:
    image: mysql:5.7.25
    environment:
     MYSQL_ROOT_PASSWORD: root
    volumes:
     - "/tmp/mysql/data:/var/lib/mysql"
     - "/tmp/mysql/conf/hmy.cnf:/etc/mysql/conf.d/hmy.cnf"
  web:
    build: .
    ports:
     - "8090:8090"

CentOS7安装DockerCompose

1)上传docker-compose到以下目录(docker-compose文件在本地)
/usr/local/bin/
2)修改文件权限
# 修改权限
chmod +x /usr/local/bin/docker-compose
3)Base自动补全命令
# 补全命令
curl -L https://raw.githubusercontent.com/docker/compose/1.29.1/contrib/completion/bash/docker-compose > /etc/bash_completion.d/docker-compose
如果这里出现错误,需要修改自己的hosts文件:
echo "199.232.68.133 raw.githubusercontent.com" >> /etc/hosts

DockerCompose部署微服务项目

1)上传cloud-demo项目到/tmp目录
2)部署微服务,相当于一次性执行了好多docker run命令(创建并执行容器)
docker-compose up -d
错误:urllib3.exceptions.ProtocolError: (‘Connection aborted.’, FileNotFoundError(2, ‘No such file or directory’))
解决办法	systemctl start docker	重新启动docker 容器。
3)查看容器状态
docker-compose ps -a
4)查看log,因为需要等nacos先启动成功,但是别的service并没有配置重试机制
docker-compose logs -f
5)重启其他服务
docker-compose restart userservice orderservice gateway
6)再次查看userservice log发现userservice已经正常启动
docker-compose logs -f userservice 
7)启动完服务,访问资料就可以了
http://192.168.98.129:10010/user/2?authorization=admin

Docker镜像仓库

带有图形化界面版本示例

1,打开要修改的文件
vi /etc/docker/daemon.json
# 添加内容:192.168.98.129指本地ip地址
# 镜像仓库推送前需要把仓库地址配置到docker服务的daemon.json文件中,被docker信任
"insecure-registries":["http://192.168.98.129:8080"]
2,重加载
systemctl daemon-reload
3,重启docker
systemctl restart docker

4,创建registry-ui目录
mkdir registry-ui
5,创建yml文件
touch docker-compose.yml
6,vi命令将以下内容写入docker-compose.yml
# 这里配置两个镜像:Docker Registry镜像和Docker Registry UI镜像
version: '3.0'
services:
  registry:
    image: registry
    volumes:
      - ./registry-data:/var/lib/registry
  ui:
    image: joxit/docker-registry-ui:static
    ports:
      - 8080:80
    environment:
      - REGISTRY_TITLE=benjamin's private docker registry
      - REGISTRY_URL=http://registry:5000
    depends_on:
      - registry
7,创建镜像并启动服务
docker-compose up -d

8,推送镜像到私有镜像服务必须先tag
重新tag本地镜像,名称前缀为私有仓库的地址
docker tag nginx:latest 192.168.98.129:8080/nginx:1.0
9,推送镜像
docker push 192.168.98.129:8080/nginx:1.0
10,拉取镜像
 docker pull 192.168.98.129:8080/nginx:1.0

Docker Registry UI界面可以看到推送的镜像

Docker_第12张图片

Docker Registry UI界面可以直接copy拉取镜像命令,比如(docker pull 192.168.98.129:8080/nginx:1.0)

Docker_第13张图片

你可能感兴趣的:(Java基础,docker)