K8s Docker实践一

简介

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 及以下版本将无法使用!

确保 Hyper-V 平台虚拟化功能已在 Windows 功能中启用。可以通过控制面板启用,或使用 PowerShell 命令 Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All

BIOS开启虚拟化参考:
1,导航到CPU或高级设置,在BIOS界面中,根据不同的BIOS界面,您可能需要导航到“Advanced”,“CPU Configuration”或“Advanced CPU Features”部分。

2,在相应的菜单中查找与“VT”, “Virtualization Technology”或“Intel® Virtualization Technology”相关的选项。

方式二:安装 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的配置文件中,将localhostip替换为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-infokubectl 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: # 【必选-ObjectPod中容器的详细定义
  containers: # 【必选-ListPod中容器的详细定义
  - 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 # 端口协议,支持TCPUDP,默认值为TCP
    env: # 【List】 容器运行前需设置的环境变量列表
    - name: String # 环境变量的名称
      value: String # 环境变量的值
    resources: # 【Object】 资源限制和资源请求的设置
      limits: # 【Object】 资源限制的设置
        cpu: String # CPU限制,单位为core数,将用于docker run --cpu-shares参数
        memory: String # 内存限制,单位可以为MBGB等,将用于docker run --memory参数
      requests: # 【Object】 资源限制的设置
        cpu: String # cpu请求,单位为core数,容器启动的初始可用数量
        memory: String # 内存请求,单位可以为MBGB等,容器启动的初始可用数量
    # 【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 # 设置NodeLabel,以key:value格式指定,Pod将被调度到具有这些LabelNode上
  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 APICRD操作。
PodDisruptionBudget:用于定义维护期间可以安全中断的pod的最小数量,以确保Kubernetes集群的高可用性。
Role:用于定义对Kubernetes资源的操作权限,例如读、写、更新、删除等。
ClusterRole:与Role类似,但是可以在整个Kubernetes集群中使用。

这些kind类型扩展了Kubernetes API的功能,使得Kubernetes更加灵活和强大,可以满足不同场景下的需求。

参考:
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

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值