【Kubernetes】K8s笔记(六):初级篇回顾和和实战

1. Kubernetes 技术要点回顾

容器只是针对单个进程的隔离和封装,而实际的应用场景却是要求许多的应用进程互相协同工作,其中的各种关系和需求非常复杂,在容器这个技术层次很难掌控。

为了解决这个问题,容器编排(Container Orchestration)就出现了,本质上还是在集群里调度管理应用程序,只不过管理的主体由人变成了计算机,管理的目标由原生进程变成了容器和镜像。

Kubernetes 源自 Borg 系统,它凝聚了 Google 的内部经验和 CNCF 的社区智慧,所以战胜了竞争对手 Apache Mesos 和 Docker Swarm,成为了容器编排领域的事实标准,也成为了云原生时代的基础操作系统。

架构

Kubernetes 的 Master / Node 架构是自动化运维的关键,下面的架构图出自 Kubernetes Blog

image

Kubernetes 将集群中的计算资源定义为节点 Node,划分为控制平面 Control Plane 和数据平面 Data Plane:

  • 控制平面是 Master Node,负责管理集群和运维监控,核心组件是 apiServer etcd scheduler controller-manager

  • 数据平面是 Worker Node,受到 Master Node 的管控,核心组件是 kubelet kube-proxy container-runtime

Kubernetes 还支持插件机制,能够灵活地扩展各项功能,常用插件有 DNS 和 Dashboard。

【Kubernetes】K8s笔记(一):什么是k8s,它解决了什么问题,它的机制是什么

API 对象

为了更好地管理集群和业务应用,Kubernetes 从现实世界中抽象出了许多概念,称为“API 对象”,管理者使用 YAML 语言来描述他们。

YAML 是 JSON 的超集,但语法更简洁,表现能力更强,更重要的是它以“声明式”来表述对象的状态,不涉及具体的操作细节,这样 Kubernetes 就能够依靠存储在 etcd 里集群的状态信息,不断地“调控”对象,直至实际状态与期望状态相同,这个过程就是 Kubernetes 的自动化运维管理。

【Kubernetes】K8s笔记(二):使用 YAML 描述 Kubernetes API 对象

Kubernetes 里有很多的 API 对象,其中最核心的对象是“Pod”,它捆绑了一组存在密切协作关系的容器,容器之间共享网络和存储,在集群里必须一起调度一起运行。通过 Pod 这个概念,Kubernetes 就简化了对容器的管理工作,其他的所有任务都是通过对 Pod 这个最小单位的再包装来实现的

【Kubernetes】K8s笔记(三):Kubernetes 中的核心概念 Pod

除了核心的 Pod 对象,基于“单一职责”和“对象组合”这两个基本原则,我们又学习了 4 个比较简单的 API 对象,分别是 Job/CronJob 和 ConfigMap/Secret。

Kubernetes 也提供一个客户端工具 kubectl,它直接与 Master 节点的 apiserver 通信,把 YAML 文件发送给 RESTful 接口,从而触发 Kubernetes 的对象管理工作流程。kubectl 的命令很多,查看自带文档可以用 api-resources explain ,查看对象状态可以用 get describe logs ,操作对象可以用 run apply exec delete 等等。

使用 YAML 描述 API 对象也有固定的格式,必须写的“头字段”是 apiVersion kind metadata,它们表示对象的版本、种类和名字等元信息。实体对象如 Pod、Job、CronJob 会再有 spec 字段描述对象的期望状态,最基本的就是容器信息,非实体对象如 ConfigMap、Secret 使用的是 data 字段,记录一些静态的字符串信息。

2. 搭建一个 WordPress 博客

下面我们就在 Kubernetes 集群里再搭建出一个 WordPress 网站,这个网站需要三个应用:Nginx,WordPress 和 MariaDB。其中 WordPress 和 MariaDB 运行在Kubernetes 中,Nginx 作为容器为WordPress 提供反向代理。

image

  • 应用封装:现在 WordPress、MariaDB 这两个应用被封装成了 Pod(由于它们都是在线业务,所以 Job/CronJob 在这里派不上用场),运行所需的环境变量也都被改写成 ConfigMap,统一用“声明式”来管理,比起 Shell 脚本更容易阅读和版本化管理。

  • 网络环境:Kubernetes 集群在内部维护了一个自己的专用网络,这个网络和外界隔离,要用特殊的“端口转发”方式来传递数据,还需要在集群之外用 Nginx 反向代理这个地址,这样才能实现内外沟通,对比 Docker 的直接端口映射,这里略微麻烦了一些。

2.1 编排 MariaDB 对象

MariaDB 需要 4 个环境变量,比如数据库名、用户名、密码等,在 Docker 里我们是在命令行里使用参数 --env,而在 Kubernetes 里我们就应该使用 ConfigMap,为此需要定义一个 maria-cm 对象:

apiVersion: v1
kind: ConfigMap
metadata:
  name: maria-cm

data:
  DATABASE: 'db'
  USER: 'wp'
  PASSWORD: '123'
  ROOT_PASSWORD: '123'
$ kubectl apply -f maria-cm.yaml 
configmap/maria-cm created
$ kubectl get cm
NAME               DATA   AGE
kube-root-ca.crt   1      6h14m
maria-cm           4      10s

然后定义 Pod 对象 maria-pod,把配置信息注入 Pod,让 MariaDB 运行时从环境变量读取这些信息:

apiVersion: v1
kind: Pod
metadata:
  name: maria-pod
  labels:
    app: wordpress
    role: database

spec:
  containers:
  - image: mariadb:10
    name: maria
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 3306

    envFrom:
    - prefix: 'MARIADB_'
      configMapRef:
        name: maria-cm

注意这里我们使用了一个新的字段 envFrom,这是因为 ConfigMap 里的信息比较多,如果用 env.valueFrom 一个个地写会非常麻烦,容易出错,而 envFrom 可以一次性地把 ConfigMap 里的字段全导入进 Pod,并且能够指定变量名的前缀(即这里的 MARIADB_)。

使用 kubectl apply 创建这个对象之后,可以用 kubectl get pod 查看它的状态,如果想要获取 IP 地址需要加上参数 -o wide

$ kubectl apply -f mariadb-pod.yml
pod/maria-pod created
$ kubectl get pod -o wide
NAME        READY   STATUS    RESTARTS   AGE     IP           NODE       NOMINATED NODE   READINESS GATES
maria-pod   1/1     Running   0          4m19s   172.17.0.3   minikube   <none>           <none>

2.2 编排 WordPress 对象

还是先用 ConfigMap 定义它的环境变量:

apiVersion: v1
kind: ConfigMap
metadata:
  name: wp-cm

data:
  HOST: '172.17.0.3'
  USER: 'wp'
  PASSWORD: '123'
  NAME: 'db'

在这个 ConfigMap 里要注意的是 HOST 字段,它必须是 MariaDB Pod 的 IP 地址,如果不写正确 WordPress 会无法正常连接数据库。

$ kubectl apply -f wp-cm.yaml 
configmap/wp-cm created
$ kubectl get cm
NAME               DATA   AGE
kube-root-ca.crt   1      6h27m
maria-cm           4      13m
wp-cm              4      119s

编写 WordPress 的 YAML 文件:

apiVersion: v1
kind: Pod
metadata:
  name: wp-pod
  labels:
    app: wordpress
    role: website

spec:
  containers:
  - image: wordpress:5
    name: wp-pod
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 80

    envFrom:
    - prefix: 'WORDPRESS_DB_'
      configMapRef:
        name: wp-cm

用下列命令创建 Pod 并查看状态:

$ kubectl apply -f wp-pod.yml
pod/wp-pod created
$ kubectl get pod -o wide
NAME        READY   STATUS    RESTARTS   AGE   IP           NODE       NOMINATED NODE   READINESS GATES
maria-pod   1/1     Running   0          15m   172.17.0.3   minikube   <none>           <none>
wp-pod      1/1     Running   0          85s   172.17.0.4   minikube   <none>           <none>

2.3 为 WordPress Pod 映射端口号,让它在集群外可见

因为 Pod 都是运行在 Kubernetes 内部的私有网段里的,外界无法直接访问,想要对外暴露服务,需要使用一个专门的 kubectl port-forward 命令,它专门负责把本机的端口映射到在目标对象的端口号,有点类似 Docker 的参数 -p,经常用于 Kubernetes 的临时调试和测试。

下面把本地的 8080 映射到 WordPress Pod 的 80kubectl 会把这个端口的所有数据都转发给集群内部的 Pod:

$ kubectl port-forward wp-pod 8080:80 &
Forwarding from [::1]:8080 -> 80

末尾使用了一个 & 符号,让端口转发工作在后台进行,这样就不会阻碍我们后续的操作。如果想关闭端口转发,需要敲命令 fg ,它会把后台的任务带回到前台,然后就可以简单地用 Ctrl + C 来停止转发了。

2.4 配置 Nginx 反向代理

目标地址是 127.0.0.1:8080,它就是我们在第三步里用 kubectl port-forward 命令创建的本地地址:

server {
  listen 80;
  default_type text/html;

  location / {
      proxy_http_version 1.1;
      proxy_set_header Host $host;
      proxy_pass http://127.0.0.1:8080;
  }
}

然后我们用 docker run -v 命令加载这个配置文件,以容器的方式启动这个 Nginx 代理:

$ docker run -d --rm \ --net=host \ -v /tmp/proxy.conf:/etc/nginx/conf.d/default.conf \ nginx:alpine

有了 Nginx 的反向代理之后,我们就可以打开浏览器,输入本机的 127.0.0.1 或者是虚拟机的 IP 地址,看到WordPress界面。

image

也可以在 Kubernetes 里使用命令 kubectl logs 查看 WordPress、MariaDB 等 Pod 的运行日志,来验证它们是否已经正确地响应了请求:

image

3. 使用 Dashboard 管理 Kubernetes

使用下面的命令启动图形管理界面:

$ minikube dashboard

它会自动打开浏览器显示当前 Kubernetes 集群的工作负载。

image

点击任意一个 Pod 的名字,就会进入管理界面,可以看到 Pod 的详细信息,而右上角有 4 个很重要的功能,分别可以查看日志、进入 Pod 内部、编辑 Pod 和删除 Pod,相当于执行 logsexeceditdelete 命令,但要比命令行要直观友好的多

image

posted @ 2022-10-09 15:57  joexu01  阅读(108)  评论(0编辑  收藏  举报