K8S备忘录

2021-03-04  本文已影响0人  winlinvip

K8S的概念:

K8S命令

在macOS下可以直接用brew安装:

brew install kubectl

常用的K8S命令:

kubectl cluster-info
kubectl get cm --all-namespaces
kubectl get cm -n kube-system
kubectl get cm/srs3-config
kubectl get cm/cluster-info -n kube-public -o yaml
kubectl get cm/cluster-info -n kube-public -o json
kubectl get deploy
kubectl get deploy/nginx-deployment -o yaml
kubectl get deploy/nginx-deployment -o json
kubectl get rs
kubectl get rs -w
kubectl get pods
kubectl get pods --show-labels
kubectl edit deployment.v1.apps/nginx-deployment
kubectl api-resources # 可以查询到缩写。
kubectl get services
kubectl get svc/nginx-service -o yaml
kubectl exec srs-deployment-f4cd6b6cc-c74bm -c nginx env
kubectl get pods -o jsonpath="{.items[*].spec.containers[*].name}"
kubectl delete po/srs-origin-deployment-577cf4c7b7-zp7bs --force --grace-period=0
kubectl get po --show-labels
kubectl label deploy/srs-origin-deployment app=srs --overwrite
kubectl label po/srs-origin-deployment-6b4fcf6674-qphdz app=srs --overwrite
kubectl exec srs-edge-deploy-58d9999b7c-f4rtr -- ./objs/srs -v
kubectl set image deploy/srs-edge-deploy srs=ossrs/srs:v4.0.6
kubectl set image deploy/srs-edge-deploy srs=ossrs/srs:v4.0.6 --record
kubectl rollout history deploy/srs-edge-deploy
kubectl get rs
kubectl get rs -w # 可以Watch变化。
kubectl scale --replicas=3 deploy/srs-edge-deploy
kubectl logs srs-edge-deploy-d4cfc9d8b-5wnw7
kubectl describe po/srs-edge-deploy-d4cfc9d8b-85nkf |grep -A 3 Events
kubectl get nodes
kubectl describe nodes/cn-beijing.172.17.232.153
kubectl config get-contexts

切换集群

查看集群:

kubectl config get-contexts

设置默认集群:

kubectl config use-context kubernetes-admin-xxx

ConfigMap保存证书

ConfigMap可以配置多个文件,比如证书的私钥(*.key)和公钥(*.pem),后台添加配置,或者用yaml:

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
  name: https-config
data:
  https.key: |-
    -----BEGIN RSA PRIVATE KEY-----
    MIIEowIBAAKCAQEA8mEyACKNJcxAfPWvAYr0uy/wVtd16LPEpy7w1l9WD9+SBsOj
    n0QZSc2+y/mEpwXA65irqUply42NabB6rgfsfbcLra8SA5CbyHtrIP4fT6jnBA85
    Jzmznp/q/1n4nlfaqawFyOB2IzPjPiwzexN/gv2wWC+5wSQ9yq2k
    -----END RSA PRIVATE KEY-----
  https.pem: |-
    -----BEGIN CERTIFICATE-----
    MIIFfjCCBGagAwIBAgIQD8reYBHHOc99faMYlJ0lazANBgkqhkiG9w0BAQsFADBu
    MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
    d3cuZGlnaWNlcnQuY29tMS0wKwYDVQQDEyRFbmNyeXB0aW9uIEV2ZXJ5d2hlcmUg
    -----END CERTIFICATE-----
EOF

挂到容器作为配置文件:

cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: srs
  labels:
    app: srs
spec:
  selector:
    matchLabels:
      app: srs
  template:
    metadata:
      labels:
        app: srs
    spec:
      volumes:
        - name: ssl-volume
          configMap:
            name: https-config
      containers:
      - name: srs
        image: registry.cn-hangzhou.aliyuncs.com/ossrs/srs:3
        imagePullPolicy: IfNotPresent
        volumeMounts:
          - name: ssl-volume
            mountPath: /usr/local/srs/etc
EOF

可以查看etc目录,就有了证书文件:

$ kubectl get pods -l app=srs
NAME                   READY   STATUS    RESTARTS   AGE
srs-77b446fbfc-ftz7c   1/1     Running   0          4m50s

$ kubectl exec srs-77b446fbfc-ftz7c -- ls -lh etc
lrwxrwxrwx 1 root root 16 Feb  1 07:06 https.key -> ..data/https.key
lrwxrwxrwx 1 root root 16 Feb  1 07:06 https.pem -> ..data/https.pem

Volume

Volumes,docker有这个概念但比较简单且无生命周期管理,k8s提供各种复杂的volume,而且volume是随pod的生命周期(大于container)。

emptyDir,临时的空目录,在pod删除时会情况,container crash后目录数据还在,可用于crash后的恢复。

比如SRS写到nginx目录后,nginx可以分发切片文件。

起一个Pod运行这两个容器,共享这个目录,这样就可以实现SRS写Nginx读了。

Container Args

设置container的命令和参数

使用command和args,command是命令,args是它的参数,一般需要一起设置。可以command指定为/bin/sh,用shell执行脚本,参数就是:

command: ["/bin/sh"]
args: ["-c", "cp -R ./objs/nginx/html/* /tmp/html/; sleep infinity"]

也可以在里面写for循环:

command: ["/bin/sh"]
args: ["-c", "while true; do echo hello; sleep 10;done"]

还可以写成数组的方式,字符串用长字符串换行:

command: ["/bin/sh"]
args:
- "-c"
- >
  while true; do
    ffmpeg -re -i ./doc/source.200kbps.768x320.flv \
      -c copy -f flv rtmp://srs/live/livestream
  done

可以用脚本做初始化的事情。也可以只用args,会从args中解析出command:

args:
- /bin/sh
- -c
- echo hello

Resource

管理容器使用的计算资源,Resource

可以创建Pod时指定需要的CPU和内存,这样调度时知道调度到哪个节点;还可以指定资源的限额。资源限额定义,Quota

资源的要求和限制,指定在:

CPU,比如cpu: 0.1就是100m,m就是千分之,millicpu,millicores。
Memory,比如memory: 100Mi就是100MiB,还有Ki,Gi,Ti,Pi。

limits是最多使用的限制;requests是需要使用的,也就是要求的资源

0<=Request<=Limit<=Infinity (如果Limit为0表示不对资源进行限制,这时可以小于Request)

关于调度

关于limit

改进:

关于QoS

OOM时KILL的顺序:最先KILL Best-Effort,然后是Burstable,最后是Guranteed。

Config Reload

ConfigMap修改后,文件会变。

注意:fsnotify signal可能因为符号链接收不到。

Linux是使用inotify机制,用inotify_init返回fd,watch后如果有变化可以read出来。

可以侦听所有事件:IN_ALL_EVENTS,但主要是IN_MODIFY和IN_CREATE

返回的内容转换成结构体:inotify_event

YAML格式

-表示列表,比如ports可以指定多个,所以就以-开头。

管道命令行apply

cat <<EOF | kubectl apply -f -
apiVersion: v1
EOF

可以把多个yaml写在一起,用三个横杠分割,比如stateful

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Service
---
apiVersion: apps/v1
kind: StatefulSet
EOF

配置镜像拉取,如果存在就不拉取images

spec.containers[*].imagePullPolicy: IfNotPresent

如果总是拉取,则设置为Always

Service

Service就是如何让Pods提供服务,或微服务,涉及服务发现和负载均衡。

一般服务发现使用的是label selector,有时候也需要无selector的Service(必须后端是另外一个K8S或非Pod)。标签(label)就是分组的一种方式了,或者一种ID。

定义服务时,需要指定selector比如app=nginx,指定服务端口port,以及后端端口targetPort(默认等于port)。

注意targetPort可以是字符串,会解析成对应的端口,这样后端服务会比较灵活。

下面是一个服务的描述。

cat <<EOF | kubectl apply -f -
kind: Service
apiVersion: v1
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
EOF

查询该服务:

$ kubectl get svc/nginx-service
NAME            TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
nginx-service   ClusterIP   172.21.7.190   <none>        80/TCP    3m13s

服务是由kube-proxy分配的VIP并进行代理,没有采用DNS因为有缓存等问题:

kube-proxy有几种不同的代理方式:

如果杀掉nginx的pod,如果只有一个pod会服务不可用,但过一会儿K8S会重新启动pod,服务就可以了。

Service Type

ServiceTypes服务类型,一般ClusterIP就是内部服务,还有其他的:

默认是ClusterIP,看到内网的IP(ClusterIP),但无外部IP(ExternalIP),ClusterIP 172.21.89.226 <none> 80/TCP,可访问性如下:

LoadBalancer负载均衡,一般阿里云标准用法是EIP绑定到SLB上,通过SLB对外提供服务。SLB创建时选内部SLB,交换机选k8s-node使用的,比如IP是172.17.232.159。然后再买EIP绑定到SLB。不用创建SLB侦听,k8s会自动做这事,创建后是这样:

$ kubectl get svc/nginx-service
NAME            TYPE           CLUSTER-IP       EXTERNAL-IP      PORT(S)        AGE
nginx-service   LoadBalancer   172.21.113.176   172.17.232.159   80:30589/TCP   6s

可以发现,类型是LoadBalancer,设置了ExternalIP。

Service Discovery

服务发现可以用ENV环境变量,或者DNS。

当注册Service后,K8S会在POD启动时,增加服务对应的环境变量,那么POD就可以用这个环境变量来发现服务了。

CoreDNS组件开启后,创建了Service就会创建对应ServiceName的DNS记录,比如nginx-service。

$ kubectl get service/nginx-service
NAME            TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
nginx-service   ClusterIP   172.21.7.190   <none>        80/TCP    16m

$ kubectl exec srs3-demo-deploy-55df684cbb-5dzsh -- ping nginx-service
PING nginx-service.default.svc.cluster.local (172.21.7.190) 56(84) bytes of data.
64 bytes from nginx-service.default.svc.cluster.local (172.21.7.190): icmp_seq=1 ttl=64 time=0.033 ms

StatefulSets时,需要给每个Pod分配可达的地址,这就是HeadlessServices。通过配置:ClusterIP: None 来指定的。

声明式更新

Declarative updates,声明式更新:

However, a Deployment is a higher-level concept that manages 
ReplicaSets and provides declarative updates to Pods along with 
a lot of other useful features.

这文章说declarative updates

  1. kubectl apply一般是declarative。参考#1#2
  2. kubectl run会转成declaratively Deployment:kubectl translates your imperative command into a declarative Kubernetes Deployment object. A Deployment is a higher-level API that allows rolling updates (see below).
  3. 意味着保持期望状态和实际状态一致:The Kubernetes API is fundamentally declarative, which means that the controllers always work to reconcile the observed state with the desired state. Therefore, if we delete a Pod, the ReplicaSet controller will create a new one to replace it, to maintain the desired replica count.
  4. 配置你想要的,K8S知道怎么实现:However, the power of Kubernetes is in its declarative API and controllers. You can just tell Kubernetes what you want, and it will know what to do.
  5. apply是幂等操作,可以执行多次:The kubectl apply command is idempotent. We can reuse it after modifying the manifests.

官方也有几个文章说Imperative命令式和Declarative声明式:

Aliyun ACK

ACK托管集群,需要的基本资源:

上一篇下一篇

猜你喜欢

热点阅读