一、前言
在文章《kubernetes POD多网卡方案multus-cni之一:概览》中,可以看到通过配置multus,可以为一个POD配置多个网络接口。根据multus主页上的描述,现在可以使用kubernetes的CDR来配置network object,允许POD对网络进行选取,在POD deployment定义中,可以指定需要使用哪个或者那些multus所管理的网络,来满足这种根据POD功能来自由组合网络的需求:
转载自https://blog.csdn.net/cloudvtech
二、测试环境设置
2.1 kubernetes(1个master,2个worker)
[root@k8s-master CRD]# kubectl get nodes NAME STATUS ROLES AGE VERSION k8s-master Ready master 23d v1.10.0 k8s-node1 Ready <none> 23d v1.10.0 k8s-node2 Ready <none> 23d v1.10.0
[root@k8s-master CRD]# kubectl version Client Version: version.Info{Major:"1", Minor:"10", GitVersion:"v1.10.0", GitCommit:"fc32d2f3698e36b93322a3465f63a14e9f0eaead", GitTreeState:"clean", BuildDate:"2018-03-26T16:55:54Z", GoVersion:"go1.9.3", Compiler:"gc", Platform:"linux/amd64"} Server Version: version.Info{Major:"1", Minor:"10", GitVersion:"v1.10.0", GitCommit:"fc32d2f3698e36b93322a3465f63a14e9f0eaead", GitTreeState:"clean", BuildDate:"2018-03-26T16:44:10Z", GoVersion:"go1.9.3", Compiler:"gc", Platform:"linux/amd64"}
2.2 运行flannel CNI
kube-flannel.yml
--- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: name: flannel rules: - apiGroups: - "" resources: - pods verbs: - get - apiGroups: - "" resources: - nodes verbs: - list - watch - apiGroups: - "" resources: - nodes/status verbs: - patch --- kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: name: flannel roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: flannel subjects: - kind: ServiceAccount name: flannel namespace: kube-system --- apiVersion: v1 kind: ServiceAccount metadata: name: flannel namespace: kube-system --- kind: ConfigMap apiVersion: v1 metadata: name: kube-flannel-cfg namespace: kube-system labels: tier: node app: flannel data: cni-conf.json: | { "name": "cbr0", "plugins": [ { "type": "flannel", "delegate": { "hairpinMode": true, "isDefaultGateway": true } }, { "type": "portmap", "capabilities": { "portMappings": true } } ] } net-conf.json: | { "Network": "10.244.0.0/16", "Backend": { "Type": "vxlan" } } --- apiVersion: extensions/v1beta1 kind: DaemonSet metadata: name: kube-flannel-ds namespace: kube-system labels: tier: node app: flannel spec: template: metadata: labels: tier: node app: flannel spec: hostNetwork: true nodeSelector: beta.kubernetes.io/arch: amd64 tolerations: - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule serviceAccountName: flannel initContainers: - name: install-cni image: quay.io/coreos/flannel:v0.10.0-amd64 command: - cp args: - -f - /etc/kube-flannel/cni-conf.json - /etc/cni/net.d/10-flannel.conflist volumeMounts: - name: cni mountPath: /etc/cni/net.d - name: flannel-cfg mountPath: /etc/kube-flannel/ containers: - name: kube-flannel image: quay.io/coreos/flannel:v0.10.0-amd64 command: - /opt/bin/flanneld args: - --ip-masq - --kube-subnet-mgr resources: requests: cpu: "100m" memory: "50Mi" limits: cpu: "100m" memory: "50Mi" securityContext: privileged: true env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace volumeMounts: - name: run mountPath: /run - name: flannel-cfg mountPath: /etc/kube-flannel/ volumes: - name: run hostPath: path: /run - name: cni hostPath: path: /etc/cni/net.d - name: flannel-cfg configMap: name: kube-flannel-cfg
kubectl apply -f kube-flannel.yml
[root@k8s-master CRD]# kubectl get pod -n kube-system | grep flannel kube-flannel-ds-gmkg8 1/1 Running 1 1h kube-flannel-ds-kjnbw 1/1 Running 3 1h kube-flannel-ds-rb997 1/1 Running 3 1h
2.3 安装multus
参见文章《kubernetes POD多网卡方案multus-cni之一:概览》
2.4 配置multus
首先清理原有的CNI配置
rm -f /etc/cni/net.d/*在所有kubernetes node建立如下的/etc/cni/net.d/10-multus.conf
{ "name": "multus-cni-network", "type": "multus", "kubeconfig": "/etc/kubernetes/kubelet.conf" }
重启kubelet
systemctl restart kubelet
转载自https://blog.csdn.net/cloudvtech
三、配置multus CRD
3.1 建立权限
clusterrole.yml
--- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: multus-crd-overpowered rules: - apiGroups: - '*' resources: - '*' verbs: - '*' - nonResourceURLs: - '*' verbs: - '*'
kubectl apply -f clusterrole.yml
kubectl create clusterrolebinding multus-node-k8s-node1 --clusterrole=multus-crd-overpowered --user=system:node:k8s-node1 kubectl create clusterrolebinding multus-node-k8s-node2 --clusterrole=multus-crd-overpowered --user=system:node:k8s-node2 kubectl create clusterrolebinding multus-node-k8s-master --clusterrole=multus-crd-overpowered --user=system:node:k8s-master
3.2 建立CRD network
crdnetwork.yaml
apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: # name must match the spec fields below, and be in the form: <plural>.<group> name: networks.kubernetes.com spec: # group name to use for REST API: /apis/<group>/<version> group: kubernetes.com # version name to use for REST API: /apis/<group>/<version> version: v1 # either Namespaced or Cluster scope: Namespaced names: # plural name to be used in the URL: /apis/<group>/<version>/<plural> plural: networks # singular name to be used as an alias on the CLI and for display singular: network # kind is normally the CamelCased singular type. Your resource manifests use this. kind: Network # shortNames allow shorter string to match your resource on the CLI shortNames: - net
kubectl apply -f crdnetwork.yml
3.3 建立network resource object
CNI flannel network object:flannel-network.yaml
apiVersion: "kubernetes.com/v1" kind: Network metadata: name: flannel-networkobj plugin: flannel args: '[ { "delegate": { "isDefaultGateway": true } } ]'CNI macvlan network object:macvlan-network.yaml
apiVersion: "kubernetes.com/v1" kind: Network metadata: name: macvlan-networkobj plugin: macvlan args: '[ { "master": "ens33", "mode": "vepa", "ipam": { "type": "host-local", "subnet": "192.168.166.0/24", "rangeStart": "192.168.166.21", "rangeEnd": "192.168.166.29", "routes": [ { "dst": "0.0.0.0/0" } ], "gateway": "192.168.166.2" } } ]'
部署这两个网络对象:
kubectl apply -f flannel-network.yaml kubectl apply -f macvlan-network.yaml
查看部署结果:
[root@k8s-master CRD]# kubectl get CustomResourceDefinition NAME AGE networks.kubernetes.com 2h
[root@k8s-master CRD]# kubectl get networks NAME AGE flannel-networkobj 1h macvlan-networkobj 58m
[root@k8s-master CRD]# kubectl describe networks Name: flannel-networkobj Namespace: default Labels: <none> Annotations: kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"kubernetes.com/v1","args":"[ { \"delegate\": { \"isDefaultGateway\": true } } ]","kind":"Network","metadata":{"annotations":{},"name":"f... API Version: kubernetes.com/v1 Args: [ { "delegate": { "isDefaultGateway": true } } ] Kind: Network Metadata: Cluster Name: Creation Timestamp: 2018-05-08T01:32:50Z Generation: 1 Resource Version: 314203 Self Link: /apis/kubernetes.com/v1/namespaces/default/networks/flannel-networkobj UID: b85192fa-525f-11e8-a891-000c29d3e746 Plugin: flannel Events: <none> Name: macvlan-networkobj Namespace: default Labels: <none> Annotations: kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"kubernetes.com/v1","args":"[ { \"master\": \"ens33\", \"mode\": \"vepa\", \"ipam\": { \"type\": \"host-local\", \"subnet\": \"192.168.16... API Version: kubernetes.com/v1 Args: [ { "master": "ens33", "mode": "vepa", "ipam": { "type": "host-local", "subnet": "192.168.166.0/24", "rangeStart": "192.168.166.21", "rangeEnd": "192.168.166.29", "routes": [ { "dst": "0.0.0.0/0" } ], "gateway": "192.168.166.2" } } ] Kind: Network Metadata: Cluster Name: Creation Timestamp: 2018-05-08T02:18:54Z Generation: 1 Resource Version: 318342 Self Link: /apis/kubernetes.com/v1/namespaces/default/networks/macvlan-networkobj UID: 27f24729-5266-11e8-9ff5-000c29d3e746 Plugin: macvlan Events: <none>
转载自https://blog.csdn.net/cloudvtech
四、选择不同的网络部署POD
4.1 使用flannel的POD
nginx_pod_flannel.yaml
apiVersion: v1 kind: Pod metadata: name: nginx-flannel annotations: networks: '[ { "name": "flannel-networkobj" } ]' spec: containers: - name: nginx image: nginx:1.7.9 ports: - containerPort: 80
查看POD内部:
[root@k8s-node1 net.d]# docker exec -it db bash root@nginx-flannel:/# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 3: eth0@if12: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1450 qdisc noqueue state UP link/ether 0a:58:0a:f4:01:03 brd ff:ff:ff:ff:ff:ff inet 10.244.1.3/24 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::744c:23ff:fe2c:11ce/64 scope link valid_lft forever preferred_lft forever
从另外一个node访问:
[root@k8s-node2 ~]# curl 10.244.1.3 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> ...... </head> <body> ...... </body> </html>
4.2 使用macvlan的POD
macvlan-network.yaml
apiVersion: "kubernetes.com/v1" kind: Network metadata: name: macvlan-networkobj plugin: macvlan args: '[ { "master": "ens33", "mode": "vepa", "ipam": { "type": "host-local", "subnet": "192.168.166.0/24", "rangeStart": "192.168.166.21", "rangeEnd": "192.168.166.29", "routes": [ { "dst": "0.0.0.0/0" } ], "gateway": "192.168.166.2" } } ]'
查看POD内部:
[root@k8s-node2 ~]# docker exec -it bf bash root@nginx-macvlan:/# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN link/ether 06:a1:c9:b2:ff:c4 brd ff:ff:ff:ff:ff:ff inet 192.168.166.23/24 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::4a1:c9ff:feb2:ffc4/64 scope link valid_lft forever preferred_lft forever
从另外一个node访问:
[root@k8s-node2 ~]# curl 192.168.166.23 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> ...... </head> <body> ...... </body> </html>
4.3 同时使用flannel和macvlan的POD
nginx_pod_both.yaml
apiVersion: v1 kind: Pod metadata: name: nginx-both annotations: networks: '[ { "name": "flannel-networkobj" }, { "name": "macvlan-networkobj" } ]' spec: containers: - name: nginx image: nginx:1.7.9 ports: - containerPort: 80
查看POD内部:
[root@k8s-node1 net.d]# docker exec -it 82 bash root@nginx-both:/# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 3: eth0@if13: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1450 qdisc noqueue state UP link/ether 0a:58:0a:f4:01:04 brd ff:ff:ff:ff:ff:ff inet 10.244.1.4/24 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::287c:8dff:fefd:4f88/64 scope link valid_lft forever preferred_lft forever 4: net0@if2: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UNKNOWN link/ether de:59:61:70:cf:a9 brd ff:ff:ff:ff:ff:ff inet 192.168.166.21/24 scope global net0 valid_lft forever preferred_lft forever inet6 fe80::dc59:61ff:fe70:cfa9/64 scope link valid_lft forever preferred_lft forever
从另外一个node访问:
[root@k8s-node2 ~]# curl 10.244.1.4 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> ...... </head> <body> ...... </body> </html> [root@k8s-node2 ~]# curl 192.168.166.21 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> ...... </head> <body> ...... </body> </html>转载自https://blog.csdn.net/cloudvtech