kubernetes 1.9部署实践

简要说明

我们知道,kubenretes的安装非常复杂,因为组件众多。为此各开源社区以及一些商业公司都发布了一些针对kubernetes集成安装组件,包括kubernetes官方的kubeadm, minikube,基于ubuntu的conjure-up,以及rancher等。但是我个人,是不太喜欢使用集成软件来完成应用部署的。使用集成软件部署固然简化了部署成本,却提升了维护成本,也不利于使用人员对软件原理的理解。所以我宁愿通过自己编写salt或者ansible配置文件的方式来实现应用的自动化部署。但这种方式就要求我们对应用的各组件必须要有深入的了解。

本篇文档我们就通过纯手动的方式来完成kubernetes 1.9的安装部署。

kubernetes的完整部署大概涉及到如下几个方面:

  • master节点的集群方案
  • pod的网络方案
  • dns方案
  • 日志收集方案
  • 容器对外暴露的负载均衡方案
  • 容器监控方案

本篇文档不会涉及到所有方面,有些方案在以往的博客中也有专门的介绍,另外一些,也会在后续的博客中介绍,最终形成kubernetes的最佳实践。在本篇文档中,只会涉及到master节点的集群方案以及pod的网络方案。容器监控方案,在实际生产中,我们采用prometheus+cadvisor的方案,但在文档中,我们使用默认的heapster+influxdb+cadvisor的方案,并且只做简单部署。

master的集群我们使用haproxy反向代理的方式,haproxy的高可用不是本篇的重点,所以只会使用一台haproxy实现集群的功能。

pod的网络方案,我这里也没有采用包括flannel, calico等cni插件的方式。而是直接使用quagga运行ospf,以打通所以节点的docker0网络。所以这也要求我们在安装docker时,就需要为每一个节点的docker0指定一个独立的网段。

至于dns方案,在1.9中coredns还处于alpha版本,在目前已经发布的1.10中,已经是beta版了。至于kube-dns,没有经过大规模集群的验证,不推荐使用。我们在实际生产中直接采用了京东开源的containerdns,具体可以参考我的这篇博客《containerdns配置说明》。但是在这篇文档中,我们还是以官方的kube-dns为例。

另外还需要说明,因为centos上docker的devicemapper性能问题,我这里使用的操作系统是ubuntu 16.04。生产环境也建议使用ubuntu系统。

环境说明

IP 角色 pod网段
10.1.61.175 master、etcd
10.1.61.176 master、etcd
10.1.61.177 master、etcd
10.1.61.178 node、docker 10.1.90.0/27
10.1.61.129 haproxy

这里使用了三个master,一个node,一个haproxy节点

安装前的约定

我们创建/opt/kubernetes作为安装目录,所有的证书文件都会存放在/opt/kubernetes/ssl目录下;所有的配置文件,包括etcd.conf, bootstrap.kubeconfig等都存放在/opt/kubernetes/cfg目录下;所有可执行文件,包括etcd,etcdctl, kube-apiserver, kubelet, kube-proxy, kube-controlelr-manager, kube-scheduler, cfssl, cfssljosn等都存放在/opt/kubernetes/bin目录下;所有日志会存放在/opt/kubernetes/log目录下;

创建安装目录如下:

mkdir -p /opt/kubernetes/{bin,ssl,cfg,log}

配置etcd

我这里etcd运行于内网中,为提高性能,不使用https方式做验证。 具体部署可直接参考我的另一篇博客《etcd集群部署》

生成相关证书

证书类型说明

证书名称 配置文件 用途
ca.pem ca-csr.json ca根证书
kube-proxy.pem ca-config.json kube-proxy-csr.json kube-proxy使用的证书
admin.pem admin-csr.json ca-config.json kubectl 使用的证书
kubernetes.pem ca-config.json kubernetes-csr.json apiserver使用的证书

cfssl配置

在这里直接使用cfssl工具来实现证书配置,cfssl工具安装如下:

wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
chmod +x cfssl_linux-amd64 cfssljson_linux-amd64 cfssl-certinfo_linux-amd64
mv cfssl_linux-amd64 /opt/kubernetes/bin/cfssl
mv cfssljson_linux-amd64 /opt/kubernetes/bin/cfssljson
mv cfssl-certinfo_linux-amd64 /opt/kubernetes/bin/cfssl-certinfo

注: 下载工具需要翻墙

证书相关配置

生成ca证书

ca-config.json文件内容如下:

{
    "signing": {
        "default": {
            "expiry": "175200h"
        },
        "profiles": {
            "kubernetes": {
                "expiry": "175200h",
                "usages": [
                    "signing",
                    "key encipherment",
                    "server auth",
		    "client auth"
                ]
            },
            "etcd": {
                "expiry": "175200h",
                "usages": [
                    "signing",
                    "key encipherment",
                    "server auth",
		            "client auth"
                ]
            }
        }
    }
}

字段说明:

  • ca-config.json:可以定义多个Profiles,分别指定不同的过期时间、使用场景等参数;后续在签名证书的时候使用某个Profile。这里定义了两个Profile,一个用于kubernetes,一个用于etcd,我这里etcd没有使用证书,所以另一个不使用。
  • signing:表示该 证书可用于签名其他证书;生成的ca.pem证书中CA=TRUE
  • server auth:表示client可以使用该ca对server提供的证书进行验证
  • client auth:表示server可以用该ca对client提供的证书进行验证

ca-csr.json内容如下:

{
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "L": "Wuhan",
            "ST": "Hubei",
    	    "O": "k8s",
    	    "OU": "System"
        }
    ]
}

生成ca证书:

cfssl gencert --initca=true ca-csr.json | cfssljson --bare ca

生成kubernetes证书

kubernetes-csr.json内容如下:

{
    "CN": "kubernetes",
    "hosts": [
        "127.0.0.1",
	"localhost",
        "10.1.61.175",
        "10.1.61.176",
        "10.1.61.177",
        "10.254.0.1",
        "kubernetes",
        "kubernetes.default",
        "kubernetes.default.svc",
        "kubernetes.default.svc.cluster",
        "kubernetes.default.svc.cluster.local"
    ],
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "ST": "Hubei",
            "L": "Wuhan",
            "O": "k8s",
            "OU": "System"
        }
    ]
}

这个内容需要做下简要说明:

上面配置hosts字段中指定授权使用该证书的IP和域名列表,因为现在要生成的证书需要被Kubernetes Master集群各个节点使用,所以这里指定了各个节点的IP和hostname。

生成kubernetes证书:

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

生成kubectl证书

admin-csr.json内容如下:

{
  "CN": "admin",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Hubei",
      "L": "Wuhan",
      "O": "system:masters",
      "OU": "System"
    }
  ]
}

  • kube-apiserver会提取CN作为客户端的用户名,这里是admin,将提取O作为用户的属组,这里是system:masters
  • 后续kube-apiserver使用RBAC对客户端(如kubelet、kube-proxy、pod)请求进行授权
  • apiserver预定义了一些RBAC使用的ClusterRoleBindings,例如cluster-admin将组system:masters与CluasterRole cluster-admin绑定,而cluster-admin拥有访问apiserver的所有权限,因此admin用户将作为集群的超级管理员。

生成kubectl证书:

cfssl gencert --ca ca.pem --ca-key ca-key.pem --config ca-config.json --profile kubernetes admin-csr.json | cfssljson --bare

生成kube-proxy证书

kube-proxy-csr.json内容如下:

{
  "CN": "system:kube-proxy",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Hubei",
      "L": "Wuhan",
      "O": "k8s",
      "OU": "System"
    }
  ]
}

  • CN指定该证书的user为system:kube-proxy
  • kube-apiserver预定义的RoleBinding cluster-admin将User system:kube-proxy与Role system:node-proxier绑定,该role授予了调用kube-apiserver Proxy相关API的权限;

生成kube-proxy证书:

cfssl gencert --ca ca.pem --ca-key ca-key.pem --config ca-config.json --profile kubernetes kube-proxy-csr.json | cfssljson --bare

上面所有证书,都可以通过如下方法一下子全部生成:

cfssl gencert --initca=true ca-csr.json | cfssljson --bare ca

for targetName in kubernetes admin kube-proxy; do
    cfssl gencert --ca ca.pem --ca-key ca-key.pem --config ca-config.json --profile kubernetes $targetName-csr.json | cfssljson --bare $targetName
done

cfssl的用法中,--profile就用于指定ca-config里的哪个profiles

生成的证书列表如下:

ll /etc/kubernetes/pki/
total 48
-rw------- 1 kube kube 1679 Aug 30 16:49 admin-key.pem
-rw-r--r-- 1 kube kube 1363 Aug 30 16:49 admin.pem
-rw------- 1 kube kube 1675 Aug 30 16:49 ca-key.pem
-rw-r--r-- 1 kube kube 1289 Aug 30 16:49 ca.pem
-rw------- 1 kube kube 1679 Aug 30 16:49 kube-proxy-key.pem
-rw-r--r-- 1 kube kube 1363 Aug 30 16:49 kube-proxy.pem
-rw------- 1 kube kube 1679 Sep 13 13:46 kubernetes-key.pem
-rw-r--r-- 1 kube kube 1586 Sep 13 13:46 kubernetes.pem

检验证书:

#以kubernetes证书为例
openssl x509  -noout -text -in  kubernetes.pem
......
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=CN, ST=Hubei, L=Wuhan, O=k8s, OU=System
        Validity
            Not Before: Sep 13 05:41:00 2017 GMT
            Not After : Sep  8 05:41:00 2037 GMT
        Subject: C=CN, ST=Hubei, L=Wuhan, O=k8s, OU=System, CN=kubernetes
......
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Extended Key Usage: 
                TLS Web Server Authentication, TLS Web Client Authentication
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 Subject Key Identifier: 
                DA:D0:E5:FD:AD:DD:25:08:19:FA:9D:F8:83:C4:44:1B:5D:8E:1E:CC
            X509v3 Authority Key Identifier: 
                keyid:20:66:77:4A:BA:E3:B8:60:50:BC:C2:EC:9A:E1:E0:DF:5E:F7:7F:35

            X509v3 Subject Alternative Name: 
                DNS:localhost, DNS:kubernetes, DNS:kubernetes.default, DNS:kubernetes.default.svc, DNS:kubernetes.default.svc.cluster, DNS:kubernetes.default.svc.cluster.local, IP Address:127.0.0.1, IP Address:10.1.61.129, IP Address:10.254.0.1
......

  • 确认 Issuer 字段的内容和 ca-csr.json 一致;
  • 确认 Subject 字段的内容和 kubernetes-csr.json 一致;
  • 确认 X509v3 Subject Alternative Name 字段的内容和 kubernetes-csr.json 一致;
  • 确认 X509v3 Key Usage、Extended Key Usage 字段的内容和 ca-config.json 中 kubernetesprofile 一致;

生成token及kubeconfig

在本次配置中,我们将会同时启用证书认证,token认证,以及http basic认证。所以需要提前生成token认证文件,basic认证文件以及kubeconfig

生成客户端使用的token

export BOOTSTRAP_TOKEN=$(head -c 16 /dev/urandom | od -An -t x | tr -d ' ')
cat > token.csv <<EOF
${BOOTSTRAP_TOKEN},kubelet-bootstrap,10001,"system:kubelet-bootstrap"
EOF

生成bashboard使用的http basic认证文件

cat > basic_auth.csv <<EOF
123456,admin,1,"system:masters"
EOF

生成kubeconfig

export KUBE_APISERVER="https://10.1.61.129:6443"
# 设置集群参数,即api-server的访问方式,给集群起个名字就叫kubernetes
kubectl config set-cluster kubernetes 
  --certificate-authority=ca.pem 
  --embed-certs=true 
  --server=${KUBE_APISERVER} 
  --kubeconfig=bootstrap.kubeconfig
  
# 设置客户端认证参数,这里采用token认证
kubectl config set-credentials kubelet-bootstrap 
  --token=${BOOTSTRAP_TOKEN} 
  --kubeconfig=bootstrap.kubeconfig

# 设置上下文参数,用于连接用户kubelet-bootstrap与集群kubernetes
kubectl config set-context default 
  --cluster=kubernetes 
  --user=kubelet-bootstrap 
  --kubeconfig=bootstrap.kubeconfig
  
# 设置默认上下文
kubectl config use-context default --kubeconfig=bootstrap.kubeconfig

kube-proxy的kubeconfig配置如下,与上面基本相同:

# 设置集群参数
kubectl config set-cluster kubernetes 
  --certificate-authority=ca.pem 
  --embed-certs=true 
  --server=${KUBE_APISERVER} 
  --kubeconfig=kube-proxy.kubeconfig
# 设置客户端认证参数
kubectl config set-credentials kube-proxy 
  --client-certificate=kube-proxy.pem 
  --client-key=kube-proxy-key.pem 
  --embed-certs=true 
  --kubeconfig=kube-proxy.kubeconfig
# 设置上下文参数
kubectl config set-context default 
  --cluster=kubernetes 
  --user=kube-proxy 
  --kubeconfig=kube-proxy.kubeconfig
# 设置默认上下文
kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig

部署master

安装

master端涉及kube-apiserver, kube-controller-manager以及kube-scheduler三个组件。所有组件我们都使用二进制包的方式安装。kubernetes源代码地址:https://github.com/kubernetes/kubernetes

我们可以通过git clone的方式把源代码下载到本地,并checkout出1.9.0版本。然后通过go build的方式执行编译,编译之后,所有的二进制文件都未于源代码目录的_output目录中。我们获取我们所需要的二进制组件即可。另外需要说明的是,编译需要依赖go开发环境。

git clone https://github.com/kubernetes/kubernetes.git
cd kubernetes
git checkout release-1.9
go build

另外,我们还需要将前面生成的ca证书及key,kubernetes的证书及key以及kubectl的证书及key分发到各个master节点的/opt/kubernetes/ssl目录中。

配置

前面所有的准备工作都做完以后,剩下的就是配置各组件的启动脚本了。

kube-apiserver的服务启动脚本/lib/systemd/system/kube-apiserver.service内容如下:

[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=network.target

[Service]
ExecStart=/opt/kubernetes/bin/kube-apiserver 
  --admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota,DefaultTolerationSeconds,NodeRestriction 
  --apiserver-count=3 
  --bind-address=10.1.61.175 
  --insecure-bind-address=127.0.0.1 
  --insecure-port=8080 
  --secure-port=6443 
  --authorization-mode=Node,RBAC 
  --runtime-config=rbac.authorization.k8s.io/v1 
  --kubelet-https=true 
  --anonymous-auth=false 
  --basic-auth-file=/opt/kubernetes/ssl/basic-auth.csv 
  --enable-bootstrap-token-auth 
  --token-auth-file=/opt/kubernetes/ssl/bootstrap-token.csv 
  --service-cluster-ip-range=10.254.0.0/16 
  --service-node-port-range=20000-40000 
  --tls-cert-file=/opt/kubernetes/ssl/kubernetes.pem 
  --tls-private-key-file=/opt/kubernetes/ssl/kubernetes-key.pem 
  --client-ca-file=/opt/kubernetes/ssl/ca.pem 
  --service-account-key-file=/opt/kubernetes/ssl/ca-key.pem 
  --etcd-servers=http://10.1.61.175:2379,http://10.1.61.176:2379,http://10.1.61.177:2379 
  --etcd-quorum-read=true 
  --enable-swagger-ui=true 
  --allow-privileged=true 
  --audit-log-maxage=30 
  --audit-log-maxbackup=3 
  --audit-log-maxsize=100 
  --audit-log-path=/opt/kubernetes/log/api-audit.log 
  --event-ttl=1h 
  --v=2 
  --logtostderr=true
Restart=on-failure
RestartSec=5
Type=notify
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

kube-controller-manager的服务启动脚本/lib/systemd/system/kube-controller-manager.service内容如下:

[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/GoogleCloudPlatform/kubernetes

[Service]
ExecStart=/opt/kubernetes/bin/kube-controller-manager 
  --cluster-name=kubernetes 
  --address=127.0.0.1 
  --master=http://127.0.0.1:8080 
  --service-cluster-ip-range=10.254.0.0/16 
  --cluster-signing-cert-file=/opt/kubernetes/ssl/ca.pem 
  --cluster-signing-key-file=/opt/kubernetes/ssl/ca-key.pem 
  --service-account-private-key-file=/opt/kubernetes/ssl/ca-key.pem 
  --root-ca-file=/opt/kubernetes/ssl/ca.pem 
  --node-monitor-grace-period=40s 
  --node-monitor-period=5s 
  --pod-eviction-timeout=5m0s 
  --controllers=*,bootstrapsigner,tokencleaner 
  --horizontal-pod-autoscaler-use-rest-clients=false 
  --leader-elect=true 
  --v=2 
  --logtostderr=true

Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

kube-scheduler的服务启动脚本/lib/systemd/system/kube-scheduler内容如下:

[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/GoogleCloudPlatform/kubernetes

[Service]
ExecStart=/opt/kubernetes/bin/kube-scheduler 
  --address=127.0.0.1 
  --master=http://127.0.0.1:8080 
  --leader-elect=true 
  --v=2 
  --logtostderr=true

Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.targe

启动

systemctl start kube-apiserver kube-controller-manager kube-scheduler
systemctl enable kube-apiserver kube-controller-manager kube-scheduler

配置haproxy

haproxy的具体配置我就不作说明了,这里直接给出haproxy的配置文件:

global 
  log 127.0.0.1 local0
  log 127.0.0.1 local1 notice
  maxconn 4096
  chroot /usr/share/haproxy
  user haproxy
  group haproxy
  daemon
  
defaults
  log global
  mode tcp
  timeout connect 5000ms
  timeout client 50000ms
  timeout server 50000ms
  
listen stats
  bind    *:9000
  mode    http
  stats   enable
  stats   hide-version
  stats   uri       /stats
  stats   refresh   30s
  stats   realm     Haproxy Statistics
  stats   auth      admin:P@ssw0rd

frontend k8s-api
    bind *:6443
    mode tcp
    option tcplog
    default_backend k8s-api

backend k8s-api
    mode tcp
    option tcplog
    option tcp-check
    balance leastconn
    default-server inter 10s downinter 5s rise 2 fall 2 slowstart 60s maxconn 250 maxqueue 256 weight 100
    server k8s-master1 10.1.61.175:6443 check
    server k8s-master2 10.1.61.176:6443 check
    server k8s-master2 10.1.61.177:6443 check

部署node节点

配置docker

使用国内的docker apt源安装docker:

sudo apt-get update
sudo apt-get -y install apt-transport-https ca-certificates curl software-properties-common
# step 2: 安装GPG证书
curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
# Step 3: 写入软件源信息
sudo add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
# Step 4: 更新并安装 Docker-CE
sudo apt-get -y update
sudo apt-get -y install docker-ce

修改/etc/docker/daemon.json配置如下:

{
    "bip": "10.1.90.1/27"
}

启动docker:

systemctl start docker
systemctl enable docker

配置quagga

# 安装
apt install quagga

# 修改/etc/quagga/daemons如下:

zebra=yes
bgpd=no
ospfd=yes
ospf6d=no
ripd=no
ripngd=no
isisd=no
babeld=no

# 修改/etc/quagga/zebra.conf配置如下:

hosname router
password zebra
enable password zebra

# 修改/etc/quagga/ospfd.conf配置如下:

hostname ospfd
password zebra
router ospf
  network 10.1.61.0/24 area 0
  network 10.1.90.0/27 area 0
  
# 启动quagga:

systemctl start quagga
systemctl enable quagga

需要说明的是,要使用quagga,必须在/etc/sysctl.conf中配置内核参数net.ipv4.ip_forward=1

配置kubelet与kube-proxy

node节点除了需要安装docker与quagga之外,还需要启动两个服务: kubelet, kube-proxy

kubelet需要前面生成的bootstrap.kubeconfig,kube-proxy需要前面生成的kube-proxy的证书及key,以及kube-proxy.kubeconfig文件,另外还需要ca的证书及key。需要先将相关文件复制到node节点的/opt/kubernetes/cfg目录下。

另外,还需要多插一嘴。kube-proxy从1.8开始引入了ipvs的负载均衡方式,在1.9里已升级为beta版,我们这里使用这种方式。而使用这种方式需要加载ip_vs模块。示例如下:

lsmod | grep ip_vs

ip_vs_sh               16384  0
ip_vs_wrr              16384  0
ip_vs_rr               16384  0
ip_vs                 151552  6 ip_vs_wrr,ip_vs_rr,ip_vs_sh
nf_conntrack          131072  9 ip_vs,xt_nat,nf_conntrack_ipv4,ipt_MASQUERADE,nf_conntrack_netlink,nf_nat_masquerade_ipv4,xt_conntrack,nf_nat_ipv4,nf_nat
libcrc32c              16384  4 ip_vs,nf_conntrack,xfs,nf_nat

如果没有看到ip_vs模块,可以通过如下方式加载:

modprobe ip_vs

同样的,前面准备工作都完成以后,也只需要修改两个服务的启动配置文件并启动即可。

kubelet的启动文件/lib/systemd/system/kubelet.service内容如下:

[Unit]
Description=Kubernetes Kubelet
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=docker.service
Requires=docker.service

[Service]
WorkingDirectory=/var/lib/kubelet
ExecStart=/opt/kubernetes/bin/kubelet 
  --eviction-hard=memory.available<100Mi,nodefs.available<10%,nodefs.inodesFree<5% 
  --address=10.1.61.178 
  --hostname-override=10.1.61.178 
  --cgroup-driver=cgroupfs 
  --pod-infra-container-image=dyhub.douyucdn.cn/kubernetes/pause-amd64:3.0 
  --experimental-bootstrap-kubeconfig=/opt/kubernetes/cfg/bootstrap.kubeconfig 
  --kubeconfig=/opt/kubernetes/cfg/kubelet.kubeconfig 
  --cert-dir=/opt/kubernetes/ssl 
  --cluster-dns=10.1.61.136 
  --cluster-domain=test01. 
  --hairpin-mode=promiscuous-bridge 
  --allow-privileged=true 
  --fail-swap-on=false 
  --serialize-image-pulls=false 
  --max-pods=60 
  --logtostderr=true 
  --v=2 
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

kube-proxy的启动文件/libe/systemd/system/kube-proxy.service内容如下:

[Unit]
Description=Kubernetes Kube-Proxy Server
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=network.target

[Service]
WorkingDirectory=/var/lib/kube-proxy
ExecStart=/opt/kubernetes/bin/kube-proxy 
  --bind-address=10.1.61.178 
  --hostname-override=10.1.61.178 
  --kubeconfig=/opt/kubernetes/cfg/kube-proxy.kubeconfig 
  --masquerade-all 
  --feature-gates=SupportIPVSProxyMode=true 
  --proxy-mode=ipvs 
  --ipvs-min-sync-period=5s 
  --ipvs-sync-period=5s 
  --ipvs-scheduler=rr 
  --logtostderr=true 
  --v=2 

Restart=on-failure
RestartSec=5
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

启动kubelet和kube-proxy:

systemctl start kubelet kube-proxy
systemctl enable kubelet kube-proxy

node节点正常启动以后,在master端执行kubectl get nodes看不到node节点,这是因为node节点启动后先向master申请证书,master签发证书以后,才能加入到集群中,如下:

# 查看 csr
➜  kubectl get csr
NAME        AGE       REQUESTOR           CONDITION
csr-l9d25   2m        kubelet-bootstrap   Pending

# 签发证书
➜  kubectl certificate approve csr-l9d25
certificatesigningrequest "csr-l9d25" approved

# 查看 node
➜  kubectl get node
NAME          STATUS    AGE       VERSION
10.1.61.140   Ready     5d        v1.7.4

部署DNS

这里就不详细说明kube-dns的部署过程了,毕竟后续版本中基本也不会再使用到了。直接贴代码:

# 获取文件
mkdir dns && cd dns
wget https://raw.githubusercontent.com/kubernetes/kubernetes/master/cluster/addons/dns/kubedns-cm.yaml
wget https://raw.githubusercontent.com/kubernetes/kubernetes/master/cluster/addons/dns/kubedns-sa.yaml
wget https://raw.githubusercontent.com/kubernetes/kubernetes/master/cluster/addons/dns/kubedns-svc.yaml.sed
wget https://raw.githubusercontent.com/kubernetes/kubernetes/master/cluster/addons/dns/kubedns-controller.yaml.sed
wget https://raw.githubusercontent.com/kubernetes/kubernetes/master/cluster/addons/dns/transforms2sed.sed

# 修改配置
cd ~/k8s/kube-dns
sed -f transforms2sed.sed kubedns-svc.yaml.base > kubedns-svc.yaml
sed -f transforms2sed.sed kubedns-controller.yaml.base > kubedns-controller.yaml

# 创建
kubectl create -f kubedns-cm.yaml
kubectl create -f kubedns-sa.yaml
kubectl create -f kubedns-svc.yaml
kubectl create -f kubedns-controller.yaml 

DNS自动扩容:

wget https://raw.githubusercontent.com/kubernetes/kubernetes/master/cluster/addons/dns-horizontal-autoscaler/dns-horizontal-autoscaler-rbac.yaml
wget https://raw.githubusercontent.com/kubernetes/kubernetes/master/cluster/addons/dns-horizontal-autoscaler/dns-horizontal-autoscaler.yaml

部署dashboard

从1.9开始,kubernetes dashboard本身就开始支持令牌授权。但我仍然更愿意在其前面加上一层http_basic授权以提升其安全性

wget https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/kubernetes-dashboard.yaml
kubectl create -f kubernetes-dashboard.yaml

在上面我创建basic_auth.csv文件时,直接给了admin用户一个system:masters组,这个组拥有超级管理员权限,如果创建用户的时候没有授权,也可以通过rbac进行授权如下:

# kubectl create clusterrolebinding login-on-dashboard-with-cluster-admin --clusterrole=cluster-admin --user=admin
clusterrolebinding "login-on-dashboard-with-cluster-admin" created

# kubectl get clusterrolebinding/login-on-dashboard-with-cluster-admin -o yaml
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  creationTimestamp: 2017-07-20T08:57:07Z
  name: login-on-dashboard-with-cluster-admin
  resourceVersion: "5363564"
  selfLink: /apis/rbac.authorization.k8s.io/v1beta1/clusterrolebindingslogin-on-dashboard-with-cluster-admin
  uid: 686a3f36-6d29-11e7-8f69-00163e1001d7
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- apiGroup: rbac.authorization.k8s.io

通过https://10.1.61.129:6443/ui访问dashboard,先通过basic认证,输入之前创建的admin的帐号和密码。然后会提示我们输入一个访问集群的kubeconfig或者一个serviceaccount的token用于访问集群。参考官方文档创建一个admin-user用户,并拿到其token。通过token的方式访问,将token填入即可。官方示例路径如下:https://github.com/kubernetes/dashboard/wiki/Creating-sample-user

我这里直接贴出创建该用户的方法:

# 创建ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kube-system

# 创建rbac授权
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: admin-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: admin-user
  namespace: kube-system


kubectl create -f admin-user.yaml
kubectl create -f admin-user.rbac.yaml

获取admin用户的token,用于令牌验证:

kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep admin-user | awk '{print $1}')

注:Kubernetes API Server新增了–anonymous-auth选项,允许匿名请求访问secure port。没有被其他authentication方法拒绝的请求即Anonymous requests, 这样的匿名请求的username为”system:anonymous”, 归属的组为”system:unauthenticated”。并且该选线是默认的。这样一来,当采用chrome浏览器访问dashboard UI时很可能无法弹出用户名、密码输入对话框,导致后续authorization失败。为了保证用户名、密码输入对话框的弹出,需要将–-anonymous-auth设置为false

部署heapster

wget https://raw.githubusercontent.com/kubernetes/heapster/master/deploy/kube-config/influxdb/grafana.yaml
wget https://raw.githubusercontent.com/kubernetes/heapster/master/deploy/kube-config/rbac/heapster-rbac.yaml
wget https://raw.githubusercontent.com/kubernetes/heapster/master/deploy/kube-config/influxdb/heapster.yaml
wget https://raw.githubusercontent.com/kubernetes/heapster/master/deploy/kube-config/influxdb/influxdb.yaml

kubectl create -f ./

heapster的部署也没什么好说的, 只是我在部署的时候遇到过一个小问题,就是部署完成后dashboard上始终不出图。检查所有pod,也都没有相关报错。后来把dashboard删掉,又重新部署下就好了。

至此,整个kubernetes 1.9的实践完成。

原文地址:https://www.cnblogs.com/breezey/p/8849395.html