1. Kubernetes masters launch and start correctly

2. Output kubeconfig in ARM output params
3. Server certificates work with DNS name (kubectl can work remotely, without dns issue)
4. Sharding of OS Disk and Data Disk storage accounts in place
This commit is contained in:
Anthony Howe 2016-10-05 21:05:38 -07:00
Родитель 3c352ecb36
Коммит cf14d79db0
24 изменённых файлов: 824 добавлений и 344 удалений

Просмотреть файл

@ -13,8 +13,8 @@ type OrchestratorProfile struct {
OrchestratorType string `json:"orchestratorType"`
ServicePrincipalClientID string `json:"servicePrincipalClientID,omitempty"`
ServicePrincipalClientSecret string `json:"servicePrincipalClientSecret,omitempty"`
ApiserverCertificate string `json:"apiserverCertificate,omitempty"`
ApiserverPrivateKey string `json:"apiserverPrivateKey,omitempty"`
ApiServerCertificate string `json:"apiServerCertificate,omitempty"`
ApiServerPrivateKey string `json:"apiServerPrivateKey,omitempty"`
CaCertificate string `json:"caCertificate,omitempty"`
ClientCertificate string `json:"clientCertificate,omitempty"`
ClientPrivateKey string `json:"clientPrivateKey,omitempty"`

Просмотреть файл

@ -32,11 +32,11 @@ func (o *OrchestratorProfile) Validate() error {
}
if o.OrchestratorType == Kubernetes {
if len(o.ApiserverCertificate) > 0 || len(o.ApiserverPrivateKey) > 0 || len(o.CaCertificate) > 0 || len(o.ClientCertificate) > 0 || len(o.ClientPrivateKey) > 0 {
if len(o.ApiServerCertificate) > 0 || len(o.ApiServerPrivateKey) > 0 || len(o.CaCertificate) > 0 || len(o.ClientCertificate) > 0 || len(o.ClientPrivateKey) > 0 {
return fmt.Errorf("API, CA, and Client certs are required for orchestrator %s", o.OrchestratorType)
}
} else {
if len(o.ApiserverCertificate) > 0 || len(o.ApiserverPrivateKey) > 0 || len(o.CaCertificate) > 0 || len(o.ClientCertificate) > 0 || len(o.ClientPrivateKey) > 0 {
if len(o.ApiServerCertificate) > 0 || len(o.ApiServerPrivateKey) > 0 || len(o.CaCertificate) > 0 || len(o.ClientCertificate) > 0 || len(o.ClientPrivateKey) > 0 {
return fmt.Errorf("API, CA, and Client certs are not required for orchestrator %s", o.OrchestratorType)
}
}
@ -138,9 +138,6 @@ func (a *AcsCluster) Validate() error {
if a.OrchestratorProfile.OrchestratorType == Kubernetes && !agentPoolProfile.IsStateful {
return errors.New("stateless (VMSS) deployments are not supported with Kubernetes, Kubernetes requires the ability to attach/detach disks. To fix specify 'isStateful=true'")
}
if a.OrchestratorProfile.OrchestratorType == Kubernetes && agentPoolProfile.IsStateful && len(agentPoolProfile.DiskSizesGB) > 0 {
return errors.New("diskSizesGB cannot be used with Kubernetes - Kubernetes attaches its own disks")
}
if a.OrchestratorProfile.OrchestratorType == Kubernetes && len(agentPoolProfile.DNSPrefix) > 0 {
return errors.New("DNSPrefix not support for agent pools in Kubernetes - Kubernetes marks its own clusters public")
}

Просмотреть файл

@ -6,7 +6,7 @@
},
"masterProfile": {
"count": 1,
"dnsPrefix": "mgmtanhowe1004c",
"dnsPrefix": "mgmtanhowe1004f",
"vmSize": "Standard_D2_v2"
},
"agentPoolProfiles": [

Просмотреть файл

@ -3,8 +3,7 @@
"contentVersion": "1.0.0.0",
"parameters": {
{{range .AgentPoolProfiles}}{{template "agentparams.t" .}},{{end}}
{{template "masterparams.t" .}},
{{GetSizeMap}}
{{template "masterparams.t" .}}
},
"variables": {
{{range $index, $agent := .AgentPoolProfiles}}
@ -16,7 +15,9 @@
"{{.Name}}AccountName": "[concat(variables('storageAccountBaseName'), 'agnt{{$index}}')]",
{{end}}
{{template "dcosmastervars.t" .}}
{{template "dcosmastervars.t" .}},
{{GetSizeMap}}
},
"resources": [
{{range .AgentPoolProfiles}}

Просмотреть файл

@ -47,7 +47,7 @@
"osImageOffer": "UbuntuServer",
"osImagePublisher": "Canonical",
"osImageSKU": "16.04.0-LTS",
"osImageVersion": "16.04.201606270",
"osImageVersion": "16.04.201606270",
"sshKeyPath": "[concat('/home/', variables('adminUsername'), '/.ssh/authorized_keys')]",
"sshRSAPublicKey": "[parameters('sshRSAPublicKey')]",
"storageAccountBaseName": "[uniqueString(concat(variables('masterEndpointDNSNamePrefix'),resourceGroup().location, variables('orchestratorName')))]",

Просмотреть файл

@ -0,0 +1,32 @@
{
"apiVersion": "v1",
"clusters": [
{
"cluster": {
"certificate-authority-data": "<<<variables('caCertificate')>>>",
"server": "https://<<<reference(concat('Microsoft.Network/publicIPAddresses/', variables('masterPublicIPAddressName'))).dnsSettings.fqdn>>>"
},
"name": "{{{resourceGroup}}}"
}
],
"contexts": [
{
"context": {
"cluster": "{{{resourceGroup}}}",
"user": "{{{resourceGroup}}}-admin"
},
"name": "{{{resourceGroup}}}"
}
],
"current-context": "{{{resourceGroup}}}",
"kind": "Config",
"users": [
{
"name": "{{{resourceGroup}}}-admin",
"user": {
"client-certificate-data": "<<<variables('clientCertificate')>>>",
"client-key-data": "<<<variables('clientPrivateKey')>>>"
}
}
]
}

Просмотреть файл

@ -0,0 +1,36 @@
{
"orchestratorProfile": {
"orchestratorType": "Kubernetes",
"servicePrincipalClientID": "REPLACE-WITH-ServicePrincipalClientID",
"servicePrincipalClientSecret": "REPLACE-WITH-myServicePrincipalClientSecret"
},
"masterProfile": {
"count": 1,
"dnsPrefix": "mgmtanhowe1004f",
"vmSize": "Standard_D2_v2"
},
"agentPoolProfiles": [
{
"name": "agentpool1",
"count": 3,
"vmSize": "Standard_D2_v2",
"isStateful": true
},
{
"name": "agentpool2",
"count": 3,
"vmSize": "Standard_D2_v2",
"isStateful": true
}
],
"linuxProfile": {
"adminUsername": "azureuser",
"ssh": {
"publicKeys": [
{
"keyData": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8fhkh3jpHUQsrUIezFB5k4Rq9giJM8G1Cr0u2IRMiqG++nat5hbOr3gODpTA0h11q9bzb6nJtK7NtDzIHx+w3YNIVpcTGLiUEsfUbY53IHg7Nl/p3/gkST3g0R6BSL7Hg45SfyvpH7kwY30MoVHG/6P3go4SKlYoHXlgaaNr3fMwUTIeE9ofvyS3fcr6xxlsoB6luKuEs50h0NGsE4QEnbfSY4Yd/C1ucc3mEw+QFXBIsENHfHfZYrLNHm2L8MXYVmAH8k//5sFs4Migln9GiUgEQUT6uOjowsZyXBbXwfT11og+syPkAq4eqjiC76r0w6faVihdBYVoc/UcyupgH azureuser@linuxvm"
}
]
}
}
}

Просмотреть файл

@ -0,0 +1,75 @@
{
"apiVersion": "[variables('apiVersionDefault')]",
"copy": {
"count": "[variables('{{.Name}}Count')]",
"name": "loop"
},
"dependsOn": [
{{if .IsCustomVNET}}
"[concat('Microsoft.Network/networkSecurityGroups/', variables('masterNSGName'))]"
{{else}}
"[variables('vnetID')]"
{{end}}
],
"location": "[variables('location')]",
"name": "[concat(variables('{{.Name}}VMNamePrefix'), 'nic-', copyIndex())]",
"properties": {
{{if .IsCustomVNET}}
"networkSecurityGroup": {
"id": "[resourceId('Microsoft.Network/networkSecurityGroups/', variables('masterNSGName'))]"
},
{{end}}
"ipConfigurations": [
{
"name": "ipconfig1",
"properties": {
"privateIPAllocationMethod": "Dynamic",
"subnet": {
"id": "[variables('subnetRef')]"
}
}
}
],
"enableIPForwarding": true
},
"type": "Microsoft.Network/networkInterfaces"
},
{
"apiVersion": "[variables('apiVersionStorage')]",
"copy": {
"count": "[variables('{{.Name}}StorageAccountsCount')]",
"name": "loop"
},
"dependsOn": [
"[concat('Microsoft.Network/publicIPAddresses/', variables('masterPublicIPAddressName'))]"
],
"location": "[variables('location')]",
"name": "[concat(variables('storageAccountPrefixes')[mod(add(copyIndex(),variables('{{.Name}}StorageAccountOffset')),variables('storageAccountPrefixesCount'))],variables('storageAccountPrefixes')[div(add(copyIndex(),variables('{{.Name}}StorageAccountOffset')),variables('storageAccountPrefixesCount'))],variables('{{.Name}}AccountName'))]",
"properties": {
"accountType": "[variables('vmSizesMap')[variables('{{.Name}}VMSize')].storageAccountType]"
},
"type": "Microsoft.Storage/storageAccounts"
},
{
"apiVersion": "[variables('apiVersionStorage')]",
"copy": {
"count": "[variables('{{.Name}}StorageAccountsCount')]",
"name": "datadiskLoop"
},
"dependsOn": [
"[concat('Microsoft.Network/publicIPAddresses/', variables('masterPublicIPAddressName'))]"
],
"location": "[variables('location')]",
"name": "[concat(variables('storageAccountPrefixes')[mod(add(copyIndex(variables('dataStorageAccountPrefixSeed')),variables('{{.Name}}StorageAccountOffset')),variables('storageAccountPrefixesCount'))],variables('storageAccountPrefixes')[div(add(copyIndex(variables('dataStorageAccountPrefixSeed')),variables('{{.Name}}StorageAccountOffset')),variables('storageAccountPrefixesCount'))],variables('{{.Name}}DataAccountName'))]",
"properties": {
"accountType": "[variables('vmSizesMap')[variables('{{.Name}}VMSize')].storageAccountType]"
},
"type": "Microsoft.Storage/storageAccounts"
},
{
"apiVersion": "[variables('apiVersionDefault')]",
"location": "[variables('location')]",
"name": "[variables('{{.Name}}AvailabilitySet')]",
"properties": {},
"type": "Microsoft.Compute/availabilitySets"
}

Просмотреть файл

@ -0,0 +1,10 @@
"{{.Name}}StorageAccountOffset": "[mul(variables('maxStorageAccountsPerAgent'),variables('{{.Name}}Index'))]",
"{{.Name}}Count": "[parameters('{{.Name}}Count')]",
{{if .IsStateful}}
"{{.Name}}AvailabilitySet": "[concat('{{.Name}}-availabilitySet-', variables('nameSuffix'))]",
"{{.Name}}StorageAccountsCount": "[add(div(variables('{{.Name}}Count'), variables('maxVMsPerStorageAccount')), mod(add(mod(variables('{{.Name}}Count'), variables('maxVMsPerStorageAccount')),2), add(mod(variables('{{.Name}}Count'), variables('maxVMsPerStorageAccount')),1)))]",
{{else}}
"{{.Name}}StorageAccountsCount": "[variables('maxStorageAccountsPerAgent')]",
{{end}}
"{{.Name}}VMNamePrefix": "[concat(variables('orchestratorName'), '-{{.Name}}-', variables('nameSuffix'), '-')]",
"{{.Name}}VMSize": "[parameters('{{.Name}}VMSize')]",

Просмотреть файл

@ -2,17 +2,32 @@
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
{{range .AgentPoolProfiles}}{{template "agentparams.t" .}},{{end}}
{{template "masterparams.t" .}},
{{GetSizeMap}}
{{template "kubernetesparams.t" .}}
},
"variables": {
{{template "kubernetesmastervars.t" .}}
{{range $index, $agent := .AgentPoolProfiles}}
{{template "kubernetesagentvars.t" .}}
"{{.Name}}DataAccountName": "[concat(variables('storageAccountBaseName'), 'data{{$index}}')]",
"{{.Name}}Index": {{$index}},
"{{.Name}}AccountName": "[concat(variables('storageAccountBaseName'), 'agnt{{$index}}')]",
{{end}}
{{template "kubernetesmastervars.t" .}},
{{GetSizeMap}}
},
"resources": [
{{range .AgentPoolProfiles}}
{{template "kubernetesagentresources.t" .}},
{{end}}
{{template "kubernetesmasterresources.t" .}}
],
"outputs": {
{{range .AgentPoolProfiles}}{{template "agentoutputs.t" .}}
{{end}}{{template "masteroutputs.t" .}}
{{template "masteroutputs.t" .}},
"kubeConfig": {
"type": "string",
"value": "[concat('{{GetKubernetesKubeConfig}}')]"
}
}
}

Просмотреть файл

@ -0,0 +1,316 @@
#cloud-config
# [ [ [ var ] ] ]
# { { { param } } }
packages:
- etcd
- jq
- traceroute
runcmd:
- /bin/bash -c "/bin/echo DAEMON_ARGS=--advertise-client-urls {{{singleQuote}}}http://127.0.0.1:2379,http://{{{masterPrivateIp}}}:2379{{{singleQuote}}} --listen-client-urls {{{singleQuote}}}http://0.0.0.0:2379,http://0.0.0.0:4001{{{singleQuote}}} | tee -a /etc/default/etcd"
- /usr/bin/curl -sSL --retry 12 --retry-delay 10 https://get.docker.com/ > /tmp/install-docker
- /bin/bash -c "/bin/bash /tmp/install-docker"
- /usr/bin/curl -sSL --retry 12 --retry-delay 10 https://storage.googleapis.com/kubernetes-release/release/v1.3.8/bin/linux/amd64/kubectl > /usr/local/bin/kubectl
- chmod +x /usr/local/bin/kubectl
- systemctl restart docker
- systemctl restart etcd
- systemctl restart kubelet
write_files:
- path: "/etc/systemd/system/docker.service.d/clear_mount_propagation_flags.conf"
permissions: "0644"
owner: "root"
content: |
[Service]
MountFlags=shared
- path: "/etc/systemd/system/docker.service.d/overlay.conf"
permissions: "0644"
owner: "root"
content: |
[Service]
ExecStart=
ExecStart=/usr/bin/docker daemon -H fd:// --storage-driver=overlay
- path: "/etc/kubernetes/azure.json"
permissions: "0644"
owner: "root"
content: |
{
"tenantId": "{{{tenantID}}}",
"subscriptionId": "{{{subscriptionId}}}",
"aadClientId": "{{{servicePrincipalClientId}}}",
"aadClientSecret": "{{{servicePrincipalClientSecret}}}",
"resourceGroup": "{{{resourceGroup}}}",
"location": "{{{location}}}",
"subnetName": "{{{subnetName}}}",
"securityGroupName": "{{{nsgName}}}",
"vnetName": "{{{virtualNetworkName}}}",
"routeTableName": "{{{routeTableName}}}"
}
- path: "/etc/kubernetes/certs/ca.crt"
permissions: "0644"
encoding: "base64"
owner: "root"
content: |
{{{caCertificate}}}
- path: "/etc/kubernetes/certs/apiserver.crt"
permissions: "0644"
encoding: "base64"
owner: "root"
content: |
{{{apiServerCertificate}}}
- path: "/etc/kubernetes/certs/apiserver.key"
permissions: "0644"
encoding: "base64"
owner: "root"
content: |
{{{apiServerPrivateKey}}}
- path: "/etc/kubernetes/certs/client.crt"
permissions: "0644"
encoding: "base64"
owner: "root"
content: |
{{{clientCertificate}}}
- path: "/etc/kubernetes/certs/client.key"
permissions: "0644"
encoding: "base64"
owner: "root"
content: |
{{{clientPrivateKey}}}
- path: "/var/lib/kubelet/kubeconfig"
permissions: "0644"
owner: "root"
content: |
apiVersion: v1
kind: Config
clusters:
- name: localcluster
cluster:
certificate-authority: /etc/kubernetes/certs/ca.crt
server: https://{{{masterPrivateIp}}}:443
users:
- name: client
user:
client-certificate: /etc/kubernetes/certs/client.crt
client-key: /etc/kubernetes/certs/client.key
contexts:
- context:
cluster: localcluster
user: client
name: localclustercontext
current-context: localclustercontext
- path: /etc/kubernetes/manifests/kube-apiserver.yaml
permissions: "0644"
owner: "root"
content: |
apiVersion: "v1"
kind: "Pod"
metadata:
name: "kube-apiserver"
namespace: "kube-system"
labels:
tier: control-plane
component: kube-apiserver
spec:
hostNetwork: true
containers:
- name: "kube-apiserver"
image: "{{{kubernetesHyperkubeSpec}}}"
command:
- "/hyperkube"
- "apiserver"
- "--admission-control=NamespaceLifecycle,LimitRanger,SecurityContextDeny,ServiceAccount,PersistentVolumeLabel,ResourceQuota"
- "--address=0.0.0.0"
- "--allow-privileged"
- "--insecure-port=8080"
- "--secure-port=443"
- "--cloud-provider=azure"
- "--cloud-config=/etc/kubernetes/azure.json"
- "--service-cluster-ip-range={{{kubeServiceCidr}}}"
- "--etcd-servers=http://127.0.0.1:4001"
- "--tls-cert-file=/etc/kubernetes/certs/apiserver.crt"
- "--tls-private-key-file=/etc/kubernetes/certs/apiserver.key"
- "--client-ca-file=/etc/kubernetes/certs/ca.crt"
- "--service-account-key-file=/etc/kubernetes/certs/apiserver.key"
- "--v=4"
volumeMounts:
- name: "etc-kubernetes"
mountPath: "/etc/kubernetes"
- name: "var-lib-kubelet"
mountPath: "/var/lib/kubelet"
volumes:
- name: "etc-kubernetes"
hostPath:
path: "/etc/kubernetes"
- name: "var-lib-kubelet"
hostPath:
path: "/var/lib/kubelet"
- path: /etc/kubernetes/manifests/kube-controller-manager.yaml
permissions: "0644"
owner: "root"
content: |
apiVersion: "v1"
kind: "Pod"
metadata:
name: "kube-controller-manager"
namespace: "kube-system"
labels:
tier: control-plane
component: kube-controller-manager
spec:
hostNetwork: true
containers:
- name: "kube-controller-manager"
image: "{{{kubernetesHyperkubeSpec}}}"
command:
- "/hyperkube"
- "controller-manager"
- "--master=127.0.0.1:8080"
- "--kubeconfig=/var/lib/kubelet/kubeconfig"
- "--allocate-node-cidrs=true"
- "--cluster-cidr=10.244.0.0/16"
- "--cluster-name={{{masterFqdnPrefix}}}"
- "--cloud-provider=azure"
- "--cloud-config=/etc/kubernetes/azure.json"
- "--root-ca-file=/etc/kubernetes/certs/ca.crt"
- "--service-account-private-key-file=/etc/kubernetes/certs/apiserver.key"
- "--v=2"
volumeMounts:
- name: "etc-kubernetes"
mountPath: "/etc/kubernetes"
- name: "var-lib-kubelet"
mountPath: "/var/lib/kubelet"
volumes:
- name: "etc-kubernetes"
hostPath:
path: "/etc/kubernetes"
- name: "var-lib-kubelet"
hostPath:
path: "/var/lib/kubelet"
- path: /etc/kubernetes/manifests/kube-scheduler.yaml
permissions: "0644"
owner: "root"
content: |
apiVersion: "v1"
kind: "Pod"
metadata:
name: "kube-scheduler"
namespace: "kube-system"
labels:
tier: control-plane
component: kube-scheduler
spec:
hostNetwork: true
containers:
- name: "kube-scheduler"
image: "{{{kubernetesHyperkubeSpec}}}"
command:
- "/hyperkube"
- "scheduler"
- "--master=127.0.0.1:8080"
- "--kubeconfig=/var/lib/kubelet/kubeconfig"
- "--v=2"
volumeMounts:
- name: "etc-kubernetes"
mountPath: "/etc/kubernetes"
- name: "var-lib-kubelet"
mountPath: "/var/lib/kubelet"
volumes:
- name: "etc-kubernetes"
hostPath:
path: "/etc/kubernetes"
- name: "var-lib-kubelet"
hostPath:
path: "/var/lib/kubelet"
- path: /etc/kubernetes/manifests/kube-proxy.yaml
permissions: "0644"
owner: "root"
content: |
apiVersion: "v1"
kind: "Pod"
metadata:
name: "kube-proxy"
namespace: "kube-system"
labels:
tier: control-plane
component: kube-proxy
spec:
hostNetwork: true
containers:
- name: "kube-proxy"
image: "{{{kubernetesHyperkubeSpec}}}"
command:
- "/hyperkube"
- "proxy"
- "--kubeconfig=/var/lib/kubelet/kubeconfig"
- "--proxy-mode=iptables"
- "--v=2"
securityContext:
privileged: true
volumeMounts:
- name: "etc-kubernetes"
mountPath: "/etc/kubernetes"
- name: "var-lib-kubelet"
mountPath: "/var/lib/kubelet"
volumes:
- name: "etc-kubernetes"
hostPath:
path: "/etc/kubernetes"
- name: "var-lib-kubelet"
hostPath:
path: "/var/lib/kubelet"
- path: "/etc/systemd/system/kubelet.service"
permissions: "0644"
owner: "root"
content: |
[Unit]
Description=Kubelet
Requires=docker.service
After=docker.service
[Service]
Restart=always
ExecStartPre=/bin/mkdir -p /var/lib/kubelet
ExecStartPre=/bin/mount --bind /var/lib/kubelet /var/lib/kubelet
ExecStartPre=/bin/mount --make-shared /var/lib/kubelet
ExecStart=/usr/bin/docker run \
--net=host \
--pid=host \
--privileged \
--volume=/:/rootfs:ro \
--volume=/sys:/sys:ro \
--volume=/var/run:/var/run:rw \
--volume=/var/lib/docker/:/var/lib/docker:rw \
--volume=/var/lib/kubelet/:/var/lib/kubelet:shared \
--volume=/var/log/containers/:/var/log/containers:rw \
--volume=/etc/kubernetes/:/etc/kubernetes:rw \
{{{kubernetesHyperkubeSpec}}} \
/hyperkube kubelet \
--api-servers="https://{{{masterPrivateIp}}}:443" \
--kubeconfig=/var/lib/kubelet/kubeconfig \
--address=0.0.0.0 \
--allow-privileged=true \
--enable-server \
--enable-debugging-handlers \
--config=/etc/kubernetes/manifests \
--cluster-dns={{{kubeDnsServiceIP}}} \
--cluster-domain=cluster.local \
--register-schedulable=false \
--cloud-provider=azure \
--cloud-config=/etc/kubernetes/azure.json \
--v=2
ExecStop=/usr/bin/docker stop -t 2 kubelet

Просмотреть файл

@ -1,5 +1,5 @@
{
"apiVersion": "[variables('computeApiVersion')]",
"apiVersion": "[variables('apiVersionDefault')]",
"location": "[variables('location')]",
"name": "[variables('masterAvailabilitySet')]",
"properties": {},
@ -116,8 +116,41 @@
}
}
}
],
"loadBalancingRules": [
{
"name": "LBRuleHTTPS",
"properties": {
"frontendIPConfiguration": {
"id": "[variables('masterLbIPConfigID')]"
},
"backendAddressPool": {
"id": "[concat(variables('masterLbID'), '/backendAddressPools/', variables('masterLbBackendPoolName'))]"
},
"protocol": "tcp",
"frontendPort": 443,
"backendPort": 443,
"enableFloatingIP": false,
"idleTimeoutInMinutes": 5,
"loadDistribution": "Default",
"probe": {
"id": "[concat(variables('masterLbID'),'/probes/tcpHTTPSProbe')]"
}
}
}
],
"probes": [
{
"name": "tcpHTTPSProbe",
"properties": {
"protocol": "tcp",
"port": 443,
"intervalInSeconds": "5",
"numberOfProbes": "2"
}
}
]
},
},
"type": "Microsoft.Network/loadBalancers"
},
{
@ -131,32 +164,71 @@
"publicIPAllocationMethod": "Dynamic"
},
"type": "Microsoft.Network/publicIPAddresses"
},
},
{
"apiVersion": "[variables('apiVersionDefault')]",
"copy": {
"count": "[variables('masterCount')]",
"name": "masterLbLoopNode"
},
"dependsOn": [
"[concat('Microsoft.Network/publicIPAddresses/', variables('masterPublicIPAddressName')]",
"[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]"
"[variables('masterLbID')]"
],
"location": "[variables('location')]",
"name": "[concat(variables('masterFqdnPrefix'), '-nic-master')]",
"name": "[concat(variables('masterLbName'), '/', 'SSH-', variables('masterVMNamePrefix'), copyIndex())]",
"properties": {
"backendPort": 22,
"enableFloatingIP": false,
"frontendIPConfiguration": {
"id": "[variables('masterLbIPConfigID')]"
},
"frontendPort": "[variables('sshNatPorts')[copyIndex()]]",
"protocol": "tcp"
},
"type": "Microsoft.Network/loadBalancers/inboundNatRules"
},
{
"apiVersion": "[variables('apiVersionDefault')]",
"copy": {
"count": "[variables('masterCount')]",
"name": "nicLoopNode"
},
"dependsOn": [
{{if not .MasterProfile.IsCustomVNET}}
"[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]",
{{end}}
"[concat(variables('masterLbID'),'/inboundNatRules/SSH-',variables('masterVMNamePrefix'),copyIndex())]",
"[variables('masterNSGID')]"
],
"location": "[variables('location')]",
"name": "[concat(variables('masterVMNamePrefix'), 'nic-', copyIndex())]",
"properties": {
"ipConfigurations": [
{
"name": "ipconfig1",
"properties": {
"privateIPAddress": "[variables('masterPrivateIp')]",
"loadBalancerBackendAddressPools": [
{
"id": "[concat(variables('masterLbID'), '/backendAddressPools/', variables('masterLbBackendPoolName'))]"
}
],
"loadBalancerInboundNatRules": [
{
"id": "[concat(variables('masterLbID'),'/inboundNatRules/SSH-',variables('masterVMNamePrefix'),copyIndex())]"
}
],
"privateIPAddress": "[concat(variables('masterFirstAddrPrefix'), copyIndex(int(variables('masterFirstAddrOctet4'))))]",
"privateIPAllocationMethod": "Static",
"publicIPAddress": {
"id": "[resourceId('Microsoft.Network/publicIpAddresses', concat(variables('masterFqdnPrefix'), '-pip-master'))]"
},
"subnet": {
"id": "[variables('subnetRef')]"
}
}
}
],
"enableIPForwarding": true
"enableIPForwarding": true,
"networkSecurityGroup": {
"id": "[variables('masterNSGID')]"
}
},
"type": "Microsoft.Network/networkInterfaces"
},
@ -167,8 +239,9 @@
"name": "vmLoopNode"
},
"dependsOn": [
"[concat('Microsoft.Storage/storageAccounts/', variables('masterStorageAccountName'))]",
"[concat('Microsoft.Network/networkInterfaces/', variables('masterFqdnPrefix'), '-nic-master')]"
"[concat('Microsoft.Network/networkInterfaces/', variables('masterVMNamePrefix'), 'nic-', copyIndex())]",
"[concat('Microsoft.Compute/availabilitySets/',variables('masterAvailabilitySet'))]",
"[variables('masterStorageAccountName')]"
],
"location": "[variables('location')]",
"name": "[concat(variables('masterVMNamePrefix'), copyIndex())]",
@ -177,18 +250,19 @@
"id": "[resourceId('Microsoft.Compute/availabilitySets',variables('masterAvailabilitySet'))]"
},
"hardwareProfile": {
"vmSize": "[variables('masterSize')]"
"vmSize": "[variables('masterVMSize')]"
},
"networkProfile": {
"networkInterfaces": [
{
"id": "[resourceId('Microsoft.Network/networkInterfaces',concat(variables('masterFqdnPrefix'),'-nic-master'))]"
"id": "[resourceId('Microsoft.Network/networkInterfaces',concat(variables('masterVMNamePrefix'),'nic-', copyIndex()))]"
}
]
},
"osProfile": {
"adminUsername": "[variables('username')]",
"computername": "[concat(variables('vmNamePrefix'), 'master')]",
"computername": "[concat(variables('masterVMNamePrefix'), copyIndex())]",
{{GetKubernetesMasterCustomData}}
"linuxConfiguration": {
"disablePasswordAuthentication": "true",
"ssh": {

Просмотреть файл

@ -1,5 +1,8 @@
"apiserverCertificate": "[parameters('apiserverCertificate')]",
"apiserverPrivateKey": "[parameters('apiserverPrivateKey')]",
"maxVMsPerPool": 100,
"maxVMsPerStorageAccount": 20,
"maxStorageAccountsPerAgent": "[div(variables('maxVMsPerPool'),variables('maxVMsPerStorageAccount'))]",
"apiServerCertificate": "[parameters('apiServerCertificate')]",
"apiServerPrivateKey": "[parameters('apiServerPrivateKey')]",
"caCertificate": "[parameters('caCertificate')]",
"clientCertificate": "[parameters('clientCertificate')]",
"clientPrivateKey": "[parameters('clientPrivateKey')]",
@ -7,18 +10,20 @@
"servicePrincipalClientId": "[parameters('servicePrincipalClientId')]",
"servicePrincipalClientSecret": "[parameters('servicePrincipalClientSecret')]",
"username": "[parameters('linuxAdminUsername')]",
"masterFqdnPrefix": "[parameters('masterFqdnPrefix')]",
"dataStorageAccountPrefixSeed": 97,
"masterFqdnPrefix": "[parameters('masterEndpointDNSNamePrefix')]",
"masterPrivateIp": "[parameters('firstConsecutiveStaticIP')]",
"masterSize": "[parameters('masterVMSize')]",
"masterVMSize": "[parameters('masterVMSize')]",
"sshPublicKeyData": "[parameters('sshRSAPublicKey')]",
"masterCount": {{.MasterProfile.Count}},
"apiVersionDefault": "2016-03-30",
"apiVersionStorage": "2015-06-15",
"kubeDnsServiceIp": "10.3.0.10",
"kubeServiceCidr": "10.3.0.0/16",
"location": "[resourceGroup().location]",
"masterAvailabilitySet": "master-availabilityset",
"nsgName": "[concat(variables('masterFqdnPrefix'), '-nsg')]",
"nsgName": "[concat(variables('masterVMNamePrefix'), 'nsg')]",
"masterNSGID": "[resourceId('Microsoft.Network/networkSecurityGroups',variables('nsgName'))]",
"masterPublicIPAddressName": "[concat(variables('orchestratorName'), '-master-ip-', variables('masterFqdnPrefix'), '-', variables('nameSuffix'))]",
"storageAccountBaseName": "[uniqueString(concat(variables('masterFqdnPrefix'),resourceGroup().location, variables('orchestratorName')))]",
"masterStorageAccountName": "[concat(variables('storageAccountBaseName'), 'mstr0')]",
@ -29,8 +34,9 @@
"osImageSKU": "16.04.0-LTS",
"osImageVersion": "16.04.201606270",
"resourceGroup": "[resourceGroup().name]",
"routeTableName": "[variables('masterFqdnPrefix')]",
"routeTableName": "[concat(variables('masterVMNamePrefix'),'-routetable')]",
"singleQuote": "'",
"sshNatPorts": [22,2201,2202,2203,2204],
"sshKeyPath": "[concat('/home/',variables('username'),'/.ssh/authorized_keys')]",
"storageAccountBaseName": "[concat(uniqueString(concat(variables('masterFqdnPrefix'),resourceGroup().location)))]",
"storageAccountPrefixes": [
@ -73,16 +79,28 @@
],
"storageAccountPrefixesCount": "[length(variables('storageAccountPrefixes'))]",
"vmsPerStorageAccount": 20,
"subnetCidr": "10.0.0.0/16",
"subnetName": "[concat(variables('masterFqdnPrefix'), '-subnet')]",
"subnetRef": "[concat(variables('vnetRef'),'/subnets/',variables('subnetName'))]",
{{if .MasterProfile.IsCustomVNET}}
"masterVnetSubnetID": "[parameters('masterVnetSubnetID')]",
{{else}}
"subnetCidr": "[parameters('masterSubnet')]",
"subnetName": "[concat(variables('orchestratorName'), '-masterSubnet')]",
"subnetRef": "[concat(variables('virtualNetworkNameRef'),'/subnets/',variables('subnetName'))]",
"vnetID": "[resourceId('Microsoft.Network/virtualNetworks',variables('virtualNetworkName'))]",
"virtualNetworkName": "[concat(variables('orchestratorName'), '-vnet-', variables('nameSuffix'))]",
"virtualNetworkNameRef": "[resourceId('Microsoft.Network/virtualNetworks',variables('virtualNetworkName'))]",
{{end}}
"masterLbID": "[resourceId('Microsoft.Network/loadBalancers',variables('masterLbName'))]",
"masterLbIPConfigID": "[concat(variables('masterLbID'),'/frontendIPConfigurations/', variables('masterLbIPConfigName'))]",
"masterLbIPConfigName": "[concat(variables('orchestratorName'), '-master-lbFrontEnd-', variables('nameSuffix'))]",
"masterLbName": "[concat(variables('orchestratorName'), '-master-lb-', variables('nameSuffix'))]",
"masterLbBackendPoolName": "[concat(variables('orchestratorName'), '-master-pool-', variables('nameSuffix'))]",
"masterFirstAddrOctets": "[split(parameters('firstConsecutiveStaticIP'),'.')]",
"masterFirstAddrOctet4": "[variables('masterFirstAddrOctets')[3]]",
"masterFirstAddrPrefix": "[concat(variables('masterFirstAddrOctets')[0],'.',variables('masterFirstAddrOctets')[1],'.',variables('masterFirstAddrOctets')[2],'.')]",
"masterVMNamePrefix": "[concat(variables('orchestratorName'), '-master-', variables('nameSuffix'), '-')]",
"subscriptionId": "[subscription().subscriptionId]",
"tenantId": "[subscription().tenantId]",
"vmNamePrefix": "[concat(variables('masterFqdnPrefix'), '-vm-')]",
"vnetCidr": "10.0.0.0/8",
"vnetName": "[concat(variables('masterFqdnPrefix'), '-vnet')]",
"vnetRef": "[resourceId('Microsoft.Network/virtualNetworks',variables('vnetName'))]"
"vnetCidr": "10.0.0.0/8"

Просмотреть файл

@ -1,40 +1,40 @@
"apiserverCertificate": {
"defaultValue": "{{.MasterProfile.ApiserverCertificate}}",
"apiServerCertificate": {
"defaultValue": "{{.OrchestratorProfile.ApiServerCertificate}}",
"metadata": {
"description": "The AD Tenant Id"
},
"type": "string"
},
"apiserverPrivateKey": {
"defaultValue": "{{.MasterProfile.ApiserverPrivateKey}}",
"apiServerPrivateKey": {
"defaultValue": "{{.OrchestratorProfile.ApiServerPrivateKey}}",
"metadata": {
"description": "User name for the Linux Virtual Machines (SSH or Password)."
},
"type": "securestring"
},
"caCertificate": {
"defaultValue": "{{.MasterProfile.CaCertificate}}",
"defaultValue": "{{.OrchestratorProfile.CaCertificate}}",
"metadata": {
"description": "The certificate authority certificate"
},
"type": "string"
},
"caPrivateKey": {
"defaultValue": "{{.MasterProfile.GetCaPrivateKey}}",
"defaultValue": "{{.OrchestratorProfile.GetCAPrivateKey}}",
"metadata": {
"description": "The certificate authority private key, this is only generated once and not used in this file, save this file for future updates"
},
"type": "string"
},
"clientCertificate": {
"defaultValue": "{{.MasterProfile.ClientCertificate}}",
"defaultValue": "{{.OrchestratorProfile.ClientCertificate}}",
"metadata": {
"description": "The client certificate used to communicate with the master"
},
"type": "string"
},
"clientPrivateKey": {
"defaultValue": "{{.MasterProfile.ClientPrivateKey}}",
"defaultValue": "{{.OrchestratorProfile.ClientPrivateKey}}",
"metadata": {
"description": "The client private key used to communicate with the master"
},
@ -48,14 +48,14 @@
"type": "string"
},
"servicePrincipalClientId": {
"defaultValue": "{{.MasterProfile.ServicePrincipalClientID}}",
"defaultValue": "{{.OrchestratorProfile.ServicePrincipalClientID}}",
"metadata": {
"description": "Client ID (used by cloudprovider)"
},
"type": "string"
},
"servicePrincipalClientSecret": {
"defaultValue": "{{.MasterProfile.ServicePrincipalClientSecret}}",
"defaultValue": "{{.OrchestratorProfile.ServicePrincipalClientSecret}}",
"metadata": {
"description": "The Service Principal Client Secret."
},

Просмотреть файл

@ -24,7 +24,7 @@
"masterSubnet": {
"defaultValue": "{{.MasterProfile.GetSubnet}}",
"metadata": {
"description": "Sets the subnet of the master."
"description": "Sets the subnet of the master node(s)."
},
"type": "string"
},

Просмотреть файл

@ -3,8 +3,7 @@
"contentVersion": "1.0.0.0",
"parameters": {
{{range .AgentPoolProfiles}}{{template "agentparams.t" .}},{{end}}
{{template "masterparams.t" .}},
{{GetSizeMap}}
{{template "masterparams.t" .}}
},
"variables": {
{{range $index, $agent := .AgentPoolProfiles}}
@ -13,7 +12,9 @@
"{{.Name}}AccountName": "[concat(variables('storageAccountBaseName'), 'agnt{{$index}}')]",
{{end}}
{{template "swarmmastervars.t" .}}
{{template "swarmmastervars.t" .}},
{{GetSizeMap}}
},
"resources": [
{{range .AgentPoolProfiles}}{{template "swarmagentresources.t" .}},{{end}}

Просмотреть файл

@ -77,188 +77,6 @@
"storageAccountPrefixesCount": "[length(variables('storageAccountPrefixes'))]",
"storageApiVersion": "2015-06-15",
"virtualNetworkName": "[concat(variables('orchestratorName'), '-vnet-', variables('nameSuffix'))]",
"vmSizesMap": {
"Basic_A3": {
"storageAccountType": "Standard_LRS"
},
"Basic_A4": {
"storageAccountType": "Standard_LRS"
},
"Standard_A10": {
"storageAccountType": "Standard_LRS"
},
"Standard_A11": {
"storageAccountType": "Standard_LRS"
},
"Standard_A3": {
"storageAccountType": "Standard_LRS"
},
"Standard_A4": {
"storageAccountType": "Standard_LRS"
},
"Standard_A6": {
"storageAccountType": "Standard_LRS"
},
"Standard_A7": {
"storageAccountType": "Standard_LRS"
},
"Standard_A8": {
"storageAccountType": "Standard_LRS"
},
"Standard_A9": {
"storageAccountType": "Standard_LRS"
},
"Standard_D12": {
"storageAccountType": "Standard_LRS"
},
"Standard_D12_v2": {
"storageAccountType": "Standard_LRS"
},
"Standard_D13": {
"storageAccountType": "Standard_LRS"
},
"Standard_D13_v2": {
"storageAccountType": "Standard_LRS"
},
"Standard_D14": {
"storageAccountType": "Standard_LRS"
},
"Standard_D14_v2": {
"storageAccountType": "Standard_LRS"
},
"Standard_D15_v2": {
"storageAccountType": "Standard_LRS"
},
"Standard_D3": {
"storageAccountType": "Standard_LRS"
},
"Standard_D3_v2": {
"storageAccountType": "Standard_LRS"
},
"Standard_D4": {
"storageAccountType": "Standard_LRS"
},
"Standard_D4_v2": {
"storageAccountType": "Standard_LRS"
},
"Standard_D5_v2": {
"storageAccountType": "Standard_LRS"
},
"Standard_DS12": {
"storageAccountType": "Premium_LRS"
},
"Standard_DS12_v2": {
"storageAccountType": "Premium_LRS"
},
"Standard_DS13": {
"storageAccountType": "Premium_LRS"
},
"Standard_DS13_v2": {
"storageAccountType": "Premium_LRS"
},
"Standard_DS14": {
"storageAccountType": "Premium_LRS"
},
"Standard_DS14_v2": {
"storageAccountType": "Premium_LRS"
},
"Standard_DS15_v2": {
"storageAccountType": "Premium_LRS"
},
"Standard_DS3": {
"storageAccountType": "Premium_LRS"
},
"Standard_DS3_v2": {
"storageAccountType": "Premium_LRS"
},
"Standard_DS4": {
"storageAccountType": "Premium_LRS"
},
"Standard_DS4_v2": {
"storageAccountType": "Premium_LRS"
},
"Standard_DS5_v2": {
"storageAccountType": "Premium_LRS"
},
"Standard_F16": {
"storageAccountType": "Standard_LRS"
},
"Standard_F16s": {
"storageAccountType": "Standard_LRS"
},
"Standard_F4": {
"storageAccountType": "Standard_LRS"
},
"Standard_F4s": {
"storageAccountType": "Standard_LRS"
},
"Standard_F8": {
"storageAccountType": "Standard_LRS"
},
"Standard_F8s": {
"storageAccountType": "Standard_LRS"
},
"Standard_G2": {
"storageAccountType": "Standard_LRS"
},
"Standard_G3": {
"storageAccountType": "Standard_LRS"
},
"Standard_G4": {
"storageAccountType": "Standard_LRS"
},
"Standard_G5": {
"storageAccountType": "Standard_LRS"
},
"Standard_GS2": {
"storageAccountType": "Premium_LRS"
},
"Standard_GS3": {
"storageAccountType": "Premium_LRS"
},
"Standard_GS4": {
"storageAccountType": "Premium_LRS"
},
"Standard_GS5": {
"storageAccountType": "Premium_LRS"
},
"Standard_H16": {
"storageAccountType": "Standard_LRS"
},
"Standard_H16m": {
"storageAccountType": "Standard_LRS"
},
"Standard_H16mr": {
"storageAccountType": "Standard_LRS"
},
"Standard_H16r": {
"storageAccountType": "Standard_LRS"
},
"Standard_H8": {
"storageAccountType": "Standard_LRS"
},
"Standard_H8m": {
"storageAccountType": "Standard_LRS"
},
"Standard_NC12": {
"storageAccountType": "Standard_LRS"
},
"Standard_NC24": {
"storageAccountType": "Standard_LRS"
},
"Standard_NC6": {
"storageAccountType": "Standard_LRS"
},
"Standard_NV12": {
"storageAccountType": "Standard_LRS"
},
"Standard_NV24": {
"storageAccountType": "Standard_LRS"
},
"Standard_NV6": {
"storageAccountType": "Standard_LRS"
}
},
"vmsPerStorageAccount": 20,
"vnetID": "[resourceId('Microsoft.Network/virtualNetworks',variables('virtualNetworkName'))]"

Просмотреть файл

@ -8,15 +8,15 @@
associated storage map.
.PARAMETER OutFile
The name of the outputfile (Default is vmsizes.go)
The name of the outputfile (Default is azureconst.go)
.EXAMPLE
.\Generate-Sizes.ps1 -OutFile "vmizes.go"
.\Get-AzureConstants.ps1 -OutFile "azureconst.go"
#>
[CmdletBinding(DefaultParameterSetName="Standard")]
param(
[string]
$OutFile = "vmsizes.go"
$OutFile = "azureconst.go"
)
function
@ -78,21 +78,66 @@ Get-AgentMap() {
return $agentMap
}
function
Get-Locations() {
$locations = Get-AzureRmLocation | Select-Object -Property Location
$locationList = @()
ForEach ($location in $locations) {
$locationList += $location.Location
}
return $locationList
}
function
Get-FileContents() {
param(
[System.Collections.Hashtable]
$MasterMap,
[System.Collections.Hashtable]
$AgentMap
$AgentMap,
[System.Collections.ArrayList]
$Locations
)
$text = "package templategenerator"
$text += @"
import "fmt"
// AUTOGENERATED FILE - last generated $(Get-Date -format 'u')
const (
// AzureProdFQDNFormat specifies the format for a prod dns name
AzureProdFQDNFormat = "%s.%s.cloudapp.azure.com"
)
// AzureLocations provides all azure regions in prod.
// Related powershell to refresh this list:
// Get-AzureRmLocation | Select-Object -Property Location
var AzureLocations = []string{
"@
ForEach ($location in ($Locations | Sort-Object)) {
$text += ' "' + $location + '"' + ",`r`n"
}
$text += @"
}
// FormatAzureProdFQDNs constructs all possible Azure prod fqdn
func FormatAzureProdFQDNs(fqdnPrefix string) []string {
var fqdns []string
for _, location := range AzureLocations {
fqdns = append(fqdns, FormatAzureProdFQDN(fqdnPrefix, location))
}
return fqdns
}
// FormatAzureProdFQDN constructs an Azure prod fqdn
func FormatAzureProdFQDN(fqdnPrefix string, location string) string {
return fmt.Sprintf(AzureProdFQDNFormat, fqdnPrefix, location)
}
// GetMasterAllowedSizes returns the master allowed sizes
func GetMasterAllowedSizes() string{
return `` "allowedValues": [
@ -139,7 +184,7 @@ func GetAgentAllowedSizes() string {
``
}
// GetAgentAllowedSizes returns the size / storage map
// GetSizeMap returns the size / storage map
func GetSizeMap() string{
return `` "vmSizesMap": {
@ -195,7 +240,8 @@ try
$allSizes = Get-AllSizes
$masterMap = Get-MasterMap -SizeMap $allSizes
$agentMap = Get-AgentMap -SizeMap $allSizes
$text = Get-FileContents -MasterMap $masterMap -AgentMap $agentMap
$locations = Get-Locations
$text = Get-FileContents -MasterMap $masterMap -AgentMap $agentMap -Locations $locations
$text | Out-File $OutFile
(Get-Content $OutFile) -replace "`0", "" | Set-Content $OutFile
}

Просмотреть файл

@ -1,6 +1,57 @@
package templategenerator
// AUTOGENERATED FILE - last generated 2016-10-04 21:10:30Z
import "fmt"
// AUTOGENERATED FILE - last generated 2016-10-05 06:09:49Z
const (
// AzureProdFQDNFormat specifies the format for a prod dns name
AzureProdFQDNFormat = "%s.%s.cloudapp.azure.com"
)
// AzureLocations provides all azure regions in prod.
// Related powershell to refresh this list:
// Get-AzureRmLocation | Select-Object -Property Location
var AzureLocations = []string{
"australiaeast",
"australiasoutheast",
"brazilsouth",
"canadacentral",
"canadaeast",
"centralindia",
"centralus",
"eastasia",
"eastus",
"eastus2",
"japaneast",
"japanwest",
"northcentralus",
"northeurope",
"southcentralus",
"southeastasia",
"southindia",
"uksouth",
"ukwest",
"westcentralus",
"westeurope",
"westindia",
"westus",
"westus2",
}
// FormatAzureProdFQDNs constructs all possible Azure prod fqdn
func FormatAzureProdFQDNs(fqdnPrefix string) []string {
var fqdns []string
for _, location := range AzureLocations {
fqdns = append(fqdns, FormatAzureProdFQDN(fqdnPrefix, location))
}
return fqdns
}
// FormatAzureProdFQDN constructs an Azure prod fqdn
func FormatAzureProdFQDN(fqdnPrefix string, location string) string {
return fmt.Sprintf(AzureProdFQDNFormat, fqdnPrefix, location)
}
// GetMasterAllowedSizes returns the master allowed sizes
func GetMasterAllowedSizes() string{
@ -148,7 +199,7 @@ func GetAgentAllowedSizes() string {
`
}
// GetAgentAllowedSizes returns the size / storage map
// GetSizeMap returns the size / storage map
func GetSizeMap() string{
return ` "vmSizesMap": {
"Basic_A2": {

Просмотреть файл

@ -10,7 +10,7 @@ const (
// DefaultKubernetesMasterSubnet specifies the default kubernetes master subnet
DefaultKubernetesMasterSubnet = "10.240.0.0/16"
// DefaultFirstConsecutiveKubernetesStaticIP specifies the static IP address on Kubernetes master 0
DefaultFirstConsecutiveKubernetesStaticIP = "10.240.0.5"
DefaultFirstConsecutiveKubernetesStaticIP = "10.240.255.5"
// DefaultAgentSubnetTemplate specifies a default agent subnet
DefaultAgentSubnetTemplate = "10.%d.0.0/24"
// DefaultKubernetesClusterDomain is the dns suffix used in the cluster (used as a SAN in the PKI generation)

Просмотреть файл

@ -54,14 +54,12 @@ func setAgentNetworkDefaults(a *vlabs.AcsCluster) {
}
func setDefaultCerts(o *vlabs.OrchestratorProfile, m *vlabs.MasterProfile) error {
// auto generate certs if not specified and the dns profile exists
if len(m.DNSPrefix) > 0 &&
len(o.ApiserverCertificate) > 0 && len(o.ApiserverPrivateKey) > 0 &&
len(o.CaCertificate) > 0 &&
len(o.ClientCertificate) > 0 && len(o.ClientPrivateKey) > 0 {
masterWildCardFQDN := util.FormatAzureProdFQDN(m.DNSPrefix, "*")
masterExtraFQDNs := util.FormatAzureProdFQDNs(m.DNSPrefix)
// auto generate certs if none of them have been set by customer
if len(o.ApiServerCertificate) == 0 && len(o.ApiServerPrivateKey) == 0 &&
len(o.CaCertificate) == 0 &&
len(o.ClientCertificate) == 0 && len(o.ClientPrivateKey) == 0 {
masterWildCardFQDN := FormatAzureProdFQDN(m.DNSPrefix, "*")
masterExtraFQDNs := FormatAzureProdFQDNs(m.DNSPrefix)
firstMasterIP := net.ParseIP(m.FirstConsecutiveStaticIP)
@ -80,8 +78,8 @@ func setDefaultCerts(o *vlabs.OrchestratorProfile, m *vlabs.MasterProfile) error
return err
}
o.ApiserverCertificate = base64.URLEncoding.EncodeToString([]byte(apiServerPair.CertificatePem))
o.ApiserverPrivateKey = base64.URLEncoding.EncodeToString([]byte(apiServerPair.PrivateKeyPem))
o.ApiServerCertificate = base64.URLEncoding.EncodeToString([]byte(apiServerPair.CertificatePem))
o.ApiServerPrivateKey = base64.URLEncoding.EncodeToString([]byte(apiServerPair.PrivateKeyPem))
o.CaCertificate = base64.URLEncoding.EncodeToString([]byte(caPair.CertificatePem))
o.SetCAPrivateKey(base64.URLEncoding.EncodeToString([]byte(caPair.PrivateKeyPem)))
o.ClientCertificate = base64.URLEncoding.EncodeToString([]byte(clientPair.CertificatePem))

Просмотреть файл

@ -9,44 +9,49 @@ import (
"math/rand"
"os"
"path"
"regexp"
"strings"
"text/template"
"./../api/vlabs"
)
const (
agentOutputs = "agentoutputs.t"
agentParams = "agentparams.t"
dcosAgentResources = "dcosagentresources.t"
dcosAgentResourcesDisks = "dcosagentresourcesdisks.t"
dcosAgentVars = "dcosagentvars.t"
dcosBaseFile = "dcosbase.t"
dcosCustomData173 = "dcoscustomdata173.t"
dcosCustomData184 = "dcoscustomdata184.t"
dcosMasterResources = "dcosmasterresources.t"
dcosMasterVars = "dcosmastervars.t"
kubernetesBaseFile = "kubernetesbase.t"
kubernetesAgentCustomData = "kubernetesagentcustomdata.t"
kubernetesAgentResources = "kubernetesagentresources.t"
kubernetesAgentVars = "kubernetesagentvars.t"
kubernetesMasterCustomData = "kubernetesmastercustomdata.t"
kubernetesMasterResources = "kubernetesmasterresources.t"
kubernetesMasterVars = "kubernetesmastervars.t"
kubernetesParams = "kubernetesparams.t"
masterOutputs = "masteroutputs.t"
masterParams = "masterparams.t"
swarmBaseFile = "swarmbase.t"
swarmAgentCustomData = "swarmagentcustomdata.t"
swarmAgentResources = "swarmagentresources.t"
swarmAgentVars = "swarmagentvars.t"
swarmMasterCustomData = "swarmmastercustomdata.t"
swarmMasterResources = "swarmmasterresources.t"
swarmMasterVars = "swarmmastervars.t"
kubernetesMasterCustomDataYaml = "kubernetesmastercustomdata.yml"
kubeConfigJSON = "kubeconfig.json"
)
const (
agentOutputs = "agentoutputs.t"
agentParams = "agentparams.t"
dcosAgentResources = "dcosagentresources.t"
dcosAgentResourcesDisks = "dcosagentresourcesdisks.t"
dcosAgentVars = "dcosagentvars.t"
dcosBaseFile = "dcosbase.t"
dcosCustomData173 = "dcoscustomdata173.t"
dcosCustomData184 = "dcoscustomdata184.t"
dcosMasterResources = "dcosmasterresources.t"
dcosMasterVars = "dcosmastervars.t"
kubernetesBaseFile = "kubernetesbase.t"
kubernetesAgentResources = "kubernetesagentresources.t"
kubernetesAgentVars = "kubernetesagentvars.t"
kubernetesMasterResources = "kubernetesmasterresources.t"
kubernetesMasterVars = "kubernetesmastervars.t"
kubernetesParams = "kubernetesparams.t"
masterOutputs = "masteroutputs.t"
masterParams = "masterparams.t"
swarmBaseFile = "swarmbase.t"
swarmAgentCustomData = "swarmagentcustomdata.t"
swarmAgentResources = "swarmagentresources.t"
swarmAgentVars = "swarmagentvars.t"
swarmMasterCustomData = "swarmmastercustomdata.t"
swarmMasterResources = "swarmmasterresources.t"
swarmMasterVars = "swarmmastervars.t"
)
var commonTemplateFiles = []string{agentOutputs, agentParams, masterOutputs, masterParams}
var dcosTemplateFiles = []string{dcosAgentResources, dcosAgentResourcesDisks, dcosAgentVars, dcosBaseFile, dcosCustomData173, dcosCustomData184, dcosMasterResources, dcosMasterVars}
var kubernetesTemplateFiles = []string{kubernetesBaseFile, kubernetesAgentCustomData, kubernetesAgentResources, kubernetesAgentVars, kubernetesMasterCustomData, kubernetesMasterResources, kubernetesMasterVars, kubernetesParams}
var kubernetesTemplateFiles = []string{kubernetesBaseFile, kubernetesAgentResources, kubernetesAgentVars, kubernetesMasterResources, kubernetesMasterVars, kubernetesParams}
var swarmTemplateFiles = []string{swarmBaseFile, swarmAgentCustomData, swarmAgentResources, swarmAgentVars, swarmBaseFile, swarmMasterCustomData, swarmMasterResources, swarmMasterVars}
// VerifyFiles verifies that the required template files exist
@ -127,6 +132,20 @@ func GenerateTemplate(acsCluster *vlabs.AcsCluster, partsDirectory string) (stri
"GetSizeMap": func() string {
return GetSizeMap()
},
"GetKubernetesMasterCustomData": func() string {
str, e := getSingleLineForTemplate(kubernetesMasterCustomDataYaml, partsDirectory)
if e != nil {
return ""
}
return fmt.Sprintf("\"customData\": \"[base64(concat('%s'))]\",", str)
},
"GetKubernetesKubeConfig": func() string {
str, e := getSingleLineForTemplate(kubeConfigJSON, partsDirectory)
if e != nil {
return ""
}
return str
},
// inspired by http://stackoverflow.com/questions/18276173/calling-a-template-with-several-pipeline-parameters/18276968#18276968
"dict": func(values ...interface{}) (map[string]interface{}, error) {
if len(values)%2 != 0 {
@ -425,3 +444,28 @@ func isSwarm(acsCluster *vlabs.AcsCluster) bool {
func isKubernetes(acsCluster *vlabs.AcsCluster) bool {
return acsCluster.OrchestratorProfile.OrchestratorType == vlabs.Kubernetes
}
// getSingleLineForTemplate returns the file as a single line for embedding in an arm template
func getSingleLineForTemplate(yamlFilename string, partsDirectory string) (string, error) {
yamlFile := path.Join(partsDirectory, yamlFilename)
if _, err := os.Stat(yamlFile); os.IsNotExist(err) {
return "", fmt.Errorf("yaml file %s does not exist, did you specify the correct template directory?", yamlFile)
}
b, err := ioutil.ReadFile(yamlFile)
if err != nil {
return "", fmt.Errorf("error reading yaml file %s: %s", yamlFile, err.Error())
}
yamlStr := string(b)
yamlStr = strings.Replace(yamlStr, "\\", "\\\\", -1)
yamlStr = strings.Replace(yamlStr, "\r\n", "\\n", -1)
yamlStr = strings.Replace(yamlStr, "\n", "\\n", -1)
yamlStr = strings.Replace(yamlStr, "\"", "\\\"", -1)
// variable replacement
rVariable := regexp.MustCompile("{{{([^}]*)}}}")
yamlStr = rVariable.ReplaceAllString(yamlStr, "',variables('$1'),'")
// verbatim replacement
rVerbatim := regexp.MustCompile("<<<([^>]*)>>>")
yamlStr = rVerbatim.ReplaceAllString(yamlStr, "',$1,'")
return yamlStr, nil
}

Просмотреть файл

@ -1,52 +0,0 @@
package util
import "fmt"
const (
// AzureProdFQDNFormat specifies the format for a prod dns name
AzureProdFQDNFormat = "%s.%s.cloudapp.azure.com"
)
// AzureLocations provides all azure regions in prod.
// Related powershell to refresh this list:
// Get-AzureRmLocation | Select-Object -Property Location
var AzureLocations = []string{
"eastasia",
"southeastasia",
"centralus",
"eastus",
"eastus2",
"westus",
"northcentralus",
"southcentralus",
"northeurope",
"westeurope",
"japanwest",
"japaneast",
"brazilsouth",
"australiaeast",
"australiasoutheast",
"southindia",
"centralindia",
"westindia",
"canadacentral",
"canadaeast",
"uksouth",
"ukwest",
"westcentralus",
"westus2",
}
// FormatAzureProdFQDNs constructs all possible Azure prod fqdn
func FormatAzureProdFQDNs(fqdnPrefix string) []string {
var fqdns []string
for _, location := range AzureLocations {
fqdns = append(fqdns, FormatAzureProdFQDN(fqdnPrefix, location))
}
return fqdns
}
// FormatAzureProdFQDN constructs an Azure prod fqdn
func FormatAzureProdFQDN(fqdnPrefix string, location string) string {
return fmt.Sprintf(AzureProdFQDNFormat, fqdnPrefix, location)
}

Просмотреть файл

@ -37,7 +37,7 @@ func CreatePki(masterFQDN string, extraFQDNs []string, extraIPs []net.IP, cluste
if err != nil {
return nil, nil, nil, err
}
apiserverCertificate, apiserverPrivateKey, err := createCertificate("apiserver", caCertificate, caPrivateKey, true, masterFQDN, extraFQDNs, extraIPs)
apiServerCertificate, apiServerPrivateKey, err := createCertificate("apiserver", caCertificate, caPrivateKey, true, masterFQDN, extraFQDNs, extraIPs)
if err != nil {
return nil, nil, nil, err
}
@ -47,7 +47,7 @@ func CreatePki(masterFQDN string, extraFQDNs []string, extraIPs []net.IP, cluste
}
return &PkiKeyCertPair{CertificatePem: string(certificateToPem(caCertificate.Raw)), PrivateKeyPem: string(privateKeyToPem(caPrivateKey))},
&PkiKeyCertPair{CertificatePem: string(certificateToPem(apiserverCertificate.Raw)), PrivateKeyPem: string(privateKeyToPem(apiserverPrivateKey))},
&PkiKeyCertPair{CertificatePem: string(certificateToPem(apiServerCertificate.Raw)), PrivateKeyPem: string(privateKeyToPem(apiServerPrivateKey))},
&PkiKeyCertPair{CertificatePem: string(certificateToPem(clientCertificate.Raw)), PrivateKeyPem: string(privateKeyToPem(clientPrivateKey))}, nil
}