kubernetes 应用实战

kubernate 作为虚拟化 集群管理的重要工具 也是衔接 微服务 机器学习 比较好的工具,有必要花点心思应用起来

Centos7部署Kubernetes集群

https://www.cnblogs.com/zhenyuyaodidiao/p/6500830.html

kubernete 官方 暴露出 各种语言的api
https://github.com/kubernetes-client
python api
https://github.com/kubernetes-client/python

非官方的但是也非常好用的
https://github.com/kelproject/pykube

python 版的kubernete调用实例
https://blog.csdn.net/u010278923/article/details/70312808

python 调用 docker 就像 python 使用hadoop spark
一样
https://www.jianshu.com/p/db6614a4894e

还有一个python 调用 minikube 的 git
https://github.com/spisakni/minikubeBootstrap
这个项目其实给我一些启发 就是 使用 python subprocess包
check_call()函数 执行 shell 命令 ,这种 wrapper 包裹的 完全可以实现非官方的 api 调用,写出自己的一个client,另外一种 就是 通过 curl 向 执行容器 的端口 发送命令,比如使用 requests 包 httplib2 urllib urllib2
还有大名鼎鼎的 libcurl

**pycurl **

所以 以后 在python中集成这些 容器组件会越来越方便 ,完全可以嵌入到程序中,不必单单写脚本

install_requires = [
    'urllib3<1.23,>=1.21.1',
]
tests_require = [
    'requests>=2.0.0, <3.0.0',
    'nose',
    'coverage',
    'mock',
    'pyaml',
    'nosexcover'
]

除了这些 我们还可以使用 跨语言的中间件 grpc thrift ,比如 pyhive 这个包

flake8==3.4.1
mock==2.0.0
pycodestyle==2.3.1
pytest==3.2.1
pytest-cov==2.5.1
pytest-flake8==0.8.1
pytest-random==0.2
pytest-timeout==1.2.0


import threading
from collections import deque
import time
import psutil
import signal, gi
import netifaces
terminaltables
pynetstat
from gi.repository import GLib
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk as gtk

# actual dependencies: let things break if a package changes
requests>=1.0.0
sasl>=0.2.1
sqlalchemy>=0.8.7
thrift>=0.10.0
#thrift_sasl>=0.1.0

https://bitbucket.org/seewind/grpc/src/56c05ce55630e351ffc51f950a5130ba5d261e03/grpc/rpc.py?at=default&fileviewer=file-view-default

Apache Kafka running on Kubernetes and OpenShift http://strimzi.io/

https://github.com/strimzi/strimzi

python 操作进程 pid 端口

ip=os.popen("ifconfig eth0|grep 'inet addr'|awk -F ':' '{print $2}'|awk '{print $1}'")
ip=ip..read().strip()
pid=os.popen("netstat -anp|grep 8998 |awk '{print $7}'").read().split('/')[0]
os.popen('kill -9 {0}'.format(int(pid)))

#! /usr/bin/python
# -*- coding: utf-8 -*-
import os
import sys
import signal
def kill(pid):
try:
a = os.kill(pid, signal.SIGKILL)
# a = os.kill(pid, signal.9) # 与上等效
print '已杀死pid为%s的进程, 返回值是:%s' % (pid, a)
except OSError, e:
print '没有如此进程!!!'
if __name__ == '__main__':
kill(8132)
ok, Enjoy it !!!

kubernetes的组件在之前的blog都已经阐述,其中scheduler负责pod的调度,确定pod所在的宿主机节点,由于scheduler通过kubernetes的api调度pod,那么我们当然也可以自己的编写一个scheduler,完成和kubernetes对接。先看下面代码



import random
import json

from kubernetes import client,config,watch

schedule_name = "tim"
client.Configuration().host="http://10.39.0.6:8080"
v1=client.CoreV1Api()

def nodes_available():
    ready_nodes = []
    for n in v1.list_node().items:
        for status in n.status.conditions:
            if status.status == "True" and status.type == "Ready":
                ready_nodes.append(n.metadata.name)
    return ready_nodes


def scheduler(name,node,namespces="default"):
    print "+++++++++++++++++++++++++++++++++"+node
    body = client.V1Binding()
    tagert = client.V1ObjectReference()
    tagert.kind = "Node"
    tagert.apiVersion = "v1"
    tagert.name = node
    meta =client.V1ObjectMeta()
    meta.name=name
    body.target = tagert
    body.metadata = meta
    return v1.create_namespaced_binding(body,namespces)

def main():
    w = watch.Watch()
    for event in w.stream(v1.list_namespaced_pod,"default"):
        if event['object'].status.phase == "Pending" and  event['object'].spec.node_name == None:
            try:
                print event['object'].metadata.name
                res = scheduler(event['object'].metadata.name,random.choice(nodes_available()))
            except client.rest.ApiException as e:
               print json.load(e.body)["message"]

if __name__ == '__main__':
    main()

代码非常简单,先是创建一个api调用的client,然后通过stream监听pod变化,这个和k8s里面的listwatch是一回事。获取到有Pending的pod没有调度,就可以通过scheduler方法调度了,scheduler方法就是随机选择一个可用的节点,通过create_namespaced_binding方法调用api绑定pod和主机,这个和kube-scheduler里面的bind方法效果相同。
其中有两个细节需要注意,第一是我这边通过http,你写可以通过kubeconfig的方式通过https,第二,event[‘object’].spec.node_name == None这个调度没有绑定主机的pod。

IBM专门对 springboot和 kubernete 衔接做了一个项目
【pring-boot-microservices-on-kubernetes】
https://developer.ibm.com/cn/patterns/deploy-spring-boot-microservices-on-kubernetes/?cm_mmc=dwchina--homepage--social-_-os

https://github.com/IBM/spring-boot-microservices-on-kubernetes?cm_sp=IBMCodeCN--deploy-spring-boot-microservices-on-kubernetes--Get-the-Code

https://developer.ibm.com/cn/blog/2018/build-a-language-model-for-text-generation/

https://blog.csdn.net/qq_32971807/article/details/56489609

本文将从创建一个 SpringBoot 的应用开始,详细讲述如何将一个 SpringBoot 的应用部署到本地的 Kubernetes 集群上面去。

创建 SpringBoot 应用

首先,我们需要创建一个 SpringBoot 的应用,可以到 http://start.spring.io/ 创建一个,在创建的时候,我们需要选择一个 Web 的依赖,以方便部署到 Kubernetes 之后可以看到效果。

创建完成之后,可以修改一下 SpringBoot 应用的 main 函数所在的类,让它成为一个 Controller:

@SpringBootApplication
@Controller
public class WebDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(WebDemoApplication.class, args);
    }

    @RequestMapping("/hello")
    @ResponseBody
    public String hello() {
        return "Hello, Kubernetes!";
    }
}

这样,在本地启动这个 SpringBoot 的应用之后,如果我们访问 http://localhost:8080/hello 的话,就可以看到 Hello, Kubernetes! 这句话。

创建一个 Dockerfile

为了能够将这个 SpringBoot 的应用部署到 Kubernetes 里面去,我们需要创建一个 Dockerfile,将它打成一个 Docker 镜像:

FROM openjdk:8-jdk-alpine
ARG JAR_FILE
ADD ${JAR_FILE} app.jar
ENTRYPOINT [ "java", "-jar", "/app.jar"]

上面的 Dockerfile 是一个非常简单的 Dockerfile,只是将 SpringBoot 应用打包后的 uber-jar 拷贝到容器里面去,然后运行这个 jar 包。有了这个 Dockerfile 之后,我们就可以在本地把 Docker 镜像打包出来了:

docker build --build-arg JAR_FILE=./target/web-demo-0.0.1-SNAPSHOT.jar . -t springboot-demo

然后需要注意的是,这样打出来的镜像是在本地的,没有办法被 minikube 找到,所以,要么将这个镜像放到一个中央的镜像仓库上,要么我们使用 minikube 的 docker daemon 来打镜像,这样 minikube 就可以找到这个镜像。

所以,你首先需要在本地将 minikube 安装上去,具体可以看官方的安装教程。安装完成之后,先运行:

minikube start

来将 minikube 启动起来,然后可以运行

eval $(minikube docker-env)

将 docker daemon 切换成 minikube 的。最后,我们再用上面的 docker build 来进行打包,minikube 就可以看到了。

将应用部署到 minikube 中去

Docker 镜像都准备好了,现在我们可以将应用部署到 minikube 中去了,首先我们需要创建一个 deployment 对象,这个可以用 yml 文件来描述:

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: springboot-demo-deployment
  labels:
    app: springboot-demo
spec:
  replicas: 3
  selector:
    matchLabels:
      app: springboot-demo
  template:
    metadata:
      labels:
        app: springboot-demo
    spec:  
      containers:
        - name: springboot-demo
          image: springboot-demo
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 8080

上面的 yaml 文件没有什么特别的地方,除了 imagePullPolicy 需要指定成 IfNotPresent,这样 minikube 才会从本地去找镜像。

有了上面的 yaml 文件之后,我们就可以运行 kubectl apply -f springboot-demo.yml 来让 minikube 将我们的 SpringBoot 的应用的集群给创建出来。

访问 minikube 中的 SpringBoot 集群

现在我们已经将 SpringBoot 应用部署到了 minikube 中去,那么怎么访问这个集群呢,首先我们需要将端口暴露出来:

kubectl expose deployment springboot-demo-deployment --type=NodePort

然后运行:

minikube service springboot-demo-deployment --url

得到访问的 URL。再在得到的 URL 后面加上 /hello,就可以看到 Hello, Kubernetes! 了。

或者,我们可以直接运行 curl $(minikube service springboot-demo-deployment --url)/hello 来访问。

以上就是如何将一个 SpringBoot 的应用部署到 Kubernetes 里面去的全过程。

你可能感兴趣的:(kubernetes 应用实战)