K8s安装理论实战笔记
文章目录
一、准备工作
1、k8s高可用架构解析
说明:
-
Etcd主要是K-V数据库,Etcd是Kubernetes集群中的一个十分重要的组件,用于保存集群所有的网络配置和对象的状态信息。
-
K8S分为Master节点和Node节点,Master节点是控制节点控制整个集群,Node节点是用来运行pod或者容器的
-
Master节点是分为这些组件的:
Kube-APIServer :非常重要组件,是整个集群的控制单元,所有的流量都会经过APIServer,
ControllerManager :整个集群的控制器,
Scheduler :调度器,控制 pod 该调度到哪个 Node节点上
-
Node节点:
Kubelet组件运行在Node节点上,维持运行中的Pods以及提供kuberntes运行时环境。
Kube-proxy是Kubernetes的核心组件,部署在每个Node节点上,它是实现Kubernetes Service的通信与负载均衡机制的重要组件; kube-proxy负责为Pod创建代理服务,从apiserver获取所有server信息,并根据server信息创建代理服务,实现server到Pod的请求路由和转发,从而实现K8s层级的虚拟转发网络。
-
在生产环境中,若是Master节点配置够高的话,Etcd也可以部署在Master节点上;若是集群规模比较大建议把Etcd和Master节点分开来安装。
2、安装要求
在开始之前,部署Kubernetes 集群机器需要满足以下几个条件:
-
一台或多台机器,操作系统CentOS7.x-86_x64
-
硬件配置:2GB 或更多RAM,2 个CPU 或更多CPU,硬盘30GB 或更多
-
集群中所有机器之间网络互通
-
可以访问外网,需要拉取镜像
-
禁止swap 分区
注:可以购买腾讯云竞价实例
二、使用kubeadm部署工具安装
1、工具选择比较
- Kubernetes 官方工具
官方提供了多种工具来部署和管理 Kubernetes,包括 kubeadm、kops、kube-up.sh 等等。这些工具都是由 Kubernetes 社区开发和维护的,能够快速地部署 Kubernetes 集群,同时提供了一些默认配置和最佳实践。
- 云服务商提供的 Kubernetes 服务
各大云服务商都提供了 Kubernetes 服务,例如 Amazon Elastic Kubernetes Service(EKS)、Google Kubernetes Engine(GKE)、Microsoft Azure Kubernetes Service(AKS)等等。这些服务可以快速地创建和管理 Kubernetes 集群,同时还提供了一些与云服务相关的功能和优化。
例如:阿里云
1)弹性容器实例(Elastic Container Instance,简称 ECI)
2)容器服务 Kubernetes 版(Container Service for Kubernetes,简称 ACK)
3)弹性 Kubernetes 服务(Elastic Kubernetes Service,简称 EKS)
总结:ECI 是一种无服务器的容器解决方案,适用于一些简单的、无状态的应用场景;ACK 是完全托管的 Kubernetes 服务,适用于各种规模的应用场景;EKS 是基于 Kubernetes 的企业级云原生应用解决方案,适用于高可用和高性能的生产环境。
- 第三方部署工具
除了官方工具和云服务商提供的 Kubernetes 服务外,还有许多第三方工具可用于部署 Kubernetes。例如,Rancher、OpenShift、Kubespray 等等,这些工具通常提供了更多的自定义选项和功能,可以更好地适应特定的场景和需求。
2、环境配置
主机名 | 外网地址 | 内网地址 | CPU | 内存 | 磁盘 | 账号 | 密码 |
---|---|---|---|---|---|---|---|
master | - | 172.168.70.251 | 2核 | 2G | 30G | root | - |
node1 | - | 172.168.70.252 | 2核 | 2G | 30G | root | - |
node2 | - | 172.168.70.253 | 2核 | 2G | 30G | Root | - |
注意:centos版本为CentOS Linux release 7.9.2009 (Core)
3、目标要求
- 在所有节点上安装Docker 和kubeadm
- 部署Kubernetes Master
- 部署容器网络插件
- 部署Kubernetes Node,将节点加入Kubernetes 集群中
- 部署Dashboard Web 页面,可视化查看Kubernetes 资源
4、环境初始化
4.1、检查操作系统的版本
[root@master ~]# cat /etc/redhat-release
CentOS Linux release 7.9.2009 (Core)
4.2、配置网络IP
# [root@master ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens33
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=none
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=ens33
UUID=ec200b3d-b115-4044-bbec-a54b94c40b06
DEVICE=ens33
ONBOOT=yes
IPADDR=172.168.70.251
PREFIX=24
GATEWAY=172.168.70.1
DNS1=192.168.0.6
DNS2=192.168.0.7
# [root@node1 ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens33
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=none
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=ens33
UUID=26620237-22fb-45d8-a9a2-9b1cdc498bff
DEVICE=ens33
ONBOOT=yes
IPADDR=172.168.70.252
PREFIX=24
GATEWAY=172.168.70.1
DNS1=192.168.0.6
DNS2=192.168.0.7
# [root@node2 ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens33
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=none
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=ens33
UUID=44ce5375-2eed-41fa-8c31-db914ec206be
DEVICE=ens33
ONBOOT=yes
IPADDR=172.168.70.253
PREFIX=24
GATEWAY=172.168.70.1
DNS1=192.168.0.6
DNS2=192.168.0.7
4.3、主机名解析
# 主机名成解析 编辑三台服务器的/etc/hosts文件,添加下面内容
172.168.70.251 master
172.168.70.252 node1
172.168.70.253 node2
#系统分别改名字
[root@master ~]# sudo hostnamectl set-hostname (master/node1/node2)
[root@master ~]# reboot
4.3、时间同步
# 启动chronyd服务
[root@master ~]# yum install chrony
[root@master ~]# systemctl start chronyd
[root@master ~]# systemctl enable chronyd
[root@master ~]# date
4.4、禁用iptable和firewalld服务
# 1 关闭firewalld服务
[root@master ~]# systemctl stop firewalld
[root@master ~]# systemctl disable firewalld
# 2 关闭iptables服务
[root@master ~]# systemctl stop iptables
[root@master ~]# systemctl disable iptables
4.5、禁用selinux–(未操作)
# 编辑 /etc/selinux/config 文件,修改SELINUX的值为disable
# 注意修改完毕之后需要重启linux服务
SELINUX=disabled
4.6、禁用swap分区–(未操作)
# 编辑分区配置文件/etc/fstab,注释掉swap分区一行
# 注意修改完毕之后需要重启linux服务
vim /etc/fstab
注释掉 /dev/mapper/centos-swap swap
# /dev/mapper/centos-swap swap
需要reboot
4.7、配置ipvs功能
在Kubernetes中Service有两种带来模型,一种是基于iptables的,一种是基于ipvs的两者比较的话,ipvs的性能明显要高一些,但是如果要使用它,需要手动载入ipvs模块
# 1.安装ipset和ipvsadm
[root@master ~]# yum install ipset ipvsadm -y
# 2.添加需要加载的模块写入脚本文件
[root@master ~]# cat <<EOF> /etc/sysconfig/modules/ipvs.modules
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4
EOF
# 3.为脚本添加执行权限
[root@master ~]# chmod +x /etc/sysconfig/modules/ipvs.modules
# 4.执行脚本文件
[root@master ~]# /bin/bash /etc/sysconfig/modules/ipvs.modules
# 5.查看对应的模块是否加载成功
[root@master ~]# lsmod | grep -e ip_vs -e nf_conntrack_ipv4
4.8、安装docker-18.06.3-ce
# 1、切换镜像源
[root@master ~]# wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
# 2、查看当前镜像源中支持的docker版本
[root@master ~]# yum list docker-ce --showduplicates
# 3、安装特定版本的docker-ce
# 必须制定--setopt=obsoletes=0,否则yum会自动安装更高版本
[root@master ~]# yum install --setopt=obsoletes=0 docker-ce-18.06.3.ce-3.el7 -y
# 4、添加一个配置文件
#Docker 在默认情况下使用Vgroup Driver为cgroupfs,而Kubernetes推荐使用systemd来替代cgroupfs
[root@master ~]# mkdir /etc/docker
[root@master ~]# cat <<EOF> /etc/docker/daemon.json
{
"exec-opts": ["native.cgroupdriver=systemd"],
"registry-mirrors": ["https://kn0t2bca.mirror.aliyuncs.com"]
}
EOF
# 5、启动dokcer
[root@master ~]# systemctl restart docker
[root@master ~]# systemctl enable docker
出了问题时,卸载docker
#卸载依赖
sudo yum remove docker-ce docker-ce-cli containerd.io
#删除文件
sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd
4.9、安装Kubernetes组件-1.17.4
# 1、由于kubernetes的镜像在国外,速度比较慢,这里切换成国内的镜像源
# 2、编辑/etc/yum.repos.d/docker-ce.repo,添加下面的配置
[kubernetes]
name=Kubernetes
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgchech=0
repo_gpgcheck=0
gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
# 3、安装kubeadm、kubelet和kubectl,注意:--nogpgcheck不使用公钥安装
[root@master ~]# yum install --setopt=obsoletes=0 kubeadm-1.17.4-0 kubelet-1.17.4-0 kubectl-1.17.4-0 -y --nogpgcheck
# 4、配置kubelet的cgroup
#编辑/etc/sysconfig/kubelet, 添加下面的配置
KUBELET_CGROUP_ARGS="--cgroup-driver=systemd"
KUBE_PROXY_MODE="ipvs"
# 5、设置kubelet开机自启
[root@master ~]# systemctl enable kubelet
4.10、准备集群镜像
# 在安装kubernetes集群之前,必须要提前准备好集群需要的镜像,所需镜像可以通过下面命令查看
[root@master ~]# kubeadm config images list
# 下载镜像
# 此镜像kubernetes的仓库中,由于网络原因,无法连接,下面提供了一种替换方案
images=(
kube-apiserver:v1.17.4
kube-controller-manager:v1.17.4
kube-scheduler:v1.17.4
kube-proxy:v1.17.4
pause:3.1
etcd:3.4.3-0
coredns:1.6.5
)
for imageName in ${
images[@]};do
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName k8s.gcr.io/$imageName
docker rmi registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName
done
4.11、集群初始化
-
下面的操作只需要在master节点上执行即可
# 创建集群,这里注意172.168.70.251为maste节点内网地址 [root@master ~]# kubeadm init \ --apiserver-advertise-address=172.168.70.251 \ --image-repository registry.aliyuncs.com/google_containers \ --kubernetes-version=v1.17.4 \ --service-cidr=10.96.0.0/12 \ --pod-network-cidr=10.244.0.0/16 # 创建必要文件 [root@master ~]# mkdir -p $HOME/.kube [root@master ~]# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config [root@master ~]# sudo chown $(id -u):$(id -g) $HOME/.kube/config
注意⚠️:
W0308 16:51:26.593396 5578 validation.go:28] Cannot validate kube-proxy config - no validator is available W0308 16:51:26.593452 5578 validation.go:28] Cannot validate kubelet config - no validator is available
- 下面的操作只需要在node节点上执行即可
kubeadm join 172.168.70.251:6443 --token 5tmxuo.z2qfhl8sy2fqwllj \
--discovery-token-ca-cert-hash sha256:9ea5e667386115b060a972825ba7d0cca523a00de1dd5cf83c3034ec03e5679b
重新初始化问题:
#初始化遇到的问题
[root@master ~]# kubeadm init --apiserver-advertise-address=172.168.70.251 --image-repository registry.aliyuncs.com/google_containers --kubernetes-version=v1.17.17 --service-cidr=10.96.0.0/12 --pod-network-cidr=10.244.0.0/16
W0615 09:34:26.155911 6237 validation.go:28] Cannot validate kube-proxy config - no validator is available
W0615 09:34:26.155948 6237 validation.go:28] Cannot validate kubelet config - no validator is available
[init] Using Kubernetes version: v1.17.17
[preflight] Running pre-flight checks
error execution phase preflight: [preflight] Some fatal errors occurred:
[ERROR FileContent--proc-sys-net-bridge-bridge-nf-call-iptables]: /proc/sys/net/bridge/bridge-nf-call-iptables contents are not set to 1
[preflight] If you know what you are doing, you can make a check non-fatal with `--ignore-preflight-errors=...`
To see the stack trace of this error execute with --v=5 or higher
#解决方法
[root@master ~]# echo "1" >/proc/sys/net/bridge/bridge-nf-call-iptables
[root@master ~]# swapoff -a
4.12、安装网络插件,只在master节点操作
wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
连不上网的话,本地创建kube-flannel.yml文件:
---
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: psp.flannel.unprivileged
annotations:
seccomp.security.alpha.kubernetes.io/allowedProfileNames: docker/default
seccomp.security.alpha.kubernetes.io/defaultProfileName: docker/default
apparmor.security.beta.kubernetes.io/allowedProfileNames: runtime/default
apparmor.security.beta.kubernetes.io/defaultProfileName: runtime/default
spec:
privileged: false
volumes:
- configMap
- secret
- emptyDir
- hostPath
allowedHostPaths:
- pathPrefix: "/etc/cni/net.d"
- pathPrefix: "/etc/kube-flannel"
- pathPrefix: "/run/flannel"
readOnlyRootFilesystem: false
runAsUser:
rule: RunAsAny
supplementalGroups:
rule: RunAsAny
fsGroup:
rule: RunAsAny
allowPrivilegeEscalation: false
defaultAllowPrivilegeEscalation: false
allowedCapabilities: ['NET_ADMIN', 'NET_RAW']
defaultAddCapabilities: []
requiredDropCapabilities: []
hostPID: false
hostIPC: false
hostNetwork: true
hostPorts:
- min: 0
max: 65535
seLinux:
rule: 'RunAsAny'
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: flannel
rules:
- apiGroups: ['extensions']
resources: ['podsecuritypolicies']
verbs: ['use']
resourceNames: ['psp.flannel.unprivileged']
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- apiGroups:
- ""
resources:
- nodes
verbs:
- list
- watch
- apiGroups:
- ""
resources:
- nodes/status
verbs:
- patch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: flannel
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: flannel
subjects:
- kind: ServiceAccount
name: flannel
namespace: kube-system
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: flannel
namespace: kube-system
---
kind: ConfigMap
apiVersion: v1
metadata:
name: kube-flannel-cfg
namespace: kube-system
labels:
tier: node
app: flannel
data:
cni-conf.json: |
{
"name": "cbr0",
"cniVersion": "0.3.1",
"plugins": [
{
"type": "flannel",
"delegate": {
"hairpinMode": true,
"isDefaultGateway": true
}
},
{
"type": "portmap",
"capabilities": {
"portMappings": true
}
}
]
}
net-conf.json: |
{
"Network": "10.244.0.0/16",
"Backend": {
"Type": "vxlan"
}
}
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: kube-flannel-ds
namespace: kube-system
labels:
tier: node
app: flannel
spec:
selector:
matchLabels:
app: flannel
template:
metadata:
labels:
tier: node
app: flannel
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/os
operator: In
values:
- linux
hostNetwork: true
priorityClassName: system-node-critical
tolerations:
- operator: Exists
effect: NoSchedule
serviceAccountName: flannel
initContainers:
- name: install-cni-plugin
image: rancher/mirrored-flannelcni-flannel-cni-plugin:v1.1.0
command:
- cp
args:
- -f
- /flannel
- /opt/cni/bin/flannel
volumeMounts:
- name: cni-plugin
mountPath: /opt/cni/bin
- name: install-cni
image: rancher/mirrored-flannelcni-flannel:v0.18.1
command:
- cp
args:
- -f
- /etc/kube-flannel/cni-conf.json
- /etc/cni/net.d/10-flannel.conflist
volumeMounts:
- name: cni
mountPath: /etc/cni/net.d
- name: flannel-cfg
mountPath: /etc/kube-flannel/
containers:
- name: kube-flannel
image: rancher/mirrored-flannelcni-flannel:v0.18.1
command:
- /opt/bin/flanneld
args:
- --ip-masq
- --kube-subnet-mgr
resources:
requests:
cpu: "100m"
memory: "50Mi"
limits:
cpu: "100m"
memory: "50Mi"
securityContext:
privileged: false
capabilities:
add: ["NET_ADMIN", "NET_RAW"]
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: EVENT_QUEUE_DEPTH
value: "5000"
volumeMounts:
- name: run
mountPath: /run/flannel
- name: flannel-cfg
mountPath: /etc/kube-flannel/
- name: xtables-lock
mountPath: /run/xtables.lock
volumes:
- name: run
hostPath:
path: /run/flannel
- name: cni-plugin
hostPath:
path: /opt/cni/bin
- name: cni
hostPath:
path: /etc/cni/net.d
- name: flannel-cfg
configMap:
name: kube-flannel-cfg
- name: xtables-lock
hostPath:
path: /run/xtables.lock
type: FileOrCreate
4.13、使用配置文件启动fannel,在master 节点操作
kubectl apply -f kube-flannel.yml
等待它安装完毕(注意:这里需要几分钟,等等看),发现已经是 集群的状态已经是Ready
4.14、kubeadm中的命令–(未操作)
# 生成 新的token
[root@master ~]# kubeadm token create --print-join-command
5、集群测试
5.1、在master节点,创建一个nginx服务
kubectl create deployment nginx --image=nginx:1.14-alpine
5.2、在master节点暴露端口
kubectl expose deploy nginx --port=80 --target-port=80 --type=NodePort
5.3、查看服务
kubectl get pod,svc
5.4、浏览器访问
http://主机外网地址:30914/
注意:需要到腾讯云开放安全组端口
三、初步理论学习与实战
1、资源管理
- kubernetes的本质上就是一个集群系统,用户可以在集群中部署各种服务,所谓的部署服务,其实就是在kubernetes集群中运行一个个的容器,并将指定的程序跑在容器中。
- kubernetes的最小管理单元是pod而不是容器,所以只能将容器放在
Pod
中,而kubernetes一般也不会直接管理Pod,而是通过`Pod控制器来管理Pod的。
2、资源管理方式
-
命令式对象管理:直接使用命令去操作kubernetes资源
kubectl run nginx-pod --image=nginx:1.17.1 --port=80
-
命令式对象配置:通过命令配置和配置文件去操作kubernetes资源
kubectl ctreate/patch -f nginx-pod.yaml
-
声明式对象配置:通过apply命令和配置文件去操作kubernetes资源
kubectl apply -f nginx-pod.yaml
类型 | 操作对象 | 适用环境 | 优点 | 缺点 |
---|---|---|---|---|
命令式对象管理 | 对象 | 测试 | 简单 | 只能操作活动对象,无法审计、跟踪 |
命令式对象配置 | 文件 | 开发 | 可以审计、跟踪 | 项目大时,配置文件多,操作麻烦 |
声明式对象配置 | 目录 | 开发 | 支持目录操作 | 意外情况下难以调试 |
2.1、命令式对象管理
-
kubectl命令
命令:kubectl [command] [type] [name] [flags] 说明: comand:指定要对资源执行的操作,例如create、get、delete type:指定资源类型,比如deployment、pod、service name:指定资源的名称,名称大小写敏感 flags:指定额外的可选参数 示例: # 查看所有pod kubectl get pod # 查看某个pod kubectl get pod pod_name # 查看某个pod,以yaml格式展示结果 kubectl get pod pod_name -o yaml
-
资源类型
kubectl api-resources
示例:
# 创建一个namespace [root@master ~]# kubectl create namespace dev namespace/dev created # 获取namespace [root@master ~]# kubectl get ns NAME STATUS AGE default Active 21h dev Active 21s kube-node-lease Active 21h kube-public Active 21h kube-system Active 21h # 在此namespace下创建并运行一个nginx的Pod [root@master ~]# kubectl run pod --image=nginx:latest -n dev kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead. deployment.apps/pod created # 查看新创建的pod [root@master ~]# kubectl get pod -n dev NAME READY STATUS RESTARTS AGE pod 1/1 Running 0 21s # 删除指定的pod [root@master ~]# kubectl delete pod pod-864f9875b9-pcw7x pod "pod" deleted # 删除指定的namespace [root@master ~]# kubectl delete ns dev namespace "dev" deleted
2.2、命令式对象配置
-
创建一个nginxpod.yaml,内容如下:
apiVersion: v1 kind: Namespace metadata: name: dev --- apiVersion: v1 kind: Pod metadata: name: nginxpod namespace: dev spec: containers: - name: nginx-containers image: nginx:latest
-
执行create命令,创建资源:
[root@master k8s]# kubectl create -f nginxpod.yaml namespace/dev created pod/nginxpod created
-
执行get命令,查看资源:
[root@master k8s]# kubectl get -f nginxpod.yaml NAME STATUS AGE namespace/dev Active 39s NAME READY STATUS RESTARTS AGE pod/nginxpod 1/1 Running 0 38s
-
执行delete命令,删除资源:
[root@master k8s]# kubectl delete -f nginxpod.yaml namespace "dev" deleted pod "nginxpod" deleted
2.3、声明式对象配置
[root@master k8s]# kubectl apply -f nginxpod.yaml
namespace/dev created
pod/nginxpod created
[root@master k8s]# kubectl apply -f nginxpod.yaml
namespace/dev unchanged
pod/nginxpod unchanged
3、Namespace
- 它的主要作用是用来实现多套环境的资源隔离或者多租户的资源隔离
- 默认情况下,kubernetes集群中的所有的Pod都是可以相互访问的。
- 可以通过kubernetes的授权机制,将不同的namespace交给不同租户进行管理,这样就实现了多租户的资源隔离
- 查询
# 1 查看所有的ns 命令:kubectl get ns
[root@master ~]# kubectl get ns
NAME STATUS AGE
default Active 45h
kube-node-lease Active 45h
kube-public Active 45h
kube-system Active 45h
# 2 查看指定的ns 命令:kubectl get ns ns名称
[root@master ~]# kubectl get ns default
NAME STATUS AGE
default Active 45h
# 3 指定输出格式 命令:kubectl get ns ns名称 -o 格式参数
# kubernetes支持的格式有很多,比较常见的是wide、json、yaml
[root@master ~]# kubectl get ns default -o yaml
apiVersion: v1
kind: Namespace
metadata:
creationTimestamp: "2021-05-08T04:44:16Z"
name: default
resourceVersion: "151"
selfLink: /api/v1/namespaces/default
uid: 7405f73a-e486-43d4-9db6-145f1409f090
spec:
finalizers:
- kubernetes
status:
phase: Active
# 4 查看ns详情 命令:kubectl describe ns ns名称
[root@master ~]# kubectl describe ns default
Name: default
Labels: <none>
Annotations: <none>
Status: Active # Active 命名空间正在使用中 Terminating 正在删除命名空间
# ResourceQuota 针对namespace做的资源限制
# LimitRange针对namespace中的每个组件做的资源限制
No resource quota.
No LimitRange resource.
- 创建
# 创建namespace
[root@master ~]# kubectl create ns dev
namespace/dev created
- 删除
# 删除namespace
[root@master ~]# kubectl delete ns dev
namespace "dev" deleted
4、pod
- Pod是kubernetes集群进行管理的最小单元,程序要运行必须部署在容器中,而容器必须存在于Pod中。
- Pod可以认为是容器的封装,一个Pod中可以存在一个或者多个容器。
- Pause容器,这是每个Pod都会有的一个根容器,它的作用有两个:1)可以以它为依据,评估整个Pod的健康状态 2)可以在根容器上设置Ip地址,其它容器都此Ip(Pod IP),以实现Pod内部的网路通信
[root@master k8s]# kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-9d85f5447-7nlzk 1/1 Running 0 18h
coredns-9d85f5447-vp9ww 1/1 Running 0 18h
etcd-master 1/1 Running 0 18h
kube-apiserver-master 1/1 Running 0 18h
kube-controller-manager-master 1/1 Running 0 18h
kube-proxy-2g89f 1/1 Running 0 18h
kube-proxy-4w5sd 1/1 Running 0 18h
kube-proxy-hlv87 1/1 Running 0 18h
kube-scheduler-master 1/1 Running 0 18h
-
创建
# 命令格式: kubectl run (pod控制器名称) [参数] # --image 指定Pod的镜像 # --port 指定端口 # --namespace 指定namespace [root@master ~]# kubectl run nginx --image=nginx:latest --port=80 --namespace dev deployment.apps/nginx created
-
查看
# 查看Pod基本信息 [root@master ~]# kubectl get pods -n dev NAME READY STATUS RESTARTS AGE nginx 1/1 Running 0 43s # 查看Pod的详细信息 [root@master ~]# kubectl describe pod nginx -n dev Name: nginx Namespace: dev Priority: 0 Node: node1/192.168.5.4 Start Time: Wed, 08 May 2021 09:29:24 +0800 Labels: pod-template-hash=5ff7956ff6 run=nginx Annotations: <none> Status: Running IP: 10.244.1.23 IPs: IP: 10.244.1.23 Controlled By: ReplicaSet/nginx Containers: nginx: Container ID: docker://4c62b8c0648d2512380f4ffa5da2c99d16e05634979973449c98e9b829f6253c Image: nginx:latest Image ID: docker-pullable://nginx@sha256:485b610fefec7ff6c463ced9623314a04ed67e3945b9c08d7e53a47f6d108dc7 Port: 80/TCP Host Port: 0/TCP State: Running Started: Wed, 08 May 2021 09:30:01 +0800 Ready: True Restart Count: 0 Environment: <none> Mounts: /var/run/secrets/kubernetes.io/serviceaccount from default-token-hwvvw (ro) Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled True Volumes: default-token-hwvvw: Type: Secret (a volume populated by a Secret) SecretName: default-token-hwvvw Optional: false QoS Class: BestEffort Node-Selectors: <none> Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s node.kubernetes.io/unreachable:NoExecute for 300s Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled <unknown> default-scheduler Successfully assigned dev/nginx-5ff7956ff6-fg2db to node1 Normal Pulling 4m11s kubelet, node1 Pulling image "nginx:latest" Normal Pulled 3m36s kubelet, node1 Successfully pulled image "nginx:latest" Normal Created 3m36s kubelet, node1 Created container nginx Normal Started 3m36s kubelet, node1 Started container nginx
-
访问pod
# 获取podIP [root@master k8s]# kubectl get pods -n dev -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-dd6b5d745-hznst 1/1 Running 0 2m8s 10.244.1.7 node1 <none> <none> #访问POD [root@master k8s]# curl http://10.244.1.7:80 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> html { color-scheme: light dark; } body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html> [root@master k8s]#
-
删除pod
# 删除指定Pod [root@master ~]# kubectl delete pod nginx -n dev pod "nginx" deleted # 此时,显示删除Pod成功,但是再查询,发现又新产生了一个 [root@master ~]# kubectl get pods -n dev NAME READY STATUS RESTARTS AGE nginx 1/1 Running 0 21s # 这是因为当前Pod是由Pod控制器创建的,控制器会监控Pod状况,一旦发现Pod死亡,会立即重建 # 此时要想删除Pod,必须删除Pod控制器 # 先来查询一下当前namespace下的Pod控制器 [root@master ~]# kubectl get deploy -n dev NAME READY UP-TO-DATE AVAILABLE AGE nginx 1/1 1 1 9m7s # 接下来,删除此PodPod控制器 [root@master ~]# kubectl delete deploy nginx -n dev deployment.apps "nginx" deleted # 稍等片刻,再查询Pod,发现Pod被删除了 [root@master ~]# kubectl get pods -n dev No resources found in dev namespace.
5、Label
-
它的作用就是在资源上添加标识,用来对它们进行区分和选择。
-
Label的特点:
1)一个Label会以key/value键值对的形式附加到各种对象上,如Node、Pod、Service等等
2)一个资源对象可以定义任意数量的Label ,同一个Label也可以被添加到任意数量的资源对象上去
3)Label通常在资源对象定义时确定,当然也可以在对象创建后动态添加或者删除
-
基于等式的Label Selector
name = slave: 选择所有包含Label中key="name"且value="slave"的对象
env != production: 选择所有包括Label中的key="env"且value不等于"production"的对象
-
基于集合的Label Selector
name in (master, slave): 选择所有包含Label中的key="name"且value="master"或"slave"的对象
name not in (frontend): 选择所有包含Label中的key="name"且value不等于"frontend"的对象
示例:
# 为pod资源打标签
[root@master ~]# kubectl label pod nginx-dd6b5d745-jbh4l version=1.0 -n dev
pod/nginx-dd6b5d745-jbh4l labeled
# 为pod资源更新标签
[root@master ~]# kubectl label pod nginx-pod version=2.0 -n dev --overwrite
pod/nginx-pod labeled
# 查看标签
[root@master ~]# kubectl get pod nginx-pod -n dev --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx-pod 1/1 Running 0 10m version=2.0
# 筛选标签
[root@master ~]# kubectl get pod -n dev -l version=2.0 --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx-pod 1/1 Running 0 17m version=2.0
[root@master ~]# kubectl get pod -n dev -l version!=2.0 --show-labels
No resources found in dev namespace.
#删除标签
[root@master ~]# kubectl label pod nginx-pod version- -n dev
pod/nginx-pod labeled
6、Deployment
- kubernetes很少直接控制Pod,一般都是通过Pod控制器来完成的。Pod控制器用于pod的管理,确保pod资源符合预期的状态,当pod的资源出现故障时,会尝试进行重启或重建pod。在kubernetes中Pod控制器的种类有很多,本章节只介绍一种:Deployment。
示例:
# 命令格式: kubectl create deployment 名称 [参数]
# --image 指定pod的镜像
# --port 指定端口
# --replicas 指定创建pod数量
# --namespace 指定namespace
[root@master ~]# kubectl run nginx --image=nginx:latest --port=80 --replicas=3 -n dev
deployment.apps/nginx created
# 查看创建的Pod
[root@master ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
nginx-5ff7956ff6-6k8cb 1/1 Running 0 19s
nginx-5ff7956ff6-jxfjt 1/1 Running 0 19s
nginx-5ff7956ff6-v6jqw 1/1 Running 0 19s
# 查看deployment的信息
[root@master ~]# kubectl get deploy -n dev
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 3/3 3 3 2m42s
# UP-TO-DATE:成功升级的副本数量
# AVAILABLE:可用副本的数量
[root@master ~]# kubectl get deploy -n dev -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
nginx 3/3 3 3 2m51s nginx nginx:latest run=nginx
# 查看deployment的详细信息
[root@master ~]# kubectl describe deploy nginx -n dev
Name: nginx
Namespace: dev
CreationTimestamp: Wed, 08 May 2021 11:14:14 +0800
Labels: run=nginx
Annotations: deployment.kubernetes.io/revision: 1
Selector: run=nginx
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max 违规词汇
Pod Template:
Labels: run=nginx
Containers:
nginx:
Image: nginx:latest
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: nginx-5ff7956ff6 (3/3 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 5m43s deployment-controller Scaled up replicaset nginx-5ff7956ff6 to 3
# 删除
[root@master ~]# kubectl delete deploy nginx -n dev
deployment.apps "nginx" deleted
7、Service
-
虽然每个Pod都会分配一个单独的Pod IP,然而却存在如下两问题:
1)Pod IP 会随着Pod的重建产生变化
2)Pod IP 仅仅是集群内可见的虚拟IP,外部无法访问
-
Service可以看作是一组同类Pod对外的访问接口。借助Service,应用可以方便地实现服务发现和负载均衡。
7.1、创建集群内部可访问的Service
# 暴露Service
[root@master ~]# kubectl expose deploy nginx --name=svc-nginx1 --type=ClusterIP --port=80 --target-port=80 -n dev
service/svc-nginx1 exposed
# 查看service
[root@master ~]# kubectl get svc svc-nginx1 -n dev -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
svc-nginx1 ClusterIP 10.109.179.231 <none> 80/TCP 3m51s run=nginx
# 这里产生了一个CLUSTER-IP,这就是service的IP,在Service的生命周期中,这个地址是不会变动的
# 可以通过这个IP访问当前service对应的POD
[root@master ~]# curl 10.109.179.231:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
</head>
<body>
<h1>Welcome to nginx!</h1>
.......
</body>
</html>
7.2、创建集群外部也可访问的Service
# 上面创建的Service的type类型为ClusterIP,这个ip地址只用集群内部可访问
# 如果需要创建外部也可以访问的Service,需要修改type为NodePort
[root@master ~]# kubectl expose deploy nginx --name=svc-nginx2 --type=NodePort --port=80 --target-port=80 -n dev
service/svc-nginx2 exposed
# 此时查看,会发现出现了NodePort类型的Service,而且有一对Port(80:31928/TC)
[root@master ~]# kubectl get svc svc-nginx2 -n dev -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
svc-nginx2 NodePort 10.100.94.0 <none> 80:31928/TCP 9s run=nginx
# 接下来就可以通过集群外的主机访问 节点IP:31928访问服务了
# 例如在的电脑主机上通过浏览器访问下面的地址
http://192.168.90.100:31928/
7.3、删除service
[root@master ~]# kubectl delete svc svc-nginx-1 -n dev
service "svc-nginx-1" deleted
四、详细理论学习与实战
1、Pod详解
1.1、Pod定义
apiVersion: v1 #必选,版本号,例如v1
kind: Pod #必选