Kubernetes CKA 证书备考笔记
dezehang 2024-11-21 13:51 2 浏览
Kubernetes 使用有好几年了,但在今年 5 月才完成 CKA 的考试。虽说用了几年,还是提前刷了部分题熟悉下。
绝大部分题都是有在 minikube 的环境上操作过,只有部分比如升级集群受限于环境问题没有实地操作。
写在最前
- 保存常用文档进书签,如果有 Alfred 启用浏览器书签 workflow。效果见下图
- kubectl 自动补全
echo "source <(kubectl completion bash)" >> ~/.bashrc; source ~/.bashrc
- 每道题开始前要切换 context 和 namespace,直接复制题目里的命令即可
- 必要的 alias
- 善用
--dry-run=client -o yaml
避免手动敲太多 - 善用
kubectl explain [resource[.field]]
- 看懂题目最重要,输出正确的结果更重要(重要的事讲三遍)
- 看懂题目最重要,输出正确的结果更重要(重要的事讲三遍)
- 看懂题目最重要,输出正确的结果更重要(重要的事讲三遍)
书签地址:K8s-CKA-CAKD-Bookmarks.html
安全:RBAC
在默认命名空间中创建一个名为 dev-sa 的服务帐户,dev-sa 可以在 dev 命名空间中创建以下组件:
Deployment
、StatefulSet
、DaemonSet
知识点
- role
- sa
- rolebinding
- auth can-i
参考文档:https://kubernetes.io/docs/reference/access-authn-authz/rbac/#command-line-utilities
解题思路
$ kubectl create sa dev-sa
$ kubectl create role dev-role --verb=create --resource=deployment,statefulset,daemonset
#检查
$ kubectl describe role dev-role
Name: dev-role
Labels: <none>
Annotations: <none>
PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
daemonsets.apps [] [] [create]
deployments.apps [] [] [create]
statefulsets.apps [] [] [create]
$ kubectl create rolebinding dev --serviceaccount default:dev-sa --role dev-role
#检查
$ kubectl auth can-i create deployment --as system:serviceaccount:default:dev-sa
yes
$ kubectl auth can-i create statefulset --as system:serviceaccount:default:dev-sa
yes
$ kubectl auth can-i create daemonset --as system:serviceaccount:default:dev-sa
yes
$ kubectl auth can-i create pod --as system:serviceaccount:default:dev-sa
no
多容器 Pod
创建一个pod名称日志,容器名称
log-pro
使用imagebusybox
,在/log/data/output.log
输出重要信息。然后另一个容器名称log-cus
使用 imagebusybox
,在/log/data/output.log
加载output.log
并打印它。 请注意,此日志文件只能在 pod 内共享。
知识点
- pod
- volume: emptyDir
参考文档:https://kubernetes.io/docs/concepts/storage/volumes/#emptydir
解题思路
kubectl run log --image busybox --dry-run=client -o yaml > log.yaml
修改 log.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: log
name: log
spec:
containers:
- command:
- sh
- -c
- echo important information > /log/data/output.log; sleep 1d
image: busybox
name: log-pro
resources: {}
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: /log/data
name: log
- command:
- sh
- -c
- tail -f /log/data/output.log
image: busybox
name: log-cus
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: /log/data
name: log
dnsPolicy: ClusterFirst
restartPolicy: Always
volumes:
- name: log
emptyDir: {}
status: {}
执行创建 kubectl apply -f log.yaml
检查
$ kubectl logs log -c log-cus
important information
安全:网络策略 NetworkPolicy
只有命名空间
mysql
的 pod 只能被另一个命名空间internal
的 pod 通过 8080 端口进行访问
知识点
- NetworkPolicy
- Ingress
参考文档:https://kubernetes.io/docs/concepts/services-networking/network-policies/#the-networkpolicy-resource
解题思路
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: cka-network
namespace: target #目的命名空间
spec:
podSelector: {}
policyTypes:
- Ingress #策略影响入栈流量
ingress:
- from: #允许流量的来源
- namespaceSelector:
matchLabels:
ns: source #源命名空间的 label
ports:
- protocol: TCP
port: 8080 #允许访问的端口
节点状态及污点
统计这个集群中没有污染的就绪节点,并输出到文件
/root/cka/readyNode.txt
。
知识点
- Node
- Taint(污点)
参考文档:https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/
解题思路
# Ready 状态的数量
$ kubectl get node | grep -w Ready | wc -l
# 查看含有 Taint 的数量,需要排除掉这些
$ kubectl describe node | grep Taints | grep -i NoSchedule | wc -l
资源
将占用CPU资源最多的pod名称输出到文件
/root/cka/name.txt
知识点
- kubectl top 命令
- metrics
解题思路
如果是 minikube 环境,报错 error: Metrics API not available
,可以执行 minikube addons enable metrics-server
命令开启 metrics server。
通过 kubectl top
命令找到 cpu 最高的 pod,将其名字写入 /root/cka/name.txt
。
$ kubectl top pod
# 或者
$ kubectl top pod | sort -k 2 -n
网络:DNS
有 pod 名称
pod-nginx
,创建服务名称service-nginx
,使用nodePort
暴露pod。 然后创建一个 pod 使用 imagebusybox
来nslookup
podpod-nginx
和 serviceservice-nginx
。
知识点
- service with nodePort
- kubectl expose
- kubectl run
参考文档:https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/
解题思路
使用 kubectl expose
创建 service。
# 创建 service
kubectl expose pod pod-nginx --name service-nginx --type NodePort --target-port 80
# 创建 pod
kubectl run busybox --image busybox:latest --command sleep 1h
获取 pod 的 ip 地址,pod 的 dns lookup 需要用用到 ip。
$ kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
busybox 1/1 Running 0 2m17s 172.17.0.5 cka <none> <none>
pod-nginx 1/1 Running 0 59m 172.17.0.4 cka <none> <none>
执行 nslookup
$ kubectl exec busybox -it -- nslookup 172.17.0.4
4.0.17.172.in-addr.arpa name = 172-17-0-4.service-nginx.default.svc.cluster.local.
$ kubectl exec busybox -it -- nslookup service-nginx
Server: 10.96.0.10
Address: 10.96.0.10#53
Name: service-nginx.default.svc.cluster.local
Address: 10.110.253.70
工作负载:扩容
将命名空间
dev
中的 Deploymentscale-deploy
缩放到三个 pod 并记录下来。
参考文档:https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#scaling-a-deployment
知识点
- deployment scale up
- kubectl scale
解题思路
kubectl scale
的使用,需要参数 --record
进行记录(将操作命令记录到 deployment 的 kubernetes.io/change-cause
annotation 中)。
$ kubectl scale deployment scale-deploy --replicas 3 --record
集群备份及恢复
备份 etcd 并将其保存在主节点上的
/root/cka/etcd-backup.db
。
最后恢复备份。
知识点
- etcd 的备份及恢复
解题思路
Kubernetes 的所有数据都记录在 etcd 中,对 etcd 进行备份就是对集群进行备份。
连接 etcd 需要证书,证书可以从 apiserver 获取,因为 apiserver 需要连接 etcd。新版本的 apiserver 都是以 static pod 的方式运行,证书是通过 volume 挂载到 pod 中的。
比如 minikube 环境,证书是从 node 节点的 /var/lib/minikube/certs
挂载进去的。
要先 ssh 到 master 节点上。命令的执行非常快,如果长时间没结束,那就说名有问题了。
#备份
$ ETCDCTL_API=3 etcdctl snapshot save /root/cka/etcd-backup.db \
--endpoints=https://127.0.0.1:2379 \
--cacert=/var/lib/minikube/certs/etcd/ca.crt \
--cert=/var/lib/minikube/certs/apiserver-etcd-client.crt \
--key=/var/lib/minikube/certs/apiserver-etcd-client.key
由于只说了 restore,所以就执行 restore 的命令,默认会恢复到当前目录的 default.etcd
下。
#恢复
$ ETCDCTL_API=3 etcdctl snapshot restore /root/cka/etcd-backup.db \
--endpoints=https://127.0.0.1:2379 \
--cacert=/var/lib/minikube/certs/etcd/ca.crt \
--cert=/var/lib/minikube/certs/apiserver-etcd-client.crt \
--key=/var/lib/minikube/certs/apiserver-etcd-client.key
集群节点升级
将master节点版本从 1.20.0 升级到 1.21.0,确保 master 节点上的 pod 重新调度到其他节点,升级完成后,使 master 节点可用。
知识点
- drain
- cordon
解题思路
受限于环境,没有实地操作。
# 将节点设置为不可调度
$ kubectl cordon master
# 驱逐 master 节点上的 pod
$ kubectl drain master --ignore-daemonsets
# 进行升级
$ apt-mark unhold kubelet kubectl && \
apt-get update && apt-get install -y kubelet=1.21.0-00 kubectl=1.21.0-00 && \
apt-mark hold kubelet kubectl
# 重新启动kubelet
$ systemctl daemon-reload
$ systemctl restart kubelet
# 将节点设置为可调度
$ kubectl uncordon master
集群:节点故障排查
现在 node01 还没有准备好,请找出根本原因并使其准备好,然后创建一个确保它在 node01 上运行的 pod。
知识点
- 节点故障排查
解题思路
这种问题大概率问题出在 kubelet 上
ssh node01
systemctl status kubelet
systemctl restart kubelet
# 再检查node状态
插播一个故障,本地安装 2 个节点的 minikube 集群时,第二个节点持续 NotReady
。使用 systemctl status kubelet
看到 unable to update cni config: no networks found in /etc/cni/net.mk
。
检查该目录确实没有文件,从 master 节点复制到该节点后重启 kubelet 解决。
存储:持久化卷
集群中有一个持久卷名称
dev-pv
,创建一个持久卷声明名称dev-pvc
,确保这个持久卷声明会绑定持久卷,然后创建一个 pod 名称test-pvc
,将这个 pvc 挂载到 path/tmp/data
,使用 nginx 镜像。
知识点
- PersistentVolume
- PersistentVolumeClaim
- Mount Volume
解题思路
创建 pvc 前先获取 pv的信息
$ kubectl get pv dev-pv -o yaml
创建 pv
$ cat > pvc.yaml <<EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: dev-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
EOF
$ kubectl apply -f pvc.yaml
创建 pod 的 manifest,记得使用 kubectl run --dry-run=client -o yaml
kubectl run test-pvc --image nginx --dry-run=client -o yaml > test-pvc.yaml
修改之后得到最终的 pod yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: test-pvc
name: test-pvc
spec:
volumes:
- name: data
persistentVolumeClaim:
claimName: dev-pvc
containers:
- image: nginx
name: test-pvc
resources: {}
volumeMounts:
- name: data
mountPath: /tmp/data
dnsPolicy: ClusterFirst
restartPolicy: Always
理论上只要 pod 能运行,就说明成功。也可以进一步确认挂载是否成功,在 pod 的 /tmp/data
中 touch 个文件,然后到节点的目录中查看是有该文件。
工作负载:多容器的 Deployment
创建一个名为
deploy-important
的 Deployment,标签为id=very-important
(pod 也应该有这个标签)和命名空间 dev 中的 3 个副本。 它应该包含两个容器,第一个名为container1
并带有镜像,第二个名为 container2 的图像为kubernetes/pause
。
在一个工作节点上应该只运行该部署的一个 Pod。 我们有两个工作节点:
cluster1-worker1
和cluster1-worker2
。 因为 Deployment 有三个副本,所以结果应该是在两个节点上都有一个 Pod 正在运行。 不会调度第三个 Pod,除非添加新的工作节点。
知识点
- deployment
- pod label
- replicas
- multi container pod
- pod anti affinity
解题思路
先创建模板
$ kubectl create deployment deploy-important --image nginx --replicas 3 --dry-run=client -o yaml > deploy-important.yaml
修改后的 yaml
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: deploy-important
id: very-important
name: deploy-important
spec:
replicas: 3
selector:
matchLabels:
app: deploy-important
id: very-important
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: deploy-important
id: very-important
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: id
operator: In
values:
- very-important
topologyKey: kubernetes.io/hostname
containers:
- image: nginx
name: container1
resources: {}
- image: kubernetes/pause
name: container2
status: {}
minikube 上测试只能调度一个 pod,符合预期
$ kgpo
NAME READY STATUS RESTARTS AGE
deploy-important-659d54fc47-6cp8r 0/2 Pending 0 3h10m
deploy-important-659d54fc47-92z4d 2/2 Running 0 3h10m
deploy-important-659d54fc47-c6llc 0/2 Pending 0 3h10m
存储:Secret的使用
在
secret
命名空间下,使用镜像busybox:1.31.1
创建一个名为secret-pod
的 pod,并保证 pod 运行一段时间
有个名为
sercret1.yaml
的 Secret 文件,在secret
命名空间下创建 Secret,并以只读的方式挂在到 Pod 的/tmp/secret1
目录创建一个新的 Secretsecret2
包含user=user1
和pass=1234
,分别以缓解变量APP_USER
和APP_PASS
输入到 Pod 中
知识点
- secret
- toleration
- taints
参考文档:https://kubernetes.io/docs/concepts/configuration/secret/#using-secretshttps://kubernetes.io/docs/concepts/configuration/secret/#using-secrets-as-environment-variables
解题思路
创建 namespace
$ kubectl create ns secret
创建 pod 模板
$ kubectl run secret-pod --image busybox:1.31.1 --dry-run=client -o yaml --command -- sleep 1d > secret-pod.yaml
修改 secret1.yaml,使用 secret namespace
apiVersion: v1
data:
halt: IyEvYmluL2Jhc2g=
kind: Secret
metadata:
creationTimestamp: "2021-05-15T07:48:02Z"
name: secret1
namespace: secret
type: Opaque
创建 secret2
$ kubectl create secret generic secret2 --from-literal user=user1 --from-literal pass=1234
修改模板
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: secret-pod
name: secret-pod
spec:
containers:
- command:
- sleep
- 1d
image: busybox:1.31.1
name: secret-pod
env:
- name: APP_USER
valueFrom:
secretKeyRef:
name: secret2
key: user
- name: APP_PASS
valueFrom:
secretKeyRef:
name: secret2
key: pass
resources: {}
volumeMounts:
- mountPath: /tmp/secret1
name: sec
dnsPolicy: ClusterFirst
restartPolicy: Always
volumes:
- name: sec
secret:
secretName: secret1
status: {}
检查结果:
$ kubectl exec secret-pod -- cat /tmp/secret1/halt
#!/bin/bash
$ kubectl exec secret-pod -- env | grep 'APP_'
APP_USER=user1
APP_PASS=1234
工作负载:静态 Pod
在
cluster3-master1
上的default
命名空间中创建一个名为my-static-pod
的静态 Pod。 使用镜像nginx:1.16-alpine
并分配 10m CPU 和 20Mi 内存的资源。
Then create a NodePort Service named static-pod-service which exposes that static Pod on port 80 and check if it has Endpoints and if its reachable through the cluster3-master1 internal IP address. You can connect to the internal node IPs from your main terminal.然后创建一个名为
static-pod-service
的 NodePort Service,该服务在端口 80 上公开该静态 Pod,并检查它是否具有端点以及是否可以通过cluster3-master1
内部 IP 地址访问它。
知识点
- static pod
- resource
- nodeport service
- endpoints
参考文档:
- https://kubernetes.io/docs/tasks/configure-pod-container/static-pod/
- https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#meaning-of-memory
解题思路
创建pod模板
$ kubectl run my-static-pod --image nginx:1.16-alpine --dry-run=client -o yaml > static-pod.yaml
修改模板,增加资源配置
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: my-static-pod
name: my-static-pod
spec:
containers:
- image: nginx:1.16-alpine
name: my-static-pod
resources:
requests:
cpu: "10m"
memory: "20Mi"
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
ssh 到主机,找到 kubelet 配置文件的位置 ps -ef | grep kubelet
查看配置文件(minikube:/var/lib/kubelet/config.yaml)中 staticPodPath
配置的就是静态 pod 的 manifest 的位置(minikube:/etc/kubernetes/manifests)
将 static-pod.yaml
放到正确的文件夹中,然后重启 kubelet
$ systemctl restart kubelet
检查pod是否正确运行
创建 node port
$ kubectl expose pod my-static-pod --name static-pod-service --type NodePort --port 80
检查是否创建成功
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
static-pod-service NodePort 10.97.248.99 <none> 80:31938/TCP 68s
获取 node 的 ip
$ kubectl get node -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
cka Ready master 10h v1.18.8 192.168.64.3 <none> Buildroot 2020.02.10 4.19.171 docker://20.10.4
在 minikube 的环境下可直接通过 minikube ip
获取
测试
$ http 192.168.64.3:31938 --headers
HTTP/1.1 200 OK
Accept-Ranges: bytes
Connection: keep-alive
Content-Length: 612
Content-Type: text/html
Date: Sat, 15 May 2021 08:35:11 GMT
ETag: "5d52db33-264"
Last-Modified: Tue, 13 Aug 2019 15:45:55 GMT
Server: nginx/1.16.1
调度:污点和容忍度
在命名空间
default
中创建图像httpd:2.4.41-alpine
的单个 Pod。Pod 应命名为pod1
,容器名为pod1-container
。在不给任何节点添加新标签的前提下,将该 pod 调度到主节点上。
知识点
- Taint
- Label
- Tolerance
参考文档:https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/
解题思路
#找出master节点(一般考试只有一个节点)
$ kubectl get node
#找到 master 节点的 taints,需要在 pod 的 .spec.tolerations 排除掉
$ kubectl describe node xxxx | grep -w Taints
#找到 master 节点的 labels
$ kubectl describe node xxxx | grep -w Labels -A10
创建pod模板
$ kubectl run pod1 --image httpd:2.4.41-alpine --dry-run=client -o yaml > pod1.yaml
修改模板: 这里假设主节点的 Taint 为 node-role.kubernetes.io/master=:NoSchedule
# minikube 集群名为 cka,主节点同名
$ kubectl describe node cka | grep -i taint
Taints: node-role.kubernetes.io/master:NoSchedule
最终的 pod 如下
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: pod1
name: pod1
spec:
containers:
- image: httpd:2.4.41-alpine
name: pod1
resources: {}
dnsPolicy: ClusterFirst
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
nodeSelector:
node-role.kubernetes.io/master: ""
restartPolicy: Always
status: {}
最后检查下是否调度到主节点上:
$ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod1 1/1 Running 0 102s 10.244.0.3 cka <none> <none>
kubectl 命令和排序
所有命名空间中都有各种 Pod。 将命令写入 /opt/course/5/find_pods.sh,其中列出所有按 AGE 排序的 Pod(metadata.creationTimestamp)。
将第二个命令写入 /opt/course/5/find_pods_uid.sh,其中列出按字段 metadata.uid 排序的所有 Pod。对这两个命令都使用 kubectl 排序。
知识点
- kubectl 命令的使用,主要是
--all-namespaces
(缩写-A
) 和--sort-by
解题思路
$ cat > /opt/course/5/find_pods.sh <<EOF
kubectl get pod -A --sort-by '.metadata.creationTimestamp'
EOF
$ cat > /opt/course/5/find_pods_uid.sh <<EOF
kubectl get pod -A --sort-by '.metadata.uid'
EOF
存储:持久化卷和挂载
创建一个名为
safari-pv
的新PersistentVolume
。它应该具有 2Gi 的容量、accessMode
ReadWriteOnce
、hostPath
/Volumes/Data
并且没有定义storageClassName
。
接下来在命名空间
project-tiger
中创建一个名为safari-pvc
的新PersistentVolumeClaim
。 它应该请求 2Gi 存储,accessMode
ReadWriteOnce
并且不应定义storageClassName
。 PVC 应该正确绑定到 PV。
最后在命名空间
project-tiger
中创建一个新的 Deploymentsafari
,它将该卷挂载到/tmp/safari-data
。该 Deployment 的 Pod 应该是镜像 httpd:2.4.41-alpine。
知识点
- pv
- pvc
- pod 使用 pvc
- deployment
- mount PVC volume
参考文档:
- https://kubernetes.io/docs/tasks/configure-pod-container/configure-persistent-volume-storage/#create-a-persistentvolume
- https://kubernetes.io/docs/tasks/configure-pod-container/configure-persistent-volume-storage/#create-a-persistentvolumeclaim
- https://kubernetes.io/docs/concepts/storage/persistent-volumes/#claims-as-volumes
解题思路
创建 pv
apiVersion: v1
kind: PersistentVolume
metadata:
name: safari-pv
labels:
type: local
spec:
capacity:
storage: 2Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/Volumes/Data"
创建 pvc
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: safari-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Gi
检查是否绑定成功
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
safari-pvc Bound pvc-d4c15825-2de3-470f-8ed0-9519cacaad21 2Gi RWO standard 24s
创建 deployment 模板
$ kubectl create deployment safari --image httpd:2.4.41-alpine --dry-run=client -o yaml
最终的yaml
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: safari
name: safari
spec:
replicas: 1
selector:
matchLabels:
app: safari
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: safari
spec:
containers:
- image: httpd:2.4.41-alpine
name: httpd
resources: {}
volumeMounts:
- mountPath: /tmp/safari-data
name: data
volumes:
- name: data
persistentVolumeClaim:
claimName: safari-pvc
status: {}
kubectl 命令和 context
可以通过 kubectl 上下文从主终端访问多个集群。将所有这些上下文名称写入 /opt/course/1/contexts。
接下来在 /opt/course/1/context_default_kubectl.sh 中写一个显示当前上下文的命令,该命令应该使用kubectl。
最后在 /opt/course/1/context_default_no_kubectl.sh 中写入第二个执行相同操作的命令,但不使用 kubectl。
知识点
kubectl config 相关命令的使用
解题思路
kubectl config get-contexts -o name > /opt/course/1/contexts
cat > /opt/course/1/context_default_kubectl.sh <<EOF
kubectl config current-context
EOF
chmod +x /opt/course/1/context_default_kubectl.sh
cat ~/.kube/config | grep current-context | awk '{print $2}'
工作负载:缩容
命名空间
project-c13
中有两个名为o3db-*
的 Pod。 C13 管理层要求将 Pod 缩减为一个副本以节省资源。 记录动作。
知识点
- scale
- deploy
- statefulset
参考文档:https://kubernetes.io/zh/docs/tasks/run-application/scale-stateful-set/https://kubernetes.io/zh/docs/concepts/workloads/controllers/deployment/#scaling-a-deployment
解题思路
kubectl scale <resource> xxx --replicas=1
scale 命令需要确认资源类型:deployment/statefulset
应用就绪和探活
在命名空间
default
中执行以下操作。为nginx:1.16.1-alpine
创建一个名为ready-if-service-ready
的 Pod。配置一个LivenessProbe
,它只是运行true
。还要配置一个ReadinessProbe
来检查url
http://service-am-i-ready:80
是否可达,可以使用wget -T2 -O- http://service-am-i-ready:80
。 启动 Pod 并确认它因为ReadinessProbe
而没有准备好。
创建第二个名为
am-i-ready
的 Pod 镜像nginx:1.16.1-alpine
,标签id:cross-server-ready
。已经存在的服务service-am-i-ready
现在应该有第二个 Pod 作为端点。
知识点
- probe
- pod
解题思路
kubectl run ready-if-service-ready --image nginx:1.16.1-alpine --dry-run=client -o yaml > ready-if-service-ready.yaml
kubectl run am-i-ready --image nginx:1.16.1-alpine --labels id=cross-server-ready --dry-run=client -o yaml > am-i-ready.yaml
添加 probes
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: ready-if-service-ready
name: ready-if-service-ready
spec:
containers:
- image: nginx:1.16.1-alpine
name: ready-if-service-ready
resources: {}
livenessProbe:
exec:
command:
- echo
- hi
readinessProbe:
exec:
command:
- wget
- -T2
- -O-
- http://service-am-i-ready:80
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
集群:控制平面
使用
ssh cluster1-master1
ssh 进入主节点。检查 master 组件 kubelet、kube-apiserver、kube-scheduler、kube-controller-manager 和 etcd 如何在 master 节点上启动/安装。还要找出 DNS 应用的名称以及它是如何在主节点上启动/安装的。
将结果写入文件 /opt/course/8/master-components.txt。该文件的结构应如下所示:
# /opt/course/8/master-components.txt kubelet: [TYPE] kube-apiserver: [TYPE] kube-scheduler: [TYPE] kube-controller-manager: [TYPE] etcd: [TYPE] dns: [TYPE] [NAME]
Choices of [TYPE] are: not-installed, process, static-pod, pod
知识点
Kubernetes components 的安装方式
解题思路
当前比较的组件都是以static pod的形式运行的,而 static pod 都是由 Kubelet 管理的,所以从 kubelet 处入手。
以 minikube 为例:
$ ps -ef | grep -w kubelet
root 140597 1 2 May15 ? 00:36:00 /var/lib/minikube/binaries/v1.18.8/kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --config=/var/lib/kubelet/config.yaml --container-runtime=docker --hostname-override=cka --kubeconfig=/etc/kubernetes/kubelet.conf --node-ip=192.168.64.3
$ systemctl is-active kubelet
active
#kubelet: process
根据前面进程中的信息,查看 /var/lib/kubelet/config.yaml
中的内容。可以得到:
etcd: static-podkube-apiserver: static-podkube-controller-manager: static-pod
$ cat /var/lib/kubelet/config.yaml | grep -i staticpod
staticPodPath: /etc/kubernetes/manifests
ls /etc/kubernetes/manifests
etcd.yaml kube-apiserver.yaml kube-controller-manager.yaml kube-scheduler.yaml
最后上下dns,查看下pod,得知 dns: pod
$ kubectl get pod -A | grep dns
kube-system coredns-66bff467f8-6k2br 1/1 Running 0 32h
最后将上面的结果写入到 /opt/course/8/master-components.txt
,不能前功尽弃。
集群:Pod 调度
使用
ssh cluster2-master1
ssh 进入主节点。暂时停止kube-scheduler
,这意味着可以在之后再次启动它。
为镜像
httpd:2.4-alpine
创建一个名为manual-schedule
的 Pod,确认它已启动但未在任何节点上调度。
现在您是调度程序并拥有所有权力,在节点
cluster2-master1
上手动调度该 Pod。 确保它正在运行。
再次启动
kube-scheduler
并通过在镜像httpd:2.4-alpine
创建第二个名为manual-schedule2
的 Pod 并检查它是否在cluster2-worker1
上运行来确认其运行正常。
知识点
- kubernetes 组件的运行方式
- 创建 pod
- pod 调度
解题思路
kube-scheduler 是以 static pod 的方式运行,因此我们需要 ssh 到节点上,将 scheduler 的 yaml 移出(记住不要删掉,还要还原回去),重启 kubelet
$ ps -ef | grep -w kubelet
root 140597 1 2 May15 ? 00:36:00 /var/lib/minikube/binaries/v1.18.8/kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --config=/var/lib/kubelet/config.yaml --container-runtime=docker --hostname-override=cka --kubeconfig=/etc/kubernetes/kubelet.conf --node-ip=192.168.64.3
$ cat /var/lib/kubelet/config.yaml | grep -i staticpod
staticPodPath: /etc/kubernetes/manifests
$ ls /etc/kubernetes/manifests
etcd.yaml kube-apiserver.yaml kube-controller-manager.yaml kube-scheduler.yaml
$ mv /etc/kubernetes/manifests/kube-scheduler.yaml /etc/kubernetes
$ systemctl restart kubelet
检查下 schedule pod 没有运行,然后尝试创建 pod,并查看 pod 处于 pending 状态,即没有 kube-scheduler 为其调度。
$ kubectl run manual-schedule --image httpd:2.4-alpine
$ kubectl get pod | grep manual-schedule
manual-schedule 0/1 Pending 0 16s
手动调度,即为 pod 指定一个 nodeName
,我的 minikube 只有一个 node 名为 cka,修改pod:
$ kubectl get pod manual-schedule -o yaml > manual-schedule.yaml
添加 nodeName 之后
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: "2021-05-16T07:27:16Z"
labels:
run: manual-schedule
name: manual-schedule
namespace: dev
resourceVersion: "84805"
selfLink: /api/v1/namespaces/dev/pods/manual-schedule
uid: c4b592f6-1e07-4911-a7fe-867d813c7a55
spec:
containers:
- image: httpd:2.4-alpine
imagePullPolicy: IfNotPresent
name: manual-schedule
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: default-token-v7f28
readOnly: true
dnsPolicy: ClusterFirst
nodeName: cka #node name here
enableServiceLinks: true
priority: 0
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
serviceAccount: default
serviceAccountName: default
terminationGracePeriodSeconds: 30
tolerations:
- effect: NoExecute
key: node.kubernetes.io/not-ready
operator: Exists
tolerationSeconds: 300
- effect: NoExecute
key: node.kubernetes.io/unreachable
operator: Exists
tolerationSeconds: 300
volumes:
- name: default-token-v7f28
secret:
defaultMode: 420
secretName: default-token-v7f28
status:
phase: Pending
qosClass: BestEffort
强制更新 pod(运行时只能修改部分内容):
$ kubectl replace -f manual-schedule.yaml --force
pod "manual-schedule" deleted
pod/manual-schedule replaced
再次检查
$ kubectl get pod | grep manual-schedule
manual-schedule 1/1 Running 0 15s
恢复 kube-scheduler 的运行:
$ mv /etc/kubernetes/kube-scheduler.yaml /etc/kubernetes/manifests
$ systemctl restart kubelet
检查是否运行
$ kubectl get pod -A | grep kube-scheduler
kube-system kube-scheduler-cka 1/1 Running 0 66s
创建第二个pod,并检查是否在运行(running)状态
$ kubectl run manual-schedule2 --image httpd:2.4-alpine
pod/manual-schedule2 created
kubectl get pod manual-schedule2
NAME READY STATUS RESTARTS AGE
manual-schedule2 1/1 Running 0 6s
集群:备份及恢复
对在
cluster3-master1
上运行的 etcd 进行备份,并将其保存在主节点上的/tmp/etcd-backup.db
。
然后在集群中创建一个你喜欢的 Pod。
最后恢复备份,确认集群仍在工作并且创建的 Pod 不再与我们在一起。
知识点
- etc 的作用:存储集群的状态信息,包括 pod 信息
- etc 的备份和恢复
解题思路
etcd的命令执行,记得设置API的版本 ETCDCTL_API=3
操作 etcd 需要 endpoints
、cacert
、cert
、key
。Kubernetes 的所有组件与 etcd 的数据交互都是通过 api-server 完成的,我只需要找到 api-server 的运行命令就行,两种方式:到 master 主机查看 api-server 的进程;或者去 api-server 的 pod 查看 .spec.containers[].command
#ssh to master
$ ps -ef | grep kube-apiserver
$ kubectl get pod -n kube-system kube-apiserver-cka -o jsonpath='{.spec.containers[].command}'
etcd 备份,命令直接从 Kubernetes 官方文档复制再修改
#ssh to master
$ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 \
--cacert=/var/lib/minikube/certs/etcd/ca.crt --cert=/var/lib/minikube/certs/apiserver-etcd-client.crt --key=/var/lib/minikube/certs/apiserver-etcd-client.key \
snapshot save /tmp/etcd-backup.db
Snapshot saved at /tmp/etcd-backup.db
创建 pod
$ kubectl run sleep1d --image busybox --command -- sleep 1d
#检查 pod 运行情况
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
sleep1d 1/1 Running 0 10s
恢复 etcd 的备份,复制前面的命令并修改,恢复备份到 /var/lib/etcd-backup
$ ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 --cacert=/var/lib/minikube/certs/etcd/ca.crt --cert=/var/lib/minikube/certs/apiserver-etcd-client.crt --key=/var/lib/minikube/certs/apiserver-etcd-client.key snapshot restore /tmp/etcd-backup.db --data-dir /var/lib/etcd-backup
2021-05-16 08:09:17.797061 I | mvcc: restore compact to 85347
2021-05-16 08:09:17.803208 I | etcdserver/membership: added member 8e9e05c52164694d [http://localhost:2380] to cluster cdf818194e3a8c32
修改 etcd 的配置, /etc/kubernetes/manifests/etcd.yaml
volumes:
- hostPath:
path: /var/lib/minikube/certs/etcd
type: DirectoryOrCreate
name: etcd-certs
- hostPath:
path: /var/lib/etcd-backup #原来是/var/lib/minikube/etcd
type: DirectoryOrCreate
name: etcd-data
status: {}
保存后重启kubelet
$ systemctl restart kubelet
检查pod是否存在:
$ kubectl get pod sleep1d
Error from server (NotFound): pods "sleep1d" not found
安全:网络策略
发生了一起安全事件,入侵者能够从一个被黑的后端 Pod 访问整个集群。
为了防止这种情况,在命名空间
project-snake
中创建一个名为np-backend
的NetworkPolicy
。它应该只允许backend-*
Pods:
连接到端口
1111
上的db1-*
Pod连接到端口2222
上的db2-*
Pod在策略中使用 Pod 的应用程序标签。
实施后,例如,端口 3333 上从
backend-*
Pod 到vault-*
Pod 的连接应该不再有效。
知识点
- NetworkPolicy
参考文档:https://kubernetes.io/docs/concepts/services-networking/network-policies
解题思路
为 backend-* pod 设置 egress 的 NetworkPolicy,只允许其访问 db1-* 的 1111 端口和 db2-* 的 2222 端口,策略中使用 app label 来进行匹配。
从 Kubernetes 官网文档中复制一段yaml配置进行修改。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: np-backend
namespace: project-snake
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Egress
egress:
- to:
- podSelector:
matchLabels:
app: db1
ports:
- protocol: TCP
port: 1111
- to:
- podSelector:
matchLabels:
app: db2
ports:
- protocol: TCP
port: 2222
假设 backend pod 的 app label 为 backend,db1 的 为 db1,db2 的为 db2。
创建环境:
$ kubectl run backend --image nginx --labels app=backend
$ kubectl run db1 --image nginx --labels app=db1
$ kubectl run db2 --image nginx --labels app=db2
$ kubectl run vault --image nginx --labels app=vault
$ kubectl get pod -L app
NAME READY STATUS RESTARTS AGE APP
backend 1/1 Running 0 13s backend
db1 1/1 Running 0 66s db1
db2 1/1 Running 0 71s db2
vault 1/1 Running 0 79s vault
由于我们用的 nginx 镜像,将前面的 NetworkPolicy 端口修改一下:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: np-backend
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Egress
egress:
- to:
- podSelector:
matchLabels:
app: db1
ports:
- protocol: TCP
port: 80
- to:
- podSelector:
matchLabels:
app: db2
ports:
- protocol: TCP
port: 80
检查一下:
$ kubectl get networkpolicy
NAME POD-SELECTOR AGE
np-backend app=backend 31s
测试下网络:
#获取pod ip
$ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
backend 1/1 Running 0 3m15s 172.17.0.7 cka <none> <none>
db1 1/1 Running 0 4m8s 172.17.0.6 cka <none> <none>
db2 1/1 Running 0 4m13s 172.17.0.3 cka <none> <none>
vault 1/1 Running 0 4m21s 172.17.0.4 cka <none> <none>
集群:kubelet 启动方式
节点
cluster2-worker1
已使用 kubeadm 和 TLS 引导添加到集群中。找到cluster2-worker1
的 “Issuer” 和 “Extended Key Usage” 值:kubelet 客户端证书,用于向外连接到 kube-apiserver 的证书。kubelet 服务器证书,用于来自 kube-apiserver 的传入连接。将信息写入文件/opt/course/23/certificate-info.txt
。
知识点
- kubelet 的功能:连接 api-server;接受来自 api-server 的响应。两种情况都需要 TLS
解题思路
kubelet 连接 apiserver 的方式在配置文件中,先找出配置文件的保存位置。
# ssh 到节点上,查看 kubelet 的启动命令
$ ps -ef | grep kubelet
root 3935 1 1 12:54 ? 00:00:23 /var/lib/minikube/binaries/v1.20.0/kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --cni-conf-dir=/etc/cni/net.mk --config=/var/lib/kubelet/config.yaml --container-runtime=docker --hostname-override=cka-m02 --kubeconfig=/etc/kubernetes/kubelet.conf --network-plugin=cni --node-ip=192.168.64.9
docker 13653 13616 0 13:22 pts/0 00:00:00 grep kubelet
#kubelet 连接 api server 的信息, client cert 的配置所在 /var/lib/kubelet/pki/kubelet-client-current.pem
cat /var/lib/kubelet/config.yaml
#kubelet 的启动信息, servert cert 的配置所在 /var/lib/minikube/certs/ca.crt
cat /etc/kubernetes/kubelet.conf
$ openssl x509 -noout -text -in /var/lib/kubelet/pki/kubelet-client-current.pem | grep -i issuer
Issuer: CN = minikubeCA
$ openssl x509 -noout -text -in /var/lib/kubelet/pki/kubelet-client-current.pem | grep -i -A1 extended
X509v3 Extended Key Usage:
TLS Web Client Authentication
$ openssl x509 -noout -text -in /var/lib/minikube/certs/ca.crt | grep -i issuer
Issuer: CN = minikubeCA
$ openssl x509 -noout -text -in /var/lib/minikube/certs/ca.crt | grep -i -A1 extended
X509v3 Extended Key Usage:
TLS Web Client Authentication, TLS Web Server Authentication
最后记得将信息写入到 /opt/course/23/certificate-info.txt
集群:证书
检查 kube-apiserver 服务器证书在
cluster2-master1
上的有效期。使用 openssl 或 cfssl 执行此操作。将到期日期写入/opt/course/22/expiration
。
同时运行正确的 kubeadm 命令以列出到期日期并确认两种方法显示相同的日期。
将更新 apiserver 服务器证书的正确 kubeadm 命令写入
/opt/course/22/kubeadm-renew-certs.sh
。
知识点
- api-server
- openssl
- kubeadm
解题思路
通过 kube-apiserver pod 的启动命令,或者 ssh 到 master 来查看命令参数,tls-cert-file=/var/lib/minikube/certs/apiserver.crt
$ openssl x509 -noout -text -in /var/lib/minikube/certs/apiserver.crt | grep -i valid -A2
Validity
Not Before: May 13 22:33:43 2021 GMT
Not After : May 14 22:33:43 2022 GMT
将 May 14 22:33:43 2022 GMT
写入 /opt/course/22/expiration
通过 kubeadm 来检查
$ kubeadm certs check-expiration | grep -i apiserver
#macos 无法安装 kubeadm
#minikube 无法使用 kubeadm 检查
将 kubeadm certs renew apiserver
写入 /opt/course/22/kubeadm-renew-certs.sh
集群:升级节点
你的同事说节点
cluster3-worker2
运行的是较旧的 Kubernetes 版本,甚至不属于集群的一部分。将 kubectl 和 kubeadm 更新为在cluster3-master1
上运行的确切版本。然后将此节点添加到集群中,您可以为此使用kubeadm。
知识点
- kubeadm 升级集群
参考文档:
解题思路
检查node
$ kubectl get nodes
检查当前组件版本
$ ssh cluster3-worker2
$ kubeadm version
$ kubectl version --short
Client Version: vx.xx.x
Server Version: vx.xx.x
$ kubelet --version
#使用命令并升级各个组件,并重启 kubelet
#如果启动失败,一般是需要token连接到api-server,需要ssh到master上运行 kubeadm create token --print-join-command
#再ssh到 node上,执行打印的命令,重启kubelet并检查装填
#最后检查node是否成功加入集群
Docker 命令
在命名空间
project-tiger
中创建一个名为Tigers-reunite
的 Pod 镜像httpd:2.4.41-alpine
,标签为pod=container
和container=pod
。找出 Pod 被安排在哪个节点上。ssh 进入该节点并找到属于该 Pod 的 docker 容器。
将容器的 docker ID 和这些正在运行的进程/命令写入
/opt/course/17/pod-container.txt
。
最后,使用 docker 命令将主 Docker 容器(来自 yaml 中指定的那个)的日志写入
/opt/course/17/pod-container.log
。
知识点
- docker 命令:ps、logs、inspect
解题思路
创建 pod
$ kubectl run tigers-reunite --image httpd:2.4.41-alpine --labels pod=container,container=pod
检查 pod 的信息
$ kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
tigers-reunite 1/1 Running 0 34s container=pod,pod=container
获取pod所在的节点
$ kubectl get pod tigers-reunite -o jsonpath='{.spec.nodeName}'
cka
ssh到节点上
docker ps | grep tigers-reunite
e6ff69b437bc 54b0995a6305 "httpd-foreground" About a minute ago Up About a minute k8s_tigers-reunite_tigers-reunite_dev_53391212-911d-4275-a19d-e8f8b0f85a98_0
06d3ca65eb08 k8s.gcr.io/pause:3.2 "/pause" About a minute ago Up About a minute k8s_POD_tigers-reunite_dev_53391212-911d-4275-a19d-e8f8b0f85a98_0
#使用docker inspect 或者 进入容器直接查看进程
$ docker inspect e6ff69b437bc | grep -i 'cmd\|entrypoint' -A1
"Cmd": [
"httpd-foreground"
--
"Entrypoint": null,
"OnBuild": null,
$ docker inspect 06d3ca65eb08 | grep -i 'cmd\|entrypoint' -A1
"Cmd": null,
"Image": "k8s.gcr.io/pause:3.2",
--
"Entrypoint": [
"/pause"
结果写入文件
e6ff69b437bc httpd-foreground
06d3ca65eb08 pause
写日志到文件
docker logs e6ff69b437bc > /opt/course/17/pod-container.log
文章统一发布在公众号
云原生指北
,关注获取最新文章。
相关推荐
- WIN10系统如何安装UG10.0
-
随着科技的不断进步与更新,现在有很多公司己经安装上了WIN10的系统以及使用UG10.0了,但很多人反映WIN10系统安装UG10.0不好装,以下详细介绍一下1如果WIN10系统没有自带有JAVA需...
- 自学UG编程的心得分享
-
为什么有的人3个月学会基本的UG建模画图编程,有的断断续续3——5年才学会,还有的人干了7年的加工中心还不会电脑画图编程。这是什么原因?1.顾虑太多,什么都想得到,什么都想一起抓,总是上班加班没时间,...
- UG/NX 绘制一个捞笊(zhào)模型,或者也可以叫它漏勺?
-
今天我们来看看这个模型,起因是群里有小伙伴说要做一个捞笊的模型,看见这名字直接给我整懵了,然后他发了张家里漏勺的图片才知道原来这玩意还有个这种名字。这东西相信每个小伙伴家里都有吧,它的建模方法也比较...
- 再也不用为学UG编程发愁了!380集最新UG资料免费送
-
上期发的UG教程很多粉丝都领到了,收获越来越多的好评!有你们一直陪伴真的很高兴,谢谢各位粉丝!为了给大家提供更优质的资源,这两个月都在整理你们最关心的UG资源,都是多位编程工厂老师傅的工厂实战精华,真...
- 优胜原创UG_3-4-5轴后处理下载
-
反复上机调试,安全稳定可靠,请放心使用2020.11.21,修复YSUG4-5轴后处理锁轴输出...
- 青华模具学院-UG10.0安装文件说明
-
青华模具学院分享:今天我们来跟大家一起学习NX10.0版本的安装方法,网上有很多这个版本的安装视频以及方法图文,但到最终安装软件时仍有很多新手对安装仍然感到头痛,基于这样的情况,我们特别就NX10.0...
- UGnx10安装说明
-
温馨提示,安装前,请退出杀毒软件,关闭防火墙,因为这些软件可能阻断NX主程序和许可程序间的通信,导致安装后,软件无法启动。1、解压下载后的压缩包,右键,选择‘’解压到UGNX10_64位正式版(csl...
- 正版UG软件,正版UG代理,正版软件和盗版软件的区别
-
大家都知道,UG软件是制造业必不可少的一款三维软件,广泛应用于:CAE(有限元分析),CAD(产品设计/模具设计),CAM(计算机辅助制造编程),那么有人不禁要问了,正版软件和盗版软件在使用上有明显区...
- 非常全面的UG加工模块中英对照(图标注释)
-
大家好,我是粥粥老师,听说很多同学都在学习UG但是没有学习资料和安装包,今天粥粥老师就全部打包好免费发放给你们,那么怎么获取全套资料图档安装包呢领取途径①关注②评论、点赞、转发③私信“UG或者...
- 腾讯自研Git客户端 UGit|Git 图形界面客户端
-
支持平台:#Windows#macOS腾讯推出的一款Git图形界面客户端,简化了Git的使用流程,特别适合处理大型项目和文件。支持直接提交和推送操作,避免在大规模项目中由于远程频繁变更而导致...
- 经典收藏:UG重用库的一些不为人知小技巧
-
免费领取UG产品编程、UG多轴UG模具编程、安装包安装教程图档资料关注私信我“领取资料”,即可免费领取完整版,感谢支持,爱你们哟,么么主题:UG后处理+仿真+外挂UG重用库的正确使用方法:首先有...
- UG编程常用指令G、M代码,快收藏好
-
今天给大家分享数控编程常用的指令代码,希望对正在学习路上的你带来一丝丝帮助。最好的方法就是转发到自己空间,方便以后学习。对了,如果你还需要其他UG教程学习资料,CNC加工中心的一些参数,以及UG画图,...
- UG NX7.0中文版从入门到精通
-
Unigraphics(简称UG)是一套功能强大的CAD/CAE/CAM应用软件,UGNX7是其最新版本。《UGNX7从入门到精通(中文版)》以UGNX7为平台,从工程应用的角度出发,通过基...
- 经典UG建模基础练习图纸
-
UG是目前工作中比较优秀拥有大量用户的一款机械模具产品行业三维设计软件,cam加工丶软件支持全中文汉化;能够带给用户更为非凡的设计与加工新体验。很多朋友私信小编问有没有UG建模练习图纸,今天给大家分享...
- UG NC软件基础操作,如何设置UG草图精度
-
默认情况下我们绘制草图一般只保留一位小数,即使你输入多位小数软件也会自动四舍五入,这个你做一些国标的图还好,国标以毫米为单位,一般保留小数点后一位就够了,但如果你做的图是英制单位,那么保留一位小数肯定...
- 一周热门
- 最近发表
- 标签列表
-
- 微信开发者工具 (41)
- amd驱动 (55)
- 下载qqhd (28)
- cad2014 (75)
- cad2014注册机 (30)
- 魔兽争霸官方对战平台 (43)
- cad2007 (31)
- directx下载 (29)
- 桌面备忘录 (51)
- msvcr100.dll下载 (24)
- office2010下载 (42)
- ipscan (20)
- 思源黑体下载 (38)
- kernel32.dll下载 (63)
- office2010下载免费完整版 (28)
- 微信开发者工具下载 (54)
- powerdesigner下载 (46)
- python3下载 (23)
- photoshop官方免费版 (55)
- ch340串口驱动 (52)
- 爱奇艺万能播放器官方下载 (30)
- ps软件官方下载中文版 (51)
- ultraedit下载 (32)
- 360一键root (32)
- ug下载 (64)