欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【Kubernetes】Docker + K8s 实践之路(K8s篇)

程序员文章站 2024-03-12 08:51:08
...

认识K8S(kubernetes)


定义

  • 生产级别的容器管理平台;

  • 开放的开发平台:无论哪种语言编写的服务,都可以映射到k8s的service上,并通过tcp通信协议交互;

  • 完备的分布式系统支撑平台:集群管理、安全防护、多租户应用支撑、服务注册与发现、负载均衡、故障发现与自我修复、服务升级与在线扩容、可扩展的资源自动调度、多粒度的资源配额管理;

工作方式

K8s中,Service是核心,一个Service拥有一个名字,一个虚拟IP,可以提供某种服务,且映射到一组可以提供服务的容器上;

Service通过Socket方式对外提供服务(比如Mysql、Redis、Kafka等),K8s可以让我们通过Service的虚拟IP + 端口 访问到某个Service,K8s通过负载均衡与故障恢复机制维持Service的正常运行;

pod是K8s的基本操作单元,一个pod中可以有一个或多个容器,他们共享网络与存储;提供服务的一个或多个pod会映射到Service上,具体的映射方式为给提供服务的pod贴上label,比如提供mysql服务的pod贴上 name = mysql 标签,然后给对应的Service定义Label Selector ,比如 Mysql Service的标签选择条件写为 name=mysql,从而建立Service和pod的关联;

集群分为Master节点和Worker节点,Master节点运行着集群管理相关的进程,比如kube-apiserver、kube-controller-manager和kube-scheduler,可以自动化的进行集群的资源管理、pod调度、谈性伸缩、安全控制、系统监控与错误恢复等功能;Woker节点运行kubelet、 kube-proxy等服务进程,用来实现pod的启动、创建、监控、销毁、负载均衡等;

扩容Service时,只需要给Service关联一个RC(Replication Controller),RC中定义了 目标pod的定义、目标pod需要的副本数和要监控的目标pod的Label,创建RC后,RC会根据Label监控pod,当pod实例小于需求数,则会根据RC中pod的定义生成新的pod,并调度到合适的Worker节点。

为什么使用容器

  • 快速创建、部署
  • 任何操作系统迁移
  • 资源隔离
  • 资源更高效利用

K8s工作原理

架构

一个K8S集群由 Master Node 和 Worker Node 两种节点角色 组成;

1、Master Node

  • kube-apiserver:集群对外的接口,提供一套 RESTful 的 Kubernetes API,可供客户端和其他组件调用;
  • etcd:存储集群的信息,比如配置(configmap,secret)、集群状态等,是分布式key-value数据库;
  • kube-scheduler:对集群内部的资源进行调度,分配 pod 和 service;
  • kube-controller-manager:处理集群常规任务的后台线程,负责启动和关闭pod,并维持pod在指定的状态;

2、Worker Node

  • pod:Kubernetes最基本的操作单元。一个Pod代表着集群中运行的一个进程,它内部封装了一个或多个紧密相关的容器。
  • kubelet:和 master node 通信,从 master 接收 pod 的定义,然后启动里面的容器,并监控容器是否一直正常运行;
  • kube-proxy :管理节点的网络规则,并转发连接;

3、Kubectl:命令管理工具

kubectl get - 列出资源
kubectl describe - 显示资源的详细信息
kubectl logs - 打印pod中的容器日志
kubectl exec - pod中容器内部执行命令

以下部分的参考链接:

https://purewhite.io/archives/page/3/

Service

1、作用

pod的IP是动态的,因为当pod挂了后,集群为了维持应用状态,会启动一个新的pod,此时IP发生变化;

Service 对 pod 进行逻辑分组,通过 label 和 selector 加以区分;

每个 Service 都会有一个 cluster 内部可以访问到的 ip 地址,叫做ClusterIP;

ENDPOINTS就是Service 所关联的pod的ip地址和端口,一个 Service 由一组 backend Pod 组成,这些 Pod 通过 endpoints 暴露出来;

当请求service时,Service 可以将请求转发到目标pod;

每个worker node 的 kube-proxy 则检测 API Server 上对于 Service 和 endpoint 的新增或者移除;
新增Service 时,kube-proxy会在对应的pod上写入ip转发规则,删除Service 时kube-proxy也会删除对应pod的iptables;

通过 kubernetes 上 dns 相关的 addon,可以实现service的服务发现,并赋予服务域名;

2、类型

参考链接:https://www.cnblogs.com/devilwind/p/8891636.html

Service 有 ClusterIP , NodePort , LoadBalancer,ExternalIP,ExternalName等类型;

ClusterIP :默认类型,有自己的虚拟IP,只能在集群内部被访问;

NodePort :可以被外网访问,通过暴露端口来暴露服务,一个端口对应一个服务;

Ingress:解耦路由与Service的依附,外网访问Service时,直接访问到 ingress 的 endpoint,然后通过 Ingress 再转发到 Service

Pod

kubernetes的最小对象,代表应用的一个单一实例;

定义时需要赋予 spec的值,代表期望的状态,创建后会有status字段,集群通过status和spec来维护Pod的状态;

是1个或多个容器的集合,这些容器在同一个host上、共享网络与存储;

通常和controller(Deployments,ReplicaSets) 一起用,把Pod的定义(spec)attach到controller ,来控制 pod 的 replica,容错,自我修复等等。

ConfigMap 和 Secret

当kubernetes上的应用需要读取一些配置,且这些配置有更改的可能时:

  • 如果放在镜像内,则需要创建新的镜像,并创建新的容器,很麻烦;
  • 如果通过env传入容器,则需要重启所有容器;

ConfigMap:通过命令或者yaml文件创建一个 ConfigMap 后,可以通过Volume的形式在pods中读取;

Secret:可以看作是加密后的ConfigMap,为安全性考虑。

Volume

一个 Volume 会 attach 到一个 Pod 上,在 Pod 里面网络和存储是共享的,所以这个 Volume 可以被 Pod 中所有的 container 所共享。一个 Volume 和 Pod 的生命周期是一样的,不过却比 containers 要更长,这样可以使得数据可以在容器之间共享。

网络

1、每个Pod分配独立IP

Kubernetes 用 CNI(Container Network Interface) 来给 Pod 分配 IP;容器运行时向 CNI 申请 IP,然后 CNI 通过其下面指定的 plugin 来获取到 IP,并且返回给容器运行时。

2、容器之间的通信

每个Linux 都有独立的隔离的网络整体,叫做Network Namespace,一个Pod在一个Node上,Pod里的所有容器共享该Node的Network Namespace,因此同一Pod里的容器通过localhost就可以互相访问。

3、不同Node上的Pod之间的通信

可以通过一些软件定义的网络(Software Defined Networking)实现,比如 flannel,weave,calico 等。

4、外网和集群的通信

通过kube-proxy 暴露service,供外网访问。

应用的角度了解概念

参考链接:https://zhuanlan.zhihu.com/p/100644716

一个应用的运行需要 计算资源、网络通信、工作模型、更新部署、数据持久化。

1、计算资源(pod)

docker可以提供应用需要的计算资源,比如CPU、内存、网络、基础文件系统等,但docker不能直接在k8s集群运行,k8s可以部署的最小单元是pod,pod的特点:

  • k8s 的最小计算单元;
  • 包括一个或多个容器,共享IP、hostname与存储资源;
  • 调度的最小单位,一个pod只可以放在一个机器上;
  • 一个容器一个 pod 是 k8s 最常见的场景

k8s集群不直接控制 docker,而是控制 pod,因为加入一个应用由多个容器组成,每个容器之间只需要localhost通信,如果这些容器在一个pod中,就很方便的实现容器间的localhost通信方式,微服务也是这个原理。

2、网络通信

pod 的 ip 是不固定的,挂了后重启 ip 会变,service 从逻辑上把 pod 分组,并设置访问策略,一般通过 labal 和 selector 分组;

每个 service 都有一个集群可以访问到的内部 ip 地址,当建立一个新的 service ,每个node上的 kube-proxy 会 设置 iptables 规则,删除 service 时,每个node上的 kube-proxy 也会随之删除对应的iptables。

service 的 type 有 ClusterIP 、 NodePort 、LoadBalancer 、 ExternalName 、ExternalIP 等:

  • ClusterIP:默认的service type,一个 service 通过 ClusterIP 获取唯一的 Virtual IP,只能在集群内部被访问;
  • NodePort:除了有可以供集群内部访问的 ClusterIP外,还会把所有worker node 的 30000 - 32767 之间的某个端口(可以随机或指定) 映射到这个 service ,这样不管哪个node,只要通过端口就能定位访问到这个 service ;

3、工作模型

为了方便管理多个 Pod,k8s 抽象出了几种工作模型,通过保持模型的状态,实现对 Pod 的管理

k8s 从目标状态开始,不断追踪集群现在的状态,并使其满足目标状态。如此循环,可以得到一个目标驱动的、有自治愈效果的系统。

模型类型:ReplicaSet、DaemonSet、Job、CronJob、StatefulSets:

  • ReplicaSet:保持指定个数的pod运行,适合无状态的服务,比如静态web服务器;
  • DaemonSet:保证每个宿主机上运行一个 Pod,适合节点常驻的服务,比如监控、日志收集等;
  • Job:ReplicaSet 中的pod 退出会自动重启, Job 允许进程正常退出不重启,适合指定次数的任务或定时任务,比如数据备份等;
  • CronJob:基于时间来调度和创建 Job ;
  • StatefulSets:有稳定的网络与数据存储, pod 的创建和销毁有序,适合有状态服务,比如 mysql ;

4、更新部署

Deployment 的两种更新策略:

  • Recreate:销毁并重建所有pod;
  • RollingUpdate:滚动升级;

5、数据持久化:

Persistent Volumes 子系统来实现支持(PV)

认识

虚拟化,容器化,云端化

服务器虚拟化,有太多的优势,低成本、高利用率、充分灵活、动态调度等。

优势

  • 快速部署应用
  • 快速扩展应用
  • 无缝对接新的应用功能
  • 节省资源,优化硬件资源的使用

特点

可移植: 支持公有云,私有云,混合云,多重云(multi-cloud)
可扩展: 模块化, 插件化, 可挂载, 可组合
自动化: 自动部署,自动重启,自动复制,自动伸缩/扩展

功能

  • 多个容器协同工作(pod)
  • 存储系统挂载
  • 应用健康检测
  • 应用实例复制
  • pod自动伸缩
  • 负载均衡
  • 滚动更新
  • 资源监控
  • 日志访问
  • 调试应用

K8s的安装


环境

环境
OS:ubuntu18.04
Docker:19.03.8
K8s:1.18

机器:一台Master Node,两台 Worker Node

生产化方案

多节点etcd、多节点Master Node、多节点 Worker Node:

etcd 被设置成了集群模式,并且在 kubernetes 集群之外。所有的 Node 都会连接到它上面去。所有的 master node 都被设置为 HA 模式,并且连接到所有的 worker node 上

安装方案

kubeadm:基于任何环境;
kubespray:基于ansible
kops:aws 和 gce

准备工作(三台机器)

1、如果安装了防火墙,则需要关闭防火墙

sudo ufw disable
# or
systemctl stop ufw

2、如果安装了SELINUX模块,则需要禁用SELINUX

sudo vi /etc/selinux/config
SELINUX=permissive 

3、关闭swap

sudo swapoff -a

sudo vim /etc/fstab  通过 "#" 注释掉带有swap的那行
# 或者直接使用命令  sed -i 's/.*swap.*/#&/' /etc/fstab

通过 free -h 确认swap是否为0

4、修改host

hostnamectl
hostnamectl set-hostname k8s-master
cat /etc/hosts # 120.133.xx.xxx k8s-master

5、修改cloud.cfg(可选)

sudo vim /etc/cloud/cloud.cfg

preserve_hostname: true

APT方式安装kubeadm、kubelet、kubectl(三台机器)

1、创建repo

sudo apt autoremove && sudo apt-get update && sudo apt-get install -y apt-transport-https curl

sudo curl -s https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | sudo apt-key add -

# 在/etc/apt/sources.list.d/kubernetes.list中添加aliyun的镜像地址

sudo tee /etc/apt/sources.list.d/kubernetes.list <<-'EOF'
deb https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial main
EOF

sudo apt-get update

2、安装

# 查看可安装版本
apt-cache madison kubeadm

# 安装 kubelet kubeadm kubectl
sudo apt-get install -y kubelet kubeadm kubectl

# 阻止apt-upgrade时更新安装包
sudo apt-mark hold kubelet kubeadm kubectl

# 查看 kubelet版本 和 kubeadm版本
kubelet --version
#Kubernetes v1.18.2
kubeadm version
# kubeadm version: &version.Info{Major:"1", Minor:"18", GitVersion:"v1.18.2", GitCommit:"52c56ce7a8272c798dbc29846288d7cd9fbae032", GitTreeState:"clean", BuildDate:"2020-04-16T11:54:15Z", GoVersion:"go1.13.9", Compiler:"gc", Platform:"linux/amd64"}

Master Node初始化

1、查看部署kubenetesv1.18需要的镜像

kubeadm config images list --kubernetes-version=v1.18.0
# 显示
W0515 15:52:03.567384   10706 configset.go:202] WARNING: kubeadm cannot validate component configs for API groups [kubelet.config.k8s.io kubeproxy.config.k8s.io]
k8s.gcr.io/kube-apiserver:v1.18.0
k8s.gcr.io/kube-controller-manager:v1.18.0
k8s.gcr.io/kube-scheduler:v1.18.0
k8s.gcr.io/kube-proxy:v1.18.0
k8s.gcr.io/pause:3.2
k8s.gcr.io/etcd:3.4.3-0
k8s.gcr.io/coredns:1.6.7

2、通过 docker info 命令 查看docker服务的 Cgroup Driver,如果值为 cgroupfs 则需要修改

在daemon.json中加入 “exec-opts”: [“native.cgroupdriver=systemd”]

sudo vim /etc/docekr/daemon.json
{
	"registry-mirrors": ["https://mfrhehq4.mirror.aliyuncs.com"],
	"insecure-registries": ["172.17.0.2:5000"],
	"exec-opts": ["native.cgroupdriver=systemd"],
	"log-driver": "json-file",
	"log-opts": {
		"max-size": "10m",
		"max-file": "1"
	}

}
#systemctl daemon-reload
#systemctl restart docker
#systemctl status docker

3、kubeadm 初始化 集群

通过命令:

sudo kubeadm init \
		--kubernetes-version=1.18.0  \
		--apiserver-advertise-address=120.133.17.174  \
		--image-repository registry.aliyuncs.com/google_containers  \
		--service-cidr=10.10.0.0/16 \
		--pod-network-cidr=10.122.0.0/16
  • kubernetes-version:指定k8s的版本
  • apiserver-advertise-address:API的地址,写master机器的IP
  • image-repository:镜像仓库写阿里云的仓库地址
  • service-cidr:指定service的网段
  • pod-network-cidr:指定pod的网段

或通过配置文件:

kubeadm config print init-defaults --kubeconfig ClusterConfiguration > kubeadm.yml
# 修改如下内容
advertiseAddress:120.133.xx.xxx
imageRepository: registry.aliyuncs.com/google_containers
kubernetesVersion: v1.18.0
networking:


kubeadm config images list --config kubeadm.yml
kubeadm config images pull --config kubeadm.yml

如果初始化报错,则可以通过如下命令重置并再次初始化:

sudo kubeadm reset

执行初始化命令后,可以看到初始化的步骤:

[init] Using Kubernetes version: v1.18.0
[preflight] Running pre-flight checks
[preflight] Pulling images required for setting up a Kubernetes cluster
[preflight] This might take a minute or two, depending on the speed of your internet connection
[preflight] You can also perform this action in beforehand using 'kubeadm config images pull'
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Starting the kubelet
[certs] Using certificateDir folder "/etc/kubernetes/pki"
[certs] Generating "ca" certificate and key
[certs] Generating "apiserver" certificate and key
[certs] apiserver serving cert is signed for DNS names [k8s-master kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [10.10.0.1 120.133.xx.xxx]
[certs] Generating "apiserver-kubelet-client" certificate and key
[certs] Generating "front-proxy-ca" certificate and key
[certs] Generating "front-proxy-client" certificate and key
[certs] Generating "etcd/ca" certificate and key
[certs] Generating "etcd/server" certificate and key
[certs] etcd/server serving cert is signed for DNS names [k8s-master localhost] and IPs [120.133.xx.xxx 127.0.0.1 ::1]
[certs] Generating "etcd/peer" certificate and key
[certs] etcd/peer serving cert is signed for DNS names [k8s-master localhost] and IPs [120.133.xx.xxx 127.0.0.1 ::1]
[certs] Generating "etcd/healthcheck-client" certificate and key
[certs] Generating "apiserver-etcd-client" certificate and key
[certs] Generating "sa" key and public key
[kubeconfig] Using kubeconfig folder "/etc/kubernetes"
[kubeconfig] Writing "admin.conf" kubeconfig file
[kubeconfig] Writing "kubelet.conf" kubeconfig file
[kubeconfig] Writing "controller-manager.conf" kubeconfig file
[kubeconfig] Writing "scheduler.conf" kubeconfig file
[control-plane] Using manifest folder "/etc/kubernetes/manifests"
[control-plane] Creating static Pod manifest for "kube-apiserver"
[control-plane] Creating static Pod manifest for "kube-controller-manager"
W0519 16:03:48.470893   11406 manifests.go:225] the default kube-apiserver authorization-mode is "Node,RBAC"; using "Node,RBAC"
[control-plane] Creating static Pod manifest for "kube-scheduler"
W0519 16:03:48.471779   11406 manifests.go:225] the default kube-apiserver authorization-mode is "Node,RBAC"; using "Node,RBAC"
[etcd] Creating static Pod manifest for local etcd in "/etc/kubernetes/manifests"
[wait-control-plane] Waiting for the kubelet to boot up the control plane as static Pods from directory "/etc/kubernetes/manifests". This can take up to 4m0s
[apiclient] All control plane components are healthy after 20.002150 seconds
[upload-config] Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
[kubelet] Creating a ConfigMap "kubelet-config-1.18" in namespace kube-system with the configuration for the kubelets in the cluster
[upload-certs] Skipping phase. Please see --upload-certs
[mark-control-plane] Marking the node k8s-master as control-plane by adding the label "node-role.kubernetes.io/master=''"
[mark-control-plane] Marking the node k8s-master as control-plane by adding the taints [node-role.kubernetes.io/master:NoSchedule]
[bootstrap-token] Using token: 1jyhoi.xxx
[bootstrap-token] Configuring bootstrap tokens, cluster-info ConfigMap, RBAC Roles
[bootstrap-token] configured RBAC rules to allow Node Bootstrap tokens to get nodes
[bootstrap-token] configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials
[bootstrap-token] configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token
[bootstrap-token] configured RBAC rules to allow certificate rotation for all node client certificates in the cluster
[bootstrap-token] Creating the "cluster-info" ConfigMap in the "kube-public" namespace
[kubelet-finalize] Updating "/etc/kubernetes/kubelet.conf" to point to a rotatable kubelet client certificate and key
[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: kube-proxy

Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

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

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 120.133.xx.xxx:6443 --token 1jyhoi.x8yvhnfizayfjn03 \
    --discovery-token-ca-cert-hash sha256:xxx

大概的步骤是:

准备工作(init,preflight):

  • 指定k8s版本为1.18
  • 启动前检查,并拉取建立k8s集群所需的镜像

kubelet-start:

  • 写入 kubelet 环境文件到 /var/lib/kubelet/kubeadm-flags.env
  • 写入 kubelet 配置文件到 /var/lib/kubelet/config.yaml
  • 启动 kubelet

certs:

生成Kubernetes使用的证书,存放在/etc/kubernetes/pki目录中

  • 证书路径是 /etc/kubernetes/pki
  • 生成 ca、apiserver、apiserver-kubelet-client、front-proxy-client、etcd 等的证书和**
  • apiserver、etcd 注册到 DNS和 IPs中

kubeconfig:

生成 KubeConfig 文件,存放在/etc/kubernetes目录中,组件之间通信需要使用对应文件

  • kubeconfig 的路径是 /etc/kubernetes
  • 写入 admin.conf
  • 写入 kubelet.conf
  • 写入 controller-manager.conf
  • 写入 scheduler.conf

control-plane:

使用/etc/kubernetes/manifest目录下的YAML文件,安装Master 组件

  • manifest的路径是 /etc/kubernetes/manifests
  • 为 kube-apiserver 创建静态pod
  • 为 kube-controller-manager 创建静态pod
  • 为 kube-scheduler 创建静态pod
  • 为etcd 创建静态pod,在 /etc/kubernetes/manifests
  • kubelet 启动 contral plane 作为静态pod

etcd:使用/etc/kubernetes/manifest/etcd.yaml安装Etcd服务。

wait-control-plane:等待control-plan部署的Master组件通过 kubelet 启动。

apiclient:检查Master组件服务状态。

upload-config:更新配置。

kubelet:使用 configMap “kubelet-config-1.18” 配置kubelet。

mark-control-plane:为当前节点打标签,打了角色Master,和不可调度标签,这样默认就不会使用Master节点来运行Pod。

bootstrap-token:生成token记录下来,后边使用kubeadm join往集群中添加节点时会用到。

addons:安装附加组件CoreDNS和kube-proxy。

初始化成功后的输出如下,根据这些输出继续进行配置。

Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

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

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 120.133.xx.xxx:6443 --token 1jyhoi.x8yvhnfizayfjn03 \
    --discovery-token-ca-cert-hash sha256:xxx

然后根据输出的提示,执行命令:

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

查看节点:

kubectl get node
# NAME         STATUS   ROLES    AGE     VERSION
# k8s-master   NotReady   master   3d1h   v1.18.2

kubectl get pod --all-namespaces
# kube-system   coredns-7ff77c879f-9cf2s             0/1     Pending   0          3d1h
# kube-system   coredns-7ff77c879f-mm9lf             0/1     Pending   0          3d1h
# kube-system   etcd-k8s-master                      1/1     Running   0          3d1h
# kube-system   kube-apiserver-k8s-master            1/1     Running   0          3d1h
# kube-system   kube-controller-manager-k8s-master   1/1     Running   0          3d1h
# kube-system   kube-proxy-7trp7                     1/1     Running   0          3d1h
# kube-system   kube-scheduler-k8s-master            1/1     Running   0          3d1h

kubeadm init 命令最后几行的输出:

kubeadm join 120.133.xx.xxx:6443 --token 1jyhoi.x8yvhnfizayfjn03 \
    --discovery-token-ca-cert-hash sha256:xxx

是节点加入集群需要执行的命令,这个命令中的token有效期是24小时,可以通过

kubeadm token list

查看,如果过期,则可以再次执行如下命令生成新的 token:

kubeadm token create

discovery-token-ca-cert-hash的值是不会变的,可以通过如下命令查看:

openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'

4、安装网络组件

kubectl apply -f https://docs.projectcalico.org/v3.14/manifests/calico.yaml

kubectl get node
# NAME         STATUS   ROLES    AGE     VERSION
# k8s-master   Ready    master   6d23h   v1.18.2

kubectl get pod --all-namespaces

NAMESPACE     NAME                                       READY   STATUS    RESTARTS   AGE
kube-system   calico-kube-controllers-789f6df884-cw8k6   1/1     Running   0          6m51s
kube-system   calico-node-fn2vr                          1/1     Running   0          6m51s
kube-system   coredns-7ff77c879f-9cf2s                   1/1     Running   0          6d23h
kube-system   coredns-7ff77c879f-mm9lf                   1/1     Running   0          6d23h
kube-system   etcd-k8s-master                            1/1     Running   0          6d23h
kube-system   kube-apiserver-k8s-master                  1/1     Running   0          6d23h
kube-system   kube-controller-manager-k8s-master         1/1     Running   0          6d23h
kube-system   kube-proxy-7trp7                           1/1     Running   0          6d23h
kube-system   kube-scheduler-k8s-master                  1/1     Running   0          6d23h

kubectl get cs
#NAME                 STATUS    MESSAGE             ERROR
#controller-manager   Healthy   ok                  
#scheduler            Healthy   ok                  
#etcd-0               Healthy   {"health":"true"}  

此时集群状态正常。

Worker Node 加入集群

在两台Worker Node上分别执行:

sudo kubeadm join 120.133.xx.xxx:6443 --token s7q162.xxx     --discovery-token-ca-cert-hash sha256:xxx

然后在Master Node上执行:

kubectl get nodes

#NAME          STATUS   ROLES    AGE    VERSION
#k8s-master    Ready    master   7d1h   v1.18.2
#k8s-node172   Ready    <none>   10m    v1.18.3
#k8s-node173   Ready    <none>   70s    v1.18.3

# 更详细的输出
kubectl get pod -n kube-system -o wide


# 某个节点的详细信息
kubectl describe node nodename

# 某个pod的详细信息
kubectl  describe pods podname -n  kube-system

测试

1、验证kube-apiserver, kube-controller-manager, kube-scheduler, pod network

# 部署一个 Nginx Deployment,包含两个Pod
kubectl create deployment nginx --image=nginx:alpine
# 扩容
kubectl scale deployment nginx --replicas=5
# 缩容
kubectl scale deployment nginx --replicas=3

# 检查是否成功
kubectl get pods -l app=nginx -o wide
kubectl get deployments

# 删除应用
kubectl delete deployment nginx
kubectl delete svc nginx

2、验证kube-proxy

kubectl expose deployment nginx --port=80 --type=NodePort
kubectl get services nginx
# NAME    TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
# nginx   NodePort   10.10.146.91   <none>        80:30146/TCP   4s

curl http://120.133.xx.xxx:30146

3、验证dns、pod、network

# 运行Busybox并进入交互模式
kubectl run -it curl --image=radial/busyboxplus:curl

# 出现[ [email protected]:/ ]$ 后,通过 nslookup nginx 验证DNS
nslookup nginx
# Server:    10.10.0.10
# Address 1: 10.10.0.10 kube-dns.kube-system.svc.cluster.local

# Name:      nginx
# Address 1: 10.10.146.91 nginx.default.svc.cluster.local

# 通过服务名进行访问,验证kube-proxy是否正常
curl http://nginx/
# <!DOCTYPE html>
# <html>
# ...

ctrl + p + q 退出

解除master隔离

解除集群不可以在master节点部署pods的限制

kubectl taint nodes --all node-role.kubernetes.io/master-

## 输出
node/ubuntu1 untainted

卸载集群

kubectl drain <node name> --delete-local-data --force --ignore-daemonsets
kubectl delete node <node name>
sudo kubeadm reset

参考资料


K8s部署

https://blog.51cto.com/lizhenliang/1983392

https://blog.csdn.net/Giotoolee/article/details/96305277

https://www.kubernetes.org.cn/7189.html

入门级:linux基础命令,例如:yum,ls,top,iptables网络基础知识,例如:host,bridge3.git/docker常用命令:docker run/stop/ps/commit/save/exec 这个阶段撸官方文档:Docker Documentation中级:linux 内核,namespace,cgroup深入理解Docker网络原理,借助第三工具(Flannel,Calico)搭建网络模型。深入理解Docker文件系统和存储原理。高级:这个阶段就是能能对Docker的网络模块,存储模块等模块进行调优。要对GO有一定的基础,尝试对一些部件的更改。 github地址:moby/moby

一整套编排方案,主要有涉及以下部分:

  • 配置管理(anisble,saltstack,jumperserver)
  • 持续集成和持续部署(Jenkins,git,gitlab)
  • 服务编排(k8s,swarm,mesos,rancher)
  • 网络模型(host,bridge,Flannel,Calico)
  • 服务注册(etcd)
  • 服务发现(confd)
  • 日志平台(ELK, loghub)
  • 监控平台(zabbix,cadvisor,prometheus,grafana)
  • 脚本开发(shell,python)
相关标签: 【Kubernetes】