极速上手k8s,Kubernetes 从入门到摸鱼系列-实践篇

大家好,我是比特桃。本文为《极速上手k8s,Kubernetes 从入门到摸鱼系列》的实战篇,旨在快速上手k8s。如没有阅读过k8s相关理论的朋友,可以先阅读理论篇

1. 实践环境

k8s 的意义在于分布式大规模容器编排,所以如果我们想要在实际中发挥它的最大价值,至少也得需要 3 台机器。其中一台是主节点,剩余两台是工作节点。当然,也可以通过虚拟机中创建三个操作系统来实践。但这样操作还是很繁琐,其实在学习中,有更方便的办法进行。

  • minikube
    能让你在本地运行 Kubernetes。 minikube 在你本地的个人计算机(包括 Windows、macOS 和 Linux PC)运行一个单节点的 Kubernetes 集群,以便你来尝试 Kubernetes 或者开展每天的开发工作。
  • Kind
    另一个Kubernetes SIGs项目,但与minikube相比有很大不同。顾名思义,它将集群移动到Docker容器中。与生成VM相比,这将显著加快启动速度。
  • Docker Desktop
    在Windows、Mac中常用的Docker Desktop 中也内置了一个 k8s 功能,只需要在设置中即可打开使用。

生产环境上的集群安装和配置不建议使用 kind 或者 minikube。本文采用 minikube 来开展,使用其他的环境其实并没有太大区别。minikube的安装可以查阅官网,根据自身不同的操作系统进行安装。minikube 是可以选择依赖于容器还是本机VM:
在这里插入图片描述
所以我们可以选择使用 Docker 来当做 minikube 运行的地方,命令:

minikube start --driver='docker’
# 如果你在Docker Desktop版本中使用,建议将 Docke Engine 切换为 Linux的版本
docker context ls
docker context use default

2. 配置

在 k8s 中的核心思想就是:声明式无状态。
在这里插入图片描述
所以当我们想通过 API 或 CLI 和 k8s 中主节点中的 API Server 进行通讯的时候,必须采取一种格式。而 CLI 是使用 YAML 格式来进行的, YAML 对于后台开发者来说并不陌生,Spring 中的配置文件也是这个格式。k8s 的 YAML 声明文件分为三个部分:1)metadata;2)specification;3)status。
在这里插入图片描述

细心地朋友会发现,第三个 status 好像并没有在文件中声明。这是因为它是由 k8s 自动生成编辑的。它的主要作用就是,时刻将容器的现有状态(status)与声明状态(specification)相比较,如果发现有区别,则会向声明状态所靠拢。
在这里插入图片描述
比如这里在声明文件中是要两个 Nginx,但实际运行中发现只有一个,k8s 发现后会主动的再创建一个让两者相匹配。status 实际是由 etcd 进行维护的。

3. 实例

这个实例是一个 Node 应用程序,通过访问MongoDB进行数据访问,部署方式如下所示:
在这里插入图片描述
所涉及到的技术点为:

  • ConfigMap:MongoDB 连接信息
  • Secret:MongoDB 用户名及密码
  • Deployment & Service :应用组合及服务

3.1 MongoDB

首先创建 ConfigMap,k8s作为一个工具类的产品,其实可以直接仿照官网的例子来去改写。
在这里插入图片描述
将官网的例子复制下来,改写成如下形式:

apiVersion: v1
kind: ConfigMap
metadata:
  name: mongo-config
data:
  mongo-url: mongo-service

然后创建 Secret,这里需要注意的是,Secret 默认采用了Opaque 的加密方式。我们的用户名和密码需要通过 base64 加密后,粘贴上去。

apiVersion: v1
kind: Secret
metadata:
  name: mongo-secret
type: Opaque
data:
  mongo-user: bW9uZ291c2Vy
  mongo-password: bW9uZ29wYXNzd29yZA==

最后,我们来声明 Deployment & Service,这两个可以单独写,但也可以写在一起:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mongo-deployment
  labels:
    app: mongo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mongo
  template:
    metadata:
      labels:
        app: mongo
    spec:
      containers:
      - name: mongodb
        image: mongo:5.0
        ports:
        - containerPort: 27017
        env:
        - name: MONGO_INITDB_ROOT_USERNAME
          valueFrom:
            secretKeyRef:
              name: mongo-secret
              key: mongo-user
        - name: MONGO_INITDB_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mongo-secret
              key: mongo-password  
---
apiVersion: v1
kind: Service
metadata:
  name: mongo-service
spec:
  selector:
    app: mongo
  ports:
    - protocol: TCP
      port: 27017
      targetPort: 27017

其中的 template 我们第一次见到,它是为了声明 Pod 的,内部也有自己的元数据(metadata)和声明(specification)。这里面最为重要的就是声明中的容器(containers),其实可以理解为 docker-compose 中声明的 image 信息。
labels是一个标签,k8s 可以为任何组件指定一个标签,可以作为一个标识符。比如 Pod 的名字是变化莫测,就可以使用标签(labels)来快速识别和寻找特定的组件。
YMAL 语法中,使用---三个破折号来区分多个配置文件,所以我们使用破折号分割后,又声明了 Service。其中targetPort为 Pod 中声明的端口,port则可以任意指定未使用的端口。

3.2 Application

如法炮制,我们来声明部署应用部分。webapp.yaml如下所示:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: webapp-deployment
  labels:
    app: webapp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: webapp
  template:
    metadata:
      labels:
        app: webapp
    spec:
      containers:
      - name: webapp
        image: nanajanashia/k8s-demo-app:v1.0
        ports:
        - containerPort: 3000
        env:
        - name: USER_NAME
          valueFrom:
            secretKeyRef:
              name: mongo-secret
              key: mongo-user
        - name: USER_PWD
          valueFrom:
            secretKeyRef:
              name: mongo-secret
              key: mongo-password 
        - name: DB_URL
          valueFrom:
            configMapKeyRef:
              name: mongo-config
              key: mongo-url
---
apiVersion: v1
kind: Service
metadata:
  name: webapp-service
spec:
  type: NodePort
  selector:
    app: webapp
  ports:
    - protocol: TCP
      port: 3000
      targetPort: 3000
      nodePort: 30100

其中,我们在 APP 的 Service 中声明了 NodePort,它的作用旨在让外部浏览器访问。nodePort则为该 k8s 节点中 ip 所绑定的端口,只是它会有端口范围的限制。
在这里插入图片描述

4. 运行

将 YAML 文件写好后,就可以通过 Kubectl 告诉 k8s 集群,我们要这些服务组件。首先创建ConfigMap、Securit:

kubectl apply -f mongo-config.yaml
kubectl apply -f mongo-secret.yaml

然后创建MongoDB 和 APP应用:

kubectl apply -f mongo.yaml
kubectl apply -f webapp.yaml

在这里插入图片描述
执行kubectl get all查看当前组件状态:
在这里插入图片描述
这里只能看到我们的Deployment、Service、Pod,但配置文件需要单独的命令查询:

kubectl get configmap
kubectl get secret

如果想查看该组件的详细信息,则可以使用该命令:

kubectl describe service webapp-service

在Docker中我们经常查看容器的Log,在 k8s 中查看 pod 日志的命令:

kubectl logs pod名称 -f

总之,kubectl 作为 k8s 最强大的交互工具,它所含的命令集非常多,我们也很难全部记住。就像Linux命令一样,善用-- help~
最后,我们来访问一下这个 k8s 所部署的应用,查询minikube的ip地址:
在这里插入图片描述
可以看到minikube的ip是192.168.64.26,直接访问:
在这里插入图片描述

5. 总结

本文我们通过组合理论篇所学习到的组件,通过一个 Node.js 网页应用连接 MongoDB 的例子,实现了在 k8s 中部署使用。虽然在本机环境下用 minikube 会显得比 Docker Compose 要麻烦的多,但只要我们上了集群,就可以凸显出 k8s 的强大之处了。

猜你喜欢

转载自blog.csdn.net/u012558210/article/details/131746788