Kubernetes 150 个操作练习 (下)

150 个练习的最后一部分,这部分主要包含三个模块:

  • 状态存储
  • 配置
  • 监控
  • 服务与网络

四. 状态存储篇

这部分的练习主要是熟悉持久卷和持久卷声明的相关使用。

96. 查看集群中的所有持久卷
$ kubectl get pv
NAME         CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                         STORAGECLASS    REASON   AGE
example-pv   1Gi        RWO            Delete           Bound    default/example-local-claim   local-storage            2d22h
97. 创建一个 hostpath 类型的持久卷,设置存储容量为 10G,读写权限是 ReadWriteOnce, 挂载到 /mnt/data 目录
  • yaml 文件
apiVersion: v1
kind: PersistentVolume
metadata:
  name: task-pv-volume
  labels:
    type: local
spec:
  storageClassName: manual
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/mnt/data"
  • 创建并查看
$ kubectl get pv
NAME             CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM                         STORAGECLASS    REASON   AGE
task-pv-volume   10Gi       RWO            Retain           Available                                 manual                   3s
98. 创建持久卷声明,设置 storage 要求为 3Gi,访问权限是 ReadWriteOnce
  • yaml 文件
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: task-pv-claim
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 3Gi
  • 创建并查看 PVC

$ kubectl create -f task-pv-claim.yaml
persistentvolumeclaim/task-pv-claim created

$ kubectl get pvc
NAME                  STATUS   VOLUME           CAPACITY   ACCESS MODES   STORAGECLASS    AGE
task-pv-claim         Bound    task-pv-volume   10Gi       RWO            manual          12s

99. 删除上面创建的 PV 和 PVC
$ kubectl delete pvc task-pv-claim
persistentvolumeclaim "task-pv-claim" deleted

$ kubectl delete pv task-pv-volume
persistentvolume "task-pv-volume" deleted
100. 创建 Pod,运行一个 Redis 容器并配置一个卷
  • yaml 文件
apiVersion: v1
kind: Pod
metadata:
  name: redis
spec:
  containers:
  - name: redis
    image: redis
    volumeMounts:
    - name: redis-storage
      mountPath: /data/redis
  volumes:
  - name: redis-storage
    emptyDir: {}
  • 创建 Pod
$ kubectl create -f redis-storage.yaml
pod/redis created
101. 进入 Pod 创建 file.txt 文件,然后打开另一个命令窗口进入 Pod 查看新创建的文件

# 第一个命令行窗口,创建文件
# 进入 Pod
$ kubectl exec -it redis -- /bin/sh
# 进入 yaml 中卷的挂载目录
cd /data/redis
# 创建文件
echo 'This is called the file' > file.txt

# 第二个命令行窗口
$ kubectl exec -it redis -- /bin/sh
# cat /data/redis/file.txt
This is called the file
#

102. 删除 Redis Pod 重新创建,然后查看文件是否会保留
kubectl delete pod redis
kubectl create -f redis-storage.yaml
kubectl exec -it redis /bin/sh
# 新的 Pod 并没有旧的文件
cat /data/redis/file.txt // file doesn't exist
103. 重新创建 PV 和 PVC
$ kubectl create -f task-pv-volume.yaml
persistentvolume/task-pv-volume created

$ kubectl create -f task-pv-claim.yaml
persistentvolumeclaim/task-pv-claim created
104. 创建运行 Nginx 的 Pod,并配置持久卷,挂载到 “/usr/share/nginx/html” 路径
apiVersion: v1
kind: Pod
metadata:
  name: task-pv-pod
spec:
  volumes:
    - name: task-pv-storage
      persistentVolumeClaim:
        claimName: task-pv-claim
  containers:
    - name: task-pv-container
      image: nginx
      ports:
        - containerPort: 80
          name: "http-server"
      volumeMounts:
        - mountPath: "/usr/share/nginx/html"
          name: task-pv-storage
  • 创建 Pod
kubectl create -f task-pv-pod.yaml

五. 配置篇

这部分的练习的主要目标是:

  • 了解 ConfigMap
  • 了解 SecurityContexts
  • 定义一个应用的资源要求
  • 创建与使用 Secret
  • 了解 ServiceAccounts
105. 查看所有的 ConfigMap

$ kubectl get configmaps

$ kubectl get cm
No resources found in default namespace.

106. 基于字面量创建 configmap
$ kubectl create cm myconfigmap --from-literal=appname=myapp
configmap/myconfigmap created
107. 查看刚创建的 configmap 的数据
$ kubectl get cm
NAME          DATA   AGE
myconfigmap   1      91s

$ kubectl describe cm
Name:         myconfigmap
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
appname:
----
myapp
Events:  <none>

$ kubectl get cm -o yaml
108. 删除刚创建的 configmap
kubectl delete cm myconfigmap
109. 创建一个待用文件,包含 key1=value1 和 key2=value2 两个键值对
$ cat >> config.txt << EOF
key1=value1
key2=value2
EOF

# 查看文件
$ cat config.txt
key1=value1
key2=value2
110. 基于上面创建的文件创建 configmap 并查看其数据
# 基于文件创建 configmap
$ kubectl create cm keyvalcfgmap --from-file=config.txt
configmap/keyvalcfgmap created

$ kubectl get cm
NAME           DATA   AGE
keyvalcfgmap   1      15s

# ubuntu @ VM-0-4-ubuntu in ~ [9:09:32]
$ kubectl describe cm keyvalcfgmap
Name:         keyvalcfgmap
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
config.txt:
----
key1=value1
key2=value2

$ kubectl get cm keyvalcfgmap -o yaml
apiVersion: v1
data:
  config.txt: |
    key1=value1
    key2=value2
kind: ConfigMap
metadata:
  creationTimestamp: "2020-04-27T01:09:17Z"
  managedFields:
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:data:
        .: {}
        f:config.txt: {}
    manager: kubectl
    operation: Update
    time: "2020-04-27T01:09:17Z"
  name: keyvalcfgmap
  namespace: default
  resourceVersion: "4394095"
  selfLink: /api/v1/namespaces/default/configmaps/keyvalcfgmap
  uid: 4d750f64-9abd-44cd-a400-66884b3b5f29

111. 创建运行 Nginx 容器的 Pod,从上面创建的 configmap 中加载配置
  • 配置 yaml 文件
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: nginx
  name: nginx
spec:
  containers:
  - image: nginx
    name: nginx
    resources: {}
    # 从指定的 configmap 中加载环境变量
    envFrom:
    - configMapRef:
        name: keyvalcfgmap
  dnsPolicy: ClusterFirst
  restartPolicy: Never
status: {}
  • 查看环境变量后删除

$ kubectl exec -it nginx -- env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=nginx
TERM=xterm
config.txt=key1=value1
key2=value2

$ kubectl delete po nginx
112. 创建 file.env 并基于此文件创建 configmap
$ echo var1=val1 > file.env
cat file.env
var1=val1

$ kubectl create cm envcfgmap --from-env-file=file.env
configmap/envcfgmap created

$ kubectl describe cm envcfgmap
Name:         envcfgmap
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
var1:
----
val1
Events:  <none>

$ kubectl get cm envcfgmap -o yaml
apiVersion: v1
data:
  var1: val1
kind: ConfigMap
metadata:
  creationTimestamp: null
  managedFields:
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:data:
        .: {}
        f:var1: {}
    manager: kubectl
    operation: Update
    time: "2020-04-27T01:16:15Z"
  name: envcfgmap
  selfLink: /api/v1/namespaces/default/configmaps/envcfgmap

113. 基于上面创建的 envcfmap 创建 Nginx 容器的 Pod
  • yaml 文件
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: nginx
  name: nginx
spec:
  containers:
  - image: nginx
    name: nginx
    resources: {}
    envFrom:
    # 配置 configmap
    - configMapRef:
        name: envcfgmap
  dnsPolicy: ClusterFirst
  restartPolicy: Never
status: {}
  • 查看配置后删除
$ kubectl exec -it nginx -- env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=nginx
TERM=xterm
var1=val1

$ kubectl delete po nginx
pod "nginx" deleted

114. 创建 Pod,并设置存储卷从 configmap 读取数据
  • yaml 文件
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: nginx
  name: nginx
spec:
  # 创建 configmap 卷
  volumes:
  - name: nginx-volume
    configMap:
      name: cfgvolume
  containers:
  - image: nginx
    name: nginx
    resources: {}
    volumeMounts:
    # 挂载卷到 /etc/cfg
    - name: nginx-volume
      mountPath: /etc/cfg
  dnsPolicy: ClusterFirst
  restartPolicy: Never
status: {}
  • 创建 yaml 文件并查看对应目录的数据
$ kubectl create -f nginx-volume.yaml
pod/nginx created

$ kubectl exec -it nginx -- /bin/sh
# cd  /etc/cfg
# ls
var1  var2
115. 创建 busybox 的 Pod,并设置 securityContext,所有进程都运行在 user ID 1000 和 组 ID 为 2000 的context 下。
  • yaml 文件
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: secbusybox
  name: secbusybox
spec:
  # 创建 securityContext
  securityContext: # add security context
    runAsUser: 1000
    runAsGroup: 2000
  containers:
  - args:
    - /bin/sh
    - -c
    - sleep 3600;
    image: busybox
    name: secbusybox
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Never
status: {}
  • 创建 Pod 并查看容器的 id 信息
$ kubectl create -f busybox.yaml
pod/secbusybox created

$ kubectl exec -it secbusybox -- sh
/ $ id
uid=1000 gid=2000
116. 创建和上面一样的 Pod,分别在 Pod 和容器层面设置 securityContext,容器层面的 securityContext 会覆盖掉 Pod 层面的设置
  • yaml 文件
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: secbusybox
  name: secbusybox
spec:
  # Pod 设置
  securityContext:
    runAsUser: 1000
  containers:
  - args:
    - /bin/sh
    - -c
    - sleep 3600;
    image: busybox
    # 容器层面的设置
    securityContext:
      runAsUser: 2000
    name: secbusybox
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Never
status: {}
  • 创建并查看 Pod 中的 id 信息
$ kubectl delete pod secbusybox
pod "secbusybox" deleted

$ kubectl create -f busybox.yaml
pod/secbusybox created

$ kubectl exec -it secbusybox -- sh
/ $ id
# 和容器层面的设置一样,覆盖掉了 Pod 层面的设置
uid=2000 gid=0(root)
/ $
117. 创建 Nginx Pod,并配置 NET_ADMIN 和 SYS_TIME
  • yaml 文件
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: nginx
  name: nginx
spec:
  containers:
  - image: nginx
    securityContext:
      capabilities:
        add: ["SYS_TIME", "NET_ADMIN"]
    name: nginx
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Never
status: {}
  • 创建并查看信息
$ kubectl create -f nginx.yaml
pod/nginx created

# ubuntu @ VM-0-4-ubuntu in ~ [9:41:15]
$ kubectl exec -it nginx -- sh
# cd /proc/1
# cat status

CapPrm:	00000000aa0435fb
CapEff:	00000000aa0435fb
118. 创建 Nginx 的 Pod 并设置内存使用限制
  • yaml
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: nginx
  name: nginx
spec:
  containers:
  - image: nginx
    name: nginx
    resources: 
      # 设置内存使用
      requests:
        memory: "100Mi"
      limits:
        memory: "200Mi"
  dnsPolicy: ClusterFirst
  restartPolicy: Never
status: {}
  • 创建并查看 Pod 的内存使用
$ kubectl create -f nginx.yaml
pod/nginx created


$ kubectl top pod
NAME                         CPU(cores)   MEMORY(bytes)
nginx                        0m           2Mi
119. 创建 Nginx 的 Pod 并设置 CPU 使用限制
  • yaml
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: nginx
  name: nginx
spec:
  containers:
  - image: nginx
    name: nginx
    resources:
      # 设置 CPU 的使用限制
      requests:
        cpu: "0.5"
      limits:
        cpu: "1"
  dnsPolicy: ClusterFirst
  restartPolicy: Never
status: {}
  • 创建并查看 CPU 使用
$ kubectl create -f nginx.yaml
pod/nginx created


$ kubectl top pod
NAME                         CPU(cores)   MEMORY(bytes)
nginx                        0m           0Mi
120. 创建 Pod, 同时设置 CPU 和 内存使用限制
  • yaml 文件
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: nginx
  name: nginx
spec:
  containers:
  - image: nginx
    name: nginx
    resources:
      requests:
        memory: "100Mi"
        cpu: "0.5"
      limits:
        memory: "200Mi"
        cpu: "1"
  dnsPolicy: ClusterFirst
  restartPolicy: Never
status: {}
  • 创建并查看资源使用
$ kubectl create -f nginx.yaml
pod/nginx created


$ kubectl top pod
NAME                         CPU(cores)   MEMORY(bytes)
nginx                        0m           0Mi
121.创建运行 Nginx 的 Pod 并设置内存上下限为 100Gi 和 200Gi,查看 Pod 信息
  • yaml 文件
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: nginx
  name: nginx
spec:
  containers:
  - image: nginx
    name: nginx
    resources:
      requests:
        memory: "100Gi"
        cpu: "0.5"
      limits:
        memory: "200Gi"
        cpu: "1"
  dnsPolicy: ClusterFirst
  restartPolicy: Never
status: {}
  • 查看 Pod 信息
$ kubectl create -f nginx.yaml
pod/nginx created

$ kubectl describe pod nginx
...
Events:
  Type     Reason            Age              From               Message
  ----     ------            ----             ----               -------
  Warning  FailedScheduling  5s (x2 over 5s)  default-scheduler  0/2 nodes are available: 2 Insufficient memory.

122. 创建一个 Secret,设置字面量值为 user=myuser 和 password=mypassword
$ kubectl create secret generic my-secret --from-literal=username=user --from-literal=password=mypassword
secret/my-secret created
123. 查看所有的 secret
$ kubectl get secret --all-namespaces
NAMESPACE         NAME                                             TYPE                                  DATA   AGE
default           default-token-wqvj8                              kubernetes.io/service-account-token   3      21d
default           my-secret                                        Opaque                                2      27s
ingress-nginx     default-token-xrdhk                              kubernetes.io/service-account-token   3      21d
ingress-nginx     nginx-ingress-serviceaccount-token-dxt72         kubernetes.io/service-account-token   3      21d
kube-node-lease   default-token-d79ll                              kubernetes.io/service-account-token   3      21d
kube-public       default-token-k2lm9                              kubernetes.io/service-account-token   3      21d
kube-system       attachdetach-controller-token-4qt2z              kubernetes.io/service-account-token   3      21d
kube-system       bootstrap-signer-token-x2z8q                     kubernetes.io/service-account-token   3      21d
kube-system       calico-kube-controllers-token-dhxsb              kubernetes.io/service-account-token   3      21d
kube-system       calico-node-token-w44hg                          kubernetes.io/service-account-token   3      21d
kube-system       certificate-controller-token-rjjgp               kubernetes.io/service-account-token   3      21d
124. 查看 secret 的 yaml 信息
kubectl get secret my-secret -o yaml
125. 创建运行 Nginx 的 Pod,并从 secret 中读取指定信息
  • yaml 文件
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: nginx
  name: nginx
spec:
  containers:
  - image: nginx
    name: nginx
    env:
    # 从 secret 中读取数据
    - name: USER_NAME
      valueFrom:
        secretKeyRef:
          name: my-secret
          key: username
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Never
status: {}
  • 创建并查看 nginx Pod 的环境变量
$ kubectl create -f nginx.yaml
pod/nginx created


$ kubectl exec -it nginx -- env
HOSTNAME=nginx
USER_NAME=user
126. 创建运行 nginx Pod 并加载 secret 中的所有字段为环境变量
  • yaml 文件
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: nginx
  name: nginx
spec:
  containers:
  - image: nginx
    name: nginx
    envFrom:
    # 加载整个 secret
    - secretRef:
        name: my-secret
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Never
status: {}
  • 创建 Pod 查看环境变量
$ kubectl create -f nginx.yaml
pod/nginx created

$ kubectl exec -it nginx -- env
...
password=mypassword
username=user
127. 获取 default 命名空间下的 service accounts
$ kubectl get sa
NAME      SECRETS   AGE
default   1         21d

128. 获取所有的 service accounts
kubectl get sa --all-namespaces
129. 创建名为 admin 的 service account
$ kubectl create sa admin
serviceaccount/admin created

130. 查看上面创建的 service account 的 yaml 信息
$ kubectl get sa admin -o yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  creationTimestamp: "2020-04-27T13:31:22Z"
  name: admin
  namespace: default
  resourceVersion: "4502353"
  selfLink: /api/v1/namespaces/default/serviceaccounts/admin
  uid: 3995f3da-6850-4a38-ac11-a5451fa6b5d2
secrets:
- name: admin-token-tpcpv
131. 创建运行 busybox 的 Pod 并设置 serviceAccount
  • yaml 文件设置
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: busybox
  name: busybox
spec:
  serviceAccountName: admin
  containers:
  - args:
    - /bin/sh
    - -c
    - sleep 3600
    image: busybox
    name: busybox
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Never
status: {}
  • 创建并查看 Pod
kubectl create -f busybox.yml
// verify
kubectl describe po busybox

六. 集群监控篇

这部分练习主要涉及下面一些目标:

  • 理解存活探针 livenessProbes and ReadinessProbes
  • 了解容器日志
  • 了解如何监控 K8S 中运行的应用
  • 了解 K8S 的 debug
132. 创建带有 Readiness 的 Nginx Pod
  • yaml 文件
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: nginx
  name: nginx
spec:
  containers:
  - image: nginx
    name: nginx
    ports:
    - containerPort: 80
    readinessProbe:
      httpGet:
        path: /
        port: 80
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Never
status: {}
  • 创建并查看 readiness
$ kubectl create -f nginx-pod.yaml
pod/nginx created


$ kubectl describe pod nginx | grep -i readiness
    Readiness:      http-get http://:80/ delay=0s timeout=1s period=10s #success=1 #failure=3
133. 创建带有 livenessProbe 的 Nginx Pod
  • yaml 文件
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: nginx
  name: nginx
spec:
  containers:
  - image: nginx
    name: nginx
    ports:
    - containerPort: 80
    livenessProbe:
      httpGet:
        path: /healthz
        port: 80
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Never
status: {}
  • 创建并查看 Pod
$ kubectl create -f nginx-pod.yaml
pod/nginx created

$ kubectl describe pod nginx | grep -i readiness

$ kubectl describe pod nginx | grep -i liveiness

$ kubectl describe pod nginx | grep -i liveness
    Liveness:       http-get http://:80/healthz delay=0s timeout=1s period=10s #success=1 #failure=3
  Warning  Unhealthy  7s    kubelet, vm-0-2-ubuntu  Liveness probe failed: HTTP probe failed with statuscode: 404
134. 创建 Nginx Pod,添加 liveness 和 readiness
  • yaml 文件

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: nginx
  name: nginx
spec:
  containers:
  - image: nginx
    name: nginx
    ports:
    - containerPort: 80
    livenessProbe:
      httpGet:
        path: /healthz
        port: 80
    readinessProbe:
      httpGet:
        path: /
        port: 80
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Never
status: {}
  • 创建并查看 Pod
kubectl create -f nginx-pod.yaml

// verify
kubectl describe pod nginx | grep -i readiness
kubectl describe pod nginx | grep -i liveness
135. 查看 liveness 和 reeadiness 的命令选项
kubectl explain Pod.spec.containers.livenessProbe
kubectl explain Pod.spec.containers.readinessProbe

136. 创建带有 readiness 和 liveness 的 Pod,并设置初次检测时间与检测间隔
  • yaml 文件
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: nginx
  name: nginx
spec:
  containers:
  - image: nginx
    name: nginx
    ports:
    - containerPort: 80
    livenessProbe:
      # 启动 20s 后开始检测
      initialDelaySeconds: 20
      # 每 25 秒检测一次
      periodSeconds: 25
      httpGet:
        path: /healthz
        port: 80
    readinessProbe:
      initialDelaySeconds: 20
      periodSeconds: 25
      httpGet:
        path: /
        port: 80
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Never
status: {}
137. 创建 busybox 并打印信息
# 创建 Pod
$ kubectl run busybox --image=busybox --restart=Never -- /bin/sh -c "echo I am from busybox pod; sleep 3600;"
pod/busybox created


# 打印日志
$ kubectl logs busybox
I am from busybox pod
138. 将上面 Pod 的日志存入文件 busybox-logs.txt
$ kubectl logs busybox > busybox-logs.txt


$ cat busybox-logs.txt
I am from busybox pod

139. 查看所有 events,基于 timestamp 排序,并将 events 信息存入到 file.log 文件中
kubectl get events --sort-by=.metadata.creationTimestamp

$ kubectl get events --sort-by=.metadata.creationTimestamp > file.log

$ cat file.log
LAST SEEN   TYPE      REASON      OBJECT        MESSAGE
16m         Normal    Killing     pod/nginx     Stopping container nginx
16m         Normal    Scheduled   pod/nginx     Successfully assigned default/nginx to vm-0-2-ubuntu
16m         Normal    Pulling     pod/nginx     Pulling image "nginx"
15m         Normal    Started     pod/nginx     Started container nginx
15m         Normal    Created     pod/nginx     Created container nginx
15m         Normal    Pulled      pod/nginx     Successfully pulled image "nginx"

140. 创建 imgee 为 alpine 的 Pod 并执行命令每 5s 打印一次日志
# 创建 Pod
$ kubectl run hello --image=alpine --restart=Never  -- /bin/sh -c "while true; do echo 'Hi I am from Alpine'; sleep 5;done"
pod/hello created


# 查看日志
$ kubectl logs --follow hello
Hi I am from Alpine
Hi I am from Alpine
Hi I am from Alpine

141. 基于下面命令创建 Pod ,启动失败时查看错误原因并修正
# 创建 Pod
$ kubectl create -f https://gist.githubusercontent.com/bbachi/212168375b39e36e2e2984c097167b00/raw/1fd63509c3ae3a3d3da844640fb4cca744543c1c/not-running.yml

pod/not-running created

# 查看 Pod
$ kubectl get pod not-running
NAME          READY   STATUS             RESTARTS   AGE
not-running   0/1     ImagePullBackOff   0          7s

$ kubectl describe po not-running
...
Events:
  Type     Reason          Age                From                    Message
  ----     ------          ----               ----                    -------
  Normal   Scheduled       39s                default-scheduler       Successfully assigned default/not-running to vm-0-2-ubuntu
  Normal   SandboxChanged  34s                kubelet, vm-0-2-ubuntu  Pod sandbox changed, it will be killed and re-created.
  Normal   Pulling         19s (x2 over 37s)  kubelet, vm-0-2-ubuntu  Pulling image "ngin"
  Warning  Failed          16s (x2 over 35s)  kubelet, vm-0-2-ubuntu  Failed to pull image "ngin": rpc error: code = Unknown desc = Error response from daemon: pull access denied for ngin, repository does not exist or may require 'docker login': denied: requested access to the resource is denied
  Warning  Failed          16s (x2 over 35s)  kubelet, vm-0-2-ubuntu  Error: ErrImagePull
  Normal   BackOff         1s (x4 over 33s)   kubelet, vm-0-2-ubuntu  Back-off pulling image "ngin"
  Warning  Failed          1s (x4 over 33s)   kubelet, vm-0-2-ubuntu  Error: ImagePullBackOff

# 修改错误
kubectl edit pod not-running
or
kubectl set image pod/not-running not-running=nginx

142. 利用下面命令创建 4 个 namespace 和 4 个 pods,查看错误的 Pod 并修正
$ kubectl create -f https://gist.githubusercontent.com/bbachi/1f001f10337234d46806929d12245397/raw/84b7295fb077f15de979fec5b3f7a13fc69c6d83/problem-pod.yaml
namespace/namespace1 created
namespace/namespace2 created
namespace/namespace3 created
namespace/namespace4 created
pod/pod1 created
pod/pod2 created
pod/pod3 created
pod/pod4 created

$ kubectl get po --all-namespaces

$ kubectl get po -n namespace2
NAME   READY   STATUS             RESTARTS   AGE
pod2   0/1     ImagePullBackOff   0          46s

$ kubectl set image pod/pod2 pod2=nginx -n namespace2
pod/pod2 image updated

$ kubectl get po -n namespace2
NAME   READY   STATUS    RESTARTS   AGE
pod2   1/1     Running   0          55s
143. 查看所有 Pod 的 CPU 与内存使用并查找出 CPU 使用率最高的三个
$ kubectl top pod --all-namespaces | sort --reverse --key 3 --numeric | head -3
kube-system     kube-apiserver-vm-0-4-ubuntu                23m          308Mi
kube-system     calico-node-njsrv                           23m          29Mi
kube-system     calico-node-ltpqg                           17m          28Mi

# 将信息写入文件
$ kubectl top pod --all-namespaces | sort --reverse --key 3 --numeric | head -3 > cpu-usage.txt

$ cat cpu-usage.txt
kube-system     kube-apiserver-vm-0-4-ubuntu                23m          308Mi
kube-system     calico-node-njsrv                           23m          29Mi
kube-system     calico-node-ltpqg                           17m          28Mi

七. 服务与网络篇

这部分的了解主要有下面两个目的:

  • 了解 Service
  • 对 NetworkPolicies 有一个基本了解
144. 创建 Nginx Pod,打上 app=my-nginx 标签并开放 80 端口
  • yaml 文件
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    app: my-nginx
  name: nginx
spec:
  containers:
  - image: nginx
    name: nginx
    ports:
    - containerPort: 80
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Never
status: {}
  • 创建 Pod
$ kubectl create -f nginx.yaml
pod/nginx created
145. 为 Pod 创建 Service
  • yaml 文件
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: my-nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376
  • 创建 service
$ kubectl create -f nginx-svc.yaml
service/my-service created
146. 查看 Pod 与 Service
$ kubectl get po nginx --show-labels
NAME    READY   STATUS    RESTARTS   AGE     LABELS
nginx   1/1     Running   0          2m17s   app=my-nginx


$ kubectl get svc my-service -o wide
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE   SELECTOR
my-service   ClusterIP   10.104.9.185   <none>        80/TCP    38s   app=my-nginx

147. 删除 my-service,并使用 kubectl expose 命令重建
$ kubectl delete svc my-service
service "my-service" deleted

$ kubectl expose po nginx --port=80 --target-port=9376
service/nginx exposed

$ kubectl get svc -l app=my-nginx
NAME    TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
nginx   ClusterIP   10.109.228.97   <none>        80/TCP    6s
148. 删除上面创建的 Service 并重建,指定 type 为 NodePort
$ kubectl delete svc nginx
service "nginx" deleted


$ kubectl expose po nginx --port=80 --type=NodePort
service/nginx exposed
149. 创建临时 busybox Pod 并通过 nginx Service 访问 Nginx Pod
$ kubectl get svc nginx -o wide
NAME    TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE    SELECTOR
nginx   NodePort   10.108.87.189   <none>        80:31305/TCP   2m1s   app=my-nginx

$ kubectl run busybox --image=busybox --restart=Never -it --rm -- wget -o- 10.108.87.189:80
Connecting to 10.108.87.189:80 (10.108.87.189:80)
saving to 'index.html'
index.html           100% |********************************|   612  0:00:00 ETA
'index.html' saved
pod "busybox" deleted
150. 创建 NetworkPolicy,拒绝所有入口流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  • 创建 networkpolicy
$ kubectl create -f network-policy.yaml
networkpolicy.networking.k8s.io/default-deny created

以上就是完整的 150 个练习了,K8S 的学习是理论与实践并重的,既要理解集群、组件的设计思想与原理,还要熟练掌握各种 API 的操作,唯一的方法就是不断练习练习再练习。
不过上面的 150 个练习我觉得内容设置的并不合理,有些地方重复了,而有些地方比如网络这一块练习量又不够,后面有时间了在这几篇文章的基础之上补充一部分其他的练习。

我是 AhriJ邹同学,前后端、小程序、DevOps 都搞的炸栈工程师。博客持续更新,欢迎小伙伴关注或与我私信交流,互相学习,共同进步。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值