Docker常用操作命令
查看Docker版本和信息
#显示docker的版本信息
docker version
#显示docker的系统信息,包括镜像和容器的数量
docker info
docker 命令 --help #帮助命令
帮助文档的地址:https://docs.docker.com/engine/reference/commandline/docker/
一、镜像相关操作命令
docker images #查看所有本地主机上的镜像 可以使用docker image ls代替
docker search 搜索镜像
docker pull 下载镜像 docker image pull
docker rmi 删除镜像 docker image rm
1、搜索官方仓库镜像(docker search)
docker search 镜像名称
docker search centos
# 示例
# docker search mysql
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 11138 [OK]
mariadb MariaDB Server is a high performing open sou… 4221 [OK]
mysql/mysql-server Optimized MySQL Server Docker images. Create… 829 [OK]
percona Percona Server is a fork of the MySQL relati… 547 [OK]
phpmyadmin phpMyAdmin - A web interface for MySQL and M… 274 [OK]
centos/mysql-57-centos7 MySQL 5.7 SQL database server 89
mysql/mysql-cluster Experimental MySQL Cluster Docker images. Cr… 88
# 可选项
--filter=STARS=3000 # 搜索出来的镜像就死starts 大于3000的
# docker search mysql --filter=STARS=3000
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 11138 [OK]
mariadb MariaDB Server is a high performing open sou… 4221 [OK]
参数 | 说明 |
---|---|
NAME | 镜像名称 |
DESCRIPTION | 镜像说明 |
STARS | 点赞数量 |
OFFICIAL | 是否是官方的 |
AUTOMATED | 是否是自动构建的 |
2、查看镜像(docker images)
#查看所有本地主机上的镜像
docker images
docker image ls
docker image list
# 示例
# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest d1165f221234 4 months ago 13.3kB
# 解释
REPOSITORY 镜像的仓库源
TAG 镜像的标签
IMAGE ID 镜像的ID
CREATED 镜像的创建时间
SIZE 镜像的大小
# 可选项
-a, --all # 列出所有的镜像
-q, --quiet # 只显示镜像的id
docker images -aq #显示所有镜像的id
docker images -a
docker images -q
标签 | 含义 |
---|---|
REPOSITORY | 镜像所在的仓库名称 |
TAG | 镜像标签 |
IMAGEID | 镜像ID |
CREATED | 镜像的创建日期(不是获取该镜像的日期) |
SIZE | 镜像大小 |
3、下载镜像(docker pull)
拉取镜像
# 官方镜像
docker image pull 镜像名称
docker image pull 镜像名称:镜像标签
# 或简写为
docker pull 镜像名称
docker pull 镜像名称:镜像标签
# 比如
docker pull ubuntu
docker pull ubuntu:16.04
# 个人镜像
docker pull 仓库名称/镜像名称
docker pull xunmi/django
# 第三方仓库拉去
docker pull 第三方仓库地址/仓库名称/镜像名称
docker pull hub.c.163.com/library/mysql:latest
(默认仓库名为library,所有从官方获取镜像相当于`sudo docker image pull library/镜像名称`)
# 示例
# 下载镜像 docker pull 镜像名[:tag]
# docker pull mysql
Using default tag: latest #如果不写tag的话,默认使用的就是latest
latest: Pulling from library/mysql
b4d181a07f80: Pull complete # 分层下载,docker images核心 联合文件系统
a462b60610f5: Pull complete
578fafb77ab8: Pull complete
524046006037: Pull complete
d0cbe54c8855: Pull complete
aa18e05cc46d: Pull complete
32ca814c833f: Pull complete
9ecc8abdb7f5: Pull complete
ad042b682e0f: Pull complete
71d327c6bb78: Pull complete
165d1d10a3fa: Pull complete
2f40c47d0626: Pull complete
Digest: sha256:52b8406e4c32b8cf0557f1b74517e14c5393aff5cf0384eff62d9e81f4985d4b #签名
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest #真实地址
# 等价于
docker pull mysql
docker pull docker.io/library/mysql:latest
# 指定版本下载
# docker pull mysql:5.7
5.7: Pulling from library/mysql
b4d181a07f80: Already exists
a462b60610f5: Already exists
578fafb77ab8: Already exists
524046006037: Already exists
d0cbe54c8855: Already exists
aa18e05cc46d: Already exists
32ca814c833f: Already exists
52645b4af634: Pull complete
bca6a5b14385: Pull complete
309f36297c75: Pull complete
7d75cacde0f8: Pull complete
Digest: sha256:1a2f9cd257e75cc80e9118b303d1648366bc2049101449bf2c8d82b022ea86b7
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7
4、删除镜像(docker rmi)
docker image rm 镜像名或镜像ID 或 docker rmi 镜像名或镜像ID
docker image rm hello-world
docker image rm centos:latest
docker rmi 9e64176cd8a2
# docker rmi -f 镜像id # 删除指定的镜像
# docker rmi -f 镜像id 镜像id 镜像id 镜像id # 删除多个镜像
# docker rmi -f $(docker images -aq) # 删除全部的镜像
删除镜像的前提是没有使用这个镜像的容器,如果有需要先删除容器(报错:Error response from daemon: conflict: unable to delete 镜像ID (must be forced) - image is being used by stopped container 容器ID则代表有容器使用了此镜像。)可以尝试先执行docker rm 容器ID删除容器,如果还报错,可以看我下方删除容器的具体方法。
几条删除命令的区别
docker rm: 删除一个或多个 容器
docker rmi: 删除一个或多个 镜像
docker prune: 用来删除不再使用的 docker 对象
5、镜像导入导出命令介绍
涉及的命令有export、import、save、load
导入导出镜像参考:https://blog.csdn.net/ncdx111/article/details/79878098
导入镜像
帮助:docker load --help
命令格式:docker load [options]
示例
docker load -i nginx.tar
或
docker load < nginx.tar
其中-i和<表示从文件输入。会成功导入镜像及相关元数据,包括tag信息
# 压缩文件在操作的同级目录下
docker image load -i docker-centos.tar.gz
docker load -i ndricrane-latest.tar
导出镜像
帮助:docker save --help
命令格式:docker save [options] images [images...]
示例
docker save -o nginx.tar nginx:latest
或
docker save > nginx.tar nginx:latest
其中-o和>表示输出到文件,nginx.tar为目标文件,nginx:latest是源镜像名(name:tag)
docker save -o F:/study/ndricrane-latest.tar 192.168.1.153:5000/ndricrane:latest
docker image save centos > docker-centos.tar.gz
给镜像打上标签
docker tag <镜像名>:<原标签> <镜像名>:<新标签>
#docker tag nginx:latest nginx:lnmp
查看镜像详细信息
docker inspect <镜像 ID>
docker image inspect <镜像 ID>
docker image inspect centos
二、容器相关操作命令
docker run 镜像id #新建容器并启动
docker ps 或者 docker container list #列出所有运行的容器
docker rm 容器id #删除指定容器
docker start 容器id #启动容器
docker restart容器id #重启容器
docker stop 容器id #停止当前正在运行的容器
docker kill 容器id #强制停止当前容器
创建容器
docker container create -i -t --name mycontainer alpine
启动容器
docker container start --attach -i mycontainer
或者直接启动运行容器
docker run -it --name mycontainer2 alpine
参考官方文档:https://docs.docker.com/engine/reference/commandline/container_create/
1、运行容器
上面我们说过,镜像只是一个只读类型的文件,而我们的环境不可能只是一个这样的文件,所以我们需要把这个镜像加载成我们的环境,也就是让他变成容器。
docker run [可选参数] 镜像名:标签 [向启动容器中传入的命令]
语法格式:docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
docker run [可选参数] image
# 参数说明
--name="Name" 容器名字 tomcat01 tomcat02, 用来区分容器
-d 后台方式运行 java常用的nohup
-it 使用交互方式运行,进入容器查看内容
-p 指定容器的端口 -p 8080:8080
-p ip:主机端口:容器端口
-p 主机端口:容器端口(常用)
-p 容器端口
容器端口
-p 随机指定端口
[root@iZuf65oftugvcjgk2jncyeZ ~]# docker run -it centos /bin/bash
runc: symbol lookup error: runc: undefined symbol: seccomp_api_get
docker: Error response from daemon: cannot start a stopped process: unknown.
常用可选参数
option | 作用 |
---|---|
-i | 以交互模式运行容器,通常与 -t 同时使用 |
-t | 启动容器后,为容器分配一个命令行,通常与 -i 同时使用 |
-v/--volume | 目录映射,容器目录挂载到宿主机目录,格式: <host目录>:<容器目录> |
-d/--detach | 守护进程,后台运行该容器 |
-p | 指定端口映射,格式:主机(宿主)端口:容器端口 |
-P | 随机端口映射,容器内部端口随机映射到主机的端口 |
--name "nginx-lb" | 容器名字(默认会随机给名字,不支持中文字符!!!) |
-m, --memory bytes | 设置容器使用内存最大值 |
-h, --hostname string | 指定容器的 host name |
--dns 8.8.8.8 | 指定容器 dns 服务器 |
–network=host | 表示将主机的网络环境映射到容器中,使容器的网络与主机相同 |
-e username="ritchie" | 设置环境变量 |
示例
#最简单的运行一个容器
docker run nginx
docker run -it -d --privileged=true --name=hop-server -p 8181:8181\
-v /hop/files:/files \
-e HOP_SERVER_USER=admin \
apache/hop:latest
docker run --name ehub-system -p 18099:80 \
--volume /home/ehub-system/appsettings.json:/app/appsettings.json \
--volume /home/ehub-system/Cert/id4svr.pfx:/app/Cert/id4svr.pfx \
--volume /home/ehub-system/vault/:/home/vault \
--volume /home/ehub-system/logs/:/app/logs \
--detach 192.168.1.153:5000/tresinbackendbase:ndri.lic.off
参考:
https://docs.docker.com/engine/reference/commandline/container_run/
https://zhuanlan.zhihu.com/p/667438581
https://zhuanlan.zhihu.com/p/433827521
https://www.runoob.com/docker/docker-run-command.html
2、查看容器(docker ps)
# 查看当前所有正在运行的容器
docker ps
# 查看当前所有的容器
docker ps -a
# 使用过滤器(除了name外,常用的还可以指定id:id= 、所有停止的容器:status=exited,正在运行的容器:status=running 等)
docker ps -f name=指定的名字
# 显示2个上次创建的容器(2可以改变)
docker ps -n 2
# 显示最新创建的容器(包括所有状态)
docker ps -l
# 仅显示ip
docker ps -q
# 显示容器大小
docker ps -s
#docker ps命令 #列出当前正在运行的容器
-a # 列出当前正在运行的容器+带出历史运行过的容器
-n=? # 显示最近创建的容器
-q # 只显示容器的编号
# 列出当前正在运行的容器
[root@iZuf65oftugvcjgk2jncyeZ /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
#列出所有正在运行的容器包含历史运行过的容器
[root@iZuf65oftugvcjgk2jncyeZ /]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
460839d39a28 centos "/bin/bash" 6 minutes ago Exited (127) 2 minutes ago peaceful_mestorf
cbe729c88d10 centos "/bin/bash" 6 minutes ago Created dreamy_agnesi
185965df630e centos "/bin/bash" 7 minutes ago Created friendly_davinci
127e09783e48 feb5d9fea6a5 "/hello" 57 minutes ago Created hardcore_black
标签 | 含义 |
---|---|
CONTAINER ID | 镜像ID |
IMAGE | 创建容器的镜像名称 |
COMMAND | 默认启动命令(启动时会自动执行) |
CREATED | 创建容器的日期 |
STATUS | 当前的状态(启动了多久,多久之前退出等) |
PORTS | 映射的端口 |
NAMES | 容器的名称 |
SIZE | 容器大小(使用-s命令参数时才能看到) |
3、启动和关闭容器
# 启动容器
docker container start 容器名或容器id
# 或可简写为
docker start 容器名或容器id
#重启容器
docker restart 容器名或容器id
# 停止当前正在运行的容器
docker container stop 容器名或容器id
# 或可简写为
docker stop 容器名或容器id
# 强制关闭停止当前运行容器
docker container kill 容器名或容器id
# 或可简写为
docker kill 容器名或容器id
- 如果我们成功启动或者关闭一个容器的话,会返回容器名或者容器id
- stop和kill的区别: stop是比较优雅的关掉一个容器,类似我们正常退出一个软件,而kill是当一个进程出现意外无法正常关闭的时候,我们强行进行关闭,有点像我们使用任务管理器进行结束进程操作
4、操作后台容器
# 如果我只需要执行简单的一两条命令可以使用docker exec
# 执行单条命令 (-i: 启动并且保留交互式命令行; -t:作用是分配一个虚拟的终端; docker run )
docker exec -it 容器名或容器id 执行的命令
# 比如
docker exec -it kali-test whoami
# 用这种方法,我们还可以启动命令行,根据Linux的特性,系统程序会在/bin中,linux中常用的Shell有多个,其中大部分用的Linux默认的为bash
# 所以我们启动命令可以自行如下命令(除了/bin/bash外,linux一般还会带/bin/sh、/bin/rbash、/bin/dash等,具体区别可以自行百度)
docker exec -it 容器名或容器id /bin/bash
# 比如
docker exec -it kali-test /bin/bash
# 除了exec外还有attach可以使用,但它有个弊端,多终端启动attach后,都会会同步显示。如果有一个窗口阻塞了,那么其他窗口也无法再进行操作。
docker attach 容器名或容器id
# 比如
docker attach kali-test
exec可选参数 | 作用 |
---|---|
-d | 会创建一个守护式容器在后台运行(这样创建容器后不会自动登录容器)。 |
-e | 设置环境变量 |
-i | 表示以《交互模式》运行容器。 |
-t | 表示容器启动后会进入其命令行。加入这两个参数后,容器创建就能登录进去。即分配一个伪终端。 |
-u | 设置用户名和UID。 |
-w | 设置容器内的工作目录。 |
5、删除容器(docker rm)
# 使用rm删除容器
docker rm 容器名或容器id
# 列如
docker rm docker-test
docker rm 容器id # 删除指定容器,不能删除正在运行的容器,如果要强制删除 rm -f
docker rm -f $(docker ps -aq) # 删除所有的容器
docker ps -a -q | xargs docker rm # 删除所有的容器
6、容器制作成镜像
# 将容器制作成镜像
docker commit 容器名 镜像名
# 镜像打包备份(打包备份的文件会自动存放在当前命令行的路径下,如果想让保存的文件可以打开,可以加.tar后缀)
docker save -o 保存的文件名 镜像名
# 镜像解压
docker load -i 文件路径/备份文件
三、Docker部署常用中间件
docker部署MySQL
$ docker pull mysql:latest
# mkdir -p /home/mysql/conf
# cd docker_v/mysql/conf
# touch my.cnf
$ docker run -itd --name mysql-test -p 3306:3306 -v /home/mysql/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=123456 mysql
docker run -itd --name mysql-test -p 3306:3306 -v /home/mydir:/mydir -v /home/datadir:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=root -e TZ=Asia/Shanghai mysql:latest
参数说明:
-p 3306:3306 :映射容器服务的 3306 端口到宿主机的 3306 端口,外部主机可以直接通过 宿主机ip:3306 访问到 MySQL 的服务。
MYSQL_ROOT_PASSWORD=123456:设置 MySQL 服务 root 用户的密码。
参考:
mysql 5.7 https://blog.csdn.net/BThinker/article/details/123471514
mysql 8.0 https://blog.csdn.net/u014576291/article/details/105890286
docker部署RabbitMQ
docker pull rabbitmq:management
docker run -d -v rabbitmq-home:/var/lib/rabbitmq -p 15672:15672 -p 5672:5672 -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=admin --name rabbitmq --hostname=rabbitmqhostone rabbitmq:management
参考:
https://cloud.tencent.com/developer/article/1612598
https://juejin.cn/post/7198430801850105916
docker部署Consul
拉取镜像
docker pull hashicorp/consul
docker run -id --name=consul -p 8300:8300 -p 8301:8301 -p 8302:8302 -p 8500:8500 -p 8600:8600 -v f:/home/consul/data:/consul/data -v f:/home/consul/config:/consul/config hashicorp/consul agent -server -ui -node=n1 -bootstrap-expect=1 -client='0.0.0.0' -advertise='192.168.1.102'
docker部署MinIO
docker run -p 9000:9000 -p 9090:9090 --name minio1 -d -e "MINIO_ROOT_USER=admin" -e "MINIO_ROOT_PASSWORD=admin123" -v F:\minio\data:/data -v F:\minio\config:/root/.minio minio/minio server /data --console-address ":9090" -address ":9000"
docker run --name=minio --hostname=1c94aefa33a1 --mac-address=02:42:ac:11:00:04 --env=MINIO_ACCESS_KEY=minioadmin --env=MINIO_SECRET_KEY=minioadmin --volume=/home/minio/data:/data --volume=/home/minio/config:/root/.minio -p 19000:9000 -p 19090:9090 --restart=always --runtime=runc --detach=true minio/minio server /data --console-address :9090 -address :9000
docker run -p 9000:9000 -p 9090:9090 --name minio1 -d -e "MINIO_ROOT_USER=admin" -e "MINIO_ROOT_PASSWORD=admin123" -v /f/minio/data:/data -v /f/minio/config:/root/.minio minio/minio server /data --console-address ":9090" -address ":9000"
docker run -p 9000:9000 -p 9090:9090 --name minio1 -d -e "MINIO_ROOT_USER=admin" -e "MINIO_ROOT_PASSWORD=admin123" -v /f/minio/data:/data -v /f/minio/config:/root/.minio minio/minio server /data --console-address :9090 -address :9000
四、使用VS 2022镜像发布.Net 项目
参考:
https://learn.microsoft.com/zh-cn/visualstudio/containers/overview?view=vs-2022
https://learn.microsoft.com/zh-cn/visualstudio/containers/deploy-containerized?view=vs-2022
https://learn.microsoft.com/zh-cn/dotnet/core/docker/build-container?tabs=windows&pivots=dotnet-8-0
https://learn.microsoft.com/zh-cn/dotnet/core/docker/publish-as-container?pivots=dotnet-8-0
dockerfile介绍:
https://docs.docker.com/engine/reference/builder/
https://www.runoob.com/docker/docker-dockerfile.html
https://www.cnblogs.com/ityouknow/p/8588725.html
1、添加Dockerfile
解决方案下项目鼠标右键选择添加,然后选择docker支持,文件选项目标OS根据选择Linux或者Windows,点击确定添加Dockerfile
#Dockerfile示例
#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
# 暴露端口
EXPOSE 80
#设置时间为中国上海
ENV TZ=Asia/Shanghai
# 使用基础的 .NET 6.0 SDK 镜像作为构建环境
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src
#设置nuget源
COPY ["NuGet.Config", "."]
# 复制项目文件并还原 NuGet 包
#COPY ["TSDH.LogViewer/NuGet.Config", "TSDH.LogViewer/"]
COPY ["NuGet.Config", "."]
COPY ["TSDH.LogViewer/TSDH.LogViewer.csproj", "TSDH.LogViewer/"]
COPY ["Camunda.Worker/Camunda.Worker.csproj", "Camunda.Worker/"]
COPY ["TSDH.LogViewer.Plugin.JsmMQ/TSDH.LogViewer.Plugin.JsmMQ.csproj", "TSDH.LogViewer.Plugin.JsmMQ/"]
COPY ["TSDH.LogViewer.Shared/TSDH.LogViewer.Shared.csproj", "TSDH.LogViewer.Shared/"]
COPY ["TSDH.Shared/TSDH.Shared.csproj", "TSDH.Shared/"]
RUN dotnet restore "./TSDH.LogViewer/./TSDH.LogViewer.csproj"
# 复制所有项目文件并构建应用程序
COPY . .
WORKDIR "/src/TSDH.LogViewer"
RUN dotnet build "./TSDH.LogViewer.csproj" -c $BUILD_CONFIGURATION -o /app/build
# 发布应用程序
FROM build AS publish
ARG BUILD_CONFIGURATION=Release
RUN dotnet publish "./TSDH.LogViewer.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
# 使用 ASP.NET Core 6.0 运行时镜像作为最终镜像
FROM base AS final
WORKDIR /app
# 复制构建结果到最终镜像
COPY --from=publish /app/publish .
# 设置应用程序入口点
ENTRYPOINT ["dotnet", "TSDH.LogViewer.dll"]
如果项目比如使用私有nuget源
NuGet.Config内容如下
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<!-- 添加私有NuGet源 -->
<add key="Tresin nuget" value="http://192.168.1.152:5000/nuget" />
<!-- 添加官方NuGet源 -->
<add key="nuget.org" value="https://api.nuget.org/v3/index.json"/>
<!-- <add key="Microsoft Visual Studio Offline Packages" value="C:\Program Files (x86)\Microsoft SDKs\NuGetPackages\" /> -->
</packageSources>
<packageRestore>
<!-- 可选:启用自动还原 NuGet 包 -->
<add key="enabled" value="True" />
<!-- 可选:禁用解决方案还原 -->
<add key="automatic" value="True" />
</packageRestore>
<disabledPackageSources>
<!-- 可选:禁用默认的 NuGet 源 -->
<!-- <add key="nuget.org" value="true" /> -->
</disabledPackageSources>
<!-- <bindingRedirects>
<add key="skip" value="False" />
</bindingRedirects>
<packageManagement>
<add key="format" value="0" />
<add key="disabled" value="False" />
</packageManagement> -->
</configuration>
2、发布
前提:当前系统安装Docker Desktop并启动
2.1、解决方案下项目鼠标右键选择发布,在发布界面下选择目标为Docker 容器注册表
2.2、如果是发布到本地或者私有的Docekr仓库,选择其他Docekr容器注册表
2.3、选择本地私有Docker 仓库地址并填写用户名和密码,如果不需要发布到私有仓库这个可以跳过,没有用户名和密码可以不填
并且在Docker Desktop填写私有仓库地址,增加insecure-registries
{
"builder": {
"gc": {
"defaultKeepStorage": "20GB",
"enabled": true
}
},
"experimental": false,
"features": {
"buildkit": true
},
"insecure-registries": [
"192.168.1.153:5000"
]
}
2.4、选择Docekr Desktop发布
6、点击发布
运行该容器
docker run 镜像id -d name 容器名 -p 8099:80 -v /home/appsettings.json:/app/appsettings.json -v /home/logs:/app/logs
docker run --name 容器名称 -d -p 9099:8080 镜像名称:Tag
docker run --name test -d -p 9099:8080 -v /home/qggateway/yarp.json:/app/yarp.json -v /home/appsettings.json:/app/appsettings.json -v /home/logs:/app/logs net8Project:latest
参考:
操作命令参考:
https://zhuanlan.zhihu.com/p/442442997(推荐)
https://blog.csdn.net/ZHUZIH6/article/details/130368360
https://www.cnblogs.com/zhangxingeng/p/11236968.html
https://zhuanlan.zhihu.com/p/442442997
docker 中文文档:https://docker-practice.github.io/zh-cn/
菜鸟教程:https://www.runoob.com/docker/docker-tutorial.html
docker 官方文档:
https://docs.docker.com/engine/reference/commandline/dockerd/
下载docker地址: https://www.docker.com/get-started/
安装docker参考:
https://blog.csdn.net/qq_39611230/article/details/108641842
https://zhuanlan.zhihu.com/p/544888491
docker部署redis文档:https://docs.docker.com/samples/redis/