Kubernetes(3)_实操

前提:

Minikube 是一种轻量级的 Kubernetes 实现,可在本地计算机上创建 VM 并部署仅包含一个节点的简单集群。 Minikube 可用于 Linux , macOS 和 Windows 系统。Minikube CLI 提供了用于引导集群工作的多种操作,包括启动、停止、查看状态和删除。

//查看Minikube的版本
minikube version
//Minikube为您启动了一个虚拟机,并且一个Kubernetes集群现在正在该虚拟机中运行。
minikube start

命令行操作指令kubectl :

//查看版本
kubectl version
//查看集群详细信息
kubectl cluster-info
//查看节点信息
kubectl get nodes

创建Deployment

什么是Deployment:

Deployment 指挥 Kubernetes 如何创建和更新应用程序的实例 ,并且支持监控这些实例,出现故障提供解决方案。

//创建deployment 
kubectl create deployment kubernetes-bootcamp --image=gcr.io/google-samples/kubernetes-bootcamp:v1

这一步其实完成了三件事情:

  • 搜索可以运行应用程序实例的合适节点(我们只有一个可用节点)
  • 调度应用程序在该节点上运行
  • 配置集群在需要时重新调度新节点上的实例
//查看当前集群的deployment实例
kubectl get deployments 

在这里插入图片描述

  • NAME列出集群中部署的名称
  • READY显示当前副本/期望副本的比例
  • “最新”显示已更新以达到所需状态的副本数量。
  • AVAILABLE显示用户可用的应用程序副本的数量。
  • AGE显示应用程序已经运行的时间量

pod是kubernetes运行的最小单位, 运行在Kubernetes内部的Pods运行在一个私有的、孤立的网络上。默认情况下,它们在同一kubernetes集群中的其他pods和服务上是可见的,但在该网络之外是不可见的。当我们使用kubectl时,我们通过API端点与应用程序进行交互。

//kubectl命令可以创建一个代理,将通信转发到集群范围的专用网络。可以通过按control-C来终止代理,它在运行时不会显示任何输出(另开终端2来创建代理)。
kubectl proxy

此时本机器可以通过api和k8s集群建立了联系。

//本地查询版本---等同于kubectl version
curl http://localhost:8001/version

将pod_name存储在环境变量中,通过api查询pod信息,

export POD_NAME=$(kubectl get pods -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}')
echo Name of the Pod: $POD_NAME
curl http://localhost:8001/api/v1/namespaces/default/pods/$POD_NAME/

pod

什么是pod:

创建 Deployment 时, Kubernetes 添加了一个 Pod 来托管你的应用实例。Pod 是 Kubernetes 抽象出来的,表示一组一个或多个应用程序容器(如 Docker),以及这些容器的一些共享资源。这些资源包括:

  • 共享存储,当作卷
  • 网络,作为唯一的集群 IP 地址
  • 有关每个容器如何运行的信息,例如容器镜像版本或要使用的特定端口。

每个 Pod 都与调度它的工作节点绑定,并保持在那里直到终止(根据重启策略)或删除。 如果工作节点发生故障,则会在集群中的其他可用工作节点上调度相同的 Pod。

//获取集群所有pod
kubectl get pods
//详细展示pod信息
kubectl describe pods
//查询日志信息(pod_name已经被写入环境变量 且只有一个容器时容器名可以省略)
kubectl logs $POD_NAME
//我们使用exec命令并使用Pod的名称作为参数。让我们列出环境变量:
kubectl exec $POD_NAME -- env
//在Pod的容器中启动bash会话
kubectl exec -ti $POD_NAME -- bash

service

什么是service:

Service 是一个抽象层, 定义了 Pod 的逻辑集和访问 Pod 的协议,并为这些 Pod 支持外部流量暴露、负载平衡和服务发现。

例子,考虑一个具有3个副本数的用作图像处理的后端程序。这些副本是可替换的; 前端系统不应该关心后端副本,即使 Pod 丢失或重新创建。也就是说,Kubernetes 集群中的每个 Pod (即使是在同一个 Node 上的 Pod )都有一个唯一的 IP 地址,因此需要一种方法自动协调 Pod 之间的变更,以便应用程序保持运行。

之前在创建deployment的时候,想用api的形式访问pod(模拟集群外访问pod),必须创建代理kubectl proxy.

有了service之后,有如下的暴露方式:

  • ClusterIP (默认) - 在集群的内部 IP 上公开 Service 。这种类型使得 Service 只能从集群内访问。
  • NodePort - 使用 NAT 在集群中每个选定 Node 的相同端口上公开 Service 。使用: 从集群外部访问 Service。是 ClusterIP 的超集。
  • LoadBalancer - 在当前云中创建一个外部负载均衡器(如果支持的话),并为 Service 分配一个固定的外部IP。是 NodePort 的超集。
  • ExternalName - 通过返回带有该名称的 CNAME 记录,使用任意名称(由 spec 中的externalName指定)公开 Service。不使用代理。这种类型需要kube-dns的v1.7或更高版本。

label:

Service 是一种抽象,它允许 Pod 死亡并在 Kubernetes 中复制,而不会影响应用程序。在依赖的 Pod (如应用程序中的前端和后端组件)之间进行发现和路由是由Kubernetes Service 处理的。

Service 匹配一组 Pod 是使用 标签(Label)和选择器(Selector), 它们是允许对 Kubernetes 中的对象进行逻辑操作的一种分组原语。标签(Label)是附加在对象上的键/值对,可以以多种方式使用:

  • 指定用于开发,测试和生产的对象
  • 嵌入版本标签
  • 使用 Label 将对象进行分类

实操:

//查询集群中存在的pod
kubectl get pods
//查询集群中存在的service
kubectl get services

在这里插入图片描述

可以看到minikubes创建默认创建以ClusterIP方式暴露的service。

//改成以NodePort方式进行暴露
kubectl expose deployment/kubernetes-bootcamp --type="NodePort" --port 8080
//此时重新查看services
kubectl get services

在这里插入图片描述

可以看到此时多了名为kubectl-bootcamp的service,

//查看服务的详细信息
kubectl describe servicer/kubernetes-bootcamp

在这里插入图片描述

#创建一个名为NODE_PORT的环境变量,它具有指定的Node端口值:
export NODE_PORT=$(kubectl get services/kubernetes-bootcamp -o go-template='{{(index .spec.ports 0).nodePort}}')
echo NODE_PORT=$NODE_PORT

现在我们可以使用curl、Node的IP和对外公开的端口来测试应用程序是否暴露在集群外部:

curl $(minikube ip):$NODE_PORT

由此我们得到了服务端的返回:
在这里插入图片描述

//查看deployment 可以看到其自动为pod创建的标签
kubectl describe deployment

在这里插入图片描述

#用这个标签查询pod或者service
kubectl get pods -l app=kubernetes-bootcamp
kubectl get services -l app=kubernetes-bootcamp
#将pod的那么存储在环境变量中
export POD_NAME=$(kubectl get pods -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}')
echo Name of the Pod: $POD_NAME
#给pod赋予新的标签
kubectl label pods $POD_NAME version=v1
#查看pod的详细信息
kubectl describe pods $POD_NAME

在这里插入图片描述

//根据label删除service
kubectl delete service -l app=kubernates-bootcamp
//此时暴露方式为NodePort的service已经删除,再用api方式外部访问就会失败
curl $(minikube ip):$NODE_PORT
//相反进入pod里面执行就会成功
kubectl exec -ti $POD_NAME -- curl localhost:8080

在这里插入图片描述

扩缩容

什么是扩缩?

在之前的模块中,我们创建了一个 Deployment,然后通过 Service让其可以开放访问。Deployment 仅为跑这个应用程序创建了一个 Pod。 当流量增加时,我们需要扩容应用程序满足用户需求。

扩缩 是通过改变 Deployment 中的副本数量来实现的。 扩展 Deployment 将创建新的 Pods,并将资源调度请求分配到有可用资源的节点上,收缩 会将 Pods 数量减少至所需的状态

一旦有了多个应用实例,就可以没有宕机地滚动更新。

实操:

//查询deployment
kubectl get deployment
//查询ReplicaSet 
kubectl get rs

在这里插入图片描述

ReplicaSet 名字总是 [DEPLOYMENT-NAME]-[RANDOM-STRING] 形式,后边是根据pod随机生成的字符串。

  • DESIRED显示应用程序的所需副本数量,这是您在创建Deployment时定义的。这是理想状态。
  • CURRENT显示当前运行的副本数量。
//扩容
kubectl scale deployments/kubernetes-bootcamp --replicas=4
//再次查看deplyment
kubectl get deployments

在这里插入图片描述

此时有四个应用程序实例,查看pod的变化

kubectl get pods -o wide

在这里插入图片描述

扩容操作会记录在deployment的日志里面,

kuebctl describe deployments/kubernetes-bootcamp

在这里插入图片描述

此时查看暴露类型为NodePortd的service获取暴露的ip和端口:

kubectl describe services/kubernetes-bootcamp

在这里插入图片描述

将节点端口放到环境变量

export NODE_PORT=$(kubectl get services/kubernetes-bootcamp -o go-template='{{(index .spec.ports 0).nodePort}}')
echo NODE_PORT=$NODE_PORT
curl $(minikube ip):$NODE_PORT
curl $(minikube ip):$NODE_PORT
curl $(minikube ip):$NODE_PORT
curl $(minikube ip):$NODE_PORT

可以看到多次访问访问到了不同的pod。

在这里插入图片描述

//缩容
kubectl scale deployments/kubernetes-bootcamp --replicas=2

kubectl get deployments
kubectl get pods -o wide

在这里插入图片描述
在这里插入图片描述

滚动更新

什么是滚动更新?

滚动更新 允许通过使用新的实例逐步更新 Pod 实例,零停机进行 Deployment 更新。新的 Pod 将在具有可用资源的节点上进行调度。

在前面的模块中,我们将应用程序扩展为运行多个实例。这是在不影响应用程序可用性的情况下执行更新的要求。默认情况下,更新期间不可用的 pod 的最大值和可以创建的新 pod 数都是 1。这两个选项都可以配置为(pod)数字或百分比。 在 Kubernetes 中,更新是经过版本控制的,任何 Deployment 更新都可以恢复到以前的(稳定)版本 。

补充:

与应用程序扩展类似,如果 Deployment 是公开的,服务将在更新期间仅对可用的 pod 进行负载均衡。可用 Pod 是应用程序用户可用的实例。

滚动更新允许以下操作:

  • 将应用程序从一个环境提升到另一个环境(通过容器镜像更新)
  • 回滚到以前的版本
  • 持续集成和持续交付应用程序,无需停机
//查看pod 信息
kubectl get pods
kubectl describe pods

在这里插入图片描述

//重新设置镜像,该命令通知部署为应用程序使用不同的映像,并启动滚动更新
kubectl set image deployments/kubernetes-bootcamp kubernetes-bootcamp=jocatalin/kubernetes-bootcamp:v2

下面检验一下是否更新了:

//查看service
kubectl describe services/kubernetes-bootcamp
//将节点端口存入环境变量,方便使用
export NODE_PORT=$(kubectl get services/kubernetes-bootcamp -o go-template='{{(index .spec.ports 0).nodePort}}')
echo NODE_PORT=$NODE_PORT
//多次curl应用
curl $(minikube ip):$NODE_PORT
curl $(minikube ip):$NODE_PORT
curl $(minikube ip):$NODE_PORT

这时可以i看到其运行在v=2版本。

在这里插入图片描述

//查看状态
kubectl rollout status deployments/kubernetes-bootcamp

回滚:

//假如更新的镜像不存在
kubectl get deployments
kubectl get pods

在这里插入图片描述

//回退
kubectl rollout undo deployments/kubernetes-bootcamp

此时再次查询deployment和pod状态,当然也可以describe查看镜像版本,这里不展示了。

ConfigMaps、Secrets

ConfigMaps 许多应用程序会从配置文件、命令行参数或环境变量中读取配置信息 , ConfigMap提供了这么一个 向容器中注入配置信息的机制, ConfigMap 可以被用来保存单个属性,也 可以用来保存整个配置文件或者 JSON 二进制大对象*

Secrets 尽管也用来存储键值对,但区别于 ConfigMaps 的是:它针对机密/敏感数据,且存储格式为 Base64 编码。 secrets 的这种特性使得它适合于存储证书、密钥、令牌

demo:
背景:

部署的两个微服务称为“系统”和“库存”。系统微服务返回运行它的容器的JVM属性。库存微服务将系统微服务中的属性添加到库存中。这演示了如何在Kubernetes集群中独立的pod中实现两个微服务之间的通信。 简而言之就是使用服务直接使用k8s中configmap和secret中的配置,使用哪一个在/sample-kubernetes-config/start/kubernetes.yamlenv字段下规定,又哪些配置在configmap和secret中规定。

//进入项目目录
cd sample-kubernete-config/start/
//使用mvn构建两个项目
mvn package -pl system
mvn package -pl inventory
//部署到kubernates
kubectl apply -f kubernetes.yaml
//检查pod的状态,并检查它们何时处于就绪状态
kubectl wait --for=condition=ready pod -l app=inventory
kubectl wait --for=condition=ready pod -l app=system
//访问服务,该服务使用在请求中传递的用户id和密码进行保护。
curl -u bob:bobpwd http://$( minikube ip ):31000/system/properties

返回的是一个响应,它将向您显示正在运行的容器的JVM系统属性

在这里插入图片描述

//同理,访问库存服务
curl http://$( minikube ip ):32000/inventory/systems/system-service

库存服务将调用系统服务,并在返回结果之前将响应数据存储在库存服务中。

在这里插入图片描述

在本教程中,你将使用Kubernetes ConfigMap来修改X-App-Name: response头文件。运行以下curl命令查看它们的当前值:

curl -# -I -u bob:bobpwd -D - http://$( minikube ip ):31000/system/properties | grep -i ^X-App-Name:

在这里插入图片描述

修改系统微服务

将 /sample-kubernetes-config/start/system/src/main/java/system/SystemResource.java 文件修改为

package system;

// CDI
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.ws.rs.GET;
// JAX-RS
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import org.eclipse.microprofile.config.inject.ConfigProperty;

@RequestScoped
@Path("/properties")
public class SystemResource {

  @Inject
  @ConfigProperty(name = "APP_NAME")
  private String appName;

  @Inject
  @ConfigProperty(name = "HOSTNAME")
  private String hostname;

  @GET
  @Produces(MediaType.APPLICATION_JSON)
  public Response getProperties() {
    return Response.ok(System.getProperties())
      .header("X-Pod-Name", hostname)
      .header("X-App-Name", appName)
      .build();
  }
}

这些更改使用MicroProfile Config和CDI将名为APP_NAME的环境变量的值注入到SystemResource类的appName成员中。MicroProfile Config支持许多可以从中接收配置的配置源,包括环境变量。

修改库存微服务

将 /sample-kubernetes-config/start/inventory/src/main/java/inventory/client/SystemClient.java

中 // Basic Auth Credentials 下面的两行修改为:

  // Basic Auth Credentials
  @Inject
  @ConfigProperty(name = "SYSTEM_APP_USERNAME")
  private String username;

  @Inject
  @ConfigProperty(name = "SYSTEM_APP_PASSWORD")
  private String password;

库存服务是硬编码的,使用bob和bobpwd作为凭据,根据系统服务进行身份验证。使用Kubernetes Secret使这些凭据可配 。

这些更改使用MicroProfile Config和CDI将环境变量SYSTEM_APP_USERNAME和SYSTEM_APP_PASSWORD的值注入SystemClient类。

创建ConfigMap和Secret

在容器中配置环境变量有几种方法。您将使用Kubernetes ConfigMap和Kubernetes secret来设置这些值。这些是Kubernetes提供的资源,用于向容器提供配置值。一个好处是它们可以跨多个容器重用,包括为不同的容器分配不同的环境变量 。

//使用以下kubectl命令创建ConfigMap配置应用程序名称:
kubectl create configmap sys-app-name --from-literal name=my-system

该命令将一个名为sys-app-name的ConfigMap部署到您的集群。它有一个名为name的键,值为my-system。from-literal标志允许您指定要存储在ConfigMap中的单个键-值对。

//使用以下kubectl命令创建一个秘密来配置目录服务将用于对系统服务进行身份验证的凭证:
kubectl create secret generic sys-app-credentials --from-literal username=bob --from-literal password=bobpwd

这个命令看起来与创建ConfigMap的命令非常相似,唯一的区别是使用了generic这个词。这意味着您正在创建一个通用的秘密,这意味着它不是专门化类型的秘密。有不同类型的秘密,例如存储Docker凭据的秘密和存储公共/私有密钥对的秘密。

更新k8s的资源

根据ConfigMap和Secret中配置的值更新Kubernetes部署,以设置容器中的环境变量 ,编辑kebernetes.yaml(定义了deployment)。

注意valueFrom字段。它指定环境变量的值,可以从各种来源设置。来源包括ConfigMap、Secret和关于集群的信息。

在本例中,configMapKeyRef用ConfigMap sys-app-name的值设置键名。类似地,secretKeyRef使用来自Secret sys-app-凭据的值设置密钥的用户名和密码。

更新 /sample-kubernetes-config/start/kubernetes.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: system-deployment
  labels:
    app: system
spec:
  selector:
    matchLabels:
      app: system
  template:
    metadata:
      labels:
        app: system
    spec:
      containers:
      - name: system-container
        image: system:1.0-SNAPSHOT
        ports:
        - containerPort: 9080
        # Set the APP_NAME environment variable
        env:
        - name: APP_NAME
          valueFrom:
            configMapKeyRef:
              name: sys-app-name
              key: name
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: inventory-deployment
  labels:
    app: inventory
spec:
  selector:
    matchLabels:
      app: inventory
  template:
    metadata:
      labels:
        app: inventory
    spec:
      containers:
      - name: inventory-container
        image: inventory:1.0-SNAPSHOT
        ports:
        - containerPort: 9080
        # Set the SYSTEM_APP_USERNAME and SYSTEM_APP_PASSWORD environment variables
        env:
        - name: SYSTEM_APP_USERNAME
          valueFrom:
            secretKeyRef:
              name: sys-app-credentials
              key: username
        - name: SYSTEM_APP_PASSWORD
          valueFrom:
            secretKeyRef:
              name: sys-app-credentials
              key: password
---
apiVersion: v1
kind: Service
metadata:
  name: system-service
spec:
  type: NodePort
  selector:
    app: system
  ports:
  - protocol: TCP
    port: 9080
    targetPort: 9080
    nodePort: 31000
---
apiVersion: v1
kind: Service
metadata:
  name: inventory-service
spec:
  type: NodePort
  selector:
    app: inventory
  ports:
  - protocol: TCP
    port: 9080
    targetPort: 9080
    nodePort: 32000

部署更改
mvn package -pl system
mvn package -pl inventory
#删除旧的部署 发布新的
kubectl replace --force -f kubernetes.yaml‘
#查看service的pod状态
kubectl get --watch pods
#此时
curl -# -I -u bob:bobpwd -D - http://$( minikube ip ):31000/system/properties | grep -i ^X-App-Name:

您应该会看到响应X-App-Name头从system更改为my-system .

curl http://$( minikube ip ):32000/inventory/systems/system-service

通过发出以下curl请求,验证库存服务现在正在使用Kubernetes Secret作为凭证:。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值