Kubernestes 1.13手工部署

2019年6月30日 0 条评论 74 次阅读 1 人点赞

基本概念

  • 节点(Node):一个节点是一个运行 Kubernetes 中的主机。
  • 容器组(Pod):一个 Pod 对应于由若干容器组成的一个容器组,同个组内的容器共享一个存储卷(volume)。
  • 容器组生命周期(pos-states):包含所有容器状态集合,包括容器组状态类型,容器组生命周期,事件,重启策略,以及 replication controllers。
  • Replication Controllers:主要负责指定数量的 pod 在同一时间一起运行。
  • 服务(services):一个 Kubernetes 服务是容器组逻辑的高级抽象,同时也对外提供访问容器组的策略。
  • 卷(volumes):一个卷就是一个目录,容器对其有访问权限。
  • 标签(labels):标签是用来连接一组对象的,比如容器组。标签可以被用来组织和选择子对象。
  • 接口权限(accessing_the_api):端口,IP 地址和代理的防火墙规则。
  • web 界面(ux):用户可以通过 web 界面操作 Kubernetes。
  • 命令行操作(cli):kubecfg命令。

构建企业级的高可用架构

  • Kubernetes 1.13.4-rc2
  • Docker 18.06.1-ce
  • Etcd 3.3.7
  • Flanneld 0.11.0
  • calico xx.xx
  • 插件:
    • Coredns
    • Dashboard
    • Heapster (influxdb、grafana)
    • Metrics-Server
    • EFK (elasticsearch、fluentd、kibana)
  • 镜像仓库:
    • docker registry
    • harbor

主要配置策略

kube-apiserver:

  • 使用 keepalived 和 haproxy 实现 3 节点高可用;
  • 关闭非安全端口 8080 和匿名访问;
  • 在安全端口 6443 接收 https 请求;
  • 严格的认证和授权策略 (x509、token、RBAC);
  • 开启 bootstrap token 认证,支持 kubelet TLS bootstrapping;
  • 使用 https 访问 kubelet、etcd,加密通信;

kube-controller-manager:

  • 3 节点高可用;
  • 关闭非安全端口,在安全端口 10252 接收 https 请求;
  • 使用 kubeconfig 访问 apiserver 的安全端口;
  • 自动 approve kubelet 证书签名请求 (CSR),证书过期后自动轮转;
  • 各 controller 使用自己的 ServiceAccount 访问 apiserver;

kube-scheduler:

  • 3 节点高可用;
  • 使用 kubeconfig 访问 apiserver 的安全端口;

kubelet:

  • 使用 kubeadm 动态创建 bootstrap token,而不是在 apiserver 中静态配置;
  • 使用 TLS bootstrap 机制自动生成 client 和 server 证书,过期后自动轮转;
  • 在 KubeletConfiguration 类型的 JSON 文件配置主要参数;
  • 关闭只读端口,在安全端口 10250 接收 https 请求,对请求进行认证和授权,拒绝匿名访问和非授权访问;
  • 使用 kubeconfig 访问 apiserver 的安全端口;

kube-proxy:

  • 使用 kubeconfig 访问 apiserver 的安全端口;
  • 在 KubeProxyConfiguration 类型的 JSON 文件配置主要参数;
  • 使用 ipvs 代理模式;

集群插件:

  • DNS:使用功能、性能更好的 coredns;
  • Dashboard:支持登录认证;
  • Metric:heapster、metrics-server,使用 https 访问 kubelet 安全端口;
  • Log:Elasticsearch、Fluend、Kibana;
  • Registry 镜像库:docker-registry、harbor;

环境初始化

内核升级

# 查看当前的内核以及系统
[[email protected] system]# uname -r 
3.10.0-862.el7.x86_64
[[email protected] system]# cat /etc/redhat-release 
CentOS Linux release 7.5.1804 (Core) 
# 开始升级
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm
yum clean all && yum makecache
yum --disablerepo=\* --enablerepo=elrepo-kernel repolist
yum --disablerepo=\* --enablerepo=elrepo-kernel list kernel*
yum --disablerepo=\* --enablerepo=elrepo-kernel install -y kernel-lt.x86_64
yum remove kernel-tools-libs.x86_64 kernel-tools.x86_64
yum --disablerepo=\* --enablerepo=elrepo-kernel install -y kernel-lt-tools.x86_64
rpm -qa | grep kernel
# reboot 选择新的内核版本进行启动
# 升级完成后可以移除久的内核
yum remove kernel-3.10.0-862.el7.x86_64

docker安装

  • 推荐使用的版本18.09以下
yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum makecache fast
yum install -y --setopt=obsoletes=0 docker-ce-18.06.1.ce-3.el7
systemctl restart docker
systemctl enable docker

修改主机名

# 根据你的规划来命名
hostnamectl set-hostname 主机名(k8s-master-01)

关闭selinux

# 关闭 SELinux,否则后续 K8S 挂载目录时可能报错 Permission denied:
# setenforce 0
# grep SELINUX /etc/selinux/config
SELINUX=disabled

开启LVS

modprobe br_netfilter
modprobe ip_vs

关闭dnsmasq

#linux 系统开启了 dnsmasq 后(如 GUI 环境),将系统 DNS Server 设置为 127.0.0.1,这会导致 docker 容器无法解析域名,需要关闭它:
service dnsmasq stop
systemctl disable dnsmasq

关闭swap分区

swapoff -a
#防止开机自动挂载 swap 分区,可以注释 /etc/fstab 中相应的条目:
sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab

关闭防火墙

systemctl stop firewalld
systemctl disable firewalld
iptables -F &&  iptables -X &&  iptables -F -t nat &&  iptables -X -t nat
iptables -P FORWARD ACCEPT

安装相关的需要的软件

yum install -y epel-release
yum install -y conntrack ipvsadm ipset jq sysstat curl iptables libseccomp lrzsz wget tree 

本地hosts

[[email protected] system]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.42.170 k8s-master-1 master01 etcd01.k8s.io k8s-master-1.k8s.io
192.168.42.171 k8s-master-2 master02 etcd02.k8s.io k8s-master-2.k8s.io
192.168.42.172 k8s-master-3 master03 etcd03.k8s.io k8s-master-3.k8s.io
192.168.42.173 k8s-node-1
192.168.42.174 k8s-node-2

时间同步

# 调整系统 TimeZone,其他同步方式也可以
timedatectl set-timezone Asia/Shanghai

# 更新系统时间
ntpdate cn.pool.ntp.org

# 将当前的 UTC 时间写入硬件时钟
timedatectl set-local-rtc 0

# 重启依赖于系统时间的服务
systemctl restart rsyslog
systemctl restart crond

相关的系统参数调优

  • cp_tw_recycle 和 Kubernetes 的 NAT 冲突,必须关闭 ,否则会导致服务不通;
  • 关闭不使用的 IPV6 协议栈,防止触发 docker BUG;
cat > kubernetes.conf <<EOF
net.bridge.bridge-nf-call-iptables=1
net.bridge.bridge-nf-call-ip6tables=1
net.ipv4.ip_forward=1
net.ipv4.tcp_tw_recycle=0
vm.swappiness=0
vm.overcommit_memory=1
vm.panic_on_oom=0
fs.inotify.max_user_watches=89100
fs.file-max=52706963
fs.nr_open=52706963
net.ipv6.conf.all.disable_ipv6=1
net.netfilter.nf_conntrack_max=2310720
EOF

# 防止到系统启动文件中
cp kubernetes.conf  /etc/sysctl.d/kubernetes.conf
# 立即生效
sysctl -p /etc/sysctl.d/kubernetes.conf
# 挂载需要使用到的内核系统
mount -t cgroup -o cpu,cpuacct none /sys/fs/cgroup/cpu,cpuacct

创建工作目录

# 所有master节点
mkdir -p /opt/k8s/{bin,cert,tag}
mkdir -p /etc/{kubernetes,etcd}
mkdir -p /var/lib/etcd
chown -R k8s /opt/k8s
chown -R k8s /etc/kubernetes
chown -R k8s /var/lib/etcd

# 主master:
mkdir -p /etc/etcd/cert
chown -R k8s /etc/etcd/cert
mkdir -p /var/lib/etcd && chown -R k8s /etc/etcd/cert

CA认证初始化

etcd高可用集群

1.创建CA证书

cd /opt/k8s/cret/

# github上提供的CA认证的自动生成的证书使用openssl生产的
git clone https://github.com/iKubernetes/k8s-certs-generator.git

# 执行生产证书这里需要填写域名认证详情查看/etc/hosts
bash gencerts.sh etcd

# 查看证书的类型
ls
apiserver-etcd-client.crt
apiserver-etcd-client.key
ca.crt
ca.key
client.crt
client.key
peer.crt
peer.key
server.crt
server.key

2.创建启动模板

cat > /var/lib/systemd/system/etcd.service <<EOF
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target
Documentation=https://github.com/coreos

[Service]
User=k8s
Type=notify
WorkingDirectory=/var/lib/etcd/
ExecStart=/opt/k8s/bin/etcd \\
  --name="etcd01.k8s.io" \\
  --data-dir="/var/lib/etcd/" \\
  --listen-peer-urls="https://192.168.42.170:2380" \\
  --listen-client-urls="https://192.168.42.170:2379,http://127.0.0.1:2379" \\
  --initial-advertise-peer-urls="https://etcd01.k8s.io:2380" \\
  --advertise-client-urls="https://etcd01.k8s.io:2379" \\
  --initial-cluster="etcd01.k8s.io=https://etcd01.k8s.io:2380,etcd02.k8s.io=https://etcd02.k8s.io:2380,etcd03.k8s.io=https://etcd03.k8s.io:2380" \\
  --initial-cluster-token="k8s-etcd-cluster" \\
  --initial-cluster-state="new" \\
  --cert-file="/opt/k8s/cert/server.crt" \\
  --key-file="/opt/k8s/cert/server.key" \\
  --client-cert-auth="false" \\
  --trusted-ca-file="/opt/k8s/cert/ca.crt" \\
  --auto-tls="false" \\
  --peer-cert-file="/opt/k8s/cert/peer.crt" \\
  --peer-key-file="/opt/k8s/cert/peer.key" \\
  --peer-client-cert-auth="true" \\
  --peer-trusted-ca-file="/opt/k8s/cert/ca.crt" \\
  --peer-auto-tls="false" \\
Restart=on-failure
RestartSec=5
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
EOF

# 将启动文件放到指定的目录下去,并且修改相应的配置文件
# --name https://都要改 --initial-cluster 不用改
# scp -r /var/lib/systemd/system/etcd.service master02/master03:/var/lib/systemd/system/

参数详细解释

User:指定以 k8s 账户运行;
WorkingDirectory、--data-dir:指定工作目录和数据目录为 /var/lib/etcd,需在启动服务前创建这个目录;
--name:指定节点名称,当 --initial-cluster-state 值为 new 时,--name 的参数值必须位于 --initial-cluster 列表中;
--cert-file、--key-file:etcd server 与 client 通信时使用的证书和私钥;
--trusted-ca-file:签名 client 证书的 CA 证书,用于验证 client 证书;
--peer-cert-file、--peer-key-file:etcd 与 peer 通信使用的证书和私钥;
--peer-trusted-ca-file:签名 peer 证书的 CA 证书,用于验证 peer 证书;

3.启动并且查看集群状态

确保data-dir 是否存在:
mkdir -p /var/lib/etcd && chown -R k8s /var/lib/etcd
启动etcd:
systemctl daemon-reload && systemctl enable etcd && systemctl restart etcd
健康状态检查:
ETCDCTL_API=3 etcdctl \
    --endpoints=https://etcd01.k8s.io:2379 \
    --cacert=/opt/k8s/cert/ca.crt \
    --cert=/opt/k8s/cert/client.crt \
    --key=/opt/k8s/cert/client.key endpoint health

4.ETCD排错姿势

journalctl --since today | grep etcd

k8s系统组件部署

创建环境

# 创建运行者的用户及其工作目录
useradd -r kube
mkdir /var/run/kubernetes
chown kube:kube /var/run/kubernetes

创建所有的证书

# 脚本设置证书的参数
[[email protected] k8s-certs-generator]# bash gencerts.sh k8s
Enter Domain Name [ilinux.io]: k8s.io   # 验证的域名
Enter Kubernetes Cluster Name [kubernetes]: # 证书名称
Enter the IP Address in default namespace 
  of the Kubernetes API Server[10.96.0.1]:  # 一般默认都是这个网段可以做修改
Enter Master servers name[master01 master02 master03]: k8s-master-1 k8s-master-2 k8s-master-3   #根据自己的主机名进行修改

# 查看生产出来的所有的CA证书
[[email protected] k8s-certs-generator]# tree kubernetes/
kubernetes/
├── CA
│   ├── ca.crt
│   └── ca.key
├── front-proxy
│   ├── front-proxy-ca.crt
│   ├── front-proxy-ca.key
│   ├── front-proxy-client.crt
│   └── front-proxy-client.key
├── ingress
│   ├── ingress-server.crt
│   ├── ingress-server.key
│   └── patches
│       └── ingress-tls.patch
├── k8s-master-1
│   ├── auth
│   │   ├── admin.conf
│   │   ├── controller-manager.conf
│   │   └── scheduler.conf
│   ├── pki
│   │   ├── apiserver.crt
│   │   ├── apiserver-etcd-client.crt
│   │   ├── apiserver-etcd-client.key
│   │   ├── apiserver.key
│   │   ├── apiserver-kubelet-client.crt
│   │   ├── apiserver-kubelet-client.key
│   │   ├── ca.crt
│   │   ├── ca.key
│   │   ├── front-proxy-ca.crt
│   │   ├── front-proxy-ca.key
│   │   ├── front-proxy-client.crt
│   │   ├── front-proxy-client.key
│   │   ├── kube-controller-manager.crt
│   │   ├── kube-controller-manager.key
│   │   ├── kube-scheduler.crt
│   │   ├── kube-scheduler.key
│   │   ├── sa.key
│   │   └── sa.pub
│   └── token.csv
├── k8s-master-2
│   ├── auth
│   │   ├── admin.conf
│   │   ├── controller-manager.conf
│   │   └── scheduler.conf
│   ├── pki
│   │   ├── apiserver.crt
│   │   ├── apiserver-etcd-client.crt
│   │   ├── apiserver-etcd-client.key
│   │   ├── apiserver.key
│   │   ├── apiserver-kubelet-client.crt
│   │   ├── apiserver-kubelet-client.key
│   │   ├── ca.crt
│   │   ├── ca.key
│   │   ├── front-proxy-ca.crt
│   │   ├── front-proxy-ca.key
│   │   ├── front-proxy-client.crt
│   │   ├── front-proxy-client.key
│   │   ├── kube-controller-manager.crt
│   │   ├── kube-controller-manager.key
│   │   ├── kube-scheduler.crt
│   │   ├── kube-scheduler.key
│   │   ├── sa.key
│   │   └── sa.pub
│   └── token.csv
├── k8s-master-3
│   ├── auth
│   │   ├── admin.conf
│   │   ├── controller-manager.conf
│   │   └── scheduler.conf
│   ├── pki
│   │   ├── apiserver.crt
│   │   ├── apiserver-etcd-client.crt
│   │   ├── apiserver-etcd-client.key
│   │   ├── apiserver.key
│   │   ├── apiserver-kubelet-client.crt
│   │   ├── apiserver-kubelet-client.key
│   │   ├── ca.crt
│   │   ├── ca.key
│   │   ├── front-proxy-ca.crt  # 聚合层在整合第三方资源时候需要使用上的认证
│   │   ├── front-proxy-ca.key
│   │   ├── front-proxy-client.crt
│   │   ├── front-proxy-client.key
│   │   ├── kube-controller-manager.crt
│   │   ├── kube-controller-manager.key
│   │   ├── kube-scheduler.crt
│   │   ├── kube-scheduler.key
│   │   ├── sa.key
│   │   └── sa.pub
│   └── token.csv       # 令牌认证时候所属的用户名和他所在的组和ID
└── kubelet
    ├── auth
    │   ├── bootstrap.conf
    │   └── kube-proxy.conf
    └── pki
        ├── ca.crt
        ├── kube-proxy.crt
        └── kube-proxy.key

16 directories, 80 files

# 复制到相应的节点上去
cp -r k8s-master-1/* /etc/kubernetes/
scp -rp k8s-master-3/* master03:/etc/kubernetes/
scp -rp k8s-master-2/* master02:/etc/kubernetes/
# 分别到master02和master03上去执行
mv /etc/kubernetes/pki /etc/kubernetes/cert

1.apiserver

手动方式

openssl ecparam -name secp521r1 -genkey -nout -out sa.key
openssl ec -in sa.key -outform PEM -pubout -out sa.pub
chomd 0600 sa.key
# 需要定制化可以手工做,不需要则用自动生成的

生成apiserver启动文件

cat > kube-apiserver.service <<EOF
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=network.target

[Service]
ExecStart=/opt/k8s/bin/kube-apiserver \\
  --enable-admission-plugins=Initializers,NamespaceLifecycle,NodeRestriction,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota \\
  --anonymous-auth=false \\
  --advertise-address=192.168.42.170 \\
  --bind-address=0.0.0.0 \\
  --insecure-port=0 \\
  --authorization-mode=Node,RBAC \\
  --runtime-config=api/all \\
  --enable-bootstrap-token-auth \\
  --service-cluster-ip-range=10.96.0.0/12 \\
  --service-node-port-range=30000-60000 \\
  --client-ca-file=/etc/kubernetes/cert/ca.crt \\
  --etcd-cafile=/etc/etcd/cert/ca.crt \\
  --etcd-certfile=/etc/kubernetes/cert/apiserver-etcd-client.crt \\
  --etcd-keyfile=/etc/kubernetes/cert/apiserver-etcd-client.key \\
  --kubelet-client-certificate=/etc/kubernetes/cert/apiserver-kubelet-client.crt \\
  --kubelet-client-key=/etc/kubernetes/cert/apiserver-kubelet-client.key \\
  --proxy-client-cert-file=/etc/kubernetes/cert/front-proxy-client.crt \\
  --proxy-client-key-file=/etc/kubernetes/cert/front-proxy-client.key \\
  --requestheader-client-ca-file=/etc/kubernetes/cert/front-proxy-ca.crt \\
  --tls-cert-file=/etc/kubernetes/cert/apiserver.crt \\
  --tls-private-key-file=/etc/kubernetes/cert/apiserver.key \\
  --etcd-servers=https://etcd01.k8s.io:2379,https://etcd01.k8s.io:2379,https://etcd01.k8s.io:2379 \\
  --enable-swagger-ui=true \\
  --allow-privileged=true \\
  --apiserver-count=3 \\
  --audit-log-maxage=30 \\
  --audit-log-maxbackup=3 \\
  --audit-log-maxsize=100 \\
  --audit-log-path=/var/log/kube-apiserver-audit.log \\
  --event-ttl=1h \\
  --alsologtostderr=true \\
  --logtostderr=false \\
  --log-dir=/var/log/kubernetes \\
  --v=3
Restart=on-failure
RestartSec=5
Type=notify
User=k8s
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
EOF

参数关键项目解释

--experimental-encryption-provider-config:启用加密特性;
--authorization-mode=Node,RBAC: 开启 Node 和 RBAC 授权模式,拒绝未授权的请求;
--enable-admission-plugins:启用 ServiceAccount 和 NodeRestriction;
--service-account-key-file:签名 ServiceAccount Token 的公钥文件,kube-controller-manager 的 --service-account-private-key-file 指定私钥文件,两者配对使用;
--tls-*-file:指定 apiserver 使用的证书、私钥和 CA 文件。--client-ca-file 用于验证 client (kue-controller-manager、kube-scheduler、kubelet、kube-proxy 等)请求所带的证书;
--kubelet-client-certificate、--kubelet-client-key:如果指定,则使用 https 访问 kubelet APIs;需要为证书对应的用户(上面 kubernetes*.pem 证书的用户为 kubernetes) 用户定义 RBAC 规则,否则访问 kubelet API 时提示未授权;
--bind-address: 不能为 127.0.0.1,否则外界不能访问它的安全端口 6443;
--insecure-port=0:关闭监听非安全端口(8080);
--service-cluster-ip-range: 指定 Service Cluster IP 地址段;
--service-node-port-range: 指定 NodePort 的端口范围;
--runtime-config=api/all=true: 启用所有版本的 APIs,如 autoscaling/v2alpha1;
--enable-bootstrap-token-auth:启用 kubelet bootstrap 的 token 认证;
--apiserver-count=3:指定集群运行模式,多台 kube-apiserver 会通过 leader 选举产生一个工作节点,其它节点处于阻塞状态;
User=k8s:使用 k8s 账户运行;

启动apiserver

systemctl daemon-reload && systemctl start kube-apiserver.service && systmectl status kube-apiserver
netstat -lnput|grep 6443    #查看端口是否已经监听
# 进行etcd健康检查
ETCDCTL_API=3 etcdctl \
     --endpoints=https://etcd01.k8s.io:2379 \
     --cacert=/opt/k8s/cert/ca.crt \
     --cert=/opt/k8s/cert/client.crt \
     --key=/opt/k8s/cert/client.key \
     get /registry/ --prefix --keys-only

配置kubectl

[[email protected] auth]# mkdir ~/.kube
[[email protected] auth]# kubectl config view --kubeconfig=/etc/kubernetes/auth/admin.conf
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://k8s-master-1.k8s.io:6443
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    user: k8s-admin     # 当前集群的用户
  name: [email protected]
current-context: [email protected]
kind: Config
preferences: {}
users:
- name: k8s-admin
  user:
    client-certificate-data: REDACTED
    client-key-data: REDACTED

创建ClusterRoleBinding授予用户组操作的权限

# 将之前创建的共享Token的用户bootstrap和用户组绑定到内部专门做RABA授权上来
# 如果不设置会导致Node节点无法Join到master中
# 可以绑定用户也可以绑定组二选一
[[email protected] kubernetes]# cat token.csv 
e96666.837357b060f2573b,"system:bootstrapper",10001,"system:bootstrappers"
[[email protected] kubernetes]# kubectl create clusterrolebinding system:bootstrapper --user=system:bootstrapper --clusterrole=system:node-bootstrapper
clusterrolebinding.rbac.authorization.k8s.io/system:bootstrapper created

检查当前的集群信息

[[email protected] kubernetes]# kubectl get svc kubernetes
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   48m
[[email protected] kubernetes]# kubectl cluster-info
Kubernetes master is running at https://k8s-master-1.k8s.io:6443

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
[[email protected] kubernetes]# kubectl get all --all-namespaces
NAMESPACE   NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
default     service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   49m
[[email protected] kubernetes]# kubectl get componentstatuses
NAME                 STATUS      MESSAGE                                                                                     ERROR
controller-manager   Unhealthy   Get http://127.0.0.1:10252/healthz: dial tcp 127.0.0.1:10252: connect: connection refused   # 这里还没有安装
scheduler            Unhealthy   Get http://127.0.0.1:10251/healthz: dial tcp 127.0.0.1:10251: connect: connection refused   # 这里还没有安装
etcd-0               Healthy     {"health":"true"}                                                                           
etcd-2               Healthy     {"health":"true"}                                                                           
etcd-1               Healthy     {"health":"true"}                                                                           
# 注意事项
如果执行 kubectl 命令式时输出如下错误信息,则说明使用的 ~/.kube/config 文件不对,请切换到正确的账户后再执行该命令: The connection to the server localhost:8080 was refused - did you specify the right host or port? 执行 kubectl get componentstatuses 命令时,apiserver 默认向 127.0.0.1 发送请求。当 controller-manager、scheduler 以集群模式运行时,有可能和 kube-apiserver 不在一台机器上,这时 controller-manager 或 scheduler 的状态为 Unhealthy,但实际上它们工作正常。

授予kubernetes证书访问kubelet-API的权限

# 在执行 kubectl exec、run、logs 等命令时,apiserver 会转发到 kubelet。这里定义 RBAC 规则,授权 apiserver 调用 kubelet API
kubectl create clusterrolebinding kube-apiserver:kubelet-apis --clusterrole=system:kubelet-api-admin --user kubernetes

2.Controller-Manager

  • 与 kube-apiserver 的安全端口通信时;
  • 在安全端口(https,10252) 输出 prometheus 格式的 metrics;

配置文件

cat > kube-controller-manager.service <<EOF
[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/GoogleCloudPlatform/kubernetes

[Service]
ExecStart=/opt/k8s/bin/kube-controller-manager \\
  --port=10252 \\
  --secure-port=0 \\
  --bind-address=127.0.0.1 \\
  --cluster-name=kubernetes \\
  --cluster-signing-cert-file=/etc/kubernetes/cert/ca.crt \\
  --cluster-signing-key-file=/etc/kubernetes/cert/ca.key \\
  --experimental-cluster-signing-duration=8760h \\
  --root-ca-file=/etc/kubernetes/cert/ca.crt \\
  --client-ca-file=/etc/kubernetes/cert/ca.crt \\
  --cluster-cidr=10.244.0.0/16 \\
  --node-cidr-mask-size=24 \\
  --service-account-private-key-file=/etc/kubernetes/cert/sa.key \\
  --feature-gates=RotateKubeletServerCertificate=true \\
  --controllers=*,bootstrapsigner,tokencleaner \\
  --kubeconfig=/etc/kubernetes/auth/controller-manager.conf \\
  --authentication-kubeconfig=/etc/kubernetes/auth/controller-manager.conf \\
  --authorization-kubeconfig=/etc/kubernetes/auth/controller-manager.conf \\
  --horizontal-pod-autoscaler-use-rest-clients=true \\
  --horizontal-pod-autoscaler-sync-period=10s \\
  --tls-cert-file=/etc/kubernetes/cert/kube-controller-manager.crt \\
  --tls-private-key-file=/etc/kubernetes/cert/kube-controller-manager.key \\
  --use-service-account-credentials=true \\
  --allocate-node-cidrs=true \\
  --leader-elect=true \\
  --alsologtostderr=true \\
  --logtostderr=false \\
  --log-dir=/var/log/kubernetes \\
  --v=2
Restart=on
Restart=on-failure
RestartSec=5
User=k8s

[Install]
WantedBy=multi-user.target
EOF

参数详解

--port=0:关闭监听 http /metrics 的请求,同时 --address 参数无效,--bind-address 参数有效;
--secure-port=10252、--bind-address=0.0.0.0: 在所有网络接口监听 10252 端口的 https /metrics 请求;
--kubeconfig:指定 kubeconfig 文件路径,kube-controller-manager 使用它连接和验证 kube-apiserver;
--cluster-signing-*-file:签名 TLS Bootstrap 创建的证书;
--experimental-cluster-signing-duration:指定 TLS Bootstrap 证书的有效期;
--root-ca-file:放置到容器 ServiceAccount 中的 CA 证书,用来对 kube-apiserver 的证书进行校验;
--service-account-private-key-file:签名 ServiceAccount 中 Token 的私钥文件,必须和 kube-apiserver 的 --service-account-key-file 指定的公钥文件配对使用;
--service-cluster-ip-range :指定 Service Cluster IP 网段,必须和 kube-apiserver 中的同名参数一致;
--leader-elect=true:集群运行模式,启用选举功能;被选为 leader 的节点负责处理工作,其它节点为阻塞状态;
--feature-gates=RotateKubeletServerCertificate=true:开启 kublet server 证书的自动更新特性;
--controllers=*,bootstrapsigner,tokencleaner:启用的控制器列表,tokencleaner 用于自动清理过期的 Bootstrap token;
--horizontal-pod-autoscaler-*:custom metrics 相关参数,支持 autoscaling/v2alpha1;
--tls-cert-file、--tls-private-key-file:使用 https 输出 metrics 时使用的 Server 证书和秘钥;
--use-service-account-credentials=true:
User=k8s:使用 k8s 账户运行;

启动服务

# systemctl daemon-reload && systemctl enable kube-controller-manager && systemctl restart kube-controller-manager

查看集群controller-manager leader info

[[email protected] etcd]# kubectl get endpoints kube-controller-manager --namespace=kube-system -o yaml
apiVersion: v1
kind: Endpoints
metadata:
  annotations:
    control-plane.alpha.kubernetes.io/leader: '{"holderIdentity":"k8s-master-02_f114f5b9-6ee7-11e9-8b96-000c29299465","leaseDurationSeconds":15,"acquireTime":"2019-05-05T03:45:09Z","renewTime":"2019-05-05T03:45:38Z","leaderTransitions":11}'
  creationTimestamp: "2019-05-05T03:36:38Z"
  name: kube-controller-manager
  namespace: kube-system
  resourceVersion: "6536"
  selfLink: /api/v1/namespaces/kube-system/endpoints/kube-controller-manager
  uid: fd25486d-6ee6-11e9-aaef-000c29ccaf3e

[[email protected] etcd]# kubectl get componentstatuses # 检查集群状态信息

3.scheduler

配置文件信息

cat > kube-scheduler.service <<EOF
[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/GoogleCloudPlatform/kubernetes

[Service]
ExecStart=/opt/k8s/bin/kube-scheduler \\
  --address=127.0.0.1 \\
  --kubeconfig=/etc/kubernetes/auth/scheduler.conf \\
  --leader-elect=true \\
  --alsologtostderr=true \\
  --logtostderr=false \\
  --log-dir=/var/log/kubernetes \\
  --v=2
Restart=on-failure
RestartSec=5
User=k8s

[Install]
WantedBy=multi-user.target
EOF

参数详解

--address:在 127.0.0.1:10251 端口接收 http /metrics 请求;kube-scheduler 目前还不支持接收 https 请求;
--kubeconfig:指定 kubeconfig 文件路径,kube-scheduler 使用它连接和验证 kube-apiserver;
--leader-elect=true:集群运行模式,启用选举功能;被选为 leader 的节点负责处理工作,其它节点为阻塞状态;
User=k8s:使用 k8s 账户运行;

查看当前的Leader

[[email protected] system]# kubectl get endpoints kube-scheduler --namespace=kube-system -o yaml
apiVersion: v1
kind: Endpoints
metadata:
  annotations:
    control-plane.alpha.kubernetes.io/leader: '{"holderIdentity":"k8s-master-1_cac7d876-6ee9-11e9-a46c-000c29ccaf3e","leaseDurationSeconds":15,"acquireTime":"2019-05-05T03:56:58Z","renewTime":"2019-05-05T03:58:06Z","leaderTransitions":1}'
  creationTimestamp: "2019-05-05T03:55:01Z"
  name: kube-scheduler
  namespace: kube-system
  resourceVersion: "15410"
  selfLink: /api/v1/namespaces/kube-system/endpoints/kube-scheduler
  uid: 8ebfa2c2-6ee9-11e9-aaef-000c29ccaf3e

查看当前的组件信息

高可用校验

# 做到这个时候我们手动关闭k8s-master-01节点看看etcd/control-manage/scheduler是否会故障转移
# 首先先将配置文件从master01传递到其他的master节点上去
scp -r ~/.kube master02/master03:~/
# 停止master01机器
[[email protected] ~]# kubectl get pod 
Unable to connect to the server: dial tcp 192.168.42.170:6443: connect: no route to host
# 如果出现这个问题则修改配置文件vim ~/.kube/config 下图展示停止master01后集群任然高可用

4.网络组件

网络选择方案draft
flanneltrue
calicotrue
  • kubernetes 要求集群内各节点(包括 master 节点)能通过 Pod 网段互联互通。flannel 使用 vxlan 技术为各节点创建一个可以互通的 Pod 网络,使用的端口为 UDP 8472,需要开放该端口如果使用公有云
  • flannel 第一次启动时,从 etcd 获取 Pod 网段信息,为本节点分配一个未使用的 /24 段地址,然后创建 flannel.1(也可能是其它名称,如 flannel1 等) 接口
  • flannel 将分配的 Pod 网段信息写入 /run/flannel/docker 文件,docker 后续使用这个文件中的环境变量设置 docker0 网桥
  • 缺点flannel不支持网络策略

下载二进制文件

  • 下载地址版本自由选择 -> https://github.com/coreos/flannel/releases
下载地址:https://github.com/coreos/flannel/releases
wget https://github.com/coreos/flannel/releases/download/v0.11.0/flannel-v0.11.0-linux-amd64.tar.gz
tar xvf flannel-v0.11.0-linux-amd64.tar.gz
cp flanneld /opt/k8s/bin/
cp mk-docker-opts.sh  /opt/k8s/bin/

5.coredns

6.kubelet

7.kube-porxy

8.监控组件

Einic Yeo

Per Aspera Ad Astra

文章评论(0)

*

code