快速入門
實驗:通過服務自動發現的redis主從
難點:
1,服務的自動發現,即如何確定coreDNS 已生效
2,redis的主從驗證
遇到的問題:
1,Can't handle RDB format version 9
解決:一般是低版本無法兼容高版本的 rdb 導致的。要求刪除 dump.rdb文件,再啟動 redis-server。 但是pod 中命令不足,所以自己新建鏡像使用。
2,使用k8s 起的pod 和docker 起的容器,在容器內部 /etc/resolve.cnf內的ns 不同,docker 起的容器和系統保持一致,但是K8S 起的pod 使用的是CoreDNS 的ns
(即pod 內與外網隔絕,使用ip 也不行,這句可能不對,未查資料,僅現有環境測試)
驗證k8s服務自動發現
一般k8s搭建正常后服務也正常
kubectl get po -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-5c98db65d4-j2925 1/1 Running 0 61m
coredns-5c98db65d4-k2rcj 1/1 Running 0 61m
etcd-k8s-master 1/1 Running 0 60m
kube-apiserver-k8s-master 1/1 Running 0 60m
kube-controller-manager-k8s-master 1/1 Running 0 60m
kube-flannel-ds-amd64-6rq62 1/1 Running 0 60m
kube-flannel-ds-amd64-ctmdz 1/1 Running 0 59m
kube-proxy-kmgc5 1/1 Running 0 61m
kube-proxy-ss8jr 1/1 Running 0 59m
kube-scheduler-k8s-master 1/1 Running 0 60m
1,驗證k8s CoreDNS搭建正常
## 起nginx 容器和服務測試
cat tt-nginx.yml
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
selector:
app: nginx
##起具有curl 和nslookup 工具的鏡像測試
cat curl-utils.yml
apiVersion: v1
kind: Pod
metadata:
name: curl-util
spec:
containers:
- name: curl-util
image: radial/busyboxplus:curl
command:
- sh
- -c
- while true ; do sleep 1 ;done
## 進入curl 工具容器測試
nslookup nginx
curl nginx:80
2,redis 簡單主從和哨兵
#根據redis 鏡像制作redis-slave
cat run.sh
#!/bin/bash
if [[ ${GET_HOSTS_FROM:-dns} == "env" ]]; then
redis-server --slaveof ${REDIS_MASTER_SERVICE_HOST} 6379
else
redis-server --slaveof redis-master 6379
fi
#############################
cat Dockerfile
FROM redis
COPY run.sh /
RUN chmod +x /run.sh
ENTRYPOINT ["/run.sh"]
docker build -t redis-slave-tt .
---------------------------------------------------------------
## redis-master 的RC和service
cat redis-master.yml
apiVersion: v1
kind: ReplicationController
metadata:
name: redis-master
labels:
name: redis-master
spec:
replicas: 1
selector:
name: redis-master
template:
metadata:
labels:
name: redis-master
spec:
containers:
- name: master
image: redis
ports:
- containerPort: 6379
---
apiVersion: v1
kind: Service
metadata:
name: redis-master
labels:
name: redis-master
spec:
ports:
- port: 6379
targetPort: 6379
selector:
name: redis-master
----------------------------------------------------
#redis-slave 的RC
cat redis-slave-controller.yaml
apiVersion: v1
kind: ReplicationController
metadata:
name: redis-slave
labels:
name: redis-slave
spec:
replicas: 2
selector:
name: redis-slave
template:
metadata:
labels:
name: redis-slave
spec:
containers:
- name: slave
image: redis-slave-tt
imagePullPolicy: Never
env:
- name: GET_HOSTS_FROM
value: dns
# If your cluster config does not include a dns service, then to
# instead access an environment variable to find the master
# service's host, comment out the 'value: dns' line above, and
# uncomment the line below.
#value: env
ports:
- containerPort: 6379
##
注意:因為K8S 使用鏡像是本地的,所以必須添加 imagePullPolicy: Never 屬性
環境變量使用env 也可以
############
哨兵配置
生成本地鏡像
cat sentinel.conf
port 8332
daemonize no
sentinel deny-scripts-reconfig yes
sentinel monitor mymaster redis-master 6379 2
sentinel config-epoch mymaster 0
# Generated by CONFIG REWRITE
dir "/data"
sentinel leader-epoch mymaster 0
sentinel current-epoch 0
cat Dockerfile
FROM redis
COPY sentinel.conf /etc/sentinel.conf
CMD [ "redis-sentinel", "/etc/sentinel.conf" ]
EXPOSE 8332
生成鏡像
docker build -t redis-sentinel .
哨兵的服務配置
cat redis-sentinel.yml
apiVersion: v1
kind: ReplicationController
metadata:
name: redis-sentinel
labels:
name: redis-sentinel
spec:
replicas: 1
selector:
name: redis-sentinel
template:
metadata:
labels:
name: redis-sentinel
spec:
containers:
- name: redis-sentinel
image: redis-sentinel
imagePullPolicy: Never
ports:
- containerPort: 8332
---
apiVersion: v1
kind: Service
metadata:
name: redis-sentinel
labels:
name: redis-sentinel
spec:
ports:
- port: 8332
targetPort: 8332
selector:
name: redis-sentinel
kubectl create -f redis-sentinel.yml 查看 kubectl get po -o wide
進入容器查看
kubectl exec -it redis-sentinel-npnn6 /bin/sh
redis-cli -p 8332
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=10.108.41.72:6379,slaves=2,sentinels=1
其他
鏡像拉取策略:
containers:
- name: uses-private-image
image: $PRIVATE_IMAGE_NAME
imagePullPolicy: Always
command: [ "echo", "SUCCESS" ]
Always 總是拉取鏡像,每次下載最新的鏡像
IfNotPresent 只有當本地沒有的時候才去下載鏡像
Never 只使用本地鏡像,從不拉取,即使本地沒有
如果省略imagePullPolicy 鏡像tag為 :latest 策略為always ,否則 策略為 IfNotPresent
一些命令
kubectl cluster-info
kubectl -s https://172.20.7.132:6443 get componentstatuses
kubectl -s https://172.20.7.132:6443 get nodes
kubectl delete replicationcontroller xx xxx xx
kubectl delete service xxx xxx xx
POD
常用命令
kubectl get pod redis-master-v8zjx -o yaml
kubectl describe pod curl-util
kubectl delete pod pod-name
kubectl delete pod --all 批量刪除全部pod
拉取私有鏡像倉庫需要的登陸;有2種方式:
1,所有node手工docker login
2 ,POD中添加Image Pull Secret 用於驗證,
操作:
系統管理員設置全局的 image pull secret ,創建pod 時自動添加上
pod的啟動命令
docker run 運行容器時沒有指定容器的啟動命令,容器則使用默認的Docker 鏡像的啟動命令。一般通過dockerfile 的CMD 和 ENTRYPOINT設置。
CMD命令可以覆蓋,docker run 指定的啟動命令會把CMD 命令覆蓋。ENTRYPOINT設置的命令是一個入口,docker 指定的啟動命令作為參數傳遞給ENTRYPOINT設置的命令,而不是進行替換。
pod的環境變量
設置容器運行時的環境變量
env:
- name: PAREMETER_1
value: value_1
- name: PAREMETER-2
value: value_2
pod的YAML 文件
pod的網絡
pod的重啟策略
通過pod定義的.spec.restartPolicy設置:
pod 的狀態和生命周期
使用kubectl describe pod pod-name 查看容器狀態
生命周期的回調函數
PostStart :容器創建成功后調用
PreStop:容器終止前調用該回調函數
自定義檢查pod
檢查pod 是否健康,默認情況下只會檢查容器是否正常運行,容器運行不代表應用正常運行
*調度pod
pod 分配到哪個node
支持的過濾函數
選擇:
通過node 的label 選擇
使用命令
kubectl label nodes kube-node- env=test
創建pod 時選擇Node
nodeSelector:
env: test
或通過Node Name 直接指定:
nodeName: kube-node-1
事件查詢
kubectl get event
kubectl describe pod my-pod
日志查詢
kubectl logs pod-name container
遠程連接容器
kubectl exec my-pod -- date pod 只有一個容器 不需要指定容器
直接進入 kubectl exec -it my-pod /bin/bash