1. 安装
1.1. 系统配置:
# 关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
# 关闭selinux
sudo sed -i 's/enforcing/disabled/' /etc/selinux/config
# 关闭交换分区
sudo sed -ri 's/.*swap.*/#&/' /etc/fstab
sudo mount -a
1.2. 使用kubeadm安装
#!/usr/bin/env bash
sudo apt update && sudo apt install -y apt-transport-https curl
curl -s https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | sudo apt-key add -
echo "deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt update && sudo apt install -y kubelet kubectl kubeadm
# master
sudo kubeadm init --image-repository="registry.cn-hangzhou.aliyuncs.com/google_containers" --kubernetes-version=$(kubeadm version -o short) --pod-network-cidr=10.244.0.0/16 --ignore-preflight-errors=all
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
# network插件
kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"
# check
kubectl get nodes
kubectl get pods --all-namespaces
# Trouble shooting:
# kubectl -n kube-system describe TYPE NAME
# 创建join token
# kubeadm token create --print-join-command
# 清除安装:
# sudo kubeadm reset -f
# rm -rf ~/.kube
# sh helper:
alias kn='kubectl get nodes -o wide'
alias kp='kubectl get pods --all-namespaces -o wide'
alias kc='kubectl create -f'
alias ka='kubectl apply -f'
alias kr='kubectl replace -f'
alias kt="kubectl -n kube-system describe secret `kubectl -n kube-system get secret | grep admin-user | awk '{print $1}'`"
1.3. 使用Vagrant安装
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/focal64"
config.vm.box_check_update = false
config.vm.define "k8s-master" do |master|
master.vm.hostname = "k8s-master"
master.vm.provider "virtualbox" do |vb|
vb.name = "k8s-master"
vb.memory = "4096"
vb.cpus = 2
vb.gui = false
end
master.vm.network "public_network", bridge: "wlp2s0", ip: "192.168.124.110"
master.vm.provision "shell", path: "./init.sh"
end
(1..3).each {|i|
config.vm.define "k8s-node#{i}" do |node|
node.vm.hostname = "k8s-node#{i}"
node.vm.provider "virtualbox" do |vb|
vb.name = "k8s-node#{i}"
vb.memory = "4096"
vb.cpus = 2
vb.gui = false
end
node.vm.network "public_network", bridge: "wlp2s0", ip: "192.168.124.11#{i}"
node.vm.provision "shell", path: "./init.sh"
end
}
end
#!/usr/bin/env bash
sudo sed -ri 's/.*swap.*/#&/' /etc/fstab
sudo sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
sudo apt-get update && sudo apt-get upgrade -y
sudo apt-get install -y curl gnupg-agent apt-transport-https ca-certificates software-properties-common
curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io
sudo usermod -aG docker vagrant
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://3itj1ym2.mirror.aliyuncs.com"]
}
EOF
sudo sed -i 's/ExecStart.*/& -H tcp:\/\/0.0.0.0:2375/g' /lib/systemd/system/docker.service
sudo chmod 777 /var/run/docker.sock
sudo chmod 777 /etc/docker -R
sudo systemctl daemon-reload
sudo systemctl restart docker
# install docker-compose
sudo wget -q https://soft-1252259164.cos.ap-shanghai.myqcloud.com/docker-compose-1.27.4 -O /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
# install kubeadm kubectl kubelet
curl -s https://soft-1252259164.cos.ap-shanghai.myqcloud.com/apt-key.gpg | sudo apt-key add -
echo "deb https://mirrors.ustc.edu.cn/kubernetes/apt/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update && sudo apt-get upgrade -y
sudo apt-get install -y kubelet kubectl kubeadm
sudo reboot now
# master节点执行
sudo kubeadm init --image-repository="registry.cn-hangzhou.aliyuncs.com/google_containers" --apiserver-advertise-address="192.168.124.110" --kubernetes-version=$(kubeadm version -o short) --pod-network-cidr=10.244.0.0/16 --ignore-preflight-errors=all
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"
2. 插件安装
2.1. helm
2.1.1. 基本概念
-
Chart: chart用于描述一个安装包
-
Repository: 存放chart的database
-
Release: chart在Kubernetes集群中部署后的一个实例
2.1.2. 安装
curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash
helm repo add stable http://mirror.azure.cn/kubernetes/charts/
2.1.3. 常用命令
helm repo list
helm repo add dev https://example.com/dev-charts
helm ls
helm search <chart>
helm inspect [values] <chart>
helm install {CHART|TAR|URL} [--name <name>]
helm delete <chart>
helm create <new_chart>
helm package <chart>
2.2. 安装Dashboard
mkdir certs
openssl req -nodes -newkey rsa:2048 -keyout certs/dashboard.key -out certs/dashboard.csr -subj "/C=/ST=/L=/O=/OU=/CN=kubernetes-dashboard"
openssl x509 -req -sha256 -days 10000 -in certs/dashboard.csr -signkey certs/dashboard.key -out certs/dashboard.crt
kubectl create -f https://soft-1252259164.cos.ap-shanghai.myqcloud.com/dashboard.yml
kubectl create secret generic kubernetes-dashboard-certs --from-file=certs -n kubernetes-dashboard
# 获取登录token
kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get secret | grep admin-user | awk '{print $1}')
2.3. 集群问题记录
2.3.1. 容器一直部署不上去
-
检查cpu/内存/磁盘使用量.
-
kubectl describe node <node>
查看node是否被打上了NoSchedule的污点. -
kubectl describe pod <pod> -n <namespace>
查看pod具体失败原因.
2.3.2. 集群证书过期
Unable to connect to the server: x509: certificate has expired or is not yet valid
sudo kubeadm alpha certs renew all
rm -rf $HOME/.kube
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
3. kubernetes各个组件功能
3.1. Master
集群控制节点,运行以下进程:
-
kube-apiserver: 提供Kubernetes所有资源操作的REST服务
-
kube-controller-manager: 自动化控制所有资源对象
-
kube-scheduler: pod调度
-
kube-proxy: 实现service通信个负载均衡
-
etcd: 保存资源数据
-
coredns
3.2. Node
集群工作负载节点,运行以下进程:
-
kubelet: 负责pod里容器的创建、启动等任务
-
kube-proxy: 实现service通信个负载均衡
-
pause: pod组件
-
docker: 负责本机的容器管理
3.3. Pod
每个pod包含pause容器和多个用户容器. 同一个pod内的容器拥有相同的Network/IPC/UTS[和PID] namespace, 所以它们拥有相同的hostname和network interfaces,但文件系统不同
-
static pod: 设置在node中,并只在该node上运行
-
normal pod: 存储在etcd中,随后会被Master调度到某个node上进行绑定,node上的kubelet进程会实例化一组docker容器运行
3.4. Label Selector
-
kube-controller进程通过RC上定义的labelSelector来筛选需要监控的Pod数量.
-
kube-proxy进程通过service的labelSelector来选择对应的pod, 自动建立起每个service到对应pod的请求路由, 从而实现service的负载均衡.
-
kube-scheduler通过node定义的label和pod定义nodeSelector实现pod的定向调度.
3.5. ReplicationController
定期监控labelSelector匹配的pod副本的数量,确保其等于期望值.
如果修改了一个pod的label, 则RC会自动新起一个pod.如果修改了RC的labelSelector, 则RC会自动创建所有pod副本. |
3.6. Replica Set
包含ReplicationController所有的功能, 同时增强了labelSelector的功能.
3.7. DaemonSet
通过nodeSelector在每个节点上运行一个实例
3.8. Job
启动批处理Job, 可以设置任务数/并行数/重试次数等
3.9. CronJob
定时任务: 分/时/日/月/星期
3.10. Deployment
扩展了Replica Set自动scale的功能.
4. kubectl命令
# 获取k8s版本号
kubectl version [-o short]
# 查看所有的api版本号
kubectl api-versions
# 查看 Config metadata
kubectl config view
# 查看集群资源概况
kubectl get [node|ns|po|depoy|cm]
# 查看指定pod中某个容器日志
kubectl logs POD -c CONTAINER
# 创建namespace
kubectl create namespace xxNameSpace
# 设置label
kubectl label po xxPod xxx=xxx [--override]
# 显示label
kubectl get pods --show-labels
# 筛选label
kubectl get pods --show-labels -l env=xxx
# 每个node都会有一些默认label: kubernetes.io/hostname=HOSTNAME
# 编辑
kubectl edit rc RC
# 删除
kubectl delete [TYPE | all] [--all] [-n NAMESPACE]
# 删除rc但保留所有pod
kubectl delete rc RC --cascade=false
# configMap
kubectl create cm CM_NAME --from-file=xxxFile # xxxFile=CONTENT
kubectl create cm CM_NAME --from-file=xxxDir # xxxFile1=CONTENT1, xxxFile2=CONTENT2
kubectl create cm CM_NAME --from-literal=a1=v1 --from-literal=a2=v2
# ======部署管理======
# 实现水平扩展
kubectl scale rc <rc_name> [-n <namespace>] --replicas=2
# 部署状态变更状态检查
kubectl rollout status
# 部署历史
kubectl rollout history
# 回滚部署
kubectl rollout undo
5. Pod
5.1. 生命周期:
-
Pending
Pod创建成功,但存在容器还未创建
-
Running
Pod中容器都已成功创建
-
Succeeded
Pod中所有容器均已创建成功
-
Failed
Pod中所有容器均已退出,并且至少有一个退出为失败状态
-
Unknown
无法获取Pod的状态
5.2. 重启策略
-
Always
容器失效时kubelet自动重启容器
-
OnFailure
容器停止运行且退出码不为0时kubelet自动重启容器
-
Never
kubelet不会自动重启容器
RC和DS必须设置为Always Job必须设置为OnFailure或Never
5.3. 健康检查
-
livenessProbe (running)
如果探测到容器不健康, 则kubelet将杀掉该容器, 并根据容器的重启策略处理
-
HTTPGetAction
-
TCPSocketAction
-
ExecAction
livenessProbe:
httpGet:
port: 8080
path: /actuator/health
initialDelaySeconds:10 # 首次进行健康检查的延时时长,单位为秒
timeoutSeconds:2 # 端点超时时长
periodSeconds:10 # 定时任务
-
readinessProbe (ready)
请求容器, 如果容器不健康, Endpoint Controller 将从Service的Endpoint中删除该Pod的Endpoint
5.4. 调度
-
Deployment 自动调度
-
NodeSelector 定向调度
-
给node打标签:
kubectl label node <node-name> <label-key>=<label-value>
-
yml配置label:
spec.template.spec.nodeSelector
-
-
NodeAffinity: Node亲和力调度
-
RequiredDuringSchedulingIgnoredDuringExecution: 必须满足指定的规则才可以调度Pod到Node上
-
PreferredDuringSchedulingIgnoredDuringExecution: 优先满足指定规则即可
-
-
PodAffinity: Pod亲和力调度
-
Taint:
kubectl taint node <node-name> <label-key>=<label-value>:<NoSchedule|PreferNoSchedule|NoExecute>
-
NoSchedule: 该节点不会参与调度
-
PreferNoSchedule: 该节点尽量不会参与调度.
-
NoExecute: 该节点不会参与调度, 并且会驱逐该节点上已有的pod.
-
-
DaemonSet 每个node调度1个Pod
-
Job 批处理调度
-
Cronjob 定时任务
5.5. 升级和回滚
5.5.1. 升级
-
kubectl set image deployment/<deployment-name> <container-name>=<image-name:tag>
-
kubectl edit deployment/<deployment-name>
可以通过spec.strategy.type确定升级方式: RollingUpdate/Recreate
5.5.2. 回滚
查看升级状态: kubectl rollout status deployment/<deployment-name>
查看升级历史: kubectl rollout history deployment/<deployment-name> 创建deployment时加上—record参数
回滚到指定版本 kubectl rollout undo deployment/<deployment-name> --to-revision=<revision>
暂停/继续更新: kubectl rollout pause/resume deployment/<deployment-name>
5.6. 扩容和缩容
kubectl scale deployment <deployment-name> --replicas <number>
6. Service
6.1. 基本用法:
apiVersion: v1
kind: Service
metadata:
name: springboot-demo
spec:
selector:
app: springboot-demo
ports:
- port: 8081 #service暴露的端口
targetPort: 8080 #pod端口
kubectl create -f springboot-svc.yml
6.2. Pod间访问
-
每一个pod中都会有集群中所有service的host/port环境变量. 如
KUBERNETES_SERVICE_HOST/KUBERNETES_SERVICE_PORT
对应名为kubernetes的service -
直接通过dns访问: SERVICE[.NAMESPACE.svc.cluster.local], 如
kubia.jy-test.svc.cluster.local
6.3. 暴露外部端口
-
设置容器级别的hostPort, 将容器应用的端口号映射到物理机上
ports:
- containerPort: 8080
hostPort: 8081
-
Pod设置hostNetwork=true, 容器中的端口号被映射到物理机上
-
Service设置nodePort映射到物理机,同时设置service的类型为NodePort
service的nodePort默认范围为30000-32767,可以修改/etc/kubernetes/manifests/kube-apiserver.yaml 添加command `- --service-node-port-range=80-32767`
type: NodePort
ports:
- port: 8080
targetPort: 8080
nodePort: 8081
-
设置service的spec.type为LoadBalancer, 不需要设置NodePort
-
Ingress
7. PV
当集群用户需要在其 pod 中使用持久化存储(PV)时, 他们首先创建持久卷声明 (Persistent VolumeClaim, 简称 PVC) 清单, 指定所需要的最低容量要求和访问模式, 然后用户将PV提交给Kubernetes apiserver, Kubernetes将找到可匹 配的PV并将其绑定到PVC。
8. ConfigMap
8.1. 创建方式
-
命令行直接创建
kubectl create configmap kubia-config --from-literal=interval=2 --from-literal=foo=bar
-
从文件(夹)创建
kubectl create configmap kubia-config --from-file=config.conf
-
yaml创建:
apiVersion: v1
kind: ConfigMap
metadata:
name: kubia-cm
namespace: jy-test
data:
log.level: debug
8.2. 使用:
envFrom:
- configMapRef:
name: kubia-cm
prefix: log