简介

当前kubernetes的最新版本已经到了1.16,而kubernetes官方推出的安装工具kubeadm也已经GA。本文就基于kubeadm来安装最新的kubernetes集群。

各组件示意图如下:

环境说明

部署环境:

主机名 ip地址 节点类型 系统版本
master.example.com 192.168.0.1 master、etcd centos7
node1.example.com 192.168.0.2 node centos7

相关组件版本说明:

组件 版本 说明
kubernetes 1.16.2 主程序
docker 19.03.3 容器
flannel 0.11.0 网络插件
etcd 3.3.15 数据库
coredns 1.6.2 dns组件
kubernetes-dashboard 2.0.0-beta5 web界面
ingress-nginx 0.26.1 ingress

安装

安装步骤说明:

  • 配置主机名、防火墙、yum源
  • 配置内核参数
  • 加载内核模块
  • 安装Docker
  • 安装kubelet、kubectl、kubeadm
  • 编辑kubeadm-config.yml文件
  • 安装master节点
  • 配置网络插件
  • 添加node节点
  • 安装addons之kubernetes dashboard
  • 安装ingress

准备基础环境

修改主机名:

hostnamectl set-hostname master.example.com --static
hostnamectl set-hostname node1.example.com --static

清空防火墙规则和selinux:

iptables -F
setenforce 0

设置yum源:

wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo

修改内核参数:

# cat  /etc/sysctl.conf
net.ipv.ip_forward = 1 sysctl -p

加载内核模块:


cat > /etc/sysconfig/modules/ipvs.modules <<EOF
#!/bin/bash
modprobe -- br_netfilter
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4
EOF chmod 755 /etc/sysconfig/modules/ipvs.modules && \
bash /etc/sysconfig/modules/ipvs.modules && \
lsmod | grep -E "ip_vs|nf_conntrack_ipv4"

安装docker

yum install -y yum-utils

yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

yum install -y docker-ce

mkdir /etc/docker

cat > /etc/docker/daemon.json << EOF
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "10"
},
"bip": "169.254.123.1/24",
"oom-score-adjust": -1000,
"registry-mirrors": ["https://pqbap4ya.mirror.aliyuncs.com"],
"storage-driver": "overlay2",
"storage-opts":["overlay2.override_kernel_check=true"],
"live-restore": false
}
EOF systemctl restart docker
systemctl enable docker

安装kubeadm、kubelet、kubectl

cat > /etc/yum.repos.d/kubernetes.repo <<EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF yum install -y kubelet kubeadm kubectl

配置kubeadm-config.yaml

通过如下指令创建默认的kubeadm-config.yaml文件:

kubeadm config print init-defaults  > kubeadm-config.yaml

kubeadm-config.yaml组成部署说明:

  • InitConfiguration: 用于定义一些初始化配置,如初始化使用的token以及apiserver地址等
  • ClusterConfiguration:用于定义apiserver、etcd、network、scheduler、controller-manager等master组件相关配置项
  • KubeletConfiguration:用于定义kubelet组件相关的配置项
  • KubeProxyConfiguration:用于定义kube-proxy组件相关的配置项

可以看到,在默认的kubeadm-config.yaml文件中只有InitConfiguration、ClusterConfiguration 两部分。我们可以通过如下操作生成另外两部分的示例文件:

# 生成KubeletConfiguration示例文件
kubeadm config print init-defaults --component-configs KubeletConfiguration # 生成KubeProxyConfiguration示例文件
kubeadm config print init-defaults --component-configs KubeProxyConfiguration

最终修改kubeadm-config.yaml文件如下:

apiVersion: kubeadm.k8s.io/v1beta2
bootstrapTokens:
- groups:
- system:bootstrappers:kubeadm:default-node-token
token: abcdef.0123456789abcdef
ttl: 24h0m0s
usages:
- signing
- authentication
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress: 192.168.0.1
bindPort: 6443
nodeRegistration:
criSocket: /var/run/dockershim.sock
name: master.example.com
taints:
- effect: NoSchedule
key: node-role.kubernetes.io/master
---
apiServer:
timeoutForControlPlane: 4m0s
bind-address: 172.26.159.88
secure-port: 6443
authorization-mode: Node,RBAC
runtime-config: "api/all=true"
kubelet-https: true
anonymous-auth: false
requestheader-allowd-names: ""
requestheader-extra-headers-prefix: "X-Remote-Extra-"
requestheader-group-headers: X-Remote-Group
requestheader-username-headers: X-remote-User
disable-admission-plugins: PersistentVolumeLabel
enable-admission-plugins: NodeRestriction
enable-swagger-ui: true
allow-privileged: true
audit-log-maxage: 30
audit-log-maxbackup: 3
audit-log-maxsize: 100
event-ttl: 1h
v: 2
logtostderr: true
apiVersion: kubeadm.k8s.io/v1beta2
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager:
address: 127.0.0.1
node-monitor-grace-period: 40s
node-monitor-period: 5s
pod-eviction-timeout: 1m0s
controllers: "*,bootstrapsigner,tokencleaner"
horizontal-pod-autoscaler-use-rest-clients: true
dns:
type: CoreDNS
etcd:
local:
dataDir: /var/lib/etcd
imageRepository: gcr.azk8s.cn/google_containers
kind: ClusterConfiguration
kubernetesVersion: v1.16.2
networking:
dnsDomain: cluster.local
serviceSubnet: 10.96.0.0/16
podSubnet: 10.244.0.0/16
scheduler:
leader-elect: true
address: 127.0.0.1
v: 2
logtostderr: true
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
imageRepository: gcr.azk8s.cn/google_containers
kubeProxy:
config:
featureGates:
SupportIPVSProxyMode: true
mode: ipvs
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
clusterDNS:
- 10.96.0.10

关于kubeadm-config.yaml更多配置语法参考: https://godoc.org/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2

使用kubeadm-config.yaml配置主节点:https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/control-plane-flags/

kube-proxy开启ipvs参考: https://github.com/kubernetes/kubernetes/blob/master/pkg/proxy/ipvs/README.md

kubelet的配置示例参考: https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/kubelet-integration/#configure-kubelets-using-kubeadm

部署master

安装master节点:

kubeadm init --config kubeadm-config.yaml

配置访问集群:

mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -u) $HOME/.kube/config

完成部署之后,发现两个问题:

  1. master节点一直notready
  2. coredns pod一直pending

其实这两个问题都是因为还没有安装网络插件导致的,接下来开始安装网络插件

安装flannel网络插件


wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml sed -i 's@quay.io/coreos@quay.azk8s.cn/coreos@g' kube-flannel.yml kubectl apply -f kube-flannel.yml

添加节点

生成用于添加节点的kubeadm-config.yaml文件

kubeadm config print join-defaults > kubeadm-config.yaml

# kubeadm-config.yaml内容如下:

apiVersion: kubeadm.k8s.io/v1beta2
caCertPath: /etc/kubernetes/pki/ca.crt
discovery:
bootstrapToken:
apiServerEndpoint: kube-apiserver:6443
token: abcdef.0123456789abcdef
unsafeSkipCAVerification: true
timeout: 5m0s
tlsBootstrapToken: abcdef.0123456789abcdef
kind: JoinConfiguration
nodeRegistration:
criSocket: /var/run/dockershim.sock
name: node1.example.com
taints: null

这里需要修改三个地方:

  1. apiServerEndpoint:连接apiserver的地址,即master的api地址,这里可以改为192.168.0.1:6443,如果master集群部署的话,这里需要改为集群vip地址
  2. token及tlsBootstrapToken:连接master使用的token,这里需要与master上的InitConfiguration中的token配置一致
  3. name:node节点的名称,如果使用主机名,需要确保master节点可以解析该主机名。否则的话可直接使用ip地址

添加节点:

kubeadm join --config kubeadm-config.yaml

需要说明的是,添加node节点,也可以直接使用master安装完成时给出的添加方式,类似如下:kubeadm join 192.168.0.1:6443 --token abcdef.0123456789abcdef

--discovery-token-ca-cert-hash sha256:cad3fa778559b724dff47bb1ad427bd39d97dd76e934b9467507a2eb990a50c7

安装dashboard

dashboard的github仓库地址:https://github.com/kubernetes/dashboard

代码仓库当中,有给出安装示例的相关部署文件,我们可以直接获取之后,直接部署即可:

wget https://raw.githubusercontent.com/kubernetes/dashboard/master/aio/deploy/recommended.yaml
kubectl apply -f ./recommended.yaml

默认这个部署文件当中,会单独创建一个名为kubernetes-dashboard的命名空间,并将kubernetes-dashboard部署在该命名空间下。dashboard的镜像来自docker hub官方,所以可不用修改镜像地址,直接从官方获取即可。

但是在默认情况下,dashboard并不对外开放访问端口,我这里简化操作,直接使用nodePort的方式将其端口暴露出来,修改serivce部分的定义:

kind: Service
apiVersion: v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
spec:
ports:
- port: 443
targetPort: 8443
nodePort: 32443
type: NodePort
selector:
k8s-app: kubernetes-dashboard

重新创建service:

kubectl delete svc kubernetes-dashboard -n kubernetes-dashboard
kubectl apply -f ./recommended.yaml

此时,即可通过浏览器访问web端,端口为32443:

可以看到出现如上图画面,需要我们输入一个kubeconfig文件或者一个token。事实上在安装dashboard时,也为我们默认创建好了一个serviceaccount,为kubernetes-dashboard,并为其生成好了token,我们可以通过如下指令获取该sa的token:

 kubectl describe secret -n kubernetes-dashboard $(kubectl get secret -n kubernetes-dashboard |grep  kubernetes-dashboard-token | awk '{print $1}') |grep token | awk '{print $2}'

 eyJhbGciOiJSUzI1NiIsImtpZCI6IkUtYTBrbU44TlhMUjhYWXU0VDZFV1JlX2NQZ0QxV0dPRjBNUHhCbUNGRzAifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291eeeeeeLWRhc2hib2FyZC10b2tlbi1rbXBuMiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFxxxxxxxxxxxxxxxxxxxxxxxGZmZmYxLWJhOTAtNDU5Ni1hMzgxLTRhNDk5NzMzYWI0YiIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDprdWJlcm5ldGVzLWRhc2hib2FyZDprdWJlcm5ldGVzLWRhc2hib2FyZCJ9.UwAsemOra-EGl2OzKc3lur8Wtg5adqadulxH7djFpmpWmDj1b8n1YFiX-AwZKSbv_jMZd-mvyyyyyyyyyyyyyyyMYLyVub98kurq0eSWbJdzvzCvBTXwYHl4m0RdQKzx9IwZznzWyk2E5kLYd4QHaydCw7vH26by4cZmsqbRkTsU6_0oJIs0YF0YbCqZKbVhrSVPp2Fw5IyVP-ue27MjaXNCSSNxLX7GNfK1W1E68CrdbX5qqz0-Ma72EclidSxgs17T34p9mnRq1-aQ3ji8bZwvhxuTtCw2DkeU7DbKfzXvJw9ENBB-A0fN4bewP6Og07Q

通过该token登入集群以后,发现很多namespace包括一些其他的资源都没有足够的权限查看。这是因为默认我们使用的这个帐户只有有限的权限。我们可以通过对该sa授予cluster-admin权限来解决这个问题:

修改ClusterRoleBinding资源内容如下:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: kubernetes-dashboard
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: kubernetes-dashboard
namespace: kubernetes-dashboard

重新创建clusterrolebinding:

kubectl delete clusterrolebindgin  kubernetes-dashboard -n kubernetes-dashboard
kubectl apply -f ./recommended.yaml

此时,kubernetes-dashboard相关配置即完成。

部署ingress

ingress提供外部访问kubernetes内部应用的入口。社区提供众多的组件实现,这里就直接使用官方的ingress-nginx组件。

github仓库地址:

和dashboard一样,代码仓库当中也提供部署文件示例,我们直接获取即可:

wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml

获取到部署文件之后,还需要改两个东西:

  1. 替换镜像地址
sed -i 's/quay.io/quay.azk8s.cn/g' mandatory.yaml
  1. 默认ingress会监听在80和443端口,我们需要让其监听在宿主机的80和443上,以实现外部访问,修改deployment资源,添加一个hostNetwork: true配置项:
...
hostNetwork: true
containers:
- name: nginx-ingress-controller
image: quay.azk8s.cn/kubernetes-ingress-controller/nginx-ingress-controller:0.26.1
args:
- /nginx-ingress-controller
- --configmap=$(POD_NAMESPACE)/nginx-configuration
- --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
- --udp-services-configmap=$(POD_NAMESPACE)/udp-services
- --publish-service=$(POD_NAMESPACE)/ingress-nginx
- --annotations-prefix=nginx.ingress.kubernetes.io
...

部署:

kubectl apply -f ./mandatory.yaml

同样的,该文件会创建一个名为ingress-nginx的命名空间,并部署ingress-nginx pod至该命名空间下。

[root@master ~]# kubectl get pods -n ingress-nginx
NAME READY STATUS RESTARTS AGE
nginx-ingress-controller-8fbcc4d76-vvgj5 1/1 Running 0 3m9s

默认情况下,ingress容器可随意在节点间调度,这样其实也存在一个问题,作为外部的访问入口,如果无法确定ingress容器所在的节点ip,则等于找不到入口。一个有效的解决方法是通过打标签的方式将ingress固定在特定的节点上,并且通过污点和容忍将这些特定节点上的其他应用排干,只用于入口流量转发

重置集群

下面给出重置集群的方法:

kubeadm reset
ifconfig cni0 down
ip link delete cni0
ifconfig flannel.1 down
ip link delete flannel.1
rm -rf /var/lib/cni/

最新文章

  1. 10款免费而优秀的图表JS插件
  2. AngularJS快速入门指南16:Bootstrap
  3. haproxy 安装 各个参数的测试
  4. zzy:java采用的是16位的Unicode字符集作为编码方式------理解
  5. 工作中遇到的问题--eclipse没有方法提示
  6. jodd-StringTemplateParser使用
  7. XtraBackup原理4
  8. LeetCode: Populating Next Right Pointer in Each Node
  9. libthrift0.9.0解析(一)之TServer
  10. [转]IBInspectable / IBDesignable
  11. react-native 环境配置及hello world
  12. 代码静态分析工具PC-LINT安装配置
  13. ACTION_NAME等常量 不能在模板里直接取值?
  14. jquery 实时监听输入框值变化方法
  15. glide:4.7.1 与 26.1.0冲突
  16. 【tmos】SpringBoot+WebSocket打包时候的注意点
  17. ebs 12.1.1打中文补丁
  18. AJAX 实战【三级联动】分析
  19. django学习之——创建项目
  20. 【mysql】字段支持JSON类型

热门文章

  1. Spring Boot MVC 使用 JSP 作为模板
  2. JVM底层原理及调优之笔记一
  3. 关于css中布局遇到的一些问题
  4. Jsp调用淘宝IP地址库获取来访IP详细信息
  5. Java中关于数据类型的一些问题
  6. vnc服务器和windows2012密钥
  7. 分母为0的坑(float)
  8. pytest文档29-allure-pytest(最新最全,保证能搞成功!)
  9. Exception in createBlockOutputStream
  10. maxima已知方程,计算结果