K8S

Kubernetes

参考:序言 · Kubernetes指南 (gitbooks.io)

Kubernetes,简称k8s,也是容器编排工具,功能上与Swarm相同。在前期时,Docker一直以Swarm为主,后面将逐步过渡至k8s上。

Kubernetes由谷歌制作,因此国内可能会无法访问。

Kubernetes的重要人物,通过该页面可以查看一些关于Kubernetes的介绍。

Kubernetes Playground,通过该页面可以不安装Kubernetes就可以使用。

架构

Kubernetes也分为两种角色:Master节点与Node节点。

Master主要包含:

  • API Server:是外界访问集群的接口;
  • Scheduler:是均衡调度容器的模块;
  • Controller:控制容器的伸缩;
  • etcd:分布式存储。

Node主要包含:

  • Pod:是调度的最基本单位,是具有相同(network) namespace的容器的组合。
  • Docker:也可以使用其他容器技术,这里使用Docker。
  • kubelet:是Master控制节点的接口,负责管理Pod。
  • kube-proxy:负责负载均衡,端口转发等功能。
  • Fluentd:查询与采集日志。
  • Optional Add-ons: DNS, UI, etc.

另外还有Image Registry负责保存Image。

创建单节点Kubernetes集群

Minikube:
安装教程
使用教程
示例

其他参考:
Ubuntu 安装 KVM
安装kubectl工具

以下过程为基于Ubuntu的,其他系统自行参考。

首先安装kubectl工具:

1
2
3
4
5
6
7
8
9
10
11
# 下载kubectl工具
curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectl

# 修改为可执行文件
chmod +x ./kubectl

# 将文件放置到环境变量bin中
sudo mv ./kubectl /usr/local/bin/kubectl

# 查看版本信息
kubectl version --client

可以使用Minikube创建单节点Kubernetes集群。首先安装Minikube(Ubuntu):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 下载安装Minikube
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 \
&& sudo install minikube-linux-amd64 /usr/local/bin/minikube

# 查看是否支持虚拟化
egrep -q 'vmx|svm' /proc/cpuinfo && echo yes || echo no

# 使用VirtualBox作为驱动启动集群
minikube start --vm-driver=virtualbox

# 配置VirtualBox为默认驱动
minikube config set vm-driver virtualbox

# 也可以使用KVM作为驱动启动集群
minikube start --vm-driver=kvm2

下面开始创建单节点集群:

1
2
3
4
5
6
7
8
9
10
11
12
# 创建集群
minikube start
# 查看集群配置
kubectl config view
# 查看context,每一个context表示一种配置
kubectl config get-contexts
# 配置minikube
kubectl config use-context minikube
# 查看集群情况
kubectl cluster-info
# 登录虚拟机
minikube ssh

Pod

Pod是调度的最基本单位,一个Pod拥有一个IP,并且可以包含Volume,Container等,它们之间可以通过localhost相互访问,就像是一台机器上的两个进程相互访问。

这里创建一个pod_nginx.yml脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: v1
kind: Pod

metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80

下面是一些常用命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
# 创建这个Pod:
kubectl create -f pod_nginx.yml
# 删除Pod:
kubectl delete -f pod_nginx.yml
# 查看部署的Pod:
# -o wide 可以显示详细信息
kubectl get pods -o wide
# 进入第一个Pod,-c表示第几个,不加表示默认的第一个
kubectl exec -it nginx -c 1 sh
# 查看Pod的详细信息
kubectl describe pods nginx
# 映射集群端口到本地,格式 本地端口:集群端口
kubectl port-forward nginx 8080:80

Replicate

首先创建一个文件rs_nginx.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
appVersion: v1
# 如果是高版本,可以用ReplicaSet
kind: ReplicationController
metadata:
name: nginx
spec:
replicas: 3
selector:
app: nginx
template:
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80

创建Replicate并可以做如下实验:

1
2
3
4
5
6
7
8
9
# 创建Replicate
kubectl create -f rs_nginx.yml
# 查看Replicate
kubectl get rc
# 查看内部的Pod
kubectl get pods
# 删除单个Pod,pod_name可以用get pods查看
kubectl delete pods pod_name
# 删除后会发现会有新的Pod被创建

如果要扩展Pod数量(或收缩Pod数量):

1
kubectl scale rc nginx --replicas=4

最后删除Replicate:

1
kubectl delete -f rc_nginx.yml

关于ReplicaSet,可以参考如下文档:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: nginx
labels:
tier: frontend
spec:
replicas: 3
selector:
matchLabels:
tier: frontend
template:
metadata:
name: nginx
labels:
tier: frontend
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80

扩展的时候使用

1
kubectl scale rs nginx --replicas=4

Deployment

Deployment指明了我们期望创建的集群,以及相应容器的版本,而其他内容则全部交给Kubernetes来实现。使用Deployment可以实现版本升级。

首先创建deployment_nginx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
appVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
container:
- name: nginx
image: nginx:1.12.2
ports:
- containerPort: 80
1
2
3
4
5
6
7
8
# 创建
kubectl create -f deployment_nginx.yml
# 查看deployment,-o wide表示更多信息
kubectl get deployment -o wide
# 查看ReplicaSet
kubectl get rs
# 查看Pods
kubectl get pods

更新升级Deployment:

1
2
3
4
5
kubectl set image deployment nginx-deployment nginx=nginx:1.13
# 再次查看deployment,可以发现nginx已经更新
kubectl get deployment -o wide
# 查看更新日志
kubectl rollout history deployment nginx-deployment

撤销更新

1
kubectl rollout undo deployment nginx-deployment

创建多节点Kubernetes集群

创建多节点Kubernetes集群,可以使用kubeadm,kops或是Tectonic(10 Nodes以内免费)。这里使用Tectonic(基于Vagrant)。

Tectonic官网
Tectonic Sandbox Github页 非官方

安装好Tectonic后,配置Tectonic与minikube并存可以到kubernetes官网查看Configure Access to Multiple Clusters

查看Node:

1
kubectl get node

可以看到刚刚创建的两个Node,即两个虚拟机。

集群使用的网络插件可以在此页查看。

Service

Service主要有三种类型:

  • ClusterIP:只有集群内部可以访问的IP。
  • NodePort:可以对外提供访问。
  • LoadBalancer:由服务商(阿里云,腾讯云)提供,可以让我们将服务交给服务商管理。

ClusterIP

1
2
3
4
5
# 对外暴露Pod端口,默认是ClusterIP
kybectl expose pods nginx-pod
# 查看服务
kybectl get svc
# 这样可以在集群内部访问Pod提供的服务

创建文件deployment_python_http.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: service-test
spec:
replicas: 2
selector:
matchLables:
app: service_test_pod
template:
metadata:
labels:
app: service_test_pod
spec:
containers:
- name: simple-http
image: python:2.7
imagePullPolicy: IfNotPresent
command: ["/bin/bash"]
args: ["-c", "echo \" <p>Hello from $(hostname)</p>\" > index.html; python -m SimpleHTTPServer 8080"]
ports:
- name: http
containerPort: 8080

创建Department:

1
2
3
4
5
6
# 创建Deployment
kybectl create -f deployment_python_http.yml
# 创建服务
kubectl expose deployment service-test
# 查看服务
kubectl get svc

下面编辑yml文件,准备更新:

1
kubectl edit deployment service-test

更改echo内容,保存退出,Pod就被更新了。

1
2
# 删除服务
kubectl delete services nginx-deployment

NodePort

创建文件pod_nginx.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx-container
image: nginx
ports:
- name: nginx-port
containerPort: 80

创建Pod:

1
kubectl create -f pod_nginx.yml

为Pod指定服务:

1
2
3
kubectl expose pods nginx-pod --type=NodePort
# 查看服务
kubectl get svc

这样就可以通过Node访问到服务了。但是一但Pod被关闭,服务就无法使用了。因此可以使用下面的方法:

创建service_nginx.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
ports:
- port: 32333 # 此两处必须介于30000到32768
nodePort: 32333
targetPort: nginx-port
protocol: TCP
selector:
app: nginx
type: NodePort

开启服务:

1
kubectl create -f service_nginx.yml

之后就可以访问了。

kops

kops是Kubernetes自己开发的用于生产环境的工具。

kops Github页面

安装方法:

1
2
3
curl -LO https://github.com/kubernetes/kops/releases/download/$(curl -s https://api.github.com/repos/kubernetes/kops/releases/latest | grep tag_name | cut -d '"' -f 4)/kops-linux-amd64
chmod +x kops-linux-amd64
sudo mv kops-linux-amd64 /usr/local/bin/kops

建立集群:

1
kops create cluster --node-count=2 --name=k8s

删除集群:

1
kops delete cluster --name=k8s --yes

架构

image-20211128152526212

API Server

K8S 的Rest接口,所有组件都来访问这个。

Controller Manager

维持副本期望数目。

Scheduler

接受任务,选择节点分配任务。

ETCD

分布式键值数据库,Rest接口。

Kubelet

操作 容器,维持Pod生命周期

KubeProxy

写入规则到 iptables,ipvs 实现服务映射。

CoreDNS

可以为集群中的SVC创建A记录。

Ingress Controller

实现七层代理。官方只有四层代理。

Fedetation

提供多K8S统一管理。

Dashboard

提供K8S访问接口。

Prometheus

提供K8S监控。

ELK

提供K8S集群日志统一分析平台。

控制器

ReplicationController - 始终保持Pod为用户定义数量,多删少补。

ReplicaSet - 同ReplicationController,建议使用ReplicaSet。支持集合式Selector(根据Pod Label匹配)。命令式:使用create启动。

Deployment - 自动管理ReplicaSet和Pot,支持滚动更新,回滚,扩容,缩容,暂停,继续。声明式:使用apply启动。

DaemonSet - 确保某些Node上运行一个Pod副本。会根据Node加入和离开动态创建Pod。守护进程、运行监控、日志、集群存储。

Job - 负责批处理任务,仅执行一次。如果退出代码非 0 会重新执行。

Cron Job - 基于时间的Job。

StatefulSet - 解决有状态服务问题。场景:持久化存储、命名网络、有序部署、有序扩展、有序收缩。

HPA - 支持根据资源使用率伸缩集群节点数量。可以控制控制器。

网络通信方式

同一个Pod内部使用Localhost访问。

所有Pod可以通过对方IP直接访问(Overlay)。采用Flanneld。

Pod与Service采用iptables、Lvs方式等。

Pod到外网,使用Stun。

外网访问Pod,使用Service。

安装

官方安装教程:安装 kubeadm | Kubernetes

Master x 1 + Node x 2 + Harbor(镜像仓库) + Router(软路由,采用koolshare)。

创建以上5台虚拟机。

网络架构

主机网络 -> Koolshare -> K8s x 3

设置主机名、MAC、Host文件、UUID,保证相互访问。

1
2
hostnamectl set-hostname k8s-master 
cat /sys/class/dmi/id/product_uuid

需要安装IPVS。

CentOS

安装依赖

1
yum install -y conntrack ntpdate ipvsadm ipset jq iptables curl sysstat libseccomp wget vim net-tools git

关闭防火墙

1
2
system stop firewalld && systemctl disable firewalld
yum -y install iptables-services && systemctl start iptables && systemctl enable iptables && iptables -F && service iptables save

关闭 SELinux

1
2
swapoff -a && sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab 
setenforce 0 && sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config

调整内核参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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_instances=8192
fs.inotify.max_user_watches=1048576
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

调整时区

1
2
3
4
timedatectl set-timezone Asia/Shanghai
timedatectl set-local-rtc 0
systemctl restart rsyslog
systemctl restart crond

关闭不需要的服务

1
systemctl stop postfix && systemctl disable postfix

设置rsyslogd和systemd journald

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
mkdir /var/log/journal
mkdir /etc/systemd/journald.conf.d
cat > /etc/systemd/journald.conf.d/99-prophet.conf <<EOF
[Journal]
Storage=persistent
Compress=yes
SyncIntervalSec=5m
RateLimitInberval=30s
RateLimitBurst=1000
SystemMaxUse=10G
SystemMaxFileSize=200M
MaxRetentionSec=2week
ForwardToSyslog=no
EOF
systemctl restart systemd-journald

Kube-Proxy 开启IPVS 前置条件

1
2
3
4
5
6
7
8
9
10
modprobe br_netfilter
cat > /etc/sysconfig/modules/ipvs.modules <<EOF
#!/bin/bash
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 -e nf_conntrack_ipv4

安装Docker

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
curl -sSL https://get.docker.com | sh
sudo cat>/etc/docker/daemon.json<<EOF
{
"registry-mirrors": ["https://sfpj1t4c.mirror.aliyuncs.com"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
}
}
EOF
sudo systemctl daemon-reload # 加载阿里云加速镜像
sudo systemctl restart docker
sudo groupadd docker # 添加当前用户到docker组
sudo usermod -aG docker $USER
newgrp docker
sudo apt-get install -y docker-compose # 安装 docker compose

安装Kubeadm

1
2
3
4
5
6
7
8
9
10
11
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-1.16.0 kubeadm-1.16.0 kubectl-1.16.0
systemctl enable kubelet

部署Master

1
2
3
4
5
6
7
8
9
kubeadm init \
--apiserver-advertise-address=192.168.153.34 \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.16.0 \
--service-cidr=10.1.0.0/16 \
--pod-network-cidr=10.244.0.0/16
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

1
2
kubeadm config print init-defaults > kubeadm-config.yaml
kubeadm init --config=kubeadm-config.yaml --experimental-upload-certs | tee kubeadm-init.log
1
2
3
4
5
6
7
8
9
10
11
12
13
# kubeadm-config.yaml
localAPIEndpoint:
advertiseAddress: 192.168.66.10 # Master
kubernetesVersion: v1.15.1
networking:
podSubnet: "10.244.0.0/16"
serviceSubnet: "10.96.0.0/12"
---
apiVersion: kubeproxy.conf.k8s.io/v1
kind: KubeProxyConfiguration
featureGates:
SupportIPVSProxyMode: true
mode: ipvs

为普通用户创建kubectl的token

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

部署Flannel插件

1
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

查看运行状态

1
2
kubectl get pod -n kube-system -o wide -w
kubectl get node

加入Worker

1
2
kubeadm join 192.168.66.10:6443 --token 6qf11n.pdyzp2zki1ydb2fc \
--discovery-token-ca-cert-hash sha256:e9055d8b3cfcf40330124f5da18e820ebcb6eb9ff28eb64c0f593e0fb154b755

Ubuntu

关闭防火墙

1
sudo ufw disable

禁用 Swap

1
2
3
sudo swapoff -a
#修改/etc/fstab,注释掉swap那行,持久化生效
sudo vi /etc/fstab

修改时区

1
2
sudo timedatectl set-timezone Asia/Shanghai
sudo systemctl restart rsyslog

设置可以看到bridged traffic

1
2
3
4
5
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sudo sysctl --system

设置rp_filter

1
2
3
4
5
6
7
8
9
#修改/etc/sysctl.d/10-network-security.conf
sudo vi /etc/sysctl.d/10-network-security.conf

#将下面两个参数的值从2修改为1
#net.ipv4.conf.default.rp_filter=1
#net.ipv4.conf.all.rp_filter=1

#然后使之生效
sudo sysctl --system

安装Docker

1
2
3
4
5
6
7
8
9
10
11
12
curl -sSL https://get.docker.com | sh
sudo cat>>/etc/docker/daemon.json<<EOF
{
"registry-mirrors": ["https://sfpj1t4c.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload # 加载阿里云加速镜像
sudo systemctl restart docker
sudo groupadd docker # 添加当前用户到docker组
sudo usermod -aG docker $USER
newgrp docker
sudo apt-get install -y docker-compose # 安装 docker compose

安装 Kubeadm

1
2
3
4
5
6
7
8
9
10
sudo apt-get update && sudo apt-get install -y ca-certificates curl software-properties-common apt-transport-https curl
curl -s https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | sudo apt-key add -

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
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

初始化

1
2
sudo kubeadm init --pod-network-cidr 172.16.0.0/16 \
--image-repository registry.cn-hangzhou.aliyuncs.com/google_containers

为普通用户创建kubectl的token

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

安装Calico

1
2
3
#下载 https://docs.projectcalico.org/v3.11/manifests/calico.yaml
#修改CALICO_IPV4POOL_CIDR,然后
kubectl apply -f calico.yaml

安装Worker

1
2
kubeadm join 192.168.0.95:6443 --token x.xxx \
--discovery-token-ca-cert-hash sha256:xxxxx

安装Dashboard

1
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0/aio/deploy/recommended.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 可以下载下来自己配置
kind: Service
apiVersion: v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
spec:
ports:
- port: 17030
targetPort: 8443
type: NodePort
externalIPs:
- 192.168.0.95
selector:
k8s-app: kubernetes-dashboard

apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kubernetes-dashboard

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

获取登录所需的token

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

安装Controller Ingress

1
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-0.32.0/deploy/static/provider/baremetal/deploy.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
apiVersion: v1
kind: Service
metadata:
labels:
helm.sh/chart: ingress-nginx-2.0.3
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 0.32.0
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: controller
name: ingress-nginx-controller
namespace: ingress-nginx
spec:
type: NodePort
ports:
- name: http
port: 80
protocol: TCP
targetPort: http
- name: https
port: 443
protocol: TCP
targetPort: https
externalIPs:
- 192.168.0.95
- 192.168.0.34
selector:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/component: controller

搭建私有仓库Harbor

配置Docker

1
"insecure-registeries": ["https://hostname"]

下载Harbor

编辑harbor.cfg

1
hostname = xxx

创建Https证书

1
2
3
4
5
6
7
8
9
10
mkdir -p /data/cert
cd !$
openssl genrsa -des3 -out server.key 2048
openssl req -new -key server.key -out server.csr
cp server.key server.key.org
openssl rsa -in server.key.org -out server.key # 退密码
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
chmod a+x *
cd -
./install.sh

为各个节点添加host解析Harbor hostname

登录:admin/Harbor12345

Kubectl 命令

1
2
3
4
5
6
7
8
9
kubectl help
kubectl explain
kubectl run xxx --replicas=1
kubectl get rs
kubectl get pod
kubectl get deployment
kubectl delete pod xxx
kubectl scale --replicas=3 xxx
kubectl exec pod-name -it -- /bin/sh

资源清单

级别:

  • 命名空间:kubeadm 默认安装到 kube-system
  • 集群:无需指定命名空间
  • 元数据:HPA,通过指标操作

类型

  • 工作负载:Pod,ReplicaSet、Deployment、StatefulSet、DaemonSet、Job、CronJob
  • 服务发现与负载均衡资源:Service、Ingress
  • 配置与存储:Volume、CSI(容器存储接口)
  • 特殊存储卷:ConfigMap(配置中心)、Secret、DownwardAPI(外部信息输入到容器)
  • 集群级资源:Namespace、Node、Role、ClusterRole、RoleBinding、ClusterRoleBinding
  • 元数据资源:HPA、PodTemplate、LimitRange

常用字段:

  • version - kubectl api-versions
  • kind - Pod / Deployment …
  • metadata
    • name
    • namespace
  • spec
    • containers[]
      • name
      • image
      • imagePullPolicy - Always / Never / IfNotPresent
      • command[]
      • args[]
      • workingDir
      • volumeMounts[]
        • name
        • mountPath
        • readOnly
      • ports[]
        • name
        • containerPort
        • hostPort
        • protocol - TCP / UDP
      • env[]
        • name
        • value
      • resources
        • limits
          • cpu
          • memory
        • requests
          • cpu
          • memory
    • restartPolicy
    • nodeSelector
    • imagePullSecrets
    • hostNetwork
1
2
3
4
5
6
7
8
9
10
11
12
# pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: app-pod
labels:
app: app-pod-label
version: v1
spec:
containers:
- name: app
image: nginx

运行

1
2
kubectl apply -f pod.yaml
kubectl create -f pod.yaml

查看日志

1
2
3
kubectl get pod
kubectl describe pod app-pod
kubectl log app-pod -c app

删除

1
kubectl delete pod app-pod

容器生命周期

Pause - 启动网络和数据卷

Init Container - 创建阶段:多个,前一个执行完成后一个执行,包含初始化的工具,可以具有不同的文件视图,可以用于探测依赖服务是否启动。初始化阶段结束后删除,全部删除后才开始Main Container。

Main Container - 部署阶段

Start

Readiness - 就绪检测

Liveness - 生存检测

Stop

Init Container探测

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# init.yaml
apiVersion: v1
kind: Pod
metadata:
name: app-pod
labels:
app: app-pod-label
version: v1
spec:
containers:
- ...
initContainers:
- name: app
image: busybox
command: ['sh', '-c', 'echo until nslookup db; do echo waiting for db; sleep 2; done;']
1
2
3
4
5
6
7
8
9
10
11
12
# db.yaml
apiVersion: v1
kind: Service
metadata:
name: app-service
labels:
app: app-service-label
version: v1
spec:
containers:
- name: db
image: mysql

探针探测

容器出现如下情况时表示容器启动成功

  • Exec Action - 容器内指令返回 0 时
  • Tcp - 当容器端口打开时
  • Http Get - 指定端口和路径上Get返回2xx,3xx时

存活检测:失败则删除容器

1
2
3
4
5
6
7
8
9
spec:
containers:
- name: db
image: mysql
livenessProbe:
exec:
command: ['test', '-e', '/tmp/live']
initialDelaySeconds: 1
periodSeconds: 3

就绪检测:失败则删除容器

1
2
3
4
5
6
7
8
9
10
spec:
containers:
- name: db
image: mysql
readinessProbe:
httpGet:
port: http
path: /index.html
initialDelaySeconds: 1
periodSeconds: 3

启动,退出

1
2
3
4
5
6
7
8
9
10
11
spec:
containers:
- name: db
image: mysql
lifecycle:
postStart:
exec:
command: [...]
preStop:
exec:
command: [...]

Pod 分类

可以包含多个容器。这些容器共用Pod的网络地址,存储。

自主式

不被管理

控制器管理式

被控制器管理数目。

ReplicaSet

副本集按照标签管理。同一个标签算一个集合。

1
kubectl explain rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
apiVersion: v1
kind: ReplicaSet
metadata:
name: frontend
spec:
replicas: 3
selector:
matchLabels:
tier: frontend
template: # pod
metadata:
labels:
tier: frontend
spec:
containers:
- name: php
image: php
env:
- name: HOST
value: localhost
ports:
- containerPort: 80

Deployment

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
apiVersion: v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
template: # pod
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80

扩容

1
kubectl scale deployment nginx-deployment --replicas 10

自动扩容

1
kubectl autoscale deployment nginx-deployment --min=10 --max=15 --cpu-percent=80

更新

1
kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1

回滚

1
kubectl rollout undo deployment/nginx-deployment

DaemonSet

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apiVersion: v1
kind: DaemonSet
metadata:
name: daemonset-example
labels:
app: daemonset
spec:
selector:
matchLabels:
name: daemonset-example
template:
metadata:
labels:
name: daemonset-example
spec:
containers:
- name: daemonset-example
image: nginx

Job

1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: v1
kind: Job
metadata:
name: pi
spec:
template:
metadata:
name: pi
spec:
containers:
- name: daemonset-example
image: perl
restartPolicy: Never

Service

ClusterIP:一个Service背后有多个同类Pod,它们共用一个ClusterIP,也就是Service的IP。

NodePort:在ClusterIP基础上,Servcie也会在所在Node上映射一个端口到自己的服务上。

LoadBalance:在NodePort基础上,借助云供应商创建外部负载均衡器,将请求转发给Node:Service

ExternalName:将集群外部服务引入到集群内部来。

Ingress

七层负载均衡。

总结

LearningNotes: Java学习笔记,主要来源于B站上视频的学习,同时会记录平时一些学习和项目中遇到的问题,同步更新在蘑菇博客,如果对我的博客网站感兴趣的话,欢迎关注我的 蘑菇博客项目 笔记主要涵盖:Java,Spring,SpringCloud,计算机网络,操作系统,数据结构,Vue等 如果笔记对您有帮助的话,欢迎star支持,谢谢~ - Gitee.com

概念:

  • 资源编排
  • Pod
  • Node
  • Controller
    • RS
    • Deployment
    • DaemonSet
  • Service
  • Secret
  • ConfigMap
  • Ingress
  • Helm
  • NFS
  • PV、PVC
  • Dashboard
  • HAProxy