结合个人学习方法,记录历程:
-
了解啥是k8s,用来解决什么问题。
-
了解大致架构和组件
- etcd 保存了整个集群的状态;
- API Server 提供了资源操作的唯一入口,并提供认证、授权、访问控制、API 注册和发现等机制;
- Controller Manager 负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;
- Scheduler 负责资源的调度,按照预定的调度策略将 Pod 调度到相应的机器上;
- Kubelet 负责维护容器的生命周期,同时也负责 Volume(CVI)和网络(CNI)的管理;
- Container Runtime 负责镜像管理以及 Pod 和容器的真正运行(CRI);
- Kube-proxy 负责为 Service 提供 cluster 内部的服务发现和负载均衡;
-
本地快速部署一个k8s集群, 以minikube实现
首先尝试在本地搭建一个k8s服务,以实践去学习理论。
- 安装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
sudo mv kubectl /usr/local/bin/
- 安装minikube
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
- 启动minikube
minikube start --vm-driver=xxx
此时k8s服务就成功部署了,可以通过 minikube dashboard
查看集群状态。既然服务部署成功了,开始尝试在集群里面部署服务吧~
-
kubectl
kubectl 是 Kubernetes 的命令行工具(CLI),是 Kubernetes 用户和管理员必备的管理工具。
-
namespace:
方法一:命令
kubectl create namespace <insert-namespace-name-here>
方法二:create my-namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: <insert-namespace-name-here>
Then run:
kubectl create -f ./my-namespace.yaml
删除namespace:
kubectl delete namespaces <insert-some-namespace-name>
-
run
运行一个名称为nginx,副本数为3,标签为app=example,镜像为nginx:1.10,端口为80(默认端口为80)的容器实例
kubectl run nginx --replicas=3 --labels="app=example" --image=nginx:1.10 --pot=80 #例子1
例子:
#运行一个容器实例:
kubectl run demo --image=yeasy/simple-web:latest
#暴露服务:
kubectl expose pod demo --port=80 --type=NodePort
# 访问服务:
minikube service demo
-
create
Create a deployment inside kubernetes cluster
# 根据镜像来创建
kubectl create deployment hello-minikube --image=k8s.gcr.io/echoserver:1.4
# 根据yaml文件创建
kubectl create -f demo-deployment.yaml
# 暴露服务, NodePort方可被外部访问
kubectl expose deployment hello-minikube --type=NodePort --port=8080
-
delete
删掉某个部署后,其运行的pod以及replicaset全部自动删除。
kubectl delete deployment [deployment-name]
-
其他常用指令
-
kubectl logs [pod-name]
: 查看某个资源日志 -
kubectl get pods
:查看所有pod 转台, -w 动态查看 -
kubectl describe pod [pod-name]
: 查看某的pod的状态 -
kubectl exec -ti [pod-name] -- bin/bash
: 进入某个服务 -
Kubectl edit deployment [deployment-name]
: 编辑某个部署
-
-
资源清单
按不同级别分类:
1. 命名空间级别
- 工作负载型资源 Pod ReplicaSet Deployment StatefulSet DaemenSet Job CronJob
- 服务发现及负载均衡型资源 Service Ingress
- 配置与存储型资源 Volume CSI
- 特殊类型存储卷: ConfigMap Secret DownwardAPI
2. 集群级别
Namespace Node Role ClusterRole RoleBinding ClusterRoleBinding
3. 元数据型
HPA PodTemplate LimitRange
查询某个字段的具体含义:kubectl explain resource-name
-
Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: mongodb-deployment
labels:
app: mongodb
spec: #This spec for deployment
replicas: 1
selector:
matchLabels:
app: mongodb
template:
metadata:
labels:
app: mongodb
spec: #This spec for pod
containers:
- name: mongodb
image: mongo
ports:
- containerPort: 27017
env:
- name: MONGO_INITDB_ROOT_USERNAME
valueFrom: # get value from k8s secret
secretKeyRef:
name: mysecret # target secret name
key: mongodb-root-username # key
- name: MONGO_INITDB_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysecret
key: mongodb-root-password
-
Service
Different Service types explained:
- ClusterIP Services: (default type)自动分配一个仅cluster内部访问的虚拟IP
- Headless Services: No cluster IP address is assigned ! spec.clusterIP=None
- NodePort Services: nodePort Range: 30000 - 32767
- LoadBalancer Services: NodePort and ClusterIP Service are create automatically
apiVersion: v1
kind: Service
metadata:
name: mongodb-service
spec:
selector:
app: mongodb
ports:
- port: 27017 # pod 端口
targetPort: 27017 # service接收端口
protocol: TCP
服务接收 targetport的消息发送到pod的port端口
-
Secret
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
mongodb-root-username: dXNlcm5hbWU=
mongodb-root-password: cGFzc3dvcmQ=
-
ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: mongodb-configmap
data:
database_url: mongodb-service
-
Ingress
分发请求
-
Helm (Package Manager)
reuse the configuration
-
Stateful
-
部分思考:
- Kubectl create/replace 和 apply 的区别
- create删除现有资源然后再通过replace触发更新,apply仅更新yaml中存在的属性
- create要求文件必须完整,apply不必
- Kubectl create/replace 和 apply 的区别
-
kubeadm搭建集群:
- 如果机器已经启动过k8s服务,可以通过 kubeadm reset 尽力还原初始化命令对节点的修改。
kubeadm init
--pod-network-cidr=10.244.0.0/16
该命令执行完后会有对应的权限控制操作与join命令:
例如:kubeadm join 10.221.88.97:6443 --token neh3gd.9yws9ispiyfxjnmb --discovery-token-ca-
cert-hash sha256:9bd2808551e949ec42b37808ed1186b794d12d09a1bc3874bbb7a74fa9fe6267
令牌token一般24小时过期,如果之后想要添加节点入集群可以通过:
kubeadm token create
:新建令牌
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
:新建discovery-token-ca-cert-hash
- 安装pod网络插件 kube-flannel.yaml :为了Flannel能够正常工作,需要为
kubeadm init
命令传递--pod-network-cidr=10.244.0.0/16
选项。 运行
sysctl net.bridge.bridge-nf-call-iptables=1
将 /proc/sys/net/bridge/bridge-nf-call-iptables 设置为1,从而将桥接的IPV4流量传递至iptables链。并执行:
kubectl apply -f kube-flannel.yml
- 控制平面节点隔离
在缺省情况下,出于安全原因,集群不会master节点上调度pod。如果你想在master节点上调度pod,例如在单节点Kubernetes集群上,请运行如下命令:
kubectl taint nodes --all node-role.kubernetes.io/control-plane- node-role.kubernetes.io/master-
-
多集群切换
我在本地起了一套minikube 服务,然后呢为了验证内网访问不通的问题,我又用kubeadm在本地建了另一套集群,而此时kubectl 无法操作 新建的这个集群,故由此引申多集群切换的问题,一般有两种解决方法,第一种是修改默认的config,第二种是以一个文件为模板,然后配置其各项内容,最后在引用的时候: export KUBECONFIG="${KUBECONFIG}:config-demo:config-demo-2"
新创建的集群admin.conf文件如下:
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: xxx...
server: https://10.221.88.97:6443
name: kubernetes
contexts:
- context:
cluster: kubernetes
user: kubernetes-admin
name: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-admin
user:
client-certificate-data: xxx...
client-key-data: xxx...
- 增加cluster到config中:
sudo kubectl config set-cluster kubernetes --server=``https://10.221.88.97:6443
--certificate-authority=fake-ca-file
- 将用户详细信息添加到配置文件中:
kubectl config set-credentials kubernetes-admin --client-certificate=fake-cert-file --client-key=fake-key-seefile
- 将上下文详细信息添加到配置文件中:
kubectl config --kubeconfig=config-demo set-context dev-frontend --cluster=development --namespace=frontend --user=developer
要删除用户,可以运行
kubectl --kubeconfig=config-demo config unset users.<name>
要删除集群,可以运行
kubectl --kubeconfig=config-demo config unset clusters.<name>
要删除上下文,可以运行
kubectl --kubeconfig=config-demo config unset contexts.<name>
--kubeconfig=config-demo , 这里添加该参数时,就会修改对应config-demo里面的值。
fake-ca-file
、fake-cert-file
和 fake-key-file
是证书文件路径名的占位符。 你需要更改这些值,使之对应你的环境中证书文件的实际路径名。
有时你可能希望在这里使用 BASE64 编码的数据而不是一个个独立的证书文件。 如果是这样,你需要在键名上添加 -data
后缀。例如, certificate-authority-data
、client-certificate-data
和 client-key-data
。
-
多角色切换
-
Debug
container runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:Network plugin returns error: cni plugin not initialized
去除污点
kubectl taint nodes --all node-role.kubernetes.io/control-plane- node-role.kubernetes.io/master-
Demo:k8s搭建一个mongoDB服务
思路:由上至下考虑结构,从浏览器访问外部服务,到mongoDB Express操作数据库,需要搭建一个可以被集群外部访问的Service,该Service与部署了mongDB Express的pod进行卯定。然后,mongDB Express访问内部Service,该Service与部署了MongoDB的pod卯定。
该过程中,除了需要用到Pod,Service,Deployment,还需要用到 Secret , ConfigMap 资源类存储,需要注意的是,后者需要提前部署于集群中。
在编写yaml文件时,Deployment 和 Service 可以写在一块,---
三横线分开即可。
注意:
- 服务与部署之间的卯定
- Service 外部访问设置 type: LoadBalancer
- 资源文件引用的写法
- 文件部署先后顺序
- 调用docker 容器时,注意其端口与需要的字段信息
demo文件:
https://github.com/Da-Qi/publicFile/blob/master/mongo-configmap.yaml
https://github.com/Da-Qi/publicFile/blob/master/mongo-express.yaml
https://github.com/Da-Qi/publicFile/blob/master/mongo-secret.yaml
https://github.com/Da-Qi/publicFile/blob/master/mongo.yaml
借鉴: