成都网站建设设计

将想法与焦点和您一起共享

kubernet+calico二进制安装及总结

Kubernetes部署了好多遍了,但是每次还是会遇到各种问题。有的是新版本问题,有的是以前踩过的坑。因为没有文档记录,坑还在那里,我也还在那里。

石首网站建设公司创新互联,石首网站设计制作,有大型网站制作公司丰富经验。已为石首1000多家提供企业网站建设服务。企业网站搭建\成都外贸网站建设公司要多少钱,请找那个售后服务好的石首做网站的公司定做!

本文是以二进制的方式部署,这样方便我们发现和解决问题。

环境说明:

角色

组件

IP

备注

Master

kube-apiserver

kube-scheduler

kube-controller-manager

etcd

10.8.8.27


Node1

Docker

Kubelet

kube-proxy

calico-kube-controllers

calico-node

10.8.8.28


Node2

Docker

Kubelet

kube-proxy

calico-node

10.8.8.29


第一部分:kubernetes安装

1、环境准备

1.1 安装docker

Kubernetes官网文档有介绍,当前版本(k8s 1.13)仅支持docker 1.11之后版本,我这里安装了docker 1.13版本(传统的yum安装:yum install docker)

配置镜像加速,避免后面下载镜像的时候出现超时:

在/etc/docker/daemon.json文件中增加以下内容:

{

"registry-mirrors": ["http://68e02ab9.m.daocloud.io"]

}

设置开机启动:systemctl  enable  docker

然后我们启动docker:systemctl start docker


1.2 Kubernetes二进制文件准备

从kubernetes官网下载需要安装的版本,我搭建的时候版本是v1.13,所以下载v1.13对应的二进制生成文件,对应连接:https://kubernetes.io/docs/setup/release/notes/#downloads-for-v1-13-0,新版本里面已经不直接提供二进制bin包了,需要手动执行里面的脚本下载。

解压下载的文件后,进入cluster目录,执行get-kube-binaries.sh脚本,会在解压路径下形成kubernetes的二进制文件

二进制文件路径:kubernetes/server/kubernetes/server/bin

管理工具路径:kubernetes/client/bin

2、配置kubernetes

2.1创建证书

我最开始并没有使用安全认证,所有的API接口都是暴露在非安全接口上。这种方式单纯部署kubernetes没有问题,但是在部署calico的时候,会出现各种错,后面会详细说

2.1.1创建apiserver的CA证书

使用openssl生成相关证书

#创建ca私钥

openssl genrsa   -out ca.key 2048   

#生成ca证书

openssl req   -x509 -new -nodes -key ca.key -days 10000 -out ca.crt -subj   "/CN=k8s-master"   

#创建apiserver私钥

openssl genrsa   -out server.key 2048  

#根据配置及私钥生成apiserver的证书请求文件

openssl req -new   -key server.key -out apiserver.csr -subj "/CN=k8s-master" -config   openssl.cnf    

#利用CA签发apiserver证书

openssl x509   -req -in apiserver.csr -CA ca.pem -CAkey ca.key -CAcreateserial -out   server.crt -days 365 -extensions v3_req -extfile openssl.cnf    

配置文件(openssl.cnf)内容如下:

[req]

req_extensions = v3_req

distinguished_name = req_distinguished_name

[req_distinguished_name]

[ v3_req ]

basicConstraints = CA:FALSE

keyUsage = nonRepudiation, digitalSignature, keyEncipherment

subjectAltName = @alt_names

[alt_names]

DNS.1 = kubernetes

DNS.2 = kubernetes.default

DNS.3 = kubernetes.default.svc

DNS.4 = kubernetes.default.svc.cluster.local

IP.1 = 10.0.254.1

IP.2 = 10.8.8.27

说明:IP.1 是apisver的cluster IP地址;IP.2 是apisver的宿主主机地址;DNS配置为kube-apiserver虚拟服务名称

以上操作会在当前目录生成:ca.crt  ca.key  ca.srl  server.crt  server.csr  server.key 六个文件


2.1.2创建kubernet-controller、kubernet-schedule的CA证书

#生成controller私钥

openssl genrsa   -out controller.key 2048

#生成证书申请文件

openssl req -new   -keycontroller.key   -outcontroller.csr -subj "/CN=k8s-master"

#签发controller证书

openssl x509   -req -in controller.csr -CA ca.crt -CAkey controller.key -CAcreateserial -out   controller.crt -days 365

以上操作会生成:controller.crt  controller.key  controller.csr

2.1.3创建node1、node2的CA证书

创建方法同2.1.2,只是-subj换成对应的信息,node1换成-subj "/CN=node1",node2换成-subj "/CN=node2"。最终会形成文件:node1.crt  node1.csr  node1.key  node2.crt  node2.csr  node2.key

至此所有的证书都配置完成了,下面开始配置kubernetes的相关组件

2.2 配置相关组件的启动脚本

2.2.1在master上配置etcd、kube-apiserver、kube-controller-manager、kube-schedule服务

1)etcd服务

Etcd服务作为kubernetes集群的主数据库,在安装kubernetes各服务之前需要首先安装和启动。从github官网(https://github.com/etcd-io/etcd/releases)下载etcd二进制文件,并将etcd和etcdctl可执行的二进制文件复制到/usr/local/bin目录下。

设置ETCD服务文件

  • 编辑 /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/local/bin/etcd

[Install]

WantedBy=multi-user.target

  • 将服务加入到开机启动:

systemctl  daemon-reload

systemctl  enable  etcd.service

  • 配置ECTD(单机模式)

编辑/etc/etcd/etcd.conf

ETCD_NAME="etcd1"

ETCD_DATA_DIR="/export/data/etcd"

ETCD_LISTEN_PEER_URLS="http://10.8.8.27:2380"

ETCD_LISTEN_CLIENT_URLS="http://10.8.8.27:2379"

ETCD_INITIAL_ADVERTISE_PEER_URLS="http://10.8.8.27:2380"

ETCD_INITIAL_CLUSTER="etcd1=http://10.8.8.27:2380"

ETCD_INITIAL_CLUSTER_STATE="new"

ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"

ETCD_ADVERTISE_CLIENT_URLS="http://10.8.8.27:2379"

  • 启动ETCD

systemctl  start  etcd.service

etcdctl --endpoints=http://10.8.8.27:2379 cluster-health  #检查etcd启动状态

2)kube-apiserver服务

将步骤1.2获取到的(目录:kubernetes/server/kubernetes/server/bin下)二进制文件kube-apiserver、kube-controller-manager、kubectl、kube-scheduler复制到/usr/local/bin目下下。

  • 编辑/lib/systemd/system/kube-api.service

[Unit]

Description=Kubernetes API Server

After=etcd.service

Wants=etcd.service

[Service]

EnvironmentFile=/etc/kubernetes/apiserver

ExecStart=/usr/local/bin/kube-apiserver $KUBE_API_ARGS

Restart=on-failure

Type=notify

LimitNOFILE=65536

[Install]

WantedBy=multi-user.target

  • 将服务加入到开机启动:

systemctl  daemon-reload

systemctl  enable  kube-api.service

  • 配置kube-api

编辑:/etc/kubernetes/apiserver

KUBE_API_ARGS="--storage-backend=etcd3 \

--etcd-servers=http://10.8.8.27:2379 \

--insecure-bind-address=0.0.0.0 \

--secure-port=64 --insecure-port=8080 \ 

--service-cluster-ip-range=10.0.254.0/24 \

--admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota \

--logtostderr=false --log-dir=/export/logs/kubernets --v=2 \

--allow-privileged=true \

--tls-private-key-file=/etc/kubernetes/ssl/apiserver/server.key \

--client-ca-file=/etc/kubernetes/ssl/apiserver/ca.crt \

--service-account-key-file=/etc/kubernetes/ssl/apiserver/server.key \

--tls-cert-file=/etc/kubernetes/ssl/apiserver/server.crt"

--service-cluster-ip-range:是集群虚拟IP地址段范围;

--admission-control:kubernetes集群的准入控制设置,各控制模块以插件的形式一次生效;

--allow-privileged:这个是为后面的calico准备,因为calico-node需要以特权模式运行在各node上;

--client-ca-file、--tls-cert-file、--tls-private-key-file:为刚才创建的api证书;

--service-account-key-file:这里稍微提一下serviceaccount,因为后面calico会创建serviceaccount账户,并且它启动的pod会频繁使用到。Service Account也是一种一种账号,但它并不是给集群的用户使用的,而是给运行在pod里的进程使用的。正常情况下,为了确保kubernetes集群安全,API server会对客户端进行身份认证,而pod就是通过serviceaccount认证的,pod在启动的时候,会根据传入的serviceaccount(没有传入的话使用默认的default),在/var/run/secrets/kubernetes.io/serviceaccount生成ca.crt、namespace、token三个文件,这三个文件就是作为API Server验证身份的要素。在master可以通过kubectl get serviceaccount --all-namespaces查看已经创建的Service Account,后面有机会我们还会提到Service Account。


2)kube-controller-manager服务

Kube-controller-manager依赖kube-apiserver服务

  •  编辑/lib/systemd/system/kube-controller-manager.service

[Unit]

Description=Kubernetes   Controller Manager

After=kube-api.service

Wants=kube-api.service

[Service]

EnvironmentFile=/etc/kubernetes/controller-manager

ExecStart=/usr/local/bin/kube-controller-manager   $KUBE_CONTROLLER_MANAGER_ARGS

Restart=on-failure

#Type=notify

LimitNOFILE=65536

[Install]

WantedBy=multi-user.target

我在使用Type=notify的时候,会一直重启,所以注释掉


  • 配置/etc/kubernetes/controller-manager

KUBE_CONTROLLER_MANAGER_ARGS="\

--kubeconfig=/etc/kubernetes/kubeconfig.yaml   \

 --master=https://10.8.8.27:6443 \

--logtostderr=false   --log-dir=/export/logs/kubernetes --v=2 \

--service-account-private-key-file=/etc/kubernetes/ssl/apiserver/server.key   \

--root-ca-file=/etc/kubernetes/ssl/apiserver/ca.crt"

对应/etc/kubernetes/kubeconfig.yaml配置如下:

apiVersion:   v1

kind:   Config

users:

 - name: controllermanager

   user:

     client-certificate:   /etc/kubernetes/ssl/kube-controller/controller.crt

     client-key:   /etc/kubernetes/ssl/kube-controller/controller.key

clusters:

 - name: local

   cluster:

     certificate-authority:   /etc/kubernetes/ssl/kube-controller/ca.crt

contexts:

 - context:

     cluster:   local

     user: controllermanager       

   name: my-context

current-context:   my-context

Config可以指定多集群配置,这里代表使用my-context的上下文,它包括user:controllermanager、cluster:local的配置

  • 将服务加入到开机启动:

systemctl  daemon-reload

systemctl  enable  kube-controller-manager.service

3)配置kube-schedule服务

kube-schedule也依赖kube-apisever服务

  • 编辑/lib/systemd/system/kube-scheduler.service

[Unit]

Description=Kubernetes   Scheduler

After=kube-api.service

Wants=kube-api.service

 

[Service]

EnvironmentFile=/etc/kubernetes/scheduler

ExecStart=/usr/local/bin/kube-scheduler   $KUBE_SCHEDULER_ARGS

Restart=on-failure

#Type=notify

LimitNOFILE=65536

 

[Install]

WantedBy=multi-user.target

同样使用默认的Type

  •  配置/etc/kubernetes/scheduler

KUBE_SCHEDULER_ARGS="   \

--kubeconfig=/etc/kubernetes/kubeconfig.yaml   \

--master=https://10.8.8.27:6443   \

--logtostderr=false   --log-dir=/export/logs/kubernetes --v=2"

--kubeconfig:共用kube-controller-manager配置

  • 将服务加入到开机启动:

systemctl  daemon-reload

systemctl  enable  kube-scheduler.service

4)启动kube-apiserver、kube-controller-manager、kube-schedule

systemctl restart kube-api.service

systemctl restart kube-controller-manager.service

systemctl restart kube-scheduler.service


2.2.2在node1、node2上配置kube-proxy、kubelet服务

同样将之前获取的二进制文件kubelet、kube-proxy同步到所有的node的/usr/local/bin目录下,相应节点的证书也同步到相应目录下。

配置kubelet服务

  • 编辑/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/local/bin/kubelet $KUBE_KUBELET_ARGS

Restart=on-failure

Type=notify

LimitNOFILE=65536

[Install]

WantedBy=multi-user.target

  • 配置kubelet

编辑/etc/kubernetes/kubelet

KUBE_KUBELET_ARGS="--kubeconfig=/etc/kubernetes/kubeconfig.yaml \

--hostname-override=10.8.8.28 \

--logtostderr=false --log-dir=/export/logs/kubernetes --v=2 \

--fail-swap-on=false \

--cgroup-driver=systemd \

--runtime-cgroups=/systemd/system.slice \

--kubelet-cgroups=/systemd/system.slice"

新版本的配置已经不支持—master,需要放在—kubeconfig指定的文件里;

--pod-infra-container-image:这个选项是指定每个POD里的基础容器镜像,它负责管理POD的network/ipc namespaces,这里可以指定自己仓库镜像(默认是:"k8s.gcr.io/pause:3.1"),也可以通过以下方式下载镜像,避免returned error: No such image: k8s.gcr.io/pause:3.1"错误:

docker pull ibmcom/pause:3.1

docker tag ibmcom/pause:3.1  k8s.gcr.io/pause:3.1

--cgroup-driver=systemd需要和docker保持一致,否则会出现以下错误:

failed to run Kubelet: failed to create kubelet: misconfiguration: kubelet cgroup driver: "system" is different from docker cgroup driver: "systemd"

配置/etc/kubernetes/kubeconfig.yaml内容:

apiVersion: v1

kind: Config

users:

 - name: kubelet

   user:

     client-certificate : /etc/kubernetes/ssl/node1.crt

     client-key: /etc/kubernetes/ssl/node1.key

clusters:

  - cluster:

      server: https://10.8.8.27:6443

      certificate-authority: /etc/kubernetes/ssl/ca.crt

    name: local

contexts:

  - context:

      cluster: local

      user: kubelet

    name: local

current-context: local

client-certificate、client-key:不同的node更换不同的路径


配置kube-proxy服务

  • 编辑/lib/systemd/system/kube-proxy.service

[Unit]

Description=Kubernetes Kube-Proxy Server

After=network.service

Requires=network.service

[Service]

EnvironmentFile=/etc/kubernetes/proxy

ExecStart=/usr/local/bin/kube-proxy $KUBE_PROXY_ARGS

Restart=on-failure

LimitNOFILE=65536

[Install]

WantedBy=multi-user.target

  • 配置/etc/kubernetes/proxy

KUBE_PROXY_ARGS="--cluster-cidr=10.0.253.0/24 \

--master=https://10.8.8.27:6443 \

--logtostderr=true --log-dir=/export/logs/kubernetes --v=2 \

--hostname-override=10.8.8.28 \

--proxy-mode=iptables \

--kubeconfig=/etc/kubernetes/kubeconfig.yaml"

--proxy-mode:proxy有三种模式,默认为iptables,新版本也支持ipvs,只是还是测试阶段

--kubeconfig:与kubelet共用

3)启动kubelet、kube-proxy

systemctl daemon-reload

systemctl enable kube-proxy.service

systemctl enable kubelet.service

systemctl start kubelet.service

systemctl start kube-proxy.service

这样我们的kubernetes就已经安装完成了


第二部分 Calico安装

官网已经提供了相应的配置文件,该配置文件定义了所有calico所需资源,直接通过kubectl就可以创建calico-node及calico-kube-controllers。

下载地址:https://docs.projectcalico.org/v3.5/getting-started/kubernetes/installation/hosted/calico.yaml  根据不同的版本,更改v3.5的内容。这里简单说明一下配置:

1、配置说明

1)configmap对象配置

kind: ConfigMap

apiVersion: v1

metadata:

  name: calico-config

  namespace: kube-system

data:

  # Configure this with the location of your etcd cluster.

  etcd_endpoints: "http://10.8.8.27:2379"

  # If you're using TLS enabled etcd uncomment the following.

  # You must also populate the Secret below with these files.

  etcd_ca: ""   # "/calico-secrets/etcd-ca"

  etcd_cert: "" # "/calico-secrets/etcd-cert"

  etcd_key: ""  # "/calico-secrets/etcd-key"

  # Typha is disabled.

  typha_service_name: "none"

  # Configure the Calico backend to use.

  calico_backend: "bird"

  # Configure the MTU to use

  veth_mtu: "1440"

  # The CNI network configuration to install on each node.  The special

  # values in this config will be automatically populated.

  cni_network_config: |-

    {

      "name": "k8s-pod-network",

      "cniVersion": "0.3.0",

      "plugins": [

        {

          "type": "calico",

          "log_level": "info",

          "etcd_endpoints": "__ETCD_ENDPOINTS__",

          "etcd_key_file": "__ETCD_KEY_FILE__",

          "etcd_cert_file": "__ETCD_CERT_FILE__",

          "etcd_ca_cert_file": "__ETCD_CA_CERT_FILE__",

          "mtu": __CNI_MTU__,

          "ipam": {

              "type": "calico-ipam"

          },

          "policy": {

              "type": "k8s"

          },

          "kubernetes": {

              "kubeconfig": "__KUBECONFIG_FILEPATH__"

          }

        },

        {

          "type": "portmap",

          "snat": true,

          "capabilities": {"portMappings": true}

        }

      ]

    }

etcd_endpoints:会替换掉变量里cni_network_config的__ETCD_ENDPOINTS__;

etcd_ca、etcd_cert、etcd_key:同上,会替换相应参数;

cni_network_config: calico-node pod的初始化容器calico-cni利用install-cni.sh,将该参数解析成10-calico.conflist,放到/etc/cni/net.d目录下,比如我的解析内容如下:

{

  "name":   "k8s-pod-network",

  "cniVersion": "0.3.0",

  "plugins": [

    {

      "type": "calico",

      "log_level":   "info",

      "etcd_endpoints":   "http://10.8.8.27:2379",

      "etcd_key_file":   "",

      "etcd_cert_file":   "",

      "etcd_ca_cert_file":   "",

      "mtu": 1440,

      "ipam": {

          "type":   "calico-ipam"

      },

      "policy": {

          "type": "k8s"

      },

      "kubernetes": {

          "kubeconfig":   "/etc/cni/net.d/calico-kubeconfig"

      }

    },

    {

      "type": "portmap",

      "snat": true,

      "capabilities":   {"portMappings": true}

    }

  ]

}

Kubeconfig:这个配置就是之前提到过的service account发挥作用了,calico-cni的install-cni.sh脚本会读取/var/run/secrets/kubernetes.io/serviceaccount下的内容,并根据kubelet设置的环境变量(KUBERNETES_SERVICE_PROTOCOL、KUBERNETES_SERVICE_HOST、KUBERNETES_SERVICE_PORT)生成/etc/cni/net.d/calico-kubeconfig配置。这个配置在后面calico-node和calico-kube-controller启动的时候,访问kube-apiserver会用到。

2)ServiceAccount对象

apiVersion:   v1

kind:   ServiceAccount

metadata:

  name: calico-node

  namespace: kube-system

创建名为calica-node的ServiceAccount对象。Pod可以通过指定serviceaccount来说明使用哪个token

3)DaemonSet对象

会在所有node上创建calico-node pod,这个pod包括两个容器,一个是初始化容器:calico-cni,一个是创建路由和iptables信息的calico-node

CALICO_IPV4POOL_CIDR:这个参数会在ETCD创建一个IPpool;

CALICO_IPV4POOL_IPIP:选择是否启动IPIP,默认启动,off是关闭,关闭的话就是通过BGP协议同步路由。

FELIX_IPINIPENABLED:false是FELIX关闭IPIP

4)Deployment对象

会创建calico-kube-controllers容器。这个容器是监控和并同步network policy、namespaces、pods、nodes、serviceaccount等信息到calico的配置存储系统。官方文档建议的是,一个calico-kube-controllers  replicas能管理200个节点,建议总共不超过20个replicas。

2、安装calico组件

2.1安装calico组件

kubectl apply -f calico.yaml  安装calico组件

2.2配置kubelet

如果kubernetes要使用calico的话,必须在kubelet的配置加上--network-plugin=cni参数,这样才能保证kubelet最终能通过cni.go去调用calico的插件。配置完成后,重启kubelet。

2.3启动测试容器,最终会得到如下信息

# kubectl get pods --all-namespaces -o wide

kubernet+calico二进制安装及总结

# kubectl get serviceaccount --all-namespaces

kubernet+calico二进制安装及总结

#kubectl get services --all-namespaces  -o wide

kubernet+calico二进制安装及总结

我列出10.8.8.28上的路由信息,会看到有到192.168.95.139的路由,这个是开启了IPIP模式

kubernet+calico二进制安装及总结

如果是BGP模式的会出现类似以下情况,路由跑在实际的物理网卡

kubernet+calico二进制安装及总结

路由协议是bird

kubernet+calico二进制安装及总结

可以看到本地启动了bird客户端,做BGP路由同步

kubernet+calico二进制安装及总结

iptables上也会看到api server的配置,这里不一一截图,大家昨晚之后可以自行查看


3、测试脚本

整个安装过程花了我很多时间,因为开始没做安全,所以遇到各种错,然后就开始看源码,找问题,中间也写了很多calico的测试脚本,我大概梳理一下整个kubernetes+calico之间各组件运行逻辑:

1)IP配置逻辑

kubernet+calico二进制安装及总结

2)IP分配逻辑

这次我没有认真看calico的IP分配逻辑,所以我把以前经过源码分析的流程图拿出来充个数

kubernet+calico二进制安装及总结

下面开始说测试脚本

1、调用calico脚本申请IP资源

这个是模拟cni.go的脚本的,calico执行的时候,会读取大量的k8s环境变量,以下是环境设置实例:

#!/bin/bash

mkdir -p /var/run/netns/

[ -L /var/run/netns/default ] &&   rm -f /var/run/netns/default

ln -s /var/run/docker/netns/default   /var/run/netns/default

 

export   CNI_ARGS="IgnoreUnknown=1;K8S_POD_NAMESPACE=;K8S_POD_NAME="

#export CNI_ARGS='IgnoreUnknown=1'

export CNI_COMMAND="ADD"

export   CNI_CONTAINERID="7dd0f5009d1e4e6d0289311755e7885b93a5a1aa7e34a066689860df5bf6d763"

export CNI_NETNS="kube-system"

export CNI_IFNAME="eth0"

export CNI_PATH="/opt/cni/bin"

export   CNI_NETNS="/var/run/netns/default"

这里说一下K8S_POD_NAMESPACE、K8S_POD_NAME(脚本保持空就行)这两个参数,如果为空的话,/opt/cni/bin/calico这个脚本是不需要去验证kube-apiserver的,所以也就不需要serviceaccount,但是如果两这个不为空,就需要用到serviceaccount了。也就是/etc/cni/net.d/calico-kubeconfig配置。

开始在没有配置service account的时候,cni获取IP出现以下错误:

Error adding default_nginx1/83637c6d9fa54573ba62538dcd6b7b5778a7beb4fc1299449e894e488fb3c116   to network calico/k8s-calico-network: invalid configuration: no configuration   has been provided

这其实就是结果返回空的结果。

以下是脚本(calicoctl)内容,go run calicoctl.go 就会出现理想的结果了:

package main

 

import (

          "io/ioutil"

          "bytes"

          "encoding/json"

          "fmt"

          "net"

          "os/exec"

          "reflect"

)

 

type Interface struct {

          Name    string   `json:"name"`

          Mac     string   `json:"mac,omitempty"`

          Sandbox string `json:"sandbox,omitempty"`

}

 

type Result struct {

          CNIVersion string           `json:"cniVersion,omitempty"`

          Interfaces []*Interface     `json:"interfaces,omitempty"`

          IPs        []*IPConfig    `json:"ips,omitempty"`

          //DNS        types.DNS      `json:"dns,omitempty"`

}

 

type IPConfig struct {

          // IP version, either "4" or "6"

          Version string

          // Index into Result structs Interfaces list

          Interface *int

          //Address   string   `json:"address,omitempty"`

          Address   net.IPNet

          Gateway   net.IP

}

 

func NewResult(data []byte) {

          result := &Result{}

          if err := json.Unmarshal(data, result); err != nil {

                fmt.Println(err)

          }

          fmt.Println(result.IPs[0].Version)

}

 

func main() {

          stdout := &bytes.Buffer{}

          stdinData, _ := ioutil.ReadFile("/etc/kubernetes/calico_test.yaml")

          c := exec.Cmd{

                Path:   "/opt/cni/bin/calico",

                Args:   []string{"/opt/cni/bin/calico"},

                Stdin:  bytes.NewBuffer(stdinData),

                Stdout: stdout,

          }

          _ = c.Run()

          result := stdout.Bytes()

          fmt.Println(string(result))

          NewResult(result)

}

对应的/etc/kubernetes/calico_test.yaml内容如下,这个文件对应的是kubelet传入的stdinData:

{

    "cniVersion": "0.3.0",

    "etcd_ca_cert_file": "",

    "etcd_cert_file": "",

    "etcd_endpoints": "http://10.8.8.27:2379",

    "etcd_key_file": "",

    "ipam": {

      "type": "calico-ipam"

    },

    "kubernetes": {

      "kubeconfig": "/etc/cni/net.d/calico-kubeconfig"

    },

    "log_level": "debug",

    "mtu": 1440,

    "name": "k8s-pod-network",

    "policy": {

      "type": "k8s"

    },

    "type": "calico"

}

2、获取kubelet cni传入的参数脚本

编辑calico.go

package main

 

import (

          "io/ioutil"

          "log"

          "os"

)

 

func main() {

          file := "/export/logs/calico/request.log"

          logFile, err := os.OpenFile(file, os.O_RDWR|os.O_CREATE|os.O_APPEND,   0766)

 

          if nil != err {

                panic(err)

          }

          loger := log.New(logFile, "calico",   log.Ldate|log.Ltime|log.Lshortfile)

          loger.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)

          Stdin := os.Stdin

          stdinData, err := ioutil.ReadAll(Stdin)

          if err != nil {

                loger.Println("error   reading from stdin:%v",err)

          }

          loger.Println(string(stdinData))

}

这里讲kubelet传入的请求写入到了/export/logs/calico/request.log文件中,你也可以直接输出。最后的结果类似以下内容:

{"cniVersion":"0.3.0","etcd_ca_cert_file":"","etcd_cert_file":"","etcd_endpoints":"http://10.8.8.27:2379","etcd_key_file":"","ipam":{"type":"calico-ipam"},"kubernetes":{"kubeconfig":"/etc/cni/net.d/calico-kubeconfig"},"log_level":"info","mtu":1440,"name":"k8s-calico-network","policy":{"type":"k8s"},"type":"calico"}

编译并放到/opt/cni/bin目录下。启动测试容器就可以看到日志输出了


3、获取ETCD key信息

export ETCDCTL_API=3

etcdctl --endpoints=http://10.8.8.27:2379 get / --prefix --keys-only

4、错误介绍

以上其实已经覆盖了一些错误的解决方案,还有一些也在这里说明一下:

  • x509: certificate is valid for 10.8.8.27, 10.0.254.1, not 10.254.0.1

这里是因为kube-apiservre的虚拟IP不在--service-cluster-ip-range配置的范围之内,解决方案是,删掉kubernetes的service,让它重新创建。这样就不会再出现这个错了。

  • pod_controller.go:206: Failed to list *v1.Pod: Unauthorized  

这是因为service account没有正确配置,导致calico-kube-controllers在向kube-apiserver获取pod、namespace(namespace_controller.go)、policy(policy_controller.go)、node(node_controller.go)、serviceaaccount(serviceaaccount_controller.go)列表信息时,认证失败.


本文名称:kubernet+calico二进制安装及总结
文章路径:http://chengdu.cdxwcx.cn/article/gdpjss.html