2021-03-21 快速部署一个Kubernetes集群

1. 生产环境部署K8s的2种方式

2. 服务器硬件配置推荐

服务器硬件配置推荐

3. 使用kubeadm快速搭建K8s集群

1、安装Docker
2、创建一个Master 节点
kubeadm init
3、将一个Node 节点加入到当前集群中
kubeadm join <Master节点的IP和端口>
4、部署容器网络(CNI)
kubectl apply -f calico.yaml
5、部署Web UI(Dashboard)

3.1 安装要求

在开始之前,部署Kubernetes集群机器需要满足以下几个条件:

  • 一台或多台机器,操作系统 CentOS7.x-86_x64
  • 硬件配置:2GB或更多RAM,2个CPU或更多CPU,硬盘30GB或更多
  • 集群中所有机器之间网络互通
  • 可以访问外网,需要拉取镜像
  • 禁止swap分区

3.2 准备环境

Kubernetes集群架构图
服务器准备

关闭防火墙:

systemctl stop firewalld
systemctl disable firewalld

关闭selinux:

sed -i 's/enforcing/disabled/' /etc/selinux/config  # 永久
setenforce 0  # 临时

关闭swap:

swapoff -a  # 临时
vim /etc/fstab  # 永久,把swap相关的配置注释掉

设置主机名:

hostnamectl set-hostname <hostname>

在master添加hosts:

cat >> /etc/hosts << EOF
192.168.9.102 k8s-master
192.168.9.103 k8s-node1
192.168.9.119 k8s-node2
EOF

将桥接的IPv4流量传递到iptables的链:

cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system  # 生效

时间同步:

yum install ntpdate -y
ntpdate time.windows.com

4. 安装Docker/kubeadm/kubelet【所有节点】

Kubernetes默认CRI(容器运行时)为Docker,因此先安装Docker。

4.1 安装Docker

wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
yum -y install docker-ce
systemctl enable docker && systemctl start docker

配置镜像下载加速器:

cat > /etc/docker/daemon.json << EOF
{
  "registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"]
}
EOF

systemctl restart docker
docker info

4.2 添加阿里云YUM软件源

$ 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

4.3 安装kubeadm,kubelet和kubectl

由于版本更新频繁,这里指定版本号部署:

$ yum install -y kubelet-1.20.0 kubeadm-1.20.0 kubectl-1.20.0
$ systemctl enable kubelet

5. 部署Kubernetes 【Master节点】

https://kubernetes.io/zh/docs/reference/setup-tools/kubeadm/kubeadm-init/#config-file
https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/#initializing-your-control-plane-node
在192.168.9.102(Master)执行。

$ kubeadm init \
  --apiserver-advertise-address=192.168.9.102 \
  --image-repository registry.aliyuncs.com/google_containers \
  --kubernetes-version v1.20.0 \
  --service-cidr=10.96.0.0/12 \
  --pod-network-cidr=10.244.0.0/16 \
  --ignore-preflight-errors=all
  • --apiserver-advertise-address 集群通告地址
  • --image-repository 由于默认拉取镜像地址k8s.gcr.io国内无法访问,这里指定阿里云镜像仓库地址
  • --kubernetes-version K8s版本,与上面安装的一致
  • --service-cidr 集群内部虚拟网络,Pod统一访问入口
  • --pod-network-cidr Pod网络,与下面部署的CNI网络组件yaml中保持一致

或者使用配置文件引导:

$ vi kubeadm.conf
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
kubernetesVersion: v1.20.0
imageRepository: registry.aliyuncs.com/google_containers 
networking:
  podSubnet: 10.244.0.0/16 
  serviceSubnet: 10.96.0.0/12 

$ kubeadm init --config kubeadm.conf --ignore-preflight-errors=all  

拷贝kubectl使用的连接k8s认证文件到默认路径:

[root@k8s-master ~]# mkdir -p $HOME/.kube
You have new mail in /var/spool/mail/root
[root@k8s-master ~]# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
[root@k8s-master ~]# sudo chown $(id -u):$(id -g) $HOME/.kube/config
[root@k8s-master ~]# kubectl get nodes
NAME         STATUS     ROLES                  AGE     VERSION
k8s-master   NotReady   control-plane,master   3m29s   v1.20.0

kubeadm init做了哪些工作?

  1. [preflight]环境检查和拉取镜像(kubeadm config images pull)
  2. [certs]创建证书目录/etc/kubernetes/pki,生成证书
  3. [kubeconfig]创建连接apiserver的配置文件目录/etc/kubernetes
  4. [kubelet-start]生成kubelet配置文件和启动
  5. [control-plane]使用静态pod启动master组件 /etc/kubernetes/mainfests
  6. [upload-config] [upload-certs] [kubelet]使用ConfigMap存储kubelet配置
  7. [mark-control-plane] 给master节点添加标签
  8. [bootstrap-token] kubelet自动申请证书机制
  9. [addons]安装插件CoreDNS和kube-proxy

6. 加入Kubernetes 【Node节点】

master创建成功后,最后面会输出以下内容:

kubeadm join 192.168.9.102:6443 --token auqu8v.0byftg2ey60hcbfb \
    --discovery-token-ca-cert-hash sha256:60262e9c944ae3f2420b221603b6b1fde91cdc8475de13120c47eb9cfa4a0d9c 
You have new mail in /var/spool/mail/root

在node1和node2节点上执行master输出的内容:

kubeadm join 192.168.9.102:6443 --token auqu8v.0byftg2ey60hcbfb \
    --discovery-token-ca-cert-hash sha256:60262e9c944ae3f2420b221603b6b1fde91cdc8475de13120c47eb9cfa4a0d9c

在master节点查看:

[root@k8s-master1 ~]# kubectl get nodes
NAME          STATUS     ROLES                  AGE   VERSION
k8s-master1   NotReady   control-plane,master   78m   v1.20.0
k8s-node1     NotReady   <none>                 44s   v1.20.0
k8s-node2     NotReady   <none>                 41s   v1.20.0

发现已经加入成功。
默认token有效期为24小时,当过期之后,该token就不可用了。这时就需要重新创建token,可以直接使用命令快捷生成:

kubeadm token create --print-join-command

7. 部署容器网络(CNI)

https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/#pod-network
注意:只需要部署下面其中一个,推荐Calico。
Calico是一个纯三层的数据中心网络方案,Calico支持广泛的平台,包括Kubernetes、OpenStack等。
Calico 在每一个计算节点利用 Linux Kernel 实现了一个高效的虚拟路由器( vRouter) 来负责数据转发,而每个 vRouter 通过 BGP 协议负责把自己上运行的 workload 的路由信息向整个 Calico 网络内传播。
此外,Calico 项目还实现了 Kubernetes 网络策略,提供ACL功能。
https://docs.projectcalico.org/getting-started/kubernetes/quickstart
下载完后还需要修改里面定义Pod网络(CALICO_IPV4POOL_CIDR),与前面kubeadm init指定的一样
修改完后应用清单(只需在master节点部署即可):

[root@k8s-master1 ~]#  wget https://docs.projectcalico.org/manifests/calico.yaml
[root@k8s-master1 ~]# vi calico.yaml  ---把下面的注释去掉,IP改成上面安装时pod-network-cidr的IP,注意格式,要对齐
             - name: CALICO_IPV4POOL_CIDR
               value: "10.244.0.0/16"
[root@k8s-master1 ~]# kubectl apply -f calico.yaml
[root@k8s-master1 ~]# kubectl get pods -n kube-system    ---可以看到在初始化中
NAME                                       READY   STATUS     RESTARTS   AGE
calico-kube-controllers-69496d8b75-9jdwp   0/1     Pending    0          5s
calico-node-djjcb                          0/1     Init:0/3   0          6s
calico-node-dt7wh                          0/1     Init:0/3   0          6s
calico-node-vms8n                          0/1     Init:0/3   0          6s
coredns-7f89b7bc75-56tcr                   0/1     Pending    0          4h14m
coredns-7f89b7bc75-hj7m6                   0/1     Pending    0          4h14m
etcd-k8s-master1                           1/1     Running    0          4h14m
kube-apiserver-k8s-master1                 1/1     Running    0          4h14m
kube-controller-manager-k8s-master1        1/1     Running    0          4h14m
kube-proxy-2955d                           1/1     Running    0          177m
kube-proxy-pl86m                           1/1     Running    0          4h14m
kube-proxy-tzwvc                           1/1     Running    0          177m
kube-scheduler-k8s-master1                 1/1     Running    0          4h14m
[root@k8s-master1 ~]# kubectl get nodes    ---等初始化完后可以看到都已经准备好了
NAME          STATUS   ROLES                  AGE     VERSION
k8s-master1   Ready    control-plane,master   5h10m   v1.20.0
k8s-node1     Ready    <none>                 3h52m   v1.20.0
k8s-node2     Ready    <none>                 3h52m   v1.20.0

8. 测试kubernetes集群

  • 验证Pod工作
  • 验证Pod网络通信
  • 验证DNS解析

在Kubernetes集群中创建一个pod,验证是否正常运行:

$ kubectl create deployment nginx --image=nginx
$ kubectl expose deployment nginx --port=80 --type=NodePort
$ kubectl get pod,svc

访问地址:http://NodeIP:Port

9. 部署 Dashboard

$ wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.3/aio/deploy/recommended.yaml -O kubernetes-dashboard.yaml

默认Dashboard只能集群内部访问,修改Service为NodePort类型,暴露到外部:

[root@k8s-master1 ~]# vi kubernertes-dashboard.yaml
...
kind: Service
apiVersion: v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
spec:
  ports:
    - port: 443
      targetPort: 8443
      nodePort: 30001
  selector:
    k8s-app: kubernetes-dashboard
  type: NodePort
...

[root@k8s-master1 ~]# kubectl apply -f kubernertes-dashboard.yaml
[root@k8s-master1 ~]# kubectl get pods -n kubernetes-dashboard
NAME                                         READY   STATUS              RESTARTS   AGE
dashboard-metrics-scraper-7b59f7d4df-9cl5f   0/1     ContainerCreating   0          7s
kubernetes-dashboard-5dbf55bd9d-b5x54        0/1     ContainerCreating   0          7s
[root@k8s-master1 ~]# kubectl get pods -n kubernetes-dashboard
NAME                                         READY   STATUS    RESTARTS   AGE
dashboard-metrics-scraper-7b59f7d4df-9cl5f   1/1     Running   0          2m9s
kubernetes-dashboard-5dbf55bd9d-b5x54        1/1     Running   0          2m9s

访问地址:https://NodeIP:30001
创建service account并绑定默认cluster-admin管理员集群角色:

创建用户:
[root@k8s-master1 ~]# kubectl create serviceaccount dashboard-admin -n kube-system
用户授权:
[root@k8s-master1 ~]# kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin
获取用户Token:
[root@k8s-master1 ~]# kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}')
Name:         dashboard-admin-token-r6k5d
Namespace:    kube-system
Labels:       <none>
Annotations:  kubernetes.io/service-account.name: dashboard-admin
              kubernetes.io/service-account.uid: 20c113e3-2cdc-4d10-939e-47c56f41ff16

Type:  kubernetes.io/service-account-token

Data
====
ca.crt:     1066 bytes
namespace:  11 bytes
token:      eyJhbGciOiJSUzI1NiIsImtpZCI6IktWeDJ1NXQ0SnZtZ09YeW56YnVxNy0wanpNZFc2VDFlQ1NBZEUwNmM4V0kifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkYXNoYm9hcmQtYWRtaW4tdG9rZW4tcjZrNWQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGFzaGJvYXJkLWFkbWluIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiMjBjMTEzZTMtMmNkYy00ZDEwLTkzOWUtNDdjNTZmNDFmZjE2Iiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Omt1YmUtc3lzdGVtOmRhc2hib2FyZC1hZG1pbiJ9.YXnU-yEQ3GKY4MSSOFulFsq4FZhhwFU8dlH-3zfXL-gejp1U_80yR7lNkKIbj28fhymePVe00b2nBHxVSbavLwIyRjzNoDv54fZx0oDxJdHk7mr8HgK0APGe0oaZFYxIAZc28-IE0ZV2P27s1fiouSspZ6be4lXVMmjAJGRmoOn0Ou_vuMjHpl66K7oubEthRZsw_cfRRbUW5D94z-rgPCnQ3fRUO14MCiQA0dA9JqGJceR9zsQv3d-3QldIPxijIbIl5jCSBwsR8GSk7XiO4zOh3jIZoCtMTifWePneWv_qsOSge3kkVs0i54-0M70ptI7Pc50NNXsxxZwn6hcnHg

使用输出的token登录Dashboard。


Dashboard主界面
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容