6 29
Golang版protobuf的安装与使用

Protobuf 介绍

序列化库在网络传输,RPC,数据库访问等环境中经常用到,它的性能的好坏直接影响着整个产品的性能, 所以我们有必要对一些优秀的序列化库进一步的学习与掌握.

protobuf是Google开发的一种数据描述语言语言,能够将结构化的数据序列化,可用于数据存储,通信协议等方面,官方版本支持 Go, C++, Java, Python,社区版本支持更多语言.

相对于JSON和XML具有以下优点:

  • 简洁

  • 体积小:消息大小只需要XML的1/10 ~ 13

  • 速度快:解析速度比XML快20 ~ 100倍

  • 使用Protobuf的编译器,可以生成更容易在编程中使用的数据访问代码

  • 更好的兼容性,Protobuf设计的一个原则就是要能够很好的支持向下或向上兼容

本文主要以Go语言的方式来具体讲述如何使用Pb进行数据的定义与传输

Protobuf 使用

安装

1.从 https://github.com/google/protobuf/releases 获取 Protobuf 编译器 protoc

wget https://github.com/google/protobuf/releases/download/v2.6.1/protobuf-2.6.1.tar.gztar zxvf protobuf-2.6.1.tar.gz
cd protobuf-2.6.1./configure
make
make install
protoc   -h

2.获取 goprotobuf 提供的 Protobuf 插件 protoc-gen-go(被放置于 $GOPATH/bin 下,$GOPATH/bin 应该被加入 PATH 环境变量,以便 protoc 能够找到 protoc-gen-go)

此插件被 protoc 使用,用于编译 .proto 文件为 Golang 源文件,通过此源文件可以使用定义在 .proto 文件中的消息。

go get github.com/golang/protobuf/protoc-gen-go
 
cd github.com/golang/protobuf/protoc-gen-go
 
go build
 
go install
 
vi /etc/profile 将$GOPATH/bin 加入环境变量
 
source profile

3.获取 goprotobuf 提供的支持库,包含诸如编码(marshaling)、解码(unmarshaling)等功能

go get github.com/golang/protobuf/proto
cd github.com/golang/protobuf/proto
go build
go install

使用 go protobuf

接着, 我们进行数据格式的定义, 写一个简单的例子: 我们在 $GOPATH下新建一个测试项目 pblearn/packet 在 $GOPATH/pblearn/packet 下, 创建一个名为 packet.proto 的文件, 然后编写如下的内容

package packet;
message Header{
    required string messageId = 1;
    required string topic = 2; //topic类型
}
//byte类消息
message BytesMessage{
    required Header  header= 1;
    required  bytes body = 2;    
}
//string类型的message
message StringMessage{
    required Header header = 1;
    required string body = 2;
}

然后通过 –go_out 来使用 goprotobuf 提供的 Protobuf 插件 protoc-gen-go。这时候我们会生成一个名为 test.pb.go 的源文件, 参考如下

protoc --go_out=. *.proto

命令执行后, pblearn/packet 下会生成一个go的文件 packet.pb.go, 这个就是我们消息操作对象

最后,我们可以编写测试例子, 在 在 $GOPATH/pblearn/ 下,我们编写 main.go

package main
 
import (
    // 辅助库
    "github.com/golang/protobuf/proto"
    // test.pb.go 的路径
    "pblearn/packet"
)
 
func main() {
 
    bodyData := "guangzhou/fangcun/vip/company"
 
    p := &packet.StringMessage{
        Body: proto.String(bodyData),
        Header: &packet.Header{
            MessageId: proto.String("20-05"),
            Topic:     proto.String("golang"),
        },
    }
 
    pData, err := proto.Marshal(p)
 
    if err != nil {
        println(err.Error())
    }
    println(string(pData))
 
    p2 := &packet.StringMessage{}
    proto.Unmarshal(pData, p2)
 
    println(p2.GetHeader().GetTopic())
}

通过运行例子 go run main.go 可以发现, 我们的数据格式可以正常的序列化和反序列化了.

这样,我们日后可以根据自己的业务需要, 进行高效的数据传输

4 21
RingBuffer的应用

最近团队在某些go开发的项目中, 都不同程度地出现内存暴涨, 计算量特别大的时候,内存一直不下降,且gc很频繁,但按理说GC后内存清理后,依旧不释放就有问题了, 经过pprof分析出的原因是: 写的缓冲层实现,不满足我们数据计算量非常大的场景, 毕竟并发的世界充满意想不到的事情

当然某些中间计算的结果,我们可以加入redis作为缓冲来存放, 但作为一级缓存, 我认为也没必要去加重代码的对第三方服务的依赖, 如果用原生map的时候,效率和手动去lock又会带来上面的回收频繁问题, 所以就想有没有好的算法或者好的手段来简单快速解决问题

然后看了很多技术文章, 跟我们目前情况差不多的团队,他们都用了很多基于RingBuffer的思路来解决问题.

概念

Ring Buffer在维基百科的解析是:

圆形缓冲区(circular buffer),也称作圆形队列(circular queue),循环缓冲区(cyclic buffer),环形缓冲区(ring buffer),是一种用于表示一个固定尺寸、头尾相连的缓冲区的数据结构,适合缓存数据流。

简单概况, 它的基本特点:

  • FIFO
  • 读指针
  • 写指针
  • 固定尺寸、头尾相连的结构

rb1

基本结构示意

rb2

存储操作示意

RingBUffer之所以ringbuffer采用这种数据结构,是因为它在可靠消息传递方面有很好的性能:

首先,因为它是数组,所以插入要比链表快

其次,你可以为数组预先分配内存,使得数组对象一直存在, 这就意味着不需要花大量的时间用于垃圾回收。此外,不像链表那样,需要为每一个添加到其上面的对象创造节点对象—对应的,当删除节点时,需要执行相应的内存清理操作。

实现

了解RingBuffer的原理后,我们可以自己来写一个简单的RingBuffer的Golang实现

我们先定义最基本的RingBuffer结构体

type RingBuffer struct {
    data         []byte
    size         int64
    writeCursor  int64
    writtenCount int64
}

提供初始化的方法: 由于rb的特定是大小需要预先固定,所以我们在初始化的时候,把尺寸都给预分配好

//size 必须大于0
func NewBuffer(size int64) (*RingBuffer, error) {
    if size <= 0 {
        return nil, errors.New("Size must be positive")
    }

    b := &RingBuffer{
        size: size,
        data: make([]byte, size)}

    return b, nil
}

RingBuffer最重要的功能就是要写数据, 由于ringbuffer的形态特殊, 我们必须写数据的时候,要移动我们的 "写指针", 再根据fifo的特点来进行数据填充

//写入buf到ringbuffer内部
//如果需要会覆盖旧数据(fifo)
func (b *RingBuffer) Write(buf []byte) (int, error) {

    n := len(buf)
    b.writtenCount += int64(n)

    //如果buf的大小超过容量限制,根据fifo原则
    //我们只关注最近最新的部分数据
    if int64(n) > b.size {
        buf = buf[int64(n)-b.size:]
    }

    remain := b.size - b.writeCursor
    copy(b.data[b.writeCursor:], buf)
    if int64(len(buf)) > remain {
        copy(b.data, buf[remain:])
    }

    b.writeCursor = ((b.writeCursor + int64(len(buf))) % b.size)
    return n, nil
}

关于读的方法实现, 这里就简单实现一个输出所有数据的方法, 当然我们也可以根据具体位置读取的方法实现, 这个大家可以根据自己的需要去扩展.

//读出buffer所有数据
func (b *RingBuffer) ReadAll() []byte {

    switch {
    case b.writtenCount >= b.size && b.writeCursor == 0:
        return b.data
    case b.writtenCount > b.size:
        out := make([]byte, b.size)
        copy(out, b.data[b.writeCursor:])
        copy(out[b.size-b.writeCursor:], b.data[:b.writeCursor])
        return out
    default:
        return b.data[:b.writeCursor]
    }

    return nil
}

总结

  1. ring buffer在网络编程各种语言很多场景下都有不同的应用和用法,一次性开块大内存是生产环境下的常用做法

  2. 使用 ring buffer 的优势是内存使用率很高,不会造成内存碎片,几乎没有浪费(比如传统动态内存分配需要的 cookie),业务处理的同一时间,访问的内存数据段集中。可以更好的适应不同系统,取得较高的性能。

  3. 内存的物理布局简单单一,不太容易发生内存越界、悬空指针等 bug,出了问题也容易在内存级别分析调试。做出来的系统容易保持健壮。

参考资料

云风的blog : RingBuffer的应用

3 29
深入学习Kubernetes(四):Etcd启用https服务

kubernetes依靠etcd来存储docker集群的配置信息,进一步说etcd作为一个受到ZooKeeper与doozer启发而催生的项目,除了拥有与之类似的功能外,更专注于以下四点:

  • 简单:基于HTTP+JSON的API让你用curl就可以轻松使用
  • 安全:可选SSL客户认证机制
  • 快速:每个实例每秒支持一千次写操作
  • 可信:使用Raft算法充分实现了分布式

由于在分布式环境中,安全性已经成为互联网技术团队非常看重的部分,所以本文主要介绍如何搭建一个支持证书的https Etcd集群。

生成证书

下载 cfssl

$ curl -s -L -o /usr/bin/cfssl https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
$ curl -s -L -o /usr/bin/cfssljson https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64

$ chmod +x /usr/bin/{cfssl,cfssljson}

生成key

先编写相关配置

$ vim ca-config.json

{
  "signing": {
    "default": {
      "expiry": "100000h"
    },
    "profiles": {
      "server": {
        "usages": ["signing", "key encipherment", "server auth", "client auth"],
        "expiry": "100000h"
      },
      "client": {
        "usages": ["signing", "key encipherment", "server auth", "client auth"],
        "expiry": "8760h"
      }
    }
  }
}
$ vim ca-csr.json

{
  "CN": "Etcd",
  "key": {
    "algo": "rsa",
    "size": 4096
  },
  "names": [
    {
      "C": "CN",
      "L": "Guangzhou",
      "O": "Gopher",
      "OU": "PaaS",
      "ST": "Guangzhou"
    }
  ]
}

编写完上面的配置文件后,我们可以开始使用cfssl来生成ca证书

$ cfssl gencert -initca ca-csr.json | cfssljson -bare ca

执行后,会生成三个文件:

  • ca-key.pem - private key for the CA

  • ca.pem - certificate for the CA

  • ca.csr - certificate signing request for the CA

生成服务端证书

编写配置文件

$ vim server-csr.json

{
  "CN": "etcd-server",
  "hosts": [
    "localhost",
    "0.0.0.0",
    "127.0.0.1",
    "192.168.139.1",
    "192.168.139.134"
  ],
  "key": {
    "algo": "rsa",
    "size": 4096
  },
  "names": [
    {
      "C": "CN",
      "L": "Guangzhou",
      "O": "Gopher",
      "OU": "PaaS",
      "ST": "Guangzhou"
    }
  ]
}

导出证书

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=server server-csr.json | cfssljson -bare server

注意:hosts需要包括允许访问ETCD Cluster的IP或者FQDN

生成三个文件:server.pem, server-key.pem和server.csr

产生客户端证书

$ vim client-csr.json

{
  "CN": "etcd-client",
  "hosts": [
    ""
  ],
  "key": {
    "algo": "rsa",
    "size": 4096
  },
  "names": [
    {
      "C": "CN",
      "L": "Guangzhou",
      "ST": "Guangzhou",
      "O": "Gopher",
      "OU": "PaaS"
    }
  ]
}

执行命令生成证书

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=client client-csr.json | cfssljson -bare client

生成三个文件:client.pem, client-key.pem和client.csr

配置etcd 集群

下面会以一个五个节点的集群为例

节点一启动脚本

/data/services/etcd-v3.1.4-linux-amd64/etcd --name cn0 --initial-advertise-peer-urls https://127.0.0.1:1080 --listen-peer-urls https://127.0.0.1:1080 --listen-client-urls https://192.168.139.134:1079,https://127.0.0.1:1079 --advertise-client-urls https://192.168.139.134:1079,https://127.0.0.1:1079 --initial-cluster-token etcd-cluster-token --initial-cluster cn0=https://127.0.0.1:1080,cn1=https://127.0.0.1:1180,cn2=https://127.0.0.1:1280,cn3=https://127.0.0.1:1380,cn4=https://127.0.0.1:1480 --initial-cluster-state new --cert-file=/home/lihaoquan/etcd/https/keygen/server.pem --key-file=/home/lihaoquan/etcd/https/keygen/server-key.pem --peer-cert-file=/home/lihaoquan/etcd/https/keygen/server.pem --peer-key-file=/home/lihaoquan/etcd/https/keygen/server-key.pem --trusted-ca-file=/home/lihaoquan/etcd/https/keygen/ca.pem --peer-trusted-ca-file=/home/lihaoquan/etcd/https/keygen/ca.pem --data-dir=./nodes/cn0 --peer-client-cert-auth=true --client-cert-auth=true

节点二启动脚本

/data/services/etcd-v3.1.4-linux-amd64/etcd \
  --name cn1 \
  --initial-advertise-peer-urls https://127.0.0.1:1180 \
  --listen-peer-urls https://127.0.0.1:1180 \
  --listen-client-urls https://192.168.139.134:1179,https://127.0.0.1:1179 \
  --advertise-client-urls https://192.168.139.134:1179,https://127.0.0.1:1179 \
  --initial-cluster-token etcd-cluster-token \
  --initial-cluster cn0=https://127.0.0.1:1080,cn1=https://127.0.0.1:1180,cn2=https://127.0.0.1:1280,cn3=https://127.0.0.1:1380,cn4=https://127.0.0.1:1480 \
  --initial-cluster-state new \
  --cert-file=/home/lihaoquan/etcd/https/keygen/server.pem  \
  --key-file=/home/lihaoquan/etcd/https/keygen/server-key.pem  \
  --peer-cert-file=/home/lihaoquan/etcd/https/keygen/server.pem  \
  --peer-key-file=/home/lihaoquan/etcd/https/keygen/server-key.pem \ 
  --trusted-ca-file=/home/lihaoquan/etcd/https/keygen/ca.pem  \
  --peer-trusted-ca-file=/home/lihaoquan/etcd/https/keygen/ca.pem  \
  --data-dir=./nodes/cn1  \
  --peer-client-cert-auth=true  \
  --client-cert-auth=true 

节点三启动脚本

/data/services/etcd-v3.1.4-linux-amd64/etcd \
  --name cn2 \
  --initial-advertise-peer-urls https://127.0.0.1:1280 \
  --listen-peer-urls https://127.0.0.1:1280 \
  --listen-client-urls https://192.168.139.134:1279,https://127.0.0.1:1279 \
  --advertise-client-urls https://192.168.139.134:1279,https://127.0.0.1:1279 \
  --initial-cluster-token etcd-cluster-token \
  --initial-cluster cn0=https://127.0.0.1:1080,cn1=https://127.0.0.1:1180,cn2=https://127.0.0.1:1280,cn3=https://127.0.0.1:1380,cn4=https://127.0.0.1:1480 \
  --initial-cluster-state new \
  --cert-file=/home/lihaoquan/etcd/https/keygen/server.pem  \
  --key-file=/home/lihaoquan/etcd/https/keygen/server-key.pem  \
  --peer-cert-file=/home/lihaoquan/etcd/https/keygen/server.pem  \
  --peer-key-file=/home/lihaoquan/etcd/https/keygen/server-key.pem \ 
  --trusted-ca-file=/home/lihaoquan/etcd/https/keygen/ca.pem \ 
  --peer-trusted-ca-file=/home/lihaoquan/etcd/https/keygen/ca.pem  \
  --data-dir=./nodes/cn2 \
  --peer-client-cert-auth=true  \
  --client-cert-auth=true 

节点四启动脚本

/data/services/etcd-v3.1.4-linux-amd64/etcd \
  --name cn3 \
  --initial-advertise-peer-urls https://127.0.0.1:1380 \
  --listen-peer-urls https://127.0.0.1:1380 \
  --listen-client-urls https://192.168.139.134:1379,https://127.0.0.1:1379 \
  --advertise-client-urls https://192.168.139.134:1379,https://127.0.0.1:1379 \
  --initial-cluster-token etcd-cluster-token \
  --initial-cluster cn0=https://127.0.0.1:1080,cn1=https://127.0.0.1:1180,cn2=https://127.0.0.1:1280,cn3=https://127.0.0.1:1380,cn4=https://127.0.0.1:1480 \
  --initial-cluster-state new \
  --cert-file=/home/lihaoquan/etcd/https/keygen/server.pem \ 
  --key-file=/home/lihaoquan/etcd/https/keygen/server-key.pem \ 
  --peer-cert-file=/home/lihaoquan/etcd/https/keygen/server.pem \ 
  --peer-key-file=/home/lihaoquan/etcd/https/keygen/server-key.pem \ 
  --trusted-ca-file=/home/lihaoquan/etcd/https/keygen/ca.pem  \
  --peer-trusted-ca-file=/home/lihaoquan/etcd/https/keygen/ca.pem  \
  --data-dir=./nodes/cn3 \
  --peer-client-cert-auth=true  \
  --client-cert-auth=true 

节点五启动脚本

/data/services/etcd-v3.1.4-linux-amd64/etcd \
  --name cn4 \
  --initial-advertise-peer-urls https://127.0.0.1:1480 \
  --listen-peer-urls https://127.0.0.1:1480 \
  --listen-client-urls https://192.168.139.134:1479,https://127.0.0.1:1479 \
  --advertise-client-urls https://192.168.139.134:1479,https://127.0.0.1:1479 \
  --initial-cluster-token etcd-cluster-token \
  --initial-cluster cn0=https://127.0.0.1:1080,cn1=https://127.0.0.1:1180,cn2=https://127.0.0.1:1280,cn3=https://127.0.0.1:1380,cn4=https://127.0.0.1:1480 \
  --initial-cluster-state new \
  --cert-file=/home/lihaoquan/etcd/https/keygen/server.pem  \
  --key-file=/home/lihaoquan/etcd/https/keygen/server-key.pem  \
  --peer-cert-file=/home/lihaoquan/etcd/https/keygen/server.pem  \
  --peer-key-file=/home/lihaoquan/etcd/https/keygen/server-key.pem  \
  --trusted-ca-file=/home/lihaoquan/etcd/https/keygen/ca.pem  \
  --peer-trusted-ca-file=/home/lihaoquan/etcd/https/keygen/ca.pem \ 
  --data-dir=./nodes/cn4 \
  --peer-client-cert-auth=true  \
  --client-cert-auth=true 

验证集群的健康情况

/data/services/etcd-v3.1.4-linux-amd64/etcdctl --cert-file=/home/lihaoquan/etcd/https/keygen/client.pem  --key-file=/home/lihaoquan/etcd/https/keygen/client-key.pem --ca-file=/home/lihaoquan/etcd/https/keygen/ca.pem --endpoints=https://0.0.0.0:1179,https://0.0.0.0:1279,https://0.0.0.0:1379,https://0.0.0.0:1479 cluster-health
3 12
深入学习Kubernetes(三):手工安装Kubernetes

由于Kubernetes还在不断的演进,不同版本的k8s,在某些命令会有出入,不过原理变化不大,本文安装的Kubernetes版本为 V1.3.0。

Kubernetes安装包下载地址

解压后,我们需要使用到的服务程序文件位于: kubernetes/server/kubernetes/server/bin 下

下面我们把安装步骤分为Master和Minion两部分,最后在统一进行验证。

环境准备

为了达到简单的集群安装,我们先准备了两台服务器,如果要扩展minion,安装方式都是一样的,所以扩展比较方便。

  • master server : 192.168.139.145

  • minion server : 192.168.139.146

我们的安装过程中,均使用centos的Systemd系统服务,进行Kubernetes服务的配置。

Centos7 默认使用firewall为防火墙,我们先关闭防火墙的设定

$ systemctl disable firewalld.service

$ systemctl stop firewalld.service

Master节点上安装

Master上需要具备的K8s程序组件是

  • etcd
  • kube-apiserver
  • kube-controller-manager
  • kube-scheduler

安装etcd

先下载最新的etcd并解压:

$ wget https://github.com/coreos/etcd/releases/download/v3.1.3/etcd-v3.1.3-darwin-amd64.zip

创建相关的工作目录:

$ mkdir /var/lib/etcd/

$ mkdir /etc/etcd && touch etcd.conf

创建etcd的服务文件:

$ vim /usr/lib/systemd/system/etcd.service

相关内容如下:

[Unit]
Description=Etcd Server
After=network.target

[Service]
Type=simple
WorkingDirectory=/var/lib/etcd/
EnvironmentFile=/etc/etcd/etcd.conf
ExecStart=/usr/bin/etcd

[Install]
WantedBy=multi-user.target

其中 /etc/etcd/etcd.conf 为etcd的配置文件,内容可以为空,我们介绍默认的配置

接下来,我们启动etcd的服务

$ systemctl daemon-reload

$ systemctl enable etcd.service

$ systemctl status etcd //检查etcd的运行状态

检查健康:

$ etcdctl cluster-health

member 8e9e05c52164694d is healthy: got healthy result from http://localhost:2379
cluster is healthy

安装 kube-apiserver

我们先创建服务的日志目录

$ mkdir -p /var/log/kubernetes

进入 kubernetes/server/kubernetes/server/bin,把相关程序文件复制到 /usr/bin下

$ cp kube-apiserver /usr/bin/

编辑systemd服务文件

$ vim /usr/lib/systemd/system/kube-apiserver.service

内容如下:

[Unit]
Description=Kubernetes API Server
After=etcd.service
Wants=etcd.service

[Service]
EnvironmentFile=/etc/kubernetes/apiserver
ExecStart=/usr/bin/kube-apiserver $KUBE_API_ARGS
Restart=on-failure
Type=notify
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

创建 apiserver 配置文件

mkdir -p /etc/kubernetes && touch /etc/kubernetes/apiserver

配置文件 /etc/kubernetes/apiserver 的内容包括了 kube-apiserver的全部启动参数,只有的配置参数在变量KUBE_API_ARGS中指定,相关内容如下:

$ vim /etc/kubernetes/apiserver

KUBE_API_ARGS="--etcd_servers=http://127.0.0.1:2379
--insecure-bind-address=0.0.0.0 --insecure-port=8080
--service-cluster-ip-range=169.169.0.0/16 --service-node-port-range=1-65535
--admission-control=NamespaceLifecycle,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota
--logtostderr=false --log-dir=/var/log/kubernetes --v=2"

相关的参数说明可以参考 https://kubernetes.io/docs/admin/kube-apiserver/

安装 kube-controller-manager

kube-controller-manager 服务依赖于 kube-apiserver服务。

跟apiserver一样,我们需要把程序文件复制到 /usr/bin/

cp kube-controller-manager /usr/bin/

编辑systemd的服务文件

$ vim /usr/lib/systemd/system/kube-controller-manager.service

[Unit]
Description=Kubernetes Controller Manager
After=kube-apiserver.service
Requires=kube-apiserver.service

[Service]
EnvironmentFile=/etc/kubernetes/controller-manager
ExecStart=/usr/bin/kube-controller-manager $KUBE_CONTROLLER_MANAGER_ARGS
Restart=on-failure
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

创建并编辑配置文件

$ vim /etc/kubernetes/controller-manager

KUBE_CONTROLLER_MANAGER_ARGS="--master=http://192.168.139.145:8080 --logtostderr=false --log-dir=/var/log/kubernetes --v=2"

配置参数可以参考 https://kubernetes.io/docs/admin/kube-controller-manager/

安装 kube-scheduler

跟apiserver一样,我们需要把程序文件复制到 /usr/bin/

cd kubernetes/server/kubernetes/server/bin

cp kube-scheduler /usr/bin/

编辑systemd的服务文件

$ vim /usr/lib/systemd/system/kube-scheduler.service

[Unit]
Description=Kubernetes Scheduler
After=kube-apiserver.service
Requires=kube-apiserver.service

[Service]
EnvironmentFile=/etc/kubernetes/scheduler
ExecStart=/usr/bin/kube-scheduler $KUBE_SCHEDULER_ARGS
Restart=on-failure
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

编辑配置文件,主要配置 KUBE_SCHEDULER_ARGS 环境变量

$ vim  /etc/kubernetes/scheduler

KUBE_SCHEDULER_ARGS="--master=http://192.168.139.145:8080 --logtostderr=false --log-dir=/var/log/kubernetes --v=2"

小结

完成上面的Master节点安装配置后,我们执行systemctl start 命令这3个服务。同时使用 systemctl enable 命令将服务加入开机启动列表中

$ systemctl daemon-reload

$ systemctl enable kube-apiserver.service
$ systemctl start kube-apiserver.service

$ systemctl enable kube-controller-manager.service
$ systemctl start kube-controller-manager.service

$ systemctl enable kube-scheduler.service
$ systemctl start kube-scheduler.service

通过 syetem status 命令来验证服务的启动状态,”running”表示启动成功。到此,Master上所需的服务就全部启动完成。

Minion节点安装

Minion上需要具备的K8s程序组件是

  • docker engine
  • kubelet
  • kube-proxy

关闭防火墙服务

$ systemctl disable firewalld.service

$ systemctl stop firewalld.service

安装Docker

$ systemctl start docker

切换docker镜像源:

可以参考 https://www.daocloud.io/mirror#accelerator-doc

$ curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://dbe35452.m.daocloud.io

重启docker后台服务

$ systemctl restart docker

安装 kubectl

创建日志目录:

$ mkdir -p /var/log/kubernetes

复制程序文件

$ cp kubelet /usr/bin/

创建工作目录:

$ mkdir -p /var/lib/kubelet

kubectl服务依赖docker服务。

编辑服务文件

$ vim /usr/lib/systemd/system/kubelet.service

[Unit]
Description=Kubernetes Kubelet Server
After=docker.service
Requires=docker.service

[Service]
WorkingDirectory=/var/lib/kubelet
EnvironmentFile=/etc/kubernetes/kubelet
ExecStart=/usr/bin/kubelet $KUBELET_ARGS
Restart=on-failure

[Install]
WantedBy=multi-user.target

接下来,我们依旧针对环境变量 KUBELET_ARGS,编辑配置文件

$ vim /etc/kubernetes/kubelet

KUBELET_ARGS="--api-servers=http://192.168.139.145:8080 --hostname-override=192.168.139.146 --logtostderr=false --log-dir=/var/log/kubernetes --v=2"

安装 kube-proxy

复制程序文件

$ cp kube-proxy /usr/bin/

编辑服务文件

[Unit]
Description=Kubernetes Kube Proxy Server
After=network.target
Requires=network.service

[Service]
EnvironmentFile=/etc/kubernetes/proxy
ExecStart=/usr/bin/kube-proxy $KUBE_PROXY_ARGS
Restart=on-failure
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

针对 KUBE_PROXY_ARGS,编辑配置文件

$ vim /etc/kubernetes/proxy

KUBE_PROXY_ARGS="--master=http://192.168.139.145:8080 --logtostderr=false --log-dir=/var/log/kubernetes --v=2"

配置完成后,通过syetemctl 启动kubelet和kube-proxy服务

systemctl daemon-reload

systemctl enable kubelet.service
systemctl start kubelet.service

systemctl enable kube-proxy.service
systemctl start kube-proxy.service

总结

kubelet默认采用向Master自动注册本Node的机制,在Master上查看各Node的状态,状态为Ready表示Node已经成功注册并状态为可用

我们在Master上,执行一下命令,查看它的工作节点:

$ kubectl get nodes

NAME              STATUS    AGE
192.168.139.146   Ready     4m
前一页 后一页