简介
Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。Docker 从 17.03 版本之后分为 CE(Community Edition: 社区版) 和 EE(Enterprise Edition: 企业版),用社区版就可以了。
Docker 包括三个基本概念:
- 镜像(Image):Docker 镜像(Image),就相当于是一个 root 文件系统。比如官方镜像 ubuntu:16.04 就包含了完整的一套 Ubuntu16.04 最小系统的 root 文件系统。
- 容器(Container):镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
- 仓库(Repository):仓库可看成一个代码控制中心,用来保存镜像。
Docker提供了容器化的基础设施,而Kubernetes则建立在Docker之上,提供了容器的编排和管理功能。使用Docker可以方便地创建和打包容器,而Kubernetes则可以帮助我们管理和运行这些容器,使得应用程序的部署和管理更加简单和可靠。
安装运行Docker
下载安装对应版本即可:
Install Docker Desktop on Windows
或
Get Started with Docker
1,win10环境,安装Docker Desktop时如果报错:
Docker Desktop requires Windows 10 Pro/Enterprise/Home version 19044 or above.
原因是Docker Desktop 要求计算机必须运行64位的Windows 10版本,且操作系统版本为Windows 10 专业版、企业版或教育版19044 以上版本,不支持Windows家庭版。查看操作系统版本方式:设置 - 系统 - 关于- Windows规格
可以尝试使用更新 Windows 系统版本Windows10Upgrade9252.exe 然后再尝试安装Docker Desktop。
2,启动Docker Desktop时如果报错:
Docker Desktop - unexpected wsl error
这是因为docker默认使用了WSL选项,在Docker Desktop的"Settings"里:
但是当前 Windows10还无法使用Linux功能 WSL(Windows Subsystem for Linux)。
方式一:去掉WSL2的勾选,使用Hyper-V
如果Hyper-V默认没使能,通过以下方式开启:
控制面板 - 程序 - 启用或关闭 Windows 功能 (bios需要开启虚拟化支持)
Hyper-V 是微软开发的虚拟机,类似于 VMWare 或 VirtualBox,仅适用于 Windows 10。这是 Docker Desktop for Windows 所使用的虚拟机。但是,这个虚拟机一旦启用,QEMU、VirtualBox 或 VMWare Workstation 15 及以下版本将无法使用!
方式二:安装 WSL
将 WSL 2 设置为默认版本
C:\WINDOWS\system32>wsl --set-default-version 2
查看wsl版本情况:
显示子系统没有已安装的分发,并给出了两个解决方法。如方法二访问:https://aka.ms/wslstore,采用 旧版 WSL 的手动安装步骤 安装 Linux 分发版Ubuntu。
配置换源
选择Docker Engine,在编辑框中输入源,如:
{
"registry-mirrors":[
"https://docker.mirrors.ustc.edu.cn",
"https://registry.docker-cn.com",
"http://hub-mirror.c.163.com",
"https://mirror.ccs.tencentyun.com"
],
"insecure-registries":[],
"debug":true,
"experimental":false,
"data-root":"F:\\docker"
}
默认情况下, Docker环境下的其它相关镜像文件及容器文件,存储在:C:\ProgramData\Docker目录下,可以通过Windows Docker Destop中的Docker Enginer的配置文件进行更改,具体是JSON文件中增加如下一行:"data-root":"F:\\docker"
docker 基础使用
测试:启动成功后可以看到左下角的running状态:
打开cmd命令框,
输入“docker -v”
,“docker info”
可以看到对应信息。
输入“docker run hello-world”
,这行命令会让docker从官方仓库中拉取hello-world的镜像到本地,并且自动将其实例化成容器。出现下图所示的提示:
我们再去查看Docker Desktop的主页会出现对应记录。直接点击容器名,我们可以进入容器的交互界面,其中能看到容器的log、参数等信息:
获取当前所有镜像(docker images)
docker image ls
# 或者
docker images
上面图的结果字段含义如下:
标签 | 含义 |
---|---|
REPOSITORY | 镜像所在的仓库名称 |
TAG | 镜像标签 |
IMAGEID | 镜像ID |
CREATED | 镜像的创建日期(不是获取该镜像的日期) |
SIZE | 镜像大小 |
拉取镜像(docker pull)
除了使用官方的镜像外,我们还可以在仓库中申请一个自己的账号,保存自己制作的镜像,或者拉取使用他人的镜像。
# 官方镜像
docker image pull 镜像名称
# 或简写为
docker pull 镜像名称
# 比如
docker pull ubuntu
docker pull ubuntu:16.04
# 个人镜像
docker pull 仓库名称/镜像名称
docker pull gyd/django
# 第三方仓库拉取
docker pull 第三方仓库地址/仓库名称/镜像名称
docker pull hub.c.163.com/library/mysql:latest
(默认仓库名为library,所有从官方获取镜像相当于`sudo docker image pull library/镜像名称`
删除镜像(docker rmi)
docker image rm 镜像名或镜像ID 或 docker rmi 镜像名或镜像ID
docker image rm hello-world
docker rmi 9e64176cd8a2
删除镜像的前提是没有使用这个镜像的容器,如果有需要先删除容器(报错: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 对象
加载镜像(docker run)
上面我们说过,镜像只是一个只读类型的文件,而我们的环境不可能只是一个这样的文件,所以我们需要把这个镜像加载成我们的环境,也就是让他变成容器
docker run [可选参数] 镜像名 [向启动容器中传入的命令]
常用可选参数 | 作用 |
---|---|
-i | 表示以《交互模式》运行容器。 |
-d | 会创建一个守护式容器在后台运行(这样创建容器后不会自动登录容器)。 |
-t | 表示容器启动后会进入其命令行。加入这两个参数后,容器创建就能登录进去。即分配一个伪终端。 |
–name | 为创建的容器命名。(默认会随机给名字,不支持中文字符!!!) |
-v | 表示目录映射关系,即宿主机目录:容器中目录。注意:最好做目录映射,在宿主机上做修改,然后共享到容器上。 |
-p | 表示端口映射,即宿主机端口:容器中端口。 比如:-p 8080:80 就是将容器中的80端口,映射到主机中的8080端口 |
– network=host | 表示将主机的网络环境映射到容器中,使容器的网络与主机相同。每个 Docker 容器都有自己的网络连接空间连接到虚拟 LAN。使用此命令则会让容器和主机共享一个网络空间。 |
可以启动一个系统(这里我使用linux的一个发行版作为介绍):
docker run -i -d -t --name=my-test-kali kalilinux/kali-rolling
或可以简写为
docker run -idt --name=my-test-kali kalilinux/kali-rolling
如果加载的是一个我们没有的镜像,docker会自动从官方仓库中进行拉取:
或者我们可以启动一个网站
docker run -dp 8080:80 --name docker-test docker/getting-started
成功启动后,可以在浏览器中输入“http://localhost:8080/”
即可看到getting-started页面。
上面我们成功将镜像变成了容器,但上述的命令中我们都加入了-d,让容器在后台运行了。下面我们就来讲如何和正在运行的容器进行交互。
查看容器(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 start\stop\kill)
# 停止容器
docker container stop 容器名或容器id
# 或可简写为
docker stop 容器名或容器id
# 强制关闭容器
docker container kill 容器名或容器id
# 或可简写为
docker kill 容器名或容器id
# 启动容器
docker container start 容器名或容器id
# 或可简写为
docker start 容器名或容器id
如果我们成功启动或者关闭一个容器的话,会返回容器名或者容器id
操作后台容器(docker exec -it 、 attach)
之前我们下过一个kali并且放在了后台运行,并且使用docker ps -a
查看其中的STATUS属性是Up的,确保我们要进入的容器是开启状态。
开启容器后,如果需要在容器内执行命令,可以将后台切换到前台,也可能使用docker命令将我们需要执行的命令传入。 操作方法有很多种,这里我们介绍一些比较常用的方法:
# 如果我只需要执行简单的一两条命令可以使用docker exec
# 执行单条命令 (-i: 启动并且保留交互式命令行; -t:作用是分配一个虚拟的终端; docker run )
docker exec -it 容器名或容器id 执行的命令
# 比如
docker exec -it my-test-kali 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 my-test-kali /bin/bash
# 除了exec外还有attach可以使用,但它有个弊端,多终端启动attach后,都会会同步显示。如果有一个窗口阻塞了,那么其他窗口也无法再进行操作。
docker attach 容器名或容器id
# 比如
docker attach my-test-kali
删除容器(docker rm)
如我们需要删除一个容器,首先需要确保这个容器已经停止了,因为正在运行的容器是无法直接删除。 我们可以运行一下docker ps -a,如果发现没有停止,可以使用docker stop停止(STATUS下已Exited开头则是停止的)
# 使用rm删除容器
docker rm 容器名或容器id
# 列如
docker rm docker-test
保存镜像(docker commit\save\load)
镜像可以看作为是一种备份,如果我们后期环境出现了问题,可以还原到早期镜像。
镜像便于传播,可以让自己的其他设备或他人的重复利用变得更加简单容易。
# 将容器制作成镜像
docker commit 容器名 镜像名
# 镜像打包备份(打包备份的文件会自动存放在当前命令行的路径下,如果想让保存的文件可以打开,可以加.tar后缀)
docker save -o 保存的文件名 镜像名
# 镜像解压
docker load -i 文件路径/备份文件
我们将打包备份的镜像可以通过网络发送到其他设备上,使用docker镜像解压即可直接使用你的环境。
另外,Docker重启后镜像消失,也可以使用Docker的镜像导出和导入功能,将我们需要的镜像保存到本地,并在需要的时候重新导入:
docker save -o my_images.tar image1 image2 image3
docker load -i my_images.tar
docker 实践
示例-部署安装mysql程序
a. 拉取最新的镜像
docker image pull mysql
b. 创建mysql容器实例并启动
容器名是mysql,自定义。第一次执行,需要先创建容器并启动(容器名是mysql):
docker run --name mysql -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=1234 mysql
后续 直接执行 docker start 容器名即可:
docker start mysql
c. 设置并使用mysql
进入mysql 交互环境,使用创建容器时设置的账户密码登录mysql环境
docker exec -it mysql mysql -u root -p
接下来可以愉快的执行mysql相关命令啦! 比如查看数据库 show databases、创建数据库 create databses; 创建表 create table等。
本地运行的springboot应用也能正常使用容器里的mysql了。
Spingboot集成docker(docker build、run)
在传统的应用程序部署中,我们往往需要手动安装和配置各种应用程序所需的组件和依赖项。这个过程通常是非常繁琐的,因为我们需要确保我们部署的代码在各个环境中都能正常运行。而且,当我们需要在多个环境中部署同一个应用程序时,这个过程可能会变得更加复杂。因此,使用Docker来部署Spring Boot应用程序可以带来以下好处:
- 环境一致性: 使用Docker容器可以确保我们在不同的环境中运行相同版本的应用程序,不管是在开发、测试还是生产环境,都可以提供相同的运行环境。
- 部署更加简单: 使用Docker容器可以大大简化应用程序的部署流程。我们只需要把应用程序打包成一个Docker镜像,然后将这个镜像推送到Docker仓库中,就可以在任何支持Docker的环境中轻松地部署应用程序。
- 资源隔离: 每个Docker容器都是一个独立的环境,它们之间是隔离的。这意味着我们可以在同一台主机上运行多个容器,每个容器都有自己的资源,例如CPU和内存,这可以提高系统的资源利用率。
生成Spring Boot应用镜像和容器
下面使用Docker来部署Spring Boot应用程序的步骤:
这里我们准备好前面的springboot项目 用户管理系统 项目里的jar包,定时任务会每过10s打印一次日志:
E:\test>java -jar demospringboot-0.0.1-SNAPSHOT.jar
2023-11-01 20:24:21.059 INFO 11848 --- [ sched-exe-2-1] c.example.demospringboot.ScheduledTasks : AnalysisLogTask start:20:24:21
2023-11-01 20:24:31.065 INFO 11848 --- [ sched-exe-2-1] c.example.demospringboot.ScheduledTasks : AnalysisLogTask end:20:24:31
2023-11-01 20:24:32.076 INFO 11848 --- [ sched-exe-2-1] c.example.demospringboot.ScheduledTasks : AnalysisLogTask start:20:24:32
2023-11-01 20:24:42.079 INFO 11848 --- [ sched-exe-2-1] c.example.demospringboot.ScheduledTasks : AnalysisLogTask end:20:24:42
1,准备Docker环境
在使用Docker之前,启动redis和mysql依赖的容器:
# redis
docker run --name reids -d -p 6379:6379 redis
# mysql
docker run --name mysql -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=1234 mysql
Docker在创建容器时有四种网络模式:bridge/host/container/none,bridge为默认不需要用–net去指定,其他三种模式需要在创建容器时使用–net去指定。
- –net=bridge,这种模式会为每个容器分配一个独立的Network Namespace,
同一个宿主机上的所有容器会在同一个网段下,相互之间是可以通信的 - -net=host,容器将不会虚拟出IP/端口,而是使用宿主机的IP和端口。但是Host 模式只支持 Linux 系统,Windows 和 macOS 此参数无效。因此容器中的localhost是指向容器本身,所以要访问容器外的,需要明确指出宿主机的IP地址。官网说明:https://docs.docker.com/network/host/
因此这里我们采用默认的bridge模式,springboot应用通过ip访问redis和mysql。
查看容器ip:
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
14f52f108fdc mysql "docker-entrypoint.s…" 6 seconds ago Up 5 seconds 0.0.0.0:3306->3306/tcp, 33060/tcp mysql
f3570e0aed2b redis "docker-entrypoint.s…" 7 hours ago Up 7 hours 0.0.0.0:6379->6379/tcp redis
# docker inspect --format='{{.NetworkSettings.IPAddress}}' mysql
172.17.0.3
# docker inspect --format='{{.NetworkSettings.IPAddress}}' redis
172.17.0.2
并修改springboot配置文件applications.properties用到的ip,打包jar包:
# mysql
spring.datasource.url=jdbc:mysql://172.17.0.3:3306/mydatabase?createDatabaseIfNotExist=true
spring.datasource.username=root
spring.datasource.password=1234
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# mysql5: spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.initialize=true
spring.datasource.schema=classpath:schema.sql
# redis
spring.redis.host=172.17.0.2
spring.redis.port=6379
2,编写Dockerfile
在Docker环境准备好之后,接下来我们需要编写一个Dockerfile文件。Dockerfile文件是一个包含Docker容器构建步骤的脚本文件。构建Docker容器时,我们可以根据Dockerfile文件中的步骤来创建和打包Docker镜像。以下是一个简单的Dockerfile文件示例:
FROM openjdk:8-jdk-alpine
COPY target/demospringboot-0.0.1-SNAPSHOT.jar F:\docker
WORKDIR F:\docker
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "demospringboot-0.0.1-SNAPSHOT.jar"]
在这个Dockerfile文件中,我们使用了一个已经存在的openjdk:8-jdk-alpine镜像作为基础镜像,并将我们的Spring Boot应用程序打成jar包后复制到镜像中,并指定工作目录和开放的端口。最后,使用ENTRYPOINT指令指定了容器启动命令。
如果没有镜像,可以先去镜像仓库拉取镜像 DockerHub
docker pull openjdk:8-jdk-alpine
3,构建Docker镜像
在编写完Dockerfile文件后,我们需要使用docker build命令来构建Docker镜像,该命令具有以下基本语法:
# docker build -f my-app-dockfile -t my-springboot-img:v1 .
# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
my-springboot-img v1 a21af825fd01 5 seconds ago 153MB
redis latest 720b987633ae 3 weeks ago 158MB
mysql latest 5d2fb452c483 4 weeks ago 622MB
其中-t参数用于指定新镜像的名称和版本,"."表示Dockerfile文件所在的当前目录。
4,运行Spring Boot应用程序容器
构建Docker镜像后,我们可以通过docker run命令来运行容器,该命令具有以下基本语法:
# 其中--name参数用于指定容器的名称,-d为后台运行,-p为主机到容器的端口映射,最后指定要运行的镜像名称和标记。
# docker run --name my-springboot -d -p 8080:8080 my-springboot-img:v1
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
80d0cfcd7e60 my-springboot-img:v1 "java -jar demosprin…" 29 seconds ago Up 28 seconds 0.0.0.0:8080->8080/tcp my-springboot
14f52f108fdc mysql "docker-entrypoint.s…" 9 minutes ago Up 9 minutes 0.0.0.0:3306->3306/tcp, 33060/tcp mysql
f3570e0aed2b redis "docker-entrypoint.s…" 7 hours ago Up 7 hours 0.0.0.0:6379->6379/tcp redis
# docker inspect --format='{{.NetworkSettings.IPAddress}}' my-springboot
172.17.0.4
# 查看日志
docker logs my-springboot
docker logs -f my-springboot // 实时查看
注:mac 系统docker 使用桥接网络ip 宿主机无法访问容器。因为mac docker 实现的桥接网络是通过了一个linux 虚拟机实现,并不是直接在mac宿主机上创建虚拟网卡,导致无法ping通。解决方案参考:https://cloud.tencent.com/developer/article/2322367
docker 查看容器网络配置:
# docker inspect my-springboot | tail -n 20
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "39180cce7b9d653bbf0838bc95e3467cd9b749f32890d7afe7e8b064d7dbe4fb",
"EndpointID": "7ad7ebc523ab57a18d601ff94f37488b1c225cd8edd83806ae585c84c497b693",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.4",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:04",
"DriverOpts": null
}
}
}
}
]
# ping 172.17.0.4
PING 172.17.0.4 (172.17.0.4): 56 data bytes
5,部署Docker镜像
最后,我们可以将Docker镜像部署到任何支持Docker的环境中。例如,我们可以使用Docker Swarm或者Kubernetes等集群管理工具来管理Docker容器。
从Spring Boot容器中连接到另一个容器中的MySQL
上面我们的springboot应用采用了ip访问mysql容器,但是由于容器ip可能会变,比较好的访问方法是使用Docker的网络功能来实现:
(1)创建一个自定义的Docker网络:运行以下命令创建一个自定义的Docker网络,以便容器可以相互通信。
docker network create mynetwork
(2)启动MySQL容器:在创建MySQL容器时,将其连接到自定义的Docker网络。运行以下命令启动MySQL容器:
docker run --name mysql-container --network=mynetwork -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=1234 mysql
(3)在Spring Boot配置中使用容器名称:在Spring Boot的配置文件中,将localhost
或ip
替换为MySQL容器的名称(在本例中为mysql-container
)。修改配置如下:
spring.datasource.url=jdbc:mysql://mysql-container:3306/mydatabase?createDatabaseIfNotExist=true ```
基于jar包生成镜像:
# docker build -f my-app-dockfile -t my-springboot-img:v1 .
(4)启动Spring Boot容器:在启动Spring Boot容器时,将其连接到相同的自定义Docker网络。运行以下命令启动Spring Boot容器:
# docker run --name my-springboot --network=mynetwork -d -p 8080:8080 my-springboot-img:v1
这样,Spring Boot容器就可以通过Docker网络连接到MySQL容器中的MySQL数据库了。
安装运行Kubernetes
Kubernetes 配置方式:
- 右键点击Docker Desktop系统托盘图标,选择"Settings"。
- 在"Kubernetes"选项卡中,启用Kubernetes,然后点击"Apply & Restart"按钮以应用更改。
- Docker将自动为你配置Kubernetes,并在运行时创建一个Kubernetes集群。
国内的用户如果一直停留在Starting状态,可能是镜像源无法下载,需要提前把Kubernetes需要的Images拉取下来。
打开PowerShell
,注:不要使用PowerShell ISE。交互式终端在PowerShell ISE中不起作用(但它们在PowerShell中起作用)。见docker / for-win / issues / 223。
并下载k8s-for-docker-desktop,这是阿里提供了一个项目,只要checkout到你需要k8s的版本分支上,然后执行一个脚本就ok了。当前k8s-for-docker-desktop的 master 分支已经在支持到 Docker for Mac/Windows 4.24.1 (包含 Docker CE 24.0.2 和 Kubernetes 1.27.2)
版本配套详见:
https://github.com/AliyunContainerService/k8s-for-docker-desktop.git
macOS:
git clone git@github.com:maguowei/k8s-docker-desktop-for-mac.git
Docker Desktop 历史版本下载:https://docs.docker.com/desktop/release-notes/
运行下面的命令拉取Kubernetes需要的Images:
Set-ExecutionPolicy -ExecutionPolicy bypass // PowerShell脚本权限
git clone https://github.com/AliyunContainerService/k8s-for-docker-desktop.git
cd k8s-for-docker-desktop
.\load_images.ps1
执行完后通过docker images
可以看到镜像拉取成功了:
不过windows上 k8s-for-docker-desktop拉取的镜像并不完整(mac没问题),还要增加如下几个镜像:
docker pull docker/desktop-kubernetes:kubernetes-v1.25.9-cni-v1.1.1-critools-v1.25.0-cri-dockerd-v0.2.6-1-debian
docker pull docker/desktop-storage-provisioner:v2.0
docker pull docker/desktop-vpnkit-controller:v2.0
然后再回到Docker Desktop卡住的界面,执行一下“Reset Kubernetes Cluster”,左下角running成功。
验证执行:kubectl cluster-info
和 kubectl get nodes
命令
➜ kubectl cluster-info
Kubernetes control plane is running at https://127.0.0.1:6443
CoreDNS is running at https://127.0.0.1:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
➜ kubectl get nodes
NAME STATUS ROLES AGE VERSION
docker-desktop Ready control-plane 2d4h v1.27.2
Kubernetes实践
最简部署
Pod是k8s中最小的可部署单元,它可以包含一个或多个容器。
命令运行:
#运行一个镜像版本为6.2.5 的redis程序
# kubectl run redis --image=redis:6.2.5
# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
redis 0/1 ContainerCreating 0 16s <none> docker-desktop <none> <none>
# kubectl delete pod redis // 或 --all --force
YAML文件运行:
# vim pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: redis
spec:
# 定义容器,可以多个
containers:
- name: redis # 容器名字
image: redis:6.2.5 # 镜像
ports:
- containerPort: 6379
- name: mysql
image: mysql:latest
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
value: "1234"
# 启动pod
# kubectl apply -f pod.yaml
# 关闭pod
# kubectl delete -f pod.yaml
pod/redis-mysql created
# 查看pod
# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
redis-mysql 0/2 ContainerCreating 0 5s <none> docker-desktop <none> <none>
# 查看所有信息
# kubectl get all
NAME READY STATUS RESTARTS AGE
pod/redis-mysql 0/2 ContainerCreating 0 3m48s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 2d6h
status定义说明:
# 查看pod详细信息
# kubectl describe pod
Name: redis-mysql
Namespace: default
Priority: 0
Service Account: default
Node: docker-desktop/192.168.65.3
Start Time: Fri, 17 Nov 2023 23:35:40 +0800
Labels: <none>
Annotations: <none>
Status: Pending
IP:
IPs: <none>
Containers:
redis:
Container ID:
Image: redis:6.2.5
Image ID:
Port: 6379/TCP
Host Port: 0/TCP
State: Waiting
Reason: ContainerCreating
Ready: False
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-nrqf6 (ro)
mysql:
Container ID:
Image: mysql:latest
Image ID:
Port: 3306/TCP
Host Port: 0/TCP
State: Waiting
Reason: ContainerCreating
Ready: False
Restart Count: 0
Environment:
MYSQL_ROOT_PASSWORD: 1234
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-nrqf6 (ro)
Conditions:
Type Status
Initialized True
Ready False
ContainersReady False
PodScheduled True
Volumes:
kube-api-access-nrqf6:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 5s default-scheduler Successfully assigned default/redis-mysql to docker-desktop
Normal Pulling 5s kubelet Pulling image "redis:6.2.5"
YAML文件说明
apiVersion: v1 # 【必须】版本号
kind: Pod # 【必选】Pod
metadata: # 【必选-Object】元数据
name: String # 【必选】 Pod的名称
namespace: String # 【必选】 Pod所属的命名空间
labels: # 【List】 自定义标签列表
- name: String
annotations: # 【List】 自定义注解列表
- name: String
spec: # 【必选-Object】 Pod中容器的详细定义
containers: # 【必选-List】 Pod中容器的详细定义
- name: String # 【必选】 容器的名称
image: String # 【必选】 容器的镜像名称
imagePullPolicy: [Always | Never | IfNotPresent] # 【String】 镜像拉取策略
command: [String] # 【List】 容器的启动命令列表,如果不指定,则使用镜像打包时使用的启动命令
args: [String] # 【List】 容器的启动命令参数列表
workingDir: String # 容器的工作目录
volumeMounts: # 【List】 挂载到容器内部的存储卷配置
- name: String # 引用Pod定义的共享存储卷的名称,需使用volumes[]部分定义的共享存储卷名称
mountPath: Sting # 存储卷在容器内mount的绝对路径,应少于512个字符
readOnly: Boolean # 是否为只读模式,默认为读写模式
ports: # 【List】 容器需要暴露的端口号列表
- name: String # 端口的名称
containerPort: Int # 容器需要监听的端口号
hostPort: Int # 容器所在主机需要监听的端口号,默认与containerPort相同。设置hostPort时,同一台宿主机将无法启动该容器的第二份副本
protocol: String # 端口协议,支持TCP和UDP,默认值为TCP
env: # 【List】 容器运行前需设置的环境变量列表
- name: String # 环境变量的名称
value: String # 环境变量的值
resources: # 【Object】 资源限制和资源请求的设置
limits: # 【Object】 资源限制的设置
cpu: String # CPU限制,单位为core数,将用于docker run --cpu-shares参数
memory: String # 内存限制,单位可以为MB,GB等,将用于docker run --memory参数
requests: # 【Object】 资源限制的设置
cpu: String # cpu请求,单位为core数,容器启动的初始可用数量
memory: String # 内存请求,单位可以为MB,GB等,容器启动的初始可用数量
# 【Object】 对Pod内各容器健康检查的设置,当探测无响应几次之后,系统将自动重启该容器。
# 可以设置的方法包括:exec、httpGet和tcpSocket。对一个容器只需要设置一种健康检查的方法
livenessProbe:
exec: # 【Object】 对Pod内各容器健康检查的设置,exec方式
command: [String] # exec方式需要指定的命令或者脚本
httpGet: # 【Object】 对Pod内各容器健康检查的设置,HTTGet方式。需要指定path、port
path: String
port: Number
host: String
scheme: String
httpHeaders:
- name: String
value: String
tcpSocket: # 【Object】 对Pod内各容器健康检查的设置,tcpSocket方式
port: Number
initialDelaySeconds: Number # 容器启动完成后首次探测的时间,单位为s
timeoutSeconds: Number # 对容器健康检查的探测等待响应的超时时间设置,单位为s,默认值为1s。
periodSeconds: Number # 对容器健康检查的定期探测时间设置,单位为s,默认10s探测一次
successThreshold: 0
failureThreshold: 0
securityContext:
privileged: Boolean
# Pod的重启策略 一旦终止运行,都将重启 | 终止后kubelet将报告给master,不会重启
# 只有Pod以非零退出码终止时,kubelet才会重启该容器。如果容器正常终止(退出码为0),则不会重启。
restartPolicy: [Always | Never | OnFailure]
nodeSelector: object # 设置Node的Label,以key:value格式指定,Pod将被调度到具有这些Label的Node上
imagePullSecrets: # 【Object】 pull镜像时使用的Secret名称,以name:secretkey格式指定
- name: String
# 是否使用主机网络模式,默认值为false。设置为true表示容器使用宿主机网络,不再使用docker网桥,该Pod将无法在同一台宿主机上启动第二个副本
hostNetwork: Boolean
volumes: # 【List】 在该Pod上定义的共享存储卷列表
- name: String # 共享存储卷的名称,volume的类型有很多emptyDir,hostPath,secret,nfs,glusterfs,cephfs,configMap
emptyDir: {} # 【Object】 类型为emptyDir的存储卷,表示与Pod同生命周期的一个临时目录,其值为一个空对象:emptyDir: {}
hostPath: # 【Object】 类型为hostPath的存储卷,表示挂载Pod所在宿主机的目录
path: String # Pod所在主机的目录,将被用于容器中mount的目录
secret: # 【Object】类型为secret的存储卷,表示挂载集群预定义的secret对象到容器内部
secretName: String
items:
- key: String
path: String
configMap: # 【Object】 类型为configMap的存储卷,表示挂载集群预定义的configMap对象到容器内部
name: String
items:
- key: String
path: String
k8s的yaml文件中kind类型详解
在Kubernetes(k8s)的YAML语法中,kind是一种重要的关键字,它用于指定Kubernetes资源的类型。根据Kubernetes官方文档,以下是kind可能的取值:
Deployment:用于定义应用程序的声明式更新。
StatefulSet:用于有状态应用程序的声明式更新和管理。
DaemonSet:用于在集群中运行一个pod的声明式更新和管理。
Job:用于在集群上运行一次性任务的声明式更新和管理。
CronJob:用于在集群上运行定期作业的声明式更新和管理。
Service:用于定义一组pod的逻辑集合,以及访问这些pod的方式。
Pod:一个Kubernetes中最基本的资源类型,它用于定义一个或多个容器的共同运行环境。
ReplicaSet:用于确保在集群中运行指定数量的pod的声明式更新和管理。
ConfigMap:用于存储非敏感数据(如配置文件)的声明式更新和管理。
Secret:用于存储敏感数据(如密码和密钥)的声明式更新和管理。
ServiceAccount:用于定义一个pod的身份验证信息,以及与Kubernetes API Server进行交互的权限。
Ingress:用于定义从外部访问Kubernetes集群中服务的方式。
PersistentVolume:用于定义持久化存储卷,并使它们在Kubernetes集群中可用。
StorageClass:用于定义不同类型的存储,例如云存储、本地存储等,并为这些存储类型指定默认的参数和策略。
Namespace:用于在Kubernetes集群中创建逻辑分区,从而将资源隔离开来,以提高安全性和可维护性。
ServiceMonitor:用于自动发现和监控在Kubernetes集群中运行的服务。
HorizontalPodAutoscaler:用于自动调整Kubernetes集群中的pod副本数量,以根据当前负载需求实现自动扩展或收缩。
NetworkPolicy:用于定义网络访问策略,以控制pod之间的网络流量。
CustomResourceDefinition:用于定义自定义资源,以扩展Kubernetes API和CRD操作。
PodDisruptionBudget:用于定义维护期间可以安全中断的pod的最小数量,以确保Kubernetes集群的高可用性。
Role:用于定义对Kubernetes资源的操作权限,例如读、写、更新、删除等。
ClusterRole:与Role类似,但是可以在整个Kubernetes集群中使用。
这些kind类型扩展了Kubernetes API的功能,使得Kubernetes更加灵活和强大,可以满足不同场景下的需求。文章来源:https://www.toymoban.com/news/detail-751531.html
参考:
https://blog.csdn.net/KingCruel/article/details/113775272
https://blog.csdn.net/bamboo_2001/article/details/129612150
https://zhuanlan.zhihu.com/p/619273476?utm_id=0
https://zhuanlan.zhihu.com/p/653147039
https://blog.csdn.net/cloudflash/article/details/128796673
https://blog.csdn.net/qq_16253859/article/details/130811097
https://www.cnblogs.com/linyouyi/p/10691060.html
https://zhuanlan.zhihu.com/p/654662196文章来源地址https://www.toymoban.com/news/detail-751531.html
到了这里,关于K8s Docker实践一的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!