如何使用Kubernetes设置MySQL服务

时间:2020-03-05 15:31:15  来源:igfitidea点击:

在本文中,我们将遵循我们的一篇关于Kubernetes(K8S)生态系统的文章。
在当前文章中,我们将主要使用K8s查看持久性部件,如何在K8S群集中设置和获取MySQL并运行。
就像我的预览Kubernetes Secrets文章一样,我将使用Minikube演示我的所有步骤。

我们将学到什么

  • 创造Pods
  • 通过服务曝光Pods
  • 连接到基于MySQL图像的POD
  • 将Pods在一起

这篇文章的结构安排如下

  • 介绍
  • 创建MySQL Pod并作为服务曝光
  • 创建nodejs api以点击mysql,pod和服务
  • 使用NodeJS API从MySQL数据库获取数据
  • 结论

注意:我将使用以下别名在我的终端中,Kubernetes-MySQL将是我的工作文件夹:

alias ctl='kubectl'
alias ccre='ctl create -f '
alias cdels='ctl delete service '
alias cdelp='ctl delete pod '
alias clog='ctl logs '
alias cdess='ctl describe service '
alias cdesp='ctl describe pod '
alias cgets='ctl get service'
alias cgetp='ctl get pods'
alias cgete='ctl get endpoints'

介绍

我们都知道数据持久性的重要意义,几乎所有的应用程序都依赖于某种数据库管理系统(AKA。
DBMS)。
因此,在K8S中设置这样的DBMS对于Devops团队非常重要,因为我在当前文章中提到的,我们将在从容器中查看如何从容器中获取MySQL并以K8S运行,并介绍为服务,并且重要的是我会去甚至进一步说明我如何使用我的数据库,主要通过在单独的POD中运行的简单API消耗它。
所以,让我们开始!

我应该提到当前的教程要求我们应该对K8S的概念有了基本的理解,主要是POD和服务。

创建mysql pod.

首先,我将从官方最新的MySQL图像创建一个基于MySQL的POD,请注意,我将MySQL_Root_Password作为环境变量传递。

>>  kubernetes-mysql cat mysql-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: "k8s-mysql"
labels:
name: "lbl-k8s-mysql"
spec:
containers:

image: mysql:latest
name:  "mysql"
env:

name: "MYSQL_ROOT_PASSWORD"
value: "test"
ports:

containerPort: 3306
name:  "mysql"
volumeMounts:

name: "k8s-mysql-storage"
mountPath: "/var/lib/mysql"
volumes:
- name: "k8s-mysql-storage"
emptyDir: {}
>>  kubernetes-mysql ccre -f mysql-pod.yaml
pod "k8s-mysql" created

检查我们的POD是否正在运行:

>>  kubernetes-mysql cgetp
NAME        READY     STATUS    RESTARTS   AGE
k8s-mysql   1/1       Running   0          5s

检查我们的POD日志:

>>  kubernetes-mysql clog k8s-mysql
Initializing database
2015-12-10T11:23:36.414301Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please...
MySQL init process done. Ready for start up.
…
2015-12-10T11:23:45.245972Z 0 [Note] mysqld: ready for connections.
Version: '5.7.16'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server (GPL)

现在我们可以连接到我们的POD来连接到我们的MySQL Server Run退出两次退出MySQL控制台和Bash:

>>  msg-api ctl exec -it k8s-mysql bash
root@k8s-mysql:/# echo $MYSQL_ROOT_PASSWORD
test
root@k8s-mysql:/# mysql --user=root --password=$MYSQL_ROOT_PASSWORD
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.16 MySQL Community Server (GPL)
 
Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
 
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names Jan be trademarks of their respective
owners.
 
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
 
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.00 sec)
 
mysql>exit
Bye

K8S附带的服务概念将POD暴露给其他Pod或者外部系统,以便我们的POD将可以到达,更精确,具有服务规范,我们不仅可以公开一个Pods,甚至可以定义一组策略/规则来访问我们的策略/规则Pods。
因此,让我们为我们的K8S-MySQL POD创建一个服务:

>>  kubernetes-mysql ccre mysql-service.yaml
service "k8s-srv-mysql" created

创建一个nodejs api来点击mysql

为了能够从其他Pods连接到MySQL,我们需要使用我们的POD的IP地址,可以使用:

>>  msg-api ctl get -o template pod k8s-mysql --template={{.status.podIP}}
172.17.0.4

好吧,现在我要创建一个示例NodeJS应用程序,要在数据库消息表中存储一组消息,该应用程序将有两个端点:

  • '/ping':检查服务器健康
  • '/msg-api /全':获取所有存储的消息

保持简单的事情。


该表将只有一列称为文本。

第一件事首先,节点应用程序:

//api。
JS - >端点走到这里

var express = require('express')
var mysql = require('mysql')
var Router = express.Router();
var ConnPool = mysql.createPool({
host: '172.17.0.4',
user: 'root',
password: 'test',
database: 'k8smysqldb'
})
//create database and MESSAGE table if not exist
ConnPool.query('CREATE DATABASE IF NOT EXISTS k8smysqldb', function (err) {
if (err) throw Error('\n\t  error creating database  ' + err)
console.log('\n\t ==== database k8smysqldb created !! ====')
ConnPool.query('USE k8smysqldb', function (err) {
if (err) throw Error('\n\t  error using database  ' + err);
console.log('\n\t ==== database k8smysqldb switched !! ====')
ConnPool.query('CREATE TABLE IF NOT EXISTS messages('
+ 'id INT NOT NULL AUTO_INCREMENT,'
+ 'PRIMARY KEY(id),'
+ 'text VARCHAR(100)'
+ ')', function (err) {
if (err) throw Error('\n\t  error creating table  ' + err);
})
})
})
/**
* /all
*/
Router.get('/all', function (req, res) {
ConnPool.getConnection(function (errConn, conn) {
if (errConn) throw Error('error get connection : ' + errConn)
conn.query('SELECT * FROM messages', function (errSelect, rows) {
if (errSelect) throw Error('error selecting messages : ' + errSelect)
res.writeHead(200, {
'Content-Type': 'application/json'
});
var result = {
success: true,
rows: rows.length,
}
res.write(JSON.stringify(rows));
res.end();
})
})
})
module.exports = Router

//服务器。
JS - > Fire ExpressJS服务器

var express = require('express')
var msgApi = require('./api')
var app = express()
app.use('/msg-api', msgApi)
app.get('/ping', function (req, res) {
res.write("hello there! I m up and running!");
res.end();
})
app.listen(8080, function () {
console.log('\n\t ==== Message API listening on 8080! ====')
})

//dockerfile - >我们的应用程序捆绑Docker图像

FROM node:latest
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY package.json /usr/src/app/package.json
RUN npm i
COPY . /usr/src/app/
EXPOSE 8080
CMD [ "node", "server.js" ]

现在我们可以从Dockerfile建立我们的Docker图像

>>  msg-api docker build -t theitroad/msg-api:v0.0.3 . --no-cache=true
Sending build context to Docker daemon 9.728 kB
Step 1 : FROM node:latest
…

并将内置图像推向Docker Hub

>>  msg-api docker push theitroad/msg-api:v0.0.3
The push refers to a repository [docker.io/theitroad/msg-api]
c4477a160652: Pushed
32c1bac97782: Pushed
3d629e3d2e5a: Pushed
…
v1: digest: sha256:dba64e7ff64561f4af866fbbb657555cad7621688c7f312975943f5baf89efa2 size: 2628

现在我们可以创建我们的NodeJS应用程序的POD,下面的Spec文件:

>>  msg-api cat msg-api-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: "k8s-msg-api"
labels:
name: "lbl-msg-api"
spec:
containers:

image: theitroad/msg-api:v0.0.1
name:  "msg-api"
ports:

containerPort: 8080
name:  "msg-api"
>>  msg-api ccre msg-api-pod.yaml
pod "k8s-msg-api" created

确保通过检查状态来运行POD:

>>  kubernetes-mysql cgetp
NAME          READY     STATUS    RESTARTS   AGE
k8s-msg-api   1/1       Running   0          22s
k8s-mysql     1/1       Running   0          5h

在此级别,我们需要公开创建的POD,以便可以从外部访问它。
这次我只使用命令行而不是SPEC文件

>>  msg-api kubectl expose pod k8s-msg-api --port=8080 --name=k8s-srv-msg-api --type=NodePort
service "k8s-srv-msg-api" exposed

使用NodeJS API从MySQL数据库获取数据

在这个级别,我需要指出一些重要的员工,为了理解所有的碎片,让我们首先概述我们所做的事情,到目前为止,我们创建了一个MySQL Pod,我们已经通过服务暴露了它可以访问其他Pods,其次,我们创建了一个示例NodeJS应用程序,我们称之为消息传递API,以便我们可以使用它来击中MySQL Pod;同样,为了能够访问消息API,我们需要通过服务公开它,我希望一切都很清楚,直到这里!

现在问题是如何从我们的集群外部拨打我们的消息传递API,主要是Minikube?
为此,我们需要我们节点的IP地址,因为我正在使用只创建一个节点所以,IP地址已解决,是Minikube IP地址本身,刚刚运行:

>>  msg-api minikube ip
192.168.99.100

港口怎么样?
好问题!让我们描述我们的消息传递API服务以检查:

>>  msg-api cdess k8s-srv-msg-api
Name:           k8s-srv-msg-api
Namespace:      default
Labels:         name=lbl-msg-api
Selector:       name=lbl-msg-api
Type:           NodePort
IP:         10.0.0.170
Port:           <unset> 8080/TCP
NodePort:       <unset> 30887/TCP
Endpoints:      172.17.0.5:8080
Session Affinity:   None
No events.

所以我们有端口是我们消息传递API服务的端口。
NodePort是公开服务可用的端口(可访问)i。
e。
,该服务可在NodeIP上提供:NodePort

让我们试试吧:

>>  msg-api curl 192.168.99.100:30887/ping
hello there! I m up and running!%
>>  msg-api curl 192.168.99.100:30887/msg-api/all
[]%

非常好,到目前为止,我们能够使用我们的MySQL数据库,让我们使用终端将一些数据插入我们的数据库。

>>  kubernetes-mysql kubectl exec -it k8s-mysql bash
root@k8s-mysql:/# mysql --user=root --password=$MYSQL_ROOT_PASSWORD
mysql: [Warning] Using a password on the command line interface can be insecure.
…
mysql> use k8smysqldb;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
 
Database changed
mysql> show tables;
+----------------------+
| Tables_in_k8smysqldb |
+----------------------+
| messages             |
+----------------------+
1 row in set (0.01 sec)
 
mysql> insert into messages(text) values ('this is the first msg!');
Query OK, 1 row affected (0.01 sec)
mysql> insert into messages(text) values ('this is the second msg!');
Query OK, 1 row affected (0.01 sec)

让我们通过使用CURL通过我们的NodeJS API获取此数据:

>>  msg-api curl 192.168.99.100:30887/msg-api/all
[{"id":1,"text":"this is the first msg!"},{"id":2,"text":"this is the second msg!"}]%